├── docs
├── .nojekyll
├── assets
│ ├── favicon
│ │ └── favicon.png
│ ├── vendor
│ │ ├── docsify
│ │ │ ├── plugins
│ │ │ │ ├── docsify-footer.min.js
│ │ │ │ ├── docsify-fontawesome.min.js
│ │ │ │ ├── docsify-footer.js
│ │ │ │ ├── docsify-img-grid.js
│ │ │ │ ├── toc.js
│ │ │ │ ├── docsify-fontawesome.js
│ │ │ │ └── search.js
│ │ │ └── LICENSE
│ │ └── themeable
│ │ │ ├── LICENSE
│ │ │ └── docsify-themeable.min.js
│ └── css
│ │ ├── editor.css
│ │ ├── toc.css
│ │ ├── print.css
│ │ ├── custom.css
│ │ └── theme.css
├── images
│ ├── 12650723674_d5c85af332_k.jpg
│ ├── 4642289926_7964e733d1_b.jpg
│ ├── 4853380320_492f9dce63_b.jpg
│ ├── 6384294717_5047a35d48_b.jpg
│ ├── 6968244538_4c0f7c7e64_k.jpg
│ ├── ux-toolkit-8-no-numbers.png
│ ├── dave-hoefler-vl2uAIdBWJ8-unsplash.jpg
│ └── belinda-fewings-6wAGwpsXHE0-unsplash.jpg
├── _navbar.md
├── contact.md
├── module-06.md
├── module-07.md
├── module-08.md
├── module-09.md
├── module-10.md
├── module-11.md
├── module-12.md
├── module-13.md
├── _footer.md
├── course-welcome.md
├── home.md
├── module-05.md
├── module-03.md
├── topics.md
├── module-01.md
├── module-04.md
├── module-02.md
├── _sidebar.md
├── lms-topics.md
├── schedule.md
├── lms-schedule.md
├── resources.md
└── index.html
├── screenshot.jpg
├── screenshot-2.jpg
├── .gitignore
├── LICENSE
├── CHANGELOG.md
└── README.md
/docs/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/screenshot.jpg
--------------------------------------------------------------------------------
/screenshot-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/screenshot-2.jpg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS generated files #
2 | ######################
3 | .DS_Store
4 | .DS_Store?
5 | .vscode
6 | .vscode?
7 | .obsidian
8 | .obsidian?
--------------------------------------------------------------------------------
/docs/assets/favicon/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/assets/favicon/favicon.png
--------------------------------------------------------------------------------
/docs/images/12650723674_d5c85af332_k.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/12650723674_d5c85af332_k.jpg
--------------------------------------------------------------------------------
/docs/images/4642289926_7964e733d1_b.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/4642289926_7964e733d1_b.jpg
--------------------------------------------------------------------------------
/docs/images/4853380320_492f9dce63_b.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/4853380320_492f9dce63_b.jpg
--------------------------------------------------------------------------------
/docs/images/6384294717_5047a35d48_b.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/6384294717_5047a35d48_b.jpg
--------------------------------------------------------------------------------
/docs/images/6968244538_4c0f7c7e64_k.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/6968244538_4c0f7c7e64_k.jpg
--------------------------------------------------------------------------------
/docs/images/ux-toolkit-8-no-numbers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/ux-toolkit-8-no-numbers.png
--------------------------------------------------------------------------------
/docs/_navbar.md:
--------------------------------------------------------------------------------
1 | * [Schedule](schedule.md)
2 | * [Topics](topics.md)
3 | * [Resources](resources.md)
4 | * [UX Techniques Guide](ux-techniques-guide.md)
5 | * [Contact](contact.md)
6 |
--------------------------------------------------------------------------------
/docs/images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg
--------------------------------------------------------------------------------
/docs/images/belinda-fewings-6wAGwpsXHE0-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/belinda-fewings-6wAGwpsXHE0-unsplash.jpg
--------------------------------------------------------------------------------
/docs/contact.md:
--------------------------------------------------------------------------------
1 | # Contact
2 |
3 | ## Course Instructor
4 | Some Name
5 | somename@somewhere.edu
6 |
7 | Online office hours:
8 | Mondays 12:00-1:30pm
9 | Fridays 12:00-1:00pm
10 |
11 | Suggestion, concern or complaint?
12 | Send me your [anonymous course feedback](#)!
13 |
--------------------------------------------------------------------------------
/docs/module-06.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Module Title
4 |
5 | ## Content Header
6 | Module content here.
7 |
8 | ## Content Header
9 | Module content here.
10 |
11 | ## Content Header
12 | Module content here.
13 |
14 | ## Content Header
15 | Module content here.
16 |
--------------------------------------------------------------------------------
/docs/module-07.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Module Title
4 |
5 | ## Content Header
6 | Module content here.
7 |
8 | ## Content Header
9 | Module content here.
10 |
11 | ## Content Header
12 | Module content here.
13 |
14 | ## Content Header
15 | Module content here.
16 |
--------------------------------------------------------------------------------
/docs/module-08.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Module Title
4 |
5 | ## Content Header
6 | Module content here.
7 |
8 | ## Content Header
9 | Module content here.
10 |
11 | ## Content Header
12 | Module content here.
13 |
14 | ## Content Header
15 | Module content here.
16 |
--------------------------------------------------------------------------------
/docs/module-09.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Module Title
4 |
5 | ## Content Header
6 | Module content here.
7 |
8 | ## Content Header
9 | Module content here.
10 |
11 | ## Content Header
12 | Module content here.
13 |
14 | ## Content Header
15 | Module content here.
16 |
--------------------------------------------------------------------------------
/docs/module-10.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Module Title
4 |
5 | ## Content Header
6 | Module content here.
7 |
8 | ## Content Header
9 | Module content here.
10 |
11 | ## Content Header
12 | Module content here.
13 |
14 | ## Content Header
15 | Module content here.
16 |
--------------------------------------------------------------------------------
/docs/module-11.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Module Title
4 |
5 | ## Content Header
6 | Module content here.
7 |
8 | ## Content Header
9 | Module content here.
10 |
11 | ## Content Header
12 | Module content here.
13 |
14 | ## Content Header
15 | Module content here.
16 |
--------------------------------------------------------------------------------
/docs/module-12.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Module Title
4 |
5 | ## Content Header
6 | Module content here.
7 |
8 | ## Content Header
9 | Module content here.
10 |
11 | ## Content Header
12 | Module content here.
13 |
14 | ## Content Header
15 | Module content here.
16 |
--------------------------------------------------------------------------------
/docs/module-13.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Module Title
4 |
5 | ## Content Header
6 | Module content here.
7 |
8 | ## Content Header
9 | Module content here.
10 |
11 | ## Content Header
12 | Module content here.
13 |
14 | ## Content Header
15 | Module content here.
16 |
--------------------------------------------------------------------------------
/docs/_footer.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License .
--------------------------------------------------------------------------------
/docs/assets/vendor/docsify/plugins/docsify-footer.min.js:
--------------------------------------------------------------------------------
1 | !function(o,i,t){i.plugins=[].concat((function(i,t){const{loadFooter:e,ext:n,requestHeaders:c}=t.config;e&&i.afterEach((function(i,l){try{var s=window.location.hash.slice(1).split("/").slice(0,-1).join("/"),r=!1,a=(s=s?s+"/":"")+(!0===e?"_footer"+n:e);o.get(t.router.getFile(a),!1,c).then((o=>{const e=t.compiler.compile(o);r=!0,l(i+e)}))}finally{r||l(i)}}))}),i.plugins)}(Docsify,$docsify);
--------------------------------------------------------------------------------
/docs/course-welcome.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Welcome to CPT-363 User Interface Design 👋🏼
4 |
5 | To help orientate yourself to the course, explore the [course syllabus](https://canvas.sfu.ca/courses/44038/assignments/syllabus). You may also want to view a brief tour of [Blackboard Collaborate Ultra](https://www.youtube.com/watch?v=1W4sGpVmJaY).
6 |
7 | Is this your first online course? If so, you might find these articles of help:
8 |
9 | * [8 Strategies for Getting the Most Out of an Online Class](https://www.northeastern.edu/graduate/blog/tips-for-taking-online-classes/)
10 | * [What Makes a Successful Online Learner?](https://careerwise.minnstate.edu/education/successonline.html)
11 | * [Student toolkit to help tackle remote learning](https://socialmediaforlearning.com/2020/03/22/guest-post-a-student-toolkit-to-help-you-tackle-remote-learning-written-by-students-for-students/)
12 |
--------------------------------------------------------------------------------
/docs/home.md:
--------------------------------------------------------------------------------
1 | > # What’s Happening This Week
2 | > ## How to explore the problem space?
3 | > ### Important Reminders
4 | > * [Journey Map](#) assignment Tue Jun 12th 11:59pm PDT
5 | > * [Course Reflection Log](#) assignment Fri Aug 3rd 11:59pm PDT
6 | >
7 | > ### Required Reading
8 | > * [The Skeptic’s Guide To Low-Fidelity Prototyping](https://www.smashingmagazine.com/2014/10/the-skeptics-guide-to-low-fidelity-prototyping/)
9 | >
10 | > [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button')
11 |
12 | # Looking Ahead to Next Week
13 | ## How to plan, conduct, and summarize usability tests?
14 | ### Week 5 Required Reading
15 | The Art of Guerrilla Usability Testing | UX Booth
16 |
17 | ### Week 5 Slides to be Discussed
18 | [Usability Testing](https://www.google.ca/slides/about/)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Paul Hibbitts
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/assets/vendor/docsify/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 - present cinwell.li
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/assets/vendor/themeable/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 John Hildenbiddle
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/module-05.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # How to plan, conduct, and summarize usability tests?
4 |
5 | ## Summaries and Questions
6 | [Jun 6th Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377746)
7 |
8 | ## Presented Slides
9 |
10 |
11 | ## Supplemental Materials
12 | VIDEO
13 |
14 | ## Required Reading
15 | The Art of Guerrilla Usability Testing
16 |
--------------------------------------------------------------------------------
/docs/module-03.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # How to make more strategic design decisions?
4 |
5 | ## Summaries and Questions
6 | [May 23rd Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377744)
7 |
8 | ## Presented Slides
9 |
10 |
11 | ## Supplemental Materials
12 | VIDEO
13 |
14 | ## Assignments
15 | [Journey Map](https://sso.canvaslms.com/courses/1924881/assignments/14377756)
16 |
17 | ## Required Reading
18 | What is a User Journey Map?
19 |
--------------------------------------------------------------------------------
/docs/topics.md:
--------------------------------------------------------------------------------
1 | # Topics
2 |
3 | [A](#a)| B | C |[D](#d)| E |[F](#f)| G |[H](#h)| I |[J](#j)|[K](#k)|[L](#l)|[M](#m)| N | O |[P](#p)| Q | R |[S](#s)|[T](#t)|[U](#u)|[V](#v)| W | X | Y | Z
4 |
5 | ## A
6 | [Agile UX](module-02)
7 |
8 | ## D
9 | [Design Ethics](module-02)
10 | [Design Thinking](module-01)
11 |
12 | ## F
13 | [5-Second Test](module-05)
14 | [Five Whys](module-01)
15 |
16 | ## H
17 | [Hypothesis](module-02)
18 |
19 | ## J
20 | [Journey Maps](module-03)
21 |
22 | ## K
23 | [Kano Model](module-03)
24 |
25 | ## L
26 | [Lean UX](module-02)
27 |
28 | ## M
29 | [Microsoft Product Reaction Cards](module-02)
30 |
31 | ## P
32 | [Problem Statement](module-03)
33 | [Product Design Principles](module-03)
34 | [Prototyping](module-04)
35 |
36 | ## S
37 | [Scenario-based Design (and Task-Centered Design)](module-04)
38 | [Scenarios (and Design Scenarios)](module-04)
39 | [Sketching](module-04)
40 | [Social Design](module-01)
41 | [Software Design Processes](module-02)
42 | [Storyboards](module-04)
43 |
44 | ## T
45 | [Task Analysis](module-02)
46 |
47 | ## U
48 | [Usability](module-01)
49 | [Usability Goals](module-02)
50 | [Usability Testing](module-05)
51 | [User-centered Design (UCD)](module-01)
52 | [User Experience Design](module-02)
53 | [UX Goals](module-02)
54 | [UX Strategy](module-03)
55 |
56 | ## V
57 | [Value Proposition](module-03)
58 |
--------------------------------------------------------------------------------
/docs/assets/vendor/docsify/plugins/docsify-fontawesome.min.js:
--------------------------------------------------------------------------------
1 | !function(e){var n={};function r(t){if(n[t])return n[t].exports;var o=n[t]={i:t,l:!1,exports:{}};return e[t].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=n,r.d=function(e,n,t){r.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,n){if(1&n&&(e=r(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(r.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)r.d(t,o,function(n){return e[n]}.bind(null,o));return t},r.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(n,"a",n),n},r.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},r.p="",r(r.s=0)}([function(e,n,r){"use strict";r.r(n),window.$docsify=window.$docsify||{},window.$docsify.plugins=(window.$docsify.plugins||[]).concat((function(e){const n=/:fa[\w -]+:/gm;e.beforeEach(e=>e.replace(n,(function(e,n){return console.log("m: "+e.replace(/:/gi,"")),` `}))),e.afterEach((function(e,r){r(e.replace(n,(function(e,n){return console.log("m: "+e.replace(/:/gi,"")),` `})))}))}))}]);
--------------------------------------------------------------------------------
/docs/module-01.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # What is usability and user experience design?
4 |
5 | ## Summaries and Questions
6 | [May 9th Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377751)
7 |
8 | ## Presented Slides
9 |
10 |
11 | ## Supplemental Materials
12 | [Elements of User Experience by Jesse James Garrett](https://qofr.files.wordpress.com/2016/11/q-of-r-presentation-11.pdf)
13 |
14 |
15 | ## Downloads
16 | [Course Overview](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Course%20Overview)
17 |
18 | ## Recommended Reading
19 | Usability 101: Introduction to Usability
20 |
--------------------------------------------------------------------------------
/docs/module-04.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # How to explore the problem space?
4 |
5 | ## Summaries and Questions
6 | [May 30th Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377745)
7 |
8 | ## Presented Slides
9 |
10 |
11 | ## Supplemental Materials
12 | VIDEO
13 |
14 | ## Downloads
15 | [4-UP BROWSERS + GRID](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Sketching%20Templates/sneakpeekit-4-browsers)
16 | [4-UP MOBILES + GRID](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Sketching%20Templates/sneakpeekit-4-mobiles)
17 |
18 | ## Required Reading
19 | The Skeptic’s Guide To Low-Fidelity Prototyping
20 |
--------------------------------------------------------------------------------
/docs/module-02.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # What does a holistic user experience design process look like?
4 |
5 | ## Summaries and Questions
6 | [May 16th Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377743)
7 |
8 | ## Presented Slides
9 |
10 |
11 | ## CPT-363 UX Design Process/Toolkit
12 | 
13 |
14 | ## Downloads
15 | [Product Reaction Cards](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Product%20Reaction%20Cards)
16 |
17 | ## Assignments
18 | [Course Reflection Log](https://sso.canvaslms.com/courses/1413912/assignments/9519528)
19 |
20 | ## Quick Quiz
21 |
22 |
23 | ## Recommended Reading
24 | The Evolution of UX Process Methodology
25 |
--------------------------------------------------------------------------------
/docs/_sidebar.md:
--------------------------------------------------------------------------------
1 | - [Course Welcome](course-welcome)
2 | - [Week 1 (May 9 - 15)](module-01)
3 | - [Week 2 (May 16 - 22)](module-02)
4 | - [Week 3 (May 23 - 29)](module-03)
5 | - [Week 4 (May 30 - Jun 5)](module-04)
6 | - **LMS Links**
7 | - [Calendar](https://canvas.sfu.ca/courses/44038/calendar)
8 | - [Assignments](https://canvas.sfu.ca/courses/44038/assignments )
9 | - [Quizzes](https://canvas.sfu.ca/courses/44038/quizzes)
10 | - [Class Discussions](https://canvas.sfu.ca/courses/44038/discussion_topics)
11 | - [Syllabus](https://canvas.sfu.ca/courses/44038/assignments/syllabus)
12 | - **Project Info**
13 | - [GitHub Repository](https://github.com/hibbitts-design/docsify-open-course-starter-kit/)
14 | - [ReadMe](https://github.com/hibbitts-design/docsify-open-course-starter-kit/blob/main/README.md)
15 |
16 |
--------------------------------------------------------------------------------
/docs/assets/vendor/docsify/plugins/docsify-footer.js:
--------------------------------------------------------------------------------
1 | // Support for footer files ('_footer.md') in subfolders
2 | // Original source plugin 'docsify-footer' by @alertbox
3 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI
4 | (function (Docsify, $docsify, undefined) {
5 | const DEFAULT_FOOTER = "_footer";
6 |
7 | const install = function (hook, vm) {
8 | const { loadFooter, ext, requestHeaders } = vm.config;
9 |
10 | // Fail fast if loadFooter is not defined
11 | if (!loadFooter) {
12 | return;
13 | }
14 |
15 | hook.afterEach(function (html, next) {
16 | try {
17 | // Parse current URL to extract folder path
18 | var urlFragment = window.location.hash.slice(1); // Remove '#' character
19 | var pathSegments = urlFragment.split("/");
20 | var folderPath = pathSegments.slice(0, -1).join("/"); // Exclude the file part
21 | folderPath = folderPath ? folderPath + "/" : ""; // Ensure folder path ends with '/'
22 |
23 | var footerAppended = false; // Flag to indicate footer append status
24 |
25 | var footerFile =
26 | folderPath +
27 | (loadFooter === true ? DEFAULT_FOOTER + ext : loadFooter);
28 |
29 | // Fetch and append the footer content
30 | Docsify.get(vm.router.getFile(footerFile), false, requestHeaders)
31 | .then((content) => {
32 | const footerHtml = vm.compiler.compile(content);
33 | footerAppended = true; // Set flag to true as footer is appended
34 | next(html + footerHtml); // Append the footer to the current page content
35 | })
36 | } finally {
37 | // Check if footer was not appended, then pass html
38 | if (!footerAppended) {
39 | next(html);
40 | }
41 | }
42 | });
43 | };
44 |
45 | $docsify.plugins = [].concat(install, $docsify.plugins);
46 | })(Docsify, $docsify);
47 |
--------------------------------------------------------------------------------
/docs/assets/css/editor.css:
--------------------------------------------------------------------------------
1 | /*
2 | ===============================================================================================================================
3 | CSS for better Markdown previews within a text editor.
4 | ===============================================================================================================================
5 | */
6 |
7 | .badge {
8 | color: var(--badge-text-color, #fff); /* Default text color */
9 | background-color: var(--badge-bg-color, #6c757d); /* Default background */
10 |
11 | display: inline-block;
12 | padding: .25em .4em .25em .4em;
13 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
14 | font-size: 75%;
15 | font-weight: 700;
16 | line-height: 1;
17 | text-align: center;
18 | white-space: nowrap;
19 | vertical-align: middle;
20 | margin-top: -0.4em;
21 | border-radius: .25rem;
22 | transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
23 | text-decoration: none;
24 | }
25 |
26 | .badge a {
27 | color: var(--badge-text-color, #fff)!important; /* Default text color */
28 | text-decoration: none !important;
29 | }
30 |
31 | ul {
32 | list-style: square outside none;
33 | }
34 |
35 | .alert {
36 | overflow: visible;
37 | margin: 2em 0;
38 | padding: 1.5em;
39 | background: #f7f7f7;
40 | }
41 |
42 | .alert ul {
43 | list-style: none;
44 | margin-top: .8em;
45 | }
46 |
47 | .alert ul li {
48 | margin: 2px 0;
49 | }
50 |
51 | .alert ul li:before {
52 | position: absolute;
53 | content: '\2B29';
54 | margin-left: -18px;
55 | }
56 |
57 | .blockquote ul {
58 | list-style: none;
59 | margin-top: .8em;
60 | }
61 |
62 | .blockquote ul li {
63 | margin: 2px 0;
64 | }
65 |
66 | .blockquote ul li:before {
67 | position: absolute;
68 | content: '\2B29';
69 | margin-left: -18px;
70 | }
71 |
72 | .video-container-4by3 {
73 | position: relative;
74 | padding-bottom: 75%;
75 | height: 0;
76 | overflow: hidden;
77 | max-width: 100%;
78 | }
79 |
80 | .video-container-16by9 {
81 | position: relative;
82 | padding-bottom: 56.25%;
83 | height: 0;
84 | overflow: hidden;
85 | max-width: 100%;
86 | }
87 |
88 | .video-container-16by9 iframe, .video-container-4by3 iframe, .embed-container object, .embed-container embed {
89 | position: absolute;
90 | top: 0;
91 | left: 0;
92 | width: 100%;
93 | height: 93%;
94 | }
95 |
--------------------------------------------------------------------------------
/docs/lms-topics.md:
--------------------------------------------------------------------------------
1 | # Topics
2 |
3 | [A](#a)| B | C |[D](#d)| E |[F](#f)| G |[H](#h)| I |[J](#j)|[K](#k)|[L](#l)|[M](#m)| N | O |[P](#p)| Q | R |[S](#s)|[T](#t)|[U](#u)|[V](#v)| W | X | Y | Z
4 |
5 | ## A
6 | [Agile UX](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
7 |
8 | ## D
9 | [Design Ethics](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
10 | [Design Thinking](https://canvas.sfu.ca/courses/44038/modules/items/1096965)
11 |
12 | ## F
13 | [5-Second Test](https://canvas.sfu.ca/courses/44038/modules/items/1096974)
14 | [Five Whys](https://canvas.sfu.ca/courses/44038/modules/items/1096965)
15 |
16 | ## H
17 | [Hypothesis](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
18 |
19 | ## J
20 | [Journey Maps](https://canvas.sfu.ca/courses/44038/modules/items/1096970)
21 |
22 | ## K
23 | [Kano Model](https://canvas.sfu.ca/courses/44038/modules/items/1096970)
24 |
25 | ## L
26 | [Lean UX](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
27 |
28 | ## M
29 | [Microsoft Product Reaction Cards](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
30 |
31 | ## P
32 | [Problem Statement](https://canvas.sfu.ca/courses/44038/modules/items/1096970)
33 | [Product Design Principles](https://canvas.sfu.ca/courses/44038/modules/items/1096970)
34 | [Prototyping](https://canvas.sfu.ca/courses/44038/modules/items/1096967)
35 |
36 | ## S
37 | [Scenario-based Design (and Task-Centered Design)](https://canvas.sfu.ca/courses/44038/modules/items/1096967)
38 | [Scenarios (and Design Scenarios)](https://canvas.sfu.ca/courses/44038/modules/items/1096967)
39 | [Sketching](https://canvas.sfu.ca/courses/44038/modules/items/1096967)
40 | [Social Design](https://canvas.sfu.ca/courses/44038/modules/items/1096965)
41 | [Software Design Processes](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
42 | [Storyboards](https://canvas.sfu.ca/courses/44038/modules/items/1096967)
43 |
44 | ## T
45 | [Task Analysis](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
46 |
47 | ## U
48 | [Usability](https://canvas.sfu.ca/courses/44038/modules/items/1096965)
49 | [Usability Goals](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
50 | [Usability Testing](https://canvas.sfu.ca/courses/44038/modules/items/1096974)
51 | [User-centered Design (UCD)](https://canvas.sfu.ca/courses/44038/modules/items/1096965)
52 | [User Experience Design](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
53 | [UX Goals](https://canvas.sfu.ca/courses/44038/modules/items/1096966)
54 | [UX Strategy](https://canvas.sfu.ca/courses/44038/modules/items/1096970)
55 |
56 | ## V
57 | [Value Proposition](https://canvas.sfu.ca/courses/44038/modules/items/1096970)
58 |
--------------------------------------------------------------------------------
/docs/schedule.md:
--------------------------------------------------------------------------------
1 | # Schedule
2 |
3 | ## :fas fa-calendar fa-pull-left: [Week 1 (May 9 - 15)](module-01)
4 | **What is usability and user experience design?**
5 | :fas fa-desktop fa-fw: [Introduction to UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
6 | :fas fa-book fa-fw: [Usability 101: Introduction to Usability](https://www.nngroup.com/articles/usability-101-introduction-to-usability/)
7 |
8 | ## :fas fa-calendar fa-pull-left: [Week 2 (May 16 - 22)](module-02)
9 | **What does a holistic user experience design process look like?**
10 | :fas fa-keyboard fa-fw: [Course Reflection Log](https://sso.canvaslms.com/courses/1924881/assignments/14377752) Fri Aug 3rd 11:59pm PDT
11 | :fas fa-desktop fa-fw: [The Process of UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
12 | :fas fa-book fa-fw: [The Evolution of UX Process Methodology](https://uxplanet.org/the-evolution-of-ux-process-methodology-47f52557178b)
13 |
14 | ## :fas fa-calendar fa-pull-left: [Week 3 (May 23 - 29)](module-03)
15 | **How to make more strategic design decisions?**
16 | :fas fa-keyboard fa-fw: [Journey Map](https://sso.canvaslms.com/courses/1924881/assignments/14377756) Tue Jun 12th 11:59pm PDT
17 | :fas fa-folder fa-fw: [Informed Consent Materials](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Informed%20Consent)
18 | :fas fa-desktop fa-fw: [Strategic UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
19 | :fas fa-book fa-fw: [What is a User Journey Map?](https://www.aytech.ca/blog/user-journey-map/)
20 |
21 | ## :fas fa-calendar fa-pull-left: [Week 4 (May 30 - Jun 5)](module-04)
22 | **How to explore the problem space?**
23 | :fas fa-desktop fa-fw: [Prototyping](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
24 | :fas fa-book fa-fw: [The Skeptic’s Guide To Low-Fidelity Prototyping](https://www.smashingmagazine.com/2014/10/the-skeptics-guide-to-low-fidelity-prototyping/)
25 | :fas fa-users fa-fw: In-class office hours (tentative)
26 |
27 | ## :fas fa-calendar fa-pull-left: [Week 5 (Jun 6 - 12)](module-05)
28 | **How to plan, conduct, and summarize usability tests?**
29 | :fas fa-desktop fa-fw: [Usability Testing](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
30 | :fas fa-book fa-fw: [The Art of Guerrilla Usability Testing](http://www.uxbooth.com/articles/the-art-of-guerrilla-usability-testing/)
31 | :fas fa-users fa-fw: In-class office hours (tentative)
32 |
--------------------------------------------------------------------------------
/docs/assets/css/toc.css:
--------------------------------------------------------------------------------
1 | .content *::-webkit-scrollbar {
2 | background-color: transparent;
3 | width: 12px;
4 | }
5 | .content *::-webkit-scrollbar-track {
6 | background-color: transparent;
7 | }
8 | .content *::-webkit-scrollbar-thumb {
9 | border-radius: 20px;
10 | border: 3px solid transparent;
11 | background-color: rgba(0,0,0,0.3);
12 | background-clip: content-box;
13 | }
14 | .content {
15 | display: flex;
16 | flex-direction: row-reverse;
17 | justify-content: center;
18 | }
19 | /* Specific style for .token.content inside code blocks */
20 | .content code .token.content {
21 | display: inline;
22 | }
23 | .markdown-section {
24 | flex: 1 1 0%;
25 | margin: 0 48px;
26 | }
27 | .nav {
28 | width: var(--toc-width, 280px);
29 | min-width: 200px;
30 | align-self: flex-start;
31 | flex: 0 0 auto;
32 | }
33 | aside.nav.nothing {
34 | width: 0;
35 | }
36 |
37 | .page_toc {
38 | border-left-style: solid;
39 | border-left-width: 1px;
40 | border-left-color: rgba(0, 0, 0, 0.07);
41 | border-image-slice: 1;
42 | padding-left: 5px;
43 | position: -webkit-sticky;
44 | position: fixed;
45 | overflow: auto;
46 | max-height: 100vh;
47 | top: 0;
48 | bottom: auto;
49 | margin-right: 10px;
50 | scrollbar-width: thin !important;
51 | scrollbar-color: grey transparent;
52 | }
53 |
54 | .page_toc a > * {
55 | pointer-events: none;
56 | }
57 |
58 | .page_toc code {
59 | background-color: #f8f8f8;
60 | border-radius: 2px;
61 | color: #e96900;
62 | font-family: 'Roboto Mono', Monaco, courier, monospace;
63 | font-size: 0.8rem;
64 | margin: 0 2px;
65 | padding: 3px 5px;
66 | }
67 |
68 | .page_toc p.title {
69 | margin: 0px 0 0px 9px;
70 | padding-top: 15px;
71 | padding-bottom: 5px;
72 | font-weight: 400;
73 | font-size: 1.2em;
74 | }
75 | .page_toc .anchor:hover:after {
76 | content: "";
77 | }
78 |
79 | .page_toc ul {
80 | list-style-type: none;
81 | margin-top: 0px;
82 | padding-left: 10px;
83 | color: var(--base-color, black);
84 | text-decoration: none;
85 | font-weight: 400;
86 | line-height: 1.2em;
87 | }
88 |
89 | .page_toc ul a:hover span {
90 | border-bottom: none !important;
91 | text-decoration:underline !important;
92 | }
93 |
94 | .page_toc ul a {
95 | color: var(--base-color, black);
96 | text-decoration: none;
97 | font-weight: 400;
98 | line-height: 1.2em;
99 | }
100 |
101 | .page_toc ul li {
102 | padding-top: 7px;
103 | }
104 |
105 | @media screen and (max-width: 900px) {
106 | .page_toc {
107 | position: relative;
108 | top: -20px;
109 | padding: 10px 0;
110 | border: none;
111 | border-bottom: 1px solid #ddd;
112 | font-size: 1.0em;
113 | }
114 | .nav {
115 | margin: 0 auto;
116 | width: 900px;
117 | }
118 | .page_toc p.title {
119 | font-weight: 400;
120 | font-size: 1.2em;
121 | }
122 | .content {
123 | display: block;
124 | }
125 | .markdown-section {
126 | margin: 0 auto;
127 | }
128 | }
129 |
130 | /*
131 | .page_toc .active {
132 | border-left: 5px solid;
133 | color: var(--theme-color, #42b983);
134 | padding-left: 10px;
135 | }
136 | */
137 |
--------------------------------------------------------------------------------
/docs/lms-schedule.md:
--------------------------------------------------------------------------------
1 | # Schedule
2 |
3 | ## :fas fa-calendar fa-pull-left: Week 1 (May 9 - 15)
4 | **[What is usability and user experience design?](https://canvas.sfu.ca/courses/44038/modules/items/1096965)**
5 | :fas fa-desktop fa-fw: [Introduction to UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
6 | :fas fa-book fa-fw: [Usability 101: Introduction to Usability](https://www.nngroup.com/articles/usability-101-introduction-to-usability/)
7 |
8 | ## :fas fa-calendar fa-pull-left: Week 2 (May 16 - 22)
9 | **[What does a holistic user experience design process look like?](https://canvas.sfu.ca/courses/44038/modules/items/1096966)**
10 | :fas fa-keyboard fa-fw: [Course Reflection Log](https://sso.canvaslms.com/courses/1924881/assignments/14377752) Fri Aug 3rd 11:59pm PDT
11 | :fas fa-desktop fa-fw: [The Process of UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
12 | :fas fa-book fa-fw: [The Evolution of UX Process Methodology](https://uxplanet.org/the-evolution-of-ux-process-methodology-47f52557178b)
13 |
14 | ## :fas fa-calendar fa-pull-left: Week 3 (May 23 - 29)
15 | **[How to make more strategic design decisions?](https://canvas.sfu.ca/courses/44038/modules/items/1096970)**
16 | :fas fa-keyboard fa-fw: [Journey Map](https://sso.canvaslms.com/courses/1924881/assignments/14377756) Tue Jun 12th 11:59pm PDT
17 | :fas fa-folder fa-fw: [Informed Consent Materials](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Informed%20Consent)
18 | :fas fa-desktop fa-fw: [Strategic UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
19 | :fas fa-book fa-fw: [What is a User Journey Map?](https://www.aytech.ca/blog/user-journey-map/)
20 |
21 | ## :fas fa-calendar fa-pull-left: Week 4 (May 30 - Jun 5)
22 | **[How to explore the problem space?](https://canvas.sfu.ca/courses/44038/modules/items/1096967)**
23 | :fas fa-desktop fa-fw: [Prototyping](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
24 | :fas fa-book fa-fw: [The Skeptic’s Guide To Low-Fidelity Prototyping](https://www.smashingmagazine.com/2014/10/the-skeptics-guide-to-low-fidelity-prototyping/)
25 | :fas fa-users fa-fw: In-class office hours (tentative)
26 |
27 | ## :fas fa-calendar fa-pull-left: Week 5 (Jun 6 - 12)
28 | **[How to plan, conduct, and summarize usability tests?](https://canvas.sfu.ca/courses/44038/modules/items/1096974)**
29 | :fas fa-desktop fa-fw: [Usability Testing](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000)
30 | :fas fa-book fa-fw: [The Art of Guerrilla Usability Testing](http://www.uxbooth.com/articles/the-art-of-guerrilla-usability-testing/)
31 | :fas fa-users fa-fw: In-class office hours (tentative)
32 |
--------------------------------------------------------------------------------
/docs/assets/vendor/docsify/plugins/docsify-img-grid.js:
--------------------------------------------------------------------------------
1 | // Original source plugin 'img-grid' by @gllmAR
2 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI
3 | (function () {
4 | const DEFAULT_CONFIG = {
5 | columns: 3,
6 | minItems: 3,
7 | minWidth: 200
8 | };
9 |
10 | const config = Object.assign({}, DEFAULT_CONFIG, (window.$docsify && window.$docsify.imgGrid) || {});
11 |
12 | function createImageGrid(images, columns = config.columns, minWidth = config.minWidth) {
13 | const gridContainer = document.createElement('div');
14 | gridContainer.className = 'img-grid';
15 | gridContainer.style.cssText = `
16 | display: flex;
17 | flex-wrap: wrap;
18 | gap: 10px;
19 | justify-content: center;
20 | margin: 1rem 0;
21 | `;
22 |
23 | images.forEach(img => {
24 | const wrapper = document.createElement('div');
25 | wrapper.className = 'img-grid-item';
26 | wrapper.style.cssText = `
27 | flex: 0 1 calc(${100 / columns}% - 10px);
28 | min-width: ${minWidth}px;
29 | `;
30 |
31 | const parentAnchor = img.closest('a');
32 | if (parentAnchor) {
33 | const anchorClone = parentAnchor.cloneNode(false);
34 | const imgClone = img.cloneNode(true);
35 | imgClone.style.cssText = `
36 | width: 100%;
37 | height: 100%;
38 | object-fit: contain;
39 | `;
40 | anchorClone.appendChild(imgClone);
41 | wrapper.appendChild(anchorClone);
42 | } else {
43 | const clone = img.cloneNode(true);
44 | clone.style.cssText = `
45 | width: 100%;
46 | height: 100%;
47 | object-fit: contain;
48 | `;
49 | wrapper.appendChild(clone);
50 | }
51 |
52 | gridContainer.appendChild(wrapper);
53 | });
54 |
55 | return gridContainer;
56 | }
57 |
58 | function processImageLists(content) {
59 | const container = document.createElement('div');
60 | container.innerHTML = content;
61 |
62 | const lists = container.getElementsByTagName('ul');
63 | Array.from(lists).forEach(list => {
64 | const images = Array.from(list.getElementsByTagName('img'));
65 |
66 | if (images.length >= config.minItems && images.length === list.children.length) {
67 | const columns = list.getAttribute('data-columns') || config.columns;
68 | const minWidth = config.minWidth;
69 | const grid = createImageGrid(images, parseInt(columns), minWidth);
70 | list.parentNode.replaceChild(grid, list);
71 | }
72 | });
73 |
74 | return container.innerHTML;
75 | }
76 |
77 | window.$docsify = window.$docsify || {};
78 | window.$docsify.plugins = (window.$docsify.plugins || []).concat(hook => {
79 | hook.afterEach((html, next) => {
80 | next(processImageLists(html));
81 | });
82 | });
83 | })();
84 |
--------------------------------------------------------------------------------
/docs/assets/css/print.css:
--------------------------------------------------------------------------------
1 | /* CSS generated/assisted by Anthropic Claude AI */
2 | @media print {
3 | :root {
4 | --print-body-size: 10pt;
5 | --print-h1-size: 14pt;
6 | --print-h2-size: 12pt;
7 | --print-h3-size: 11pt;
8 | --print-h4-h6-size: 10pt;
9 | --print-code-size: 9pt;
10 | --print-url-size: 8pt;
11 | }
12 |
13 | /* Reset minimum heights to prevent phantom spacing */
14 | * {
15 | min-height: 0 !important;
16 | }
17 |
18 | /* Hide UI elements */
19 | .button-secondary,
20 | .button-rounded,
21 | .button-secondary-rounded,
22 | .edit-link,
23 | .cover,
24 | .skip-link,
25 | .app-nav,
26 | #__sidebar,
27 | aside,
28 | .button,
29 | .github-corner,
30 | .docsify-pagination-container,
31 | .emoji {
32 | display: none !important;
33 | }
34 |
35 | /* Reset layout for print */
36 | body,
37 | main,
38 | .content,
39 | .app,
40 | .markdown-section {
41 | margin: 0 !important;
42 | padding: 0 !important;
43 | width: 100% !important;
44 | max-width: none !important;
45 | transform: none !important;
46 | position: static !important;
47 | }
48 |
49 | body {
50 | font-size: var(--print-body-size);
51 | line-height: 1.4;
52 | }
53 |
54 | * {
55 | background: transparent !important;
56 | color: #000 !important;
57 | box-shadow: none !important;
58 | }
59 |
60 | @page {
61 | margin: 2cm;
62 | }
63 |
64 | /* Typography */
65 | .markdown-section h1 {
66 | font-size: var(--print-h1-size) !important;
67 | page-break-after: avoid;
68 | margin-top: 1.5em;
69 | }
70 |
71 | .markdown-section h2 {
72 | font-size: var(--print-h2-size) !important;
73 | page-break-after: avoid;
74 | margin-top: 1.2em;
75 | }
76 |
77 | .markdown-section h3 {
78 | font-size: var(--print-h3-size) !important;
79 | page-break-after: avoid;
80 | margin-top: 1em;
81 | }
82 |
83 | .markdown-section h4,
84 | .markdown-section h5,
85 | .markdown-section h6 {
86 | font-size: var(--print-h4-h6-size) !important;
87 | page-break-after: avoid;
88 | margin-top: 0.8em;
89 | }
90 |
91 | .markdown-section p,
92 | .markdown-section li,
93 | .markdown-section td,
94 | .markdown-section th {
95 | font-size: var(--print-body-size) !important;
96 | }
97 |
98 | code,
99 | pre {
100 | font-family: monospace;
101 | font-size: var(--print-code-size) !important;
102 | white-space: pre-wrap;
103 | word-wrap: break-word;
104 | }
105 |
106 | /* Page flow */
107 | p,
108 | li {
109 | orphans: 3;
110 | widows: 3;
111 | }
112 |
113 | /* Make columns print-friendly */
114 | .row {
115 | display: flex !important;
116 | page-break-inside: avoid !important;
117 | }
118 |
119 | .column {
120 | flex: 1 !important;
121 | page-break-inside: avoid !important;
122 | break-inside: avoid !important;
123 | }
124 |
125 | img {
126 | max-width: 100% !important;
127 | page-break-inside: avoid;
128 | }
129 |
130 | blockquote,
131 | pre,
132 | table {
133 | page-break-inside: avoid;
134 | }
135 |
136 | /* Tables */
137 | table {
138 | border-collapse: collapse;
139 | width: 100%;
140 | font-size: 0.9em;
141 | }
142 |
143 | th,
144 | td {
145 | border: 1pt solid #ccc;
146 | padding: 4pt;
147 | text-align: left;
148 | vertical-align: top;
149 | }
150 |
151 | /* Links */
152 | a {
153 | color: #000 !important;
154 | text-decoration: underline;
155 | }
156 |
157 | /* External URLs */
158 | a[href^="http"]:after {
159 | content: " (" attr(href) ")";
160 | font-size: var(--print-url-size);
161 | font-style: italic;
162 | }
163 |
164 | .no-print {
165 | display: none !important;
166 | }
167 | }
--------------------------------------------------------------------------------
/docs/resources.md:
--------------------------------------------------------------------------------
1 | # Resources
2 |
3 | ## Reflective Writing
4 | * [A short guide to reflective writing](https://intranet.birmingham.ac.uk/as/libraryservices/library/skills/asc/documents/public/Short-Guide-Reflective-Writing.pdf)
5 | * [How Reflecting On Your Work Can Make You A Better Designer](https://medium.com/center-centre-cohort-01/how-reflecting-on-your-work-can-make-you-a-better-designer-5ce2f3886f51)
6 | * [Online Guide to Reflective Writing](https://nile.northampton.ac.uk/bbcswebdav/pid-1244383-dt-content-rid-3278540_1/courses/Centre-for-Achievement-and-Performance/Skills/Reflective%20Writing/Reflective%20Writing%20-%20Feb%202017.pdf)
7 | * [Reflective Toolbox](http://writeonline.ca/media/documents/ReflectiveToolbox.pdf)
8 | * [Reflective writing: a basic introduction](http://www.port.ac.uk/media/contacts-and-departments/student-support-services/ask/downloads/Reflective-writing---a-basic-introduction.pdf)
9 |
10 | ## UX Platform Guideline Collections
11 | * [Android User Interface Design Guidelines](https://developer.android.com/guide/practices/ui_guidelines/index.html)
12 | * [Google Material Design Guidelines](https://material.google.com/)
13 | * [iOS Human Interface Design Guidelines (iPhone and iPad)](https://developer.apple.com/ios/human-interface-guidelines/)
14 | * [KDE Human Interface Design Guidelines](https://community.kde.org/KDE_Visual_Design_Group/HIG)
15 | * [OS X Human Interface Design Guidelines](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/index.html#//apple_ref/doc/uid/TP40002720-TPXREF101)
16 | * [Windows App Design Guidelines (Touch)](https://msdn.microsoft.com/en-us/library/dn742468.aspx)
17 |
18 | ## UX Templates
19 | * [Contextual Interview Form](http://userfocus.co.uk/pdf/cisheet.pdf)
20 | * [One Page User Research Plan](https://www.smashingmagazine.com/2012/01/ux-research-plan-stakeholders-love/)
21 | * [Templates & Downloadable Documents | Usability.gov](http://www.usability.gov/how-to-and-tools/resources/templates.html)
22 | * [cxpartners | Resources](http://www.cxpartners.co.uk/ux-resources/)
23 | * [The PM Toolkit](http://thepmtoolkit.com/)
24 | * [UX Project Checklist](http://uxchecklist.github.io/)
25 |
26 | ## UX Design Checklists
27 | * [A Checklist for Designing Mobile Input Fields](http://www.nngroup.com/articles/mobile-input-checklist/)
28 | * [Mobile UX Checklist (PDF, by Mobify)](http://downloads.mobify.com.s3.amazonaws.com/ebooks/25-Ways-to-Make-Your-Mobile-E-Commerce-Revenue-Skyrocket-Mobify.pdf)
29 | * [One-Page Touch Interaction Design Checklist (PDF)](https://canvas.sfu.ca/courses/38847/files/folder/Handouts/Touch%20Interaction%20Checklist)
30 | * [Usability checklist (Userium)](https://userium.com/)
31 | * [UX Project Checklist](http://uxchecklist.github.io/)
32 |
33 | ## UX Technique Collections
34 | * [Methods | Usability.gov](http://www.usability.gov/how-to-and-tools/methods/)
35 | * [Methods | Usability Body of Knowledge](http://www.usabilitybok.org/methods)
36 | * [Usability Planner](http://usabilityplanner.org/#home)
37 | * [UX Techniques (by UX Mastery)](http://uxmastery.com/resources/techniques)
38 |
39 | ## UX Article Collections
40 | * [The UX Bookmark](http://www.theuxbookmark.com/)
41 | * [User Experience Magazine (UXPA)](http://uxpamagazine.org/)
42 | * [UI/UX Articles (Medium)](https://medium.com/ui-ux-articles)
43 |
44 | ## UX eBooks
45 | * [50 UX Best Practices by Above the Fold (email address required)](http://www.userexperiencedesigns.com/)
46 | * [Bright Ideas for User Experience Designers](http://www.userfocus.co.uk/ebooks/uxdesign.html)
47 | * [The Fable of the User-Centered Designer](http://www.userfocus.co.uk/fable/)
48 |
49 | ## UX Design MOOCs & Courses
50 | * [Human-Computer Interaction | Coursera](https://www.coursera.org/course/hciucsd)
51 | * [The Design of Everyday Things | Udacity](https://www.udacity.com/course/design101)
52 | * [Rapid Wireframing: Finding the Right Product Design](https://www.skillshare.com/classes/design/Rapid-Wireframing-Finding-the-Right-Product-Design/1947996659)
53 |
54 | ## UX Podcast Collections
55 | * [Design Critique: Products for People](http://designcritique.net/)
56 | * [Podcasts - UIE Brain Sparks](http://www.uie.com/brainsparks/topics/podcasts/)
57 | * [Boagworld Podcast](https://boagworld.com/show/)
58 | * [User Experience Podcast](http://www.infodesign.com.au/uxpod)
59 |
60 | ## UX Video Collections
61 | * [Google Developers Channel](https://www.youtube.com/user/GoogleDevelopers/search?query=user+experience+usability)
62 | * [Interaction Design Association Vimeo Channels](http://vimeo.com/ixdaglobal/channels)
63 | * [NNgroup YouTube Channel](https://www.youtube.com/user/NNgroup/videos)
64 | * [UX Mastery YouTube Channel](https://www.youtube.com/channel/UCXmQyv8sAjmvgCCgvRKi9hw)
65 |
--------------------------------------------------------------------------------
/docs/assets/vendor/docsify/plugins/toc.js:
--------------------------------------------------------------------------------
1 | var defaultOptions = {
2 | headings: 'h1, h2',
3 | scope: '.markdown-section',
4 |
5 | // To make work
6 | title: 'Contents',
7 | listType: 'ul',
8 | }
9 |
10 | // Element builders
11 | var tocHeading = function(Title) {
12 | return document.createElement('h2').appendChild(
13 | document.createTextNode(Title)
14 | )
15 | }
16 |
17 | var aTag = function(src) {
18 | var a = document.createElement('a');
19 | var content = src.firstChild.innerHTML;
20 |
21 | // Use this to clip text w/ HTML in it.
22 | // https://github.com/arendjr/text-clipper
23 | a.innerHTML = content;
24 | a.href = src.firstChild.href;
25 | a.onclick = tocClick
26 |
27 | // In order to remove this gotta fix the styles.
28 | a.setAttribute('class', 'anchor');
29 |
30 | return a
31 | };
32 |
33 | var tocClick = function(e) {
34 | var divs = document.querySelectorAll('.page_toc .active');
35 |
36 | // Remove the previous classes
37 | [].forEach.call(divs, function(div) {
38 | div.setAttribute('class', 'anchor')
39 | });
40 |
41 | // Make sure this is attached to the parent not itself
42 | e.currentTarget.setAttribute('class', 'active')
43 | };
44 |
45 | var createList = function(wrapper, count) {
46 | while (count--) {
47 | if(wrapper){
48 | wrapper = wrapper.appendChild(
49 | document.createElement('ul')
50 | );
51 | }
52 | if (count) {
53 | wrapper = wrapper.appendChild(
54 | document.createElement('li')
55 | );
56 | }
57 | }
58 |
59 | return wrapper;
60 | };
61 |
62 | //------------------------------------------------------------------------
63 |
64 | var getHeaders = function(selector) {
65 | var headings2 = document.querySelectorAll(selector);
66 | var ret = [];
67 |
68 | [].forEach.call(headings2, function(heading) {
69 | ret = ret.concat(heading);
70 | });
71 |
72 | return ret;
73 | };
74 |
75 | var getLevel = function(header) {
76 | var decs = header.match(/\d/g);
77 |
78 | return decs ? Math.min.apply(null, decs) : 1;
79 | };
80 |
81 | var jumpBack = function(currentWrapper, offset) {
82 | while (offset--) {
83 | currentWrapper = currentWrapper.parentElement;
84 | }
85 |
86 | return currentWrapper;
87 | };
88 |
89 | var buildTOC = function(options) {
90 | var ret = document.createElement('ul');
91 | var wrapper = ret;
92 | var lastLi = null;
93 | var selector = options.scope + ' ' + options.headings
94 | var headers = getHeaders(selector).filter(h => h.id);
95 |
96 | headers.reduce(function(prev, curr, index) {
97 | var currentLevel = getLevel(curr.tagName);
98 | var offset = currentLevel - prev;
99 |
100 | wrapper = (offset > 0)
101 | ? createList(lastLi, offset)
102 | : jumpBack(wrapper, -offset * 2)
103 |
104 | wrapper = wrapper || ret;
105 |
106 | var li = document.createElement('li');
107 |
108 | wrapper.appendChild(li).appendChild(aTag(curr));
109 |
110 | lastLi = li;
111 |
112 | return currentLevel;
113 | }, getLevel(options.headings));
114 |
115 | return ret;
116 | };
117 |
118 | // Docsify plugin functions
119 | function plugin(hook, vm) {
120 | var userOptions = vm.config.toc;
121 |
122 | hook.mounted(function () {
123 | var content = window.Docsify.dom.find(".content");
124 | if (content) {
125 | var nav = window.Docsify.dom.create("aside", "");
126 | window.Docsify.dom.toggleClass(nav, "add", "nav");
127 | window.Docsify.dom.before(content, nav);
128 | }
129 | });
130 |
131 | hook.doneEach(function () {
132 | var nav = document.querySelectorAll('.nav')[0]
133 | var t = Array.from(document.querySelectorAll('.nav'))
134 |
135 | if (!nav) {
136 | return;
137 | }
138 |
139 | const toc = buildTOC(userOptions);
140 |
141 | // Just unset it for now.
142 | if (!toc.innerHTML) {
143 | nav.innerHTML = null
144 | return;
145 | }
146 |
147 | // Fix me in the future
148 | var title = document.createElement('p');
149 | title.innerHTML = userOptions.title;
150 | title.setAttribute('class', 'title');
151 |
152 | var container = document.createElement('div');
153 | container.setAttribute('class', 'page_toc');
154 |
155 | container.appendChild(title);
156 | container.appendChild(toc);
157 |
158 | // Existing TOC
159 | var tocChild = document.querySelectorAll('.nav .page_toc');
160 |
161 | if (tocChild.length > 0) {
162 | tocChild[0].parentNode.removeChild(tocChild[0]);
163 | }
164 |
165 | nav.appendChild(container);
166 | });
167 | }
168 |
169 | // Docsify plugin options
170 | window.$docsify['toc'] = Object.assign(defaultOptions, window.$docsify['toc']);
171 | window.$docsify.plugins = [].concat(plugin, window.$docsify.plugins);
172 |
--------------------------------------------------------------------------------
/docs/assets/vendor/docsify/plugins/docsify-fontawesome.js:
--------------------------------------------------------------------------------
1 | /*
2 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
3 | * This devtool is neither made for production nor for readable output files.
4 | * It uses "eval()" calls to create a separate source file in the browser devtools.
5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6 | * or disable the default devtool with "devtool: false".
7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8 | */
9 | /******/ (() => { // webpackBootstrap
10 | /******/ "use strict";
11 | /******/ var __webpack_modules__ = ({
12 |
13 | /***/ "./src/index.js":
14 | /*!**********************!*\
15 | !*** ./src/index.js ***!
16 | \**********************/
17 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
18 |
19 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _plugin_fontawesome__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./plugin-fontawesome */ \"./src/plugin-fontawesome.js\");\n\n\n// if (!window.$docsify) {\n// window.$docsify = {}\n// }\nwindow.$docsify = window.$docsify || {};\nwindow.$docsify.plugins = (window.$docsify.plugins || []).concat(_plugin_fontawesome__WEBPACK_IMPORTED_MODULE_0__.install);\n\n\n//# sourceURL=webpack://docsify-fontawesome/./src/index.js?");
20 |
21 | /***/ }),
22 |
23 | /***/ "./src/plugin-fontawesome.js":
24 | /*!***********************************!*\
25 | !*** ./src/plugin-fontawesome.js ***!
26 | \***********************************/
27 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
28 |
29 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"install\": () => (/* binding */ install)\n/* harmony export */ });\nfunction install(hook) {\n const faRegExp = /:fa[\\w -]+:/gm;\n\n hook.beforeEach(content => {\n let faHtmlRendered = content.replace(faRegExp, function (m, code) {\n console.log('m: ' + m.replace(/:/gi, ''));\n let rendered = ` `;\n return rendered;\n });\n return faHtmlRendered;\n });\n hook.afterEach(function (html, next) {\n let faHtmlRendered = html.replace(faRegExp, function (m, code) {\n console.log('m: ' + m.replace(/:/gi, ''));\n let rendered = ` `;\n return rendered;\n });\n //console.log('faHtmlRendered: '+faHtmlRendered);\n next(faHtmlRendered);\n });\n}\n\n\n//# sourceURL=webpack://docsify-fontawesome/./src/plugin-fontawesome.js?");
30 |
31 | /***/ })
32 |
33 | /******/ });
34 | /************************************************************************/
35 | /******/ // The module cache
36 | /******/ var __webpack_module_cache__ = {};
37 | /******/
38 | /******/ // The require function
39 | /******/ function __webpack_require__(moduleId) {
40 | /******/ // Check if module is in cache
41 | /******/ var cachedModule = __webpack_module_cache__[moduleId];
42 | /******/ if (cachedModule !== undefined) {
43 | /******/ return cachedModule.exports;
44 | /******/ }
45 | /******/ // Create a new module (and put it into the cache)
46 | /******/ var module = __webpack_module_cache__[moduleId] = {
47 | /******/ // no module.id needed
48 | /******/ // no module.loaded needed
49 | /******/ exports: {}
50 | /******/ };
51 | /******/
52 | /******/ // Execute the module function
53 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
54 | /******/
55 | /******/ // Return the exports of the module
56 | /******/ return module.exports;
57 | /******/ }
58 | /******/
59 | /************************************************************************/
60 | /******/ /* webpack/runtime/define property getters */
61 | /******/ (() => {
62 | /******/ // define getter functions for harmony exports
63 | /******/ __webpack_require__.d = (exports, definition) => {
64 | /******/ for(var key in definition) {
65 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
66 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
67 | /******/ }
68 | /******/ }
69 | /******/ };
70 | /******/ })();
71 | /******/
72 | /******/ /* webpack/runtime/hasOwnProperty shorthand */
73 | /******/ (() => {
74 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
75 | /******/ })();
76 | /******/
77 | /******/ /* webpack/runtime/make namespace object */
78 | /******/ (() => {
79 | /******/ // define __esModule on exports
80 | /******/ __webpack_require__.r = (exports) => {
81 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
82 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
83 | /******/ }
84 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
85 | /******/ };
86 | /******/ })();
87 | /******/
88 | /************************************************************************/
89 | /******/
90 | /******/ // startup
91 | /******/ // Load entry module and return exports
92 | /******/ // This entry module can't be inlined because the eval devtool is used.
93 | /******/ var __webpack_exports__ = __webpack_require__("./src/index.js");
94 | /******/
95 | /******/ })()
96 | ;
--------------------------------------------------------------------------------
/docs/assets/css/custom.css:
--------------------------------------------------------------------------------
1 | /*
2 | ===============================================================================================================================
3 | Put your custom CSS in this file.
4 | ===============================================================================================================================
5 | */
6 |
7 | /* CSS to better visually match Docsify pages within Canvas LMS (uncomment to use) */
8 | /*
9 | @import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap');
10 |
11 | body .markdown-section {
12 | font-family: "Lato Extended","Lato","Helvetica Neue",Arial,sans-serif;
13 | line-height: 1.4;
14 | font-size: 16px;
15 | }
16 | */
17 |
18 | /* Link colors to match SFU branding visual styling (uncomment to use) */
19 | /*
20 | :root {
21 | --link-color: #CC0633!important;
22 | --link-text-decoration: none!important;
23 | --link-text-decoration--hover: underline!important;
24 |
25 | --sidebar-name-color: #CC0633!important;
26 | --sidebar-nav-link-color: #757575!important;
27 | --sidebar-nav-link-color--active: #CC0633!important;
28 | --sidebar-nav-link-border-color--active: #CC0633!important;
29 |
30 | --sidebar-nav-pagelink-background--active:
31 | no-repeat 0px center / 5px 6px
32 | linear-gradient(225deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4.25px),
33 | no-repeat 5px center / 5px 6px
34 | linear-gradient(135deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4.25px)!important;
35 | --sidebar-nav-pagelink-background--collapse:
36 | no-repeat 2px calc(50% - 2.5px) / 6px 5px
37 | linear-gradient(45deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4px),
38 | no-repeat 2px calc(50% + 2.5px) / 6px 5px
39 | linear-gradient(135deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4px)!important;
40 | --sidebar-nav-pagelink-background--loaded:
41 | no-repeat 0px center / 5px 6px
42 | linear-gradient(225deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4.25px),
43 | no-repeat 5px center / 5px 6px
44 | linear-gradient(135deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4.25px)!important;
45 |
46 | --navbar-root-color: #757575!important;
47 | --navbar-root-color--active: #CC0633!important;
48 |
49 | --blockquote-border-color: #757b7f!important;
50 |
51 | --pagination-title-color: #CC0633!important;
52 | }
53 | */
54 |
55 | /* Dark mode colours to match SFU branding visual styling for use with light + dark theme (uncomment to use) */
56 | /*
57 | @media (prefers-color-scheme: dark) {
58 | :root {
59 |
60 | --link-color: #EA7688!important;
61 | --link-text-decoration: none!important;
62 | --link-text-decoration--hover: underline!important;
63 |
64 | --sidebar-name-color: #EA7688!important;
65 | --sidebar-nav-link-color: #B2B4B4!important;
66 | --sidebar-nav-link-color--active: #EA7688!important;
67 | --sidebar-nav-link-border-color--active: #EA7688!important;
68 |
69 | --sidebar-nav-pagelink-background--active:
70 | no-repeat 0px center / 5px 6px linear-gradient(225deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4.25px), no-repeat 5px center / 5px 6px linear-gradient(135deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4.25px)!important;
71 | --sidebar-nav-pagelink-background--collapse:
72 | no-repeat 2px calc(50% - 2.5px) / 6px 5px linear-gradient(45deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4px), no-repeat 2px calc(50% + 2.5px) / 6px 5px linear-gradient(135deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4px)!important;
73 | --sidebar-nav-pagelink-background--loaded:
74 | no-repeat 0px center / 5px 6px linear-gradient(225deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4.25px), no-repeat 5px center / 5px 6px linear-gradient(135deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4.25px)!important;
75 |
76 | --navbar-root-color: #B2B4B4!important;
77 | --navbar-root-color--active: #EA7688!important;
78 |
79 | --blockquote-border-color: #757B7F!important;
80 |
81 | --pagination-title-color: #EA7688!important;
82 | }
83 | }
84 | */
85 |
86 | /* CSS to better visually match Docsify pages within Moodle LMS (uncomment to use) */
87 | /*
88 | body .markdown-section {
89 | font-family: system-ui,sans-serif;
90 | line-height: 1.5;
91 | font-size: 15px;
92 | }
93 | */
94 |
95 | /* Link colors to match visual styling of Moodle LMS (uncomment to use) */
96 | /*
97 | :root {
98 | --link-color: #0F6CBF!important;
99 | --link-color--hover: #03005D!important;
100 | --link-text-decoration: none!important;
101 | --link-text-decoration--hover: underline!important;
102 |
103 | --sidebar-name-color: #0F6CBF!important;
104 | --sidebar-nav-link-color--active: #0F6CBF!important;
105 | --sidebar-nav-link-border-color--active: #0F6CBF!important;
106 |
107 | --sidebar-nav-pagelink-background--active:
108 | no-repeat 0px center / 5px 6px
109 | linear-gradient(225deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4.25px),
110 | no-repeat 5px center / 5px 6px
111 | linear-gradient(135deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4.25px)!important;
112 | --sidebar-nav-pagelink-background--collapse:
113 | no-repeat 2px calc(50% - 2.5px) / 6px 5px
114 | linear-gradient(45deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4px),
115 | no-repeat 2px calc(50% + 2.5px) / 6px 5px
116 | linear-gradient(135deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4px)!important;
117 | --sidebar-nav-pagelink-background--loaded:
118 | no-repeat 0px center / 5px 6px
119 | linear-gradient(225deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4.25px),
120 | no-repeat 5px center / 5px 6px
121 | linear-gradient(135deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4.25px)!important;
122 | --navbar-root-color--active: #0F6CBF!important;
123 |
124 | --blockquote-border-color: #0F6CBF!important;
125 |
126 | --pagination-title-color: #0F6CBF!important;
127 | }
128 | */
129 |
130 | /* CSS to better visually match Docsify pages within Sakai LMS (uncomment to use) */
131 | /*
132 | @import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&display=swap');
133 |
134 | body .markdown-section {
135 | font-family: "Open Sans",sans-serif;
136 | line-height: 1.3;
137 | font-size: 14px;
138 | }
139 | */
140 |
141 | /* Link colors to match visual styling of Sakai LMS (uncomment to use) */
142 | /*
143 | :root {
144 | --link-color: #0B1660!important;
145 |
146 | --sidebar-name-color: #0B1660!important;
147 | --sidebar-nav-link-color--active: #0B1660!important;
148 | --sidebar-nav-link-border-color--active: #0B1660!important;
149 |
150 | --sidebar-nav-pagelink-background--active:
151 | no-repeat 0px center / 5px 6px
152 | linear-gradient(225deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4.25px),
153 | no-repeat 5px center / 5px 6px
154 | linear-gradient(135deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4.25px)!important;
155 | --sidebar-nav-pagelink-background--collapse:
156 | no-repeat 2px calc(50% - 2.5px) / 6px 5px
157 | linear-gradient(45deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4px),
158 | no-repeat 2px calc(50% + 2.5px) / 6px 5px
159 | linear-gradient(135deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4px)!important;
160 | --sidebar-nav-pagelink-background--loaded:
161 | no-repeat 0px center / 5px 6px
162 | linear-gradient(225deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4.25px),
163 | no-repeat 5px center / 5px 6px
164 | linear-gradient(135deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4.25px)!important;
165 |
166 | --navbar-root-color--active: #0B1660!important;
167 | --navbar-root-color--active: #0B1660!important;
168 |
169 | --blockquote-border-color: #0B1660!important;
170 |
171 | --pagination-title-color: #0B1660!important;
172 | }
173 | */
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [v1.3.6](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.6)
4 | ### XX/XX/2025
5 |
6 | **Improved:**
7 | * Hide empty rows in responsive tables
8 | * Left align rows in responsive tables
9 | * Version-lock Font Awesome CSS assets
10 |
11 | ## [v1.3.5](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.5)
12 | ### 11/26/2025
13 |
14 | **New:**
15 | * Added sidebar banner image support via HTML image
16 | * Automatic image path resolution for HTML image assets using data-src attribute relative to site base path with fallback support
17 | * Added (long overdue) basic support for printing
18 |
19 | **Improved:**
20 | * Improved support for Docsify configuration settings of 'topMargin'
21 |
22 | **Bugfix:**
23 | * Restored missing content-max-width default
24 |
25 | ## [v1.3.4](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.4)
26 | ### 08/01/2025
27 |
28 | **New:**
29 | * Added CSS Markdown classes to support cards (`card` & `card-rounded`) and responsive card lists (`card-list`)
30 | * Added CSS Markdown classes to support header overlays on full-width images (`header-image-full-width-headings-overlay` and `header-tall-image-full-width-headings-overlay`)
31 | * Added support for topic index using standard links in first paragraph
32 |
33 | **Improved:**
34 | * Updated ReadMe
35 | * Improve visual design of h1 and h2 below top full width image (use HTML tags to keep default styling)
36 |
37 | **Bugfix:**
38 | * Minor CSS fixes
39 |
40 | ## [v1.3.3](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.3)
41 | ### 07/02/2025
42 |
43 | **Improved:**
44 | * Updated to use latest docsify-footnotes plugin (v2.2.1)
45 |
46 | ## [v1.3.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.2)
47 | ### 04/09/2025
48 |
49 | **Bugfix:**
50 | * Set margin instead of padding for images contained in columns
51 |
52 | ## [v1.3.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.1)
53 | ### 03/04/2025
54 |
55 | **Improved:**
56 | * Various minor enhancements to Search plugin
57 | * Adjusted default behaviour of image grid to add needed whitespace (padding) instead of cropping when source images are of different sizes (thanks to a helpful discussion with @davidmalawey)
58 |
59 | **Bugfix:**
60 | * Fixed incorrect theme CSS with regards to image scaling (with thanks and appreciation to @harlows for the PR)
61 |
62 | ## [v1.3.0](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.0)
63 | ### 02/04/2025
64 |
65 | **New:**
66 | * Support for image grid plugin, including customizations (with thanks and appreciation to @gllmAR)
67 | * Include zoom image plugin (not enabled by default)
68 | * Use of Docsify and Docsify Themeable preview build assets for access to upcoming Docsify accessibility enhancements authored by @jhildenbiddle (with thanks and appreciation to John and tested extensively in Docsify-This)
69 |
70 | **Improved:**
71 | * Updated ReadMe
72 | * Updated example custom CSS for Moodle LMS
73 | * Updated to latest stable Docsify 4.x preview build (including Marked 4.2.12)
74 | * Support horizontal scrolling in code blocks
75 | * Adjusted bottom margin for summary elements
76 | * Match Docsify-This CSS with Docsify Starter Kits CSS
77 | * Browser-level image lazy loading via plugin 'docsify-loading' no longer enabled by default to match updated Docsify-This behaviour
78 | * Default search plugin settings adjusted to match Docsify-This
79 |
80 | ## [v1.2.20](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.20)
81 | ### 12/03/2024
82 |
83 | **New:**
84 | * Added default setting of false for `mergeNavbar` to move Navbar items to the top of the Sidebar on smaller screens
85 |
86 | **Improved:**
87 | * Updated CSS with word-wrap for code blocks
88 | * Use of window.matchMedia.addListener replaced with window.matchMedia.addEventListener
89 | * Cleanup HTML
90 | * Update uses of Font Awesome
91 | * Match Docsify-This CSS with Docsify Starter Kits CSS
92 |
93 | **Bugfix:**
94 | * Scroll offset fix (with thanks and appreciation to @rizdaprasetya for the initial code)
95 | * Added missing Prism language files
96 | * Fix formatting conflict with Prism formatted code blocks
97 |
98 | ## [v1.2.19](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.19)
99 | ### 10/09/2024
100 |
101 | **Improved:**
102 | * Minor theme update
103 |
104 | ## [v1.2.18](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.18)
105 | ### 09/03/2024
106 |
107 | **Improved:**
108 | * Updated ReadMe
109 |
110 | ## [v1.2.17](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.17)
111 | ### 07/23/2024
112 |
113 | **Improved:**
114 | * Improve accessibility of Font Awesome icons when used for decorative elements (automatic addition of `aria-hidden` attribute assuming decorative icons)
115 |
116 | **Bugfix:**
117 | * Added indentation for LMS Links items in Docsify Sidebar
118 |
119 | ## [v1.2.16](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.16)
120 | ### 06/24/2024🏒
121 |
122 | **Improved:**
123 | * Adjusted bottom margin for summary elements
124 | * Improved Search plugin results list presentation, including source page title when appropriate
125 |
126 | **Bugfix:**
127 | * Check the global variable 'standalone' when setting externalLinkTarget
128 |
129 | ## [v1.2.15](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.15)
130 | ### 06/03/2024
131 |
132 | **Improved:**
133 | * Added CSS Markdown class to support responsive HTML images `responsive`
134 |
135 | **Bugfix:**
136 | * Added CSS to automatically wrap links that overflow
137 | * Added CSS to automatically wrap code blocks that overflow
138 | * Added CSS to better vertically align 'Edit this Page' emoji and text
139 |
140 | ## [v1.2.14](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.14)
141 | ### 04/29/2024
142 |
143 | **Bugfix:**
144 | * Remove CSS for use with accordion elements with plain details/summary elements
145 |
146 | ## [v1.2.13](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.13)
147 | ### 03/04/2024
148 |
149 | **New:**
150 | * Support for the Browser-level image lazy loading (with thanks and appreciation to @sy-records for the source plugin 'docsify-loading')
151 |
152 | **Improved:**
153 | * Add ability to define custom colors for badges (with thanks to @cmadland for the example use of colored badges)
154 | * Updated ReadMe
155 | * Updated Editor.css file for improved Markdown previews
156 | * Use docsify-loading plugin rather than added Javascript
157 | * Reorganize and update custom assets (as used in Docsify-This)
158 |
159 | **Bugfix:**
160 | * Include missing docsify-footnotes plugin
161 |
162 | ## [v1.2.12](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.12)
163 | ### 02/09/2024
164 |
165 | **New:**
166 | * Added CSS Markdown class for right-aligned columns `column-right`
167 | * Added CSS Markdown class for full width background gradient header image (`header-image-fade-full-width`)
168 |
169 | **Improved:**
170 | * ReadMe updated
171 |
172 | ## [v1.2.11](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.11)
173 | ### 01/18/2024
174 |
175 | **New:**
176 | * Added CSS Markdown class `reverse-columns`
177 | * Added CSS Markdown class for taller full width header image `header-tall-image-full-width`
178 | * Added CSS Markdown class for rounded button `button-rounded`
179 | * Added CSS Markdown classes for secondary buttons `button-secondary` and `button-secondary-rounded`
180 |
181 | **Improved:**
182 | * Improved image alignment with two column layouts
183 | * Improved contrast for unselected Tabs
184 | * Improved support of logo image in Docsify Sidebar
185 | * Adjusted display of full width header image
186 |
187 | ## [v1.2.10](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.10)
188 | ### 11/27/2023
189 |
190 | **Improved:**
191 | * Added 'onedrive.live.com' to domains made responsive through the automatic addition of the CSS Markdown class `video-container-16by9`
192 |
193 | ## [v1.2.9](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.9)
194 | ### 11/15/2023
195 |
196 | **Improved:**
197 | * ReadMe updated
198 |
199 | ## [v1.2.8](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.8)
200 | ### 08/31/2023
201 |
202 | **Improved:**
203 | * ReadMe updated
204 |
205 | ## [v1.2.7](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.7)
206 | ### 08/25/2023
207 |
208 | **Improved:**
209 | * Updated example custom CSS for LMSs
210 | * Cleanup default CSS
211 | * Adjusted badge colours for dark theme
212 | * Use light/dark theme display for topic indexes
213 | * Clarify light + dark theme use comments
214 | * ReadMe updated
215 |
216 | ## [v1.2.6](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.6)
217 | ### 08/15/2023
218 |
219 | **New:**
220 | * Support for nav pill (`navpill`) Markdown CSS class
221 |
222 | **Improved:**
223 | * Added 'youtube-nocookie.com' to domains made responsive through the automatic addition of the CSS Markdown class `video-container-16by9`
224 |
225 | **Improved:**
226 | * ReadMe updated
227 |
228 | ## [v1.2.5](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.5)
229 | ### 06/27/2023
230 |
231 | **Improved:**
232 | * Match Docsify-This Markdown file rendering with Docsify Starter Kits CSS (incl. faded header image ToC adjustments and automatic responsive iFrames for YouTube and Google Docs embeds)
233 |
234 | ## [v1.2.4](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.4)
235 | ### 05/08/2023
236 |
237 | **Improved:**
238 | * Refined responsize header line heights
239 |
240 | ## [v1.2.3](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.3)
241 | ### 04/09/2023
242 |
243 | **Improved:**
244 | * Set font of buttons to sans-serif
245 | * Set font of badges to sans-serif
246 | * Remove unneeded GitHub image file path adjustments
247 | * Refined responsize header font size and line heights
248 |
249 | ## [v1.2.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.2)
250 | ### 03/13/2023
251 |
252 | **Improved:**
253 | * Restore initial header spacing except for alerts and blockquotes
254 | * Remove extra space between Sidebar icons and labels
255 | * ReadMe updated
256 |
257 | ## [v1.2.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.1)
258 | ### 02/13/2023
259 |
260 | **New:**
261 | * Support for images with border and rounded border (`image-border`,`image-border-rounded`)
262 | * Support for 75%, 50% and 25% scaled images with border (`image-75-border`,`image-50-border` and `image-25-border`)
263 |
264 | **Improved:**
265 | * Consolidate and simplify example custom CSS for LMSs
266 | * Additional support and improvements for optional dark mode
267 | * Match Docsify-This CSS with Docsify Starter Kits CSS
268 |
269 | ## [v1.2.0](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.0)
270 | ### 01/02/2023
271 |
272 | **New:**
273 | * Support for 75%, 50% and 25% scaled images (`image-75`,`image-50` and `image-25`)
274 | * Additional languages for Prismjs (Bash, Go, Java, Kotlin, PHP, Python and Swift in addition to the base set https://docsify.js.org/#/language-highlight?id=language-highlighting)
275 |
276 | **Improved:**
277 | * Adjust page margins when content is being embedded
278 | * Adjust margins and padding for alerts and blockquotes
279 | * Increase clickable areas for Topics alphabetical index
280 | * ReadMe updated
281 |
282 | ## [v1.1.4](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.4)
283 | ### 01/17/2023
284 |
285 | **New:**
286 | * Support for optionaly showing the navbar when embedded/standalone (now fully supported with v1.1.2 release)
287 | * Support for displaying a footer ('_footer.md' file) via 'footer' setting in index.html or using the URL parameter 'footer=true'
288 |
289 | **Improved:**
290 | * Adjusted opacity of 'header-image-fade' class for improved accessibility
291 |
292 | **Bugfix:**
293 | * Pass 'navbar' URL parameter for page-to-page navigation links
294 |
295 | ## [v1.1.3](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.3)
296 | ### 12/15/2022
297 |
298 | **New**
299 | * Support for background gradient header image (`header-image-fade`, with thanks to Jamie Adam for original CSS)
300 | * Support for full-width header image (`header-image-full-width`, optional Table of Contents not available)
301 |
302 | **Improved:**
303 | * ReadMe updated
304 |
305 | ## [v1.1.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.2)
306 | ### 11/23/2022
307 |
308 | **Improved:**
309 | * Aligned ToC CSS with Docsify-This.net
310 | * Support for scrolling of Table of Contents
311 | * ReadMe updated
312 | * Removed deprecated emoji plugin (as of Docsify v4.13)
313 | * Support for page-to-page navigation when embedded/standalone
314 | * Changed support for light/dark Themeable theme switching to optional
315 |
316 | ## [v1.1.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.1)
317 | ### 09/02/2022
318 |
319 | **Improved:**
320 | * Reduced page margins when displayed as embedded or standalone
321 | * Adjusted font size and line height for Topics index items
322 | * Added example CSS colours to be the same as Sakai LMS
323 | * Streamlined settings for custom CSS colours
324 | * Simplified 'ToC' setting in index.html
325 | * Reduced left margin of page Table of Contents on smaller screens
326 | * Updated Table of Contents plugin items
327 | * Added Editor.css file for better Markdown previews
328 | * Added new Themeable support for light/dark theme switching (OS-level)
329 | * Adjusted link colours for dark theme
330 |
331 | **Bugfix:**
332 | * Removed unused JS and CSS resources
333 | * Fixed incorrect links in example course content
334 | * Added missing Sidebar name and link colour settings
335 | * Support the removal of the '_sidebar.md' file with standalone setting
336 | * Fixed embedded code blocks overflow issues
337 |
338 | ## [v1.1.0](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.0)
339 | ### 05/30/2022
340 |
341 | **Improved:**
342 | * Aligned default link colour to be the same as Canvas LMS
343 | * Added example link colours to be the same as Moodle LMS
344 | * Adjusted left Markdown section padding
345 | * Adjusted margins for site name in Sidebar
346 | * Added 'standalone' setting in index.html to permanently alter the display of all pages (i.e. hidden Sidebar and Navbar)
347 |
348 | **Bugfix:**
349 | * Fixed 'hidegitlink' URL parameter detection
350 |
351 | ## [v1.0.8](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.8)
352 | ### 03/21/2022
353 |
354 | **Improved:**
355 | * Adjusted link colours for improved contrast
356 |
357 | ## [v1.0.7](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.7)
358 | ### 02/15/2022
359 |
360 | **New:**
361 | * Added conditional display of page table of contents (`?toc=true`)
362 |
363 | **Improved:**
364 | * Restored user zoom ability for improved accessibility
365 | * Revised alt image text for improved accessibility
366 | * Revised JS function `getURLParameterByName` to accept multiple terms (i.e. to support aliases) and also include functionality of previous returnByURLParameterByName function
367 |
368 | **Bugfix:**
369 | * Fixed incorrect H3 headers
370 |
371 | ## [v1.0.6](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.6)
372 | ### 11/15/2021
373 |
374 | **Improved:**
375 | * Adjusted header line heights for improved readability
376 | * Added initial support for responsive font sizing (480px only)
377 | * Improved badge alignment
378 | * Improved text label spacing for buttons
379 | * Removed unneeded embedded check for Pagination Plugin
380 | * Adjusted right margin of navbar to improve alignment
381 | * Removed background colour from accordions to better support a dark theme
382 |
383 | **Bugfix:**
384 | * Added an additional new line before Edit this Page on GitHub links to ensure proper formatting break
385 |
386 | ## [v1.0.5](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.5)
387 | ### 10/15/2021
388 |
389 | **Improved:**
390 | * Relocated images to be within top-level docs folder
391 |
392 | ## [v1.0.4](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.4)
393 | ### 10/05/2021
394 |
395 | **Improved:**
396 | * Added 'Use this Template on GitHub' button on Sidebar
397 | * Changed name of Sidebar page
398 | * Revised Sidebar project links
399 | * Updated example image descriptions
400 | * Adjusted tall banner images for use in multi-course setups
401 |
402 | ## [v1.0.3](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.3)
403 | ### 08/03/2021
404 |
405 | **Improved:**
406 | * Added variable for text of Edit this Page on GitHub links to make modifications easier
407 | * Changed JS function name from `getParameterByName` to `getURLParameterByName` for improved clarity
408 | * Added the new JS function `returnByURLParameterByName` to return one of two values based on URL parameter (e.g. choose external link behaviour based on embedded status)
409 |
410 | ## [v1.0.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.2)
411 | ### 06/16/2021
412 |
413 | **Improved:**
414 | * Adjusted custom list bullet presentation
415 |
416 | ## [v1.0.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.1)
417 | ### 05/30/2021
418 |
419 | **Improved:**
420 | * Changed variable name `yourRepoURL` to `gitLinkRepoURL` for improved clarity
421 |
422 | ## [v1.0.0](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.0)
423 | ### 05/18/2021
424 |
425 | **Improved:**
426 | * ReadMe and screenshot updates
427 | * Changed conditional loading of Pagination script to asynchronous
428 | * Adjusted breakpoint for two column display
429 | * Decreased padding between items in navbar
430 |
431 | **Bugfix:**
432 | * Fixed URL to project ReadMe file
433 |
434 | ## [v1.0.0-preview.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.0-preview.2)
435 | ### 05/10/2021
436 |
437 | **Improved:**
438 | * Moved example Canvas LMS visual style adjustments from index.html to custom.css file
439 | * Adjusted CSS of Headers for improved line wrapping
440 | * Adjusted root base line height to increase lines in Sidebar
441 | * Renamed 'responsive-wrap' class to 'responsive-container' for improved consistency
442 | * Changed default external target link to '_top'
443 | * Updated example styling for matching Docsify pages within Canvas LMS
444 | * Increased padding below custom navbar to support more menu items
445 | * Adjusted header sizes and margins
446 | * List and button style updates
447 | * Updated GitHub repo URL config and documentation
448 | * Relocated embedly script to index.html file
449 |
450 | **Bugfix:**
451 | * Fixed label colour for linked badges
452 | * Consistent hover behaviour for linked badges and buttons
453 |
454 | ## [v1.0.0-preview.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.0-preview.1)
455 | ### 05/04/2021
456 |
457 | **New:**
458 | * Welcome to the preview release of Docsify Open Course Starter Kit!
459 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Docsify Open Course Starter Kit
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
96 |
97 |
98 |
99 |
100 |
101 |
437 |
438 |
439 |
440 |
441 |
442 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Docsify Open Course Starter Kit
2 |
3 | [](https://docsify.js.org/)
4 | [](https://github.com/hibbitts-design/docsify-open-course-starter-kit/blob/main/LICENSE)
5 |
6 |
7 |
8 |
9 |
10 | > This is a starter kit to quickly create a Markdown-based open course site with the site generator [Docsify](https://docsify.js.org). Global navigation elements can be hidden for seamlessly embedding pages (i.e., into an LMS). Includes an optional "Edit this Page" link.
11 |
12 | Docsify sites use client-side rendering, which means your content will not be indexed by search engines like Google, Bing, or DuckDuckGo.
13 |
14 | 📸 Docsify Open Course Screenshots
15 | ---
16 | 
17 | _Figure 1. Docsify Open Course Starter Kit. Explore a demo at [hibbitts-design.github.io/demo-docsify-open-course-starter-kit/](https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/)_
18 |
19 | 🚀 GitHub Pages Quickstart
20 | ---
21 | **Pre-flight Checklist**
22 |
23 | 1. GitHub account
24 |
25 | **Installation and Deployment**
26 |
27 | 1. Sign in to [GitHub](https://github.com) if you have not already done so
28 |
29 | 2. Tap **Use this template** on the source repository (upper-right green button) and then choose **Create a new repository**
30 | 
31 |
32 | 3. Choose the name for your new repository to contain the copied site files and then tap **Create repository from template**
33 | 
34 |
35 | 4. Go to **Settings** of your newly created repository, tap the **Pages** tab (on the left-hand side), choose **main branch**, then **docs folder** and finally tap the **Save** button (see more details in the [Docsify documentation](https://docsify.js.org/#/deploy?id=github-pages))
36 | 
37 |
38 | 5. And you're done! (view your new site using the provided URL on the **Pages** tab - it can take up to 10 minutes for your site to be initially available)
39 | 
40 |
41 | Do you use GitLab? You can also use Docsify with [GitLab Pages](https://docsify.js.org/#/deploy?id=gitlab-pages)!
42 |
43 | ✏️ Editing Your Docsify Site Pages on GitHub
44 | ---
45 |
46 | 1. Go to the Docsify Markdown (.md) page in the `docs` folder of your repository you want to edit
47 | 
48 |
49 | 2. Tap the **Pencil Icon** (top left-hand toolbar area) to start the editor
50 | 
51 |
52 | 3. Scroll down to the bottom of the page and tap the **Commit changes** button to save your changes
53 | 
54 |
55 | [Learn more about creating pages in Docsify.](https://docsify.js.org/#/more-pages)
56 |
57 | 🔗 Activating the “Edit this Page” Link on Your Docsify Site
58 | ---
59 |
60 | 1. At the top-level of your GitHub Repository copy the URL
61 | 
62 |
63 | 2. Tap on the **docs** folder
64 | 
65 |
66 | 2. Tap on the **index.html** file
67 | 
68 |
69 | 3. Tap the **Pencil Icon** (top left-hand toolbar area) to start the editor
70 | 
71 |
72 | 4. Find the line `var gitLinkRepoURL = '';` and enter the URL of your own GitHub Repository between the two quotes (replace `github.com` with `github.dev` to use the GitHub.dev web-based editor currently in Beta) and then scroll down to the bottom of the page and tap the **Commit changes** button to save your changes
73 | 
74 |
75 | To remove the “Edit this Page” link on your Docsify site, restore the value of `gitLinkRepoURL` to `''`.
76 |
77 | 💻 Locally Editing Your Docsify Site Pages
78 | ---
79 |
80 | **Editing Your Docsify Site Pages on Your Desktop**
81 | 1. Tap **Code** on your repository (upper-right green button)
82 | 2. Choose **Open Desktop** and follow the prompts, installing [GitHub Desktop](https://desktop.github.com/) if not already present
83 | 3. You will now be able to edit your Docsify site (in the `docs` folder) using the desktop editor of your choice (e.g. [Atom](https://atom.io/))
84 | 4. Use GitHub Desktop to push any changes to your repository.
85 |
86 | [Learn more about using GitHub Desktop](https://help.github.com/en/desktop/contributing-to-projects/committing-and-reviewing-changes-to-your-project).
87 |
88 | You can also clone (i.e download) a copy of your repository to your computer and [run Docsify locally](https://docsify.js.org/#/quickstart) to preview your site. See the below video for details.
89 |
90 | 🧩 Embedding your Docsify Page Content into Other Systems
91 | ---
92 |
93 | 
94 | _Figure 2. Docsify Open Course Page Embedded into the Canvas LMS. Explore an example Canvas LMS course using Docsify Open Course pages for content at [https://canvas.sfu.ca/courses/44038/](https://canvas.sfu.ca/courses/44038)_
95 |
96 | The optional `embedded` (all lowercase) URL parameter hides a site’s sidebar for seamlessly embedding Docsify page content within another platform such as Canvas LMS, Moodle, Microsoft Teams or being displayed in an existing or new Browser tab. The parameter `standalone` is supported as an alias for `embedded`.
97 |
98 | To only display Docsify page content, add the following to a Docsify page URL:
99 |
100 | `?embedded=true`
101 |
102 | Example standard Docsify page:
103 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources
104 |
105 | Example Docsify page displaying only page content (i.e., no sidebar is shown):
106 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true
107 |
108 | To optionally show a page Table of Contents (based on included Headers), use the following:
109 |
110 | `?embedded=true&toc=true`
111 |
112 | Example Docsify page displaying only page content:
113 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true
114 |
115 | Example Docsify page displaying only page content with a page Table of Contents included:
116 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true&toc=true
117 |
118 | To optionally override the hiding of the navbar when displaying only page content, use the following:
119 |
120 | `?embedded=true&navbar=true`
121 |
122 | Example Docsify page displaying only page content:
123 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true
124 |
125 | Example Docsify page displaying only page content with the navbar still displayed:
126 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true&navbar=true
127 |
128 | To optionally hide the 'Edit this Page' link, use the following:
129 |
130 | `?embedded=true&hidegitlink=true`
131 |
132 | Example Docsify page displaying only page content:
133 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true
134 |
135 | Example Docsify page displaying only page content with the 'Edit this Page' link hidden:
136 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true&hidegitlink=true
137 |
138 | To optionally show the footer ('_footer.md' file), use the following:
139 |
140 | `?embedded=true&footer=true`
141 |
142 | Example Docsify page without footer:
143 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true
144 |
145 | Example Docsify page with footer shown:
146 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true&footer=true
147 |
148 | 🖼 Presenting your Docsify Page Content as Standalone Webpages
149 | ---
150 |
151 | In addition to using URL parameters when embedding Docsify page content into other systems, it is possible to permanently display all pages as standalone, and to also always display a page Table of Contents.
152 |
153 | **To Display all Pages as Standalone**
154 | 1. Open the `index.html` file for editing.
155 | 2. Locate the line `var standalone = false;` and change it to `var standalone = true;`.
156 | 3. Save the `index.html` file and reload site.
157 |
158 | **To Display Page Table of Contents**
159 | 1. Open the `index.html` file for editing.
160 | 2. Locate the line `var ToC = false;` and change it to `var showToC = true;`.
161 | 3. Save the `index.html` file and reload site.
162 |
163 | Please note a page must have a series of Headings (#, ##, ###) for the Table of Contents to be displayed correctly.
164 |
165 | ❛❜ Setting the Name of your Docsify Site
166 | ---
167 |
168 | 1. Open the `index.html` file for editing.
169 | 2. Locate the line `Docsify Open Course Starter Kit ` and change the text between the title tags to be displayed as the site name on the Browser tab
170 | 3. Locate the line `name: 'Docsify Open Course Starter Kit',` and change the text between the quotes to be displayed as the site name at the top of the Docsify Sidebar
171 | 4. Save the `index.html` file and reload site.
172 |
173 | ⚠️ Troubleshooting
174 | ---
175 | _Site not displaying on GitHub Pages_
176 | The most likely cause of not seeing your Docsify site on GitHub Pages is that the 'docs' folder is not selected as the source folder. Go to **Settings** of your repository, tap the **Pages** tab (on the left-hand side), choose **main branch**, then **docs folder** and finally tap the **Save** button.
177 |
178 | 🛠 Using an LMS to Host a Docsify Open Course Site
179 | ---
180 |
181 | As Docsify Open Course Starter Kit does not require a web server, it can actually be hosted on many LMSs that support file libraries such as Canvas and Moodle.
182 |
183 | For example, here is a [Docsify Open Course Site hosted within a Canvas course](https://canvas.sfu.ca/courses/44038/files/15884796/download). Single Docsify Open Course site pages can also be embedded while hosted on the same system.
184 |
185 | **Hosting a Docsify Open Course Site on your LMS**
186 | 1. Tap **Download** on your repository page
187 | 2. Upload to your LMS file storage area, and unzip the upload file
188 | 3. Based on your LMS, determine the external URL required to load the `index.html` file within the Docsify `Docs` folder. In Canvas, an example URL would look similar to `https://canvas.sfu.ca/courses/44038/files/15884796/download`.
189 |
190 | | :warning: | Once hosted within your LMS, changes made to the source GitHub repository are no longer automatically reflected on your hosted Docsify site. Any GitHub repository updates must be manually uploaded to the LMS file library area. |
191 | |---|:--|
192 |
193 | 📚 Docsify and Markdown Resources
194 | ---
195 | **Docsify**
196 | [Docsify Documentation](https://docsify.js.org/#/?id=docsifyg)
197 | [Docsify Basics by MichaelCurrin](https://michaelcurrin.github.io/docsify-js-tutorial/#/?id=docsify-basics)
198 |
199 | **Docsify Themable**
200 | [Docsify Themeable Documentation](https://jhildenbiddle.github.io/docsify-themeable/#/introduction)
201 | [Docsify Themeable GitHub](https://github.com/jhildenbiddle/docsify-themeable)
202 |
203 | **Markdown**
204 | [Markdown Here Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Here-Cheatsheet)
205 | [Markdown Guide](https://www.markdownguide.org/)
206 |
207 | 💡 Content Display Tips and Techniques
208 | ---
209 | **Including Code Blocks**
210 | Using [Prismjs](https://prismjs.com/) code blocks with syntax highlighting is supported for the languages [included with Docsify](https://docsify.js.org/#/language-highlight?id=language-highlighting) and as well Bash, Go, Java, Kotlin, PHP, Python and Swift. To embed a code block use the Markdown standard of triple backticks and start the block with the name of the language, for example to embed a block of Javascript code with syntax highlight the following would be used:
211 |
212 |
213 | ```javascript
214 | function test() {
215 | console.log("Hello world!");
216 | }
217 | ```
218 |
219 | Which would then appear as:
220 | ```javascript
221 | function test() {
222 | console.log("Hello world!");
223 | }
224 | ```
225 |
226 | **Displaying Images in a Grid**
227 | 3 or more images can be transformed into a responsive grid gallery by including them in lists. For example:
228 | ```markdown
229 | - 
230 | - 
231 | - 
232 | ```
233 |
234 | 🧰 Useful Markdown CSS Classes
235 | ---
236 |
237 | `accordion`
238 |
239 | ```html
240 |
241 |
242 |
243 | Topic One
244 |
245 | Topic one details here.
246 |
247 |
248 |
249 |
250 | Topic Two
251 |
252 | Topic two details here.
253 |
254 |
255 |
256 |
257 | ```
258 |
259 | `badge`
260 |
261 | ```html
262 | Tue Jun 12th 11:59pm PDT
263 | ```
264 |
265 | ```html
266 | Tue Jun 12th 11:59pm PDT
267 | ```
268 |
269 | ```html
270 | Tue Jun 12th 11:59pm PDT
271 | ```
272 |
273 | ```html
274 | [Tue May 16 2:30pm PT](https://www.timeanddate.com/worldclock/fixedtime.html?msg=CMPT-363+Blackboard+Mini-lectures+and+Activities&iso=20220516T1430&p1=256&ah=1&am=50)
275 | ```
276 |
277 | `banner-image` (cropped to height of 250px on large screens, 125px on small screens)
278 |
279 | ```markdown
280 | 
281 | ```
282 |
283 | `banner-tall-image` (cropped to height of 350px on large screens, 175px on small screens)
284 |
285 | ```markdown
286 | 
287 | ```
288 |
289 | `button`
290 |
291 | ```markdown
292 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button')
293 | ```
294 |
295 | `button-rounded`
296 |
297 | ```markdown
298 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button-rounded')
299 | ```
300 |
301 | `button-secondary`
302 |
303 | ```markdown
304 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button-secondary')
305 | ```
306 |
307 | `button-rounded-secondary`
308 |
309 | ```markdown
310 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button-rounded-secondary')
311 | ```
312 |
313 | `card`
314 |
315 | ```html
316 |
317 |
318 | ## [Card Title](#)
319 | 
320 | Card content goes here.
321 |
322 |
323 | ```
324 |
325 | `card-list`
326 |
327 | ```html
328 |
329 |
330 |
331 | ## [Blog Post Title Link](#)
332 | 
333 |
334 | Blog post preview text goes here with more details about the content.
335 |
336 | Jan 1, 1970.
337 |
338 | [Read More](# ":class=navpill")
339 |
340 |
341 |
342 |
343 | ## [Another Blog Post](#)
344 | 
345 |
346 | Another blog post preview with different content.
347 |
348 | Jan 1, 1970.
349 |
350 | [Read More](# ":class=navpill")
351 |
352 |
353 |
354 | ```
355 |
356 | `card-rounded`
357 |
358 | ```html
359 |
360 |
361 | ## [Card Title](#)
362 | 
363 | Card content goes here.
364 |
365 |
366 | ```
367 |
368 | `embedly-card` (for linked article previews, embedded slides/videos, etc.)
369 |
370 | ```markdown
371 | Defining usability
372 | ```
373 |
374 | `header-image-fade` (suggested width of 1200px to 2000px)
375 |
376 | ```markdown
377 | 
378 | ```
379 |
380 | `header-image-fade-full-width` (suggested size of 1200px to 2000px, and display of Table of Contents is not available)
381 |
382 | ```markdown
383 | 
384 | ```
385 |
386 | `header-image-full-width` (suggested size of 1200px to 2000px width and 400px to 600px height, and display of Table of Contents is not available)
387 |
388 | ```markdown
389 | 
390 | ```
391 |
392 | `header-tall-image-full-width` (suggested size of 1200px to 2000px width and 400px to 600px height, and display of Table of Contents is not available)
393 |
394 | ```markdown
395 | 
396 | ```
397 |
398 | `header-image-full-width-headings-overlay` (Suggested size of 1200px to 2000px width and 400px to 600px height, and display of Table of Contents is not available)
399 |
400 | ```markdown
401 | 
402 |
403 | # Page Title
404 | ```
405 |
406 | `header-tall-image-full-width-headings-overlay` (Suggested size of 1200px to 2000px width and 400px to 600px height, and display of Table of Contents is not available)
407 |
408 | ```markdown
409 | 
410 |
411 | # Page Title
412 | ```
413 |
414 | `image-75` (scale image to 75%)
415 |
416 | ```markdown
417 | 
418 | ```
419 |
420 | `image-50` (scale image to 50%)
421 |
422 | ```markdown
423 | 
424 | ```
425 |
426 | `image-25` (scale image to 25%)
427 |
428 | ```markdown
429 | 
430 | ```
431 |
432 | `image-75-border`
433 |
434 | ```markdown
435 | 
436 | ```
437 |
438 | `image-50-border`
439 |
440 | ```markdown
441 | 
442 | ```
443 |
444 | `image-25-border`
445 |
446 | ```markdown
447 | 
448 | ```
449 |
450 | `image-border`
451 |
452 | ```markdown
453 | 
454 | ```
455 |
456 | `image-border-rounded`
457 |
458 | ```markdown
459 | 
460 | ```
461 |
462 | `navpill`
463 |
464 | ```markdown
465 | [GitHub](https://github.com/hibbitts-design/docsify-this ':class=navpill')
466 | ```
467 |
468 | ```html
469 | GitHub
470 | ```
471 |
472 | `responsive`
473 |
474 | ```html
475 |
476 | ```
477 |
478 | `row` & `column`
479 |
480 | ```html
481 |
482 |
483 |
484 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
485 |
486 |
487 |
488 |
489 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
490 |
491 |
492 |
493 | ```
494 |
495 | ```html
496 |
497 |
498 |
499 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
500 |
501 |
502 |
503 |
504 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
505 |
506 |
507 |
508 | ```
509 |
510 | ```html
511 |
512 |
513 |
514 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
515 |
516 |
517 |
518 |
519 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
520 |
521 |
522 |
523 | ```
524 |
525 | `video-container-4by3`
526 |
527 | ```html
528 | VIDEO
529 | ```
530 |
531 | `video-container-16by9`
532 | Automatically added to all iFrames with the source domains 'youtube.com' or 'docs.google.com'.
533 | ```html
534 |
VIDEO
535 | ```
536 |
537 | 🎨 Visual Customization
538 | ---
539 |
540 | A Docsify Open Course Starter Kit site can be visually customized using CSS within the `custom.css` file located in the folder `docs/assets/css`. Using this file new Markdown CSS classes can be defined.
541 |
542 | CSS:
543 | ```css
544 | .markdown-section .mybutton, .markdown-section .mybutton:hover {
545 | cursor: pointer;
546 | color: #CC0000;
547 | height: auto;
548 | display: inline-block;
549 | border: 2px solid #CC0000;
550 | border-radius: 4rem;
551 | margin: 2px 0px 2px 0px;
552 | padding: 8px 18px 8px 18px;
553 | line-height: 1.2rem;
554 | background-color: white;
555 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
556 | font-weight: bold;
557 | text-decoration: none;
558 | }
559 | ```
560 |
561 | Markdown:
562 | ```markdown
563 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=mybutton')
564 | ```
565 |
566 | [Docsify Themeable CSS settings](https://jhildenbiddle.github.io/docsify-themeable/#/customization?id=base) can also be configured, as seen in the examples provided in the default `custom.css` file.
567 |
568 | CSS:
569 | ```css
570 | :root {
571 | --link-color: #0F6CBF!important;
572 | }
573 | */
574 | ```
575 |
576 | It is also possible for dual CSS styling to be configured, with CSS applied to when viewing the site (with overriding custom CSS included in a `STYLE` tag in the `_sidebar.md` file) and then other CSS settings within the `custom.css` file applied to when viewing standalone pages (i.e. `?embedded=true`)
577 |
578 | CSS in Sidebar file (`_sidebar.md`):
579 | ```css
580 |
587 | ```
588 |
589 | 🌐 Using MAMP to View Docsify Sites Locally
590 | ---
591 |
592 | An alternative to installing Docsify locally (as described following this section) is to use MAMP to view your Docsify sites locally on your own computer.
593 |
594 | 1. Download [MAMP](https://www.mamp.info/)
595 | 2. Move your local Docsify site to the **htdocs** folder of MAMP
596 | 3. Turn MAMP on, tap **WebStart** and then tap **My Website**
597 | 4. Tap on the folder containing your local Docsify site and then tap on the **docs** folder
598 |
599 | 📼 Video Walkthrough of Local Docsify Install/Config
600 | ---
601 | [](https://www.youtube.com/watch?v=TV88lp7egMw)
602 | _Video 1. Generating Documentation Sites with GitHub and Docsify - Alysson Alvaran_
603 |
604 | 🙇Credits and Special Thanks
605 | ---
606 | [Docsify Themeable](https://github.com/jhildenbiddle/docsify-themeable)
607 |
--------------------------------------------------------------------------------
/docs/assets/vendor/themeable/docsify-themeable.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * docsify-themeable
3 | * v0.9.0
4 | * https://jhildenbiddle.github.io/docsify-themeable/
5 | * (c) 2018-2024 John Hildenbiddle
6 | * MIT license
7 | */
8 | !function(){"use strict";function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t
1&&void 0!==arguments[1]?arguments[1]:{},n={mimeType:t.mimeType||null,onBeforeSend:t.onBeforeSend||Function.prototype,onSuccess:t.onSuccess||Function.prototype,onError:t.onError||Function.prototype,onComplete:t.onComplete||Function.prototype},r=Array.isArray(e)?e:[e],o=Array.apply(null,Array(r.length)).map((function(e){return null}));function s(e){var t="string"==typeof e,n=t&&"<"===e.trim().charAt(0);return t&&!n}function a(e,t){n.onError(e,r[t],t)}function c(e,t){var s=n.onSuccess(e,r[t],t);e=!1===s?"":s||e,o[t]=e,-1===o.indexOf(null)&&n.onComplete(o)}var i=document.createElement("a");r.forEach((function(e,t){if(i.setAttribute("href",e),i.href=String(i.href),Boolean(document.all&&!window.atob)&&i.host.split(":")[0]!==location.host.split(":")[0]){if(i.protocol===location.protocol){var r=new XDomainRequest;r.open("GET",e),r.timeout=0,r.onprogress=Function.prototype,r.ontimeout=Function.prototype,r.onload=function(){var e=r.responseText;s(e)?c(e,t):a(r,t)},r.onerror=function(e){a(r,t)},setTimeout((function(){r.send()}),0)}else console.warn("Internet Explorer 9 Cross-Origin (CORS) requests must use the same protocol (".concat(e,")")),a(null,t)}else{var o=new XMLHttpRequest;o.open("GET",e),n.mimeType&&o.overrideMimeType&&o.overrideMimeType(n.mimeType),n.onBeforeSend(o,e,t),o.onreadystatechange=function(){if(4===o.readyState){var e=o.responseText;o.status<400&&s(e)||0===o.status&&s(e)?c(e,t):a(o,t)}},o.send()}}))}function r(e){var t={cssComments:/\/\*[\s\S]+?\*\//g,cssImports:/(?:@import\s*)(?:url\(\s*)?(?:['"])([^'"]*)(?:['"])(?:\s*\))?(?:[^;]*;)/g},r={rootElement:e.rootElement||document,include:e.include||'style,link[rel="stylesheet"]',exclude:e.exclude||null,filter:e.filter||null,skipDisabled:!1!==e.skipDisabled,useCSSOM:e.useCSSOM||!1,onBeforeSend:e.onBeforeSend||Function.prototype,onSuccess:e.onSuccess||Function.prototype,onError:e.onError||Function.prototype,onComplete:e.onComplete||Function.prototype},s=Array.apply(null,r.rootElement.querySelectorAll(r.include)).filter((function(e){return t=e,n=r.exclude,!(t.matches||t.matchesSelector||t.webkitMatchesSelector||t.mozMatchesSelector||t.msMatchesSelector||t.oMatchesSelector).call(t,n);var t,n})),a=Array.apply(null,Array(s.length)).map((function(e){return null}));function c(){if(-1===a.indexOf(null)){a.reduce((function(e,t,n){return""===t&&e.push(n),e}),[]).reverse().forEach((function(e){return[s,a].forEach((function(t){return t.splice(e,1)}))}));var e=a.join("");r.onComplete(e,a,s)}}function i(e,t,n,o){var s=r.onSuccess(e,n,o);l(e=void 0!==s&&!1===Boolean(s)?"":s||e,n,o,(function(e,o){null===a[t]&&(o.forEach((function(e){return r.onError(e.xhr,n,e.url)})),!r.filter||r.filter.test(e)?a[t]=e:a[t]="",c())}))}function u(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],s={};return s.rules=(e.replace(t.cssComments,"").match(t.cssImports)||[]).filter((function(e){return-1===r.indexOf(e)})),s.urls=s.rules.map((function(e){return e.replace(t.cssImports,"$1")})),s.absoluteUrls=s.urls.map((function(e){return o(e,n)})),s.absoluteRules=s.rules.map((function(e,t){var r=s.urls[t],a=o(s.absoluteUrls[t],n);return e.replace(r,a)})),s}function l(e,t,o,s){var a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],c=arguments.length>5&&void 0!==arguments[5]?arguments[5]:[],i=u(e,o,c);i.rules.length?n(i.absoluteUrls,{onBeforeSend:function(e,n,o){r.onBeforeSend(e,t,n)},onSuccess:function(e,n,o){var s=r.onSuccess(e,t,n),a=u(e=!1===s?"":s||e,n,c);return a.rules.forEach((function(t,n){e=e.replace(t,a.absoluteRules[n])})),e},onError:function(n,r,u){a.push({xhr:n,url:r}),c.push(i.rules[u]),l(e,t,o,s,a,c)},onComplete:function(n){n.forEach((function(t,n){e=e.replace(i.rules[n],t)})),l(e,t,o,s,a,c)}}):s(e,a)}s.length?s.forEach((function(e,t){var s=e.getAttribute("href"),u=e.getAttribute("rel"),l="link"===e.nodeName.toLowerCase()&&s&&u&&-1!==u.toLowerCase().indexOf("stylesheet"),d=!1!==r.skipDisabled&&e.disabled,f="style"===e.nodeName.toLowerCase();if(l&&!d)if(-1!==s.indexOf("data:text/css")){var m=decodeURIComponent(s.substring(s.indexOf(",")+1));r.useCSSOM&&(m=Array.apply(null,e.sheet.cssRules).map((function(e){return e.cssText})).join("")),i(m,t,e,location.href)}else n(s,{mimeType:"text/css",onBeforeSend:function(t,n,o){r.onBeforeSend(t,e,n)},onSuccess:function(n,r,a){var c=o(s);i(n,t,e,c)},onError:function(n,o,s){a[t]="",r.onError(n,e,o),c()}});else if(f&&!d){var p=e.textContent;r.useCSSOM&&(p=Array.apply(null,e.sheet.cssRules).map((function(e){return e.cssText})).join("")),i(p,t,e,location.href)}else a[t]="",c()})):r.onComplete("",[])}function o(e,t){var n=document.implementation.createHTMLDocument(""),r=n.createElement("base"),o=n.createElement("a");return n.head.appendChild(r),n.body.appendChild(o),r.href=t||document.baseURI||(document.querySelector("base")||{}).href||location.href,o.href=e,o.href}var s=a;function a(e,t,n){e instanceof RegExp&&(e=c(e,n)),t instanceof RegExp&&(t=c(t,n));var r=i(e,t,n);return r&&{start:r[0],end:r[1],pre:n.slice(0,r[0]),body:n.slice(r[0]+e.length,r[1]),post:n.slice(r[1]+t.length)}}function c(e,t){var n=t.match(e);return n?n[0]:null}function i(e,t,n){var r,o,s,a,c,i=n.indexOf(e),u=n.indexOf(t,i+1),l=i;if(i>=0&&u>0){if(e===t)return[i,u];for(r=[],s=n.length;l>=0&&!c;)l==i?(r.push(l),i=n.indexOf(e,l+1)):1==r.length?c=[r.pop(),u]:((o=r.pop())=0?i:u;r.length&&(c=[s,a])}return c}function u(e){var n=t({},{preserveStatic:!0,removeComments:!1},arguments.length>1&&void 0!==arguments[1]?arguments[1]:{});function r(e){throw new Error("CSS parse error: ".concat(e))}function o(t){var n=t.exec(e);if(n)return e=e.slice(n[0].length),n}function a(){return o(/^{\s*/)}function c(){return o(/^}/)}function i(){o(/^\s*/)}function u(){if(i(),"/"===e[0]&&"*"===e[1]){for(var t=2;e[t]&&("*"!==e[t]||"/"!==e[t+1]);)t++;if(!e[t])return r("end of comment is missing");var n=e.slice(2,t);return e=e.slice(t+2),{type:"comment",comment:n}}}function l(){for(var e,t=[];e=u();)t.push(e);return n.removeComments?[]:t}function d(){for(i();"}"===e[0];)r("extra closing bracket");var t=o(/^(("(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[^{])+)/);if(t){var n,s=t[0].trim();/\/\*/.test(s)&&(s=s.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g,""));var a=/["']\w*,\w*["']/.test(s);return a&&(s=s.replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g,(function(e){return e.replace(/,/g,"")}))),n=/,/.test(s)?s.split(/\s*(?![^(]*\)),\s*/):[s],a&&(n=n.map((function(e){return e.replace(/\u200C/g,",")}))),n}}function f(){if("@"===e[0])return v();o(/^([;\s]*)+/);var t=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,n=o(/^(\*?[-#/*\\\w.]+(\[[0-9a-z_-]+\])?)\s*/);if(n){if(n=n[0].trim(),!o(/^:\s*/))return r("property missing ':'");var s=o(/^((?:\/\*.*?\*\/|'(?:\\'|.)*?'|"(?:\\"|.)*?"|\((\s*'(?:\\'|.)*?'|"(?:\\"|.)*?"|[^)]*?)\s*\)|[^};])+)/),a={type:"declaration",property:n.replace(t,""),value:s?s[0].replace(t,"").trim():""};return o(/^[;\s]*/),a}}function m(){if(!a())return r("missing '{'");for(var e,t=l();e=f();)t.push(e),t=t.concat(l());return c()?t:r("missing '}'")}function p(){i();for(var e,t=[];e=o(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/);)t.push(e[1]),o(/^,\s*/);if(t.length)return{type:"keyframe",values:t,declarations:m()}}function v(){if(i(),"@"===e[0]){var t=function(){var e=o(/^@(import|charset|namespace)\s*([^;]+);/);if(e)return{type:e[1],name:e[2].trim()}}()||function(){if(o(/^@font-face\s*/))return{type:"font-face",declarations:m()}}()||function(){var e=o(/^@media([^{]+)*/);if(e)return{type:"media",media:(e[1]||"").trim(),rules:y()}}()||function(){var e=o(/^@([-\w]+)?keyframes\s*/);if(e){var t=e[1];if(!(e=o(/^([-\w]+)\s*/)))return r("@keyframes missing name");var n,s=e[1];if(!a())return r("@keyframes missing '{'");for(var i=l();n=p();)i.push(n),i=i.concat(l());return c()?{type:"keyframes",name:s,vendor:t,keyframes:i}:r("@keyframes missing '}'")}}()||function(){var e=o(/^@supports *([^{]+)/);if(e)return{type:"supports",supports:e[1].trim(),rules:y()}}()||function(){var e=o(/^@([-\w]+)?document *([^{]+)/);if(e)return{type:"document",document:e[2].trim(),vendor:e[1]?e[1].trim():null,rules:y()}}()||function(){var e=o(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);if(e)return{type:"custom-media",name:e[1].trim(),media:e[2].trim()}}()||function(){if(o(/^@host\s*/))return{type:"host",rules:y()}}()||function(){if(o(/^@page */))return{type:"page",selectors:d()||[],declarations:m()}}()||function(){var e=o(/@(top|bottom|left|right)-(left|center|right|top|middle|bottom)-?(corner)?\s*/);if(e)return{type:"page-margin-box",name:"".concat(e[1],"-").concat(e[2])+(e[3]?"-".concat(e[3]):""),declarations:m()}}();if(t&&!n.preserveStatic){var s=!1;if(t.declarations)s=t.declarations.some((function(e){return/var\(/.test(e.value)}));else s=(t.keyframes||t.rules||[]).some((function(e){return(e.declarations||[]).some((function(e){return/var\(/.test(e.value)}))}));return s?t:{}}return t}}function h(){if(!n.preserveStatic){var t=s("{","}",e);if(t){var o=/:(?:root|host)(?![.:#(])/.test(t.pre)&&/--\S*\s*:/.test(t.body),a=/var\(/.test(t.body);if(!o&&!a)return e=e.slice(t.end+1),{}}}var c=d()||[],i=n.preserveStatic?m():m().filter((function(e){var t=c.some((function(e){return/:(?:root|host)(?![.:#(])/.test(e)}))&&/^--\S/.test(e.property),n=/var\(/.test(e.value);return t||n}));return c.length||r("selector missing"),{type:"rule",selectors:c,declarations:i}}function y(t){if(!t&&!a())return r("missing '{'");for(var n,o=l();e.length&&(t||"}"!==e[0])&&(n=v()||h());)n.type&&o.push(n),o=o.concat(l());return t||c()?o:r("missing '}'")}return{type:"stylesheet",stylesheet:{rules:y(!0),errors:[]}}}function l(e){var n=t({},{parseHost:!1,store:{},onWarning:function(){}},arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}),r=new RegExp(":".concat(n.parseHost?"host":"root","$"));return"string"==typeof e&&(e=u(e,n)),e.stylesheet.rules.forEach((function(e){"rule"===e.type&&e.selectors.some((function(e){return r.test(e)}))&&e.declarations.forEach((function(e,t){var r=e.property,o=e.value;r&&0===r.indexOf("--")&&(n.store[r]=o)}))})),n.store}function d(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2?arguments[2]:void 0,r={charset:function(e){return"@charset "+e.name+";"},comment:function(e){return 0===e.comment.indexOf("__CSSVARSPONYFILL")?"/*"+e.comment+"*/":""},"custom-media":function(e){return"@custom-media "+e.name+" "+e.media+";"},declaration:function(e){return e.property+":"+e.value+";"},document:function(e){return"@"+(e.vendor||"")+"document "+e.document+"{"+o(e.rules)+"}"},"font-face":function(e){return"@font-face{"+o(e.declarations)+"}"},host:function(e){return"@host{"+o(e.rules)+"}"},import:function(e){return"@import "+e.name+";"},keyframe:function(e){return e.values.join(",")+"{"+o(e.declarations)+"}"},keyframes:function(e){return"@"+(e.vendor||"")+"keyframes "+e.name+"{"+o(e.keyframes)+"}"},media:function(e){return"@media "+e.media+"{"+o(e.rules)+"}"},namespace:function(e){return"@namespace "+e.name+";"},page:function(e){return"@page "+(e.selectors.length?e.selectors.join(", "):"")+"{"+o(e.declarations)+"}"},"page-margin-box":function(e){return"@"+e.name+"{"+o(e.declarations)+"}"},rule:function(e){var t=e.declarations;if(t.length)return e.selectors.join(",")+"{"+o(t)+"}"},supports:function(e){return"@supports "+e.supports+"{"+o(e.rules)+"}"}};function o(e){for(var o="",s=0;s1&&void 0!==arguments[1]?arguments[1]:{});return"string"==typeof e&&(e=u(e,n)),f(e.stylesheet,(function(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;if(-1===e.indexOf("var("))return e;var r=s("(",")",e);return r?"var"===r.pre.slice(-3)?0===r.body.trim().length?(t.onWarning("var() must contain a non-whitespace string"),e):r.pre.slice(0,-3)+function(e){var r=e.split(",")[0].replace(/[\s\n\t]/g,""),o=(e.match(/(?:\s*,\s*){1}(.*)?/)||[])[1],s=Object.prototype.hasOwnProperty.call(t.variables,r)?String(t.variables[r]):void 0,a=s||(o?String(o):void 0),c=n||e;return s||t.onWarning('variable "'.concat(r,'" is undefined')),a&&"undefined"!==a&&a.length>0?y(a,t,c):"var(".concat(c,")")}(r.body)+y(r.post,t):r.pre+"(".concat(y(r.body,t),")")+y(r.post,t):(-1!==e.indexOf("var(")&&t.onWarning('missing closing ")" in the value "'.concat(e,'"')),e)}var g="undefined"!=typeof window,b=g&&window.CSS&&window.CSS.supports&&window.CSS.supports("(--a: 0)"),w={group:0,job:0},S={rootElement:g?document:null,shadowDOM:!1,include:"style,link[rel=stylesheet]",exclude:"",variables:{},onlyLegacy:!0,preserveStatic:!0,preserveVars:!1,silent:!1,updateDOM:!0,updateURLs:!0,watch:null,onBeforeSend:function(){},onError:function(){},onWarning:function(){},onSuccess:function(){},onComplete:function(){},onFinally:function(){}},E={cssComments:/\/\*[\s\S]+?\*\//g,cssKeyframes:/@(?:-\w*-)?keyframes/,cssMediaQueries:/@media[^{]+\{([\s\S]+?})\s*}/g,cssUrls:/url\((?!['"]?(?:data|http|\/\/):)['"]?([^'")]*)['"]?\)/g,cssVarDeclRules:/(?::(?:root|host)(?![.:#(])[\s,]*[^{]*{\s*[^}]*})/g,cssVarDecls:/(?:[\s;]*)(-{2}\w[\w-]*)(?:\s*:\s*)([^;]*);/g,cssVarFunc:/var\(\s*--[\w-]/,cssVars:/(?:(?::(?:root|host)(?![.:#(])[\s,]*[^{]*{\s*[^;]*;*\s*)|(?:var\(\s*))(--[^:)]+)(?:\s*[:)])/},C={dom:{},job:{},user:{}},x=!1,A=null,O=0,k=null,L=!1;function _(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n="cssVars(): ",o=t({},S,e);function s(e,t,r,s){!o.silent&&window.console&&console.error("".concat(n).concat(e,"\n"),t),o.onError(e,t,r,s)}function a(e){!o.silent&&window.console&&console.warn("".concat(n).concat(e)),o.onWarning(e)}function c(e){o.onFinally(Boolean(e),b,M()-o.__benchmark)}if(g){if(o.watch)return o.watch=S.watch,function(e){function t(e){var t=n(e)&&e.hasAttribute("disabled"),r=(e.sheet||{}).disabled;return t||r}function n(e){return"link"===e.nodeName.toLowerCase()&&-1!==(e.getAttribute("rel")||"").indexOf("stylesheet")}function r(e){return"style"===e.nodeName.toLowerCase()}function o(r){var o=!1;if("attributes"===r.type&&n(r.target)&&!t(r.target)){var s="disabled"===r.attributeName,a="href"===r.attributeName,c="skip"===r.target.getAttribute("data-cssvars"),i="src"===r.target.getAttribute("data-cssvars");s?o=!c&&!i:a&&(c?r.target.setAttribute("data-cssvars",""):i&&T(e.rootElement,!0),o=!0)}return o}function s(e){var t=!1;if("childList"===e.type){var n=r(e.target),o="out"===e.target.getAttribute("data-cssvars");t=n&&!o}return t}function a(e){var o=!1;return"childList"===e.type&&(o=[].slice.call(e.addedNodes).some((function(e){var o=1===e.nodeType&&e.hasAttribute("data-cssvars"),s=r(e)&&E.cssVars.test(e.textContent);return!o&&(n(e)||s)&&!t(e)}))),o}function c(t){var n=!1;return"childList"===t.type&&(n=[].slice.call(t.removedNodes).some((function(t){var n=1===t.nodeType,r=n&&"out"===t.getAttribute("data-cssvars"),o=n&&"src"===t.getAttribute("data-cssvars"),s=o;if(o||r){var a=t.getAttribute("data-cssvars-group"),c=e.rootElement.querySelector('[data-cssvars-group="'.concat(a,'"]'));o&&T(e.rootElement,!0),c&&c.parentNode.removeChild(c)}return s}))),n}if(!window.MutationObserver)return;A&&(A.disconnect(),A=null);A=new MutationObserver((function(t){t.some((function(e){return o(e)||s(e)||a(e)||c(e)}))&&_(e)})),A.observe(document.documentElement,{attributes:!0,attributeFilter:["disabled","href"],childList:!0,subtree:!0})}(o),void _(o);if(!1===o.watch&&A&&(A.disconnect(),A=null),!o.__benchmark){if(x===o.rootElement)return void function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100;clearTimeout(k),k=setTimeout((function(){e.__benchmark=null,_(e)}),t)}(e);var i=[].slice.call(o.rootElement.querySelectorAll('[data-cssvars]:not([data-cssvars="out"])'));if(o.__benchmark=M(),o.exclude=[A?'[data-cssvars]:not([data-cssvars=""])':'[data-cssvars="out"]',"link[disabled]:not([data-cssvars])",o.exclude].filter((function(e){return e})).join(","),o.variables=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=/^-{2}/;return Object.keys(e).reduce((function(n,r){return n[t.test(r)?r:"--".concat(r.replace(/^-+/,""))]=e[r],n}),{})}(o.variables),i.forEach((function(e){var t="style"===e.nodeName.toLowerCase()&&e.__cssVars.text,n=t&&e.textContent!==e.__cssVars.text;t&&n&&(e.sheet&&(e.sheet.disabled=!1),e.setAttribute("data-cssvars",""))})),!A)[].slice.call(o.rootElement.querySelectorAll('[data-cssvars="out"]')).forEach((function(e){var t=e.getAttribute("data-cssvars-group");(t?o.rootElement.querySelector('[data-cssvars="src"][data-cssvars-group="'.concat(t,'"]')):null)||e.parentNode.removeChild(e)})),O&&i.length2&&void 0!==arguments[2]?arguments[2]:[],i=t({},C.dom,C.user);if(C.job={},r.forEach((function(e,t){var r=n[t];if(e.__cssVars=e.__cssVars||{},e.__cssVars.text=r,E.cssVars.test(r))try{var c=u(r,{preserveStatic:o.preserveStatic,removeComments:!0});l(c,{parseHost:Boolean(o.rootElement.host),store:C.dom,onWarning:a}),e.__cssVars.tree=c}catch(t){s(t.message,e)}})),t(C.job,C.dom),o.updateDOM?(t(C.user,o.variables),t(C.job,C.user)):(t(C.job,C.user,o.variables),t(i,o.variables)),w.job>0&&Boolean(Object.keys(C.job).length>Object.keys(i).length||Boolean(Object.keys(i).length&&Object.keys(C.job).some((function(e){return C.job[e]!==i[e]})))))T(o.rootElement),_(o);else{var f=[],m=[],p=!1;if(o.updateDOM&&w.job++,r.forEach((function(e,r){var c=!e.__cssVars.tree;if(e.__cssVars.tree)try{v(e.__cssVars.tree,t({},o,{variables:C.job,onWarning:a}));var i=d(e.__cssVars.tree);if(o.updateDOM){var u=n[r],l=E.cssVarFunc.test(u);if(e.getAttribute("data-cssvars")||e.setAttribute("data-cssvars","src"),i.length&&l){var h=e.getAttribute("data-cssvars-group")||++w.group,y=i.replace(/\s/g,""),g=o.rootElement.querySelector('[data-cssvars="out"][data-cssvars-group="'.concat(h,'"]'))||document.createElement("style");p=p||E.cssKeyframes.test(i),o.preserveStatic&&e.sheet&&(e.sheet.disabled=!0),g.hasAttribute("data-cssvars")||g.setAttribute("data-cssvars","out"),y===e.textContent.replace(/\s/g,"")?(c=!0,g&&g.parentNode&&(e.removeAttribute("data-cssvars-group"),g.parentNode.removeChild(g))):y!==g.textContent.replace(/\s/g,"")&&([e,g].forEach((function(e){e.setAttribute("data-cssvars-job",w.job),e.setAttribute("data-cssvars-group",h)})),g.textContent=i,f.push(i),m.push(g),g.parentNode||e.parentNode.insertBefore(g,e.nextSibling))}}else e.textContent.replace(/\s/g,"")!==i&&f.push(i)}catch(t){s(t.message,e)}c&&e.setAttribute("data-cssvars","skip"),e.hasAttribute("data-cssvars-job")||e.setAttribute("data-cssvars-job",w.job)})),O=o.rootElement.querySelectorAll('[data-cssvars]:not([data-cssvars="out"])').length,o.shadowDOM)for(var h,y=[].concat(o.rootElement).concat([].slice.call(o.rootElement.querySelectorAll("*"))),g=0;h=y[g];++g){if(h.shadowRoot&&h.shadowRoot.querySelector("style"))_(t({},o,{rootElement:h.shadowRoot}))}o.updateDOM&&p&&function(e){var t=["animation-name","-moz-animation-name","-webkit-animation-name"].filter((function(e){return getComputedStyle(document.body)[e]}))[0];if(t){for(var n=[].slice.call(e.querySelectorAll("*")),r=[],o="__CSSVARSPONYFILL-KEYFRAMES__",s=0,a=n.length;s1&&void 0!==arguments[1]?arguments[1]:location.href,n=document.implementation.createHTMLDocument(""),r=n.createElement("base"),o=n.createElement("a");return n.head.appendChild(r),n.body.appendChild(o),r.href=t,o.href=e,o.href}function M(){return g&&(window.performance||{}).now?window.performance.now():(new Date).getTime()}function T(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];[].slice.call(e.querySelectorAll('[data-cssvars="skip"],[data-cssvars="src"]')).forEach((function(e){return e.setAttribute("data-cssvars","")})),t&&(C.dom={})}function V(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,r=3===e.childNodes[0].nodeType,o=e.querySelector("ul");if(r&&o&&!Array.apply(null,e.children).some((function(e){return e.tabIndex>-1})).length){var s=document.createElement("span");for(null!==n&&s.setAttribute("tabindex",n),e.insertBefore(s,o);e.childNodes[0]!==s;)s.appendChild(e.childNodes[0])}}_.reset=function(){for(var e in w.job=0,w.group=0,x=!1,A&&(A.disconnect(),A=null),O=0,k=null,L=!1,C)C[e]={}};var N="0.9.0";function R(e){for(var t=((window.Docsify||{}).version||"0.0.0").split("."),n=e.split(".");n.length a");e&&(e.parentNode.innerHTML=e.innerHTML)}))},function(e,t){e.doneEach((function(){var e=Array.apply(null,document.querySelectorAll("body > nav.app-nav > ul > li")),t=Array.apply(null,document.querySelectorAll(".sidebar > nav > ul > li"));e.forEach((function(e){var t="focus-within";V(e,"span",0),e.addEventListener("focusin",(function(n){e.contains(document.activeElement)&&e.classList.add(t)})),e.addEventListener("focusout",(function(n){e.contains(document.activeElement)||e.classList.remove(t)}))})),t.forEach((function(e){V(e,"span")}))}))},function(e,t){e.doneEach((function(){Array.apply(null,document.querySelectorAll("pre[data-lang]")).forEach((function(e){var t=e.querySelector("code"),n="language-".concat(e.getAttribute("data-lang"));e.classList.add(n),t.classList.add(n)}))}))},function(e,t){e.mounted((function(){var e=document.querySelector(".content"),t=setInterval((function(){e.textContent.length&&(document.body.classList.add("ready-fix"),clearInterval(t))}),250)})),e.ready((function(){document.body.classList.add("ready-fix")}))},function(e,t){e.init((function(){if(!1!==((window.$docsify||{}).themeable||{}).responsiveTables){var e=window.$docsify.markdown=window.$docsify.markdown||{},t=e.renderer=e.renderer||{};t.table=t.table||function(e,t){var n='\n \n
\n '.concat(e," \n ").concat(t," \n
\n
");try{var r=document.createElement("div"),o=document.head.appendChild(document.createElement("style")).sheet,s="_"+Math.random().toString(36).substr(2,9);r.innerHTML=n;var a=r.querySelector("table");Array.apply(null,a.getElementsByTagName("th")).map((function(e){return e.innerHTML.replace(" "," ")})).forEach((function(e,t){var n="#".concat(s," td:nth-child(").concat(t+1,')::before{content:"').concat(e,'";}');o.insertRule(n,o.cssRules.length)})),a.id=s,n=r.innerHTML}catch(e){console.log("Failed to render responsive table: "+e)}return n}}}))}],window.$docsify.plugins||[],[function(e,t){e.ready((function(){var e=document.querySelector(".sidebar .search .clear-button");if(e){var t=document.createElement("button");t.className="clear-button",t.setAttribute("aria-label","Clear search"),t.innerHTML='\n \n \n \n \n \n ',e.parentNode.replaceChild(t,e)}}))},R("4.8.0"),R("4.8.0")]).filter((function(e){return null!==e})),"object"!==e(window.$docsify.search)?window.$docsify.search={}:Array.isArray(window.$docsify.search)&&(window.$docsify.search={paths:window.$docsify.search}),window.$docsify.search.hideOtherSidebarContent=!0,window.$docsify.themeable=window.$docsify.themeable||{},window.$docsify.themeable.version=N,window.$docsify.themeable.semver=N.split("."),window.$docsify.themeable.util={cssVars:function(){_(arguments.length>0&&void 0!==arguments[0]?arguments[0]:q)}}}}();
9 | //# sourceMappingURL=docsify-themeable.min.js.map
10 |
--------------------------------------------------------------------------------
/docs/assets/css/theme.css:
--------------------------------------------------------------------------------
1 | .app-nav:not(:empty) ~ main .markdown-section {
2 | padding-top: 5rem;
3 | }
4 |
5 | .sidebar-nav a,
6 | .sidebar nav a {
7 | overflow: visible;
8 | white-space: break-spaces;
9 | }
10 |
11 | .pagination-item,
12 | .pagination-item-title {
13 | opacity: 0.9 !important;
14 | }
15 |
16 | .pagination-item:not(:last-child) a .pagination-item-label,
17 | .pagination-item:not(:last-child) a .pagination-item-subtitle,
18 | .pagination-item:not(:last-child) a .pagination-item-title {
19 | opacity: 0.9 !important;
20 | transition: all 0.2s;
21 | }
22 |
23 | .markdown-section {
24 | padding: 1rem 40px;
25 | }
26 |
27 | .markdown-section .alert,
28 | .markdown-section blockquote {
29 | overflow: visible;
30 | margin: 1em 0;
31 | padding: 1em;
32 | border-width: var(--blockquote-border-width, 0);
33 | border-style: var(--blockquote-border-style);
34 | border-color: var(--blockquote-border-color);
35 | border-radius: var(--blockquote-border-radius);
36 | background: var(--blockquote-background);
37 | color: var(--blockquote-color);
38 | font-family: var(--blockquote-font-family);
39 | font-size: var(--blockquote-font-size);
40 | font-style: var(--blockquote-font-style);
41 | font-weight: var(--blockquote-font-weight);
42 | quotes: "“" "”" "‘" "’";
43 | }
44 |
45 | .markdown-section ul {
46 | list-style: square outside none;
47 | }
48 |
49 | .markdown-section .alert ul,
50 | .markdown-section blockquote ul {
51 | list-style: none;
52 | margin-top: 0.8em;
53 | }
54 |
55 | .markdown-section .alert ul li,
56 | .markdown-section blockquote ul li {
57 | margin: 2px 0;
58 | }
59 |
60 | .markdown-section .alert ul li:before,
61 | .markdown-section blockquote ul li:before {
62 | position: absolute;
63 | content: "\2B29";
64 | margin-left: -18px;
65 | }
66 |
67 | .markdown-section .button {
68 | cursor: pointer;
69 | color: var(--base-background-color);
70 | height: auto;
71 | display: inline-block;
72 | padding: 10px;
73 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
74 | line-height: 1.2rem;
75 | background-color: var(--link-color);
76 | text-decoration: none;
77 | border-radius: 0.25rem;
78 | }
79 |
80 | .markdown-section a.button {
81 | cursor: pointer;
82 | color: var(--base-background-color);
83 | text-decoration: none !important;
84 | }
85 |
86 | .markdown-section .button-secondary {
87 | cursor: pointer;
88 | color: var(--link-color);
89 | height: auto;
90 | display: inline-block;
91 | padding: 10px;
92 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
93 | line-height: 1.2rem;
94 | background-color: transparent;
95 | text-decoration: none;
96 | border: 1px solid var(--link-color) !important;
97 | border-radius: 0.25rem;
98 | }
99 |
100 | .markdown-section a.button-secondary {
101 | cursor: pointer;
102 | color: var(--link-color);
103 | text-decoration: none !important;
104 | }
105 |
106 | .markdown-section .button-rounded {
107 | cursor: pointer;
108 | color: var(--base-background-color);
109 | height: auto;
110 | display: inline-block;
111 | padding: 10px min(20px, 5%) 10px min(20px, 5%);
112 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
113 | line-height: 1.2rem;
114 | background-color: var(--link-color);
115 | text-decoration: none;
116 | border-radius: 1.2rem;
117 | }
118 |
119 | .markdown-section a.button-rounded {
120 | cursor: pointer;
121 | color: var(--base-background-color);
122 | text-decoration: none !important;
123 | }
124 |
125 | .markdown-section .button-secondary-rounded {
126 | cursor: pointer;
127 | color: var(--link-color);
128 | height: auto;
129 | display: inline-block;
130 | padding: 10px min(20px, 5%) 10px min(20px, 5%);
131 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
132 | line-height: 1.2rem;
133 | background-color: transparent;
134 | text-decoration: none;
135 | border: 1px solid var(--link-color) !important;
136 | border-radius: 1.4rem;
137 | }
138 |
139 | .markdown-section a.button-secondary-rounded {
140 | cursor: pointer;
141 | color: var(--link-color);
142 | text-decoration: none !important;
143 | }
144 |
145 | .markdown-section .navpill {
146 | cursor: pointer;
147 | color: var(--base-color);
148 | height: auto;
149 | display: inline-block;
150 | border: 1px solid var(--base-color);
151 | border-radius: 4rem;
152 | padding: 4px 14px 4px 14px;
153 | margin-bottom: 4px;
154 | margin-right: 6px;
155 | font-size: 0.8rem;
156 | line-height: 0.9rem;
157 | background-color: var(--base-background-color);
158 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
159 | font-weight: bold;
160 | text-decoration: none;
161 | }
162 |
163 | .markdown-section a.navpill {
164 | cursor: pointer;
165 | color: var(--base-color) !important;
166 | border: 1px solid var(--base-color);
167 | text-decoration: none !important;
168 | }
169 |
170 | .markdown-section .badge {
171 | color: var(
172 | --badge-text-color,
173 | var(--base-background-color)
174 | ); /* Default text color */
175 | background-color: var(
176 | --badge-bg-color,
177 | color-mix(in srgb, var(--base-color) 70%, transparent)
178 | ); /* Default background */
179 |
180 | display: inline-block;
181 | padding: 0.25em 0.4em 0.25em 0.4em;
182 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
183 | font-size: 75%;
184 | font-weight: 700;
185 | line-height: 1;
186 | text-align: center;
187 | white-space: nowrap;
188 | vertical-align: middle;
189 | margin-top: -0.4em;
190 | border-radius: 0.25rem;
191 | transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,
192 | border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
193 | text-decoration: none;
194 | }
195 |
196 | .markdown-section .badge a {
197 | color: var(
198 | --badge-text-color,
199 | var(--base-background-color)
200 | ) !important; /* Default text color */
201 | text-decoration: none !important;
202 | }
203 |
204 | .markdown-section a[href$="?id=a"],
205 | .markdown-section a[href$="?id=b"],
206 | .markdown-section a[href$="?id=c"],
207 | .markdown-section a[href$="?id=d"],
208 | .markdown-section a[href$="?id=e"],
209 | .markdown-section a[href$="?id=f"],
210 | .markdown-section a[href$="?id=g"],
211 | .markdown-section a[href$="?id=h"],
212 | .markdown-section a[href$="?id=i"],
213 | .markdown-section a[href$="?id=j"],
214 | .markdown-section a[href$="?id=k"],
215 | .markdown-section a[href$="?id=l"],
216 | .markdown-section a[href$="?id=m"],
217 | .markdown-section a[href$="?id=n"],
218 | .markdown-section a[href$="?id=o"],
219 | .markdown-section a[href$="?id=p"],
220 | .markdown-section a[href$="?id=q"],
221 | .markdown-section a[href$="?id=r"],
222 | .markdown-section a[href$="?id=s"],
223 | .markdown-section a[href$="?id=t"],
224 | .markdown-section a[href$="?id=u"],
225 | .markdown-section a[href$="?id=v"],
226 | .markdown-section a[href$="?id=w"],
227 | .markdown-section a[href$="?id=x"],
228 | .markdown-section a[href$="?id=y"],
229 | .markdown-section a[href$="?id=z"] {
230 | display: inline-flex;
231 | padding-top: 0px;
232 | padding-right: 6px;
233 | padding-bottom: 0px;
234 | padding-left: 6px;
235 | line-height: 1.2em;
236 | }
237 |
238 | .markdown-section #a,
239 | .markdown-section #b,
240 | .markdown-section #c,
241 | .markdown-section #d,
242 | .markdown-section #e,
243 | .markdown-section #f,
244 | .markdown-section #g,
245 | .markdown-section #h,
246 | .markdown-section #i,
247 | .markdown-section #j,
248 | .markdown-section #k,
249 | .markdown-section #l,
250 | .markdown-section #m,
251 | .markdown-section #n,
252 | .markdown-section #o,
253 | .markdown-section #p,
254 | .markdown-section #q,
255 | .markdown-section #r,
256 | .markdown-section #s,
257 | .markdown-section #t,
258 | .markdown-section #u,
259 | .markdown-section #v,
260 | .markdown-section #w,
261 | .markdown-section #x,
262 | .markdown-section #y,
263 | .markdown-section #z {
264 | width: 2em;
265 | color: var(--base-background-color);
266 | font-weight: 700;
267 | margin-top: 1rem;
268 | background: color-mix(in srgb, var(--base-color) 70%, transparent);
269 | background-clip: content-box;
270 | }
271 |
272 | /* Target first paragraphs with 5+ links (reasonable index minimum) */
273 | .markdown-section p:first-of-type:has(a[href^="#"]):has(a:nth-of-type(5)) {
274 | flex-wrap: wrap;
275 | gap: 2px;
276 | font-size: var(--font-size-l);
277 | font-weight: 500;
278 | line-height: 1.4;
279 | }
280 |
281 | .markdown-section p:first-of-type:has(a[href^="#"]):has(a:nth-of-type(5)) a {
282 | padding: 0 4px;
283 | }
284 |
285 | .markdown-section .accordion {
286 | margin-top: 1.05rem;
287 | position: relative;
288 | display: -ms-flexbox;
289 | display: flex;
290 | -ms-flex-direction: column;
291 | flex-direction: column;
292 | min-width: 0;
293 | word-wrap: break-word;
294 | background-clip: border-box;
295 | border-top: 1px solid #cccccc;
296 | border-right: 1px solid #cccccc;
297 | border-left: 1px solid #cccccc;
298 | border-radius: 0.15rem;
299 | }
300 |
301 | .markdown-section .accordion details {
302 | padding: 0.75rem 1.25rem;
303 | margin-bottom: 0;
304 | border-bottom: 1px solid #cccccc;
305 | }
306 |
307 | .markdown-section summary {
308 | cursor: pointer;
309 | color: var(--link-color);
310 | padding: 0;
311 |
312 | h1,
313 | h2,
314 | h3 {
315 | margin: 0;
316 | display: inline-block;
317 | }
318 | }
319 |
320 | .markdown-section code {
321 | white-space: pre-wrap !important;
322 | overflow-wrap: break-word;
323 | }
324 |
325 | .markdown-section pre {
326 | white-space: pre-wrap !important;
327 | overflow-wrap: break-word;
328 | }
329 |
330 | .markdown-section pre code {
331 | white-space: pre-wrap !important;
332 | overflow-wrap: break-word;
333 | }
334 |
335 | .markdown-section a {
336 | overflow-wrap: anywhere;
337 | }
338 |
339 | /* Included to support earlier Markdown Schedule templates */
340 | .markdown-section h2 .fa-fw {
341 | text-align: left;
342 | }
343 |
344 | .markdown-section .video-container-4by3 {
345 | position: relative;
346 | padding-bottom: 75%;
347 | height: 0;
348 | overflow: hidden;
349 | max-width: 100%;
350 | }
351 |
352 | .markdown-section .video-container-16by9 {
353 | position: relative;
354 | padding-bottom: 56.25%;
355 | height: 0;
356 | overflow: hidden;
357 | max-width: 100%;
358 | }
359 |
360 | .video-container-16by9 iframe,
361 | .video-container-4by3 iframe,
362 | .embed-container object,
363 | .embed-container embed {
364 | position: absolute;
365 | top: 0;
366 | left: 0;
367 | width: 100%;
368 | height: 93%;
369 | }
370 |
371 | .markdown-section .responsive-container iframe {
372 | max-width: 100%;
373 | }
374 |
375 | .markdown-section .responsive {
376 | max-width: 100%;
377 | height: auto;
378 | }
379 |
380 | aside#__sidebar .card-image-sidebar,
381 | aside#__sidebar .card-image-sidebar-rounded {
382 | width: 100%; /* fills full width of sidebar */
383 | height: auto;
384 | max-height: 165px; /* prevents it from getting too tall */
385 | object-fit: cover; /* crops image to fit dimensions */
386 | display: block;
387 | margin-top:0px;
388 | }
389 |
390 | aside#__sidebar .card-image-sidebar-rounded {
391 | border-radius: 6px 6px 0 0;
392 | }
393 |
394 | /* Make sidebar a flex container when banner image exists */
395 | aside#__sidebar:has(.sidebar-nav > [class*="card-image-sidebar"]:first-child) {
396 | display: flex;
397 | flex-direction: column;
398 | }
399 |
400 | /* Put sidebar-nav (with image) first */
401 | aside#__sidebar:has(.sidebar-nav > [class*="card-image-sidebar"]:first-child) .sidebar-nav {
402 | order: 1;
403 | }
404 |
405 | /* Put secondary nav second */
406 | aside#__sidebar:has(.sidebar-nav > [class*="card-image-sidebar"]:first-child) nav[aria-label="secondary"] {
407 | order: 2;
408 | }
409 |
410 | /* Only apply negative margin when both banner image and mergedNavbar nav exist */
411 | aside#__sidebar:has(.sidebar-nav > [class*="card-image-sidebar"]:first-child):has(nav[aria-label="secondary"]) .sidebar-nav > ul > li:last-child {
412 | margin-bottom: -40px !important;
413 | }
414 |
415 | .markdown-section .banner-image {
416 | width: 100%;
417 | height: 125px;
418 | object-fit: cover;
419 | object-position: 50% 50%;
420 | }
421 |
422 | @media (min-width: 576px) {
423 | .markdown-section .banner-image {
424 | height: 250px;
425 | }
426 | }
427 |
428 | .markdown-section .banner-tall-image {
429 | width: 100%;
430 | height: 175px;
431 | object-fit: cover;
432 | object-position: 50% 50%;
433 | }
434 |
435 | @media (min-width: 576px) {
436 | .markdown-section .banner-tall-image {
437 | height: 350px;
438 | }
439 | }
440 |
441 | .markdown-section .header-image-fade {
442 | width: 100%;
443 | margin: 0px auto;
444 | position: absolute;
445 | top: 0px;
446 | left: 0;
447 | -webkit-mask-image: -webkit-gradient(
448 | linear,
449 | left top,
450 | left bottom,
451 | from(rgba(0, 0, 0, 1)),
452 | to(rgba(0, 0, 0, 0))
453 | );
454 | mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
455 | opacity: 0.4;
456 | z-index: -1;
457 | }
458 |
459 | /* CSS currently only works with sidebar and standalone pages */
460 | .markdown-section .header-image-fade-full-width {
461 | margin-top: -2rem;
462 | left: 50%;
463 | right: 50%;
464 | margin-left: -50vw;
465 | margin-right: -50vw;
466 | position: absolute;
467 | width: 100vw;
468 | max-width: 100vw;
469 | -webkit-mask-image: -webkit-gradient(
470 | linear,
471 | left top,
472 | left bottom,
473 | from(rgba(0, 0, 0, 1)),
474 | to(rgba(0, 0, 0, 0))
475 | );
476 | mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
477 | opacity: 0.4;
478 | z-index: -1;
479 | }
480 |
481 | /* CSS currently only works with sidebar and standalone pages */
482 | .markdown-section .header-image-full-width,
483 | .markdown-section .header-image-full-width-headings-overlay {
484 | margin-top: -3rem;
485 | left: 50%;
486 | margin-left: -50vw;
487 | margin-right: -50vw;
488 | max-width: 100vw;
489 | position: relative;
490 | right: 50%;
491 | width: 100vw;
492 | height: 30dvh;
493 | object-fit: cover;
494 | object-position: center 50%;
495 | }
496 |
497 | .markdown-section .header-tall-image-full-width,
498 | .markdown-section .header-tall-image-full-width-headings-overlay {
499 | margin-top: -3rem;
500 | left: 50%;
501 | margin-left: -50vw;
502 | margin-right: -50vw;
503 | max-width: 100vw;
504 | position: relative;
505 | right: 50%;
506 | width: 100vw;
507 | height: 40dvh;
508 | object-fit: cover;
509 | object-position: center 50%;
510 | }
511 |
512 | .markdown-section p:has(.header-tall-image-full-width, .header-image-full-width) + h1[tabindex="-1"],
513 | .markdown-section p:has(.header-tall-image-full-width, .header-image-full-width) + * + h1[tabindex="-1"] {
514 | font-size: clamp(2rem, 5vw, 3.0rem); /* Scales between 2rem and 3.0rem */
515 | line-height: clamp(2.2rem, 5.5vw, 3.4rem);
516 | margin-left: -3px;
517 | font-weight: 600;
518 | letter-spacing: clamp(-0.02em, -0.5vw, -0.01em); /* Tighten large text */
519 | margin-top: clamp(1.5rem, 3vw, 2.5rem);
520 | margin-bottom: clamp(0.75rem, 1.5vw, 1.25rem);
521 | }
522 |
523 | .markdown-section p:has(.header-tall-image-full-width, .header-image-full-width) + h1[tabindex="-1"] + h2[tabindex="-1"],
524 | .markdown-section p:has(.header-tall-image-full-width, .header-image-full-width) + * + h1[tabindex="-1"] + h2[tabindex="-1"] {
525 | font-size: clamp(1.2rem, 3vw, 1.8rem); /* Scales between 1.2rem and 1.8rem */
526 | line-height: clamp(1.4rem, 3.5vw, 2rem);
527 | margin-left: -2px;
528 | font-weight: 500;
529 | margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
530 | }
531 |
532 | /* CSS generated/assisted by Anthropic Claude AI */
533 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay,
534 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] {
535 | position: absolute;
536 | top: calc(-3rem + 20dvh + 1rem); /* h1 center + spacing */
537 | left: 50%;
538 | transform: translate(-50%, -50%);
539 | color: white;
540 | text-shadow:
541 | 2px 2px 4px rgba(0,0,0,0.8),
542 | 0 0 20px rgba(0,0,0,0.4);
543 | z-index: 10;
544 | margin: 0;
545 | font-size: clamp(2rem, 5vw, 3.0rem); /* Scales between 2rem and 3.0rem */
546 | line-height: clamp(2.2rem, 5.5vw, 3.4rem);
547 | width: 100%;
548 | text-align: center;
549 | font-weight: 500;
550 | letter-spacing: -0.03em;
551 | backdrop-filter: blur(2px);
552 | background: linear-gradient(
553 | 135deg,
554 | rgba(0,0,0,0.3) 0%,
555 | rgba(0,0,0,0.1) 100%
556 | );
557 | padding: clamp(0.5rem, 2vw, 1rem) clamp(1rem, 4vw, 2rem);
558 | border-radius: 8px;
559 | max-width: 90vw;
560 | }
561 |
562 | .markdown-section p:has(.header-image-full-width-headings-overlay) + h1[tabindex="-1"] {
563 | top: calc(-3rem + 15dvh + 1rem); /* h1 center + spacing for regular images */
564 | }
565 |
566 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay,
567 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] + h2[tabindex="-1"] {
568 | position: absolute;
569 | top: calc(-3rem + 20dvh + 3.5rem); /* h1 center + spacing */
570 | left: 50%;
571 | transform: translateX(-50%); /* Only center horizontally */
572 | color: rgba(255,255,255,0.95);
573 | text-shadow:
574 | 1px 1px 3px rgba(0,0,0,0.7),
575 | 0 0 15px rgba(0,0,0,0.3);
576 | z-index: 10;
577 | margin: 0;
578 | font-size: clamp(1.2rem, 3vw, 1.8rem); /* Scales between 1.2rem and 1.8rem */
579 | line-height: clamp(1.4rem, 3.5vw, 2rem);
580 | width: 100%;
581 | text-align: center;
582 | font-weight: 300;
583 | letter-spacing: 0.05em;
584 | padding: clamp(0.25rem, 1vw, 0.5rem) clamp(0.75rem, 3vw, 1.5rem);
585 | max-width: 80vw;
586 | border: 0;
587 | }
588 |
589 | .markdown-section p:has(.header-image-full-width-headings-overlay) + h1[tabindex="-1"] + h2[tabindex="-1"] {
590 | top: calc(-3rem + 15dvh + 3.5rem); /* h2 center + spacing for regular images */
591 | }
592 |
593 | /* Keep text-shadow for links in h1 and h2 (same as parent) */
594 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay,
595 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] a,
596 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay,
597 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] + h2[tabindex="-1"] a {
598 | text-shadow: inherit; /* Inherit shadow from parent */
599 | text-decoration: none; /* Remove default underline */
600 | }
601 |
602 | /* Apply underline only on hover */
603 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay,
604 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] a:hover,
605 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay,
606 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] + h2[tabindex="-1"] a:hover {
607 | text-decoration: underline; /* Show underline on hover */
608 | }
609 |
610 | .markdown-section .image-75 {
611 | width: 75%;
612 | height: auto;
613 | }
614 |
615 | .markdown-section .image-50 {
616 | width: 50%;
617 | height: auto;
618 | }
619 |
620 | .markdown-section .image-25 {
621 | width: 25%;
622 | height: auto;
623 | }
624 |
625 | .markdown-section .image-75-border {
626 | width: 75%;
627 | height: auto;
628 | border: 1px solid #dfdfdf;
629 | }
630 |
631 | .markdown-section .image-50-border {
632 | width: 50%;
633 | height: auto;
634 | border: 1px solid #dfdfdf;
635 | }
636 |
637 | .markdown-section .image-25-border {
638 | width: 25%;
639 | height: auto;
640 | border: 1px solid #dfdfdf;
641 | }
642 |
643 | .markdown-section .image-border {
644 | border: 1px solid #dfdfdf;
645 | }
646 |
647 | .markdown-section .image-border-rounded {
648 | border-radius: 0.35em;
649 | border: 1px solid #dfdfdf;
650 | }
651 |
652 | .markdown-section .column {
653 | float: left;
654 | padding-right: 1rem;
655 | width: 50%;
656 | }
657 |
658 | .markdown-section .column-right {
659 | float: right;
660 | padding-left: 1rem;
661 | width: 50%;
662 | }
663 |
664 | .markdown-section .column img {
665 | margin-top: 0.35rem;
666 | }
667 |
668 | .markdown-section .column-right img {
669 | margin-top: 0.35rem;
670 | }
671 |
672 | .markdown-section .reverse-columns .column {
673 | float: right;
674 | }
675 |
676 | .markdown-section .row:after {
677 | content: "";
678 | display: table;
679 | clear: both;
680 | }
681 |
682 | /* Hide empty rows in responsive tables */
683 | @media (max-width: 30em) {
684 | .markdown-section .table-wrapper td:empty::before {
685 | display: none;
686 | }
687 | }
688 |
689 | /* Left align rows in responsive tables */
690 | @media (max-width: 30em) {
691 | .markdown-section .table-wrapper tbody td {
692 | text-align: left !important;
693 | }
694 | }
695 |
696 | @media screen and (max-width: 800px) {
697 | .markdown-section .column,
698 | .markdown-section .column-right {
699 | width: 100%;
700 | padding-right: 0rem;
701 | padding-left: 0rem;
702 | }
703 |
704 | .markdown-section .image-75,
705 | .markdown-section .image-50,
706 | .markdown-section .image-25,
707 | .markdown-section .image-75-border,
708 | .markdown-section .image-50-border,
709 | .markdown-section .image-25-border {
710 | width: 100%;
711 | height: auto;
712 | }
713 | }
714 |
715 | /* CSS generated/assisted by Anthropic Claude AI */
716 | .markdown-section .card-list {
717 | display: grid;
718 | grid-template-columns: repeat(2, 1fr);
719 | gap: 2rem;
720 | margin-top: 2rem;
721 | }
722 |
723 | .markdown-section .card:not(.card-list .card),
724 | .markdown-section .card-rounded:not(.card-list .card-rounded) {
725 | margin-top: 2rem;
726 | }
727 |
728 | .markdown-section .card,
729 | .markdown-section .card-rounded {
730 | border: 1px solid var(--mono-tint2);
731 | padding: 1rem;
732 | display: flex;
733 | flex-direction: column;
734 | overflow: hidden; /* This ensures images respect border-radius */
735 | }
736 |
737 | .markdown-section .card-rounded {
738 | border-radius: 0.35em;
739 | }
740 |
741 | .markdown-section .card h2,
742 | .markdown-section .card-rounded h2 {
743 | margin: 0 0 .1rem 0;
744 | padding-bottom: .5rem;
745 | font-size: 1.3rem;
746 | }
747 |
748 | /* Adjust space above and below h2 that follows edge-to-edge images */
749 | .markdown-section .card p:has(img):first-child + h2,
750 | .markdown-section .card-rounded p:has(img):first-child + h2 {
751 | margin-top: 1rem;
752 | padding-bottom: .25rem;
753 | }
754 |
755 | /* All images have normal padding by default */
756 | .markdown-section .card p:has(img),
757 | .markdown-section .card-rounded p:has(img) {
758 | margin: 0;
759 | }
760 |
761 | /* First images extend to card edges */
762 | .markdown-section .card p:has(img):first-child,
763 | .markdown-section .card-rounded p:has(img):first-child {
764 | margin: -1.6rem -1.5rem -1rem -1.5rem;
765 | }
766 |
767 | .markdown-section .card img,
768 | .markdown-section .card-rounded img {
769 | width: 100%;
770 | height: 240px;
771 | object-fit: cover;
772 | }
773 |
774 | .markdown-section .card p,
775 | .markdown-section .card-rounded p {
776 | flex-grow: 1;
777 | margin-bottom: .1rem;
778 | }
779 |
780 | /* Mobile */
781 | @media screen and (max-width: 768px) {
782 | .markdown-section .card-list {
783 | grid-template-columns: 1fr;
784 | gap: 1.5rem;
785 | }
786 |
787 | .markdown-section .card,
788 | .markdown-section .card-rounded {
789 | padding: 1.25rem;
790 | }
791 |
792 | .markdown-section .card img,
793 | .markdown-section .card-rounded img {
794 | height: 200px;
795 | }
796 |
797 | .markdown-section .card p:has(img):first-child,
798 | .markdown-section .card-rounded p:has(img):first-child {
799 | margin: -1.35rem -1.25rem -0.75rem -1.25rem;
800 | }
801 | }
802 |
803 | .markdown-section figure,
804 | .markdown-section p,
805 | .markdown-section ol,
806 | .markdown-section ul {
807 | margin: 1em 0em 0.5em 0em;
808 | }
809 |
810 | .markdown-section h1 {
811 | line-height: 1.9rem;
812 | }
813 |
814 | .markdown-section h2 {
815 | line-height: 1.7rem;
816 | }
817 |
818 | .markdown-section h3 {
819 | line-height: 1.5rem;
820 | }
821 |
822 | .markdown-section h4 {
823 | line-height: 1.45rem;
824 | }
825 |
826 | .markdown-section h5 {
827 | line-height: 1.4rem;
828 | }
829 |
830 | .markdown-section h6 {
831 | line-height: 1.3rem;
832 | }
833 |
834 | .markdown-section .alert hr,
835 | .markdown-section blockquote hr {
836 | margin: 1em 0;
837 | }
838 |
839 | .markdown-section .alert h1,
840 | .markdown-section blockquote h1 {
841 | font-size: 1.5rem;
842 | line-height: 1.6rem;
843 | }
844 |
845 | .markdown-section .alert h2,
846 | .markdown-section blockquote h2 {
847 | font-size: 1.35rem;
848 | line-height: 1.5rem;
849 | }
850 |
851 | .markdown-section .alert h3,
852 | .markdown-section blockquote h3 {
853 | font-size: 1.2rem;
854 | line-height: 1.35rem;
855 | }
856 |
857 | .markdown-section .alert h4,
858 | .markdown-section blockquote h4 {
859 | font-size: 1.15rem;
860 | line-height: 1.3rem;
861 | }
862 |
863 | .markdown-section .alert h5,
864 | .markdown-section blockquote h5 {
865 | font-size: 1.1rem;
866 | line-height: 1.25rem;
867 | }
868 |
869 | .markdown-section .alert h6,
870 | .markdown-section blockquote h6 {
871 | font-size: 1rem;
872 | line-height: 1.15rem;
873 | }
874 |
875 | .markdown-section .edit-link {
876 | display: inline-flex;
877 | align-items: center;
878 | }
879 |
880 | .markdown-section .edit-link .emoji {
881 | margin-right: 2px;
882 | }
883 |
884 | body .app-nav {
885 | margin-right: -10px;
886 | }
887 |
888 | body .docsify-pagination-container {
889 | display: flex;
890 | flex-wrap: wrap;
891 | justify-content: space-between;
892 | overflow: hidden;
893 | margin: 3em 0 1em;
894 | border-top: 0px solid rgba(0, 0, 0, 0.07);
895 | }
896 |
897 | @media only screen and (max-width: 480px) {
898 | .markdown-section h1 {
899 | font-size: 1.45rem;
900 | line-height: 1.75rem;
901 | }
902 |
903 | .markdown-section h2 {
904 | font-size: 1.35rem;
905 | line-height: 1.65rem;
906 | }
907 |
908 | .markdown-section h3 {
909 | font-size: 1.25rem;
910 | line-height: 1.55rem;
911 | }
912 |
913 | .markdown-section h4 {
914 | font-size: 1.15rem;
915 | line-height: 1.45rem;
916 | }
917 |
918 | .markdown-section h5 {
919 | font-size: 1.1rem;
920 | line-height: 1.4rem;
921 | }
922 |
923 | .markdown-section h6 {
924 | font-size: 1rem;
925 | line-height: 1.3rem;
926 | }
927 |
928 | .markdown-section .alert h1,
929 | .markdown-section blockquote h1 {
930 | font-size: 1.3rem;
931 | line-height: 1.4rem;
932 | }
933 |
934 | .markdown-section .alert h2,
935 | .markdown-section blockquote h2 {
936 | font-size: 1.2rem;
937 | line-height: 1.35rem;
938 | }
939 |
940 | .markdown-section .alert h3,
941 | .markdown-section blockquote h3 {
942 | font-size: 1.15rem;
943 | line-height: 1.3rem;
944 | }
945 |
946 | .markdown-section .alert h4,
947 | .markdown-section blockquote h4 {
948 | font-size: 1.1rem;
949 | line-height: 1.25rem;
950 | }
951 |
952 | .markdown-section .alert h5,
953 | .markdown-section blockquote h5 {
954 | font-size: 1.05rem;
955 | line-height: 1.20rem;
956 | }
957 |
958 | .markdown-section .alert h6,
959 | .markdown-section blockquote h6 {
960 | font-size: 1rem;
961 | line-height: 1.15rem;
962 | }
963 | }
964 |
965 | /* Dark mode colours for use with Simple light + dark theme (uncomment to use) */
966 | @media (prefers-color-scheme: dark) {
967 | /*
968 | :root {
969 | --link-color: #1BA1EE!important;
970 |
971 | --sidebar-name-color: #1BA1EE!important;
972 | --sidebar-nav-link-color--active: #1BA1EE!important;
973 | --sidebar-nav-link-border-color--active: #1BA1EE!important;
974 |
975 | --sidebar-nav-pagelink-background--active:
976 | no-repeat 0px center / 5px 6px
977 | linear-gradient(225deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4.25px),
978 | no-repeat 5px center / 5px 6px
979 | linear-gradient(135deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4.25px)!important;
980 | --sidebar-nav-pagelink-background--collapse:
981 | no-repeat 2px calc(50% - 2.5px) / 6px 5px
982 | linear-gradient(45deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4px),
983 | no-repeat 2px calc(50% + 2.5px) / 6px 5px
984 | linear-gradient(135deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4px)!important;
985 | --sidebar-nav-pagelink-background--loaded:
986 | no-repeat 0px center / 5px 6px
987 | linear-gradient(225deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4.25px),
988 | no-repeat 5px center / 5px 6px
989 | linear-gradient(135deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4.25px)!important;
990 |
991 | --navbar-root-color--active: #1BA1EE!important;
992 | --navbar-root-color--active: #1BA1EE!important;
993 |
994 | --blockquote-border-color: #1BA1EE!important;
995 |
996 | --pagination-title-color: #1BA1EE!important;
997 | }
998 | }
999 | */
--------------------------------------------------------------------------------
/docs/assets/vendor/docsify/plugins/search.js:
--------------------------------------------------------------------------------
1 | (function () {
2 |
3 | /**
4 | * Converts a colon formatted string to a object with properties.
5 | *
6 | * This is process a provided string and look for any tokens in the format
7 | * of `:name[=value]` and then convert it to a object and return.
8 | * An example of this is ':include :type=code :fragment=demo' is taken and
9 | * then converted to:
10 | *
11 | * ```
12 | * {
13 | * include: '',
14 | * type: 'code',
15 | * fragment: 'demo'
16 | * }
17 | * ```
18 | *
19 | * @param {string} str The string to parse.
20 | *
21 | * @return {{str: string, config: object}} The original string formatted, and parsed object, { str, config }.
22 | */
23 | function getAndRemoveConfig(str = '') {
24 | const config = {};
25 |
26 | if (str) {
27 | str = str
28 | .replace(/^('|")/, '')
29 | .replace(/('|")$/, '')
30 | .replace(/(?:^|\s):([\w-]+:?)=?([\w-%]+)?/g, (m, key, value) => {
31 | if (key.indexOf(':') === -1) {
32 | config[key] = (value && value.replace(/"/g, '')) || true;
33 | return '';
34 | }
35 |
36 | return m;
37 | })
38 | .trim();
39 | }
40 |
41 | return { str, config };
42 | }
43 |
44 | /**
45 | * Remove the docsifyIgnore configs and return the str
46 | * @param {string} content The string to deal with.
47 | *
48 | * @return {{content: string, ignoreAllSubs: boolean, ignoreSubHeading: boolean}} The string after delete the docsifyIgnore configs, and whether to ignore some or all.
49 | */
50 | function getAndRemoveDocisfyIgnoreConfig(content = '') {
51 | let ignoreAllSubs, ignoreSubHeading;
52 | if (//g.test(content)) {
53 | content = content.replace('', '');
54 | ignoreSubHeading = true;
55 | }
56 |
57 | if (/{docsify-ignore}/g.test(content)) {
58 | content = content.replace('{docsify-ignore}', '');
59 | ignoreSubHeading = true;
60 | }
61 |
62 | if (//g.test(content)) {
63 | content = content.replace('', '');
64 | ignoreAllSubs = true;
65 | }
66 |
67 | if (/{docsify-ignore-all}/g.test(content)) {
68 | content = content.replace('{docsify-ignore-all}', '');
69 | ignoreAllSubs = true;
70 | }
71 |
72 | return { content, ignoreAllSubs, ignoreSubHeading };
73 | }
74 |
75 | /* eslint-disable no-unused-vars */
76 |
77 | let INDEXS = {};
78 |
79 | const LOCAL_STORAGE = {
80 | EXPIRE_KEY: 'docsify.search.expires',
81 | INDEX_KEY: 'docsify.search.index',
82 | };
83 |
84 | function resolveExpireKey(namespace) {
85 | return namespace
86 | ? `${LOCAL_STORAGE.EXPIRE_KEY}/${namespace}`
87 | : LOCAL_STORAGE.EXPIRE_KEY;
88 | }
89 |
90 | function resolveIndexKey(namespace) {
91 | return namespace
92 | ? `${LOCAL_STORAGE.INDEX_KEY}/${namespace}`
93 | : LOCAL_STORAGE.INDEX_KEY;
94 | }
95 |
96 | function escapeHtml(string) {
97 | const entityMap = {
98 | '&': '&',
99 | '<': '<',
100 | '>': '>',
101 | '"': '"',
102 | "'": ''',
103 | };
104 |
105 | return String(string).replace(/[&<>"']/g, s => entityMap[s]);
106 | }
107 |
108 | function getAllPaths(router) {
109 | const paths = [];
110 |
111 | Docsify.dom
112 | .findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])')
113 | .forEach(node => {
114 | const href = node.href;
115 | const originHref = node.getAttribute('href');
116 | const path = router.parse(href).path;
117 |
118 | if (
119 | path &&
120 | paths.indexOf(path) === -1 &&
121 | !Docsify.util.isAbsolutePath(originHref)
122 | ) {
123 | paths.push(path);
124 | }
125 | });
126 |
127 | return paths;
128 | }
129 |
130 | function getTableData(token) {
131 | if (!token.text && token.type === 'table') {
132 | token.rows.unshift(token.header);
133 | token.text = token.rows
134 | .map(columns => columns.map(r => r.text).join(' | '))
135 | .join(' |\n ');
136 | }
137 | return token.text;
138 | }
139 |
140 | function getListData(token) {
141 | if (!token.text && token.type === 'list') {
142 | token.text = token.raw;
143 | }
144 | return token.text;
145 | }
146 |
147 | function saveData(maxAge, expireKey, indexKey) {
148 | localStorage.setItem(expireKey, Date.now() + maxAge);
149 | localStorage.setItem(indexKey, JSON.stringify(INDEXS));
150 | }
151 |
152 | function genIndex(path, content = '', router, depth) {
153 | const tokens = window.marked.lexer(content);
154 | const slugify = window.Docsify.slugify;
155 | const index = {};
156 | let slug;
157 | let title = '';
158 |
159 | tokens.forEach((token, tokenIndex) => {
160 | if (token.type === 'heading' && token.depth <= depth) {
161 | const { str, config } = getAndRemoveConfig(token.text);
162 |
163 | const text = getAndRemoveDocisfyIgnoreConfig(token.text).content;
164 |
165 | // Extract title from Markdown link
166 | const match = text.match(/\[(.*?)\]\((.*?)\)/);
167 | let title = match ? match[1] : text;
168 | if (config.id) {
169 | slug = router.toURL(path, { id: slugify(config.id) });
170 | } else {
171 | // Sanitize title for ID only if using title for the slug
172 | slug = router.toURL(path, {
173 | id: slugify(title)
174 | .replace(/\//g, '') // Remove slashes
175 | .replace(/\?/g, '') // Remove question marks
176 | .replace(/[^a-zA-Z0-9-]/g, '-') // Replace other non-alphanumeric
177 | .replace(/^\(|\)$/g, '') // Remove parentheses
178 | .replace(/['"]/g, '') // Remove straight quotes
179 | .replace(/[\u2018\u2019\u201C\u201D]/g, '') // Remove curved quotes
180 | .replace(/^-/, '_') // Remove leading hyphen with underscore
181 | .toLowerCase()
182 | });
183 | }
184 |
185 | if (str) {
186 | title = getAndRemoveDocisfyIgnoreConfig(str).content;
187 | }
188 |
189 | index[slug] = { slug, title: title, body: '' };
190 | } else {
191 | if (tokenIndex === 0) {
192 | slug = router.toURL(path);
193 | index[slug] = {
194 | slug,
195 | title: path !== '/' ? path.slice(1) : 'Home Page',
196 | body: token.text || '',
197 | };
198 | }
199 |
200 | if (!slug) {
201 | return;
202 | }
203 |
204 | if (!index[slug]) {
205 | index[slug] = { slug, title: '', body: '' };
206 | } else if (index[slug].body) {
207 | token.text = getTableData(token);
208 | token.text = getListData(token);
209 |
210 | index[slug].body += '\n' + (token.text || '');
211 | } else {
212 | token.text = getTableData(token);
213 | token.text = getListData(token);
214 |
215 | index[slug].body = token.text || '';
216 | }
217 | }
218 | });
219 | slugify.clear();
220 | return index;
221 | }
222 |
223 | function ignoreDiacriticalMarks(keyword) {
224 | if (keyword && keyword.normalize) {
225 | return keyword.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
226 | }
227 | return keyword;
228 | }
229 |
230 | // Function to convert string to title case and replace hyphens with spaces
231 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI
232 | function convertToTitle(str) {
233 | return str
234 | .split('-') // Split the string by hyphens
235 | .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize the first letter and lower case the rest
236 | .join(' '); // Join the words with spaces
237 | }
238 |
239 | // Function to strip common Markdown markup
240 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI
241 | function stripCommonMarkdown(markdown) {
242 | // Regular expressions for common Markdown elements
243 | const regexes = [
244 | { pattern: /(\*\*|__)(.*?)\1/g, replacement: '$2' }, // Bold: **text** or __text__
245 | { pattern: /(\*|_)(.*?)\1/g, replacement: '$2' }, // Italic: *text* or _text_
246 | { pattern: /[-+*]\s+(.*?)/g, replacement: '$1' }, // Unordered lists: - item, + item, * item
247 | { pattern: /\d+\.\s+(.*?)/g, replacement: '$1' }, // Ordered lists: 1. item
248 | { pattern: /^#{1,6}\s+(.*)/gm, replacement: '$1' } // Headers: # Header, ## Header, etc.
249 | ];
250 |
251 | // Apply all regular expressions to the input text
252 | let plainText = markdown;
253 | regexes.forEach(({ pattern, replacement }) => {
254 | plainText = plainText.replace(pattern, replacement);
255 | });
256 |
257 | // Trim leading/trailing whitespace and return
258 | return plainText.trim();
259 | }
260 |
261 | // Function to replace Markdown links with their titles and remove Markdown images
262 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI
263 | function replaceMarkdownLinksWithTitlesandRemoveImages(content) {
264 | // Regular expression to match both Markdown images and links
265 | // Capture images separately to identify and remove them
266 | const markdownLinkRegex = /(!?\[([^\]]+)\]\(([^)]+)\))/g;
267 |
268 | return content.replace(markdownLinkRegex, (match, fullMatch, title, url) => {
269 | // Check if it's an image link by the presence of '!' at the start
270 | if (fullMatch.startsWith('!')) {
271 | // Return an empty string to remove the image
272 | return '';
273 | }
274 | // Otherwise, replace the link with its title
275 | return title;
276 | });
277 | }
278 |
279 | // Function to strip all HTML tags from a string
280 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI
281 | function stripHtmlTags(content) {
282 | // Regular expression to match HTML tags
283 | const htmlTagRegex = /<[^>]*>/g;
284 |
285 | // Replace all HTML tags with an empty string
286 | return content.replace(htmlTagRegex, '');
287 | }
288 |
289 | /**
290 | * @param {String} query Search query
291 | * @returns {Array} Array of results
292 | */
293 | function search(query) {
294 | const matchingResults = [];
295 | let data = [];
296 | Object.keys(INDEXS).forEach(key => {
297 | data = [
298 | ...data,
299 | ...Object.keys(INDEXS[key]).map(page => INDEXS[key][page]),
300 | ];
301 | });
302 |
303 | query = query.trim();
304 | let keywords = query.split(/[\s\-,\\/]+/);
305 | if (keywords.length !== 1) {
306 | keywords = [query, ...keywords];
307 | }
308 |
309 | for (const post of data) {
310 | let matchesScore = 0;
311 | let resultStr = '';
312 | let handlePostTitle = '';
313 | let handlePostContent = '';
314 | const postTitle = post.title && post.title.trim();
315 | const postContent = stripHtmlTags(stripCommonMarkdown(replaceMarkdownLinksWithTitlesandRemoveImages(post.body && post.body.trim())));
316 | const postUrl = post.slug || '';
317 | const postPageSlug = postUrl.split('/')[1].split('?')[0].replace('0', '');
318 | const postPageTitle = convertToTitle(postPageSlug);
319 |
320 | // Skip posts that contain iframes, Font Awesome icons, or embedly cards
321 | // console.log(postContent);
322 | // const isImage = /!\[[^\]]*\]\([^)]*\)/g.test(postContent); // Check if it's a Markdown image
323 |
324 | if (postContent.includes('iframe') || postContent.includes(':fas') || postContent.includes(':fab') || postContent.includes('embedly-card')) {
325 | continue;
326 | }
327 |
328 | if (postTitle) {
329 | keywords.forEach(keyword => {
330 | // From https://github.com/sindresorhus/escape-string-regexp
331 | const regEx = new RegExp(
332 | escapeHtml(ignoreDiacriticalMarks(keyword)).replace(
333 | /[|\\{}()[\]^$+*?.]/g,
334 | '\\$&'
335 | ),
336 | 'gi'
337 | );
338 | let indexTitle = -1;
339 | let indexContent = -1;
340 | handlePostTitle = postTitle
341 | ? escapeHtml(ignoreDiacriticalMarks(postTitle))
342 | : postTitle;
343 |
344 | // Remove Markdown link syntax from title
345 | handlePostTitle = handlePostTitle.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1').trim();
346 |
347 | handlePostContent = postContent
348 | ? escapeHtml(ignoreDiacriticalMarks(postContent))
349 | : postContent;
350 |
351 | indexTitle = postTitle ? handlePostTitle.search(regEx) : -1;
352 | indexContent = postContent ? handlePostContent.search(regEx) : -1;
353 |
354 | if (indexTitle >= 0 || indexContent >= 0) {
355 | matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0;
356 | if (indexContent < 0) {
357 | indexContent = 0;
358 | }
359 |
360 | let start = 0;
361 | let end = 0;
362 |
363 | start = indexContent < 11 ? 0 : indexContent - 10;
364 | end = start === 0 ? 70 : indexContent + keyword.length + 60;
365 |
366 | if (postContent && end > postContent.length) {
367 | end = postContent.length;
368 | }
369 |
370 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI
371 | const matchContent = handlePostContent && (() => {
372 | // Extract the substring where the match will be applied
373 | const contentSegment = handlePostContent.substring(start, end);
374 |
375 | // Find the first occurrence of the word using the regular expression
376 | const match = contentSegment.match(regEx);
377 |
378 | if (match) {
379 | // Get the position of the first match
380 | const matchIndex = contentSegment.indexOf(match[0]);
381 |
382 | // Split the content segment into before, match, and after parts
383 | const beforeMatch = contentSegment.substring(0, matchIndex);
384 | const firstMatch = contentSegment.substring(matchIndex, matchIndex + match[0].length);
385 | const afterMatch = contentSegment.substring(matchIndex + match[0].length);
386 |
387 | // Return the reassembled string with the first match wrapped in tags
388 | return '...' +
389 | beforeMatch +
390 | `${firstMatch} ` +
391 | afterMatch +
392 | '...';
393 | }
394 |
395 | // If no match is found, return the original segment surrounded by ellipses
396 | return '...' + contentSegment + '...';
397 | })();
398 |
399 | resultStr += matchContent;
400 | }
401 | });
402 |
403 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI
404 | // Only prepend postPageTitle when it is not empty and not equal to handlePostTitle (case insensitive)
405 | if (matchesScore > 0) {
406 | const matchingPost = {
407 | title: handlePostTitle,
408 | content: (
409 | // Convert both postPageTitle and handlePostTitle to lowercase for case-insensitive comparison
410 | postPageTitle &&
411 | postPageTitle.toLowerCase() !== handlePostTitle.toLowerCase() &&
412 | postPageTitle.toLowerCase() !== 'readme' // Exclude 'ReadMe' from being prepended
413 | ? `${postPageTitle} `
414 | : ''
415 | ) + (postContent ? resultStr : ''),
416 | url: postUrl,
417 | score: matchesScore,
418 | };
419 |
420 | matchingResults.push(matchingPost);
421 | }
422 | }
423 | }
424 |
425 | const uniquePageTitles = new Set();
426 | matchingResults.forEach(result => {
427 | const contentMatch = result.content.match(/^(.*?)<\/strong> /);
428 | if (contentMatch) {
429 | uniquePageTitles.add(contentMatch[1]);
430 | }
431 | });
432 |
433 | // If all results share the same postPageTitle, remove it from display
434 | if (uniquePageTitles.size === 1) {
435 | const sharedPageTitle = [...uniquePageTitles][0]; // Extract the single title
436 | matchingResults.forEach(result => {
437 | // Ensure we only remove the correct title, avoiding partial removals
438 | result.content = result.content.replace(new RegExp(`^${sharedPageTitle} `, 'i'), '');
439 | });
440 | }
441 |
442 | return matchingResults.sort((r1, r2) => r2.score - r1.score);
443 | }
444 |
445 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI
446 | function init$1(config, vm) {
447 | const isAuto = config.paths === 'auto';
448 | const paths = isAuto ? getAllPaths(vm.router) : config.paths;
449 |
450 | let namespaceSuffix = '';
451 |
452 | // only in auto mode
453 | if (paths.length && isAuto && config.pathNamespaces) {
454 | const path = paths[0];
455 |
456 | if (Array.isArray(config.pathNamespaces)) {
457 | namespaceSuffix =
458 | config.pathNamespaces.filter(
459 | prefix => path.slice(0, prefix.length) === prefix
460 | )[0] || namespaceSuffix;
461 | } else if (config.pathNamespaces instanceof RegExp) {
462 | const matches = path.match(config.pathNamespaces);
463 |
464 | if (matches) {
465 | namespaceSuffix = matches[0];
466 | }
467 | }
468 | const isExistHome = paths.indexOf(namespaceSuffix + '/') === -1;
469 | const isExistReadme = paths.indexOf(namespaceSuffix + '/README') === -1;
470 | if (isExistHome && isExistReadme) {
471 | paths.unshift(namespaceSuffix + '/');
472 | }
473 | } else if (paths.indexOf('/') === -1 && paths.indexOf('/README') === -1) {
474 | paths.unshift('/');
475 | }
476 |
477 | const expireKey = resolveExpireKey(config.namespace) + namespaceSuffix;
478 | const indexKey = resolveIndexKey(config.namespace) + namespaceSuffix;
479 |
480 | // Check if the database is expired
481 | const isExpired = localStorage.getItem(expireKey) < Date.now();
482 |
483 | if (isExpired) {
484 | // If expired, clear the existing database
485 | localStorage.removeItem(expireKey);
486 | localStorage.removeItem(indexKey);
487 | // console.log('Existing database expired and deleted.');
488 | } else {
489 | // console.log('Database is not expired, but it will still be reset.');
490 | }
491 |
492 | // Clear the database every load regardless of expiration
493 | localStorage.removeItem(expireKey);
494 | localStorage.removeItem(indexKey);
495 | // console.log('Existing database cleared.');
496 |
497 | // Initialize INDEXS to an empty object
498 | INDEXS = {};
499 |
500 | const len = paths.length;
501 | let count = 0;
502 |
503 | paths.forEach(path => {
504 | if (INDEXS[path]) {
505 | return count++;
506 | }
507 |
508 | Docsify.get(vm.router.getFile(path), false, vm.config.requestHeaders).then(
509 | result => {
510 | INDEXS[path] = genIndex(path, result, vm.router, config.depth);
511 | len === ++count && saveData(config.maxAge, expireKey, indexKey);
512 | }
513 | );
514 | });
515 | }
516 |
517 | /* eslint-disable no-unused-vars */
518 |
519 | let NO_DATA_TEXT = '';
520 | let options;
521 |
522 | function style() {
523 | const code = `
524 | .sidebar {
525 | padding-top: 0;
526 | }
527 |
528 | .search {
529 | margin-bottom: 20px;
530 | padding: 6px;
531 | border-bottom: 1px solid #eee;
532 | }
533 |
534 | .search .input-wrap {
535 | display: flex;
536 | align-items: center;
537 | }
538 |
539 | .search .results-status:not(:empty) {
540 | margin-top: 10px;
541 | font-size: smaller;
542 | }
543 |
544 | .search .results-panel {
545 | display: none;
546 | }
547 |
548 | .search .results-panel.show {
549 | display: block;
550 | }
551 |
552 | .search input {
553 | outline: none;
554 | border: none;
555 | width: 100%;
556 | padding: 0.6em 7px;
557 | font-size: inherit;
558 | border: 1px solid transparent;
559 | }
560 |
561 | .search input:focus {
562 | box-shadow: 0 0 5px var(--theme-color, #42b983);
563 | border: 1px solid var(--theme-color, #42b983);
564 | }
565 |
566 | .search input::-webkit-search-decoration,
567 | .search input::-webkit-search-cancel-button,
568 | .search input {
569 | -webkit-appearance: none;
570 | -moz-appearance: none;
571 | appearance: none;
572 | }
573 |
574 | .search input::-ms-clear {
575 | display: none;
576 | height: 0;
577 | width: 0;
578 | }
579 |
580 | .search .clear-button {
581 | cursor: pointer;
582 | width: 36px;
583 | text-align: right;
584 | display: none;
585 | }
586 |
587 | .search .clear-button.show {
588 | display: block;
589 | }
590 |
591 | .search .clear-button svg {
592 | transform: scale(.5);
593 | }
594 |
595 | .search kbd {
596 | position: absolute;
597 | right: 8px;
598 | margin: 0;
599 | }
600 |
601 | .search input:focus ~ kbd,
602 | .search input:not(:empty) ~ kbd {
603 | display: none;
604 | }
605 |
606 | .search h2 {
607 | font-size: 17px;
608 | margin: 10px 0;
609 | }
610 |
611 | .search a {
612 | text-decoration: none;
613 | color: inherit;
614 | }
615 |
616 | .search .matching-post {
617 | border-bottom: 1px solid #eee;
618 | }
619 |
620 | .search .matching-post:last-child {
621 | border-bottom: 0;
622 | }
623 |
624 | .search p {
625 | font-size: 14px;
626 | overflow: hidden;
627 | text-overflow: ellipsis;
628 | display: -webkit-box;
629 | -webkit-line-clamp: 2;
630 | -webkit-box-orient: vertical;
631 | }
632 |
633 | .search p.empty {
634 | text-align: center;
635 | }
636 |
637 | .sidebar-nav.hide {
638 | display: none;
639 | }`;
640 |
641 | Docsify.dom.style(code);
642 | }
643 |
644 | function tpl(defaultValue = '') {
645 | const html = /* html */ `
646 |
657 |
658 |
659 | `;
660 | const el = Docsify.dom.create('div', html);
661 | const aside = Docsify.dom.find('aside');
662 |
663 | Docsify.dom.toggleClass(el, 'search');
664 | el.setAttribute('role', 'search');
665 | Docsify.dom.before(aside, el);
666 | }
667 |
668 | function doSearch(value) {
669 | const $search = Docsify.dom.find('div.search');
670 | const $panel = Docsify.dom.find($search, '.results-panel');
671 | const $clearBtn = Docsify.dom.find($search, '.clear-button');
672 | const $sidebarNav = Docsify.dom.find('.sidebar-nav');
673 | const $status = Docsify.dom.find('div.search .results-status');
674 |
675 | if (!value) {
676 | $panel.classList.remove('show');
677 | $clearBtn.classList.remove('show');
678 | $panel.innerHTML = '';
679 | $status.textContent = '';
680 |
681 | if (options.hideOtherSidebarContent) {
682 | $sidebarNav && $sidebarNav.classList.remove('hide');
683 | }
684 |
685 | return;
686 | }
687 |
688 | const matches = search(value);
689 |
690 | let html = '';
691 | matches.forEach((post, i) => {
692 | html += /* html */ `
693 |
699 | `;
700 | });
701 |
702 | $panel.classList.add('show');
703 | $clearBtn.classList.add('show');
704 | $panel.innerHTML = html || /* html */ `${NO_DATA_TEXT}
`;
705 | $status.textContent = `Found ${matches.length} results`;
706 |
707 | if (options.hideOtherSidebarContent) {
708 | $sidebarNav && $sidebarNav.classList.add('hide');
709 | }
710 | }
711 |
712 | function bindEvents() {
713 | const $search = Docsify.dom.find('div.search');
714 | const $input = Docsify.dom.find($search, 'input');
715 | const $inputWrap = Docsify.dom.find($search, '.input-wrap');
716 |
717 | let timeId;
718 |
719 | /**
720 | Prevent to Fold sidebar.
721 |
722 | When searching on the mobile end,
723 | the sidebar is collapsed when you click the INPUT box,
724 | making it impossible to search.
725 | */
726 | Docsify.dom.on(
727 | $search,
728 | 'click',
729 | e =>
730 | ['A', 'H2', 'P', 'EM'].indexOf(e.target.tagName) === -1 &&
731 | e.stopPropagation()
732 | );
733 | Docsify.dom.on($input, 'input', e => {
734 | clearTimeout(timeId);
735 | timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100);
736 | });
737 | Docsify.dom.on($inputWrap, 'click', e => {
738 | // Click input outside
739 | if (e.target.tagName !== 'INPUT') {
740 | $input.value = '';
741 | doSearch();
742 | }
743 | });
744 | }
745 |
746 | function updatePlaceholder(text, path) {
747 | const $input = Docsify.dom.getNode('.search input[type="search"]');
748 |
749 | if (!$input) {
750 | return;
751 | }
752 |
753 | if (typeof text === 'string') {
754 | $input.placeholder = text;
755 | } else {
756 | const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0];
757 | $input.placeholder = text[match];
758 | }
759 | }
760 |
761 | function updateNoData(text, path) {
762 | if (typeof text === 'string') {
763 | NO_DATA_TEXT = text;
764 | } else {
765 | const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0];
766 | NO_DATA_TEXT = text[match];
767 | }
768 | }
769 |
770 | function updateOptions(opts) {
771 | options = opts;
772 | }
773 |
774 | function init(opts, vm) {
775 | const keywords = vm.router.parse().query.s;
776 |
777 | updateOptions(opts);
778 | style();
779 | tpl(keywords);
780 | bindEvents();
781 | keywords && setTimeout(_ => doSearch(keywords), 500);
782 | }
783 |
784 | function update(opts, vm) {
785 | updateOptions(opts);
786 | updatePlaceholder(opts.placeholder, vm.route.path);
787 | updateNoData(opts.noData, vm.route.path);
788 | }
789 |
790 | /* eslint-disable no-unused-vars */
791 |
792 | const CONFIG = {
793 | placeholder: 'Type to search',
794 | noData: 'No matches found.',
795 | paths: 'auto',
796 | depth: 2,
797 | maxAge: 86400000, // 1 day
798 | hideOtherSidebarContent: false,
799 | namespace: undefined,
800 | pathNamespaces: undefined,
801 | keyBindings: ['/', 'meta+k', 'ctrl+k'],
802 | };
803 |
804 | const install = function (hook, vm) {
805 | const { util } = Docsify;
806 | const opts = vm.config.search || CONFIG;
807 |
808 | if (Array.isArray(opts)) {
809 | CONFIG.paths = opts;
810 | } else if (typeof opts === 'object') {
811 | CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto';
812 | CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge;
813 | CONFIG.placeholder = opts.placeholder || CONFIG.placeholder;
814 | CONFIG.noData = opts.noData || CONFIG.noData;
815 | CONFIG.depth = opts.depth || CONFIG.depth;
816 | CONFIG.hideOtherSidebarContent =
817 | opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent;
818 | CONFIG.namespace = opts.namespace || CONFIG.namespace;
819 | CONFIG.pathNamespaces = opts.pathNamespaces || CONFIG.pathNamespaces;
820 | CONFIG.keyBindings = opts.keyBindings || CONFIG.keyBindings;
821 | }
822 |
823 | const isAuto = CONFIG.paths === 'auto';
824 |
825 | hook.init(() => {
826 | const { keyBindings } = vm.config;
827 |
828 | // Add key bindings
829 | if (keyBindings.constructor === Object) {
830 | keyBindings.focusSearch = {
831 | bindings: CONFIG.keyBindings,
832 | callback(e) {
833 | const sidebarElm = document.querySelector('.sidebar');
834 | const sidebarToggleElm = document.querySelector('.sidebar-toggle');
835 | const searchElm = sidebarElm?.querySelector('input[type="search"]');
836 | const isSidebarHidden = sidebarElm?.getBoundingClientRect().x < 0;
837 |
838 | isSidebarHidden && sidebarToggleElm?.click();
839 |
840 | setTimeout(() => searchElm?.focus(), isSidebarHidden ? 250 : 0);
841 | },
842 | };
843 | }
844 | });
845 | hook.mounted(_ => {
846 | init(CONFIG, vm);
847 | !isAuto && init$1(CONFIG, vm);
848 | });
849 | hook.doneEach(_ => {
850 | update(CONFIG, vm);
851 | isAuto && init$1(CONFIG, vm);
852 | });
853 | };
854 |
855 | window.$docsify = window.$docsify || {};
856 | $docsify.plugins = [install, ...($docsify.plugins || [])];
857 |
858 | })();
859 |
--------------------------------------------------------------------------------