@pimaonline/pimaonline-themepack 3.12.1 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -26
- package/dist/css/main.css +1 -1
- package/dist/css/plugins/alt-icons.css +1 -1
- package/dist/css/plugins/dark-mode.css +1 -0
- package/dist/css/plugins/font-awesome.css +1 -1
- package/dist/css/routes.css +1 -1
- package/dist/css/themes/ait/styles.css +1 -1
- package/dist/css/themes/ajs/styles.css +1 -1
- package/dist/css/themes/ant/styles.css +1 -0
- package/dist/css/themes/art/styles.css +1 -1
- package/dist/css/themes/aviation/styles.css +1 -1
- package/dist/css/themes/bct/styles.css +1 -1
- package/dist/css/themes/bio/styles.css +1 -1
- package/dist/css/themes/blobs/styles.css +1 -0
- package/dist/css/themes/business/styles.css +1 -1
- package/dist/css/themes/cad/styles.css +1 -1
- package/dist/css/themes/cards/styles.css +1 -1
- package/dist/css/themes/cas/styles.css +1 -0
- package/dist/css/themes/cda/styles.css +1 -1
- package/dist/css/themes/chm/styles.css +1 -0
- package/dist/css/themes/cis/styles.css +1 -1
- package/dist/css/themes/communication/styles.css +1 -1
- package/dist/css/themes/computer-information-systems/styles.css +1 -1
- package/dist/css/themes/culinary/styles.css +1 -1
- package/dist/css/themes/culinary/versions/black-marble.css +1 -1
- package/dist/css/themes/culinary/versions/stainless.css +1 -1
- package/dist/css/themes/culinary/versions/wood.css +1 -1
- package/dist/css/themes/dental/styles.css +1 -1
- package/dist/css/themes/ece/styles.css +1 -1
- package/dist/css/themes/ecn/styles.css +1 -1
- package/dist/css/themes/eng/styles.css +1 -1
- package/dist/css/themes/fashion/styles.css +1 -1
- package/dist/css/themes/fitness/styles.css +1 -1
- package/dist/css/themes/fsc/styles.css +1 -1
- package/dist/css/themes/geography/styles.css +1 -1
- package/dist/css/themes/geology/styles.css +1 -1
- package/dist/css/themes/health-it/styles.css +1 -1
- package/dist/css/themes/history/styles.css +1 -1
- package/dist/css/themes/hrm/styles.css +1 -1
- package/dist/css/themes/hrs/styles.css +1 -1
- package/dist/css/themes/journalism/styles.css +1 -1
- package/dist/css/themes/lang/styles.css +1 -1
- package/dist/css/themes/lgm/styles.css +1 -1
- package/dist/css/themes/machine/styles.css +1 -1
- package/dist/css/themes/math/styles.css +1 -1
- package/dist/css/themes/mgt/styles.css +1 -1
- package/dist/css/themes/minimalist/styles.css +1 -1
- package/dist/css/themes/mkt/styles.css +1 -0
- package/dist/css/themes/music/styles.css +1 -1
- package/dist/css/themes/nursing/styles.css +1 -0
- package/dist/css/themes/philosophy/styles.css +1 -1
- package/dist/css/themes/pht/styles.css +1 -1
- package/dist/css/themes/phy/styles.css +1 -0
- package/dist/css/themes/pos/styles.css +1 -0
- package/dist/css/themes/psy/styles.css +1 -1
- package/dist/css/themes/reading/styles.css +1 -0
- package/dist/css/themes/resort/styles.css +1 -1
- package/dist/css/themes/soc/styles.css +1 -1
- package/dist/css/themes/ss/styles.css +1 -1
- package/dist/css/themes/tps/styles.css +1 -0
- package/dist/css/themes/university/styles.css +1 -1
- package/dist/css/themes/vet/styles.css +1 -1
- package/dist/css/themes/welding/styles.css +1 -1
- package/dist/css/themes/writing/styles.css +1 -1
- package/dist/img/general/arrow-right-black.svg +1 -0
- package/dist/img/general/arrow-right-primary-blue.svg +1 -0
- package/dist/img/general/arrow-right-white.svg +1 -0
- package/dist/img/general/eye-icon.svg +4 -0
- package/dist/img/general/gear-icon.svg +3 -0
- package/dist/img/general/moon-icon.svg +4 -0
- package/dist/img/general/sliders-icon.svg +1 -0
- package/dist/img/general/text-icon.svg +4 -0
- package/dist/img/general/width-icon.svg +4 -0
- package/dist/img/theme-images/ant/texture.png +0 -0
- package/dist/img/theme-images/cas/city-vector.svg +92 -0
- package/dist/img/theme-images/cas/farm-vector.svg +1 -0
- package/dist/img/theme-images/cas/ocean-vector.svg +1 -0
- package/dist/img/theme-images/cas/recycle-symbol.svg +1 -0
- package/dist/img/theme-images/chm/chem-letters/letter-a.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-b.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-c.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-d.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-e.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-f.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-g.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-h.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-i.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-j.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-k.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-l.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-m.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-n.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-o.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-p.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-q.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-r.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-s.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-t.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-u.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-v.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-w.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-x.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-y.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-z.png +0 -0
- package/dist/img/theme-images/mkt/blue/bluebars.svg +36 -0
- package/dist/img/theme-images/mkt/blue/blueheader.jpg +0 -0
- package/dist/img/theme-images/mkt/blue/bluepie.svg +42 -0
- package/dist/img/theme-images/mkt/green/greenbars.svg +36 -0
- package/dist/img/theme-images/mkt/green/greenheader.jpg +0 -0
- package/dist/img/theme-images/mkt/green/greenpie.svg +42 -0
- package/dist/img/theme-images/mkt/yellow/yellowbars.svg +36 -0
- package/dist/img/theme-images/mkt/yellow/yellowheader.jpg +0 -0
- package/dist/img/theme-images/mkt/yellow/yellowpie.svg +42 -0
- package/dist/img/theme-images/nursing/blue/bottomright-blue.svg +95 -0
- package/dist/img/theme-images/nursing/blue/topleft-blue.svg +111 -0
- package/dist/img/theme-images/nursing/green/bottomright-green.svg +95 -0
- package/dist/img/theme-images/nursing/green/topleft-green.svg +111 -0
- package/dist/img/theme-images/nursing/purple/bottomright-purple.svg +95 -0
- package/dist/img/theme-images/nursing/purple/topleft-purple.svg +111 -0
- package/dist/img/theme-images/nursing/teal/bottomright-teal.svg +95 -0
- package/dist/img/theme-images/nursing/teal/topleft-teal.svg +111 -0
- package/dist/img/theme-images/phy/background.svg +150 -0
- package/dist/img/theme-images/phy/tape-style1.svg +8 -0
- package/dist/img/theme-images/reading/bg10.jpg +0 -0
- package/dist/js/scripts2.js +1 -1552
- package/dist/js/themes/blobs.js +1 -0
- package/dist/js/themes/cas.js +1 -0
- package/dist/js/themes/chm.js +1 -0
- package/dist/js/themes/ecn.js +1 -13
- package/dist/js/themes/hrs.js +1 -19
- package/dist/plugins/fancybox/fancybox-example.html +1 -1
- package/dist/plugins/fancybox/helpers/jquery.fancybox-buttons.js +2 -122
- package/dist/plugins/fancybox/helpers/jquery.fancybox-media.js +2 -201
- package/dist/plugins/fancybox/helpers/jquery.fancybox-thumbs.js +2 -165
- package/dist/plugins/fancybox/jquery.fancybox.js +2 -2018
- package/dist/plugins/fancybox/jquery.fancybox.pack.js +2 -46
- package/dist/plugins/flashcards/flashcards-example.html +1 -1
- package/dist/plugins/flashcards/js/flash_cards.min.js +1 -12
- package/dist/plugins/flashcards/js/plugins/flash_cards.js +1 -62
- package/dist/plugins/flashcards/js/plugins/jquery.cycle.js +2 -1148
- package/dist/plugins/flashcards/js/vendor/jquery-1.7.2.js +2 -9404
- package/dist/plugins/flashcards/js/vendor/jquery-1.7.2.min.js +2 -4
- package/dist/plugins/flashcards/js/vendor/modernizr-2.5.3.min.js +1 -4
- package/dist/plugins/floating-particles/floating-particles.js +1 -68
- package/dist/plugins/global-homepage-overrides/global-homepage-overrides.js +1 -53
- package/dist/plugins/preview-banner/preview-banner.js +1 -57
- package/package.json +12 -16
- package/dist/js/jumpTo.js +0 -4
- package/dist/js/scripts-ts.js +0 -1
- package/dist/js/scripts.js +0 -327
- package/dist/js/themes/ss.js +0 -197
package/dist/js/scripts2.js
CHANGED
|
@@ -1,1552 +1 @@
|
|
|
1
|
-
const columnWidget = document.querySelector("#column-widget");
|
|
2
|
-
const contentLockWidgets = document.querySelectorAll(".content-lock-widget");
|
|
3
|
-
const contentLockInstructions = document.querySelectorAll(".instructions");
|
|
4
|
-
const contentLockQuizzes = document.querySelectorAll(".quiz");
|
|
5
|
-
const contentWrapper = document.querySelector("#content-wrapper");
|
|
6
|
-
const courseBody = document.querySelector("body");
|
|
7
|
-
const docHead = document.querySelector("head");
|
|
8
|
-
const flipCards = document.querySelectorAll(".flip-card-group");
|
|
9
|
-
const focusReaderTooltipText = "Highlight text as you scroll";
|
|
10
|
-
const galleryWrappers = document.querySelectorAll(".gallery-wrapper");
|
|
11
|
-
const h5pIframes = document.querySelectorAll("iframe");
|
|
12
|
-
const h5pResizer = document.createElement("script");
|
|
13
|
-
const h5pResizerExists = docHead.querySelector("script[src='https://pima.h5p.com/js/h5p-resizer.js']");
|
|
14
|
-
// This array contains CDNs for Bootstrap and Remix icon libraries stored as objects
|
|
15
|
-
const iconClasses = [
|
|
16
|
-
{ class: "bi-", cdn: "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" },
|
|
17
|
-
{ class: "ri-", cdn: "https://cdn.jsdelivr.net/npm/remixicon@4.0.1/fonts/remixicon.css" }
|
|
18
|
-
];
|
|
19
|
-
const imageGallery = document.querySelector(".image-gallery");
|
|
20
|
-
const imgBoxes = document.querySelectorAll(".image-box");
|
|
21
|
-
const imgGalleries = document.querySelectorAll(".image-gallery");
|
|
22
|
-
const lockedContent = document.querySelectorAll(".locked-content");
|
|
23
|
-
const mediaContainers = document.querySelectorAll(".media-container");
|
|
24
|
-
const rolePres = document.querySelectorAll('[role="presentation"]');
|
|
25
|
-
const secondColumn = document.querySelector("#second-column");
|
|
26
|
-
const tables = document.querySelectorAll(".display, .display-lg")
|
|
27
|
-
const tabsWidgets = document.querySelectorAll(".tabs");
|
|
28
|
-
const thirdColumn = document.querySelector("#third-column");
|
|
29
|
-
const vocabCloseBtns = document.querySelectorAll("dl.vocab-list button");
|
|
30
|
-
const vocabDefs = document.querySelectorAll("dl.vocab-list dd");
|
|
31
|
-
const vocabListWidget = document.querySelector("dl.vocab-list");
|
|
32
|
-
const vocabLists = document.querySelectorAll("dl[class^='vocab-list']");
|
|
33
|
-
const vocabTerms = document.querySelectorAll("dl.vocab-list dt");
|
|
34
|
-
const videoWrapper = document.querySelector("#video-wrapper");
|
|
35
|
-
// JS to add role and aria-label to content-wrapper, second-column, and third-column
|
|
36
|
-
const addAria = () => {
|
|
37
|
-
if (contentWrapper) {
|
|
38
|
-
contentWrapper.setAttribute("role", "main");
|
|
39
|
-
} else if (!contentWrapper) {
|
|
40
|
-
console.log("Document error: does not contain #content-wrapper.");
|
|
41
|
-
}
|
|
42
|
-
if (secondColumn) {
|
|
43
|
-
secondColumn.setAttribute("role", "region");
|
|
44
|
-
secondColumn.setAttribute("aria-label", "Second column");
|
|
45
|
-
}
|
|
46
|
-
if (thirdColumn) {
|
|
47
|
-
thirdColumn.setAttribute("role", "region");
|
|
48
|
-
thirdColumn.setAttribute("aria-label", "Third column");
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
addAria();
|
|
52
|
-
const addGrid = () => {
|
|
53
|
-
if (contentWrapper && secondColumn && thirdColumn) {
|
|
54
|
-
courseBody.id = "three-column";
|
|
55
|
-
} else if (contentWrapper && secondColumn && !columnWidget) {
|
|
56
|
-
courseBody.id = "two-column";
|
|
57
|
-
} else if (contentWrapper && secondColumn && columnWidget) {
|
|
58
|
-
courseBody.id = "two-col-widget";
|
|
59
|
-
} else if ((contentWrapper && videoWrapper)) {
|
|
60
|
-
courseBody.id = "video-grid";
|
|
61
|
-
} else if (contentWrapper && !secondColumn && !thirdColumn && !columnWidget && !videoWrapper) {
|
|
62
|
-
courseBody.id = "one-column";
|
|
63
|
-
} else if (contentWrapper && !secondColumn && (thirdColumn || columnWidget)) {
|
|
64
|
-
console.log("Document error: <body> is missing id because #second-column doesn't exist.");
|
|
65
|
-
} else {
|
|
66
|
-
console.log("Document error: unable to determine the page layout for setting <body> id.");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const topLevelElements = document.body.children;
|
|
70
|
-
let foundNestedElement = false;
|
|
71
|
-
|
|
72
|
-
// Check for additional content outside #content-wrapper, #second-column, #third-column, or footer
|
|
73
|
-
for (let i = 0; i < topLevelElements.length; i++) {
|
|
74
|
-
const element = topLevelElements[i];
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
element.id !== "content-wrapper" &&
|
|
78
|
-
element.id !== "second-column" &&
|
|
79
|
-
element.id !== "third-column" &&
|
|
80
|
-
element.id !== "column-widget" &&
|
|
81
|
-
element.tagName !== "HEADER" &&
|
|
82
|
-
element.tagName !== "FOOTER" &&
|
|
83
|
-
element.tagName !== "SCRIPT" &&
|
|
84
|
-
element.id !== "loom-companion-mv3" &&
|
|
85
|
-
element.className !== "focus-reader-switches"
|
|
86
|
-
) {
|
|
87
|
-
foundNestedElement = true;
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (foundNestedElement) {
|
|
93
|
-
console.log("Document error: Additional content outside #content-wrapper, #second-column, #third-column, or footer.");
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
addGrid();
|
|
97
|
-
// Media Container
|
|
98
|
-
const addMediaContainersAria = () => {
|
|
99
|
-
mediaContainers.forEach((eachContainer, index) => {
|
|
100
|
-
// loopID: find the current index value, convert it to its letter equivalent, then convert to lowercase
|
|
101
|
-
let loopId = String.fromCharCode(index + 65).toLowerCase();
|
|
102
|
-
let mediaObject = eachContainer.querySelector(".media-object");
|
|
103
|
-
let iframe = eachContainer.querySelector("iframe");
|
|
104
|
-
let mediaInfo = eachContainer.querySelector(".media-info");
|
|
105
|
-
|
|
106
|
-
// Check if media container items are present
|
|
107
|
-
if (!iframe) {
|
|
108
|
-
console.log("Document error: no iframe found for media container");
|
|
109
|
-
}
|
|
110
|
-
if (!mediaObject) {
|
|
111
|
-
console.log("Document error: no media object found for media container");
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// If element DOES NOT have "aria-describedby" && it DOES have a sibling element.
|
|
115
|
-
if (!iframe.hasAttribute("aria-describedby") && mediaInfo != null) {
|
|
116
|
-
iframe.setAttribute("aria-describedby", `${loopId}`);
|
|
117
|
-
mediaInfo.id = `${[loopId]}`;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
if (mediaContainers) { addMediaContainersAria(); }
|
|
122
|
-
// -------- Add CDNs for Bootstrap and Remix icon libraries ---------
|
|
123
|
-
|
|
124
|
-
// The respective CDN will be added to <head> only if a page contains an icon with a prefix specific to that library. We use forEach to loop through iconClasses because that's more efficient than using multiple if statements to make sure only the necessary CDNs are added.
|
|
125
|
-
|
|
126
|
-
iconClasses.forEach(icon => {
|
|
127
|
-
const iconElement = document.querySelector(`[class*='${icon.class}']`);
|
|
128
|
-
if (iconElement) {
|
|
129
|
-
const metaTagRef = docHead.querySelector("meta[name='viewport']");
|
|
130
|
-
//Check if viewport meta tag exists
|
|
131
|
-
if (!metaTagRef) {
|
|
132
|
-
console.log("Document error: could not find viewport meta tag");
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const iconCDN = document.createElement("link");
|
|
136
|
-
iconCDN.setAttribute("href", icon.cdn);
|
|
137
|
-
iconCDN.setAttribute("rel", "stylesheet");
|
|
138
|
-
|
|
139
|
-
// Stylesheets are added after meta tag and before themepack stylesheets and scripts to ensure proper styling override
|
|
140
|
-
docHead.insertBefore(iconCDN, metaTagRef.nextSibling);
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
// Check if parent of .gallery-wrapper has .image-gallery class
|
|
144
|
-
const checkGalleryWrapperParent = () => {
|
|
145
|
-
galleryWrappers.forEach((galleryWrapper) => {
|
|
146
|
-
if (!galleryWrapper.parentNode.classList.contains("image-gallery")) {
|
|
147
|
-
console.log(`Document error: parent of .gallery-wrapper does not have the .image-gallery class.`);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
};
|
|
151
|
-
checkGalleryWrapperParent();
|
|
152
|
-
|
|
153
|
-
// Check if parent of .image-box has .gallery-wrapper class
|
|
154
|
-
const checkImageBoxParent = () => {
|
|
155
|
-
imgBoxes.forEach((imgBox) => {
|
|
156
|
-
if (!imgBox.parentNode.classList.contains("gallery-wrapper")) {
|
|
157
|
-
console.log(`Document error: parent of .image-box does not have the .gallery-wrapper class.`);
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
};
|
|
161
|
-
checkImageBoxParent();
|
|
162
|
-
|
|
163
|
-
// Check if direct children of .gallery-wrapper have .image-box class
|
|
164
|
-
const checkGalleryWrapperChildren = () => {
|
|
165
|
-
galleryWrappers.forEach((galleryWrapper) => {
|
|
166
|
-
let directChildren = Array.from(galleryWrapper.children).every(child => child.classList.contains("image-box"));
|
|
167
|
-
|
|
168
|
-
if (!directChildren) {
|
|
169
|
-
console.log(`Document error: not all direct children of .gallery-wrapper have the .image-box class.`);
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
};
|
|
173
|
-
checkGalleryWrapperChildren();
|
|
174
|
-
|
|
175
|
-
// Function to add Font Awesome CDN to the head
|
|
176
|
-
const addFontAwesomeCdn = () => {
|
|
177
|
-
const fontAwesomeCdn = document.createElement("link");
|
|
178
|
-
fontAwesomeCdn.rel = "stylesheet";
|
|
179
|
-
fontAwesomeCdn.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css";
|
|
180
|
-
docHead.appendChild(fontAwesomeCdn);
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
// Function to create modal box HTML string
|
|
184
|
-
const createModalBox = () => {
|
|
185
|
-
return `<div class="modal-box invisible">
|
|
186
|
-
<div class="gallery-overlay"></div>
|
|
187
|
-
<figure class="modal-box--image"><i class="fa-solid fa-x close-img"></i> <img src="#" alt="image here" /><figcaption class="img-caption"></figcaption></figure>
|
|
188
|
-
</div>
|
|
189
|
-
<button class="hide-gallery">Hide</button>`;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
// Function to initialize the image gallery
|
|
193
|
-
const callImageGallery = () => {
|
|
194
|
-
// Insert modal box HTML at the beginning of each image gallery
|
|
195
|
-
imgGalleries.forEach((gallery) => {
|
|
196
|
-
gallery.insertAdjacentHTML("afterbegin", createModalBox());
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
// Select necessary elements for later use
|
|
200
|
-
const overlay = document.querySelector(".gallery-overlay"),
|
|
201
|
-
modalBox = document.querySelector(".modal-box"),
|
|
202
|
-
modalImg = document.querySelector(".modal-box--image img"),
|
|
203
|
-
modalCaption = document.querySelector(".img-caption"),
|
|
204
|
-
closeImg = document.querySelector(".close-img"),
|
|
205
|
-
hideGalleries = document.querySelectorAll(".hide-gallery");
|
|
206
|
-
|
|
207
|
-
// Function to show modal with specified image source and caption
|
|
208
|
-
const showModal = (imgSrc, imgCaption) => {
|
|
209
|
-
modalBox.classList.remove("invisible");
|
|
210
|
-
modalImg.src = imgSrc;
|
|
211
|
-
modalCaption.innerHTML = imgCaption;
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// Function to hide the modal
|
|
215
|
-
const hideModal = () => {
|
|
216
|
-
modalBox.classList.add("invisible");
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
// Attach event listeners to each image box
|
|
220
|
-
imgBoxes.forEach((imgBox) => {
|
|
221
|
-
// Show modal on click
|
|
222
|
-
imgBox.addEventListener("click", function () {
|
|
223
|
-
showModal(this.querySelector("img").src, this.querySelector("img").alt);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
// Make images tab-able and show modal on Enter key press
|
|
227
|
-
imgBox.setAttribute("tabindex", "0");
|
|
228
|
-
imgBox.addEventListener("keydown", function (event) {
|
|
229
|
-
if (event.key === "Enter") {
|
|
230
|
-
showModal(this.querySelector("img").src, this.querySelector("img").alt);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// Attach event listeners for overlay, Escape key, and close button to hide the modal
|
|
236
|
-
overlay.onclick = hideModal;
|
|
237
|
-
window.onkeydown = (event) => {
|
|
238
|
-
if (event.keyCode === 27) {
|
|
239
|
-
hideModal();
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
closeImg.onclick = hideModal;
|
|
243
|
-
|
|
244
|
-
// Attach event listeners for "Hide/Show" button to toggle gallery visibility
|
|
245
|
-
hideGalleries.forEach((hideGallery) => {
|
|
246
|
-
hideGallery.addEventListener("click", () => {
|
|
247
|
-
hideGallery.nextElementSibling.classList.toggle("invisible");
|
|
248
|
-
hideGallery.innerHTML = hideGallery.innerHTML === "Hide" ? "Show" : "Hide";
|
|
249
|
-
});
|
|
250
|
-
});
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
// Check if imageGallery exists before initializing the image gallery
|
|
254
|
-
if (imageGallery) {
|
|
255
|
-
// Add Font Awesome CDN and initialize the image gallery
|
|
256
|
-
addFontAwesomeCdn();
|
|
257
|
-
callImageGallery();
|
|
258
|
-
}
|
|
259
|
-
//Tabs Widget
|
|
260
|
-
const callTabsWidget = () => {
|
|
261
|
-
|
|
262
|
-
let tabsWidgetsNum = 0;
|
|
263
|
-
|
|
264
|
-
tabsWidgets.forEach((tab, index) => {
|
|
265
|
-
let tabInputs = tab.querySelectorAll("input");
|
|
266
|
-
let tabLabels = tab.querySelectorAll("label");
|
|
267
|
-
let tabDivs = tab.querySelectorAll("div");
|
|
268
|
-
|
|
269
|
-
//Check that there are more than just one tab
|
|
270
|
-
if (tabInputs.length < 2 || tabLabels.length < 2 || tabDivs.length < 2) {
|
|
271
|
-
console.log("Document error: please add more than just one tab for tabs widget");
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// Check amount of tab elements present
|
|
275
|
-
if (tabInputs.length < tabLabels.length || tabInputs.length < tabDivs.length) {
|
|
276
|
-
console.log("Document error: missing tab input(s) in tab widget");
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (tabLabels.length < tabInputs.length || tabLabels.length < tabDivs.length) {
|
|
280
|
-
console.log("Document error: missing tab label(s) in tab widget");
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
let groupNum = index + 1;
|
|
284
|
-
|
|
285
|
-
//Add region and aria-label to parent div
|
|
286
|
-
tab.setAttribute("role", "region");
|
|
287
|
-
tab.setAttribute("aria-label", `tab group ${groupNum}`)
|
|
288
|
-
|
|
289
|
-
// Iterate over the entries of the tabInputs NodeList using a for loop. Inside the loop, tabIndex is the index of the current tab input element. tabInput is the actual input element itself.
|
|
290
|
-
for (tabIndex = 0; tabIndex < tabInputs.length; tabIndex++) {
|
|
291
|
-
|
|
292
|
-
// Add the hide-tab class to the "Hide" label
|
|
293
|
-
if (tabLabels[tabIndex].textContent.trim() === "Hide") {
|
|
294
|
-
tabLabels[tabIndex].classList.add("hide-tab");
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
let tabNum = tabsWidgetsNum + 1;
|
|
298
|
-
|
|
299
|
-
// Check on present variables
|
|
300
|
-
if (tabInputs === null) {
|
|
301
|
-
console.log("Document error: no inputs found for tabs widget");
|
|
302
|
-
console.log("Document error: no divs (tab panels) found for tabs widget");
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
if (tabLabels === null) {
|
|
306
|
-
console.log("Document error: no labels found for tabs widget");
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
//Add class, id, name, and aria-described by for inputs
|
|
310
|
-
tabInputs[tabIndex].classList.add("tab-input");
|
|
311
|
-
tabInputs[tabIndex].setAttribute("type", "radio")
|
|
312
|
-
tabInputs[tabIndex].setAttribute("id", `tab${tabNum}`);
|
|
313
|
-
tabInputs[tabIndex].setAttribute("name", `hint-group-${groupNum}`);
|
|
314
|
-
tabInputs[tabIndex].setAttribute("aria-describedby", `tabHeading${tabNum}`);
|
|
315
|
-
|
|
316
|
-
//Add class and for for labels
|
|
317
|
-
tabLabels[tabIndex].classList.add("tab-header");
|
|
318
|
-
tabLabels[tabIndex].setAttribute("for", `tab${tabNum}`);
|
|
319
|
-
|
|
320
|
-
//Add class, tabindex, and id for divs
|
|
321
|
-
if (tabDivs[tabIndex]) {
|
|
322
|
-
tabDivs[tabIndex].classList.add("tab-panel");
|
|
323
|
-
tabDivs[tabIndex].setAttribute("tabindex", 0);
|
|
324
|
-
tabDivs[tabIndex].setAttribute("id", `tabHeading${tabNum}`);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
//Add attributes for hide tab
|
|
328
|
-
if (tabIndex === 0) { // Change this condition to check the first tab
|
|
329
|
-
tabLabels[tabIndex].classList.remove("hide-tab"); // Remove the hide-tab class
|
|
330
|
-
tabInputs[tabIndex].checked = true; // Check the first tab input
|
|
331
|
-
if (tabDivs[tabIndex]) {
|
|
332
|
-
tabDivs[tabIndex].classList.remove("hide-panel"); // Remove the hide-panel class
|
|
333
|
-
}
|
|
334
|
-
} else {
|
|
335
|
-
tabInputs[tabIndex].checked = false;
|
|
336
|
-
if (tabDivs[tabIndex]) {
|
|
337
|
-
tabDivs[tabIndex].classList.add("hide-panel");
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// Add click event listener to each tab label
|
|
342
|
-
tabLabels[tabIndex].addEventListener("click", ((index) => {
|
|
343
|
-
return () => {
|
|
344
|
-
// Check if the clicked label is the "Hide" label
|
|
345
|
-
if (tabLabels[index].textContent.trim() === "Hide") {
|
|
346
|
-
// Hide all tab panels
|
|
347
|
-
tabDivs.forEach(div => div.classList.add("hide-panel"));
|
|
348
|
-
} else {
|
|
349
|
-
// Uncheck all tab inputs
|
|
350
|
-
tabInputs.forEach(input => input.checked = false);
|
|
351
|
-
// Check the clicked tab input
|
|
352
|
-
tabInputs[index].checked = true;
|
|
353
|
-
// Show the clicked tab panel
|
|
354
|
-
if (tabDivs[index]) {
|
|
355
|
-
tabDivs[index].classList.remove("hide-panel");
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
};
|
|
359
|
-
})(tabIndex)); // Immediately invoke the function with the current tabIndex
|
|
360
|
-
|
|
361
|
-
tabsWidgetsNum++;
|
|
362
|
-
}
|
|
363
|
-
})
|
|
364
|
-
}
|
|
365
|
-
if (tabsWidgets) { callTabsWidget(); }
|
|
366
|
-
// Vocab list widget
|
|
367
|
-
const callVocabList = () => {
|
|
368
|
-
|
|
369
|
-
const handleVocabClose = (vocabItem) => {
|
|
370
|
-
if (vocabItem) {
|
|
371
|
-
let listDefinitions = vocabItem.querySelectorAll("dd");
|
|
372
|
-
let listTerms = vocabItem.querySelectorAll("dt");
|
|
373
|
-
|
|
374
|
-
// If the button is clicked and it is the DD - then hide it
|
|
375
|
-
listDefinitions.forEach((definition) => {
|
|
376
|
-
definition.style.display = "none";
|
|
377
|
-
})
|
|
378
|
-
|
|
379
|
-
// If the button is clicked and it is the DT - then remove active class
|
|
380
|
-
listTerms.forEach((term) => {
|
|
381
|
-
term.classList.remove("active");
|
|
382
|
-
})
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
// Check if the vocab list has one or multiple items within
|
|
387
|
-
vocabLists.forEach((list) => {
|
|
388
|
-
|
|
389
|
-
//Count and ensure it has more than 1 term and definition
|
|
390
|
-
let terms = 0;
|
|
391
|
-
let definitions = 0;
|
|
392
|
-
let closeBtnPresent = false;
|
|
393
|
-
|
|
394
|
-
// If the list contains more than one set of <dt> and <dd> tags then add a close button
|
|
395
|
-
for (let listIndex = 0; listIndex < list.children.length; listIndex++) {
|
|
396
|
-
// Count terms
|
|
397
|
-
if (list.children[listIndex].tagName == "DT") {
|
|
398
|
-
list.children[listIndex].setAttribute("tabindex", "0");
|
|
399
|
-
terms++;
|
|
400
|
-
}
|
|
401
|
-
// Count definitions
|
|
402
|
-
if (list.children[listIndex].tagName == "DD") {
|
|
403
|
-
definitions++;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
//Check for close all button
|
|
407
|
-
if (list.children[listIndex].tagName == "BUTTON") {
|
|
408
|
-
closeBtnPresent = true;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// Check for terms and definitions in the vocab list
|
|
413
|
-
if (terms < 1) {
|
|
414
|
-
console.log("Document error: no terms found in vocab list");
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
if (definitions < 1) {
|
|
418
|
-
console.log("Document error: no definitions found in vocab list");
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
if (terms > definitions) {
|
|
422
|
-
console.log("Document error: more terms than definitions in vocab list")
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// If there are more than 2 terms and 2 definitions, then check for a button
|
|
426
|
-
if (terms >= 2 && definitions >= 2) {
|
|
427
|
-
|
|
428
|
-
// If there isn't a close button then add one
|
|
429
|
-
if (!closeBtnPresent) {
|
|
430
|
-
// Add a close button
|
|
431
|
-
const closeButton = document.createElement("button");
|
|
432
|
-
closeButton.textContent = "Close All"; // Set the button text as needed
|
|
433
|
-
// Add click event listener for button
|
|
434
|
-
closeButton.addEventListener("click", () => handleVocabClose(list))
|
|
435
|
-
|
|
436
|
-
// Add keydown event listener for button
|
|
437
|
-
closeButton.addEventListener("keydown", (event) => {
|
|
438
|
-
if (event.key == "Enter") {
|
|
439
|
-
handleVocabClose(list);
|
|
440
|
-
}
|
|
441
|
-
})
|
|
442
|
-
// Append the button to the end of the list
|
|
443
|
-
list.appendChild(closeButton);
|
|
444
|
-
}
|
|
445
|
-
// If button is present, remove it
|
|
446
|
-
else {
|
|
447
|
-
let closeBtn = list.querySelector("button");
|
|
448
|
-
|
|
449
|
-
// Add the same event listeners as if you were to add a new button
|
|
450
|
-
closeBtn.addEventListener("click", () => handleVocabClose(list))
|
|
451
|
-
|
|
452
|
-
closeBtn.addEventListener("keydown", (event) => {
|
|
453
|
-
if (event.key == "Enter") {
|
|
454
|
-
handleVocabClose(list);
|
|
455
|
-
}
|
|
456
|
-
})
|
|
457
|
-
|
|
458
|
-
}
|
|
459
|
-
} else {
|
|
460
|
-
|
|
461
|
-
// List does not have more than 2 pairs of terms and definitions
|
|
462
|
-
|
|
463
|
-
// Don't add a close button since there is only one term, but remove the button if it is present
|
|
464
|
-
for (let listIndex = 0; listIndex < list.children.length; listIndex++) {
|
|
465
|
-
|
|
466
|
-
//Check for close all button
|
|
467
|
-
if (list.children[listIndex].tagName == "BUTTON") {
|
|
468
|
-
closeBtnPresent = true;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
if (closeBtnPresent) {
|
|
473
|
-
let closeBtn = list.querySelector("button");
|
|
474
|
-
closeBtn.style.display = "none";
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
})
|
|
478
|
-
|
|
479
|
-
// Loop through all the terms and apply click and keydown event
|
|
480
|
-
for (let activeTerm = 0; activeTerm < vocabTerms.length; activeTerm++) {
|
|
481
|
-
// Add click event for toggling vocab terms
|
|
482
|
-
vocabTerms[activeTerm].addEventListener("click", function () {
|
|
483
|
-
// When clicked, toggle the active class
|
|
484
|
-
this.classList.toggle("active");
|
|
485
|
-
|
|
486
|
-
// Target the definition <dd> element
|
|
487
|
-
let termPanel = this.nextElementSibling;
|
|
488
|
-
|
|
489
|
-
// Toggle the display from none to block
|
|
490
|
-
if (termPanel.style.display === "block") {
|
|
491
|
-
termPanel.style.display = "none";
|
|
492
|
-
} else {
|
|
493
|
-
termPanel.style.display = "block";
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
// Start a while loop to continue through the DOM
|
|
497
|
-
while (termPanel.nextElementSibling) {
|
|
498
|
-
// Move to the next sibling element
|
|
499
|
-
termPanel = termPanel.nextElementSibling;
|
|
500
|
-
|
|
501
|
-
// Check if the current element is a <dd>
|
|
502
|
-
if (termPanel.tagName === "DD") {
|
|
503
|
-
// Toggle the display from none to block
|
|
504
|
-
if (termPanel.style.display === "block") {
|
|
505
|
-
termPanel.style.display = "none";
|
|
506
|
-
} else {
|
|
507
|
-
termPanel.style.display = "block";
|
|
508
|
-
}
|
|
509
|
-
} else {
|
|
510
|
-
// Stop the loop if the current element is not a <dd>
|
|
511
|
-
break;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
// Add keydown event for toggling vocab terms
|
|
518
|
-
vocabTerms[activeTerm].addEventListener("keydown", function (e) {
|
|
519
|
-
|
|
520
|
-
// When user hits enter, toggle the active class
|
|
521
|
-
if (e.key === "Enter") {
|
|
522
|
-
// When clicked, toggle the active class
|
|
523
|
-
this.classList.toggle("active");
|
|
524
|
-
|
|
525
|
-
// Target the definition <dd> element
|
|
526
|
-
let termPanel = this.nextElementSibling;
|
|
527
|
-
|
|
528
|
-
// Toggle the display from none to block
|
|
529
|
-
if (termPanel.style.display === "block") {
|
|
530
|
-
termPanel.style.display = "none";
|
|
531
|
-
} else {
|
|
532
|
-
termPanel.style.display = "block";
|
|
533
|
-
}
|
|
534
|
-
// Start a while loop to continue through the DOM
|
|
535
|
-
while (termPanel.nextElementSibling) {
|
|
536
|
-
// Move to the next sibling element
|
|
537
|
-
termPanel = termPanel.nextElementSibling;
|
|
538
|
-
|
|
539
|
-
// Check if the current element is a <dd>
|
|
540
|
-
if (termPanel.tagName === "DD") {
|
|
541
|
-
// Toggle the display from none to block
|
|
542
|
-
if (termPanel.style.display === "block") {
|
|
543
|
-
termPanel.style.display = "none";
|
|
544
|
-
} else {
|
|
545
|
-
termPanel.style.display = "block";
|
|
546
|
-
}
|
|
547
|
-
} else {
|
|
548
|
-
// Stop the loop if the current element is not a <dd>
|
|
549
|
-
break;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
if (vocabListWidget) { callVocabList(); }
|
|
557
|
-
// Clean up HTML
|
|
558
|
-
const cleanMarkup = () => {
|
|
559
|
-
// Remove role="presentation" attr from any element that has it
|
|
560
|
-
if (rolePres) {
|
|
561
|
-
rolePres.forEach((roleElem) => roleElem.removeAttribute("role"));
|
|
562
|
-
}
|
|
563
|
-
// Set functino to remove atrributes from elements
|
|
564
|
-
const discardAttributes = (element, ...attributes) => {
|
|
565
|
-
attributes.forEach((attribute) => element.removeAttribute(attribute));
|
|
566
|
-
}
|
|
567
|
-
// Remove attributes from tables
|
|
568
|
-
const tableElems = document.querySelectorAll("table, thead, tbody, tr, th, td");
|
|
569
|
-
tableElems.forEach((elem) => {
|
|
570
|
-
discardAttributes(elem, "cellspacing", "cellpadding", "width", "style");
|
|
571
|
-
});
|
|
572
|
-
};
|
|
573
|
-
cleanMarkup();
|
|
574
|
-
const handleContentLockWidget = (contentLockWidgets) => {
|
|
575
|
-
|
|
576
|
-
const lockedContentQuizIncorrectAnswer = "Incorrect response. Please try again."; // Error response for quizzes
|
|
577
|
-
const lockedContentQuizEmptyResponse = "Please select an option before submitting."; // Error response for quizzes
|
|
578
|
-
const unlockBtnContent = []; // Save text content of unlock button
|
|
579
|
-
|
|
580
|
-
// ––––––––– Functions –––––––––
|
|
581
|
-
|
|
582
|
-
// Function to run when local storage is updated
|
|
583
|
-
const handleContentLockLocalStorageUpdate = (event, courseNumber) => {
|
|
584
|
-
if (event && event.key === "contentLockData" && event.newValue) {
|
|
585
|
-
// Update contentLockData variable
|
|
586
|
-
contentLockData = JSON.parse(event.newValue);
|
|
587
|
-
// Run your code here
|
|
588
|
-
checkHiddenContent(courseNumber);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
// Function that checks key status, toggles classes, and updates local storage, and checks for other content areas
|
|
593
|
-
const unlockCheck = (contentLockKeyNum, courseNumber, buttonIndex) => {
|
|
594
|
-
|
|
595
|
-
// Toggle the key status to true to unlock the content
|
|
596
|
-
contentLockData[courseNumber].keys[contentLockKeyNum] = true;
|
|
597
|
-
|
|
598
|
-
// Toggle classes based on key status
|
|
599
|
-
if (contentLockData[courseNumber].keys[contentLockKeyNum]) {
|
|
600
|
-
lockedContent[buttonIndex].classList.add("open");
|
|
601
|
-
contentLockInstructions[buttonIndex].classList.add("complete");
|
|
602
|
-
} else {
|
|
603
|
-
lockedContent[buttonIndex].classList.remove("open");
|
|
604
|
-
contentLockInstructions[buttonIndex].classList.remove("complete");
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// Save the updated contentLockData object to local storage
|
|
608
|
-
localStorage.setItem("contentLockData", JSON.stringify(contentLockData));
|
|
609
|
-
|
|
610
|
-
// Update the hidden content based on the key status
|
|
611
|
-
checkHiddenContent(courseNumber);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
// Function to display the error message from the form
|
|
615
|
-
const displayError = (quizForm, contentLockErrorMessage) => {
|
|
616
|
-
|
|
617
|
-
// Create a new paragraph element for the error message
|
|
618
|
-
let contentLockerrorContainer = quizForm.querySelector(".error-container");
|
|
619
|
-
let errorMessage = document.createElement("span");
|
|
620
|
-
|
|
621
|
-
// Clear any previous error messages
|
|
622
|
-
contentLockerrorContainer.innerHTML = "";
|
|
623
|
-
|
|
624
|
-
// Clear error message
|
|
625
|
-
errorMessage.textContent = "";
|
|
626
|
-
|
|
627
|
-
// Append the blank text message to the container
|
|
628
|
-
contentLockerrorContainer.appendChild(errorMessage);
|
|
629
|
-
|
|
630
|
-
// Add a timer to apply the new error message to ensure the user understands it is a new error message
|
|
631
|
-
setTimeout(function () {
|
|
632
|
-
|
|
633
|
-
// Clear error message
|
|
634
|
-
errorMessage.textContent = contentLockErrorMessage;
|
|
635
|
-
|
|
636
|
-
// Append the new error message to the container
|
|
637
|
-
contentLockerrorContainer.appendChild(errorMessage);
|
|
638
|
-
|
|
639
|
-
}, 200); // 200 milliseconds = .2 seconds
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
// Quiz checking function
|
|
643
|
-
const submitContentLockQuiz = (contentLockKeyNum) => {
|
|
644
|
-
let contentLockQuizForm = document.getElementById(`quiz${contentLockKeyNum}`);
|
|
645
|
-
|
|
646
|
-
// This selects the option that the user selected
|
|
647
|
-
let selectedOption = contentLockQuizForm.querySelector("input[name='options']:checked");
|
|
648
|
-
|
|
649
|
-
// This finds the input option that had the correct answer
|
|
650
|
-
let contentLockQuizcorrectAnswer = contentLockQuizForm.querySelector("input.correct-answer");
|
|
651
|
-
|
|
652
|
-
// Initialize a variable for error message, that can changed based on which error
|
|
653
|
-
let contentLockErrorMessage = "";
|
|
654
|
-
|
|
655
|
-
// If there is a selected option, run the logic to see if it matches
|
|
656
|
-
if (selectedOption) {
|
|
657
|
-
// If selected option matches correct answer
|
|
658
|
-
if (selectedOption.value === contentLockQuizcorrectAnswer.value) {
|
|
659
|
-
|
|
660
|
-
// Tells the user they selected the correct response
|
|
661
|
-
alert("Correct response");
|
|
662
|
-
return true;
|
|
663
|
-
} else {
|
|
664
|
-
|
|
665
|
-
// Sets the error message for the user
|
|
666
|
-
contentLockErrorMessage = lockedContentQuizIncorrectAnswer;
|
|
667
|
-
displayError(contentLockQuizForm, contentLockErrorMessage)
|
|
668
|
-
return false;
|
|
669
|
-
}
|
|
670
|
-
} else {
|
|
671
|
-
contentLockErrorMessage = lockedContentQuizEmptyResponse;
|
|
672
|
-
displayError(contentLockQuizForm, contentLockErrorMessage)
|
|
673
|
-
return false;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
/* This function loops through each content area on the page
|
|
678
|
-
* and checks the status of the data-key to see if it should
|
|
679
|
-
* be unlocked or not
|
|
680
|
-
*/
|
|
681
|
-
const checkHiddenContent = (courseNumber) => {
|
|
682
|
-
|
|
683
|
-
// Get data-key number for each content area
|
|
684
|
-
lockedContent.forEach((contentArea, contentAreaIndex) => {
|
|
685
|
-
let contentLockKeyNum = contentArea.getAttribute("data-key");
|
|
686
|
-
|
|
687
|
-
// Toggle classes based on key status
|
|
688
|
-
if (contentLockData[courseNumber].keys[contentLockKeyNum]) {
|
|
689
|
-
lockedContent[contentAreaIndex].classList.add("open");
|
|
690
|
-
contentLockInstructions[contentAreaIndex].classList.add("complete");
|
|
691
|
-
} else {
|
|
692
|
-
lockedContent[contentAreaIndex].classList.remove("open");
|
|
693
|
-
contentLockInstructions[contentAreaIndex].classList.remove("complete");
|
|
694
|
-
}
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
/* This function is when a user clicks or keysdown to unlock
|
|
699
|
-
* a content area. This function is the same wether clicked on
|
|
700
|
-
* or if it is through a keyboard
|
|
701
|
-
*/
|
|
702
|
-
const handleContentUnlock = (unlockButton, buttonIndex, unlockBtnContent, courseNumber) => {
|
|
703
|
-
|
|
704
|
-
/* This variable acts as a flag, for determining if a content unlock button is related to a quiz
|
|
705
|
-
* or if the content related to this button is supposed to use a confirmation window.
|
|
706
|
-
*/
|
|
707
|
-
let quizElement = false;
|
|
708
|
-
|
|
709
|
-
// Loop through all the contentUnlockBtns and add an event listener
|
|
710
|
-
|
|
711
|
-
let contentLockKeyNum = lockedContent[buttonIndex].getAttribute("data-key");
|
|
712
|
-
|
|
713
|
-
// This is used as a flag. Needs to be set to true in order to unlock the content
|
|
714
|
-
let contentLockAnswerConfirmed = false;
|
|
715
|
-
|
|
716
|
-
//Query Selector to see if there is a quiz option or not
|
|
717
|
-
if (unlockButton.tagName === "INPUT") {
|
|
718
|
-
quizElement = true;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
// If quiz exists for this data key number, otherwise, do the confirmation window
|
|
722
|
-
if (quizElement) {
|
|
723
|
-
|
|
724
|
-
// Show the html for the quiz. The html will handle the quiz functionality. Returns true or false.
|
|
725
|
-
contentLockAnswerConfirmed = submitContentLockQuiz(contentLockKeyNum)
|
|
726
|
-
if (contentLockAnswerConfirmed) {
|
|
727
|
-
|
|
728
|
-
// Unlock the content and perform other related actions (see function for more)
|
|
729
|
-
unlockCheck(contentLockKeyNum, courseNumber, buttonIndex)
|
|
730
|
-
}
|
|
731
|
-
} else {
|
|
732
|
-
|
|
733
|
-
/* Add a confirmation window that pops up and waits for the user to confirm
|
|
734
|
-
* the instructions were followed to unlock the content(if no quiz is available)
|
|
735
|
-
*/
|
|
736
|
-
contentLockAnswerConfirmed = window.confirm(`Please confirm: ${unlockBtnContent[buttonIndex]}`)
|
|
737
|
-
|
|
738
|
-
if (contentLockAnswerConfirmed) {
|
|
739
|
-
unlockCheck(contentLockKeyNum, courseNumber, buttonIndex)
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
// –––––––––––––––– End of Functions ––––––––––––––––
|
|
745
|
-
|
|
746
|
-
// Checks the URL for the course number
|
|
747
|
-
const currentURL = window.parent.location.href;
|
|
748
|
-
const match = currentURL.match(/\/content\/(\d+)/);
|
|
749
|
-
const courseNumber = match ? match[1] : null;
|
|
750
|
-
|
|
751
|
-
// Error Checking - course number exists
|
|
752
|
-
if (!courseNumber) {
|
|
753
|
-
console.log("Document Error: course number does not exist");
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
// Letters are used in inputs as values. Each letter represents an input option.
|
|
757
|
-
const optionLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
|
|
758
|
-
|
|
759
|
-
// Create an object that keeps track of keys and their statuses
|
|
760
|
-
const contentLockData = JSON.parse(localStorage.getItem("contentLockData")) || {};
|
|
761
|
-
|
|
762
|
-
// Add event listener for storage changes
|
|
763
|
-
window.addEventListener("storage", (event) => {
|
|
764
|
-
if (courseNumber) {
|
|
765
|
-
handleContentLockLocalStorageUpdate(event, courseNumber);
|
|
766
|
-
}
|
|
767
|
-
});
|
|
768
|
-
|
|
769
|
-
// Apply the quiz IDs and search if quizzes are being used
|
|
770
|
-
contentLockWidgets.forEach((contentLockWidget, contentLockWidgetIndex) => {
|
|
771
|
-
|
|
772
|
-
let contentLockForm = contentLockWidget.querySelector(".quiz form");
|
|
773
|
-
|
|
774
|
-
/* If a quiz is present in content lock widget, then go through the page
|
|
775
|
-
* and assign the quiz ID based on the data-key for the corresponding
|
|
776
|
-
* locked-content.
|
|
777
|
-
*/
|
|
778
|
-
if (contentLockForm) {
|
|
779
|
-
let lockedContent = contentLockWidget.querySelector(".locked-content");
|
|
780
|
-
let contentLockKeyNum = lockedContent.getAttribute("data-key");
|
|
781
|
-
let contentLockQuizcorrectAnswer = contentLockWidget.querySelector(".quiz .correct-answer");
|
|
782
|
-
|
|
783
|
-
// Error checking - locked-content class
|
|
784
|
-
if (!lockedContent) {
|
|
785
|
-
console.log(`Document Error: missing the locked-content class for widget number ${contentLockWidgetIndex + 1} on this page`)
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
// Error checking - data key
|
|
789
|
-
if (!contentLockKeyNum) {
|
|
790
|
-
console.log(`Document Error: missing data-key for locked content for widget number ${contentLockWidgetIndex + 1} on this page`)
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
// Error Check - correct-answer class for the quiz
|
|
794
|
-
if (!contentLockQuizcorrectAnswer) {
|
|
795
|
-
console.log(`Document Error: missing correct-answer for content lock quiz for widget number ${contentLockWidgetIndex + 1} on this page`)
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
// Assign each form an ID
|
|
799
|
-
contentLockForm.id = `quiz${contentLockKeyNum}`;
|
|
800
|
-
|
|
801
|
-
// Search for error container in the widget
|
|
802
|
-
let errorContainerExists = contentLockWidget.querySelector(".error-container");
|
|
803
|
-
|
|
804
|
-
// If the error container doesn't exist, add it via HTML
|
|
805
|
-
if (!errorContainerExists) {
|
|
806
|
-
let errorContainer = document.createElement("div");
|
|
807
|
-
errorContainer.classList.add("error-container");
|
|
808
|
-
let contentLockSubmitBtn = contentLockWidget.querySelector("input[value='Submit']");
|
|
809
|
-
if (contentLockSubmitBtn) {
|
|
810
|
-
// Add the error container above the submit button in the quiz
|
|
811
|
-
contentLockSubmitBtn.insertAdjacentHTML("beforebegin", errorContainer.outerHTML)
|
|
812
|
-
} else {
|
|
813
|
-
console.log(`Document Error: quiz is missing an input with value 'Submit' for widget number ${contentLockWidgetIndex + 1} on this page.`)
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
// If the content lock widget does not use a form and uses a confirmation window instead
|
|
818
|
-
else {
|
|
819
|
-
// Error checking - ensure it has an unlock button in the HTML
|
|
820
|
-
let unlockBtn = contentLockWidget.querySelector(".unlock-btn");
|
|
821
|
-
if (!unlockBtn) {
|
|
822
|
-
console.log(`Document Error: locked content area (that is not using a quiz) is missing <a> with .unlock-btn for widget number ${contentLockWidgetIndex + 1} on this page.`)
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
})
|
|
826
|
-
|
|
827
|
-
/* Function to apply attributes to quiz elements. This function uses
|
|
828
|
-
* an asynchronous function to ensure that the JS doesn't run until
|
|
829
|
-
* after this function is complete and the promise has been returned.
|
|
830
|
-
* This helps ensure that no other querySelectors are broken.
|
|
831
|
-
*/
|
|
832
|
-
const applyAttributesToQuiz = () => {
|
|
833
|
-
|
|
834
|
-
// Returns the resolve value or reject value depending on if the promise is successful or fails
|
|
835
|
-
return new Promise((resolve, reject) => {
|
|
836
|
-
let contentLockQuizForms = document.querySelectorAll(".quiz form");
|
|
837
|
-
|
|
838
|
-
// If there are forms, then apply the specific attributes to the inputs
|
|
839
|
-
if (contentLockQuizForms) {
|
|
840
|
-
contentLockQuizForms.forEach((quizForm) => {
|
|
841
|
-
let quizInputs = quizForm.querySelectorAll("input");
|
|
842
|
-
|
|
843
|
-
// Loop through all the inputs and apply the correct attributes
|
|
844
|
-
quizInputs.forEach((quizInput, InputIndex) => {
|
|
845
|
-
|
|
846
|
-
// If the values are null, then populate it with the right attributes
|
|
847
|
-
if (!quizInput.getAttribute("value")) {
|
|
848
|
-
quizInput.setAttribute("value", optionLetters[InputIndex]);
|
|
849
|
-
quizInput.setAttribute("name", "options");
|
|
850
|
-
quizInput.setAttribute("type", "radio");
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
// If the input has the value "submit" then apply different attributes for submit button
|
|
854
|
-
else if (quizInput.getAttribute("value") == "Submit") {
|
|
855
|
-
quizInput.setAttribute("type", "button");
|
|
856
|
-
quizInput.classList.add("unlock-btn");
|
|
857
|
-
}
|
|
858
|
-
})
|
|
859
|
-
})
|
|
860
|
-
}
|
|
861
|
-
resolve(); // Resolve the Promise once attributes are applied
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
applyAttributesToQuiz().then(() => {
|
|
865
|
-
|
|
866
|
-
/* This query selector relies on the dynamically added attributes above, so do not put this
|
|
867
|
-
* variable with the other ones at the top of the file
|
|
868
|
-
*/
|
|
869
|
-
const contentUnlockBtns = document.querySelectorAll(".unlock-btn");
|
|
870
|
-
|
|
871
|
-
/* Check if the course data object has the course number. If not, then add it.
|
|
872
|
-
* The contentLockData object that lives in local storage stores the course number and keys.
|
|
873
|
-
*/
|
|
874
|
-
if (!contentLockData.hasOwnProperty(courseNumber)) {
|
|
875
|
-
contentLockData[courseNumber] = {
|
|
876
|
-
keys: {},
|
|
877
|
-
};
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
// Get key number for each content area
|
|
881
|
-
lockedContent.forEach((contentArea, contentAreaIndex) => {
|
|
882
|
-
let contentLockKeyNum = contentArea.getAttribute("data-key");
|
|
883
|
-
|
|
884
|
-
// Error check - ensure it is wrapped in parent container
|
|
885
|
-
let contentLockWrapper = contentArea.parentElement;
|
|
886
|
-
if (contentLockWrapper) {
|
|
887
|
-
let hasContentLockWrapper = contentLockWrapper.classList.contains("content-lock-widget");
|
|
888
|
-
if (!hasContentLockWrapper) {
|
|
889
|
-
console.log(`Document Error: content lock widget wrapper is missing .content-lock-widget class for widget number ${contentAreaIndex + 1} on this page`);
|
|
890
|
-
}
|
|
891
|
-
} else {
|
|
892
|
-
console.log(`Document Error: content lock widget is missing parent container for widget number ${contentAreaIndex + 1} on this page`);
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
// Error check - ensure it has an instructions <div> as sibling element
|
|
896
|
-
let lockedContentSibling = contentArea.nextElementSibling;
|
|
897
|
-
if (lockedContentSibling) {
|
|
898
|
-
let hasInstructions = lockedContentSibling.classList.contains("instructions");
|
|
899
|
-
if (!hasInstructions) {
|
|
900
|
-
console.log(`Document Error: instructions <div> is missing .instructions class for widget number ${contentAreaIndex + 1} on this page`);
|
|
901
|
-
}
|
|
902
|
-
} else {
|
|
903
|
-
console.log(`Document Error: locked content area is missing <div> with instructions for widget number ${contentAreaIndex + 1} on this page`);
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
// Check if key already exists within the course, if it doesn't, add the key
|
|
907
|
-
if (!contentLockData[courseNumber].keys[contentLockKeyNum]) {
|
|
908
|
-
// Add the key to the course keys and set it equal to false by default
|
|
909
|
-
contentLockData[courseNumber].keys[contentLockKeyNum] = false;
|
|
910
|
-
}
|
|
911
|
-
});
|
|
912
|
-
|
|
913
|
-
// Go through each show/hide button and add click listener
|
|
914
|
-
contentUnlockBtns.forEach((unlockButton, buttonIndex) => {
|
|
915
|
-
|
|
916
|
-
// For each unlock-btn take the text and put the text content into an array for the confirmation window to use
|
|
917
|
-
unlockBtnContent.push(unlockButton.textContent);
|
|
918
|
-
|
|
919
|
-
// Add tab index to each unlock button
|
|
920
|
-
unlockButton.setAttribute("tabIndex", "0");
|
|
921
|
-
|
|
922
|
-
// Applies click event listener (and by default in HTML the keydown event will fire this function) to unlock the content
|
|
923
|
-
unlockButton.addEventListener("click", () => {
|
|
924
|
-
handleContentUnlock(unlockButton, buttonIndex, unlockBtnContent, courseNumber)
|
|
925
|
-
});
|
|
926
|
-
|
|
927
|
-
// Apply initial classes based on key status
|
|
928
|
-
let contentLockKeyNum = lockedContent[buttonIndex].getAttribute("data-key");
|
|
929
|
-
|
|
930
|
-
// Make sure contentLockData[courseNumber] is initialized
|
|
931
|
-
if (!contentLockData[courseNumber]) {
|
|
932
|
-
contentLockData[courseNumber] = {
|
|
933
|
-
keys: {},
|
|
934
|
-
id: 0
|
|
935
|
-
};
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
if (contentLockData[courseNumber].keys[contentLockKeyNum]) {
|
|
939
|
-
lockedContent[buttonIndex].classList.add("open");
|
|
940
|
-
contentLockInstructions[buttonIndex].classList.add("complete");
|
|
941
|
-
}
|
|
942
|
-
});
|
|
943
|
-
|
|
944
|
-
// Call the checkHiddenContent function initially
|
|
945
|
-
checkHiddenContent(courseNumber);
|
|
946
|
-
|
|
947
|
-
// Save the updated contentLockData object to local storage
|
|
948
|
-
localStorage.setItem("contentLockData", JSON.stringify(contentLockData));
|
|
949
|
-
|
|
950
|
-
}).catch(error => {
|
|
951
|
-
// Handle the error if needed
|
|
952
|
-
console.log("Error occurred during applyAttributesToQuiz:", error);
|
|
953
|
-
});
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
957
|
-
// Your script code here
|
|
958
|
-
if (contentLockWidgets) { handleContentLockWidget(contentLockWidgets) }
|
|
959
|
-
});
|
|
960
|
-
// Flip Card Widget
|
|
961
|
-
function callFlipCardWidget() {
|
|
962
|
-
// Loop through each card
|
|
963
|
-
flipCards.forEach((flipCardGroup) => {
|
|
964
|
-
|
|
965
|
-
let flipCard = flipCardGroup.querySelectorAll(".flip-card");
|
|
966
|
-
let innerFlipCard = flipCardGroup.querySelectorAll(".inner-card");
|
|
967
|
-
let numOfCardsInGroup = flipCardGroup.children.length;
|
|
968
|
-
|
|
969
|
-
// Check to ensure each card has the .flip-card class
|
|
970
|
-
if (numOfCardsInGroup !== flipCard.length) {
|
|
971
|
-
console.log("Document error: missing .flip-card class for flip card widget");
|
|
972
|
-
}
|
|
973
|
-
// Check to ensure each card has the .inner-card class
|
|
974
|
-
if (numOfCardsInGroup !== innerFlipCard.length) {
|
|
975
|
-
console.log("Document error: missing .inner-card class for flip card widget");
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
flipCard.forEach((card) => {
|
|
979
|
-
let innerFlipCard = card.querySelectorAll(".inner-card");
|
|
980
|
-
|
|
981
|
-
innerFlipCard.forEach((innerCard) => {
|
|
982
|
-
innerCard.setAttribute("tabindex", 0); // Add tab index to allow flip cards to be tabbable
|
|
983
|
-
innerCard.addEventListener("click", () => {
|
|
984
|
-
innerCard.offsetHeight; // Force reflow by accessing the offsetHeight property
|
|
985
|
-
innerCard.classList.toggle("flip");
|
|
986
|
-
})
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
// Add a keydownevent event to each card
|
|
990
|
-
innerCard.addEventListener("keydown", (event) => {
|
|
991
|
-
if (event.key === "Enter") {
|
|
992
|
-
// Force reflow by accessing the offsetHeight property
|
|
993
|
-
innerCard.offsetHeight;
|
|
994
|
-
innerCard.classList.toggle("flip");
|
|
995
|
-
}
|
|
996
|
-
})
|
|
997
|
-
})
|
|
998
|
-
})
|
|
999
|
-
})
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
// If flip cards are present in the file, run this code
|
|
1003
|
-
if (flipCards) { callFlipCardWidget() }
|
|
1004
|
-
if (document.querySelector("body[focus-reader]")) {
|
|
1005
|
-
|
|
1006
|
-
// Initializations
|
|
1007
|
-
let focusOn = false;
|
|
1008
|
-
|
|
1009
|
-
const fr_contentWrapper = document.querySelector("#content-wrapper");
|
|
1010
|
-
const fr_thisBody = document.querySelector("body[focus-reader]");
|
|
1011
|
-
|
|
1012
|
-
// Add fontAwesome to header
|
|
1013
|
-
const fr_pageHead = document.querySelector("head");
|
|
1014
|
-
const fontAweLink = document.createElement("link");
|
|
1015
|
-
fontAweLink.rel = "stylesheet";
|
|
1016
|
-
fontAweLink.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css";
|
|
1017
|
-
fr_pageHead.append(fontAweLink);
|
|
1018
|
-
|
|
1019
|
-
// add intersection observer to head tag
|
|
1020
|
-
const observerScript = document.createElement("script");
|
|
1021
|
-
observerScript.setAttribute("src", "https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver");
|
|
1022
|
-
fr_pageHead.append(observerScript);
|
|
1023
|
-
|
|
1024
|
-
// Create Switches container
|
|
1025
|
-
const fr_switchesContainer = document.createElement("div");
|
|
1026
|
-
fr_switchesContainer.className = "focus-reader-switches";
|
|
1027
|
-
fr_thisBody.append(fr_switchesContainer);
|
|
1028
|
-
|
|
1029
|
-
// Focus-text container
|
|
1030
|
-
const fr_focusTextContainer = document.createElement("div");
|
|
1031
|
-
fr_switchesContainer.append(fr_focusTextContainer);
|
|
1032
|
-
|
|
1033
|
-
// Focus-text Icon
|
|
1034
|
-
const fr_focusTextIcon = document.createElement("p");
|
|
1035
|
-
fr_focusTextIcon.innerHTML = "Focus Text"
|
|
1036
|
-
fr_focusTextContainer.append(fr_focusTextIcon);
|
|
1037
|
-
|
|
1038
|
-
// info icon
|
|
1039
|
-
const fr_infoIcon = document.createElement("i");
|
|
1040
|
-
fr_infoIcon.classList.add("fa-solid");
|
|
1041
|
-
fr_infoIcon.classList.add("fa-circle-info");
|
|
1042
|
-
fr_focusTextContainer.append(fr_infoIcon);
|
|
1043
|
-
|
|
1044
|
-
// info tooltip
|
|
1045
|
-
const fr_infoTooltip = document.createElement("span");
|
|
1046
|
-
const focusReaderTooltipText = "Highlight text as you scroll";
|
|
1047
|
-
fr_infoTooltip.classList.add("info-tooltip");
|
|
1048
|
-
fr_infoTooltip.innerHTML = focusReaderTooltipText;
|
|
1049
|
-
fr_infoIcon.append(fr_infoTooltip);
|
|
1050
|
-
|
|
1051
|
-
// Focus-text switch button
|
|
1052
|
-
const fr_focusTextSwitch = document.createElement("button");
|
|
1053
|
-
fr_focusTextSwitch.id = "focus-text";
|
|
1054
|
-
fr_focusTextSwitch.innerHTML = (focusOn) ? `<i class="fas fa-toggle-on"></i>` : `<i class="fas fa-toggle-off"></i>`;
|
|
1055
|
-
fr_focusTextContainer.append(fr_focusTextSwitch);
|
|
1056
|
-
|
|
1057
|
-
// Focus-text logic
|
|
1058
|
-
fr_focusTextSwitch.addEventListener("click", () => {
|
|
1059
|
-
if (focusOn) {
|
|
1060
|
-
focusOn = !focusOn;
|
|
1061
|
-
fr_contentWrapper.removeAttribute("on");
|
|
1062
|
-
fr_focusTextSwitch.innerHTML = (focusOn) ? `<i class="fas fa-toggle-on"></i>` : `<i class="fas fa-toggle-off"></i>`;
|
|
1063
|
-
removeSpans(fr_contentWrapper);
|
|
1064
|
-
} else {
|
|
1065
|
-
focusOn = !focusOn;
|
|
1066
|
-
fr_contentWrapper.setAttribute("on", "");
|
|
1067
|
-
fr_focusTextSwitch.innerHTML = (focusOn) ? `<i class="fas fa-toggle-on"></i>` : `<i class="fas fa-toggle-off"></i>`;
|
|
1068
|
-
const elements = document.querySelectorAll("#content-wrapper .content-body :is(p, li, dd, dt, blockquote)");
|
|
1069
|
-
elements.forEach(element => {
|
|
1070
|
-
traverseAndWrapTextInSpans(element, focusText);
|
|
1071
|
-
});
|
|
1072
|
-
}
|
|
1073
|
-
});
|
|
1074
|
-
|
|
1075
|
-
const options = {
|
|
1076
|
-
root: null,
|
|
1077
|
-
rootMargin: '-48.9% 0px',
|
|
1078
|
-
threshold: 0.00
|
|
1079
|
-
};
|
|
1080
|
-
|
|
1081
|
-
const focusText = new IntersectionObserver(entries => {
|
|
1082
|
-
entries.forEach(entry => {
|
|
1083
|
-
if (entry.isIntersecting) {
|
|
1084
|
-
entry.target.closest("span").classList.add("focus-text");
|
|
1085
|
-
} else {
|
|
1086
|
-
entry.target.closest("span").classList.remove("focus-text");
|
|
1087
|
-
}
|
|
1088
|
-
});
|
|
1089
|
-
}, options);
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
function traverseAndWrapTextInSpans(node, focusText) {
|
|
1095
|
-
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== '') {
|
|
1096
|
-
// Split the text into words
|
|
1097
|
-
const words = node.textContent.split(' ');
|
|
1098
|
-
|
|
1099
|
-
// Wrap each word in a span
|
|
1100
|
-
words.forEach(word => {
|
|
1101
|
-
if (word !== '') {
|
|
1102
|
-
const span = document.createElement("span");
|
|
1103
|
-
span.textContent = word + ' '; // Add a space after the word to preserve spacing
|
|
1104
|
-
|
|
1105
|
-
// Observe the span
|
|
1106
|
-
focusText.observe(span);
|
|
1107
|
-
|
|
1108
|
-
// Insert the span before the text node
|
|
1109
|
-
node.parentNode.insertBefore(span, node);
|
|
1110
|
-
}
|
|
1111
|
-
});
|
|
1112
|
-
|
|
1113
|
-
// Remove the original text node
|
|
1114
|
-
node.parentNode.removeChild(node);
|
|
1115
|
-
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
1116
|
-
// Recursively process child nodes
|
|
1117
|
-
Array.from(node.childNodes).forEach(childNode => {
|
|
1118
|
-
traverseAndWrapTextInSpans(childNode, focusText);
|
|
1119
|
-
});
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
function removeSpans(node) {
|
|
1124
|
-
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
1125
|
-
// If the node is a span with the class 'focus-text', an empty class attribute, is empty, or has no attributes, replace it with a text node
|
|
1126
|
-
if (node.tagName === 'SPAN' && (node.className === 'focus-text' || node.className === '' || node.textContent.trim() === '' || node.attributes.length === 0)) {
|
|
1127
|
-
const textNode = document.createTextNode(node.textContent);
|
|
1128
|
-
node.parentNode.insertBefore(textNode, node);
|
|
1129
|
-
node.parentNode.removeChild(node);
|
|
1130
|
-
} else {
|
|
1131
|
-
// Recursively process child nodes
|
|
1132
|
-
Array.from(node.childNodes).forEach(childNode => {
|
|
1133
|
-
removeSpans(childNode);
|
|
1134
|
-
});
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
// Change footnotes from 'show' to 'hide'
|
|
1139
|
-
const footnotes = document.querySelector(".toggle-footnotes");
|
|
1140
|
-
|
|
1141
|
-
if (footnotes) {
|
|
1142
|
-
footnotes.addEventListener("click", () => {
|
|
1143
|
-
footnotes.innerHTML = (footnotes.innerHTML === "[Show Footnotes]") ? "[Hide Footnotes]" : "[Show Footnotes]";
|
|
1144
|
-
})
|
|
1145
|
-
}
|
|
1146
|
-
// Add h5p resizer dynamically
|
|
1147
|
-
h5pResizer.setAttribute("src", "https://pima.h5p.com/js/h5p-resizer.js");
|
|
1148
|
-
h5pResizer.setAttribute("charset", "UTF-8");
|
|
1149
|
-
h5pResizer.setAttribute("defer", "");
|
|
1150
|
-
|
|
1151
|
-
// If any iframes are detected run this function
|
|
1152
|
-
function checkIframes() {
|
|
1153
|
-
h5pIframes.forEach(function (h5pIframe) {
|
|
1154
|
-
const src = h5pIframe.getAttribute("src");
|
|
1155
|
-
if (src.includes("/d2l/common/dialogs/quickLink") || src.includes("https://pima.h5p.com/content") || src.includes("h5p") && !h5pResizerExists) {
|
|
1156
|
-
docHead.appendChild(h5pResizer);
|
|
1157
|
-
}
|
|
1158
|
-
});
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
// Call function if iframes exist
|
|
1162
|
-
if (h5pIframes) { checkIframes() }
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
// Helper JS for Responsive Tables
|
|
1166
|
-
const initResponsiveTables = () => {
|
|
1167
|
-
for (let table = 0; table < tables.length; table++) {
|
|
1168
|
-
let headertext = [],
|
|
1169
|
-
headers = tables[table].querySelectorAll(".display table th, table.display th, .display-lg table th, table.display-lg th"),
|
|
1170
|
-
tablebody = tables[table].querySelector(".display table tbody, table.display tbody, .display-lg table tbody, table.display-lg tbody");
|
|
1171
|
-
for (let header = 0; header < headers.length; header++) {
|
|
1172
|
-
let current = headers[header];
|
|
1173
|
-
headertext.push(current.textContent.replace(/\r?\n|\r/, ""));
|
|
1174
|
-
}
|
|
1175
|
-
for (let y = 0, row; row = tablebody.rows[y]; y++) {
|
|
1176
|
-
for (let j = 0, col; col = row.cells[j]; j++) {
|
|
1177
|
-
col.setAttribute("data-th", headertext[j]);
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
if (tables) {
|
|
1183
|
-
initResponsiveTables();
|
|
1184
|
-
}
|
|
1185
|
-
// Call function with jQuery scripts
|
|
1186
|
-
const callJquery = () => {
|
|
1187
|
-
// Toggle Button's Arrow Right Points Down on Click
|
|
1188
|
-
$('.arrow-right').on('click', function () {
|
|
1189
|
-
$(this).toggleClass('arrow-down');
|
|
1190
|
-
});
|
|
1191
|
-
// TOOLTIP
|
|
1192
|
-
// Allows Screen readers to toggle a tooltip on click and to say if the tooltip is collapsed or expanded.
|
|
1193
|
-
$(".tooltip").click(function () {
|
|
1194
|
-
$(this).children(".tip-hover").toggle();
|
|
1195
|
-
if ($(this).children(".tip-hover").is(':visible')) {
|
|
1196
|
-
$(this).attr('aria-expanded', 'true');
|
|
1197
|
-
$(this).removeClass('hidden');
|
|
1198
|
-
} else {
|
|
1199
|
-
$(this).attr('aria-expanded', 'false');
|
|
1200
|
-
$(this).addClass('hidden');
|
|
1201
|
-
}
|
|
1202
|
-
});
|
|
1203
|
-
let start = 999;
|
|
1204
|
-
$('.tooltip').each(function (i) {
|
|
1205
|
-
$(this).css('z-index', start--);
|
|
1206
|
-
});
|
|
1207
|
-
$(".tooltip .video-container").parent().css("width", "450px");
|
|
1208
|
-
}
|
|
1209
|
-
callJquery();
|
|
1210
|
-
// This is called by anchor links via onlick="" in the HTML
|
|
1211
|
-
// Added because default anchor links don't work on all browsers using D2L
|
|
1212
|
-
const jumpTo = (anchor) => {
|
|
1213
|
-
document.getElementById(anchor).scrollIntoView();
|
|
1214
|
-
}
|
|
1215
|
-
const sliderWidgets = document.querySelectorAll(".slider-widget");
|
|
1216
|
-
const slideHeight = 300;
|
|
1217
|
-
|
|
1218
|
-
// Function to check if all direct children of each slider have the 'slider-item' class
|
|
1219
|
-
const checkSliderChildren = () => {
|
|
1220
|
-
[...sliderWidgets].forEach((slider) => {
|
|
1221
|
-
// Check if every direct child of the slider has the 'slider-item' class
|
|
1222
|
-
let sliderChildren = [...slider.children].every(child => child.classList.contains("slider-item"));
|
|
1223
|
-
|
|
1224
|
-
// Log an error message if any direct child does not have the 'slider-item' class
|
|
1225
|
-
if (!sliderChildren) {
|
|
1226
|
-
console.log(`Document error: not all direct children of .slider have the .slider-item class.`);
|
|
1227
|
-
}
|
|
1228
|
-
});
|
|
1229
|
-
};
|
|
1230
|
-
checkSliderChildren();
|
|
1231
|
-
|
|
1232
|
-
// Function to hide all slides except the active one and deactivate all dots except the active one
|
|
1233
|
-
const hideSlidesAndDots = (sliderItems, sliderDots, newIndex) => {
|
|
1234
|
-
// Iterate over each slider item
|
|
1235
|
-
sliderItems.forEach((item, index) => {
|
|
1236
|
-
// Set the display style based on whether the item is the active slide
|
|
1237
|
-
item.style.display = index === newIndex ? "block" : "none";
|
|
1238
|
-
});
|
|
1239
|
-
// Iterate over each dot
|
|
1240
|
-
sliderDots.forEach((sliderDot, index) => {
|
|
1241
|
-
// Toggle the 'active' class based on whether the dot corresponds to the active slide
|
|
1242
|
-
sliderDot.classList.toggle("active", index === newIndex);
|
|
1243
|
-
});
|
|
1244
|
-
};
|
|
1245
|
-
|
|
1246
|
-
// Function to update the display of slides and dots when a new slide is selected
|
|
1247
|
-
const updateSlide = (sliderItems, sliderDots, newIndex) => {
|
|
1248
|
-
// Call the function to hide all slides and deactivate all dots except for the active ones
|
|
1249
|
-
hideSlidesAndDots(sliderItems, sliderDots, newIndex);
|
|
1250
|
-
};
|
|
1251
|
-
|
|
1252
|
-
// Function to create a button element with the specified class name
|
|
1253
|
-
const createSliderButton = (className) => {
|
|
1254
|
-
// Create a new button element
|
|
1255
|
-
const sliderButton = document.createElement("button");
|
|
1256
|
-
// Set the class name of the button
|
|
1257
|
-
sliderButton.className = className;
|
|
1258
|
-
// Set tabindex to -1 to skip when tabbing
|
|
1259
|
-
sliderButton.setAttribute("tabindex", "-1");
|
|
1260
|
-
// Return the created button
|
|
1261
|
-
return sliderButton;
|
|
1262
|
-
};
|
|
1263
|
-
|
|
1264
|
-
// Function to vertically center the content of a slide if it is short and does not contain videos
|
|
1265
|
-
const totalSlideContentHeight = (sliderItem) => {
|
|
1266
|
-
// Initialize a variable to keep track of the total height of the content
|
|
1267
|
-
let totalContentHeight = 0;
|
|
1268
|
-
// Iterate over each child element of the slider item
|
|
1269
|
-
for (let child of sliderItem.children) {
|
|
1270
|
-
// Add the height of the child to the total content height
|
|
1271
|
-
totalContentHeight += child.offsetHeight;
|
|
1272
|
-
}
|
|
1273
|
-
// Check if the total content height is less than 300px and the item does not contain a video
|
|
1274
|
-
if (totalContentHeight < slideHeight && !sliderItem.querySelector(".media-container")) {
|
|
1275
|
-
// Create a wrapper div to contain the content
|
|
1276
|
-
const sliderWrapper = document.createElement("div");
|
|
1277
|
-
// Move each child of the slider item into the wrapper
|
|
1278
|
-
while (sliderItem.firstChild) {
|
|
1279
|
-
sliderWrapper.appendChild(sliderItem.firstChild);
|
|
1280
|
-
}
|
|
1281
|
-
// Append the wrapper to the slider item
|
|
1282
|
-
sliderItem.appendChild(sliderWrapper);
|
|
1283
|
-
// Add the 'short-content' class to the slider item to apply vertical centering
|
|
1284
|
-
sliderItem.classList.add("short-content");
|
|
1285
|
-
}
|
|
1286
|
-
};
|
|
1287
|
-
|
|
1288
|
-
// Initialize each slider with navigation buttons, dots, and keyboard navigation
|
|
1289
|
-
[...sliderWidgets].forEach((slider, index) => {
|
|
1290
|
-
// Set accessibility attributes for the slider
|
|
1291
|
-
slider.setAttribute("tabindex", "0");
|
|
1292
|
-
slider.setAttribute("role", "group");
|
|
1293
|
-
|
|
1294
|
-
// Create a hidden label for the slider for screen readers
|
|
1295
|
-
const sliderLabel = document.createElement("span");
|
|
1296
|
-
sliderLabel.id = `slider-label-${index + 1}`;
|
|
1297
|
-
sliderLabel.textContent = "Interactive Slider";
|
|
1298
|
-
sliderLabel.hidden = true;
|
|
1299
|
-
// Insert the label at the beginning of the slider
|
|
1300
|
-
slider.prepend(sliderLabel);
|
|
1301
|
-
|
|
1302
|
-
// Associate the label with the slider for screen readers
|
|
1303
|
-
slider.setAttribute("aria-labelledby", `slider-label-${index + 1}`);
|
|
1304
|
-
|
|
1305
|
-
// Initialize the current index for the slider
|
|
1306
|
-
let currentSlide = 0;
|
|
1307
|
-
// Select all slider items within the current slider
|
|
1308
|
-
const sliderItems = [...slider.querySelectorAll(".slider-item")];
|
|
1309
|
-
// Create a div to contain the dots for navigation
|
|
1310
|
-
const sliderDotsBar = document.createElement("div");
|
|
1311
|
-
sliderDotsBar.className = "slider-dots-bar";
|
|
1312
|
-
// Append the dots bar to the slider
|
|
1313
|
-
slider.appendChild(sliderDotsBar);
|
|
1314
|
-
// Initialize an array to keep track of the dots
|
|
1315
|
-
let sliderDots = [];
|
|
1316
|
-
|
|
1317
|
-
// Create dots for each slide and set up click events to navigate to the slide
|
|
1318
|
-
sliderItems.forEach((sliderItem, i) => {
|
|
1319
|
-
// Create a span element to represent a dot
|
|
1320
|
-
const sliderDot = document.createElement("span");
|
|
1321
|
-
sliderDot.className = "slider-dot";
|
|
1322
|
-
// Add a click event listener to the dot
|
|
1323
|
-
sliderDot.addEventListener("click", () => {
|
|
1324
|
-
// Update the current index to the index of the clicked dot
|
|
1325
|
-
currentSlide = i;
|
|
1326
|
-
// Call the function to update the slide display
|
|
1327
|
-
hideSlidesAndDots(sliderItems, sliderDots, currentSlide);
|
|
1328
|
-
// Ensure the current slide is displayed
|
|
1329
|
-
sliderItems[currentSlide].style.display = "block";
|
|
1330
|
-
// Add the 'active' class to the current dot
|
|
1331
|
-
sliderDot.classList.add("active");
|
|
1332
|
-
// Call the function to align the slide content if necessary
|
|
1333
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
|
1334
|
-
});
|
|
1335
|
-
// Append the dot to the dots bar
|
|
1336
|
-
sliderDotsBar.appendChild(sliderDot);
|
|
1337
|
-
// Add the dot to the array of dots
|
|
1338
|
-
sliderDots.push(sliderDot);
|
|
1339
|
-
|
|
1340
|
-
// Hide the slide if it's not the current one
|
|
1341
|
-
sliderItem.style.display = i !== currentSlide ? "none" : "block";
|
|
1342
|
-
// If it's the current slide, add the 'active' class to the corresponding dot
|
|
1343
|
-
if (i === currentSlide) {
|
|
1344
|
-
sliderDot.classList.add("active");
|
|
1345
|
-
}
|
|
1346
|
-
});
|
|
1347
|
-
|
|
1348
|
-
// Create navigation buttons and set up click events to navigate between slides
|
|
1349
|
-
const sliderLeftArrow = createSliderButton("slider-arrow icon-chevron-left");
|
|
1350
|
-
const sliderRightArrow = createSliderButton("slider-arrow icon-chevron-right");
|
|
1351
|
-
// Append the navigation buttons to the slider
|
|
1352
|
-
slider.appendChild(sliderLeftArrow);
|
|
1353
|
-
slider.appendChild(sliderRightArrow);
|
|
1354
|
-
|
|
1355
|
-
// Add a click event listener to the left arrow button
|
|
1356
|
-
sliderLeftArrow.addEventListener("click", () => {
|
|
1357
|
-
// Update the current index to the previous slide, wrapping around if necessary
|
|
1358
|
-
currentSlide = currentSlide > 0 ? currentSlide - 1 : sliderItems.length - 1;
|
|
1359
|
-
// Call the function to update the slide display
|
|
1360
|
-
updateSlide(sliderItems, sliderDots, currentSlide);
|
|
1361
|
-
// Call the function to align the slide content if necessary
|
|
1362
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
|
1363
|
-
});
|
|
1364
|
-
|
|
1365
|
-
// Add a click event listener to the right arrow button
|
|
1366
|
-
sliderRightArrow.addEventListener("click", () => {
|
|
1367
|
-
// Update the current index to the next slide, wrapping around if necessary
|
|
1368
|
-
currentSlide = currentSlide < sliderItems.length - 1 ? currentSlide + 1 : 0;
|
|
1369
|
-
// Call the function to update the slide display
|
|
1370
|
-
updateSlide(sliderItems, sliderDots, currentSlide);
|
|
1371
|
-
// Call the function to align the slide content if necessary
|
|
1372
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
|
1373
|
-
});
|
|
1374
|
-
|
|
1375
|
-
// Function to update the label text when the slide changes
|
|
1376
|
-
function updateSliderLabel() {
|
|
1377
|
-
// Update the text content of the label to reflect the current slide number
|
|
1378
|
-
sliderLabel.textContent = `Interactive Slide: slide ${currentSlide + 1} of ${sliderItems.length}`;
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
// Set up keyboard navigation for the slider
|
|
1382
|
-
slider.addEventListener("keydown", (event) => {
|
|
1383
|
-
// Handle the left and right arrow keys
|
|
1384
|
-
switch (event.key) {
|
|
1385
|
-
case "ArrowLeft":
|
|
1386
|
-
// Update the current index to the previous slide, wrapping around if necessary
|
|
1387
|
-
currentSlide = currentSlide > 0 ? currentSlide - 1 : sliderItems.length - 1;
|
|
1388
|
-
break;
|
|
1389
|
-
case "ArrowRight":
|
|
1390
|
-
// Update the current index to the next slide, wrapping around if necessary
|
|
1391
|
-
currentSlide = currentSlide < sliderItems.length - 1 ? currentSlide + 1 : 0;
|
|
1392
|
-
break;
|
|
1393
|
-
default:
|
|
1394
|
-
// If any other key is pressed, do nothing and return
|
|
1395
|
-
return;
|
|
1396
|
-
}
|
|
1397
|
-
// Call the function to update the slide display
|
|
1398
|
-
updateSlide(sliderItems, sliderDots, currentSlide);
|
|
1399
|
-
// Call the function to align the slide content if necessary
|
|
1400
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
|
1401
|
-
// Prevent the default action for the keydown event
|
|
1402
|
-
event.preventDefault();
|
|
1403
|
-
// Call the function to update the label text
|
|
1404
|
-
updateSliderLabel();
|
|
1405
|
-
// Focus the slider widget
|
|
1406
|
-
slider.focus();
|
|
1407
|
-
});
|
|
1408
|
-
|
|
1409
|
-
// Variables to store the starting and ending X coordinates of a touch event
|
|
1410
|
-
let touchStartX = 0;
|
|
1411
|
-
let touchEndX = 0;
|
|
1412
|
-
|
|
1413
|
-
// Event listener for the 'touchstart' event, which fires when a touch point is placed on the touch surface
|
|
1414
|
-
slider.addEventListener("touchstart", (e) => {
|
|
1415
|
-
// Store the X coordinate of the touch point when the touch starts
|
|
1416
|
-
touchStartX = e.changedTouches[0].screenX;
|
|
1417
|
-
}, false);
|
|
1418
|
-
|
|
1419
|
-
// Event listener for the 'touchend' event, which fires when a touch point is removed from the touch surface
|
|
1420
|
-
slider.addEventListener("touchend", (e) => {
|
|
1421
|
-
// Store the X coordinate of the touch point when the touch ends
|
|
1422
|
-
touchEndX = e.changedTouches[0].screenX;
|
|
1423
|
-
// Call the function to handle the swipe gesture
|
|
1424
|
-
sliderSwipe();
|
|
1425
|
-
}, false);
|
|
1426
|
-
|
|
1427
|
-
// Function to handle the swipe gesture
|
|
1428
|
-
const sliderSwipe = () => {
|
|
1429
|
-
// Calculate the difference between the starting and ending X coordinates
|
|
1430
|
-
let diffX = touchEndX - touchStartX;
|
|
1431
|
-
|
|
1432
|
-
// Check if the absolute value of the difference is greater than a minimum threshold (50 pixels)
|
|
1433
|
-
if (Math.abs(diffX) > 50) { // Minimum distance for a swipe
|
|
1434
|
-
// Determine the direction of the swipe based on the sign of the difference
|
|
1435
|
-
if (diffX > 0) {
|
|
1436
|
-
// If the difference is positive, the user swiped to the left
|
|
1437
|
-
// Update the current slide index to the previous slide, wrapping around if necessary
|
|
1438
|
-
currentSlide = currentSlide > 0 ? currentSlide - 1 : sliderItems.length - 1;
|
|
1439
|
-
} else {
|
|
1440
|
-
// If the difference is negative, the user swiped to the right
|
|
1441
|
-
// Update the current slide index to the next slide, wrapping around if necessary
|
|
1442
|
-
currentSlide = currentSlide < sliderItems.length - 1 ? currentSlide + 1 : 0;
|
|
1443
|
-
}
|
|
1444
|
-
// Call the function to update the slide display
|
|
1445
|
-
updateSlide(sliderItems, sliderDots, currentSlide);
|
|
1446
|
-
// Call the function to align the slide content if necessary
|
|
1447
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
|
1448
|
-
// Refocus the slider widget to maintain accessibility
|
|
1449
|
-
slider.focus();
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
});
|
|
1453
|
-
|
|
1454
|
-
// Function to check if the slider contains all required elements for navigation
|
|
1455
|
-
const checkSliderNavs = (slider, index) => {
|
|
1456
|
-
// Select the navigation controls within the context of the current slider
|
|
1457
|
-
const sliderNextButton = slider.querySelector(".icon-chevron-right");
|
|
1458
|
-
const sliderPrevButton = slider.querySelector(".icon-chevron-left");
|
|
1459
|
-
const sliderDotsBar = slider.querySelector(".slider-dots-bar");
|
|
1460
|
-
|
|
1461
|
-
// Check if the navigation controls are present
|
|
1462
|
-
if (!sliderNextButton) {
|
|
1463
|
-
console.log(`Document error: next button is missing for slider ${index + 1}.`);
|
|
1464
|
-
}
|
|
1465
|
-
if (!sliderPrevButton) {
|
|
1466
|
-
console.log(`Document error: previous button is missing for slider ${index + 1}.`);
|
|
1467
|
-
}
|
|
1468
|
-
if (!sliderDotsBar) {
|
|
1469
|
-
console.log(`Document error: dots bar is missing for slider ${index + 1}.`);
|
|
1470
|
-
}
|
|
1471
|
-
};
|
|
1472
|
-
|
|
1473
|
-
// Call the function for each slider to perform the check
|
|
1474
|
-
[...sliderWidgets].forEach((slider, index) => {
|
|
1475
|
-
checkSliderNavs(slider, index);
|
|
1476
|
-
});
|
|
1477
|
-
|
|
1478
|
-
// Check if slider items are empty
|
|
1479
|
-
const checkEmptySliderItems = () => {
|
|
1480
|
-
[...sliderWidgets].forEach((slider, sliderIndex) => {
|
|
1481
|
-
// Get all .slider-item children of the current slider
|
|
1482
|
-
let sliderItems = [...slider.querySelectorAll(".slider-item")];
|
|
1483
|
-
|
|
1484
|
-
// Check each .slider-item to see if it is empty
|
|
1485
|
-
sliderItems.forEach((item, itemIndex) => {
|
|
1486
|
-
// An element is considered empty if it has no children, or all its children are either comment nodes or text nodes with only whitespace
|
|
1487
|
-
const isEmpty = [...item.childNodes].every(node => {
|
|
1488
|
-
return node.nodeType === Node.COMMENT_NODE || (node.nodeType === Node.TEXT_NODE && !node.textContent.trim());
|
|
1489
|
-
});
|
|
1490
|
-
|
|
1491
|
-
// Log an error message if the .slider-item is empty
|
|
1492
|
-
if (isEmpty) {
|
|
1493
|
-
console.log(`Document error: .slider-item at index ${itemIndex} in slider ${sliderIndex + 1} is empty.`);
|
|
1494
|
-
}
|
|
1495
|
-
});
|
|
1496
|
-
});
|
|
1497
|
-
};
|
|
1498
|
-
checkEmptySliderItems();
|
|
1499
|
-
// Array for all themes that require theme specific js
|
|
1500
|
-
const customJsThemes = ["ecn", "hrs", "ss"];
|
|
1501
|
-
|
|
1502
|
-
//Search links for theme styles
|
|
1503
|
-
const themeJsCheck = () => {
|
|
1504
|
-
|
|
1505
|
-
const links = document.querySelectorAll("link");
|
|
1506
|
-
|
|
1507
|
-
links.forEach((link) => {
|
|
1508
|
-
const href = link.getAttribute("href");
|
|
1509
|
-
customJsThemes.forEach((theme) => {
|
|
1510
|
-
// If theme requires custom js, run addThemeScript()
|
|
1511
|
-
if (href && href.includes(`/${theme}/styles.css`)) {
|
|
1512
|
-
addThemeScript(theme);
|
|
1513
|
-
}
|
|
1514
|
-
});
|
|
1515
|
-
});
|
|
1516
|
-
|
|
1517
|
-
// Adds a script to the head for that particular theme
|
|
1518
|
-
function addThemeScript(theme) {
|
|
1519
|
-
let themeScript = document.createElement("script");
|
|
1520
|
-
// URL references theme-specific js module from CDN
|
|
1521
|
-
themeScript.src = `https://cdn.jsdelivr.net/npm/@pimaonline/pimaonline-themepack/dist/js/themes/${theme}.js`;
|
|
1522
|
-
document.head.appendChild(themeScript);
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
|
-
|
|
1526
|
-
themeJsCheck()
|
|
1527
|
-
// Toggle footnotes
|
|
1528
|
-
const toggleBtns = document.querySelectorAll(".toggle-btn, .toggle-footnotes");
|
|
1529
|
-
|
|
1530
|
-
if (toggleBtns) {
|
|
1531
|
-
if (document.querySelector(".toggle-btn") || document.querySelector(".toggle-footnotes")) {
|
|
1532
|
-
for (let toggleBtn = 0; toggleBtn < toggleBtns.length; toggleBtn++) {
|
|
1533
|
-
// Add tabindex
|
|
1534
|
-
toggleBtns[toggleBtn].setAttribute("tabindex", "0");
|
|
1535
|
-
// Show/hide on click
|
|
1536
|
-
toggleBtns[toggleBtn].addEventListener("click", () => {
|
|
1537
|
-
if (toggleBtns[toggleBtn].nextElementSibling) {
|
|
1538
|
-
toggleBtns[toggleBtn].nextElementSibling.classList.toggle("show");
|
|
1539
|
-
}
|
|
1540
|
-
})
|
|
1541
|
-
|
|
1542
|
-
// Show/hide on enter for users who use tab
|
|
1543
|
-
toggleBtns[toggleBtn].addEventListener("keydown", (enter) => {
|
|
1544
|
-
if (enter.keyCode === 13) {
|
|
1545
|
-
if (toggleBtns[toggleBtn].nextElementSibling) {
|
|
1546
|
-
toggleBtns[toggleBtn].nextElementSibling.classList.toggle("show");
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
})
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1
|
+
(()=>{"use strict";var e={2152:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.discardAttributes=void 0,t.discardAttributes=(e,...t)=>{t.forEach((t=>e.removeAttribute(t)))}},7080:(e,t,o)=>{o(3271),o(6381),o(1034),o(1645),o(71),o(4e3),o(161),o(3982),o(8795),o(9308),o(7721),o(7121),o(81),o(4786),o(4407),o(1952),o(7174),o(6433),o(4709),o(4393),o(4019),o(4262),o(3258),o(2692),o(9191),o(1424),o(3966)},3271:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079),r=[{class:"bi-",cdn:new URL("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css")},{class:"ri-",cdn:new URL("https://cdn.jsdelivr.net/npm/remixicon@4.0.1/fonts/remixicon.css")}];document.querySelectorAll(r.map((e=>`[class*='${e.class}']`)).join(", ")).length>0&&r.forEach((e=>{var t;if(document.querySelector(`[class*='${e.class}']`)){const o=null!==(t=null===n.docHead||void 0===n.docHead?void 0:n.docHead.querySelector("meta[name='viewport']"))&&void 0!==t?t:null;o||console.warn("Document error: could not find viewport meta tag");const r=document.createElement("link");r.setAttribute("href",e.cdn.toString()),r.setAttribute("rel","stylesheet"),o&&(null===n.docHead||void 0===n.docHead||n.docHead.insertBefore(r,o.nextSibling))}}))},6381:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079);n.contentWrapper?n.contentWrapper.setAttribute("role","main"):n.contentWrapper||console.log("Document error: does not contain #content-wrapper."),n.secondColumn&&(n.secondColumn.setAttribute("role","region"),n.secondColumn.setAttribute("aria-label","Second column")),n.thirdColumn&&(n.thirdColumn.setAttribute("role","region"),n.thirdColumn.setAttribute("aria-label","Third column"))},1034:()=>{const e=document.querySelectorAll(".arrow-right");e.length>0&&e.forEach((e=>{(e=>{e.addEventListener("click",(t=>{e.classList.toggle("arrow-down")})),e.addEventListener("keydown",(t=>{"Enter"!==t.key&&" "!==t.key||e.classList.toggle("arrow-down")}))})(e)}))},1645:()=>{const e=document.querySelectorAll("dl.vocab-list dt"),t=(document.querySelectorAll("dl.vocab-list dd"),document.querySelectorAll("dl.vocab-list")),o=(document.querySelectorAll("dl.vocab-list button"),e=>{e.classList.toggle("active");let t=e.nextElementSibling instanceof HTMLElement?e.nextElementSibling:null;for(t&&"block"===t.style.display?t.style.display="none":t&&(t.style.display="block");t&&t.nextElementSibling;){const e=t.nextElementSibling;if(e instanceof HTMLElement){if(t=e,!t||"DD"!==t.tagName)break;"block"===t.style.display?t.style.display="none":t.style.display="block"}}}),n=e=>{if(e){let t=e.querySelectorAll("dd"),o=e.querySelectorAll("dt");t.forEach((e=>{e.style.display="none"})),o.forEach((e=>{e.classList.remove("active")}))}};t.length>0&&(()=>{t.forEach((e=>{let t=0,o=0,r=!1;for(let n=0;n<e.children.length;n++)"DT"==e.children[n].tagName&&(e.children[n].setAttribute("tabindex","0"),t++),"DD"==e.children[n].tagName&&o++,"BUTTON"==e.children[n].tagName&&(r=!0);if(t<1&&console.warn("Document error: no terms found in vocab list"),o<1&&console.warn("Document error: no definitions found in vocab list"),t>o&&console.warn("Document error: more terms than definitions in vocab list"),t>=2&&o>=2)if(r){let t=e.querySelector("button");null==t||t.addEventListener("click",(()=>n(e)))}else{const t=document.createElement("button");t.textContent="Close All",t.addEventListener("click",(()=>n(e))),e.appendChild(t)}else{for(let t=0;t<e.children.length;t++)"BUTTON"==e.children[t].tagName&&(r=!0);if(r){let t=e.querySelector("button");t&&(t.style.display="none")}}}));for(let t=0;t<e.length;t++)e[t].addEventListener("click",(n=>{o(e[t])})),e[t].addEventListener("keydown",(n=>{"Enter"===n.key&&o(e[t])}))})()},71:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.cleanMarkup=void 0;const n=o(6079),r=o(2152);t.cleanMarkup=()=>{n.rolePres&&n.rolePres.forEach((e=>e.removeAttribute("role"))),document.querySelectorAll(l.join(",")).forEach((e=>{(0,r.discardAttributes)(e,...i)})),n.jqueryScript&&n.jqueryScript.remove()};const l=["table","thead","tbody","tr","th","td"],i=["cellspacing","cellpadding","width","style"];var c;(n.rolePres&&n.rolePres.length>0||(c=i,l.some((e=>c.some((t=>null!==document.querySelector(`${e}[${t}]`))))))||n.jqueryScript)&&(0,t.cleanMarkup)()},4e3:()=>{const e=document.querySelectorAll(".content-lock-widget"),t=document.querySelectorAll(".locked-content"),o=document.querySelectorAll(".instructions"),n=[],r=e=>{const r=(e,n,r)=>{u[n].keys[e]=!0,u[n].keys[e]?(t[r].classList.add("open"),o[r].classList.add("complete")):(t[r].classList.remove("open"),o[r].classList.remove("complete")),localStorage.setItem("contentLockData",JSON.stringify(u)),i(n)},l=(e,t)=>{let o=e.querySelector(".error-container"),n=document.createElement("span");o&&(o.innerHTML="",o.appendChild(n)),n.textContent="",setTimeout((function(){n.textContent=t,o&&o.appendChild(n)}),200)},i=e=>{t.forEach(((n,r)=>{let l=n.getAttribute("data-key");if(l){let n=parseInt(l,10);u[e].keys[n]?(t[r].classList.add("open"),o[r].classList.add("complete")):(t[r].classList.remove("open"),o[r].classList.remove("complete"))}}))},c=window.parent.location.href.match(/\/content\/(\d+)/),s=c?c[1]:null,a=["a","b","c","d","e","f","g","h","i"],d=localStorage.getItem("contentLockData");let u=d?JSON.parse(d):{};if(s){const c=parseInt(s,10);window.addEventListener("storage",(e=>{s&&((e,t)=>{e&&"contentLockData"===e.key&&e.newValue&&(u=JSON.parse(e.newValue),i(t))})(e,c)}));let d=1;e.forEach(((e,o)=>{let n=e.querySelector(".quiz form");if(t){if(n){let t=e.querySelector(".locked-content"),r=e.querySelector(".quiz .correct-answer");if(r&&(t||console.warn(`Document error: missing the locked-content class for widget number ${o+1} on this page`),r||console.warn(`Document error: missing correct-answer for content lock quiz for widget number ${o+1} on this page`),n.id=`quiz${d}`,!e.querySelector(".error-container"))){let t=document.createElement("div");t.classList.add("error-container");let n=e.querySelector("input[value='Submit']");n?n.insertAdjacentHTML("beforebegin",t.outerHTML):console.warn(`Document error: quiz is missing an input with value 'Submit' for widget number ${o+1} on this page.`)}}d++}else e.querySelector(".unlock-btn")||console.warn(`Document error: locked content area (that is not using a quiz) is missing <a> with .unlock-btn for widget number ${o+1} on this page.`)})),new Promise(((e,t)=>{let o=document.querySelectorAll(".quiz form");o&&o.forEach((e=>{e.querySelectorAll("input").forEach(((e,t)=>{e.getAttribute("value")?"Submit"==e.getAttribute("value")&&(e.setAttribute("type","button"),e.classList.add("unlock-btn")):(e.setAttribute("value",a[t]),e.setAttribute("name","options"),e.setAttribute("type","radio"))}))})),e()})).then((()=>{(()=>{const e=new Map;t.forEach((t=>{const o=t.getAttribute("data-key");if(o)if(e.has(o)){const t=e.get(o)||0;e.set(o,t+1)}else e.set(o,1)}));let o=!1;e.forEach(((e,t)=>{e>1&&(console.warn(`Document error: multiple quizzes found with the same data key (${t})`),o=!0)}))})();const e=document.querySelectorAll(".unlock-btn");u.hasOwnProperty(s)||(u[c]={keys:{}}),t.forEach(((e,t)=>{let o=e.getAttribute("data-key");if(o){let n=parseInt(o,10),r=e.parentElement;r?r.classList.contains("content-lock-widget")||console.warn(`Document error: content lock widget wrapper is missing .content-lock-widget class for widget number ${t+1} on this page`):console.warn(`Document error: content lock widget is missing parent container for widget number ${t+1} on this page`);let l=e.nextElementSibling;if(l)if(l.classList.contains("instructions")&&"DIV"===l.tagName){if(!l.querySelector(".unlock-btn")){let e=l.nextElementSibling;e?e.classList.contains("quiz")||console.warn(`Document error: missing .quiz class after locked-content ${t+1} on this page`):console.warn(`Document error: missing .unlock-btn class inside instructions ${t+1} on this page`)}}else console.warn(`Document error: instructions <div> is missing .instructions class for widget number ${t+1} on this page`);else console.warn(`Document error: locked content area is missing <div> with instructions for widget number ${t+1} on this page`);u[c].keys[n]||(u[c].keys[n]=!1)}else o||console.warn(`Document error: missing data-key for locked content for widget number ${t+1} on this page`)})),e.forEach(((e,i)=>{let s=t[i].getAttribute("data-key");if(s){let a=parseInt(s,10);null!==e.textContent&&n.push(e.textContent),e.setAttribute("tabIndex","0"),e.addEventListener("click",(()=>((e,t,o,n,i)=>{let c=!1,s=!1;"INPUT"===t.tagName&&(c=!0),c?(s=(e=>{let t=document.getElementById(`quiz${e}`);if(t){let e=t.querySelector("input[name='options']:checked"),o=t.querySelector("input.correct-answer"),n="";return e?o?e.value===o.value?(alert("Correct response"),!0):(n="Incorrect response. Please try again.",l(t,n),!1):(console.warn("Document error: no .correct-answer class applied"),!1):(n="Please select an option before submitting.",l(t,n),!1)}return console.warn("Document error: quiz id for content lock quiz, not being applied"),!1})(e),s&&r(e,i,o)):(s=window.confirm(`Please confirm: ${n[o]}`),s&&r(e,i,o))})(a,e,i,n,c))),u[c]||(u[c]={keys:{},id:0}),u[c].keys[a]&&(t[i].classList.add("open"),o[i].classList.add("complete"))}})),i(c),localStorage.setItem("contentLockData",JSON.stringify(u))})).catch((e=>{console.warn("Document error: error occurred during applyAttributesToQuiz:",e)}))}else console.warn("Document error: No course number found")};document.addEventListener("DOMContentLoaded",(()=>{e.length>0&&r(e)}))},161:()=>{const e=document.querySelectorAll(".flip-card-widget, .flip-card-group");e.length>0&&e.forEach((e=>{let t=e.querySelectorAll(".flip-card"),o=e.querySelectorAll(".inner-card"),n=e.children.length;n!==t.length&&console.warn("Document error: missing .flip-card class for flip card widget"),n!==o.length&&console.warn("Document error: missing .inner-card class for flip card widget"),t.forEach((e=>{e.querySelectorAll(".inner-card").forEach((e=>{e.setAttribute("tabindex","0"),e.addEventListener("click",(()=>{e.offsetHeight,e.classList.toggle("flip")})),e.addEventListener("keydown",(t=>{"Enter"===t.key&&(e.offsetHeight,e.classList.toggle("flip"))}))}))}))}))},3982:()=>{if(document.querySelector("body[focus-reader]")){let o=!1;const n=document.querySelector("#content-wrapper"),r=document.querySelector("body[focus-reader]"),l=document.querySelector("head"),i=document.createElement("link");i.rel="stylesheet",i.href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css",l&&l.append(i);const c=document.createElement("script");c.src="https://www.jsdelivr.com/package/npm/intersection-observer",l&&l.append(c);const s=document.createElement("div");s.className="focus-reader-switches",r&&r.append(s);const a=document.createElement("div");s.append(a);const d=document.createElement("p");d.innerHTML="Focus Text",a.append(d);const u=document.createElement("i");u.classList.add("fa-solid"),u.classList.add("fa-circle-info"),a.append(u);const m=document.createElement("span");m.classList.add("info-tooltip"),m.innerHTML="Highlight text as you scroll",u.append(m);const p=document.createElement("button");p.id="focus-text",p.innerHTML=o?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',a.append(p),p.addEventListener("click",(()=>{o?(o=!o,n&&(n.removeAttribute("on"),p.innerHTML=o?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',t(n))):(o=!o,n&&(n.setAttribute("on",""),p.innerHTML=o?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',document.querySelectorAll("#content-wrapper .content-body :is(p, li, dd, dt, blockquote)").forEach((t=>{e({node:t,focusText:g})}))))}));const g=new IntersectionObserver((e=>{e.forEach((e=>{var t,o;e.isIntersecting?null===(t=e.target.closest("span"))||void 0===t||t.classList.add("focus-text"):null===(o=e.target.closest("span"))||void 0===o||o.classList.remove("focus-text")}))}),{root:null,rootMargin:"-48.9% 0px",threshold:0})}function e({node:t,focusText:o}){var n,r;t.nodeType===Node.TEXT_NODE&&""!==(null===(n=t.textContent)||void 0===n?void 0:n.trim())?(t.textContent.split(" ").forEach((e=>{var n;if(""!==e){const r=document.createElement("span");r.textContent=e+" ",o.observe(r),null===(n=t.parentNode)||void 0===n||n.insertBefore(r,t)}})),null===(r=t.parentNode)||void 0===r||r.removeChild(t)):t.nodeType===Node.ELEMENT_NODE&&Array.from(t.childNodes).forEach((t=>{e({node:t,focusText:o})}))}function t(e){var o,n,r;if(e.nodeType===Node.ELEMENT_NODE){const l=e;if(l instanceof HTMLElement&&"SPAN"===l.tagName&&("focus-text"===l.className||""===l.className||!(null===(o=l.textContent)||void 0===o?void 0:o.trim())||0===l.attributes.length)){const e=document.createTextNode(l.textContent||"");null===(n=l.parentNode)||void 0===n||n.insertBefore(e,l),null===(r=l.parentNode)||void 0===r||r.removeChild(l)}else Array.from(l.childNodes).forEach((e=>{t(e)}))}}},8795:()=>{const e=document.querySelector(".toggle-footnotes");e&&(e=>{var t;const o=document.createElement("button");o.classList.add("toggle-footnotes"),o.textContent="[Show Footnotes]",null===(t=e.parentNode)||void 0===t||t.replaceChild(o,e),o.addEventListener("click",(()=>{o.textContent="[Show Footnotes]"===o.textContent?"[Hide Footnotes]":"[Show Footnotes]";const e=o.nextElementSibling;e&&e.classList.toggle("show")}))})(e)},9308:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079);(()=>{if(null!==n.courseBody){n.contentWrapper&&n.secondColumn&&n.thirdColumn?n.courseBody.id="three-column":n.contentWrapper&&n.secondColumn&&!n.columnWidget?n.courseBody.id="two-column":n.contentWrapper&&n.secondColumn&&n.columnWidget?n.courseBody.id="two-col-widget":n.contentWrapper&&n.videoWrapper?n.courseBody.id="video-grid":!n.contentWrapper||n.secondColumn||n.thirdColumn||n.columnWidget||n.videoWrapper?n.contentWrapper&&!n.secondColumn&&(n.thirdColumn||n.columnWidget)?console.log("Document error: <body> is missing id because #second-column doesn't exist."):console.log("Document error: unable to determine the page layout for setting <body> id."):n.courseBody.id="one-column";const e=document.body.children;let t=!1;for(let o=0;o<e.length;o++){const n=e[o];if("content-wrapper"!==n.id&&"second-column"!==n.id&&"third-column"!==n.id&&"column-widget"!==n.id&&"HEADER"!==n.tagName&&"FOOTER"!==n.tagName&&"SCRIPT"!==n.tagName&&"loom-companion-mv3"!==n.id&&"focus-reader-switches"!==n.className&&"view-options-switches"!==n.className){t=!0;break}}t&&console.log("Document error: Additional content outside #content-wrapper, #second-column, #third-column, or footer.")}else console.log("Document error: no <body> element found.")})()},7721:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079),r=document.createElement("script");r.setAttribute("src","https://pima.h5p.com/js/h5p-resizer.js"),r.setAttribute("charset","UTF-8"),r.setAttribute("defer","");const l=document.querySelectorAll("iframe"),i=null===n.docHead||void 0===n.docHead?void 0:n.docHead.querySelector("script[src='https://pima.h5p.com/js/h5p-resizer.js']");l.length>0&&l.forEach((e=>{const t=e.getAttribute("src");t&&(t.includes("/d2l/common/dialogs/quickLink")||t.includes("https://pima.h5p.com/content")||t.includes("h5p"))&&!i&&n.docHead&&n.docHead.appendChild(r)}))},7121:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079),r=document.querySelectorAll(".gallery-wrapper"),l=document.querySelectorAll(".image-box"),i=document.querySelectorAll(".image-gallery");r.length>0&&r.forEach((e=>{const t=e.parentNode;t instanceof Element&&t.classList.contains("image-gallery")||console.warn("Document error: parent of .gallery-wrapper does not have the .image-gallery class.")})),l.length>0&&l.forEach((e=>{const t=e.parentNode;t instanceof Element&&t.classList.contains("gallery-wrapper")||console.log("Document error: parent of .image-box does not have the .gallery-wrapper class.")})),r.length>0&&r.forEach((e=>{Array.from(e.children).every((e=>e instanceof HTMLElement&&e.classList.contains("image-box")))||console.warn("Document error: not all direct children of .gallery-wrapper have the .image-box class.")}));i.length>0&&((()=>{const e=document.createElement("link");e.rel="stylesheet",e.href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css",null===n.docHead||void 0===n.docHead||n.docHead.appendChild(e)})(),(()=>{i.forEach((e=>{e.insertAdjacentHTML("afterbegin",'<div class="modal-box invisible">\n <div class="gallery-overlay"></div>\n <figure class="modal-box--image"><i class="fa-solid fa-x close-img"></i> <img src="#" alt="image here" /><figcaption class="img-caption"></figcaption></figure>\n </div>\n <button class="hide-gallery">Hide</button>')}));const e=document.querySelector(".gallery-overlay"),t=document.querySelector(".modal-box"),o=document.querySelector(".modal-box--image img"),n=document.querySelector(".img-caption"),r=document.querySelector(".close-img"),c=document.querySelectorAll(".hide-gallery"),s=e=>{null==t||t.classList.remove("invisible"),o&&(o.src=e.imgSrc),n&&(n.innerHTML=e.imgCaption)},a=()=>{null==t||t.classList.add("invisible")};l.forEach((e=>{e.addEventListener("click",(function(){var e,t;s({imgSrc:(null===(e=this.querySelector("img"))||void 0===e?void 0:e.src)||"",imgCaption:(null===(t=this.querySelector("img"))||void 0===t?void 0:t.alt)||""})})),e.setAttribute("tabindex","0"),e.addEventListener("keydown",(function(e){var t,o;"Enter"===e.key&&s({imgSrc:(null===(t=this.querySelector("img"))||void 0===t?void 0:t.src)||"",imgCaption:(null===(o=this.querySelector("img"))||void 0===o?void 0:o.alt)||""})}))})),e&&(e.onclick=a),window.onkeydown=e=>{"Escape"===e.key&&a()},r&&(r.onclick=a),c.forEach((e=>{e.addEventListener("click",(()=>{var t;null===(t=e.nextElementSibling)||void 0===t||t.classList.toggle("invisible"),e.innerHTML="Hide"===e.innerHTML?"Show":"Hide"}))}))})())},81:()=>{document.addEventListener("DOMContentLoaded",(()=>{document.querySelectorAll("a[href^='#']").forEach((e=>{var t;const o=null===(t=e.getAttribute("href"))||void 0===t?void 0:t.substring(1);o&&e.setAttribute("onclick",`jumpTo("${o}")`)}))}))},4786:()=>{const e=document.querySelectorAll(".media-container");e.length>0&&e.forEach(((e,t)=>{let o=String.fromCharCode(t+65).toLowerCase(),n=e.querySelector(".media-object"),r=e.querySelector("iframe"),l=e.querySelector(".media-info");r||console.warn("Document error: no iframe found for media container"),n||console.warn("Document error: no media object found for media container"),r&&!r.hasAttribute("aria-describedby")&&l&&(r.setAttribute("aria-describedby",`${o}`),l.id=`${[o]}`)}))},4407:()=>{const e=document.querySelectorAll(".display, .display-lg");e.length>0&&[...e].forEach((e=>{const t=e.querySelectorAll(".display table th, table.display th, .display-lg table th, table.display-lg th"),o=e.querySelector(".display table tbody, table.display tbody, .display-lg table tbody, table.display-lg tbody");if(t.length>0){const e=[...t].map((e=>{var t;return(null===(t=e.textContent)||void 0===t?void 0:t.replace(/\r?\n|\r/,""))||""}));o?[...o.rows].forEach((t=>{[...t.cells].forEach(((t,o)=>{t.setAttribute("data-th",e[o])}))})):console.warn("Document error: no table <tbody> found")}else console.warn("Document error: no table headers <th> found")}))},4393:()=>{const e=document.querySelectorAll(".slider-widget");e.length>0&&(()=>{[...e].forEach((e=>{[...e.children].every((e=>e.classList.contains("slider-item")))||console.warn("Document error: not all direct children of .slider have the .slider-item class.")}));const t=(e,t,o)=>{e.forEach(((e,t)=>{e.style.display=t===o?"block":"none"})),t.forEach(((e,t)=>{e.classList.toggle("active",t===o)}))},o=(e,o,n)=>{t(e,o,n)},n=e=>{const t=document.createElement("button");return t.className=e,t.setAttribute("tabindex","-1"),t},r=e=>{let t=0;for(let o=0;o<e.children.length;o++){const n=e.children[o];n instanceof HTMLElement&&(t+=n.offsetHeight)}if(t<300&&!e.querySelector(".media-container")){const t=document.createElement("div");for(;e.firstChild;)t.appendChild(e.firstChild);e.appendChild(t),e.classList.add("short-content")}};document.querySelectorAll(".slider-widget").forEach(((e,l)=>{e.setAttribute("tabindex","0"),e.setAttribute("role","group");const i=document.createElement("span");i.id=`slider-label-${l+1}`,i.textContent="Interactive Slider",i.hidden=!0,e.prepend(i),e.setAttribute("aria-labelledby",`slider-label-${l+1}`);let c=0;const s=Array.from(e.querySelectorAll(".slider-item")),a=document.createElement("div");a.className="slider-dots-bar",e.appendChild(a);let d=[];s.forEach(((e,o)=>{const n=document.createElement("span");n.className="slider-dot",n.addEventListener("click",(()=>{c=o,t(s,d,c),s[c].style.display="block",n.classList.add("active"),r(s[c])})),a.appendChild(n),d.push(n),e.style.display=o!==c?"none":"block",o===c&&n.classList.add("active")}));const u=n("slider-arrow icon-chevron-left"),m=n("slider-arrow icon-chevron-right");e.appendChild(u),e.appendChild(m),u.addEventListener("click",(()=>{c=c>0?c-1:s.length-1,o(s,d,c),r(s[c])})),m.addEventListener("click",(()=>{c=c<s.length-1?c+1:0,o(s,d,c),r(s[c])})),e.addEventListener("keydown",(t=>{switch(t.key){case"ArrowLeft":c=c>0?c-1:s.length-1;break;case"ArrowRight":c=c<s.length-1?c+1:0;break;default:return}o(s,d,c),r(s[c]),t.preventDefault(),i.textContent=`Interactive Slide: slide ${c+1} of ${s.length}`,e.focus()}));let p=0,g=0;e.addEventListener("touchstart",(e=>{p=e.changedTouches[0].screenX}),!1),e.addEventListener("touchend",(e=>{g=e.changedTouches[0].screenX,h()}),!1);const h=()=>{let t=g-p;Math.abs(t)>50&&(c=t>0?c>0?c-1:s.length-1:c<s.length-1?c+1:0,o(s,d,c),r(s[c]),e.focus())}})),e.forEach(((e,t)=>{((e,t)=>{const o=e.querySelector(".icon-chevron-right"),n=e.querySelector(".icon-chevron-left"),r=e.querySelector(".slider-dots-bar");o||console.warn(`Document error: next button is missing for slider ${t+1}.`),n||console.warn(`Document error: previous button is missing for slider ${t+1}.`),r||console.warn(`Document error: dots bar is missing for slider ${t+1}.`)})(e,t)})),e.forEach(((e,t)=>{Array.from(e.querySelectorAll(".slider-item")).forEach(((e,o)=>{Array.from(e.childNodes).every((e=>e.nodeType===Node.COMMENT_NODE||e.nodeType===Node.TEXT_NODE&&!e.textContent.trim()))&&console.warn(`Document error: .slider-item at index ${o} in slider ${t+1} is empty.`)}))}))})()},1952:()=>{const e=document.querySelectorAll(".tabs, .tabs-widget");e.length>0&&(()=>{let t=0;e.forEach(((e,o)=>{var n,r,l,i,c,s,a,d,u,m,p,g;let h=e.querySelectorAll("input"),b=e.querySelectorAll("label"),f=e.querySelectorAll("div");if((h.length<2||b.length<2||f.length<2)&&console.warn("Document error: add more than just one tab for tabs widget"),h.length<3||b.length<3||f.length<3){let e=b[1].querySelector("span");e&&("Hide"!==e.textContent&&""!==e.textContent||console.warn("Document error: add more tabs, than just 1 tab and the hide tab"))}let v=b[b.length-1].querySelector("span");v&&"Hide"!==v.textContent&&console.warn("Document error: ensure last tab is a hide tab and label text is 'Hide'"),(h.length<b.length||h.length<f.length)&&console.warn("Document error: missing tab input(s) in tab widget"),(b.length<h.length||b.length<f.length)&&console.warn("Document error: missing tab label(s) in tab widget");let y=o+1;e.setAttribute("role","region"),e.setAttribute("aria-label",`tab group ${y}`);for(let e=0;e<h.length;e++){"Hide"===(null===(r=null===(n=b[e])||void 0===n?void 0:n.textContent)||void 0===r?void 0:r.trim())&&b[e].classList.add("hide-tab");let o=t+1;h&&f||(console.warn("Document error: no inputs found for tabs widget"),console.warn("Document error: no divs (tab panels) found for tabs widget")),b||console.warn("Document error: no labels found for tabs widget"),null===(l=h[e])||void 0===l||l.classList.add("tab-input"),null===(i=h[e])||void 0===i||i.setAttribute("type","radio"),null===(c=h[e])||void 0===c||c.setAttribute("id",`tab${o}`),null===(s=h[e])||void 0===s||s.setAttribute("name",`hint-group-${y}`),null===(a=h[e])||void 0===a||a.setAttribute("aria-describedby",`tabHeading${o}`),null===(d=b[e])||void 0===d||d.classList.add("tab-header"),null===(u=b[e])||void 0===u||u.setAttribute("for",`tab${o}`),f[e]&&(null===(m=f[e])||void 0===m||m.classList.add("tab-panel"),null===(p=f[e])||void 0===p||p.setAttribute("tabindex","0"),null===(g=f[e])||void 0===g||g.setAttribute("id",`tabHeading${o}`)),h[e].checked=0===e,e+1==h.length&&(b[e].classList.add("hide-tab"),f[e]&&f[e].classList.add("hide-panel")),t++}}))})()},7174:()=>{const e=["cas","ecn","hrs","chm","blobs"];document.querySelectorAll("link").forEach((t=>{const o=t.getAttribute("href");e.forEach((e=>{o&&o.includes(`/${e}/styles.css`)&&function(e){let t=document.createElement("script");t.src=`https://cdn.jsdelivr.net/npm/@pimaonline/pimaonline-themepack/dist/js/themes/${e}.js`,document.head.appendChild(t)}(e)}))}))},6433:()=>{const e=document.querySelectorAll(".toggle-btn");e.length>0&&(()=>{if(document.querySelector(".toggle-btn"))for(let t=0;t<e.length;t++)e[t].setAttribute("tabindex","0"),e[t].addEventListener("click",(()=>{const o=e[t].nextElementSibling;o&&o.classList.toggle("show")})),e[t].addEventListener("keydown",(o=>{if("Enter"===o.key){const o=e[t].nextElementSibling;o&&o.classList.toggle("show")}}))})()},4709:()=>{const e="toolTip",t="toolTipHover",o=document.querySelectorAll(".tooltip");o.length>0&&(()=>{const n=(e,t)=>{t.style.display="block",e.classList.toggle("hidden",!1)},r=(e,t)=>{t.style.display="none",e.setAttribute("aria-expanded","false"),e.classList.toggle("hidden",!0)};o.forEach(((o,l)=>{let i=l+1;o.id=`${e}${i}`,o.role="tooltip",o.tabIndex=0,o.setAttribute("aria-expanded","false"),o.setAttribute("aria-controls",`${t}${i.toString()}`);const c=o.querySelector(".tip-hover");c?(c.id=`${t}${i}`,c.setAttribute("aria-describedby",`${e}${i.toString()}`),o.addEventListener("mouseover",(()=>n(o,c))),o.addEventListener("mouseout",(()=>r(o,c))),o.addEventListener("focus",(()=>n(o,c))),o.addEventListener("blur",(()=>r(o,c))),o.addEventListener("touchstart",(()=>n(o,c))),o.addEventListener("touchend",(()=>r(o,c)))):console.warn("Document error: tooltip is missing .tip-hover class");let s=30-i;o.style.zIndex=s.toString()})),document.querySelectorAll(".tooltip .video-container, .tooltip .video-container").forEach((e=>{const t=e.parentElement;t&&(t.style.width="450px")}))})()},6079:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.jqueryScript=t.videoWrapper=t.rolePres=t.thirdColumn=t.secondColumn=t.docHead=t.courseBody=t.contentWrapper=t.columnWidget=void 0,t.columnWidget=document.querySelector("#column-widget"),t.contentWrapper=document.querySelector("#content-wrapper"),t.courseBody=document.querySelector("body"),t.docHead=document.querySelector("head"),t.secondColumn=document.querySelector("#second-column"),t.thirdColumn=document.querySelector("#third-column"),t.rolePres=document.querySelectorAll('[role="presentation"]'),t.videoWrapper=document.querySelector("#video-wrapper"),t.jqueryScript=document.querySelector('script[src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"]')},4019:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(3258),r=o(2692),l=o(4996),i=o(9191),c=o(3966),s=document.querySelector("body");s&&["view-options","focus-text","dark-mode","large-text","narrow-width"].some((e=>s.hasAttribute(e)))&&((0,n.callViewOptionsDrawer)(),(0,r.callFocusText)(),(0,l.callDarkMode)(),(0,i.callLargeText)(),(0,c.callNarrowWidth)())},4262:()=>{const e=document.querySelectorAll(".vocab-cards"),t=document.querySelectorAll(".vocab-cards .vocab");e.length>0&&(e.forEach((e=>{e.setAttribute("role","region"),e.setAttribute("aria-label","vocabulary list")})),t.length>0&&t.forEach((e=>{e.setAttribute("role","group")})))},7261:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528),l=o(5528),i=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("#CompletionTaskForm d2l-button-subtle");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${i.viewOptions}='activity-details']`);(0,n.darkModeCheck)(e,i.activityDetailsTabCss,t,"activity-details");let o=r.parentWindow.document.querySelector("#CompletionTaskForm d2l-button-subtle .d2l-image");o&&(l.darkOn?o.src="/shared/images/svg/chevron-down-solid-white.svg":o.src="https://s.brightspace.com/lib/bsi/2024.4.218/images/tier1/chevron-down.svg")}}}},7471:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528),l=o(5528);t.default=()=>{r.parentWindow.document.querySelectorAll("d2l-button-icon, d2l-button-icon").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${l.viewOptions}='button']`);(0,n.darkModeCheck)(e,l.buttonGroupStyle2Css,t,"button");const o=t.querySelector("d2l-icon");if(o){const e=o.shadowRoot;if(e){const t=e.querySelector(`style[${l.viewOptions}='button']`);(0,n.darkModeCheck)(t,l.buttonGroupStyle2Css,e,"button")}}}}))}},8338:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("#d2l_btn_bar");if(e){const t=e.querySelectorAll("button");if(t.length>0){let e=`\n\t#d2l_btn_bar button.d2l-button:hover {\n\t\tbackground-color: ${r.colors.colorDp1};\n\t}`;if(t.forEach((t=>{if(t.textContent){if("Edit HTML"===t.textContent.trim()){let o=t.id;o&&(e+=`\n #${o} span.d2l-icon-custom::before {\n content: url("/shared/images/svg/pencil-solid-white.svg");\n\t\t\t\twidth: 18px;\n\t\t\t\theight: 18px;\n\t\t\t\tdisplay: inline-block;\n }\n `)}if("Download"===t.textContent.trim()){let o=t.id;o&&(e+=`\n #${o} span.d2l-icon-custom::before {\n content: url("/shared/images/svg/cloud-arrow-down-solid.svg");\n\t\t\t\twidth: 18px;\n\t\t\t\theight: 18px;\n\t\t\t\tdisplay: inline-block;\n }\n `)}if("Print"===t.textContent.trim()){let o=t.id;o&&(e+=`\n #${o} span.d2l-icon-custom::before {\n content: url("/shared/images/svg/print-solid.svg");\n\t\t\t\twidth: 18px;\n\t\t\t\theight: 18px;\n\t\t\t\tdisplay: inline-block;\n }\n `)}if(t.classList.contains("ally-d2l-button")){let o=t.querySelector("img"),n=document.createElement("span");if(o)if(r.darkOn)o.style.width="0px",o.style.height="0px",n&&(n.classList.add("d2l-icon-custom"),t.prepend(n));else{o.style.width="22px",o.style.height="13px";let e=t.querySelector("span.d2l-icon-custom");e&&e.remove()}e+='\n button.ally-d2l-button span.d2l-icon-custom::before {\n content: url("/shared/images/svg/file-arrow-down-solid.svg");\n\t\t\t\t width: 14px;\n\t\t\t\t height: 18px;\n\t\t\t\t display: inline-block;\n }'}}})),r.d2lBodyElement){const t=r.d2lBodyElement.querySelector(`style[${r.viewOptions}='bottom-buttons']`);(0,n.darkModeCheck)(t,e,r.d2lBodyElement,"bottom-buttons")}}}}},8039:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(5528),r=o(8256);t.default=()=>{n.parentWindow.document.querySelectorAll("d2l-breadcrumbs > d2l-breadcrumb").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${n.viewOptions}='breadcrumb']`);(0,r.darkModeCheck)(e,n.breadcrumbsCss,t,"breadcrumb");const o=t.querySelector("d2l-icon");if(o){const e=o.shadowRoot;if(e){const t=e.querySelector(`style[${n.viewOptions}='breadcrumb-icon']`);(0,r.darkModeCheck)(t,n.whiteIconCss,e,"breadcrumb-icon")}}}}))}},3167:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(5528),r=o(8256);t.default=()=>{const e=()=>{(()=>{const e=n.parentWindow.document.querySelectorAll(".d2l-draghandle-content img.d2l-image");n.darkOn?e.forEach((e=>{e.src="/shared/images/svg/check-solid-white.svg"})):e.forEach((e=>{e.src="https://s.brightspace.com/lib/bsi/2024.4.218/images/tier1/check.svg"}))})();const t=n.parentWindow.document.querySelector("#ContentNavigator");if(t){const o=t.querySelector("d2l-button-icon[icon='tier1:chevron-left']");if(o){const l=t.querySelector("d2l-button-icon[icon='tier1:chevron-right']");if(l){const t=o.shadowRoot;if(t){const o=t.querySelector("d2l-icon");if(o){const i=o.shadowRoot;if(i){const o=l.shadowRoot;if(o){const l=o.querySelector("d2l-icon");if(l){const e=l.shadowRoot;if(e){const l=t.querySelector(`style[${n.viewOptions}='chevron']`),c=o.querySelector(`style[${n.viewOptions}='chevron']`),s=i.querySelector(`style[${n.viewOptions}='chevron']`),a=e.querySelector(`style[${n.viewOptions}='chevron']`);(0,r.darkModeCheck)(l,n.buttonGroupCss,t,"chevron"),(0,r.darkModeCheck)(c,n.buttonGroupCss,o,"chevron"),(0,r.darkModeCheck)(s,n.buttonGroupCss,i,"chevron"),(0,r.darkModeCheck)(a,n.buttonGroupCss,e,"chevron")}}const c=t.querySelector("button[title='Previous module']"),s=o.querySelector("button[title='Next module']");c&&(c.addEventListener("click",(()=>{setTimeout(e,500)})),c.addEventListener("keydown",(t=>{"Enter"===t.key&&setTimeout(e,500)}))),s&&(s.addEventListener("click",(()=>{setTimeout(e,500)})),s.addEventListener("keydown",(t=>{"Enter"===t.key&&setTimeout(e,500)})))}}}}}}}},t=n.parentWindow.document.querySelector(".d2l-page-collapsepane-shadow");t&&(t.addEventListener("click",(()=>{setTimeout(e,500)})),t.addEventListener("keydown",(t=>{"Enter"===t.key&&e()})))}},1179:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-navigation-button-icon[icon='tier1:chevron-left']");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='chevron-back']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"chevron-back")}}}}const t=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:classes']"),o=()=>{r.parentWindow.document.querySelectorAll(".d2l-datalist-item .d2l-course-selector-item span d2l-button-icon").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='pin']`),o=t.querySelector("d2l-icon");if(o){const l=o.shadowRoot;if(l){const o=l.querySelector(`style[${r.viewOptions}='pin']`);(0,n.darkModeCheck)(o,r.whiteIconCss,l,"pin"),(0,n.darkModeCheck)(e,r.pinBtnStylesCss,t,"pin")}}}}))};t&&(t.addEventListener("click",(()=>{setTimeout(o,1e3)})),t.addEventListener("keydown",(e=>{"Enter"===e.key&&setTimeout(o,1e3)})));const l=r.parentWindow.document.querySelector("d2l-navigation-button-icon[icon='tier3:classes']");if(l){const e=l.shadowRoot;if(e){const t=e.querySelector("d2l-icon");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector(`style[${r.viewOptions}='waffle-icon']`);(0,n.darkModeCheck)(t,r.whiteIconCss,e,"waffle-icon"),l.addEventListener("click",(()=>{setTimeout(o,1e3)})),l.addEventListener("keydown",(e=>{"Enter"===e.key&&setTimeout(o,1e3)}))}}}}}},4387:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(5528);t.default=()=>{const e=document.querySelector("head"),t=document.querySelector("body");if(e&&t){const o=e.querySelector("link[href='darkmode.css']");if(n.darkOn){if(t.setAttribute("dark-mode-on",""),!o){const t=document.createElement("link");t.setAttribute("rel","stylesheet"),t.setAttribute("href","darkmode.css"),e.append(t)}}else t.hasAttribute("dark-mode-on")&&t.removeAttribute("dark-mode-on"),o&&e.removeChild(o)}}},7338:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-dropdown-context-menu");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-button-icon");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon");if(e){const o=e.shadowRoot;if(o){const e=o.querySelector(`style[${r.viewOptions}='chevron']`),l=o.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(e,r.buttonGroupCss,t,"chevron"),(0,n.darkModeCheck)(l,r.buttonGroupCss,o,"chevron")}}}}}}const t=r.parentWindow.document.querySelector("d2l-dropdown-context-menu"),o=()=>{const e=r.parentWindow.document.querySelector(".d2l-dropdown-menu-contextmenu");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='dropdown-menu']`);(0,n.darkModeCheck)(e,r.dropdownDarkBackgroundCss,t,"dropdown-menu")}}};t&&t.addEventListener("click",(()=>{setTimeout(o,250)}))}},2209:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-navigation-button-icon[icon='tier3:menu-hamburger']");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon[icon='tier3:menu-hamburger']");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='hamburger']`);(0,n.darkModeCheck)(e,r.buttonGroupCss,t,"hamburger")}}}}}},7383:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{r.parentWindow.document.querySelectorAll("d2l-icon").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='svg']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"svg")}}))}},630:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(5528),r=o(8256);t.default=()=>{n.parentWindow.document.querySelectorAll("d2l-navigation-link-image").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(".d2l-navigation-link-image-container");if(e){const o=t.querySelectorAll(`style[${n.viewOptions}='logo-img']`);if(n.darkOn){let l=e.querySelector("img");l&&l.remove(),0===o.length&&(0,r.injectCSS)(n.logoCss,t,"logo-img");const i=document.createElement("img");i.classList.add("logo-img-white"),i.src="/shared/images/svg/pima-logo-white.svg",i.alt="My Home",e.append(i)}else{let t=e.querySelector("img");t&&t.remove(),o.length>1&&o[0].remove();const n=document.createElement("img");n.classList.add("logo-img"),n.src="/d2l/lp/navbars/6606/theme/viewimage/2389656/view?v=20.24.4.19097",e.append(n)}}}}))}},2:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-menu-item-link");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='hamburger']`);(0,n.darkModeCheck)(e,r.buttonGroupCss,t,"hamburger")}}r.parentWindow.document.querySelectorAll(".d2l-navigation-s-mobile-menu-nav > d2l-menu > d2l-menu-item").forEach((e=>{(e=>{const t=e.shadowRoot;if(t){const o=t.querySelector("d2l-icon");if(o){const t=o.shadowRoot;if(t){const o=t.querySelector(`style[${r.viewOptions}='chevron']`),l=e.querySelector("d2l-menu");if(l){const e=l.shadowRoot;if(e){const l=e.querySelector("d2l-menu-item-return");if(l){const i=t.querySelector(`style[${r.viewOptions}='return-item-one']`),c=l.shadowRoot;if(c){const l=c.querySelector("d2l-icon");if(l){const c=l.shadowRoot;if(c){const l=c.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(o,r.whiteIconCss,t,"chevron"),(0,n.darkModeCheck)(i,r.returnMenuCss,e,"return-item-one"),(0,n.darkModeCheck)(l,r.whiteIconCss,c,"chevron")}}}}}}}}}})(e),e.querySelectorAll("d2l-menu>d2l-menu-item").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelectorAll("d2l-icon");e.length>0&&e.forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"chevron")}}))}const o=e.querySelector("d2l-menu");if(o){const e=o.shadowRoot;if(e){const t=e.querySelector("d2l-menu-item-return");if(t){const o=e.querySelector(`style[${r.viewOptions}='return-item-two']`),l=t.shadowRoot;if(l){const t=l.querySelector("d2l-icon");if(t){const l=t.shadowRoot;if(l){const t=l.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(t,r.whiteIconCss,l,"chevron"),(0,n.darkModeCheck)(o,r.returnMenuCss,e,"return-item-two")}}}}}}}))}))}},9085:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528),l=o(5528);t.default=()=>{r.parentWindow.document.querySelectorAll("d2l-menu > d2l-menu-item-link, d2l-menu > d2l-menu-item").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='dropdown']`);(0,n.darkModeCheck)(e,l.dropdownMenuCss,t,"dropdown")}})),r.parentWindow.document.querySelectorAll("d2l-dropdown-menu, d2l-dropdown-content").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='dropdown']`);(0,n.darkModeCheck)(e,l.dropdownBorderCss,t,"dropdown");const o=t.querySelector("d2l-icon[icon='tier1:chevron-right']"),i=t.querySelector(`style[${r.viewOptions}='chevron']`);o&&(0,n.darkModeCheck)(i,l.dropdownMenuCss,t,"chevron")}}))}},9764:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=".d2l-branding-navigation-dark-foreground-color .d2l-navigation-s-group",t=".vui-list>li.vui-selected, .vui-list>li.vui-selected",o="#ContentNavigator .vui-list > .vui-selected",l=".vui-tabmenu > .vui-tabmenu-item-select > a",i="#CompletionTaskForm d2l-button-subtle",c="div.d2l-filterinline-group-filter > div > a",s=`html {background: ${r.colors.colorDark};}`,a=`#d2l_body, .d2l-body {background: ${r.colors.colorDark};}`,d=`.d2l-navigation-s, .d2l-branding-navigation-background-color, d2l-navigation-main-header {background: ${r.colors.colorDp1};}`,u=`.d2l-branding-navigation-dark-foreground-color a.d2l-navigation-s-link, .d2l-branding-navigation-dark-foreground-color a.d2l-navigation-s-link:link, .d2l-branding-navigation-dark-foreground-color a.d2l-navigation-s-link:visited, .d2l-branding-navigation-dark-foreground-color div.d2l-navigation-s-item>span, ${e}, ${e} {color: ${r.colors.textColor}}`,m=`d2l-breadcrumbs::after {background: ${r.colors.colorDark};}`,p=`${t} {background: ${r.colors.colorDp1}}`,g=`.d2l-courseselector-wrapper, .d2l-page-main-padding > .d2l-datalist-style1, .d2l-page-main-padding > .d2l-placeholder > .d2l-datalist-style1, .d2l-page-main-padding > form > .d2l-datalist-style1, .d2l-datalist-outdent, ${t} {background: ${r.colors.colorDark}}`,h=`.vui-list>.d2l-list-item-action-hover {background: ${r.colors.colorDp1} !important}`,b=`.vui-list>li.d2l-list-item-action-hover.vui-selected {background: ${r.colors.colorDp2} !important}`,f=`.d2l-admin-tools, .d2l-admin-tools .d2l-heading {background: ${r.colors.colorDark}; color: ${r.colors.textColor}}`,v=`.d2l-page-collapsepane-content-inner, ${o}, .d2l-page-collapsepane-handle, .d2l-page-collapsepane.d2l-page-collapsepane-opening .d2l-page-collapsepane-handle, .d2l-page-collapsepane-content {background: ${r.colors.colorDark}}`,y=`${o} {background: ${r.colors.colorDp1}; border-top-color: ${r.colors.textColor}}`,w=`.d2l-link.d2l-link-flat, .d2l-linkheading-link.d2l-link-flat {color: ${r.colors.colorLinks}}`,k=`.d2l-page-collapsepane.d2l-page-collapsepane-opening .d2l-page-collapsepane-handle .d2l-page-collapsepane-handle-link, .d2l-page-collapsepane-handle-link {border-right-color: ${r.colors.textColor}; border-left-color: ${r.colors.textColor}; border-color: ${r.colors.borderColor}}`,S=`.d2l-iterator-button, .d2l-iterator-button.d2l-iterator-button-disabled:hover, .d2l-iterator-button.d2l-iterator-button-disabled:focus {background: transparent; border-color: ${r.colors.colorDp1};}`,C=`.d2l-link, .d2l-link:visited, .d2l-link:active, .d2l-link:link {color: ${r.colors.linkColor}}`,$=`d2l-dropdown-content .d2l-list {background: ${r.colors.colorDark};}`,q=`.d2l-editable:hover {background: ${r.colors.colorDp4}}`,E=`.d2l-button, .d2l-button[active][disabled], .d2l-button[disabled]:focus, .d2l-button[disabled]:hover {background: ${r.colors.colorDark}; border: 1px solid ${r.colors.textColor}; color: ${r.colors.textColor}}`,x=`${l}, .vui-tabmenu > .vui-tabmenu-item:last-child > a, ${l}, .vui-tabmenu > .vui-tabmenu-item > a {background: ${r.colors.colorDp1}; color: ${r.colors.textColor}}`,A=`.d2l-typography {color: ${r.colors.textColor}}`,L=`.d2l-navigation-s-personal-menu-text, .d2l-textblock-secondary {color: ${r.colors.textColor}}`,D=`.d2l-navigation-s-linkarea-no-color .d2l-navigation-s-group:hover, .d2l-navigation-s-linkarea-no-color a.d2l-navigation-s-link:hover {color: ${r.colors.linkColor};}`,M=`\n button:not([disabled]):hover, button:not([disabled]):focus, button[active], *:focus > .d2l-navigation-highlight-border, *:hover > .d2l-navigation-highlight-border, *[active] > .d2l-navigation-highlight-border {\n --d2l-icon-fill-color: ${r.colors.colorLinks} !important;\n --d2l-color-celestine: ${r.colors.colorLinks} !important;\n }\n `,O=`#AdditionalInfoPlaceholder .vui-tabmenu .vui-tabmenu-item a:hover {color: ${r.colors.borderColor}}`,T=`${i} .d2l-container-icon .d2l-textblock {color: ${r.colors.textColor}}\n\t${i} .d2l-inline .d2l-container-icon {background-image: url("/shared/images/svg/check-solid-white.svg")}\n`,_=`${c} {color: ${r.colors.textColor}}\n\t${c}:hover {color: ${r.colors.borderColor}}\n\t#ResultDetails #Filter .d2l-filterinline-item-selected {color: ${r.colors.colorLinks}}\n\t`,N=`#EvaluationSummaryTabId button:hover {background-color: ${r.colors.colorDp1}}`,j=`button:focus:not([disabled]) {background-color: ${r.colors.colorDp1}}`,P=`.d2l-page-collapsepane .d2l-page-collapsepane-handle-link {border-color: transparent;border-left: 5px solid ${r.colors.textColor};}`,H=`.d2l-page-collapsepane.d2l-page-collapsepane-open .d2l-page-collapsepane-handle-link {border-color: transparent !important; border-right: 5px solid ${r.colors.textColor} !important;}`,B=`.d2l-branding-navigation-dark-foreground-color .d2l-navigation-s-mobile-menu-title-bp {color: ${r.colors.textColor}}`,W=`.d2l-navigation-s-mobile-menu-content {background-color: ${r.colors.colorDark}}`,R=`.d2l-navigation-s-mobile-menu-nav d2l-menu-item-link, .d2l-navigation-s-mobile-menu-nav d2l-menu-item, .d2l-navigation-s-mobile-menu-nav d2l-menu-item {background-color: ${r.colors.colorDark}}`,I=`\n\t\t${a}\n\t\t${d}\n\t\t${v}\n\t\t${y}\n\t\t${S}\n\t\t${g}\n\t\t${h}\n\t\t${p}\n\t\t${b}\n\t\t${f}\n\t\t${u}\n\t\t${w}\n\t\t${C}\n\t\t${k}\n\t\t${$}\n\t\t${q}\n\t\t${E}\n\t\t${x}\n\t\t${A}\n\t\t${L}\n\t\t${M}\n\t\t${D}\n\t ${m}\n\t ${O}\n\t ${T}\n\t ${_}\n\t ${N}\n\t ${j}\n\t ${P}\n\t ${H}\n\t .d2l-draghandle-handle-icon {background-image: url("/shared/images/svg/grip-vertical-solid-white.svg")}\n\t .d2l-draghandle-content .d2l-container-icon {background-image: url("/shared/images/svg/globe-solid-white.svg")}\n\t ${B}\n\t ${W}\n\t .d2l-navigation-s-mobile-menu-nav d2l-menu-item-link:hover, .d2l-navigation-s-mobile-menu-nav d2l-menu-item:hover {background-color: ${r.colors.colorDp1}}\n\t ${R}\n\t #ContentNavigator .d2l-link.d2l-link-flat:focus, #ContentNavigator .d2l-link.d2l-link-flat:hover, .d2l-linkheading-link.d2l-link-flat:focus, #ContentNavigator .d2l-linkheading-link.d2l-link-flat:hover {color: ${r.colors.linkColor}}\n\t .d2l-typography .d2l-body-small {color: ${r.colors.textColor}}\n\t \n\n d2l-menu-item-link.d2l-navigation-s-menu-item-root, d2l-menu-item.d2l-navigation-s-menu-item-root {\n background: ${r.colors.colorDark};\n }\n\n .d2l-menu-item-text {\n color: ${r.colors.textColor};\n }\n\n\t\td2l-dropdown d2l-icon[icon='tier1:chevron-down'] {\n\t\t\tfill: ${r.colors.textColor};\n\t\t}\n\t .d2l-courseselector-wrapper #courseSelectorId .d2l-datalist-item .d2l-course-selector-item a {color: ${r.colors.textColor}}\n\t d2l-dropdown-content d2l-datalist vui-list d2l-datalist-item {background-color: ${r.colors.colorDp1} !important}\n\t d2l-dropdown-content .d2l-data-list-item-action-hover {background-color: ${r.colors.colorDp2} !important}\n\t .d2l-navigation-s-mobile-menu-content d2l-navigation-band {background: transparent}\n\t d2l-navigation-dropdown-button-icon[icon='tier3:notification-bell'] d2l-dropdown-content button.d2l-loadmore-pager {\n\tbackground-color: ${r.colors.colorPrimary};\n\tcolor: ${r.colors.colorBlack};\n\tborder: none;\n\t}\n\t d2l-navigation-dropdown-button-icon[icon='tier3:notification-bell'] d2l-dropdown-content button.d2l-loadmore-pager:hover {\n\tbackground-color: ${r.colors.colorPrimaryHover};\n\tcolor: ${r.colors.colorBlack};\n\tborder: none;\n\t}\n\t .d2l-messagebucket-button-container + #AB_DL_PH_Messages .d2l-datalist-container {background: ${r.colors.colorDark}}\n\t d2l-menu.d2l-menu-mvc.d2l-contextmenu d2l-menu-item {color: ${r.colors.textColor};\n\tbackground-color: ${r.colors.colorDark};\n\t}\n\t d2l-menu.d2l-menu-mvc.d2l-contextmenu d2l-menu-item:hover {\n\tcolor: ${r.colors.textColor};\n\tbackground: ${r.colors.colorDp1};\n\t}\n\t .d2l-navigation-s-more d2l-menu > d2l-menu-item {\n\t\tbackground: ${r.colors.colorDark}\n\t}\n\t .d2l-navigation-s-more d2l-menu > d2l-menu-item:hover {\n\t\tbackground: ${r.colors.colorDp1}\n\t}\n\t .d2l-editable.d2l-editable-autosize.d2l-editable-focus {background: ${r.colors.colorDark}}\n\t .d2l-navigation-s-linkarea-no-color .d2l-navigation-s-group:focus {color: ${r.colors.textColor}}\n\t d2l-dropdown-more d2l-menu d2l-menu-item, d2l-dropdown-more d2l-menu d2l-menu-item-link {\n\tbackground-color: ${r.colors.colorDark};\n\t}\n\t d2l-dropdown-more d2l-menu d2l-menu-item:hover, d2l-dropdown-more d2l-menu d2l-menu-item-link:hover {\n\tbackground-color: ${r.colors.colorDp1};\n\t}\n\t #CompletionTaskForm .d2l-container-icon {background-image: url('/shared/images/svg/check-solid-white.svg')}\n\t\tul.d2l-personal-tools-list li {color: ${r.colors.textColor}}\n\t\tul.d2l-personal-tools-list li a.d2l-link {color: ${r.colors.textColor}}\n\tul.d2l-personal-tools-list li a.d2l-link:hover {color: ${r.colors.linkColor}}\n\t\t#ContentNavigator a.d2l-link {color: ${r.colors.textColor}}\n\t\t#ContentNavigator a.d2l-link:hover {color: ${r.colors.linkColor}}\n\t\td2l-menu-item.d2l-navigation-s-menu-item-root:hover, d2l-menu-item-link.d2l-navigation-s-menu-item-root:hover {background: ${r.colors.colorDp1}}\n\t\t#AdminToolsPlaceholderId a.d2l-link {color: ${r.colors.textColor}}\n\t\t#AdminToolsPlaceholderId a.d2l-link:hover {color: ${r.colors.linkColor}}\n\t\t.d2l-iterator-button {background: ${r.colors.colorDp1}}\n\t\t${s}\n\t`;if(r.d2lBodyElement){const e=r.d2lBodyElement.querySelector(`style[${r.viewOptions}='parent']`);(0,n.darkModeCheck)(e,I,r.d2lBodyElement,"parent")}}},7152:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelectorAll(".d2l-navigation-s-item.d2l-navigation-s-more d2l-menu-item");e.length>0&&e.forEach((e=>{const t=e.querySelector("d2l-menu");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector(`style[${r.viewOptions}='return-item']`);(0,n.darkModeCheck)(t,r.returnMenuCss,e,"return-item");const o=e.querySelector("d2l-menu-item-return");if(o){const e=o.shadowRoot;if(e){const t=e.querySelector("d2l-icon");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(t,r.whiteIconCss,e,"chevron")}}}}}}const o=e.shadowRoot;if(o){const e=o.querySelector("d2l-icon");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"chevron")}}}}))}},9301:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-navigation");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='band']`);(0,n.darkModeCheck)(e,r.topNavigationBandCss,t,"band")}}}},9283:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=()=>{const e=r.parentWindow.document.querySelectorAll("d2l-navigation-dropdown-button-icon");e.length>0&&e.forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon");if(e){const o=e.shadowRoot;if(o){const e=t.querySelector(`style[${r.viewOptions}='waffle']`),l=o.querySelector(`style[${r.viewOptions}='waffle-icon']`);(0,n.darkModeCheck)(l,r.topNavIconCss,t,"waffle"),(0,n.darkModeCheck)(e,r.whiteIconCss,o,"waffle-icon")}}}}));const t=r.parentWindow.document.querySelector("d2l-navigation-button-icon[icon='tier3:classes']");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector("d2l-icon");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector(`style[${r.viewOptions}='waffle-icon']`);(0,n.darkModeCheck)(t,r.whiteIconCss,e,"waffle-icon")}}}}};e();const t=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:notification-bell']");t&&t.addEventListener("click",e);const o=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:discussions']");o&&o.addEventListener("click",e);const l=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:email']");l&&l.addEventListener("click",e)}},513:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:notification-bell']");if(e){const t=()=>{e.querySelectorAll("d2l-icon").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='icon-white']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"icon-white")}}))};e.addEventListener("click",(()=>{setTimeout(t,750)}))}const t=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:discussions']");if(t){const e=()=>{const e=t.querySelector("d2l-empty-state-simple");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='icon-white']`);(0,n.darkModeCheck)(e,r.messageAreaBkgCss,t,"icon-white")}}};t.addEventListener("click",(()=>{setTimeout(e,500)}))}const o=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:email']");if(o){const e=()=>{const e=o.querySelector("d2l-button-subtle[icon='tier1:email']");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon");if(e){const l=e.shadowRoot;if(l){const e=l.querySelector(`style[${r.viewOptions}='button-styles']`),i=l.querySelector(`style[${r.viewOptions}='button-styles']`);(0,n.darkModeCheck)(i,r.messageButtonCss,t,"button-styles"),(0,n.darkModeCheck)(e,r.messageButtonCss,l,"button-styles");const c=o.querySelector("#AB_DL_PH_Messages>div");if(c){const e=c.querySelector("d2l-empty-state-simple");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='empty-state-container']`);(0,n.darkModeCheck)(e,r.messageAreaBkgCss,t,"empty-state-container")}}}}}}}};o.addEventListener("click",(()=>{setTimeout(e,500)}))}}},8495:function(e,t,o){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=n(o(7261)),l=n(o(7471)),i=n(o(8338)),c=n(o(8039)),s=n(o(3167)),a=n(o(1179)),d=n(o(4387)),u=n(o(7338)),m=n(o(2209)),p=n(o(7383)),g=n(o(630)),h=n(o(2)),b=n(o(9085)),f=n(o(9764)),v=n(o(7152)),y=n(o(9301)),w=n(o(9283)),k=n(o(513)),S=()=>{(0,r.default)(),(0,l.default)(),(0,i.default)(),(0,c.default)(),(0,s.default)(),(0,a.default)(),(0,d.default)(),(0,u.default)(),(0,m.default)(),(0,p.default)(),(0,g.default)(),(0,h.default)(),(0,b.default)(),(0,f.default)(),(0,v.default)(),(0,y.default)(),(0,w.default)(),(0,k.default)()};document.querySelector("body[dark-mode]")&&S(),t.default=S},1424:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),o(5528),o(8256),o(8495)},8256:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.darkModeCheck=t.injectCSS=void 0;const n=o(5528);function r(e,t,o){const r=document.createElement("style");r.setAttribute(`${n.viewOptions}`,o),r.innerHTML=e,t.prepend(r)}t.injectCSS=r,t.darkModeCheck=function(e,t,o,l){n.darkOn?null==e&&r(t,o,l):null!=e&&e.remove()}},5528:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.darkBackgroundAlertCss=t.topNavIconCss=t.topNavigationBandCss=t.dropdownDarkBackgroundCss=t.pinBtnStylesCss=t.breadcrumbsCss=t.buttonGroupStyle2Css=t.activityDetailsTabCss=t.dropdownBorderCss=t.dropdownMenuCss=t.messageButtonCss=t.messageAreaBkgCss=t.returnMenuCss=t.logoCss=t.buttonGroupCss=t.whiteIconCss=t.d2lBodyElement=t.parentWindow=t.toggleDarkOn=t.darkOn=t.colors=t.viewOptions=void 0,t.viewOptions="pccviewoptions",t.colors={colorPrimary:"rgba(149, 209, 255, 1)",colorPrimaryHover:"rgba(126, 199, 255, 1)",colorDark:"rgba(15, 23, 42, 1)",colorDp1:"rgba(255, 255, 255, .05)",colorDp2:"rgba(255, 255, 255, .07)",colorDp3:"rgba(255, 255, 255, .08)",colorDp4:"rgba(255, 255, 255, .09)",colorLinks:"rgba(56, 189, 248, 1)",colorLinksHover:"rgba(136, 179, 202, 1)",colorLinksVisited:"rgba(185, 183, 237, 1)",colorBlack:"rgba(13, 13, 13, 1)",linkColor:"rgba(56, 189, 248, 1)",textColor:"rgba(255, 255, 255, 1)",borderColor:"rgba(255, 255, 255, .5)",pccPrimary:"rgba(4, 85, 148, 1)"},t.darkOn=!1,t.toggleDarkOn=()=>{t.darkOn=!t.darkOn},t.parentWindow=window.parent,t.d2lBodyElement=t.parentWindow.document.querySelector(".d2l-body"),t.whiteIconCss=`svg {color: ${t.colors.textColor};fill: ${t.colors.textColor};}`,t.buttonGroupCss="\n\tbutton:hover:not([disabled]), button:focus:not([disabled]), :host([active]) button:not([disabled]) {\n\t\tbackground-color: transparent !important;\n\t}\n\n\tsvg {\n\t\tcolor: white !important;\n\t\tfill: white !important;\n\t}",t.logoCss="\n\t.logo-img {\n\t\twidth: 40px;\n\t\theight: 173px;\n\t}\n\t.logo-img-white {\n\t\twidth: 60px;\n\t\tmax-height: 60px !important;\n\t\theight: 173px;\n\t\tmargin-left: -10px;\n\t\tmargin-right: -5px;\n\t}",t.returnMenuCss=`\n\td2l-menu-item-return {background-color: ${t.colors.colorDp2}}\n\td2l-menu-item-return:hover {background-color: ${t.colors.colorDp3}}\n\td2l-menu-item-return {color: ${t.colors.textColor}}\n\t`,t.messageAreaBkgCss=`\n\t.empty-state-container {background: ${t.colors.colorDark}}\n\t.empty-state-container p {color: ${t.colors.textColor}}\n\t}`,t.messageButtonCss=`\nbutton:hover:not([disabled]), button:focus:not([disabled]), :host([active]) button:not([disabled]) {\n color: ${t.colors.colorBlack} !important;\n background-color: ${t.colors.colorPrimaryHover} !important;\n}\nbutton {\n color: ${t.colors.colorBlack} !important;\n background-color: ${t.colors.colorPrimary} !important;\n} \nbutton .d2l-button-subtle-content {\n color: ${t.colors.colorBlack} !important;\n background-color: transparent !important;\n}\nbutton .d2l-button-subtle-content:hover {\n color: ${t.colors.colorBlack} !important;\n background-color: transparent !important;\n}\nsvg {\n color: ${t.colors.colorBlack} !important;\n fill: ${t.colors.colorBlack} !important;\n}`;const o="d2l-menu-item-link.d2l-navigation-s-menu-item-root",n="d2l-menu-item.d2l-navigation-s-menu-item-root";t.dropdownMenuCss=`\n ${o}, ${n} {\n background: ${t.colors.colorDark} !important;\n }\n .d2l-menu-item-text {\n color: ${t.colors.textColor} !important;\n }\n ${o}:hover, ${n}:hover {\n background: rgba(255, 255, 255, .05) !important;\n } \n `,t.dropdownBorderCss=`\n .d2l-dropdown-content-top, .d2l-dropdown-content-bottom, .d2l-dropdown-content-pointer > div {\n background: ${t.colors.colorDark} !important;\n }\n\n\t.d2l-dropdown-content-width {\n\t background-color: ${t.colors.colorDark} !important;\n\t}`,t.activityDetailsTabCss=`\nbutton:hover, button:focus, :host([active]) button {\n background-color: ${t.colors.colorDp2} !important;\n}`,t.buttonGroupStyle2Css=`\nbutton:hover:not([disabled]), button:focus:not([disabled]), :host([active]) button:not([disabled]) {\n background-color: ${t.colors.colorDp1} !important;\n}\nsvg {\n color: white !important;\n fill: white !important;\n}`,t.breadcrumbsCss=`\n.d2l-link, .d2l-link:visited, .d2l-link:active, .d2l-link:link { \n color: ${t.colors.textColor} !important; \n}\n .d2l-link:hover { \n color: ${t.colors.linkColor} !important; \n}`,t.pinBtnStylesCss=`\nbutton:hover:not([disabled]), button:focus:not([disabled]), :host([active]) button:not([disabled]) {\n background-color: ${t.colors.linkColor} !important\n}`,t.dropdownDarkBackgroundCss=`\n#d2l-dropdown-wrapper {\n background-color: ${t.colors.colorDark}\n}`,t.topNavigationBandCss="\n\td2l-navigation-band {\n\t background: transparent;\n\t}",t.topNavIconCss=`button:not([disabled]):hover, button:not([disabled]):focus, button[active], *:focus > .d2l-navigation-highlight-border, *:hover > .d2l-navigation-highlight-border, *[active] > .d2l-navigation-highlight-border {\n --d2l-icon-fill-color: ${t.colors.colorLinks} !important;\n --d2l-color-celestine: ${t.colors.colorLinks} !important;\n }`,t.darkBackgroundAlertCss=`\nd2l-alert {\n background-color: ${t.colors.colorDark}\n}`,t.default=t.colors},4996:function(e,t,o){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.callDarkMode=void 0;const r=o(5528),l=n(o(8495));let i=!1;t.callDarkMode=function(){const e=document.querySelector("#dark-mode-btn");e?(e.addEventListener("click",(t=>{t.stopPropagation(),i=!i,(0,r.toggleDarkOn)(),e.innerHTML=i?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',(0,l.default)()})),e.addEventListener("keydown",(t=>{"Enter"!==t.key&&13!==t.keyCode||(t.preventDefault(),i=!i,(0,r.toggleDarkOn)(),e.innerHTML=i?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',(0,l.default)())}))):console.warn("Document error: dark mode switch element is missing - event listeners not added")}},3258:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.callViewOptionsDrawer=void 0,t.callViewOptionsDrawer=function(){let e=!1;const t=document.querySelector("body"),o=document.querySelector("head"),n=(e,t)=>{const n=document.createElement(e);Object.keys(t).forEach((e=>n.setAttribute(e,t[e]))),null==o||o.append(n)};n("link",{rel:"stylesheet",href:"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"}),n("script",{src:"https://www.jsdelivr.com/package/npm/intersection-observer"});const r=document.createElement("div");function l(e,t,o,n){return`\n <div class="${o}-wrapper">\n <img src="${n}" alt="">\n <p class="feature">${e}</p>\n <p class="caption">${t}</p>\n <button id="${o}-btn" class="vo-toggle-btns" tabindex="-1" aria-label="${e.toLowerCase()} toggle button" aria-checked="false" role="button">\n <i class="fas fa-toggle-off"></i>\n </button>\n </div>\n `}r.className="view-options-switches",null==t||t.append(r),r.innerHTML=`\n <button aria-label="view options drawer" aria-expanded="false" role="button" tabindex="1">\n <img src="/shared/images/svg/sliders-icon.svg" alt="">\n </button>\n <div class="control-panel">\n <h2>View Options</h2>\n ${l("Dark Mode","Turn browser dark","dark-mode","/shared/images/svg/moon-icon.svg")}\n ${l("Large Text","Increase font size","large-text","/shared/images/svg/text-icon.svg")}\n ${l("Focus Text","Highlight text as you scroll","focus-text","/shared/images/svg/eye-icon.svg")}\n ${l("Narrow Width","Make width of text narrow","narrow-width","/shared/images/svg/width-icon.svg")}\n </div>\n `;const i={"focus-text":document.querySelector(".focus-text-wrapper"),"dark-mode":document.querySelector(".dark-mode-wrapper"),"large-text":document.querySelector(".large-text-wrapper"),"narrow-width":document.querySelector(".narrow-width-wrapper"),"view-options":document.querySelectorAll(".focus-text-wrapper, .dark-mode-wrapper, .large-text-wrapper, .narrow-width-wrapper")};for(const e in i)if(null==t?void 0:t.hasAttribute(e)){const t=i[e];"view-options"===e?t.forEach((e=>{e instanceof HTMLElement&&(e.style.display="grid")})):t instanceof HTMLElement&&(t.style.display="grid")}((null==t?void 0:t.hasAttribute("view-options"))&&(document.querySelector("#second-column")||document.querySelector("#third-column"))||window.innerWidth<768)&&i["narrow-width"]&&(i["narrow-width"].style.display="none");const c=document.querySelector(".view-options-switches > button"),s=["#focus-text-btn","#dark-mode-btn","#large-text-btn","#narrow-width-btn"].map((e=>document.querySelector(e)));function a(t){t.stopPropagation(),e=!e,r.classList.toggle("expand-panel"),s.forEach((t=>null==t?void 0:t.setAttribute("tabindex",e?"1":"-1")))}null==c||c.addEventListener("click",a),null==c||c.addEventListener("keydown",(e=>{"Enter"!==e.key&&13!==e.keyCode||(e.preventDefault(),a(e))})),document.addEventListener("click",(t=>{!e||r.contains(t.target)||(null==c?void 0:c.contains(t.target))||a(t)}))}},6289:(e,t)=>{function o(e,t){e.nodeType===Node.TEXT_NODE&&""!==e.textContent.trim()?(e.textContent.split(" ").forEach((o=>{if(""!==o){const n=document.createElement("span");n.textContent=o+" ",t.observe(n),e.parentNode?e.parentNode.insertBefore(n,e):console.warn("Document error: parent node not found for text node")}})),e.parentNode?e.parentNode.removeChild(e):console.warn("Document error: parent node not found to remove text node")):e.nodeType===Node.ELEMENT_NODE&&Array.from(e.childNodes).forEach((e=>{o(e,t)}))}function n(e){if(e.nodeType===Node.ELEMENT_NODE){const t=e;if("SPAN"!==t.tagName||"focus-text"!==t.className&&""!==t.className&&""!==t.textContent.trim()&&0!==t.attributes.length)Array.from(e.childNodes).forEach((e=>{n(e)}));else{const e=document.createTextNode(t.textContent);t.parentNode?(t.parentNode.insertBefore(e,t),t.parentNode.removeChild(t)):console.warn("Document error: parent node not found for span element")}}}Object.defineProperty(t,"__esModule",{value:!0}),t.focusText=t.removeSpans=t.traverseAndWrapTextInSpans=t.toggleFocusText=t.options=void 0,t.options={root:null,rootMargin:"-48.9% 0px",threshold:0},t.toggleFocusText=function(e,t,r){if(e&&t){const e=t.querySelectorAll("#content-wrapper .content-body :is(p, li, dd, dt, blockquote)");0===e.length&&console.warn("Document error: no elements found to wrap for focus text"),e.forEach((e=>{o(e,r)}))}else t?n(t):console.warn("Document error: content wrapper element not found for removing spans")},t.traverseAndWrapTextInSpans=o,t.removeSpans=n,t.focusText=new IntersectionObserver((e=>{e.forEach((e=>{const t=e.target.closest("span");t?e.isIntersecting?t.classList.add("focus-text"):t.classList.remove("focus-text"):console.warn("Document error: closest span not found for intersection observer entry")}))}),t.options)},2692:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.callFocusText=void 0;const n=o(6289);t.callFocusText=function(){let e=!1;const t=document.querySelector("#content-wrapper"),o=document.querySelector("#focus-text-btn");function r(){e=!e,t?t.toggleAttribute("focus-on",e):console.warn("Document error: content wrapper element not found"),o?(o.setAttribute("aria-checked",e.toString()),o.innerHTML=e?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>'):console.warn("Document error: focus text switch element not found"),(0,n.toggleFocusText)(e,t,n.focusText)}o?(o.addEventListener("click",(e=>{e.stopPropagation(),r()})),o.addEventListener("keydown",(e=>{"Enter"!==e.key&&13!==e.keyCode||(e.preventDefault(),r())}))):console.warn("Document error: focus text switch element is missing - event listeners not added")}},5207:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.processElements=t.getLargeTextElementsSelectors=t.adjustParagraphMargins=t.wordSpacing=t.lineHeight=t.lgFont=t.mdFont=void 0,t.mdFont=4,t.lgFont=6,t.lineHeight=1.5,t.wordSpacing=.16,t.adjustParagraphMargins=function(e){document.querySelectorAll(".content-body p, .content-body > h3").forEach((t=>{e?(t.dataset.originalMarginBottom=t.style.marginBottom,t.style.marginBottom="1em"):t.style.marginBottom=t.dataset.originalMarginBottom||""}))},t.getLargeTextElementsSelectors=function(e){const t=".header :is(h1, p), .content-body :is(h2, h3, h4, h5, h6, p:not(table p), li, a:not(table a), blockquote, figcaption, .front, .overlay, .back, dt, dd, span), footer *, #footer p",o="td, th, label";return{largeTextElements:e.querySelectorAll(t),smallerTextElements:e.querySelectorAll(o),largeTextSelectors:t,smallerTextSelectors:o}},t.processElements=function(e,t,o,n,r,l,i,c,s){e.forEach((e=>{if(!e)return;let a=e.parentElement;for(;a&&!a.matches(t?s:c);)a=a.parentElement;if(!a)if(o){const o=window.getComputedStyle(e);e.dataset.originalFontSize=o.fontSize,e.dataset.originalLineHeight=o.lineHeight,e.dataset.originalWordSpacing=o.wordSpacing;const c=parseFloat(o.fontSize)+(t?n:r);e.style.fontSize=`${c}px`,e.style.lineHeight=`${l}`,e.style.wordSpacing=`${i}em`}else e.removeAttribute("style"),e.removeAttribute("data-original-margin-bottom"),e.removeAttribute("data-original-font-size"),e.removeAttribute("data-original-line-height"),e.removeAttribute("data-original-word-spacing")}))}},9191:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.callLargeText=void 0;const n=o(6079),r=o(5207);t.callLargeText=function(){let e=!1;const t=document.querySelector("#large-text-btn");function o(){if(e=!e,!n.courseBody)return void console.warn("Document error: content wrapper element not found");n.courseBody.toggleAttribute("large-text-on",e),(0,r.adjustParagraphMargins)(e);const{largeTextElements:o,smallerTextElements:l,largeTextSelectors:i,smallerTextSelectors:c}=(0,r.getLargeTextElementsSelectors)(n.courseBody);(0,r.processElements)(l,!0,e,r.mdFont,r.lgFont,r.lineHeight,r.wordSpacing,i,c),(0,r.processElements)(o,!1,e,r.mdFont,r.lgFont,r.lineHeight,r.wordSpacing,i,c),t.setAttribute("aria-checked",e.toString()),t.innerHTML=e?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>'}t?(t.addEventListener("click",(e=>{e.stopPropagation(),o()})),t.addEventListener("keydown",(e=>{"Enter"!==e.key&&13!==e.keyCode||(e.preventDefault(),o())}))):console.warn("Document error: large text switch element is missing - event listeners not added")}},3966:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.callNarrowWidth=void 0,t.callNarrowWidth=function(){let e=!1;const t=document.querySelector("#content-wrapper"),o=document.querySelector("#narrow-width-btn");function n(){e=!e,t?t.toggleAttribute("narrow-on",e):console.warn("Document error: content wrapper element not found"),o?(o.setAttribute("aria-checked",e.toString()),o.innerHTML=e?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>'):console.warn("Document error: narrow width switch element not found")}o?(o.addEventListener("click",(e=>{e.stopPropagation(),n()})),o.addEventListener("keydown",(e=>{"Enter"!==e.key&&13!==e.keyCode||(e.preventDefault(),n())}))):console.warn("Document error: narrow width switch element is missing - event listeners not added")}}},t={};!function o(n){var r=t[n];if(void 0!==r)return r.exports;var l=t[n]={exports:{}};return e[n].call(l.exports,l,l.exports,o),l.exports}(7080)})();
|