├── .gitignore
├── LICENSE
├── _quarto.yml
├── articles
├── html
│ ├── README.md
│ ├── html.html
│ ├── html.qmd
│ ├── manifest.json
│ └── requirements.txt
├── msword
│ ├── msword.docx
│ └── msword.qmd
└── pdf
│ ├── pandoc-user-guide.pdf
│ └── pandoc-user-guide.qmd
├── docs
├── articles
│ ├── html
│ │ └── html.html
│ ├── msword
│ │ └── msword.docx
│ └── pdf
│ │ └── pandoc-user-guide.pdf
├── page-layout
│ ├── tufte.html
│ └── tufte.pdf
├── presentations
│ ├── beamer
│ │ └── beamer.pdf
│ ├── powerpoint
│ │ └── powerpoint.pptx
│ └── revealjs
│ │ └── reveal.html
├── search.json
└── site_libs
│ ├── bootstrap
│ ├── bootstrap-icons.css
│ ├── bootstrap-icons.woff
│ ├── bootstrap.min.css
│ └── bootstrap.min.js
│ ├── clipboard
│ └── clipboard.min.js
│ ├── dygraphs-1.1.1
│ ├── dygraph-combined-dev.js
│ ├── dygraph-combined.js
│ ├── dygraph.css
│ └── shapes.js
│ ├── dygraphs-binding-1.1.1.6
│ └── dygraphs.js
│ ├── htmlwidgets-1.5.2
│ └── htmlwidgets.js
│ ├── jquery-1.11.1
│ ├── AUTHORS.txt
│ └── jquery.min.js
│ ├── moment-2.8.4
│ ├── moment-timezone-with-data.js
│ └── moment.js
│ ├── moment-fquarter-1.0.0
│ └── moment-fquarter.min.js
│ ├── moment-timezone-0.2.5
│ ├── moment-timezone-with-data.js
│ └── moment.js
│ ├── quarto-html
│ ├── anchor.min.js
│ ├── popper.min.js
│ ├── quarto-html.min.css
│ ├── quarto-syntax-highlighting.css
│ ├── quarto.js
│ ├── tabby.min.js
│ ├── tippy.css
│ └── tippy.umd.min.js
│ ├── quarto-nav
│ └── quarto-nav.js
│ ├── quarto-search
│ ├── autocomplete.umd.js
│ ├── fuse.min.js
│ └── quarto-search.js
│ └── revealjs
│ ├── dist
│ ├── reset.css
│ ├── reveal.css
│ ├── reveal.esm.js
│ ├── reveal.esm.js.map
│ ├── reveal.js
│ ├── reveal.js.map
│ └── theme
│ │ ├── fonts
│ │ ├── league-gothic
│ │ │ ├── LICENSE
│ │ │ ├── league-gothic.css
│ │ │ ├── league-gothic.eot
│ │ │ ├── league-gothic.ttf
│ │ │ └── league-gothic.woff
│ │ └── source-sans-pro
│ │ │ ├── LICENSE
│ │ │ ├── source-sans-pro-italic.eot
│ │ │ ├── source-sans-pro-italic.ttf
│ │ │ ├── source-sans-pro-italic.woff
│ │ │ ├── source-sans-pro-regular.eot
│ │ │ ├── source-sans-pro-regular.ttf
│ │ │ ├── source-sans-pro-regular.woff
│ │ │ ├── source-sans-pro-semibold.eot
│ │ │ ├── source-sans-pro-semibold.ttf
│ │ │ ├── source-sans-pro-semibold.woff
│ │ │ ├── source-sans-pro-semibolditalic.eot
│ │ │ ├── source-sans-pro-semibolditalic.ttf
│ │ │ ├── source-sans-pro-semibolditalic.woff
│ │ │ └── source-sans-pro.css
│ │ └── quarto.css
│ └── plugin
│ ├── highlight
│ ├── highlight.esm.js
│ ├── highlight.js
│ ├── monokai.css
│ ├── plugin.js
│ └── zenburn.css
│ ├── markdown
│ ├── markdown.esm.js
│ ├── markdown.js
│ └── plugin.js
│ ├── math
│ ├── katex.js
│ ├── math.esm.js
│ ├── math.js
│ ├── mathjax2.js
│ ├── mathjax3.js
│ └── plugin.js
│ ├── notes
│ ├── notes.esm.js
│ ├── notes.js
│ ├── plugin.js
│ └── speaker-view.html
│ ├── pdf-export
│ ├── pdfexport.js
│ └── plugin.yml
│ ├── quarto-line-highlight
│ ├── line-highlight.css
│ ├── line-highlight.js
│ └── plugin.yml
│ ├── quarto-support
│ ├── footer.css
│ ├── plugin.yml
│ └── support.js
│ ├── reveal-menu
│ ├── menu.css
│ ├── menu.js
│ ├── plugin.yml
│ ├── quarto-menu.css
│ └── quarto-menu.js
│ ├── search
│ ├── plugin.js
│ ├── search.esm.js
│ └── search.js
│ └── zoom
│ ├── plugin.js
│ ├── zoom.esm.js
│ └── zoom.js
├── page-layout
├── README.md
├── manifest.json
├── requirements.txt
├── skeleton.bib
├── tufte.html
├── tufte.pdf
└── tufte.qmd
├── presentations
├── beamer
│ ├── beamer.pdf
│ ├── beamer.qmd
│ └── clemson.png
├── powerpoint
│ ├── powerpoint.pptx
│ ├── powerpoint.qmd
│ ├── ref-arch.png
│ ├── servers.png
│ └── template.pptx
└── revealjs
│ ├── README.md
│ ├── image
│ ├── background_1.png
│ ├── background_2.png
│ ├── division_1.png
│ ├── division_2.png
│ ├── documentation.png
│ ├── efficiency.png
│ ├── format_1_1.png
│ ├── format_1_2.png
│ ├── format_1_3.png
│ ├── format_1_4.png
│ ├── format_2_1.png
│ ├── format_2_2.png
│ ├── format_2_3.png
│ ├── format_2_4.png
│ ├── gif_0.png
│ ├── gif_1.png
│ ├── gif_2.png
│ ├── gif_3.png
│ ├── gif_4.png
│ ├── gif_5.png
│ ├── gif_6.png
│ ├── gif_7.png
│ ├── gif_8.png
│ ├── gif_9.png
│ ├── icjia.png
│ ├── il_seal.gif
│ ├── interface.gif
│ ├── modularity_1.png
│ ├── modularity_2.png
│ ├── process_new.png
│ └── process_old.png
│ ├── manifest.json
│ ├── requirements.txt
│ ├── reveal.html
│ ├── reveal.qmd
│ └── rsconnect
│ └── documents
│ └── reveal.qmd
│ └── rpubs.com
│ └── rpubs
│ └── Document.dcf
└── quarto-gallery.Rproj
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 |
6 |
7 | /.quarto/
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 quarto-dev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/_quarto.yml:
--------------------------------------------------------------------------------
1 | project:
2 | type: website
3 | output-dir: docs
4 | resources:
5 | - page-layout/tufte.pdf
6 |
--------------------------------------------------------------------------------
/articles/html/README.md:
--------------------------------------------------------------------------------
1 | ## HTML article
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/articles/html/html.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
element after existing one
91 | code.parentNode.appendChild(fragmentBlock);
92 |
93 | // Each new element is highlighted based on the new attributes value
94 | highlightCodeBlock(fragmentBlock);
95 |
96 | if (typeof fragmentIndex === "number") {
97 | fragmentBlock.setAttribute(kFragmentIndex, fragmentIndex);
98 | fragmentIndex += 1;
99 | } else {
100 | fragmentBlock.removeAttribute(kFragmentIndex);
101 | }
102 |
103 | // Scroll highlights into view as we step through them
104 | fragmentBlock.addEventListener(
105 | "visible",
106 | scrollHighlightedLineIntoView.bind(
107 | this,
108 | fragmentBlock,
109 | scrollState
110 | )
111 | );
112 | fragmentBlock.addEventListener(
113 | "hidden",
114 | scrollHighlightedLineIntoView.bind(
115 | this,
116 | fragmentBlock.previousSibling,
117 | scrollState
118 | )
119 | );
120 | }
121 | );
122 | code.removeAttribute(kFragmentIndex);
123 | code.setAttribute(
124 | kCodeLineNumbersAttr,
125 | joinLineNumbers([highlightSteps[0]])
126 | );
127 | }
128 |
129 | // Scroll the first highlight into view when the slide becomes visible.
130 | const slide =
131 | typeof code.closest === "function"
132 | ? code.closest("section:not(.stack)")
133 | : null;
134 | if (slide) {
135 | const scrollFirstHighlightIntoView = function () {
136 | scrollHighlightedLineIntoView(code, scrollState, true);
137 | slide.removeEventListener(
138 | "visible",
139 | scrollFirstHighlightIntoView
140 | );
141 | };
142 | slide.addEventListener("visible", scrollFirstHighlightIntoView);
143 | }
144 |
145 | highlightCodeBlock(code);
146 | });
147 | }
148 | }
149 | });
150 | }
151 |
152 | function highlightCodeBlock(codeBlock) {
153 | const highlightSteps = splitLineNumbers(
154 | codeBlock.getAttribute(kCodeLineNumbersAttr)
155 | );
156 |
157 | if (highlightSteps.length) {
158 | // If we have at least one step, we generate fragments
159 | highlightSteps[0].forEach((highlight) => {
160 | // Add expected class on for reveal CSS
161 | codeBlock.parentNode.classList.add("code-wrapper");
162 |
163 | // Select lines to highlight
164 | spanToHighlight = [];
165 | if (typeof highlight.last === "number") {
166 | spanToHighlight = [].slice.call(
167 | codeBlock.querySelectorAll(
168 | ":scope > span:nth-child(n+" +
169 | highlight.first +
170 | "):nth-child(-n+" +
171 | highlight.last +
172 | ")"
173 | )
174 | );
175 | } else if (typeof highlight.first === "number") {
176 | spanToHighlight = [].slice.call(
177 | codeBlock.querySelectorAll(
178 | ":scope > span:nth-child(" + highlight.first + ")"
179 | )
180 | );
181 | }
182 | if (spanToHighlight.length) {
183 | // Add a class on and to select line to highlight
184 | spanToHighlight.forEach((span) =>
185 | span.classList.add("highlight-line")
186 | );
187 | codeBlock.classList.add("has-line-highlights");
188 | }
189 | });
190 | }
191 | }
192 |
193 | /**
194 | * Animates scrolling to the first highlighted line
195 | * in the given code block.
196 | */
197 | function scrollHighlightedLineIntoView(block, scrollState, skipAnimation) {
198 | window.cancelAnimationFrame(scrollState.animationFrameID);
199 |
200 | // Match the scroll position of the currently visible
201 | // code block
202 | if (scrollState.currentBlock) {
203 | block.scrollTop = scrollState.currentBlock.scrollTop;
204 | }
205 |
206 | // Remember the current code block so that we can match
207 | // its scroll position when showing/hiding fragments
208 | scrollState.currentBlock = block;
209 |
210 | const highlightBounds = getHighlightedLineBounds(block);
211 | let viewportHeight = block.offsetHeight;
212 |
213 | // Subtract padding from the viewport height
214 | const blockStyles = window.getComputedStyle(block);
215 | viewportHeight -=
216 | parseInt(blockStyles.paddingTop) + parseInt(blockStyles.paddingBottom);
217 |
218 | // Scroll position which centers all highlights
219 | const startTop = block.scrollTop;
220 | let targetTop =
221 | highlightBounds.top +
222 | (Math.min(highlightBounds.bottom - highlightBounds.top, viewportHeight) -
223 | viewportHeight) /
224 | 2;
225 |
226 | // Make sure the scroll target is within bounds
227 | targetTop = Math.max(
228 | Math.min(targetTop, block.scrollHeight - viewportHeight),
229 | 0
230 | );
231 |
232 | if (skipAnimation === true || startTop === targetTop) {
233 | block.scrollTop = targetTop;
234 | } else {
235 | // Don't attempt to scroll if there is no overflow
236 | if (block.scrollHeight <= viewportHeight) return;
237 |
238 | let time = 0;
239 |
240 | const animate = function () {
241 | time = Math.min(time + 0.02, 1);
242 |
243 | // Update our eased scroll position
244 | block.scrollTop =
245 | startTop + (targetTop - startTop) * easeInOutQuart(time);
246 |
247 | // Keep animating unless we've reached the end
248 | if (time < 1) {
249 | scrollState.animationFrameID = requestAnimationFrame(animate);
250 | }
251 | };
252 |
253 | animate();
254 | }
255 | }
256 |
257 | function getHighlightedLineBounds(block) {
258 | const highlightedLines = block.querySelectorAll(".highlight-line");
259 | if (highlightedLines.length === 0) {
260 | return { top: 0, bottom: 0 };
261 | } else {
262 | const firstHighlight = highlightedLines[0];
263 | const lastHighlight = highlightedLines[highlightedLines.length - 1];
264 |
265 | return {
266 | top: firstHighlight.offsetTop,
267 | bottom: lastHighlight.offsetTop + lastHighlight.offsetHeight,
268 | };
269 | }
270 | }
271 |
272 | /**
273 | * The easing function used when scrolling.
274 | */
275 | function easeInOutQuart(t) {
276 | // easeInOutQuart
277 | return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
278 | }
279 |
280 | function splitLineNumbers(lineNumbersAttr) {
281 | // remove space
282 | lineNumbersAttr = lineNumbersAttr.replace("/s/g", "");
283 | // seperate steps (for fragment)
284 | lineNumbersAttr = lineNumbersAttr.split(delimiters.step);
285 |
286 | // for each step, calculate first and last line, if any
287 | return lineNumbersAttr.map((highlights) => {
288 | // detect lines
289 | const lines = highlights.split(delimiters.line);
290 | return lines.map((range) => {
291 | if (/^[\d-]+$/.test(range)) {
292 | range = range.split(delimiters.lineRange);
293 | const firstLine = parseInt(range[0], 10);
294 | const lastLine = range[1] ? parseInt(range[1], 10) : undefined;
295 | return {
296 | first: firstLine,
297 | last: lastLine,
298 | };
299 | } else {
300 | return {};
301 | }
302 | });
303 | });
304 | }
305 |
306 | function joinLineNumbers(splittedLineNumbers) {
307 | return splittedLineNumbers
308 | .map(function (highlights) {
309 | return highlights
310 | .map(function (highlight) {
311 | // Line range
312 | if (typeof highlight.last === "number") {
313 | return highlight.first + delimiters.lineRange + highlight.last;
314 | }
315 | // Single line
316 | else if (typeof highlight.first === "number") {
317 | return highlight.first;
318 | }
319 | // All lines
320 | else {
321 | return "";
322 | }
323 | })
324 | .join(delimiters.line);
325 | })
326 | .join(delimiters.step);
327 | }
328 |
329 | return {
330 | id: "quarto-line-highlight",
331 | init: function (deck) {
332 | initQuartoLineHighlight(deck);
333 |
334 | // If we're printing to PDF, scroll the code highlights of
335 | // all blocks in the deck into view at once
336 | deck.on("pdf-ready", function () {
337 | [].slice
338 | .call(
339 | deck
340 | .getRevealElement()
341 | .querySelectorAll(
342 | "pre code[data-code-line-numbers].current-fragment"
343 | )
344 | )
345 | .forEach(function (block) {
346 | scrollHighlightedLineIntoView(block, {}, true);
347 | });
348 | });
349 | },
350 | };
351 | };
352 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/quarto-line-highlight/plugin.yml:
--------------------------------------------------------------------------------
1 | # adapted from https://github.com/hakimel/reveal.js/tree/master/plugin/highlight
2 | name: QuartoLineHighlight
3 | script: line-highlight.js
4 | stylesheet: line-highlight.css
5 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/quarto-support/footer.css:
--------------------------------------------------------------------------------
1 | .reveal .slide-logo {
2 | display: block;
3 | position: fixed;
4 | bottom: 0;
5 | right: 12px;
6 | max-height: 2.2rem;
7 | width: auto;
8 | }
9 |
10 | .reveal .footer {
11 | display: block;
12 | position: fixed;
13 | bottom: 18px;
14 | width: 100%;
15 | margin: 0 auto;
16 | text-align: center;
17 | font-size: 18px;
18 | z-index: 2;
19 | }
20 |
21 | .reveal .footer > * {
22 | margin-top: 0;
23 | margin-bottom: 0;
24 | }
25 |
26 | .reveal .slide .footer {
27 | display: none;
28 | }
29 |
30 | .reveal .slide-number {
31 | bottom: 10px;
32 | right: 10px;
33 | font-size: 16px;
34 | background-color: transparent;
35 | }
36 |
37 | .reveal.has-logo .slide-number {
38 | bottom: initial;
39 | top: 8px;
40 | right: 8px;
41 | }
42 |
43 | .reveal .slide-number .slide-number-delimiter {
44 | margin: 0;
45 | }
46 |
47 | .reveal .slide-menu-button {
48 | left: 8px;
49 | bottom: 8px;
50 | }
51 |
52 | .reveal .slide-chalkboard-buttons {
53 | position: fixed;
54 | left: 12px;
55 | bottom: 8px;
56 | z-index: 30;
57 | font-size: 24px;
58 | }
59 |
60 | .reveal .slide-chalkboard-buttons.slide-menu-offset {
61 | left: 54px;
62 | }
63 |
64 | .reveal .slide-chalkboard-buttons > span {
65 | margin-right: 14px;
66 | cursor: pointer;
67 | }
68 |
69 | @media screen and (max-width: 800px) {
70 | .reveal .slide-logo {
71 | max-height: 1.1rem;
72 | bottom: -2px;
73 | right: 10px;
74 | }
75 | .reveal .footer {
76 | font-size: 14px;
77 | bottom: 12px;
78 | }
79 | .reveal .slide-number {
80 | font-size: 12px;
81 | bottom: 7px;
82 | }
83 | .reveal .slide-menu-button .fas::before {
84 | height: 1.3rem;
85 | width: 1.3rem;
86 | vertical-align: -0.125em;
87 | background-size: 1.3rem 1.3rem;
88 | }
89 |
90 | .reveal .slide-chalkboard-buttons .fas::before {
91 | height: 0.95rem;
92 | width: 0.95rem;
93 | background-size: 0.95rem 0.95rem;
94 | vertical-align: -0em;
95 | }
96 |
97 | .reveal .slide-chalkboard-buttons.slide-menu-offset {
98 | left: 36px;
99 | }
100 | .reveal .slide-chalkboard-buttons > span {
101 | margin-right: 9px;
102 | }
103 | }
104 |
105 | html.print-pdf .reveal .slide-menu-button,
106 | html.print-pdf .reveal .slide-chalkboard-buttons {
107 | display: none;
108 | }
109 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/quarto-support/plugin.yml:
--------------------------------------------------------------------------------
1 | name: QuartoSupport
2 | script: support.js
3 | stylesheet: footer.css
4 | config:
5 | smaller: false
6 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/quarto-support/support.js:
--------------------------------------------------------------------------------
1 | // catch all plugin for various quarto features
2 | window.QuartoSupport = function () {
3 | function isPrintView() {
4 | return /print-pdf/gi.test(window.location.search);
5 | }
6 |
7 | // implement controlsAudo
8 | function controlsAuto(deck) {
9 | const config = deck.getConfig();
10 | if (config.controlsAuto === true) {
11 | const iframe = window.location !== window.parent.location;
12 | const localhost =
13 | window.location.hostname === "localhost" ||
14 | window.location.hostname === "127.0.0.1";
15 | deck.configure({
16 | controls:
17 | (iframe && !localhost) ||
18 | (deck.hasVerticalSlides() && config.navigationMode !== "linear"),
19 | });
20 | }
21 | }
22 |
23 | // helper to provide event handlers for all links in a container
24 | function handleLinkClickEvents(deck, container) {
25 | Array.from(container.querySelectorAll("a")).forEach((el) => {
26 | const url = el.getAttribute("href");
27 | if (/^(http|www)/gi.test(url)) {
28 | el.addEventListener(
29 | "click",
30 | (ev) => {
31 | const fullscreen = !!window.document.fullscreen;
32 | const dataPreviewLink = el.getAttribute("data-preview-link");
33 |
34 | // if there is a local specifcation then use that
35 | if (dataPreviewLink) {
36 | if (
37 | dataPreviewLink === "true" ||
38 | (dataPreviewLink === "auto" && fullscreen)
39 | ) {
40 | ev.preventDefault();
41 | deck.showPreview(url);
42 | return false;
43 | }
44 | } else {
45 | const previewLinks = !!deck.getConfig().previewLinks;
46 | const previewLinksAuto =
47 | deck.getConfig().previewLinksAuto === true;
48 | if (previewLinks == true || (previewLinksAuto && fullscreen)) {
49 | ev.preventDefault();
50 | deck.showPreview(url);
51 | return false;
52 | }
53 | }
54 |
55 | // if the deck is in an iframe we want to open it externally
56 | const iframe = window.location !== window.parent.location;
57 | if (iframe) {
58 | ev.preventDefault();
59 | ev.stopImmediatePropagation();
60 | window.open(url, "_blank");
61 | return false;
62 | }
63 |
64 | // if the user has set data-preview-link to "auto" we need to handle the event
65 | // (because reveal will interpret "auto" as true)
66 | if (dataPreviewLink === "auto") {
67 | ev.preventDefault();
68 | ev.stopImmediatePropagation();
69 | const target =
70 | el.getAttribute("target") ||
71 | (ev.ctrlKey || ev.metaKey ? "_blank" : "");
72 | if (target) {
73 | window.open(url, target);
74 | } else {
75 | window.location.href = url;
76 | }
77 | return false;
78 | }
79 | },
80 | false
81 | );
82 | }
83 | });
84 | }
85 |
86 | // implement previewLinksAuto
87 | function previewLinksAuto(deck) {
88 | handleLinkClickEvents(deck, deck.getRevealElement());
89 | }
90 |
91 | // apply styles
92 | function applyGlobalStyles(deck) {
93 | if (deck.getConfig()["smaller"] === true) {
94 | const revealParent = deck.getRevealElement();
95 | revealParent.classList.add("smaller");
96 | }
97 | }
98 |
99 | // add logo image
100 | function addLogoImage(deck) {
101 | const revealParent = deck.getRevealElement();
102 | const logoImg = document.querySelector(".slide-logo");
103 | if (logoImg) {
104 | revealParent.appendChild(logoImg);
105 | revealParent.classList.add("has-logo");
106 | }
107 | }
108 |
109 | // add footer text
110 | function addFooter(deck) {
111 | const revealParent = deck.getRevealElement();
112 | const defaultFooterDiv = document.querySelector(".footer-default");
113 | if (defaultFooterDiv) {
114 | revealParent.appendChild(defaultFooterDiv);
115 | handleLinkClickEvents(deck, defaultFooterDiv);
116 | if (!isPrintView()) {
117 | deck.on("slidechanged", function (ev) {
118 | const prevSlideFooter = document.querySelector(
119 | ".reveal > .footer:not(.footer-default)"
120 | );
121 | if (prevSlideFooter) {
122 | prevSlideFooter.remove();
123 | }
124 | const currentSlideFooter = ev.currentSlide.querySelector(".footer");
125 | if (currentSlideFooter) {
126 | defaultFooterDiv.style.display = "none";
127 | const slideFooter = currentSlideFooter.cloneNode(true);
128 | handleLinkClickEvents(deck, slideFooter);
129 | deck.getRevealElement().appendChild(slideFooter);
130 | } else {
131 | defaultFooterDiv.style.display = "block";
132 | }
133 | });
134 | }
135 | }
136 | }
137 |
138 | // add chalkboard buttons
139 | function addChalkboardButtons(deck) {
140 | const chalkboard = deck.getPlugin("RevealChalkboard");
141 | if (chalkboard && !isPrintView()) {
142 | const revealParent = deck.getRevealElement();
143 | const chalkboardDiv = document.createElement("div");
144 | chalkboardDiv.classList.add("slide-chalkboard-buttons");
145 | if (document.querySelector(".slide-menu-button")) {
146 | chalkboardDiv.classList.add("slide-menu-offset");
147 | }
148 | // add buttons
149 | const buttons = [
150 | {
151 | icon: "easel2",
152 | title: "Toggle Chalkboard (b)",
153 | onclick: chalkboard.toggleChalkboard,
154 | },
155 | {
156 | icon: "brush",
157 | title: "Toggle Notes Canvas (c)",
158 | onclick: chalkboard.toggleNotesCanvas,
159 | },
160 | ];
161 | buttons.forEach(function (button) {
162 | const span = document.createElement("span");
163 | span.title = button.title;
164 | const icon = document.createElement("i");
165 | icon.classList.add("fas");
166 | icon.classList.add("fa-" + button.icon);
167 | span.appendChild(icon);
168 | span.onclick = function (event) {
169 | event.preventDefault();
170 | button.onclick();
171 | };
172 | chalkboardDiv.appendChild(span);
173 | });
174 | revealParent.appendChild(chalkboardDiv);
175 | const config = deck.getConfig();
176 | if (!config.chalkboard.buttons) {
177 | chalkboardDiv.classList.add("hidden");
178 | }
179 |
180 | // show and hide chalkboard buttons on slidechange
181 | deck.on("slidechanged", function (ev) {
182 | const config = deck.getConfig();
183 | let buttons = !!config.chalkboard.buttons;
184 | const slideButtons = ev.currentSlide.getAttribute(
185 | "data-chalkboard-buttons"
186 | );
187 | if (slideButtons) {
188 | if (slideButtons === "true" || slideButtons === "1") {
189 | buttons = true;
190 | } else if (slideButtons === "false" || slideButtons === "0") {
191 | buttons = false;
192 | }
193 | }
194 | if (buttons) {
195 | chalkboardDiv.classList.remove("hidden");
196 | } else {
197 | chalkboardDiv.classList.add("hidden");
198 | }
199 | });
200 | }
201 | }
202 |
203 | function handleTabbyClicks() {
204 | const tabs = document.querySelectorAll(".panel-tabset-tabby > li > a");
205 | for (let i = 0; i < tabs.length; i++) {
206 | const tab = tabs[i];
207 | tab.onclick = function (ev) {
208 | ev.preventDefault();
209 | ev.stopPropagation();
210 | return false;
211 | };
212 | }
213 | }
214 |
215 | function fixupForPrint(deck) {
216 | if (isPrintView()) {
217 | const slides = deck.getSlides();
218 | slides.forEach(function (slide) {
219 | slide.removeAttribute("data-auto-animate");
220 | });
221 | window.document.querySelectorAll(".hljs").forEach(function (el) {
222 | el.classList.remove("hljs");
223 | });
224 | window.document.querySelectorAll(".hljs-ln-code").forEach(function (el) {
225 | el.classList.remove("hljs-ln-code");
226 | });
227 | }
228 | }
229 |
230 | return {
231 | id: "quarto-support",
232 | init: function (deck) {
233 | controlsAuto(deck);
234 | previewLinksAuto(deck);
235 | fixupForPrint(deck);
236 | applyGlobalStyles(deck);
237 | addLogoImage(deck);
238 | addFooter(deck);
239 | addChalkboardButtons(deck);
240 | handleTabbyClicks();
241 | },
242 | };
243 | };
244 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/reveal-menu/menu.css:
--------------------------------------------------------------------------------
1 | .slide-menu-wrapper {
2 | font-family: 'Source Sans Pro', Helvetica, sans-serif;
3 | }
4 |
5 | .slide-menu-wrapper .slide-menu {
6 | background-color: #333;
7 | z-index: 200;
8 | position: fixed;
9 | top: 0;
10 | width: 300px;
11 | height: 100%;
12 | /*overflow-y: scroll;*/
13 | transition: transform 0.3s;
14 | font-size: 16px;
15 | font-weight: normal;
16 | }
17 |
18 | .slide-menu-wrapper .slide-menu.slide-menu--wide {
19 | width: 500px;
20 | }
21 |
22 | .slide-menu-wrapper .slide-menu.slide-menu--third {
23 | width: 33%;
24 | }
25 |
26 | .slide-menu-wrapper .slide-menu.slide-menu--half {
27 | width: 50%;
28 | }
29 |
30 | .slide-menu-wrapper .slide-menu.slide-menu--full {
31 | width: 95%;
32 | }
33 |
34 | /*
35 | * Slides menu
36 | */
37 |
38 | .slide-menu-wrapper .slide-menu-items {
39 | margin: 0;
40 | padding: 0;
41 | width: 100%;
42 | border-bottom: solid 1px #555;
43 | }
44 |
45 | .slide-menu-wrapper .slide-menu-item,
46 | .slide-menu-wrapper .slide-menu-item-vertical {
47 | display: block;
48 | text-align: left;
49 | padding: 10px 18px;
50 | color: #aaa;
51 | cursor: pointer;
52 | }
53 |
54 | .slide-menu-wrapper .slide-menu-item-vertical {
55 | padding-left: 30px;
56 | }
57 |
58 | .slide-menu-wrapper .slide-menu--wide .slide-menu-item-vertical,
59 | .slide-menu-wrapper .slide-menu--third .slide-menu-item-vertical,
60 | .slide-menu-wrapper .slide-menu--half .slide-menu-item-vertical,
61 | .slide-menu-wrapper .slide-menu--full .slide-menu-item-vertical,
62 | .slide-menu-wrapper .slide-menu--custom .slide-menu-item-vertical {
63 | padding-left: 50px;
64 | }
65 |
66 | .slide-menu-wrapper .slide-menu-item {
67 | border-top: solid 1px #555;
68 | }
69 |
70 | .slide-menu-wrapper .active-menu-panel li.selected {
71 | background-color: #222;
72 | color: white;
73 | }
74 |
75 | .slide-menu-wrapper .active-menu-panel li.active {
76 | color: #eee;
77 | }
78 |
79 | .slide-menu-wrapper .slide-menu-item.no-title .slide-menu-item-title,
80 | .slide-menu-wrapper .slide-menu-item-vertical.no-title .slide-menu-item-title {
81 | font-style: italic;
82 | }
83 |
84 | .slide-menu-wrapper .slide-menu-item-number {
85 | color: #999;
86 | padding-right: 6px;
87 | }
88 |
89 | .slide-menu-wrapper .slide-menu-item i.far,
90 | .slide-menu-wrapper .slide-menu-item i.fas,
91 | .slide-menu-wrapper .slide-menu-item-vertical i.far,
92 | .slide-menu-wrapper .slide-menu-item-vertical i.fas,
93 | .slide-menu-wrapper .slide-menu-item svg.svg-inline--fa,
94 | .slide-menu-wrapper .slide-menu-item-vertical svg.svg-inline--fa {
95 | padding-right: 12px;
96 | display: none;
97 | }
98 |
99 | .slide-menu-wrapper .slide-menu-item.past i.fas.past,
100 | .slide-menu-wrapper .slide-menu-item-vertical.past i.fas.past,
101 | .slide-menu-wrapper .slide-menu-item.active i.fas.active,
102 | .slide-menu-wrapper .slide-menu-item-vertical.active i.fas.active,
103 | .slide-menu-wrapper .slide-menu-item.future i.far.future,
104 | .slide-menu-wrapper .slide-menu-item-vertical.future i.far.future,
105 | .slide-menu-wrapper .slide-menu-item.past svg.svg-inline--fa.past,
106 | .slide-menu-wrapper .slide-menu-item-vertical.past svg.svg-inline--fa.past,
107 | .slide-menu-wrapper .slide-menu-item.active svg.svg-inline--fa.active,
108 | .slide-menu-wrapper .slide-menu-item-vertical.active svg.svg-inline--fa.active,
109 | .slide-menu-wrapper .slide-menu-item.future svg.svg-inline--fa.future,
110 | .slide-menu-wrapper .slide-menu-item-vertical.future svg.svg-inline--fa.future {
111 | display: inline-block;
112 | }
113 |
114 | .slide-menu-wrapper .slide-menu-item.past i.fas.past,
115 | .slide-menu-wrapper .slide-menu-item-vertical.past i.fas.past,
116 | .slide-menu-wrapper .slide-menu-item.future i.far.future,
117 | .slide-menu-wrapper .slide-menu-item-vertical.future i.far.future,
118 | .slide-menu-wrapper .slide-menu-item.past svg.svg-inline--fa.past,
119 | .slide-menu-wrapper .slide-menu-item-vertical.past svg.svg-inline--fa.past,
120 | .slide-menu-wrapper .slide-menu-item.future svg.svg-inline--fa.future,
121 | .slide-menu-wrapper .slide-menu-item-vertical.future svg.svg-inline--fa.future {
122 | opacity: 0.4;
123 | }
124 |
125 | .slide-menu-wrapper .slide-menu-item.active i.fas.active,
126 | .slide-menu-wrapper .slide-menu-item-vertical.active i.fas.active,
127 | .slide-menu-wrapper .slide-menu-item.active svg.svg-inline--fa.active,
128 | .slide-menu-wrapper .slide-menu-item-vertical.active svg.svg-inline--fa.active {
129 | opacity: 0.8;
130 | }
131 |
132 | .slide-menu-wrapper .slide-menu--left {
133 | left: 0;
134 | -webkit-transform: translateX(-100%);
135 | -ms-transform: translateX(-100%);
136 | transform: translateX(-100%);
137 | }
138 |
139 | .slide-menu-wrapper .slide-menu--left.active {
140 | -webkit-transform: translateX(0);
141 | -ms-transform: translateX(0);
142 | transform: translateX(0);
143 | }
144 |
145 | .slide-menu-wrapper .slide-menu--right {
146 | right: 0;
147 | -webkit-transform: translateX(100%);
148 | -ms-transform: translateX(100%);
149 | transform: translateX(100%);
150 | }
151 |
152 | .slide-menu-wrapper .slide-menu--right.active {
153 | -webkit-transform: translateX(0);
154 | -ms-transform: translateX(0);
155 | transform: translateX(0);
156 | }
157 |
158 | .slide-menu-wrapper {
159 | transition: transform 0.3s;
160 | }
161 |
162 | /*
163 | * Toolbar
164 | */
165 | .slide-menu-wrapper .slide-menu-toolbar {
166 | height: 60px;
167 | width: 100%;
168 | font-size: 12px;
169 | display: table;
170 | table-layout: fixed; /* ensures equal width */
171 | margin: 0;
172 | padding: 0;
173 | border-bottom: solid 2px #666;
174 | }
175 |
176 | .slide-menu-wrapper .slide-menu-toolbar > li {
177 | display: table-cell;
178 | line-height: 150%;
179 | text-align: center;
180 | vertical-align: middle;
181 | cursor: pointer;
182 | color: #aaa;
183 | border-radius: 3px;
184 | }
185 |
186 | .slide-menu-wrapper .slide-menu-toolbar > li.toolbar-panel-button i,
187 | .slide-menu-wrapper
188 | .slide-menu-toolbar
189 | > li.toolbar-panel-button
190 | svg.svg-inline--fa {
191 | font-size: 1.7em;
192 | }
193 |
194 | .slide-menu-wrapper .slide-menu-toolbar > li.active-toolbar-button {
195 | color: white;
196 | text-shadow: 0 1px black;
197 | text-decoration: underline;
198 | }
199 |
200 | .slide-menu-toolbar > li.toolbar-panel-button:hover {
201 | color: white;
202 | }
203 |
204 | .slide-menu-toolbar
205 | > li.toolbar-panel-button:hover
206 | span.slide-menu-toolbar-label,
207 | .slide-menu-wrapper
208 | .slide-menu-toolbar
209 | > li.active-toolbar-button
210 | span.slide-menu-toolbar-label {
211 | visibility: visible;
212 | }
213 |
214 | /*
215 | * Panels
216 | */
217 | .slide-menu-wrapper .slide-menu-panel {
218 | position: absolute;
219 | width: 100%;
220 | visibility: hidden;
221 | height: calc(100% - 60px);
222 | overflow-x: hidden;
223 | overflow-y: auto;
224 | color: #aaa;
225 | }
226 |
227 | .slide-menu-wrapper .slide-menu-panel.active-menu-panel {
228 | visibility: visible;
229 | }
230 |
231 | .slide-menu-wrapper .slide-menu-panel h1,
232 | .slide-menu-wrapper .slide-menu-panel h2,
233 | .slide-menu-wrapper .slide-menu-panel h3,
234 | .slide-menu-wrapper .slide-menu-panel h4,
235 | .slide-menu-wrapper .slide-menu-panel h5,
236 | .slide-menu-wrapper .slide-menu-panel h6 {
237 | margin: 20px 0 10px 0;
238 | color: #fff;
239 | line-height: 1.2;
240 | letter-spacing: normal;
241 | text-shadow: none;
242 | }
243 |
244 | .slide-menu-wrapper .slide-menu-panel h1 {
245 | font-size: 1.6em;
246 | }
247 | .slide-menu-wrapper .slide-menu-panel h2 {
248 | font-size: 1.4em;
249 | }
250 | .slide-menu-wrapper .slide-menu-panel h3 {
251 | font-size: 1.3em;
252 | }
253 | .slide-menu-wrapper .slide-menu-panel h4 {
254 | font-size: 1.1em;
255 | }
256 | .slide-menu-wrapper .slide-menu-panel h5 {
257 | font-size: 1em;
258 | }
259 | .slide-menu-wrapper .slide-menu-panel h6 {
260 | font-size: 0.9em;
261 | }
262 |
263 | .slide-menu-wrapper .slide-menu-panel p {
264 | margin: 10px 0 5px 0;
265 | }
266 |
267 | .slide-menu-wrapper .slide-menu-panel a {
268 | color: #ccc;
269 | text-decoration: underline;
270 | }
271 |
272 | .slide-menu-wrapper .slide-menu-panel a:hover {
273 | color: white;
274 | }
275 |
276 | .slide-menu-wrapper .slide-menu-item a {
277 | text-decoration: none;
278 | }
279 |
280 | .slide-menu-wrapper .slide-menu-custom-panel {
281 | width: calc(100% - 20px);
282 | padding-left: 10px;
283 | padding-right: 10px;
284 | }
285 |
286 | .slide-menu-wrapper .slide-menu-custom-panel .slide-menu-items {
287 | width: calc(100% + 20px);
288 | margin-left: -10px;
289 | margin-right: 10px;
290 | }
291 |
292 | /*
293 | * Theme and Transitions buttons
294 | */
295 |
296 | .slide-menu-wrapper div[data-panel='Themes'] li,
297 | .slide-menu-wrapper div[data-panel='Transitions'] li {
298 | display: block;
299 | text-align: left;
300 | cursor: pointer;
301 | color: #848484;
302 | }
303 |
304 | /*
305 | * Menu controls
306 | */
307 | .reveal .slide-menu-button {
308 | position: fixed;
309 | left: 30px;
310 | bottom: 30px;
311 | z-index: 30;
312 | font-size: 24px;
313 | }
314 |
315 | /*
316 | * Menu overlay
317 | */
318 |
319 | .slide-menu-wrapper .slide-menu-overlay {
320 | position: fixed;
321 | z-index: 199;
322 | top: 0;
323 | left: 0;
324 | overflow: hidden;
325 | width: 0;
326 | height: 0;
327 | background-color: #000;
328 | opacity: 0;
329 | transition: opacity 0.3s, width 0s 0.3s, height 0s 0.3s;
330 | }
331 |
332 | .slide-menu-wrapper .slide-menu-overlay.active {
333 | width: 100%;
334 | height: 100%;
335 | opacity: 0.7;
336 | transition: opacity 0.3s;
337 | }
338 |
339 | /*
340 | * Hide menu for pdf printing
341 | */
342 | body.print-pdf .slide-menu-wrapper .slide-menu,
343 | body.print-pdf .reveal .slide-menu-button,
344 | body.print-pdf .slide-menu-wrapper .slide-menu-overlay {
345 | display: none;
346 | }
347 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/reveal-menu/plugin.yml:
--------------------------------------------------------------------------------
1 | name: RevealMenu
2 | script: [menu.js, quarto-menu.js]
3 | stylesheet: [menu.css, quarto-menu.css]
4 | config:
5 | menu:
6 | side: "left"
7 | useTextContentForMissingTitles: true
8 | markers: false
9 | loadIcons: false
10 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/reveal-menu/quarto-menu.css:
--------------------------------------------------------------------------------
1 | .slide-menu-wrapper .slide-tool-item {
2 | display: block;
3 | text-align: left;
4 | padding: 10px 18px;
5 | color: #aaa;
6 | cursor: pointer;
7 | border-top: solid 1px #555;
8 | }
9 |
10 | .slide-menu-wrapper .slide-tool-item a {
11 | text-decoration: none;
12 | }
13 |
14 | .slide-menu-wrapper .slide-tool-item kbd {
15 | font-family: monospace;
16 | margin-right: 10px;
17 | padding: 3px 8px;
18 | color: inherit;
19 | border: 1px solid;
20 | border-radius: 5px;
21 | border-color: #555;
22 | }
23 |
24 | .slide-menu-wrapper .slide-menu-toolbar > li.active-toolbar-button {
25 | text-decoration: none;
26 | }
27 |
28 | .reveal .slide-menu-button {
29 | left: 8px;
30 | bottom: 8px;
31 | }
32 |
33 | .reveal .slide-menu-button .fas::before,
34 | .reveal .slide-chalkboard-buttons .fas::before,
35 | .slide-menu-wrapper .slide-menu-toolbar .fas::before {
36 | display: inline-block;
37 | height: 2.2rem;
38 | width: 2.2rem;
39 | content: "";
40 | vertical-align: -0.125em;
41 | background-repeat: no-repeat;
42 | background-size: 2.2rem 2.2rem;
43 | }
44 |
45 | .reveal .slide-chalkboard-buttons .fas::before {
46 | height: 1.45rem;
47 | width: 1.45rem;
48 | background-size: 1.45rem 1.45rem;
49 | vertical-align: 0.1em;
50 | }
51 |
52 | .slide-menu-wrapper .slide-menu-toolbar .fas::before {
53 | height: 1.8rem;
54 | width: 1.8rem;
55 | background-size: 1.8rem 1.8rem;
56 | }
57 |
58 | .slide-menu-wrapper .slide-menu-toolbar .fa-images::before {
59 | background-image: url('data:image/svg+xml,');
60 | }
61 |
62 | .slide-menu-wrapper .slide-menu-toolbar .fa-gear::before {
63 | background-image: url('data:image/svg+xml,');
64 | }
65 |
66 | .slide-menu-wrapper .slide-menu-toolbar .fa-times::before {
67 | background-image: url('data:image/svg+xml,');
68 | }
69 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/reveal-menu/quarto-menu.js:
--------------------------------------------------------------------------------
1 | window.revealMenuToolHandler = function (handler) {
2 | return function (event) {
3 | event.preventDefault();
4 | handler();
5 | Reveal.getPlugin("menu").closeMenu();
6 | };
7 | };
8 |
9 | window.RevealMenuToolHandlers = {
10 | fullscreen: revealMenuToolHandler(function () {
11 | const element = document.documentElement;
12 | const requestMethod =
13 | element.requestFullscreen ||
14 | element.webkitRequestFullscreen ||
15 | element.webkitRequestFullScreen ||
16 | element.mozRequestFullScreen ||
17 | element.msRequestFullscreen;
18 | if (requestMethod) {
19 | requestMethod.apply(element);
20 | }
21 | }),
22 | speakerMode: revealMenuToolHandler(function () {
23 | Reveal.getPlugin("notes").open();
24 | }),
25 | keyboardHelp: revealMenuToolHandler(function () {
26 | Reveal.toggleHelp(true);
27 | }),
28 | overview: revealMenuToolHandler(function () {
29 | Reveal.toggleOverview(true);
30 | }),
31 | toggleChalkboard: revealMenuToolHandler(function () {
32 | RevealChalkboard.toggleChalkboard();
33 | }),
34 | toggleNotesCanvas: revealMenuToolHandler(function () {
35 | RevealChalkboard.toggleNotesCanvas();
36 | }),
37 | downloadDrawings: revealMenuToolHandler(function () {
38 | RevealChalkboard.download();
39 | }),
40 | };
41 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/search/plugin.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
3 | * by navigatating to that slide and highlighting it.
4 | *
5 | * @author Jon Snyder , February 2013
6 | */
7 |
8 | const Plugin = () => {
9 |
10 | // The reveal.js instance this plugin is attached to
11 | let deck;
12 |
13 | let searchElement;
14 | let searchButton;
15 | let searchInput;
16 |
17 | let matchedSlides;
18 | let currentMatchedIndex;
19 | let searchboxDirty;
20 | let hilitor;
21 |
22 | function render() {
23 |
24 | searchElement = document.createElement( 'div' );
25 | searchElement.classList.add( 'searchbox' );
26 | searchElement.style.position = 'absolute';
27 | searchElement.style.top = '10px';
28 | searchElement.style.right = '10px';
29 | searchElement.style.zIndex = 10;
30 |
31 | //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
32 | searchElement.innerHTML = `
33 | `;
34 |
35 | searchInput = searchElement.querySelector( '.searchinput' );
36 | searchInput.style.width = '240px';
37 | searchInput.style.fontSize = '14px';
38 | searchInput.style.padding = '4px 6px';
39 | searchInput.style.color = '#000';
40 | searchInput.style.background = '#fff';
41 | searchInput.style.borderRadius = '2px';
42 | searchInput.style.border = '0';
43 | searchInput.style.outline = '0';
44 | searchInput.style.boxShadow = '0 2px 18px rgba(0, 0, 0, 0.2)';
45 | searchInput.style['-webkit-appearance'] = 'none';
46 |
47 | deck.getRevealElement().appendChild( searchElement );
48 |
49 | // searchButton.addEventListener( 'click', function(event) {
50 | // doSearch();
51 | // }, false );
52 |
53 | searchInput.addEventListener( 'keyup', function( event ) {
54 | switch (event.keyCode) {
55 | case 13:
56 | event.preventDefault();
57 | doSearch();
58 | searchboxDirty = false;
59 | break;
60 | default:
61 | searchboxDirty = true;
62 | }
63 | }, false );
64 |
65 | closeSearch();
66 |
67 | }
68 |
69 | function openSearch() {
70 | if( !searchElement ) render();
71 |
72 | searchElement.style.display = 'inline';
73 | searchInput.focus();
74 | searchInput.select();
75 | }
76 |
77 | function closeSearch() {
78 | if( !searchElement ) render();
79 |
80 | searchElement.style.display = 'none';
81 | if(hilitor) hilitor.remove();
82 | }
83 |
84 | function toggleSearch() {
85 | if( !searchElement ) render();
86 |
87 | if (searchElement.style.display !== 'inline') {
88 | openSearch();
89 | }
90 | else {
91 | closeSearch();
92 | }
93 | }
94 |
95 | function doSearch() {
96 | //if there's been a change in the search term, perform a new search:
97 | if (searchboxDirty) {
98 | var searchstring = searchInput.value;
99 |
100 | if (searchstring === '') {
101 | if(hilitor) hilitor.remove();
102 | matchedSlides = null;
103 | }
104 | else {
105 | //find the keyword amongst the slides
106 | hilitor = new Hilitor("slidecontent");
107 | matchedSlides = hilitor.apply(searchstring);
108 | currentMatchedIndex = 0;
109 | }
110 | }
111 |
112 | if (matchedSlides) {
113 | //navigate to the next slide that has the keyword, wrapping to the first if necessary
114 | if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
115 | currentMatchedIndex = 0;
116 | }
117 | if (matchedSlides.length > currentMatchedIndex) {
118 | deck.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
119 | currentMatchedIndex++;
120 | }
121 | }
122 | }
123 |
124 | // Original JavaScript code by Chirp Internet: www.chirp.com.au
125 | // Please acknowledge use of this code by including this header.
126 | // 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
127 | function Hilitor(id, tag) {
128 |
129 | var targetNode = document.getElementById(id) || document.body;
130 | var hiliteTag = tag || "EM";
131 | var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$");
132 | var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
133 | var wordColor = [];
134 | var colorIdx = 0;
135 | var matchRegex = "";
136 | var matchingSlides = [];
137 |
138 | this.setRegex = function(input)
139 | {
140 | input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
141 | matchRegex = new RegExp("(" + input + ")","i");
142 | }
143 |
144 | this.getRegex = function()
145 | {
146 | return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
147 | }
148 |
149 | // recursively apply word highlighting
150 | this.hiliteWords = function(node)
151 | {
152 | if(node == undefined || !node) return;
153 | if(!matchRegex) return;
154 | if(skipTags.test(node.nodeName)) return;
155 |
156 | if(node.hasChildNodes()) {
157 | for(var i=0; i < node.childNodes.length; i++)
158 | this.hiliteWords(node.childNodes[i]);
159 | }
160 | if(node.nodeType == 3) { // NODE_TEXT
161 | var nv, regs;
162 | if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
163 | //find the slide's section element and save it in our list of matching slides
164 | var secnode = node;
165 | while (secnode != null && secnode.nodeName != 'SECTION') {
166 | secnode = secnode.parentNode;
167 | }
168 |
169 | var slideIndex = deck.getIndices(secnode);
170 | var slidelen = matchingSlides.length;
171 | var alreadyAdded = false;
172 | for (var i=0; i < slidelen; i++) {
173 | if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
174 | alreadyAdded = true;
175 | }
176 | }
177 | if (! alreadyAdded) {
178 | matchingSlides.push(slideIndex);
179 | }
180 |
181 | if(!wordColor[regs[0].toLowerCase()]) {
182 | wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
183 | }
184 |
185 | var match = document.createElement(hiliteTag);
186 | match.appendChild(document.createTextNode(regs[0]));
187 | match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
188 | match.style.fontStyle = "inherit";
189 | match.style.color = "#000";
190 |
191 | var after = node.splitText(regs.index);
192 | after.nodeValue = after.nodeValue.substring(regs[0].length);
193 | node.parentNode.insertBefore(match, after);
194 | }
195 | }
196 | };
197 |
198 | // remove highlighting
199 | this.remove = function()
200 | {
201 | var arr = document.getElementsByTagName(hiliteTag);
202 | var el;
203 | while(arr.length && (el = arr[0])) {
204 | el.parentNode.replaceChild(el.firstChild, el);
205 | }
206 | };
207 |
208 | // start highlighting at target node
209 | this.apply = function(input)
210 | {
211 | if(input == undefined || !input) return;
212 | this.remove();
213 | this.setRegex(input);
214 | this.hiliteWords(targetNode);
215 | return matchingSlides;
216 | };
217 |
218 | }
219 |
220 | return {
221 |
222 | id: 'search',
223 |
224 | init: reveal => {
225 |
226 | deck = reveal;
227 | deck.registerKeyboardShortcut( 'CTRL + Shift + F', 'Search' );
228 |
229 | document.addEventListener( 'keydown', function( event ) {
230 | if( event.key == "F" && (event.ctrlKey || event.metaKey) ) { //Control+Shift+f
231 | event.preventDefault();
232 | toggleSearch();
233 | }
234 | }, false );
235 |
236 | },
237 |
238 | open: openSearch
239 |
240 | }
241 | };
242 |
243 | export default Plugin;
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/zoom/plugin.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * reveal.js Zoom plugin
3 | */
4 | const Plugin = {
5 |
6 | id: 'zoom',
7 |
8 | init: function( reveal ) {
9 |
10 | reveal.getRevealElement().addEventListener( 'mousedown', function( event ) {
11 | var defaultModifier = /Linux/.test( window.navigator.platform ) ? 'ctrl' : 'alt';
12 |
13 | var modifier = ( reveal.getConfig().zoomKey ? reveal.getConfig().zoomKey : defaultModifier ) + 'Key';
14 | var zoomLevel = ( reveal.getConfig().zoomLevel ? reveal.getConfig().zoomLevel : 2 );
15 |
16 | if( event[ modifier ] && !reveal.isOverview() ) {
17 | event.preventDefault();
18 |
19 | zoom.to({
20 | x: event.clientX,
21 | y: event.clientY,
22 | scale: zoomLevel,
23 | pan: false
24 | });
25 | }
26 | } );
27 |
28 | }
29 |
30 | };
31 |
32 | export default () => Plugin;
33 |
34 | /*!
35 | * zoom.js 0.3 (modified for use with reveal.js)
36 | * http://lab.hakim.se/zoom-js
37 | * MIT licensed
38 | *
39 | * Copyright (C) 2011-2014 Hakim El Hattab, http://hakim.se
40 | */
41 | var zoom = (function(){
42 |
43 | // The current zoom level (scale)
44 | var level = 1;
45 |
46 | // The current mouse position, used for panning
47 | var mouseX = 0,
48 | mouseY = 0;
49 |
50 | // Timeout before pan is activated
51 | var panEngageTimeout = -1,
52 | panUpdateInterval = -1;
53 |
54 | // Check for transform support so that we can fallback otherwise
55 | var supportsTransforms = 'WebkitTransform' in document.body.style ||
56 | 'MozTransform' in document.body.style ||
57 | 'msTransform' in document.body.style ||
58 | 'OTransform' in document.body.style ||
59 | 'transform' in document.body.style;
60 |
61 | if( supportsTransforms ) {
62 | // The easing that will be applied when we zoom in/out
63 | document.body.style.transition = 'transform 0.8s ease';
64 | document.body.style.OTransition = '-o-transform 0.8s ease';
65 | document.body.style.msTransition = '-ms-transform 0.8s ease';
66 | document.body.style.MozTransition = '-moz-transform 0.8s ease';
67 | document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
68 | }
69 |
70 | // Zoom out if the user hits escape
71 | document.addEventListener( 'keyup', function( event ) {
72 | if( level !== 1 && event.keyCode === 27 ) {
73 | zoom.out();
74 | }
75 | } );
76 |
77 | // Monitor mouse movement for panning
78 | document.addEventListener( 'mousemove', function( event ) {
79 | if( level !== 1 ) {
80 | mouseX = event.clientX;
81 | mouseY = event.clientY;
82 | }
83 | } );
84 |
85 | /**
86 | * Applies the CSS required to zoom in, prefers the use of CSS3
87 | * transforms but falls back on zoom for IE.
88 | *
89 | * @param {Object} rect
90 | * @param {Number} scale
91 | */
92 | function magnify( rect, scale ) {
93 |
94 | var scrollOffset = getScrollOffset();
95 |
96 | // Ensure a width/height is set
97 | rect.width = rect.width || 1;
98 | rect.height = rect.height || 1;
99 |
100 | // Center the rect within the zoomed viewport
101 | rect.x -= ( window.innerWidth - ( rect.width * scale ) ) / 2;
102 | rect.y -= ( window.innerHeight - ( rect.height * scale ) ) / 2;
103 |
104 | if( supportsTransforms ) {
105 | // Reset
106 | if( scale === 1 ) {
107 | document.body.style.transform = '';
108 | document.body.style.OTransform = '';
109 | document.body.style.msTransform = '';
110 | document.body.style.MozTransform = '';
111 | document.body.style.WebkitTransform = '';
112 | }
113 | // Scale
114 | else {
115 | var origin = scrollOffset.x +'px '+ scrollOffset.y +'px',
116 | transform = 'translate('+ -rect.x +'px,'+ -rect.y +'px) scale('+ scale +')';
117 |
118 | document.body.style.transformOrigin = origin;
119 | document.body.style.OTransformOrigin = origin;
120 | document.body.style.msTransformOrigin = origin;
121 | document.body.style.MozTransformOrigin = origin;
122 | document.body.style.WebkitTransformOrigin = origin;
123 |
124 | document.body.style.transform = transform;
125 | document.body.style.OTransform = transform;
126 | document.body.style.msTransform = transform;
127 | document.body.style.MozTransform = transform;
128 | document.body.style.WebkitTransform = transform;
129 | }
130 | }
131 | else {
132 | // Reset
133 | if( scale === 1 ) {
134 | document.body.style.position = '';
135 | document.body.style.left = '';
136 | document.body.style.top = '';
137 | document.body.style.width = '';
138 | document.body.style.height = '';
139 | document.body.style.zoom = '';
140 | }
141 | // Scale
142 | else {
143 | document.body.style.position = 'relative';
144 | document.body.style.left = ( - ( scrollOffset.x + rect.x ) / scale ) + 'px';
145 | document.body.style.top = ( - ( scrollOffset.y + rect.y ) / scale ) + 'px';
146 | document.body.style.width = ( scale * 100 ) + '%';
147 | document.body.style.height = ( scale * 100 ) + '%';
148 | document.body.style.zoom = scale;
149 | }
150 | }
151 |
152 | level = scale;
153 |
154 | if( document.documentElement.classList ) {
155 | if( level !== 1 ) {
156 | document.documentElement.classList.add( 'zoomed' );
157 | }
158 | else {
159 | document.documentElement.classList.remove( 'zoomed' );
160 | }
161 | }
162 | }
163 |
164 | /**
165 | * Pan the document when the mosue cursor approaches the edges
166 | * of the window.
167 | */
168 | function pan() {
169 | var range = 0.12,
170 | rangeX = window.innerWidth * range,
171 | rangeY = window.innerHeight * range,
172 | scrollOffset = getScrollOffset();
173 |
174 | // Up
175 | if( mouseY < rangeY ) {
176 | window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
177 | }
178 | // Down
179 | else if( mouseY > window.innerHeight - rangeY ) {
180 | window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
181 | }
182 |
183 | // Left
184 | if( mouseX < rangeX ) {
185 | window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
186 | }
187 | // Right
188 | else if( mouseX > window.innerWidth - rangeX ) {
189 | window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
190 | }
191 | }
192 |
193 | function getScrollOffset() {
194 | return {
195 | x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
196 | y: window.scrollY !== undefined ? window.scrollY : window.pageYOffset
197 | }
198 | }
199 |
200 | return {
201 | /**
202 | * Zooms in on either a rectangle or HTML element.
203 | *
204 | * @param {Object} options
205 | * - element: HTML element to zoom in on
206 | * OR
207 | * - x/y: coordinates in non-transformed space to zoom in on
208 | * - width/height: the portion of the screen to zoom in on
209 | * - scale: can be used instead of width/height to explicitly set scale
210 | */
211 | to: function( options ) {
212 |
213 | // Due to an implementation limitation we can't zoom in
214 | // to another element without zooming out first
215 | if( level !== 1 ) {
216 | zoom.out();
217 | }
218 | else {
219 | options.x = options.x || 0;
220 | options.y = options.y || 0;
221 |
222 | // If an element is set, that takes precedence
223 | if( !!options.element ) {
224 | // Space around the zoomed in element to leave on screen
225 | var padding = 20;
226 | var bounds = options.element.getBoundingClientRect();
227 |
228 | options.x = bounds.left - padding;
229 | options.y = bounds.top - padding;
230 | options.width = bounds.width + ( padding * 2 );
231 | options.height = bounds.height + ( padding * 2 );
232 | }
233 |
234 | // If width/height values are set, calculate scale from those values
235 | if( options.width !== undefined && options.height !== undefined ) {
236 | options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
237 | }
238 |
239 | if( options.scale > 1 ) {
240 | options.x *= options.scale;
241 | options.y *= options.scale;
242 |
243 | magnify( options, options.scale );
244 |
245 | if( options.pan !== false ) {
246 |
247 | // Wait with engaging panning as it may conflict with the
248 | // zoom transition
249 | panEngageTimeout = setTimeout( function() {
250 | panUpdateInterval = setInterval( pan, 1000 / 60 );
251 | }, 800 );
252 |
253 | }
254 | }
255 | }
256 | },
257 |
258 | /**
259 | * Resets the document zoom state to its default.
260 | */
261 | out: function() {
262 | clearTimeout( panEngageTimeout );
263 | clearInterval( panUpdateInterval );
264 |
265 | magnify( { x: 0, y: 0 }, 1 );
266 |
267 | level = 1;
268 | },
269 |
270 | // Alias
271 | magnify: function( options ) { this.to( options ) },
272 | reset: function() { this.out() },
273 |
274 | zoomLevel: function() {
275 | return level;
276 | }
277 | }
278 |
279 | })();
280 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/zoom/zoom.esm.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * reveal.js Zoom plugin
3 | */
4 | var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))}},t=function(){var e=1,o=0,n=0,i=-1,d=-1,s="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style;function r(t,o){var n=y();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,s)if(1===o)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=y();nwindow.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),owindow.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function y(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(document.body.style.transition="transform 0.8s ease",document.body.style.OTransition="-o-transform 0.8s ease",document.body.style.msTransition="-ms-transform 0.8s ease",document.body.style.MozTransition="-moz-transform 0.8s ease",document.body.style.WebkitTransition="-webkit-transform 0.8s ease"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,r(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();export default function(){return e}
5 |
--------------------------------------------------------------------------------
/docs/site_libs/revealjs/plugin/zoom/zoom.js:
--------------------------------------------------------------------------------
1 | !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealZoom=o()}(this,(function(){"use strict";
2 | /*!
3 | * reveal.js Zoom plugin
4 | */var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(t){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;t[i]&&!e.isOverview()&&(t.preventDefault(),o.to({x:t.clientX,y:t.clientY,scale:d,pan:!1}))}))}},o=function(){var e=1,t=0,n=0,i=-1,d=-1,s="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style;function r(o,t){var n=l();if(o.width=o.width||1,o.height=o.height||1,o.x-=(window.innerWidth-o.width*t)/2,o.y-=(window.innerHeight-o.height*t)/2,s)if(1===t)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-o.x+"px,"+-o.y+"px) scale("+t+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===t?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+o.x)/t+"px",document.body.style.top=-(n.y+o.y)/t+"px",document.body.style.width=100*t+"%",document.body.style.height=100*t+"%",document.body.style.zoom=t);e=t,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var o=.12*window.innerWidth,i=.12*window.innerHeight,d=l();nwindow.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),twindow.innerWidth-o&&window.scroll(d.x+(1-(window.innerWidth-t)/o)*(14/e),d.y)}function l(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(document.body.style.transition="transform 0.8s ease",document.body.style.OTransition="-o-transform 0.8s ease",document.body.style.msTransition="-ms-transform 0.8s ease",document.body.style.MozTransition="-moz-transform 0.8s ease",document.body.style.WebkitTransition="-webkit-transform 0.8s ease"),document.addEventListener("keyup",(function(t){1!==e&&27===t.keyCode&&o.out()})),document.addEventListener("mousemove",(function(o){1!==e&&(t=o.clientX,n=o.clientY)})),{to:function(t){if(1!==e)o.out();else{if(t.x=t.x||0,t.y=t.y||0,t.element){var n=t.element.getBoundingClientRect();t.x=n.left-20,t.y=n.top-20,t.width=n.width+40,t.height=n.height+40}void 0!==t.width&&void 0!==t.height&&(t.scale=Math.max(Math.min(window.innerWidth/t.width,window.innerHeight/t.height),1)),t.scale>1&&(t.x*=t.scale,t.y*=t.scale,r(t,t.scale),!1!==t.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();return function(){return e}}));
5 |
--------------------------------------------------------------------------------
/page-layout/README.md:
--------------------------------------------------------------------------------
1 | ## Page layout example
2 |
3 |
--------------------------------------------------------------------------------
/page-layout/requirements.txt:
--------------------------------------------------------------------------------
1 | jupyter
2 |
--------------------------------------------------------------------------------
/page-layout/skeleton.bib:
--------------------------------------------------------------------------------
1 | @Manual{R-base,
2 | title = {R: A Language and Environment for Statistical Computing},
3 | author = {{R Core Team}},
4 | organization = {R Foundation for Statistical Computing},
5 | address = {Vienna, Austria},
6 | year = {2021},
7 | url = {https://www.R-project.org/},
8 | }
9 |
10 | @Manual{R-rmarkdown,
11 | title = {rmarkdown: Dynamic Documents for R},
12 | author = {JJ Allaire and Yihui Xie and Jonathan McPherson and Javier Luraschi and Kevin Ushey and Aron Atkins and Hadley Wickham and Joe Cheng and Winston Chang and Richard Iannone},
13 | year = {2021},
14 | note = {R package version 2.11},
15 | url = {https://CRAN.R-project.org/package=rmarkdown},
16 | }
17 |
18 | @Book{rmarkdown2018,
19 | title = {R Markdown: The Definitive Guide},
20 | author = {Yihui Xie and J.J. Allaire and Garrett Grolemund},
21 | publisher = {Chapman and Hall/CRC},
22 | address = {Boca Raton, Florida},
23 | year = {2018},
24 | note = {ISBN 9781138359338},
25 | url = {https://bookdown.org/yihui/rmarkdown},
26 | }
27 |
28 | @Book{rmarkdown2020,
29 | title = {R Markdown Cookbook},
30 | author = {Yihui Xie and Christophe Dervieux and Emily Riederer},
31 | publisher = {Chapman and Hall/CRC},
32 | address = {Boca Raton, Florida},
33 | year = {2020},
34 | note = {ISBN 9780367563837},
35 | url = {https://bookdown.org/yihui/rmarkdown-cookbook},
36 | }
37 |
38 |
39 | @inbook{xie2018,
40 | title = {Tufte Handouts},
41 | author = {Xie, Yihui and Allaire, J. J. and Grolemund, Garrett},
42 | year = {2018},
43 | month = {07},
44 | date = {2018-07-27},
45 | publisher = {Chapman and Hall/CRC},
46 | booktitle = {R Markdown: The Definitive Guide},
47 | pages = {137--146},
48 | doi = {10.1201/9781138359444-6},
49 | url = {http://dx.doi.org/10.1201/9781138359444-6}
50 | }
51 |
--------------------------------------------------------------------------------
/page-layout/tufte.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/page-layout/tufte.pdf
--------------------------------------------------------------------------------
/page-layout/tufte.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "A Quarto Page Layout Example"
3 | subtitle: "Inspired by Tufte Handout, Using Quarto"
4 | date: "`r Sys.Date()`"
5 | format:
6 | pdf: default
7 | html:
8 | self-contained: true
9 | grid:
10 | margin-width: 350px
11 | execute:
12 | echo: fenced
13 | reference-location: margin
14 | citation-location: margin
15 | bibliography: skeleton.bib
16 | ---
17 |
18 | # Introduction
19 |
20 | This document demonstrates the use of a number of advanced page layout features to produce an attractive and usable document inspired by the Tufte handout style and the use of Tufte's styles in RMarkdown documents [@xie2018]. The Tufte handout style is a style that Edward Tufte uses in his books and handouts. Tufte's style is known for its extensive use of sidenotes, tight integration of graphics with text, and well-set typography. Quarto[^1] supports most of the layout techniques that are used in the Tufte handout style for both HTML and LaTeX/PDF output.
21 |
22 | [^1]: To learn more, you can read more about [Quarto](https://www.quarto.org) or visit [Quarto's Github repository](https://www.github.com/quarto-dev/quarto-cli).
23 |
24 | ``` yaml
25 | ---
26 | title: "An Example Using the Tufte Style"
27 | author: "John Smith"
28 | format:
29 | html:
30 | grid:
31 | margin-width: 350px # <1>
32 | pdf: default
33 | reference-location: margin # <2>
34 | citation-location: margin # <2>
35 | ---
36 | ```
37 |
38 | 1. Increases the width of the margin to make more room for sidenotes and margin figures (HTML only).
39 | 2. Places footnotes and cited sources in the margin. Other layout options (for example placing a figure in the margin) will be set per element in examples below.
40 |
41 | These layout features are designed with two important goals in mind:
42 |
43 | 1. To produce both PDF and HTML output with similar styles from the same Quarto document;
44 | 2. To provide simple syntax to write elements of the Tufte style such as side notes and margin figures. If you'd like a figure placed in the margin, just set the option `fig-column: margin` for your code chunk, and we will take care of the details for you[^2].
45 |
46 | [^2]: You never need to think about `\begin{marginfigure}` or ``; the LaTeX and HTML code under the hood may be complicated, but you never need to learn or write such code.
47 |
48 | If you have any feature requests or find bugs in these capabilities, please do not hesitate to file them to .
49 |
50 | # Figures
51 |
52 | ## Margin Figures
53 |
54 | Images and graphics play an integral role in Tufte's work. To place figures in the margin you can use the **Quarto** chunk option `column: margin`. For example:
55 |
56 | ```{r}
57 | #| label: fig-margin
58 | #| fig-cap: "MPG vs horsepower, colored by transmission."
59 | #| column: margin
60 | #| message: false
61 | library(ggplot2)
62 | mtcars2 <- mtcars
63 | mtcars2$am <- factor(
64 | mtcars$am, labels = c('automatic', 'manual')
65 | )
66 | ggplot(mtcars2, aes(hp, mpg, color = am)) +
67 | geom_point() + geom_smooth() +
68 | theme(legend.position = 'bottom')
69 | ```
70 |
71 | Note the use of the `fig-cap` chunk option to provide a figure caption. You can adjust the proportions of figures using the `fig-width` and `fig-height` chunk options. These are specified in inches, and will be automatically scaled down to fit within the handout margin.
72 |
73 | ## Arbitrary Margin Content
74 |
75 | You can include anything in the margin by places the class `.column-margin` on the element. See an example on the right about the first fundamental theorem of calculus.
76 |
77 | ::: column-margin
78 | We know from *the first fundamental theorem of calculus* that for $x$ in $[a, b]$:
79 |
80 | $$\frac{d}{dx}\left( \int_{a}^{x} f(u)\,du\right)=f(x).$$
81 | :::
82 |
83 | ## Full Width Figures
84 |
85 | You can arrange for figures to span across the entire page by using the chunk option `fig-column: page-right`.
86 |
87 | ```{r}
88 | #| label: fig-fullwidth
89 | #| fig-cap: "A full width figure."
90 | #| fig-width: 11
91 | #| fig-height: 3
92 | #| fig-column: page-right
93 | #| warning: false
94 | ggplot(diamonds, aes(carat, price)) + geom_smooth() +
95 | facet_grid(~ cut)
96 | ```
97 |
98 | Other chunk options related to figures can still be used, such as `fig-width`, `fig-cap`, and so on. For full width figures, usually `fig-width` is large and `fig-height` is small. In the above example, the plot size is $11 \times 3$.
99 |
100 | ## Arbitrary Full Width Content
101 |
102 | Any content can span to the full width of the page, simply place the element in a `div` and add the class `column-page-right`. For example, the following code will display its contents as full width.
103 |
104 | ``` md
105 | ::: {.fullwidth}
106 | Any _full width_ content here.
107 | :::
108 | ```
109 |
110 | Below is an example:
111 |
112 | ::: column-page-right
113 | *R is free software and comes with ABSOLUTELY NO WARRANTY.* You are welcome to redistribute it under the terms of the GNU General Public License versions 2 or 3. For more information about these matters see .
114 | :::
115 |
116 | ## Main Column Figures
117 |
118 | Besides margin and full width figures, you can of course also include figures constrained to the main column. This is the default type of figures in the LaTeX/HTML output.
119 |
120 | ```{r}
121 | #| label: fig-main
122 | #| fig-cap: "A figure in the main column."
123 | ggplot(diamonds, aes(cut, price)) + geom_boxplot()
124 | ```
125 |
126 | ## Margin Captions
127 |
128 | When you include a figure constrained to the main column, you can choose to place the figure's caption in the margin by using the `cap-location` chunk option. For example:
129 |
130 | ```{r}
131 | #| label: fig-main-margin-cap
132 | #| fig-cap: "A figure with a longer caption. The figure appears in the main column, but the caption is placed in the margin. Captions can even contain elements like a citation such as @xie2018."
133 | #| cap-location: margin
134 | ggplot(diamonds, aes(cut, price)) + geom_boxplot()
135 | ```
136 |
137 | # Sidenotes
138 |
139 | One of the most prominent and distinctive features of this style is the extensive use of sidenotes. There is a wide margin to provide ample room for sidenotes and small figures. Any use of a footnote will automatically be converted to a sidenote.
140 |
141 | [This is a span that has the class `column-margin` which places it in the margin without the sidenote mark.]{.column-margin} If you'd like to place ancillary information in the margin without the sidenote mark (the superscript number), you can use apply the `column-margin` class to the element.
142 |
143 | # References
144 |
145 | References can be displayed as margin notes for HTML output. For example, we can cite R here [@R-base].
146 |
147 | ::: {.callout-note appearance="simple"}
148 | This feature depends upon `link-citations` to locate and place references in the margin. This is enabled by default, but if you disable `link-citations` then references in the HTML output will be placed at the end of the output document as they normally are.
149 | :::
150 |
151 | # Tables
152 |
153 | You can use the `kable()` function from the **knitr** package to format tables that integrate well with the rest of the Tufte handout style. The table captions are placed in the margin like figures in the HTML output.
154 |
155 | ```{r}
156 | #| tbl-cap-location: margin
157 | knitr::kable(
158 | mtcars[1:6, 1:6], caption = 'A subset of mtcars.'
159 | )
160 | ```
161 |
162 | # Responsiveness
163 |
164 | The HTML page layout is responsive- as the page width shrinks, elements will automatically adjust their position. Elements that appear in the margins will move inline with the content and elements that span the body and margin will automatically span only the body.
165 |
166 | # More Examples
167 |
168 | The rest of this document consists of a few test cases to make sure everything still works well in slightly more complicated scenarios. First we generate two plots in one figure environment with the chunk option `fig-show: hold`:
169 |
170 | ```{r}
171 | #| label: fig-two-together
172 | #| fig-cap: "Two plots in one figure environment."
173 | #| fig-show: hold
174 | #| warning: false
175 | #| cap-location: margin
176 | p <- ggplot(mtcars2, aes(hp, mpg, color = am)) +
177 | geom_point()
178 | p
179 | p + geom_smooth()
180 | ```
181 |
182 | Then two plots in separate figure environments (the code is identical to the previous code chunk, but the chunk option is the default `fig-show: asis` now):
183 |
184 | ```{r fig-two-separate, ref.label='fig-two-together', fig.cap=sprintf("Two plots in separate figure environments (the %s plot).", c("first", "second")), message=FALSE}
185 | #| cap-location: margin
186 | ```
187 |
188 | You may have noticed that the two figures have different captions, and that is because we used a character vector of length 2 for the chunk option `fig.cap` (something like `fig.cap = c('first plot', 'second plot')`).
189 |
190 | ::: {.callout-tip}
191 | ## Using R within Chunk Options
192 | If you wish to use raw R expressions as part of the chunk options (like above), then you need to define those in the `tag=value` format within the curly brackets `{r label, tag=value}` instead of the `tag: value` YAML syntax on a new line starting with the hashpipe `#|`. The former approach is documented on [knitr's website](https://yihui.org/knitr/options/) while the latter is explained in [Quarto's documentation](https://quarto.org/docs/reference/cells/cells-knitr.html).
193 | :::
194 |
195 | Next we show multiple plots in margin figures. Similarly, two plots in the same figure environment in the margin:
196 |
197 | ```{r}
198 | #| label: fig-margin-together
199 | #| fig-cap: "Two plots in one figure environment in the margin."
200 | #| fig-width: 3.5
201 | #| fig-height: 2
202 | #| fig-show: hold
203 | #| column: margin
204 | #| warning: false
205 | #| echo: false
206 | p
207 | p + geom_smooth(method = 'lm')
208 | ```
209 |
210 | Then two plots from the same code chunk placed in different figure environments:
211 |
212 | ```{r}
213 | #| echo: false
214 | knitr::kable(head(iris[,c(1,2,3,4)], 13))
215 | ```
216 |
217 | ```{r}
218 | #| label: fig-margin-separate-a
219 | #| fig-cap: "Two plots in separate figure environments in the margin"
220 | #| fig-width: 3.5
221 | #| fig-height: 2
222 | #| column: margin
223 | #| warning: false
224 | #| echo: false
225 | p
226 | p + geom_smooth(method = 'lm')
227 | ```
228 |
229 | ```{r}
230 | #| echo: false
231 | knitr::kable(head(iris[,c(1,2,3,4)], 11))
232 | ```
233 |
234 | We blended some tables in the above code chunk only as *placeholders* to make sure there is enough vertical space among the margin figures, otherwise they will be stacked tightly together. For a practical document, you should not insert too many margin figures consecutively and make the margin crowded.
235 |
236 | You do not have to assign captions to figures. We show three figures with no captions below in the margin, in the main column, and in full width, respectively.
237 |
238 | ```{r}
239 | #| fig-width: 3.5
240 | #| fig-height: 2
241 | #| column: margin
242 | # a boxplot of weight vs transmission; this figure
243 | # will be placed in the margin
244 | ggplot(mtcars2, aes(am, wt)) + geom_boxplot() +
245 | coord_flip()
246 | ```
247 |
248 | ```{r}
249 | #| warning: false
250 | # a figure in the main column
251 | p <- ggplot(mtcars, aes(wt, hp)) + geom_point()
252 | p
253 | ```
254 |
255 | ```{r}
256 | #| fig-width: 11
257 | #| fig-height: 4
258 | #| column: page-right
259 | #| warning: false
260 | # a fullwidth figure
261 | p + geom_smooth(method = 'lm') + facet_grid(~ gear)
262 | ```
263 |
264 | # Some Notes on Page Layout
265 |
266 | To see the Quarto markdown source of this example document, you may follow [this link to Github](https://raw.githubusercontent.com/quarto-dev/quarto-gallery/main/page-layout/tufte.qmd).
267 |
--------------------------------------------------------------------------------
/presentations/beamer/beamer.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/beamer/beamer.pdf
--------------------------------------------------------------------------------
/presentations/beamer/beamer.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: Pop Songs and Political Science
3 | author: Steven V. Miller
4 | institute: Department of Political Science
5 | format:
6 | beamer:
7 | navigation: horizontal
8 | header-includes: |
9 | \titlegraphic{\includegraphics[width=0.4\paperwidth]{clemson.png}}
10 | ---
11 |
12 | ## Sheena Easton and Game Theory
13 |
14 | Sheena Easton describes the following scenario for her baby:
15 |
16 | 1. Takes the morning train
17 | 2. Works from nine 'til five
18 | 3. Takes another train home again
19 | 4. Finds Sheena Easton waiting for him
20 |
21 | ## A Total Conflict Game Between Sheena Easton and Her Baby
22 |
23 | | | Stays Home | Goes to Work |
24 | |------------------------|---------------|---------------|
25 | | **Baby Home Again** | -100, **100** | **100**, 0 |
26 | | **Baby Stays at Work** | **50**, 0 | -100, **100** |
27 |
28 | Sheena Easton and her baby are playing a **zero-sum (total conflict) game**.
29 |
30 | - Akin to Holmes-Moriarty game (see: von Neumann and Morgenstern)
31 | - Solution: **mixed strategy**
32 |
33 | ## Rick Astley's Re-election Platform
34 |
35 | Rick Astley's campaign promises:
36 |
37 | - Never gonna give you up.
38 | - Never gonna let you down.
39 | - Never gonna run around and desert you.
40 | - Never gonna make you cry.
41 | - Never gonna say goodbye.
42 | - Never gonna tell a lie and hurt you.
43 |
44 | Are these promises (if credible) sufficient to secure re-election?
45 |
46 | ## Rick Astley and Median Voter Theorem
47 |
48 | Whereas these pledges conform to the preferences of the **median voter**, we expect Congressman Astley to secure re-election.
49 |
50 | ## Caribbean Queen and Operation Urgent Fury
51 |
52 | Billy Ocean released "Caribbean Queen" in 1984.
53 |
54 | - Emphasized sharing the same dream
55 | - Hearts beating as one
56 |
57 | "Caribbean Queen" is about the poor execution of Operation Urgent Fury.
58 |
59 | - Echoed JCS chairman David Jones' frustrations with military establishment.
60 |
61 | Billy Ocean is advocating for what became the Goldwater-Nichols Act.
62 |
63 | - Wanted to take advantage of **economies of scale**, resolve **coordination problems** in U.S. military.
64 |
65 | ## The Good Day Hypothesis
66 |
67 | We know the following about Ice Cube's day.
68 |
69 | 1. The Lakers beat the Supersonics.
70 | 2. No helicopter looked for a murder.
71 | 3. Consumed Fatburger at 2 a.m.
72 | 4. Goodyear blimp: "Ice Cube's a pimp."
73 |
74 | ## The Good Day Hypothesis
75 |
76 | This leads to two different hypotheses:
77 |
78 | - $H_0$: Ice Cube's day is statistically indistinguishable from a typical day.
79 | - $H_1$: Ice Cube is having a good (i.e. greater than average) day.
80 |
81 | These hypotheses are tested using archival data of Ice Cube's life.
82 |
--------------------------------------------------------------------------------
/presentations/beamer/clemson.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/beamer/clemson.png
--------------------------------------------------------------------------------
/presentations/powerpoint/powerpoint.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/powerpoint/powerpoint.pptx
--------------------------------------------------------------------------------
/presentations/powerpoint/powerpoint.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Best Practices for Administering RStudio in Production"
3 | author: "Nathan Stephens"
4 | format:
5 | pptx:
6 | reference-doc: template.pptx
7 | ---
8 |
9 | # Overview
10 |
11 | ## Solutions engineering
12 |
13 | ### We help you integrate RStudio products into your systems
14 |
15 | ### Our team
16 |
17 | ### Where do we hang out?
18 |
19 | * [Community.rstudio.com](http://community.rstudio.com)
20 | * [Github.com/sol-eng](http://)
21 | * [Solutions.rstudio.com](http://solutions.rstudio.com)
22 | * [Support.rstudio.com](http://support.rstudio.com)
23 | * [Docs.rstudio.com](docs.rstudio.com)
24 |
25 | ## Who is this webinar for?
26 |
27 | ### R Admin -- data scientists who want to do more
28 |
29 | ### R Evangelists
30 |
31 | ### IT/Ops
32 |
33 | ### Anyone who wants to try RStudio professional products
34 |
35 | ## RStudio
36 |
37 | ### RStudio empowers individuals to be productive with data science.
38 |
39 | * Open source and reproducible research
40 | * APIs and interoperability
41 | * Usability and clear documentation
42 | * Inclusive and collective success
43 | * Creating lasting value for data science
44 |
45 | ## What we do
46 |
47 | ### RStudio builds open source and professional software for data science
48 |
49 | * Our professional features include things like
50 |
51 | * Security
52 | * Authentication
53 | * Load balancing
54 | * Support
55 |
56 | ### RStudio professional products
57 |
58 | * RStudio Server Pro
59 | * RStudio Connect
60 | * RStudio Package Manager
61 |
62 |
63 | ## What is the relationship between R and RStudio?
64 |
65 | ### We don’t own R, package R, or distribute R
66 |
67 | ### R Core team: 20 members -- Zero from RStudio
68 |
69 | ### RStudio products "sit on top of R"
70 |
71 | * You standardize on R first
72 | * Install our products second
73 |
74 | ### We assume you have chosen to invest in R
75 |
76 | ## Professional R tooling and integration
77 |
78 | ### Legitimacy
79 |
80 | * Recognize R as an analytic standard
81 |
82 | ### Competencies*
83 |
84 | * Understand and manage R tooling
85 |
86 | ### Adoption
87 |
88 | * Rely on integrated R based solutions
89 |
90 |
91 | ## Administering RStudio professional products
92 |
93 | ### People want to know if they are doing things the best way
94 |
95 | * R is relatively unknown in most organizations
96 | * No single place to get all the information you need
97 | * Hard to see the forest through the trees
98 |
99 | ### We see a lot of trial and error
100 |
101 | * Organizational hurdles
102 | * Resource limitations
103 |
104 | ## Outline
105 |
106 | ### I want to share some best practices for managing RStudio in production
107 |
108 | * Share product requirements
109 | * Some tips
110 | * A path for getting started
111 |
112 | Goal is to give you a big picture view of what success looks like, assuming you are using RStudio professional products
113 |
114 | # 5 Best practices for administering RStudio in production
115 |
116 | ## 1. Keep your system up to date
117 |
118 | ### Modern tools
119 |
120 | * Operating system
121 | * Browsers
122 |
123 | ### C++11 compiler
124 |
125 | * R packages on Linux must be compiled
126 |
127 | ### Internet access
128 |
129 | * R packages
130 |
131 | ## 2. Support multiple versions of R
132 |
133 | ### Why do you want to run multiple versions of R?
134 |
135 | * Manage upgrades of R
136 | * Test code on a variety of R versions and distributions
137 | * Support projects that depend on various versions of R
138 | * All products support multiple versions of R
139 |
140 | ### Upgrade yearly (version 3.1.0+)
141 |
142 | ### Build R from source
143 |
144 | * Multiple versions of R side by side requires you build R from source
145 | * Not hard to do (i.e. config/make/make install)
146 | * [Instructions](https://support.rstudio.com/hc/en-us/articles/360002242413-Multiple-versions-of-R)
147 |
148 | ## 3. Organize your R packages
149 |
150 | ### R Packages rule the nest.
151 |
152 | * Packages will drive your R version, Linux dependencies, and even your operating system
153 | * Data scientists will want access to their most beloved packages
154 |
155 | ### Managing packages for a single user is easy.
156 |
157 | * Managing packages for an entire platform is hard
158 |
159 | ### RStudio Package Manager solves several problems
160 |
161 | * Disconnected, air-gapped environments
162 | * Curate packages into multiple repositories for security and control
163 | * Share internal packages
164 |
165 | ## 4. Use root privileges
166 |
167 | The group in your organization that installs, configures, and manages R and RStudio will need root privileges
168 |
169 | ### RStudio products
170 |
171 | * Installs require root privileges
172 | * Runs require root privileges
173 | * RStudio Server Pro runs as the root user in order to create new R sessions on behalf of its users
174 | * RStudio Connect runs as the root user in order to isolate applications and processes
175 |
176 | ### R
177 |
178 | * System-wide installations of R on Linux often involve root also
179 |
180 | ## 5. Securely manage your users
181 |
182 | ### R programmers - RStudio Server Pro
183 |
184 | * They will need access to R, file shares, databases, and probably many other sensitive systems.
185 | * R processes run as the user under a local account
186 |
187 | ### End users - RStudio Connect
188 |
189 | * End users consume apps and reports.
190 | * R Processes typically run under a service account
191 |
192 | ## Authentication
193 |
194 | ### Your organization
195 |
196 | * Probably has strong opinions on how to authenticate users
197 | * This space is only getting more fragmented not less
198 | * LDAP, Active Directory, PAM, OAuth, Okta, Duo, Auth0, etc.
199 |
200 | ### Proxied authentication
201 |
202 | * If we don't support your specific system, then you can use our proxied authentication
203 | * With proxied auth, users do not log in through RStudio but through a proxy that you set up
204 |
205 | ## Supported Auth Methods
206 |
207 | ### RStudio Server Pro
208 |
209 | * PAM (LDAP and Active Directory)
210 | * OAuth 2.0 using Google Apps
211 | * *Proxied authentication*
212 |
213 | ### RStudio Connect
214 |
215 | * LDAP and Active Directory
216 | * OAuth 2.0 using Google Apps
217 | * PAM
218 | * SAML [Beta]
219 | * *Proxied authentication*
220 |
221 | ## Recommendations (your Happy path)
222 |
223 | ### 1. Keep your operating systems and browsers up to date
224 |
225 | ### 2. Plan to support multiple versions of R by building R from source
226 |
227 | ### 3. Organize your R packages for reliability and consistency
228 |
229 | ### 4. Use root privileges to install and run RStudio products
230 |
231 | ### 5. Securely manage your R programmers and end users
232 |
233 | # Getting Started
234 |
235 | ## Tooling
236 |
237 | ### RStudio makes software tools that are designed to work together
238 |
239 | * Our R packages and products work together
240 | * There are many ways to assemble our tools
241 | * But it will be up to you to decide how to do it
242 | * Your configuration depends on what does data science means to your organization
243 |
244 | Our goal is to make it easy to install and configure all of our products
245 |
246 | ## Solutions
247 |
248 | ### Data science lab
249 |
250 | ### Application factories (Dev/Test/Prod)
251 |
252 | ### On premises, cloud, hybrid cloud
253 |
254 | ### Single server or a multi-departmental deployment
255 |
256 | ### Crawl, walk, run strategies
257 |
258 | ## Architecture
259 |
260 | 
261 |
262 | ## Server Setup
263 |
264 | 
265 |
266 | ## Recipes
267 |
268 | ### Overview
269 |
270 | * List of ingredients that make up your platform
271 | * Helps you organize and automate your work
272 | * And are unique to your organization
273 |
274 | ### Structure
275 |
276 | * Most of your code will be for Linux, R, and R packages
277 | * A small part of your code will be for installation
278 | * If you've installed R properly, installation is usually easy
279 | * The rest will be configuration
280 |
281 | ## Infrastructure as code
282 |
283 | ### Organize your recipes so that can manage your platform
284 |
285 | * [Configuration management tools for the R admin](https://resources.rstudio.com/rstudio-server-pro/configuration-management-tools-for-the-r-admin)
286 | * Ansible, Chef, Puppet, CodeDeploy, SaltStack, etc.
287 | * Sandbox
288 |
289 | # What if I've never used these products?
290 |
291 | ## RStudio Quickstart
292 |
293 | ### Overview
294 |
295 | * A virtual machine that runs on your desktop
296 | * Includes all our professional products
297 | * And includes pre built assets for you to explore and demonstrate to others
298 |
299 | ### Motivation
300 |
301 | * Experience RStudio professional products
302 | * Free and easy
303 |
304 | [Demo](https://www.rstudio.com/products/quickstart/)
305 |
306 | ## Summary
307 |
308 | ### The happy path
309 |
310 | * Keep your operating system and browser up to date
311 | * Support multiple versions of R by building R from source
312 | * Make sure you have easy access to R packages
313 | * Install products as root
314 | * Use a supported authentication system
315 |
316 | ### How to get started
317 |
318 | * Recipes and [checklists](https://support.rstudio.com/hc/en-us/articles/360015079054)
319 | * Crawl/Walk/Run strategies
320 | * [RStudio QuickStart](https://www.rstudio.com/products/quickstart/)
321 |
322 | ## Summary
323 |
324 | ### Connecting with solutions engineering
325 |
326 | * [Community.rstudio.com](https://community.rstudio.com/)
327 | * [Github.com/sol-eng](http://)
328 | * [Solutions.rstudio.com](http://solutions.rstudio.com)
329 | * [Support.rstudio.com](http://support.rstudio.com)
330 | * [Docs.rstudio.com](docs.rstudio.com)
331 |
332 | ## References
333 |
334 | [Administration of Pro Products](https://resources.rstudio.com/administration-of-pro-products)
335 |
336 | [Professional R Tooling and Integration](https://resources.rstudio.com/webinars/2018-07-11-13-00-professional-r-tooling-and-integration-nathan-stephens-1)
337 |
338 | [The R Admin is Rad](https://resources.rstudio.com/rstudio-conf-2018/the-r-admin-is-rad-a-guide-to-professional-r-tooling-and-integration-nathan-stephens)
339 |
340 | [R Admin Community](https://community.rstudio.com/c/r-admin)
341 |
342 | [RStudio Docs](https://docs.rstudio.com/resources.html)
343 |
344 | [RStudio Professional Product Requirements](https://support.rstudio.com/hc/en-us/articles/360015177453-RStudio-professional-product-requirements)
345 |
346 | [RStudio Server Pro Example Checklist](https://support.rstudio.com/hc/en-us/articles/360015079054-RStudio-Server-Pro-Installation-and-Configuration-Example-Checklist)
347 |
348 | [R for the Enterprise](https://rviews.rstudio.com/categories/r-for-the-enterprise/)
349 |
350 | [Configuration Management Tools for the R Admin](https://resources.rstudio.com/rstudio-server-pro/configuration-management-tools-for-the-r-admin)
351 |
352 |
353 |
--------------------------------------------------------------------------------
/presentations/powerpoint/ref-arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/powerpoint/ref-arch.png
--------------------------------------------------------------------------------
/presentations/powerpoint/servers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/powerpoint/servers.png
--------------------------------------------------------------------------------
/presentations/powerpoint/template.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/powerpoint/template.pptx
--------------------------------------------------------------------------------
/presentations/revealjs/README.md:
--------------------------------------------------------------------------------
1 | ## Reveal.js presentation
2 |
3 |
--------------------------------------------------------------------------------
/presentations/revealjs/image/background_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/background_1.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/background_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/background_2.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/division_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/division_1.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/division_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/division_2.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/documentation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/documentation.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/efficiency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/efficiency.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/format_1_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_1_1.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/format_1_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_1_2.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/format_1_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_1_3.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/format_1_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_1_4.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/format_2_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_2_1.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/format_2_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_2_2.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/format_2_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_2_3.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/format_2_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/format_2_4.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_0.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_1.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_2.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_3.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_4.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_5.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_6.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_7.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_8.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/gif_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/gif_9.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/icjia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/icjia.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/il_seal.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/il_seal.gif
--------------------------------------------------------------------------------
/presentations/revealjs/image/interface.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/interface.gif
--------------------------------------------------------------------------------
/presentations/revealjs/image/modularity_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/modularity_1.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/modularity_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/modularity_2.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/process_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/process_new.png
--------------------------------------------------------------------------------
/presentations/revealjs/image/process_old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quarto-dev/quarto-gallery/91c314637cba9d8a7639e62645e8088365b618c4/presentations/revealjs/image/process_old.png
--------------------------------------------------------------------------------
/presentations/revealjs/requirements.txt:
--------------------------------------------------------------------------------
1 | jupyter
2 |
--------------------------------------------------------------------------------
/presentations/revealjs/reveal.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Modernizing R&A Data Products With Python"
3 | author: "Bobae Kang and Yizi (Winnie) Huang
Center for Criminal Justice Data and Analytics"
4 | date: "R&A Staff Meeting
August 14, 2018"
5 | format:
6 | revealjs:
7 | theme: white
8 | center: true
9 | transition: slide
10 | incremental: false
11 | slide-level: 2
12 | navigationMode: linear
13 | self-contained: true
14 | ---
15 |
16 | ```{=html}
17 |
23 | ```
24 |
25 | ## Agenda {transition="zoom"}
26 |
27 | > - Background
28 | > - Design and Implementation
29 | > - Showcase
30 | > - Path forward
31 |
32 | # Background {background="#466c8c"}
33 |
34 | ## {transition="concave-in fade-out"}
35 |
36 | {width="70%"}
37 |
38 | ## {transition="fade-in concave-out"}
39 |
40 | {width="70%"}
41 |
42 | ##
43 |
44 | {width="75%"}
45 |
46 | ##
47 |
48 | {width="75%"}
49 |
50 | ## Motivation
51 |
52 | - Time-consuming
53 | - Difficult to maintain
54 | - Suboptimal tools
55 | - Outmoded data format
56 | - Overreliance on a single individual
57 |
58 |
59 | # Design and implementation {background="#466c8c"}
60 |
61 | ## What we did
62 |
63 | - Automation
64 | - Modular and flexible design
65 | - Fast and efficient tools
66 | - Machine-friendly format
67 | - Potential division of labor
68 |
69 | ## Automation
70 |
71 | {width="60%"}
72 |
73 | ## Modularity {transition="concave-in fade-out"}
74 |
75 | {width="60%"}
76 |
77 | ## Modularity {transition="fade-in concave-out"}
78 |
79 | {width="60%"}
80 |
81 | ## Efficiency
82 |
83 | {width="75%"}
84 |
85 | ## Format (old) {transition="concave-in fade-out"}
86 |
87 | {width="75%"}
88 |
89 | ## Format (old) {transition="fade"}
90 |
91 | {width="75%"}
92 |
93 | ## Format (old) {transition="fade"}
94 |
95 | {width="75%"}
96 |
97 | ## Format (old) {transition="fade-in concave-out"}
98 |
99 | {width="75%"}
100 |
101 | ## Format (new) {transition="concave-in fade-out"}
102 |
103 | {width="75%"}
104 |
105 | ## Format (new) {transition="fade"}
106 |
107 | {width="75%"}
108 |
109 | ## Format (new) {transition="fade-in concave-out"}
110 |
111 | {width="75%"}
112 |
113 | ## Format (new)
114 |
115 | {width="70%"}
116 |
117 | ## Division of labor {transition="concave-in fade-out"}
118 |
119 | {width="60%"}
120 |
121 | ## Division of labor {transition="fade-in concave-out"}
122 |
123 | {width="60%"}
124 |
125 | ##
126 |
127 | {width="70%"}
128 |
129 | # Showcase {background="#466c8c"}
130 |
131 | ##
132 |
133 | {width="70%"}
134 |
135 | ##
136 |
137 | [{width="70%"}](https://bobaekang.github.io/icjia-web-dataset-maintenance-tool/)
138 |
139 | # Path forward {background="#466c8c"}
140 |
141 | # Thank you!
142 |
--------------------------------------------------------------------------------
/presentations/revealjs/rsconnect/documents/reveal.qmd/rpubs.com/rpubs/Document.dcf:
--------------------------------------------------------------------------------
1 | name: Document
2 | title:
3 | username:
4 | account: rpubs
5 | server: rpubs.com
6 | hostUrl: rpubs.com
7 | appId: https://api.rpubs.com/api/v1/document/799576/7997c4a7f70b4662a46da9e666bda906
8 | bundleId: https://api.rpubs.com/api/v1/document/799576/7997c4a7f70b4662a46da9e666bda906
9 | url: http://rpubs.com/publish/claim/799576/df06d8d83bd241c6b19a89a6a6e7ea47
10 | when: 1629076119.00407
11 | lastSyncTime: 1629076119.00408
12 |
--------------------------------------------------------------------------------
/quarto-gallery.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: knitr
13 | LaTeX: pdfLaTeX
14 |
--------------------------------------------------------------------------------