├── .DS_Store ├── .gitattributes ├── .github └── workflows │ └── build.yml ├── .gitignore ├── _freeze ├── posts │ ├── quarto-website │ │ └── index │ │ │ └── execute-results │ │ │ └── html.json │ ├── softblock-demo │ │ └── index │ │ │ ├── execute-results │ │ │ └── html.json │ │ │ └── figure-html │ │ │ ├── hte_plot-1.png │ │ │ ├── plot_fx-1.png │ │ │ └── power_plot-1.png │ └── test-post │ │ └── index │ │ └── execute-results │ │ └── html.json └── site_libs │ ├── clipboard │ └── clipboard.min.js │ ├── crosstalk-1.2.0 │ ├── css │ │ └── crosstalk.min.css │ ├── js │ │ ├── crosstalk.js │ │ ├── crosstalk.js.map │ │ ├── crosstalk.min.js │ │ └── crosstalk.min.js.map │ └── scss │ │ └── crosstalk.scss │ ├── datatables-binding-0.22 │ └── datatables.js │ ├── datatables-css-0.0.0 │ └── datatables-crosstalk.css │ ├── dt-core-1.11.3 │ ├── css │ │ ├── jquery.dataTables.extra.css │ │ └── jquery.dataTables.min.css │ └── js │ │ └── jquery.dataTables.min.js │ ├── htmlwidgets-1.5.4 │ └── htmlwidgets.js │ ├── jquery-3.6.0 │ ├── jquery-3.6.0.js │ ├── jquery-3.6.0.min.js │ └── jquery-3.6.0.min.map │ └── quarto-listing │ ├── list.min.js │ └── quarto-listing.js ├── _publish.yml ├── _quarto.yml ├── _site ├── about.html ├── blog.html ├── blog.xml ├── cv.html ├── favicon.png ├── headshot.jpg ├── index.html ├── listings.json ├── posts │ ├── quarto-website │ │ ├── cv.pdf │ │ ├── index.html │ │ └── tobias-meme.jpg │ ├── softblock-demo │ │ ├── index.html │ │ ├── index_files │ │ │ └── figure-html │ │ │ │ ├── hte_plot-1.png │ │ │ │ ├── plot_fx-1.png │ │ │ │ └── power_plot-1.png │ │ └── three-designs.jpg │ └── sound-monitoring │ │ └── index.html ├── research.html ├── robots.txt ├── search.json ├── site_libs │ ├── bootstrap │ │ ├── bootstrap-icons.css │ │ ├── bootstrap-icons.woff │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.js │ ├── clipboard │ │ └── clipboard.min.js │ ├── crosstalk-1.2.0 │ │ ├── css │ │ │ └── crosstalk.min.css │ │ ├── js │ │ │ ├── crosstalk.js │ │ │ ├── crosstalk.js.map │ │ │ ├── crosstalk.min.js │ │ │ └── crosstalk.min.js.map │ │ └── scss │ │ │ └── crosstalk.scss │ ├── datatables-binding-0.22 │ │ └── datatables.js │ ├── datatables-css-0.0.0 │ │ └── datatables-crosstalk.css │ ├── dt-core-1.11.3 │ │ ├── css │ │ │ ├── jquery.dataTables.extra.css │ │ │ └── jquery.dataTables.min.css │ │ └── js │ │ │ └── jquery.dataTables.min.js │ ├── htmlwidgets-1.5.4 │ │ └── htmlwidgets.js │ ├── jquery-3.6.0 │ │ ├── jquery-3.6.0.js │ │ ├── jquery-3.6.0.min.js │ │ └── jquery-3.6.0.min.map │ ├── quarto-html │ │ ├── anchor.min.js │ │ ├── popper.min.js │ │ ├── quarto-syntax-highlighting.css │ │ ├── quarto.js │ │ ├── tippy.css │ │ ├── tippy.umd.min.js │ │ └── zenscroll-min.js │ ├── quarto-listing │ │ ├── list.min.js │ │ └── quarto-listing.js │ ├── quarto-nav │ │ ├── headroom.min.js │ │ └── quarto-nav.js │ └── quarto-search │ │ ├── autocomplete.umd.js │ │ ├── fuse.min.js │ │ └── quarto-search.js ├── sitemap.xml ├── social-card.jpg ├── software.html └── styles.css ├── about.qmd ├── blog.qmd ├── favicon.png ├── headshot.jpg ├── includes.html ├── index.qmd ├── papers.yaml ├── posts ├── .DS_Store ├── _metadata.yml ├── quarto-website │ ├── .DS_Store │ ├── cv.pdf │ ├── index.qmd │ └── tobias-meme.jpg ├── softblock-demo │ ├── index.qmd │ ├── index_cache │ │ └── html │ │ │ └── __packages │ ├── index_files │ │ └── figure-html │ │ │ ├── hte_plot-1.png │ │ │ ├── plot_fx-1.png │ │ │ └── power_plot-1.png │ └── three-designs.jpg └── sound-monitoring │ └── index.qmd ├── requirements.txt ├── research.qmd ├── site_libs ├── bootstrap │ ├── bootstrap-icons.css │ ├── bootstrap-icons.woff │ ├── bootstrap.min.css │ └── bootstrap.min.js ├── clipboard │ └── clipboard.min.js ├── crosstalk-1.2.0 │ ├── css │ │ └── crosstalk.min.css │ ├── js │ │ ├── crosstalk.js │ │ ├── crosstalk.js.map │ │ ├── crosstalk.min.js │ │ └── crosstalk.min.js.map │ └── scss │ │ └── crosstalk.scss ├── datatables-binding-0.22 │ └── datatables.js ├── datatables-css-0.0.0 │ └── datatables-crosstalk.css ├── dt-core-1.11.3 │ ├── css │ │ ├── jquery.dataTables.extra.css │ │ └── jquery.dataTables.min.css │ └── js │ │ └── jquery.dataTables.min.js ├── htmlwidgets-1.5.4 │ └── htmlwidgets.js ├── jquery-3.6.0 │ ├── jquery-3.6.0.js │ ├── jquery-3.6.0.min.js │ └── jquery-3.6.0.min.map ├── quarto-html │ ├── anchor.min.js │ ├── popper.min.js │ ├── quarto-syntax-highlighting.css │ ├── quarto.js │ ├── tippy.css │ ├── tippy.umd.min.js │ └── zenscroll-min.js ├── quarto-listing │ ├── list.min.js │ └── quarto-listing.js ├── quarto-nav │ ├── headroom.min.js │ └── quarto-nav.js └── quarto-search │ ├── autocomplete.umd.js │ ├── fuse.min.js │ └── quarto-search.js ├── social-card.jpg ├── software.qmd ├── software.yaml └── styles.css /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: main 4 | pull_request: 5 | branches: main 6 | # to be able to trigger a manual build 7 | workflow_dispatch: 8 | 9 | name: Render and deploy website to Netlify 10 | 11 | jobs: 12 | build-deploy: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: actions/setup-python@v4 17 | with: 18 | python-version: '3.9' 19 | cache: 'pip' 20 | - run: pip install -r requirements.txt 21 | 22 | - uses: r-lib/actions/setup-r@v2 23 | with: 24 | use-public-rspm: true 25 | 26 | - name: Set up Quarto 27 | uses: quarto-dev/quarto-actions/setup@v2 28 | with: 29 | # To install LaTeX to build PDF book 30 | tinytex: true 31 | 32 | - name: Publish to Netlify (and render) 33 | uses: quarto-dev/quarto-actions/publish@v2 34 | with: 35 | target: netlify 36 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.quarto/ 2 | *.RData 3 | *.rdb 4 | *.rdx 5 | -------------------------------------------------------------------------------- /_freeze/posts/quarto-website/index/execute-results/html.json: -------------------------------------------------------------------------------- 1 | { 2 | "hash": "2be81e55e4e784f01b255211bb7279f4", 3 | "result": { 4 | "markdown": "---\ntitle: \"Quarto for Academic Websites\"\ndescription: |\n I continue my life-long search for a system that will allow me to generate a nicely formatted\n website and CV based on adding publications to one single source of truth.\ndate: \"2022-05-11\"\ncategories:\n - website\ncode-fold: true\nexecute:\n eval: false\nimage: /posts/quarto-website/tobias-meme.jpg\n---\n\nI've never been good at keeping my website updated. I always go through two different phases of maintenance:\n\n1. Rushing around creating a new website with bells and whistles\n2. Never updating an existing website\n\nI'm hoping to break out of this cycle, but am current in Phase 1. \nA highlight from my time in Phase 2 was when I forgot to update my DNS and I totally lost control of `drewdimmery.com` (don't go there, it has a squatter).\nI think my website at that time was some Octopress monstrosity\nThere are a few reasons I think [Quarto](https://quarto.org/) might help with this.\n\n- Serving static HTML pages is about as easy as it gets\n- Lots of flexibility (Python / R) in how to generate that content\n- Full programmability means that generation can be based on arbitrary data structures of my choosing\n\nThis post will detail how I've set up Quarto. I've nearly completely separated the two main concerns around maintaining an academic website / CV, which to me are data on *publications* and *software* from the design elements of how to display an atomic *publication* or *software package*.\n\n# Setup\n\nSetting up Quarto was very easy, so I won't belabor this. The combination of the [Get Started guide](https://quarto.org/docs/get-started/) with the [Website Creation guide](https://quarto.org/docs/websites/) kept everything very straightforward. I also used [Danielle Navarro's post](https://blog.djnavarro.net/posts/2022-04-20_porting-to-quarto/) and [her blog's code](https://github.com/djnavarro/quarto-blog).\n\nI decided late in the setup process to add a blog, so I will mention that it's actually very easy to do: it basically just requires adding a [Listing page](https://quarto.org/docs/reference/projects/websites.html#listings) (i.e. the blog's index), a folder to contain the various posts and a `_metadata.yml` file in that folder to describe global settings to apply to all posts. I just created these manually without too much trouble.\n\n# Site Design\n\nTo demonstrate how I've set things up to populate the website from data about my academic life, I'll focus on my [publications](/research.qmd) page. There are two main files undergirding this page:\n\n`papers.yaml`\n: a data file in YAML with standardized information on each publication. I chose YAML because it's fairly easy to write correctly formatted YAML by hand (and I'll be updating)\n\n`research.qmd`\n: The page which takes the data in `papers.yaml` and turns it into nicely formatted Markdown / HTML. This is setup as a Jupyter-backed `qmd` file (essentially a Jupyter notebook).\n\nThis idea of separating the data side (information about publications) and formatting is aimed at making my life easier. One of the reasons I often stop updating my website is because when I come back in 3 months with a new publication, I never remember all the details about how I formatted entries in whatever flavor of Bootstrap I happened to be using when I built the website.\n\nBy separating out the data entry from the formatting, this simplifies matters substantially.\n\nI previously used Hugo Academic for building my website, which was much better than just editing the markup directly, but I never remembered the right way to generate a new publication (there was a CLI, but I never remembered the syntax). Each publication got its own file describing its details, and I found this quite clunky. I wanted something extremely lightweight: there isn't much reason for my individual publications to get pages of their own. I just want some basic information about each of them and a set of appropriate links.\n\n## Data\n\nI put data about each publication in a basic YAML format:\n\n
See example data\n\n```{yaml}\nsoftblock:\n title: Efficient Balanced Treatment Assignments for Experimentation\n authors:\n - David Arbour\n - me\n - Anup Rao\n year: 2021\n venue: AISTATS\n preprint: https://arxiv.org/abs/2010.11332\n published_url: https://proceedings.mlr.press/v130/arbour21a.html\n github: https://github.com/ddimmery/softblock\n```\n\n
\n\nThis is basically like a simplified bibtex entry with more URLs so I can annotate where to find replication materials for a given paper, as well as distinguish between preprints (always freely accessible) versus published versions (not always open access). A convenience that I add in the markup here is referring to myself as `me` in the author list (which is an ordered list). This allows me to add in extra post-processing to highlight where I sit in the author list.\n\nSome additional things I considered adding but chose to ignore for a first version:\n\n- An abstract\n- A suggested bibtex entry\n\nBoth of these would be easy to add, but I chose to start simpler. I also don't love YAML for entering long blocks of text.\n\n## Formatting\n\nSince I can write logic for a page in Python, this puts me on comfortable ground to hack something together. To knit the above publication data into HTML, I just literally bind together the programmatically generated raw HTML which should show up for a single entry.\n\nI do a couple additional useful things in this process:\n- Separate out working papers or non-archival papers from published work (I make this distinction based on whether I include a `published_url` field or not).\n- Order and categorize papers by year\n- Provide nice Bootstrappy buttons for external links (e.g. to Preprints / Code / etc)\n\n::: {.cell execution_count=1}\n``` {.python .cell-code}\nimport yaml\nfrom IPython.display import display, Markdown, HTML\n\ndef readable_list(_s):\n if len(_s) < 3:\n return ' and '.join(map(str, _s))\n *a, b = _s\n return f\"{', '.join(map(str, a))}, and {b}\"\n\ndef button(url, str, icon):\n icon_base = icon[:2]\n return f\"\"\"\n \n {str}\n \"\"\"\n\nyaml_data = yaml.safe_load(open(\"papers.yaml\"))\npub_strs = {\"pubs\": {}, \"wps\": {}}\nfor _, data in yaml_data.items():\n title_str = data[\"title\"]\n authors = data.get(\"authors\", [\"me\"])\n authors = [\n aut if aut != \"me\" else \"Drew Dimmery\" for aut in authors\n ]\n author_str = readable_list(authors)\n year_str = data[\"year\"]\n\n buttons = []\n preprint = data.get(\"preprint\")\n if preprint is not None:\n buttons.append(button(preprint, \"Preprint\", \"bi-file-earmark-pdf\"))\n\n github = data.get(\"github\")\n if github is not None:\n buttons.append(button(github, \"Github\", \"bi-github\"))\n\n pub_url = data.get(\"published_url\")\n venue = data.get(\"venue\")\n working_paper = pub_url is None\n \n pub_str = f'{author_str}. ({year_str}) \"{title_str}.\"'\n\n if venue is not None:\n pub_str += f\" {venue}\"\n\n if working_paper:\n if year_str not in pub_strs[\"wps\"]:\n pub_strs[\"wps\"][year_str] = []\n pub_strs[\"wps\"][year_str].append(\n \"
  • \" + pub_str + \"
    \" + \" \".join(buttons) + \"
  • \"\n )\n else:\n if year_str not in pub_strs[\"pubs\"]:\n pub_strs[\"pubs\"][year_str] = []\n buttons.append(button(pub_url, \"Published\", \"ai-archive\"))\n pub_strs[\"pubs\"][year_str].append(\n \"
  • \" + pub_str + \"
    \" + \" \".join(buttons) + \"
  • \"\n )\n```\n:::\n\n\nI then print this out using the `display` functions from the IPython module and using the `asis` chunk option:\n\n::: {.cell execution_count=2}\n``` {.python .cell-code}\nfor year in sorted(pub_strs[\"pubs\"].keys(), reverse=True):\n display(Markdown(f\"### {year}\" + \"{#\" + f\"published-{year}\" + \"}\"))\n display(HTML(\n \"\"\n ))\n```\n:::\n\n\nThe [full code is on GitHub](https://github.com/ddimmery/quarto-website/blob/main/research.qmd).\n\nIt's worth noting that to get the years to show up in the Table of Contents its necessary to be careful exactly how the content is stuck onto the page. If you don't use the `asis` chunk option, you can still get all the right content to show up, but it won't necessarily appear in the ToC. It's also necessary to include `section-divs: false` in the header, or else the output will be wrapped in additional `div` tags which makes it harder to get the right classes in the right divs.\n\nI use the same basic setup to populate the [Software page](/software.qmd), albeit with simpler logic.\n\n### Additions\nI debated adding an abstract that expands out on click (like the code folding above in this post). This would actually be more or less trivial to add using a `
    ` HTML tag if I wanted to provide the data in the YAML. I'm ignoring this for now because I want to minimize data entry for my future self (and its anyway just a click away at the Preprint).\n\n# Deployment\n\nIt's extremely easy to build a new version of the website locally (`quarto render` from CLI), but there's no guarantee I'll remember that off the top of my head in a month without Googling, so I think it's worthwhile to setup automatic building after I push a commit to GitHub.\n\nGitHub Actions is incredible. I adapted the [example config from Quarto](https://github.com/quarto-dev/quarto-actions/blob/main/examples/quarto-book-netlify.yaml) to the following (also [on GitHub here](https://github.com/ddimmery/quarto-website/blob/main/.github/workflows/build.yml)):\n\n
    GitHub Actions for Netlify\n\n```{yaml}\non:\n push:\n branches: main\n pull_request:\n branches: main\n # to be able to trigger a manual build\n workflow_dispatch:\n\nname: Render and deploy website to Netlify\n\njobs:\n build-deploy:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v2\n - uses: actions/setup-python@v3\n with:\n python-version: '3.9'\n cache: 'pip'\n - run: pip install -r requirements.txt\n\n - uses: r-lib/actions/setup-r@v2\n with:\n use-public-rspm: true\n\n - uses: r-lib/actions/setup-renv@v2\n \n - name: Install Quarto\n uses: quarto-dev/quarto-actions/install-quarto@v1\n with:\n # To install LaTeX to build PDF book \n tinytex: true \n # uncomment below and fill to pin a version\n # version: 0.9.105\n\n - name: Render website\n # Add any command line argument needed\n run: |\n quarto render\n - name: Deploy to Netlify\n id: netlify-deploy\n uses: nwtgck/actions-netlify@v1\n with:\n # The folder the action should deploy. Adapt if you changed in Quarto config\n publish-dir: './_site'\n production-branch: main\n github-token: ${{ secrets.GITHUB_TOKEN }}\n deploy-message:\n 'Deploy from GHA: ${{ github.event.pull_request.title || github.event.head_commit.message }} (${{ github.sha }})'\n enable-pull-request-comment: true # Comment on pull request\n enable-commit-comment: true # Comment on GitHub commit\n enable-commit-status: true # GitHub commit status \n env:\n NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}\n NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}\n timeout-minutes: 1\n```\n\n
    \n\nThis Action requires two pieces of information from Netlify entered as secrets in GitHub. The `NETLIFY_SITE_ID` may be found in the site configuration settings, while the `NETLIFY_AUTH_TOKEN` may be found in personal settings (the personal access token).\n\nSetting this up means that simple updates to pages can actually be done directly in the GitHub editing UI, which further lowers the barrier for my future self. I don't even need to clone the repository to whatever computer I'm working on!\n\n# Future dreams\n\n## Combined CV + Website\nI imagine my CV is similar to most academics' in that it's built like a house of cards (and overfull hboxs). Whenever I add something new to it, I have to copy some lines from elsewhere and modify them to fit the new entry. This always takes me way more time than I'd like. If I mashed together my current [About page](/about.qmd) with the [Research page](/research.qmd), it's like 90% of the way to a full CV. It should presumably be pretty easy to do this explicitly and output a reasonable-looking CV. \n\nThis is a project for another day, though. Too much of the Research page directly outputs HTML, which makes it difficult to naively import into a $\\LaTeX$ CV.\n\nAn almost completely naïve approach to directly importing the relevant pages creates [this ugly document](cv.pdf).\n\n
    Naïve CV\n\n```{markdown}\n---\ntitle: \"Curriculum Vitae\"\nformat: pdf\n---\n\n{{< include about.qmd >}}\n\n{{< include research.md >}}\n```\n\n
    \n\nIt's definitely possible to improve on this. The easiest hacky approach is to just write a whole alternative version of the formatting code which resides in `research.qmd` to output appropriately formatted $\\LaTeX$ markup.\n\n# Conclusion\n\n", 5 | "supporting": [ 6 | "index_files" 7 | ], 8 | "filters": [], 9 | "includes": {} 10 | } 11 | } -------------------------------------------------------------------------------- /_freeze/posts/softblock-demo/index/figure-html/hte_plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_freeze/posts/softblock-demo/index/figure-html/hte_plot-1.png -------------------------------------------------------------------------------- /_freeze/posts/softblock-demo/index/figure-html/plot_fx-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_freeze/posts/softblock-demo/index/figure-html/plot_fx-1.png -------------------------------------------------------------------------------- /_freeze/posts/softblock-demo/index/figure-html/power_plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_freeze/posts/softblock-demo/index/figure-html/power_plot-1.png -------------------------------------------------------------------------------- /_freeze/posts/test-post/index/execute-results/html.json: -------------------------------------------------------------------------------- 1 | { 2 | "hash": "7a9877e166d6e788fe4a392072a96bfa", 3 | "result": { 4 | "markdown": "---\ntitle: \"Example Post With Code\"\ndescription: \"This is a short description of what goes on here.\"\nabstract: >\n This is a longer abstract which I will copy a few times to get some actual text.\n This is a longer abstract which I will copy a few times to get some actual text.\n This is a longer abstract which I will copy a few times to get some actual text.\n This is a longer abstract which I will copy a few times to get some actual text.\nauthor: \"Drew Dimmery\"\ndate: \"5/22/2021\"\ncategories:\n - code\n - analysis\n---\n\n\n# Header\n\nTesting this stuff.\n\nA second paragraph.\n\nA bit of a list:\n\n- Item 1\n- Item 2\n\n## Math\n\n\n$$\\pi = 3.14\\dots$$\n\n\n## Code\n\nThis will be formatted but not printed.\n\n\n::: {.cell}\n\n```{.r .cell-code}\nprint(\"Not Printed!\")\n```\n:::\n\n\nThis will actually be executed and printed.\n\n\n::: {.cell}\n\n```{.r .cell-code}\nprint(\"Printed!\")\n```\n\n::: {.cell-output .cell-output-stdout}\n```\n[1] \"Printed!\"\n```\n:::\n:::", 5 | "supporting": [], 6 | "filters": [ 7 | "rmarkdown/pagebreak.lua" 8 | ], 9 | "includes": {}, 10 | "engineDependencies": {}, 11 | "preserve": {}, 12 | "postProcess": null 13 | } 14 | } -------------------------------------------------------------------------------- /_freeze/site_libs/clipboard/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v2.0.10 3 | * https://clipboardjs.com/ 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1.container-fluid.crosstalk-bscols{margin-left:auto;margin-right:auto}.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:inline-block;padding-right:12px;vertical-align:top}@media only screen and (max-width: 480px){.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:block;padding-right:inherit}}.crosstalk-input{margin-bottom:15px}.crosstalk-input .control-label{margin-bottom:0;vertical-align:middle}.crosstalk-input input[type="checkbox"]{margin:4px 0 0;margin-top:1px;line-height:normal}.crosstalk-input .checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.crosstalk-input .checkbox>label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.crosstalk-input .checkbox input[type="checkbox"],.crosstalk-input .checkbox-inline input[type="checkbox"]{position:absolute;margin-top:2px;margin-left:-20px}.crosstalk-input .checkbox+.checkbox{margin-top:-5px}.crosstalk-input .checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.crosstalk-input .checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px} 2 | -------------------------------------------------------------------------------- /_freeze/site_libs/crosstalk-1.2.0/scss/crosstalk.scss: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | 29 | /* Relevant BS3 styles to make filter_checkbox() look reasonable without Bootstrap */ 30 | .crosstalk-input { 31 | margin-bottom: 15px; /* a la .form-group */ 32 | .control-label { 33 | margin-bottom: 0; 34 | vertical-align: middle; 35 | } 36 | input[type="checkbox"] { 37 | margin: 4px 0 0; 38 | margin-top: 1px; 39 | line-height: normal; 40 | } 41 | .checkbox { 42 | position: relative; 43 | display: block; 44 | margin-top: 10px; 45 | margin-bottom: 10px; 46 | } 47 | .checkbox > label{ 48 | padding-left: 20px; 49 | margin-bottom: 0; 50 | font-weight: 400; 51 | cursor: pointer; 52 | } 53 | .checkbox input[type="checkbox"], 54 | .checkbox-inline input[type="checkbox"] { 55 | position: absolute; 56 | margin-top: 2px; 57 | margin-left: -20px; 58 | } 59 | .checkbox + .checkbox { 60 | margin-top: -5px; 61 | } 62 | .checkbox-inline { 63 | position: relative; 64 | display: inline-block; 65 | padding-left: 20px; 66 | margin-bottom: 0; 67 | font-weight: 400; 68 | vertical-align: middle; 69 | cursor: pointer; 70 | } 71 | .checkbox-inline + .checkbox-inline { 72 | margin-top: 0; 73 | margin-left: 10px; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /_freeze/site_libs/datatables-css-0.0.0/datatables-crosstalk.css: -------------------------------------------------------------------------------- 1 | .dt-crosstalk-fade { 2 | opacity: 0.2; 3 | } 4 | 5 | html body div.DTS div.dataTables_scrollBody { 6 | background: none; 7 | } 8 | 9 | 10 | /* 11 | Fix https://github.com/rstudio/DT/issues/563 12 | If the `table.display` is set to "block" (e.g., pkgdown), the browser will display 13 | datatable objects strangely. The search panel and the page buttons will still be 14 | in full-width but the table body will be "compact" and shorter. 15 | In therory, having this attributes will affect `dom="t"` 16 | with `display: block` users. But in reality, there should be no one. 17 | We may remove the below lines in the future if the upstream agree to have this there. 18 | See https://github.com/DataTables/DataTablesSrc/issues/160 19 | */ 20 | 21 | table.dataTable { 22 | display: table; 23 | } 24 | -------------------------------------------------------------------------------- /_freeze/site_libs/dt-core-1.11.3/css/jquery.dataTables.extra.css: -------------------------------------------------------------------------------- 1 | /* Selected rows/cells */ 2 | table.dataTable tr.selected td, table.dataTable td.selected { 3 | background-color: #b0bed9 !important; 4 | } 5 | /* In case of scrollX/Y or FixedHeader */ 6 | .dataTables_scrollBody .dataTables_sizing { 7 | visibility: hidden; 8 | } 9 | 10 | /* The datatables' theme CSS file doesn't define 11 | the color but with white background. It leads to an issue that 12 | when the HTML's body color is set to 'white', the user can't 13 | see the text since the background is white. One case happens in the 14 | RStudio's IDE when inline viewing the DT table inside an Rmd file, 15 | if the IDE theme is set to "Cobalt". 16 | 17 | See https://github.com/rstudio/DT/issues/447 for more info 18 | 19 | This fixes should have little side-effects because all the other elements 20 | of the default theme use the #333 font color. 21 | 22 | TODO: The upstream may use relative colors for both the table background 23 | and the color. It means the table can display well without this patch 24 | then. At that time, we need to remove the below CSS attributes. 25 | */ 26 | div.datatables { 27 | color: #333; 28 | } 29 | -------------------------------------------------------------------------------- /_freeze/site_libs/quarto-listing/quarto-listing.js: -------------------------------------------------------------------------------- 1 | const kProgressiveAttr = "data-src"; 2 | let categoriesLoaded = false; 3 | 4 | window.quartoListingCategory = (category) => { 5 | if (categoriesLoaded) { 6 | activateCategory(category); 7 | setCategoryHash(category); 8 | } 9 | }; 10 | 11 | window["quarto-listing-loaded"] = () => { 12 | // Process any existing hash 13 | const hash = getHash(); 14 | 15 | if (hash) { 16 | // If there is a category, switch to that 17 | if (hash.category) { 18 | activateCategory(hash.category); 19 | } 20 | // Paginate a specific listing 21 | const listingIds = Object.keys(window["quarto-listings"]); 22 | for (const listingId of listingIds) { 23 | const page = hash[getListingPageKey(listingId)]; 24 | if (page) { 25 | showPage(listingId, page); 26 | } 27 | } 28 | } 29 | 30 | const listingIds = Object.keys(window["quarto-listings"]); 31 | for (const listingId of listingIds) { 32 | // The actual list 33 | const list = window["quarto-listings"][listingId]; 34 | 35 | // Update the handlers for pagination events 36 | refreshPaginationHandlers(listingId); 37 | 38 | // Render any visible items that need it 39 | renderVisibleProgressiveImages(list); 40 | 41 | // Whenever the list is updated, we also need to 42 | // attach handlers to the new pagination elements 43 | // and refresh any newly visible items. 44 | list.on("updated", function () { 45 | renderVisibleProgressiveImages(list); 46 | setTimeout(() => refreshPaginationHandlers(listingId)); 47 | 48 | // Show or hide the no matching message 49 | toggleNoMatchingMessage(list); 50 | }); 51 | } 52 | }; 53 | 54 | window.document.addEventListener("DOMContentLoaded", function (_event) { 55 | // Attach click handlers to categories 56 | const categoryEls = window.document.querySelectorAll( 57 | ".quarto-listing-category .category" 58 | ); 59 | 60 | for (const categoryEl of categoryEls) { 61 | const category = categoryEl.getAttribute("data-category"); 62 | categoryEl.onclick = () => { 63 | activateCategory(category); 64 | setCategoryHash(category); 65 | }; 66 | } 67 | 68 | // Attach a click handler to the category title 69 | // (there should be only one, but since it is a class name, handle N) 70 | const categoryTitleEls = window.document.querySelectorAll( 71 | ".quarto-listing-category-title" 72 | ); 73 | for (const categoryTitleEl of categoryTitleEls) { 74 | categoryTitleEl.onclick = () => { 75 | activateCategory(""); 76 | setCategoryHash(""); 77 | }; 78 | } 79 | 80 | categoriesLoaded = true; 81 | }); 82 | 83 | function toggleNoMatchingMessage(list) { 84 | const selector = `#${list.listContainer.id} .listing-no-matching`; 85 | const noMatchingEl = window.document.querySelector(selector); 86 | if (noMatchingEl) { 87 | if (list.visibleItems.length === 0) { 88 | noMatchingEl.classList.remove("d-none"); 89 | } else { 90 | if (!noMatchingEl.classList.contains("d-none")) { 91 | noMatchingEl.classList.add("d-none"); 92 | } 93 | } 94 | } 95 | } 96 | 97 | function setCategoryHash(category) { 98 | setHash({ category }); 99 | } 100 | 101 | function setPageHash(listingId, page) { 102 | const currentHash = getHash() || {}; 103 | currentHash[getListingPageKey(listingId)] = page; 104 | setHash(currentHash); 105 | } 106 | 107 | function getListingPageKey(listingId) { 108 | return `${listingId}-page`; 109 | } 110 | 111 | function refreshPaginationHandlers(listingId) { 112 | const listingEl = window.document.getElementById(listingId); 113 | const paginationEls = listingEl.querySelectorAll( 114 | ".pagination li.page-item:not(.disabled) .page.page-link" 115 | ); 116 | for (const paginationEl of paginationEls) { 117 | paginationEl.onclick = (sender) => { 118 | setPageHash(listingId, sender.target.getAttribute("data-i")); 119 | showPage(listingId, sender.target.getAttribute("data-i")); 120 | return false; 121 | }; 122 | } 123 | } 124 | 125 | function renderVisibleProgressiveImages(list) { 126 | // Run through the visible items and render any progressive images 127 | for (const item of list.visibleItems) { 128 | const itemEl = item.elm; 129 | if (itemEl) { 130 | const progressiveImgs = itemEl.querySelectorAll( 131 | `img[${kProgressiveAttr}]` 132 | ); 133 | for (const progressiveImg of progressiveImgs) { 134 | const srcValue = progressiveImg.getAttribute(kProgressiveAttr); 135 | if (srcValue) { 136 | progressiveImg.setAttribute("src", srcValue); 137 | } 138 | progressiveImg.removeAttribute(kProgressiveAttr); 139 | } 140 | } 141 | } 142 | } 143 | 144 | function getHash() { 145 | // Hashes are of the form 146 | // #name:value|name1:value1|name2:value2 147 | const currentUrl = new URL(window.location); 148 | const hashRaw = currentUrl.hash ? currentUrl.hash.slice(1) : undefined; 149 | return parseHash(hashRaw); 150 | } 151 | 152 | const kAnd = "&"; 153 | const kEquals = "="; 154 | 155 | function parseHash(hash) { 156 | if (!hash) { 157 | return undefined; 158 | } 159 | const hasValuesStrs = hash.split(kAnd); 160 | const hashValues = hasValuesStrs 161 | .map((hashValueStr) => { 162 | const vals = hashValueStr.split(kEquals); 163 | if (vals.length === 2) { 164 | return { name: vals[0], value: vals[1] }; 165 | } else { 166 | return undefined; 167 | } 168 | }) 169 | .filter((value) => { 170 | return value !== undefined; 171 | }); 172 | 173 | const hashObj = {}; 174 | hashValues.forEach((hashValue) => { 175 | hashObj[hashValue.name] = decodeURIComponent(hashValue.value); 176 | }); 177 | return hashObj; 178 | } 179 | 180 | function makeHash(obj) { 181 | return Object.keys(obj) 182 | .map((key) => { 183 | return `${key}${kEquals}${obj[key]}`; 184 | }) 185 | .join(kAnd); 186 | } 187 | 188 | function setHash(obj) { 189 | const hash = makeHash(obj); 190 | window.history.pushState(null, null, `#${hash}`); 191 | } 192 | 193 | function showPage(listingId, page) { 194 | const list = window["quarto-listings"][listingId]; 195 | if (list) { 196 | list.show((page - 1) * list.page + 1, list.page); 197 | } 198 | } 199 | 200 | function activateCategory(category) { 201 | // Deactivate existing categories 202 | const activeEls = window.document.querySelectorAll( 203 | ".quarto-listing-category .category.active" 204 | ); 205 | for (const activeEl of activeEls) { 206 | activeEl.classList.remove("active"); 207 | } 208 | 209 | // Activate this category 210 | const categoryEl = window.document.querySelector( 211 | `.quarto-listing-category .category[data-category='${category}'` 212 | ); 213 | if (categoryEl) { 214 | categoryEl.classList.add("active"); 215 | } 216 | 217 | // Filter the listings to this category 218 | filterListingCategory(category); 219 | } 220 | 221 | function filterListingCategory(category) { 222 | const listingIds = Object.keys(window["quarto-listings"]); 223 | for (const listingId of listingIds) { 224 | const list = window["quarto-listings"][listingId]; 225 | if (list) { 226 | if (category === "") { 227 | // resets the filter 228 | list.filter(); 229 | } else { 230 | // filter to this category 231 | list.filter(function (item) { 232 | const itemValues = item.values(); 233 | if (itemValues.categories !== null) { 234 | const categories = itemValues.categories.split(","); 235 | return categories.includes(category); 236 | } else { 237 | return false; 238 | } 239 | }); 240 | } 241 | } 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /_publish.yml: -------------------------------------------------------------------------------- 1 | - source: project 2 | netlify: 3 | - id: "7ba304f7-27a3-42b9-afaa-f625ebc31b6c" 4 | url: "https://ddimmery.com" 5 | -------------------------------------------------------------------------------- /_quarto.yml: -------------------------------------------------------------------------------- 1 | project: 2 | type: website 3 | output-dir: _site 4 | 5 | website: 6 | title: "Drew Dimmery" 7 | description: "Personal website of Drew Dimmery" 8 | site-url: https://ddimmery.com 9 | repo-url: https://github.com/ddimmery/quarto-website 10 | google-analytics: "G-Y7YLFF5F90" 11 | open-graph: true 12 | favicon: favicon.png 13 | twitter-card: 14 | creator: "@drewdim" 15 | site: "@drewdim" 16 | card-style: "summary_large_image" 17 | navbar: 18 | background: dark 19 | foreground: light 20 | left: 21 | - href: index.qmd 22 | text: Home 23 | - href: about.qmd 24 | - href: research.qmd 25 | - href: software.qmd 26 | - href: blog.qmd 27 | 28 | format: 29 | html: 30 | theme: journal 31 | css: styles.css 32 | toc: true 33 | toc-depth: 4 34 | toc-title: "Contents" 35 | html-math-method: katex 36 | include-in-header: 37 | - includes.html 38 | highlight-style: tango 39 | 40 | execute: 41 | freeze: auto 42 | -------------------------------------------------------------------------------- /_site/blog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Drew Dimmery - Blog 11 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 58 | 81 | 82 | 83 | 90 | 91 | 92 | 93 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
    120 |
    121 | 151 |
    152 | 153 |
    154 | 155 | 156 | 159 | 160 |
    161 | 162 |
    163 |
    164 |

    Blog

    165 |
    166 | 167 | 168 | 169 | 170 | 171 |
    172 | 173 | 174 | 175 |
    176 | 177 | 178 |
    179 | 180 | 181 | 182 | 183 | 184 |
    258 | 337 |
    338 | 339 | 340 | 341 | -------------------------------------------------------------------------------- /_site/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/favicon.png -------------------------------------------------------------------------------- /_site/headshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/headshot.jpg -------------------------------------------------------------------------------- /_site/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Drew Dimmery 12 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 57 | 58 | 59 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 |
    84 |
    85 | 115 |
    116 | 117 | 270 | 271 | 272 | 273 | -------------------------------------------------------------------------------- /_site/listings.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "listing": "/blog.html", 4 | "items": [ 5 | "/posts/quarto-website/index.html", 6 | "/posts/softblock-demo/index.html" 7 | ] 8 | } 9 | ] -------------------------------------------------------------------------------- /_site/posts/quarto-website/cv.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/posts/quarto-website/cv.pdf -------------------------------------------------------------------------------- /_site/posts/quarto-website/tobias-meme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/posts/quarto-website/tobias-meme.jpg -------------------------------------------------------------------------------- /_site/posts/softblock-demo/index_files/figure-html/hte_plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/posts/softblock-demo/index_files/figure-html/hte_plot-1.png -------------------------------------------------------------------------------- /_site/posts/softblock-demo/index_files/figure-html/plot_fx-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/posts/softblock-demo/index_files/figure-html/plot_fx-1.png -------------------------------------------------------------------------------- /_site/posts/softblock-demo/index_files/figure-html/power_plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/posts/softblock-demo/index_files/figure-html/power_plot-1.png -------------------------------------------------------------------------------- /_site/posts/softblock-demo/three-designs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/posts/softblock-demo/three-designs.jpg -------------------------------------------------------------------------------- /_site/posts/sound-monitoring/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Drew Dimmery - Monitoring Sound Levels 14 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 59 | 60 | 61 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 78 | 79 | 80 | 81 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 |
    93 |
    94 | 124 |
    125 | 126 |
    127 |
    128 |
    129 |

    Monitoring Sound Levels

    130 |
    131 |
    data science
    132 |
    misc
    133 |
    134 |
    135 |
    136 | 137 |
    138 |
    139 |

    Sometimes you have to learn basic principles of sound engineering in order to prove that you’re a good neighbor.

    140 |
    141 |
    142 | 143 |
    144 |
    Author
    145 |
    Affiliation
    146 | 147 |
    148 | Drew Dimmery 149 |
    150 | 157 |
    158 | 159 | 160 | 161 |
    162 | 163 | 164 |
    165 |
    Published
    166 |
    167 |

    May 18, 2022

    168 |
    169 |
    170 | 171 |
    172 | 173 | 174 |
    175 | 176 | 177 | 186 | 187 |
    188 | 189 | 190 | 191 | 192 |
    193 |

    Prelude

    194 |

    Austria cares about keeping things peaceful and quiet. In Vienna there’s a law that quiet hours must be kept between 10pm and 6am every day, and the residents take this extremely seriously. As almost anyone from Vienna and they’ll invariably have at least a story or two of their having the police called for a noise disturbance complaint.

    195 |

    Approximately one day after we moved into our apartment, our neighbor complained to our property manager about the fact that we were too loud. For some additional context, our neighbor’s window looks out just below our terrace.

    196 | 197 | 198 |
    199 | 200 |

    Reuse

    Citation

    BibTeX citation:
    @online{dimmery2022,
    201 |   author = {Drew Dimmery},
    202 |   title = {Monitoring {Sound} {Levels}},
    203 |   date = {2022-05-18},
    204 |   url = {https://ddimmery.com/posts/sound-monitoring},
    205 |   langid = {en}
    206 | }
    207 | 
    For attribution, please cite this work as:
    208 | Drew Dimmery. 2022. “Monitoring Sound Levels.” May 18, 209 | 2022. https://ddimmery.com/posts/sound-monitoring. 210 |
    211 | 212 | 291 |
    292 | 293 | 294 | 295 | -------------------------------------------------------------------------------- /_site/robots.txt: -------------------------------------------------------------------------------- 1 | Sitemap: https://ddimmery.com/sitemap.xml 2 | -------------------------------------------------------------------------------- /_site/site_libs/bootstrap/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/site_libs/bootstrap/bootstrap-icons.woff -------------------------------------------------------------------------------- /_site/site_libs/clipboard/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v2.0.10 3 | * https://clipboardjs.com/ 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1.container-fluid.crosstalk-bscols{margin-left:auto;margin-right:auto}.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:inline-block;padding-right:12px;vertical-align:top}@media only screen and (max-width: 480px){.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:block;padding-right:inherit}}.crosstalk-input{margin-bottom:15px}.crosstalk-input .control-label{margin-bottom:0;vertical-align:middle}.crosstalk-input input[type="checkbox"]{margin:4px 0 0;margin-top:1px;line-height:normal}.crosstalk-input .checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.crosstalk-input .checkbox>label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.crosstalk-input .checkbox input[type="checkbox"],.crosstalk-input .checkbox-inline input[type="checkbox"]{position:absolute;margin-top:2px;margin-left:-20px}.crosstalk-input .checkbox+.checkbox{margin-top:-5px}.crosstalk-input .checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.crosstalk-input .checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px} 2 | -------------------------------------------------------------------------------- /_site/site_libs/crosstalk-1.2.0/scss/crosstalk.scss: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | 29 | /* Relevant BS3 styles to make filter_checkbox() look reasonable without Bootstrap */ 30 | .crosstalk-input { 31 | margin-bottom: 15px; /* a la .form-group */ 32 | .control-label { 33 | margin-bottom: 0; 34 | vertical-align: middle; 35 | } 36 | input[type="checkbox"] { 37 | margin: 4px 0 0; 38 | margin-top: 1px; 39 | line-height: normal; 40 | } 41 | .checkbox { 42 | position: relative; 43 | display: block; 44 | margin-top: 10px; 45 | margin-bottom: 10px; 46 | } 47 | .checkbox > label{ 48 | padding-left: 20px; 49 | margin-bottom: 0; 50 | font-weight: 400; 51 | cursor: pointer; 52 | } 53 | .checkbox input[type="checkbox"], 54 | .checkbox-inline input[type="checkbox"] { 55 | position: absolute; 56 | margin-top: 2px; 57 | margin-left: -20px; 58 | } 59 | .checkbox + .checkbox { 60 | margin-top: -5px; 61 | } 62 | .checkbox-inline { 63 | position: relative; 64 | display: inline-block; 65 | padding-left: 20px; 66 | margin-bottom: 0; 67 | font-weight: 400; 68 | vertical-align: middle; 69 | cursor: pointer; 70 | } 71 | .checkbox-inline + .checkbox-inline { 72 | margin-top: 0; 73 | margin-left: 10px; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /_site/site_libs/datatables-css-0.0.0/datatables-crosstalk.css: -------------------------------------------------------------------------------- 1 | .dt-crosstalk-fade { 2 | opacity: 0.2; 3 | } 4 | 5 | html body div.DTS div.dataTables_scrollBody { 6 | background: none; 7 | } 8 | 9 | 10 | /* 11 | Fix https://github.com/rstudio/DT/issues/563 12 | If the `table.display` is set to "block" (e.g., pkgdown), the browser will display 13 | datatable objects strangely. The search panel and the page buttons will still be 14 | in full-width but the table body will be "compact" and shorter. 15 | In therory, having this attributes will affect `dom="t"` 16 | with `display: block` users. But in reality, there should be no one. 17 | We may remove the below lines in the future if the upstream agree to have this there. 18 | See https://github.com/DataTables/DataTablesSrc/issues/160 19 | */ 20 | 21 | table.dataTable { 22 | display: table; 23 | } 24 | -------------------------------------------------------------------------------- /_site/site_libs/dt-core-1.11.3/css/jquery.dataTables.extra.css: -------------------------------------------------------------------------------- 1 | /* Selected rows/cells */ 2 | table.dataTable tr.selected td, table.dataTable td.selected { 3 | background-color: #b0bed9 !important; 4 | } 5 | /* In case of scrollX/Y or FixedHeader */ 6 | .dataTables_scrollBody .dataTables_sizing { 7 | visibility: hidden; 8 | } 9 | 10 | /* The datatables' theme CSS file doesn't define 11 | the color but with white background. It leads to an issue that 12 | when the HTML's body color is set to 'white', the user can't 13 | see the text since the background is white. One case happens in the 14 | RStudio's IDE when inline viewing the DT table inside an Rmd file, 15 | if the IDE theme is set to "Cobalt". 16 | 17 | See https://github.com/rstudio/DT/issues/447 for more info 18 | 19 | This fixes should have little side-effects because all the other elements 20 | of the default theme use the #333 font color. 21 | 22 | TODO: The upstream may use relative colors for both the table background 23 | and the color. It means the table can display well without this patch 24 | then. At that time, we need to remove the below CSS attributes. 25 | */ 26 | div.datatables { 27 | color: #333; 28 | } 29 | -------------------------------------------------------------------------------- /_site/site_libs/quarto-html/anchor.min.js: -------------------------------------------------------------------------------- 1 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 2 | // 3 | // AnchorJS - v4.3.1 - 2021-04-17 4 | // https://www.bryanbraun.com/anchorjs/ 5 | // Copyright (c) 2021 Bryan Braun; Licensed MIT 6 | // 7 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 8 | !function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(this,function(){"use strict";return function(A){function d(A){A.icon=Object.prototype.hasOwnProperty.call(A,"icon")?A.icon:"",A.visible=Object.prototype.hasOwnProperty.call(A,"visible")?A.visible:"hover",A.placement=Object.prototype.hasOwnProperty.call(A,"placement")?A.placement:"right",A.ariaLabel=Object.prototype.hasOwnProperty.call(A,"ariaLabel")?A.ariaLabel:"Anchor",A.class=Object.prototype.hasOwnProperty.call(A,"class")?A.class:"",A.base=Object.prototype.hasOwnProperty.call(A,"base")?A.base:"",A.truncate=Object.prototype.hasOwnProperty.call(A,"truncate")?Math.floor(A.truncate):64,A.titleText=Object.prototype.hasOwnProperty.call(A,"titleText")?A.titleText:""}function w(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new TypeError("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],d(this.options),this.isTouchDevice=function(){return Boolean("ontouchstart"in window||window.TouchEvent||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(A){var e,t,o,i,n,s,a,c,r,l,h,u,p=[];if(d(this.options),"touch"===(l=this.options.visible)&&(l=this.isTouchDevice()?"always":"hover"),0===(e=w(A=A||"h2, h3, h4, h5, h6")).length)return this;for(null===document.head.querySelector("style.anchorjs")&&((u=document.createElement("style")).className="anchorjs",u.appendChild(document.createTextNode("")),void 0===(A=document.head.querySelector('[rel="stylesheet"],style'))?document.head.appendChild(u):document.head.insertBefore(u,A),u.sheet.insertRule(".anchorjs-link{opacity:0;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}",u.sheet.cssRules.length),u.sheet.insertRule(":hover>.anchorjs-link,.anchorjs-link:focus{opacity:1}",u.sheet.cssRules.length),u.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",u.sheet.cssRules.length),u.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',u.sheet.cssRules.length)),u=document.querySelectorAll("[id]"),t=[].map.call(u,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}}); 9 | // @license-end -------------------------------------------------------------------------------- /_site/site_libs/quarto-html/quarto-syntax-highlighting.css: -------------------------------------------------------------------------------- 1 | /* quarto syntax highlight colors */ 2 | :root { 3 | --quarto-hl-ot-color: #8f5902; 4 | --quarto-hl-at-color: #c4a000; 5 | --quarto-hl-ss-color: #4e9a06; 6 | --quarto-hl-an-color: #8f5902; 7 | --quarto-hl-fu-color: #000000; 8 | --quarto-hl-st-color: #4e9a06; 9 | --quarto-hl-cf-color: #204a87; 10 | --quarto-hl-op-color: #ce5c00; 11 | --quarto-hl-er-color: #a40000; 12 | --quarto-hl-bn-color: #0000cf; 13 | --quarto-hl-al-color: #ef2929; 14 | --quarto-hl-va-color: #000000; 15 | --quarto-hl-ex-color: inherit; 16 | --quarto-hl-pp-color: #8f5902; 17 | --quarto-hl-in-color: #8f5902; 18 | --quarto-hl-vs-color: #4e9a06; 19 | --quarto-hl-wa-color: #8f5902; 20 | --quarto-hl-do-color: #8f5902; 21 | --quarto-hl-im-color: inherit; 22 | --quarto-hl-ch-color: #4e9a06; 23 | --quarto-hl-dt-color: #204a87; 24 | --quarto-hl-fl-color: #0000cf; 25 | --quarto-hl-co-color: #8f5902; 26 | --quarto-hl-cv-color: #8f5902; 27 | --quarto-hl-cn-color: #000000; 28 | --quarto-hl-sc-color: #000000; 29 | --quarto-hl-dv-color: #0000cf; 30 | --quarto-hl-kw-color: #204a87; 31 | } 32 | 33 | /* other quarto variables */ 34 | :root { 35 | --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 36 | } 37 | 38 | code span.ot { 39 | color: #8f5902; 40 | } 41 | 42 | code span.at { 43 | color: #c4a000; 44 | } 45 | 46 | code span.ss { 47 | color: #4e9a06; 48 | } 49 | 50 | code span.an { 51 | color: #8f5902; 52 | font-weight: bold; 53 | font-style: italic; 54 | } 55 | 56 | code span.fu { 57 | color: #000000; 58 | } 59 | 60 | code span.st { 61 | color: #4e9a06; 62 | } 63 | 64 | code span.cf { 65 | color: #204a87; 66 | font-weight: bold; 67 | } 68 | 69 | code span.op { 70 | color: #ce5c00; 71 | font-weight: bold; 72 | } 73 | 74 | code span.er { 75 | color: #a40000; 76 | font-weight: bold; 77 | } 78 | 79 | code span.bn { 80 | color: #0000cf; 81 | } 82 | 83 | code span.al { 84 | color: #ef2929; 85 | } 86 | 87 | code span.va { 88 | color: #000000; 89 | } 90 | 91 | code span.pp { 92 | color: #8f5902; 93 | font-style: italic; 94 | } 95 | 96 | code span.in { 97 | color: #8f5902; 98 | font-weight: bold; 99 | font-style: italic; 100 | } 101 | 102 | code span.vs { 103 | color: #4e9a06; 104 | } 105 | 106 | code span.wa { 107 | color: #8f5902; 108 | font-weight: bold; 109 | font-style: italic; 110 | } 111 | 112 | code span.do { 113 | color: #8f5902; 114 | font-weight: bold; 115 | font-style: italic; 116 | } 117 | 118 | code span.ch { 119 | color: #4e9a06; 120 | } 121 | 122 | code span.dt { 123 | color: #204a87; 124 | } 125 | 126 | code span.fl { 127 | color: #0000cf; 128 | } 129 | 130 | code span.co { 131 | color: #8f5902; 132 | font-style: italic; 133 | } 134 | 135 | code span.cv { 136 | color: #8f5902; 137 | font-weight: bold; 138 | font-style: italic; 139 | } 140 | 141 | code span.cn { 142 | color: #000000; 143 | } 144 | 145 | code span.sc { 146 | color: #000000; 147 | } 148 | 149 | code span.dv { 150 | color: #0000cf; 151 | } 152 | 153 | code span.kw { 154 | color: #204a87; 155 | font-weight: bold; 156 | } 157 | 158 | .prevent-inlining { 159 | content: ".tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} -------------------------------------------------------------------------------- /_site/site_libs/quarto-html/zenscroll-min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"function"==typeof define&&define.amd?define([],e()):"object"==typeof module&&module.exports?module.exports=e():function n(){document&&document.body?t.zenscroll=e():setTimeout(n,9)}()}(this,function(){"use strict";var t=function(t){return t&&"getComputedStyle"in window&&"smooth"===window.getComputedStyle(t)["scroll-behavior"]};if("undefined"==typeof window||!("document"in window))return{};var e=function(e,n,o){n=n||999,o||0===o||(o=9);var i,r=function(t){i=t},u=function(){clearTimeout(i),r(0)},c=function(t){return Math.max(0,e.getTopOf(t)-o)},a=function(o,i,c){if(u(),0===i||i&&i<0||t(e.body))e.toY(o),c&&c();else{var a=e.getY(),f=Math.max(0,o)-a,s=(new Date).getTime();i=i||Math.min(Math.abs(f),n),function t(){r(setTimeout(function(){var n=Math.min(1,((new Date).getTime()-s)/i),o=Math.max(0,Math.floor(a+f*(n<.5?2*n*n:n*(4-2*n)-1)));e.toY(o),n<1&&e.getHeight()+os?f(t,n,i):u+o>d?a(u-s+o,n,i):i&&i()},l=function(t,n,o,i){a(Math.max(0,e.getTopOf(t)-e.getHeight()/2+(o||t.getBoundingClientRect().height/2)),n,i)};return{setup:function(t,e){return(0===t||t)&&(n=t),(0===e||e)&&(o=e),{defaultDuration:n,edgeOffset:o}},to:f,toY:a,intoView:s,center:l,stop:u,moving:function(){return!!i},getY:e.getY,getTopOf:e.getTopOf}},n=document.documentElement,o=function(){return window.scrollY||n.scrollTop},i=e({body:document.scrollingElement||document.body,toY:function(t){window.scrollTo(0,t)},getY:o,getHeight:function(){return window.innerHeight||n.clientHeight},getTopOf:function(t){return t.getBoundingClientRect().top+o()-n.offsetTop}});if(i.createScroller=function(t,o,i){return e({body:t,toY:function(e){t.scrollTop=e},getY:function(){return t.scrollTop},getHeight:function(){return Math.min(t.clientHeight,window.innerHeight||n.clientHeight)},getTopOf:function(t){return t.offsetTop}},o,i)},"addEventListener"in window&&!window.noZensmooth&&!t(document.body)){var r="history"in window&&"pushState"in history,u=r&&"scrollRestoration"in history;u&&(history.scrollRestoration="auto"),window.addEventListener("load",function(){u&&(setTimeout(function(){history.scrollRestoration="manual"},9),window.addEventListener("popstate",function(t){t.state&&"zenscrollY"in t.state&&i.toY(t.state.zenscrollY)},!1)),window.location.hash&&setTimeout(function(){var t=i.setup().edgeOffset;if(t){var e=document.getElementById(window.location.href.split("#")[1]);if(e){var n=Math.max(0,i.getTopOf(e)-t),o=i.getY()-n;0<=o&&o<9&&window.scrollTo(0,n)}}},9)},!1);var c=new RegExp("(^|\\s)noZensmooth(\\s|$)");window.addEventListener("click",function(t){for(var e=t.target;e&&"A"!==e.tagName;)e=e.parentNode;if(!(!e||1!==t.which||t.shiftKey||t.metaKey||t.ctrlKey||t.altKey)){if(u){var n=history.state&&"object"==typeof history.state?history.state:{};n.zenscrollY=i.getY();try{history.replaceState(n,"")}catch(t){}}var o=e.getAttribute("href")||"";if(0===o.indexOf("#")&&!c.test(e.className)){var a=0,f=document.getElementById(o.substring(1));if("#"!==o){if(!f)return;a=i.getTopOf(f)}t.preventDefault();var s=function(){window.location=o},l=i.setup().edgeOffset;l&&(a=Math.max(0,a-l),r&&(s=function(){history.pushState({},"",o)})),i.toY(a,null,s)}}},!1)}return i}); -------------------------------------------------------------------------------- /_site/site_libs/quarto-listing/quarto-listing.js: -------------------------------------------------------------------------------- 1 | const kProgressiveAttr = "data-src"; 2 | let categoriesLoaded = false; 3 | 4 | window.quartoListingCategory = (category) => { 5 | if (categoriesLoaded) { 6 | activateCategory(category); 7 | setCategoryHash(category); 8 | } 9 | }; 10 | 11 | window["quarto-listing-loaded"] = () => { 12 | // Process any existing hash 13 | const hash = getHash(); 14 | 15 | if (hash) { 16 | // If there is a category, switch to that 17 | if (hash.category) { 18 | activateCategory(hash.category); 19 | } 20 | // Paginate a specific listing 21 | const listingIds = Object.keys(window["quarto-listings"]); 22 | for (const listingId of listingIds) { 23 | const page = hash[getListingPageKey(listingId)]; 24 | if (page) { 25 | showPage(listingId, page); 26 | } 27 | } 28 | } 29 | 30 | const listingIds = Object.keys(window["quarto-listings"]); 31 | for (const listingId of listingIds) { 32 | // The actual list 33 | const list = window["quarto-listings"][listingId]; 34 | 35 | // Update the handlers for pagination events 36 | refreshPaginationHandlers(listingId); 37 | 38 | // Render any visible items that need it 39 | renderVisibleProgressiveImages(list); 40 | 41 | // Whenever the list is updated, we also need to 42 | // attach handlers to the new pagination elements 43 | // and refresh any newly visible items. 44 | list.on("updated", function () { 45 | renderVisibleProgressiveImages(list); 46 | setTimeout(() => refreshPaginationHandlers(listingId)); 47 | 48 | // Show or hide the no matching message 49 | toggleNoMatchingMessage(list); 50 | }); 51 | } 52 | }; 53 | 54 | window.document.addEventListener("DOMContentLoaded", function (_event) { 55 | // Attach click handlers to categories 56 | const categoryEls = window.document.querySelectorAll( 57 | ".quarto-listing-category .category" 58 | ); 59 | 60 | for (const categoryEl of categoryEls) { 61 | const category = categoryEl.getAttribute("data-category"); 62 | categoryEl.onclick = () => { 63 | activateCategory(category); 64 | setCategoryHash(category); 65 | }; 66 | } 67 | 68 | // Attach a click handler to the category title 69 | // (there should be only one, but since it is a class name, handle N) 70 | const categoryTitleEls = window.document.querySelectorAll( 71 | ".quarto-listing-category-title" 72 | ); 73 | for (const categoryTitleEl of categoryTitleEls) { 74 | categoryTitleEl.onclick = () => { 75 | activateCategory(""); 76 | setCategoryHash(""); 77 | }; 78 | } 79 | 80 | categoriesLoaded = true; 81 | }); 82 | 83 | function toggleNoMatchingMessage(list) { 84 | const selector = `#${list.listContainer.id} .listing-no-matching`; 85 | const noMatchingEl = window.document.querySelector(selector); 86 | if (noMatchingEl) { 87 | if (list.visibleItems.length === 0) { 88 | noMatchingEl.classList.remove("d-none"); 89 | } else { 90 | if (!noMatchingEl.classList.contains("d-none")) { 91 | noMatchingEl.classList.add("d-none"); 92 | } 93 | } 94 | } 95 | } 96 | 97 | function setCategoryHash(category) { 98 | setHash({ category }); 99 | } 100 | 101 | function setPageHash(listingId, page) { 102 | const currentHash = getHash() || {}; 103 | currentHash[getListingPageKey(listingId)] = page; 104 | setHash(currentHash); 105 | } 106 | 107 | function getListingPageKey(listingId) { 108 | return `${listingId}-page`; 109 | } 110 | 111 | function refreshPaginationHandlers(listingId) { 112 | const listingEl = window.document.getElementById(listingId); 113 | const paginationEls = listingEl.querySelectorAll( 114 | ".pagination li.page-item:not(.disabled) .page.page-link" 115 | ); 116 | for (const paginationEl of paginationEls) { 117 | paginationEl.onclick = (sender) => { 118 | setPageHash(listingId, sender.target.getAttribute("data-i")); 119 | showPage(listingId, sender.target.getAttribute("data-i")); 120 | return false; 121 | }; 122 | } 123 | } 124 | 125 | function renderVisibleProgressiveImages(list) { 126 | // Run through the visible items and render any progressive images 127 | for (const item of list.visibleItems) { 128 | const itemEl = item.elm; 129 | if (itemEl) { 130 | const progressiveImgs = itemEl.querySelectorAll( 131 | `img[${kProgressiveAttr}]` 132 | ); 133 | for (const progressiveImg of progressiveImgs) { 134 | const srcValue = progressiveImg.getAttribute(kProgressiveAttr); 135 | if (srcValue) { 136 | progressiveImg.setAttribute("src", srcValue); 137 | } 138 | progressiveImg.removeAttribute(kProgressiveAttr); 139 | } 140 | } 141 | } 142 | } 143 | 144 | function getHash() { 145 | // Hashes are of the form 146 | // #name:value|name1:value1|name2:value2 147 | const currentUrl = new URL(window.location); 148 | const hashRaw = currentUrl.hash ? currentUrl.hash.slice(1) : undefined; 149 | return parseHash(hashRaw); 150 | } 151 | 152 | const kAnd = "&"; 153 | const kEquals = "="; 154 | 155 | function parseHash(hash) { 156 | if (!hash) { 157 | return undefined; 158 | } 159 | const hasValuesStrs = hash.split(kAnd); 160 | const hashValues = hasValuesStrs 161 | .map((hashValueStr) => { 162 | const vals = hashValueStr.split(kEquals); 163 | if (vals.length === 2) { 164 | return { name: vals[0], value: vals[1] }; 165 | } else { 166 | return undefined; 167 | } 168 | }) 169 | .filter((value) => { 170 | return value !== undefined; 171 | }); 172 | 173 | const hashObj = {}; 174 | hashValues.forEach((hashValue) => { 175 | hashObj[hashValue.name] = decodeURIComponent(hashValue.value); 176 | }); 177 | return hashObj; 178 | } 179 | 180 | function makeHash(obj) { 181 | return Object.keys(obj) 182 | .map((key) => { 183 | return `${key}${kEquals}${obj[key]}`; 184 | }) 185 | .join(kAnd); 186 | } 187 | 188 | function setHash(obj) { 189 | const hash = makeHash(obj); 190 | window.history.pushState(null, null, `#${hash}`); 191 | } 192 | 193 | function showPage(listingId, page) { 194 | const list = window["quarto-listings"][listingId]; 195 | if (list) { 196 | list.show((page - 1) * list.page + 1, list.page); 197 | } 198 | } 199 | 200 | function activateCategory(category) { 201 | // Deactivate existing categories 202 | const activeEls = window.document.querySelectorAll( 203 | ".quarto-listing-category .category.active" 204 | ); 205 | for (const activeEl of activeEls) { 206 | activeEl.classList.remove("active"); 207 | } 208 | 209 | // Activate this category 210 | const categoryEl = window.document.querySelector( 211 | `.quarto-listing-category .category[data-category='${category}'` 212 | ); 213 | if (categoryEl) { 214 | categoryEl.classList.add("active"); 215 | } 216 | 217 | // Filter the listings to this category 218 | filterListingCategory(category); 219 | } 220 | 221 | function filterListingCategory(category) { 222 | const listingIds = Object.keys(window["quarto-listings"]); 223 | for (const listingId of listingIds) { 224 | const list = window["quarto-listings"][listingId]; 225 | if (list) { 226 | if (category === "") { 227 | // resets the filter 228 | list.filter(); 229 | } else { 230 | // filter to this category 231 | list.filter(function (item) { 232 | const itemValues = item.values(); 233 | if (itemValues.categories !== null) { 234 | const categories = itemValues.categories.split(","); 235 | return categories.includes(category); 236 | } else { 237 | return false; 238 | } 239 | }); 240 | } 241 | } 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /_site/site_libs/quarto-nav/headroom.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it 3 | * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js 4 | * License: MIT 5 | */ 6 | 7 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s}); 8 | -------------------------------------------------------------------------------- /_site/site_libs/quarto-nav/quarto-nav.js: -------------------------------------------------------------------------------- 1 | const headroomChanged = new CustomEvent("quarto-hrChanged", { 2 | detail: {}, 3 | bubbles: true, 4 | cancelable: false, 5 | composed: false, 6 | }); 7 | 8 | window.document.addEventListener("DOMContentLoaded", function () { 9 | let init = false; 10 | 11 | function throttle(func, wait) { 12 | var timeout; 13 | return function () { 14 | const context = this; 15 | const args = arguments; 16 | const later = function () { 17 | clearTimeout(timeout); 18 | timeout = null; 19 | func.apply(context, args); 20 | }; 21 | 22 | if (!timeout) { 23 | timeout = setTimeout(later, wait); 24 | } 25 | }; 26 | } 27 | 28 | function headerOffset() { 29 | // Set an offset if there is are fixed top navbar 30 | const headerEl = window.document.querySelector("header.fixed-top"); 31 | if (headerEl) { 32 | return headerEl.clientHeight; 33 | } else { 34 | return 0; 35 | } 36 | } 37 | 38 | function footerOffset() { 39 | const footerEl = window.document.querySelector("footer.footer"); 40 | if (footerEl) { 41 | return footerEl.clientHeight; 42 | } else { 43 | return 0; 44 | } 45 | } 46 | 47 | function updateDocumentOffsetWithoutAnimation() { 48 | updateDocumentOffset(false); 49 | } 50 | 51 | function updateDocumentOffset(animated) { 52 | // set body offset 53 | const topOffset = headerOffset(); 54 | const bodyOffset = topOffset + footerOffset(); 55 | const bodyEl = window.document.body; 56 | bodyEl.setAttribute("data-bs-offset", topOffset); 57 | bodyEl.style.paddingTop = topOffset + "px"; 58 | 59 | // deal with sidebar offsets 60 | const sidebars = window.document.querySelectorAll( 61 | ".sidebar, .headroom-target" 62 | ); 63 | sidebars.forEach((sidebar) => { 64 | if (!animated) { 65 | sidebar.classList.add("notransition"); 66 | // Remove the no transition class after the animation has time to complete 67 | setTimeout(function () { 68 | sidebar.classList.remove("notransition"); 69 | }, 201); 70 | } 71 | 72 | if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) { 73 | sidebar.style.top = "0"; 74 | sidebar.style.maxHeight = "100vh"; 75 | } else { 76 | sidebar.style.top = topOffset + "px"; 77 | sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)"; 78 | } 79 | }); 80 | 81 | // allow space for footer 82 | const mainContainer = window.document.querySelector(".quarto-container"); 83 | if (mainContainer) { 84 | mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)"; 85 | } 86 | 87 | // link offset 88 | let linkStyle = window.document.querySelector("#quarto-target-style"); 89 | if (!linkStyle) { 90 | linkStyle = window.document.createElement("style"); 91 | window.document.head.appendChild(linkStyle); 92 | } 93 | while (linkStyle.firstChild) { 94 | linkStyle.removeChild(linkStyle.firstChild); 95 | } 96 | if (topOffset > 0) { 97 | linkStyle.appendChild( 98 | window.document.createTextNode(` 99 | section:target::before { 100 | content: ""; 101 | display: block; 102 | height: ${topOffset}px; 103 | margin: -${topOffset}px 0 0; 104 | }`) 105 | ); 106 | } 107 | if (init) { 108 | window.dispatchEvent(headroomChanged); 109 | } 110 | init = true; 111 | } 112 | 113 | // initialize headroom 114 | var header = window.document.querySelector("#quarto-header"); 115 | if (header && window.Headroom) { 116 | const headroom = new window.Headroom(header, { 117 | tolerance: 5, 118 | onPin: function () { 119 | const sidebars = window.document.querySelectorAll( 120 | ".sidebar, .headroom-target" 121 | ); 122 | sidebars.forEach((sidebar) => { 123 | sidebar.classList.remove("sidebar-unpinned"); 124 | }); 125 | updateDocumentOffset(); 126 | }, 127 | onUnpin: function () { 128 | const sidebars = window.document.querySelectorAll( 129 | ".sidebar, .headroom-target" 130 | ); 131 | sidebars.forEach((sidebar) => { 132 | sidebar.classList.add("sidebar-unpinned"); 133 | }); 134 | updateDocumentOffset(); 135 | }, 136 | }); 137 | headroom.init(); 138 | 139 | let frozen = false; 140 | window.quartoToggleHeadroom = function () { 141 | if (frozen) { 142 | headroom.unfreeze(); 143 | frozen = false; 144 | } else { 145 | headroom.freeze(); 146 | frozen = true; 147 | } 148 | }; 149 | } 150 | 151 | // Observe size changed for the header 152 | const headerEl = window.document.querySelector("header.fixed-top"); 153 | if (headerEl && window.ResizeObserver) { 154 | const observer = new window.ResizeObserver( 155 | throttle(updateDocumentOffsetWithoutAnimation, 50) 156 | ); 157 | observer.observe(headerEl, { 158 | attributes: true, 159 | childList: true, 160 | characterData: true, 161 | }); 162 | } else { 163 | window.addEventListener( 164 | "resize", 165 | throttle(updateDocumentOffsetWithoutAnimation, 50) 166 | ); 167 | setTimeout(updateDocumentOffsetWithoutAnimation, 500); 168 | } 169 | 170 | // fixup index.html links if we aren't on the filesystem 171 | if (window.location.protocol !== "file:") { 172 | const links = window.document.querySelectorAll("a"); 173 | for (let i = 0; i < links.length; i++) { 174 | links[i].href = links[i].href.replace(/\/index\.html/, "/"); 175 | } 176 | 177 | // Fixup any sharing links that require urls 178 | // Append url to any sharing urls 179 | const sharingLinks = window.document.querySelectorAll( 180 | "a.sidebar-tools-main-item" 181 | ); 182 | for (let i = 0; i < sharingLinks.length; i++) { 183 | const sharingLink = sharingLinks[i]; 184 | const href = sharingLink.getAttribute("href"); 185 | if (href) { 186 | sharingLink.setAttribute( 187 | "href", 188 | href.replace("|url|", window.location.href) 189 | ); 190 | } 191 | } 192 | 193 | // Scroll the active navigation item into view, if necessary 194 | const navSidebar = window.document.querySelector("nav#quarto-sidebar"); 195 | if (navSidebar) { 196 | // Find the active item 197 | const activeItem = navSidebar.querySelector("li.sidebar-item a.active"); 198 | if (activeItem) { 199 | // Wait for the scroll height and height to resolve by observing size changes on the 200 | // nav element that is scrollable 201 | const resizeObserver = new ResizeObserver((_entries) => { 202 | // The bottom of the element 203 | const elBottom = activeItem.offsetTop; 204 | const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight; 205 | 206 | // The element height and scroll height are the same, then we are still loading 207 | if (viewBottom !== navSidebar.scrollHeight) { 208 | // Determine if the item isn't visible and scroll to it 209 | if (elBottom >= viewBottom) { 210 | navSidebar.scrollTop = elBottom; 211 | } 212 | 213 | // stop observing now since we've completed the scroll 214 | resizeObserver.unobserve(navSidebar); 215 | } 216 | }); 217 | resizeObserver.observe(navSidebar); 218 | } 219 | } 220 | } 221 | }); 222 | -------------------------------------------------------------------------------- /_site/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://ddimmery.com/research.html 5 | 2022-05-19T11:03:33.252Z 6 | 7 | 8 | https://ddimmery.com/posts/softblock-demo/index.html 9 | 2022-05-19T11:03:34.368Z 10 | 11 | 12 | https://ddimmery.com/posts/quarto-website/index.html 13 | 2022-05-19T11:03:35.223Z 14 | 15 | 16 | https://ddimmery.com/index.html 17 | 2022-05-19T11:03:35.902Z 18 | 19 | 20 | https://ddimmery.com/about.html 21 | 2022-05-19T11:03:36.171Z 22 | 23 | 24 | https://ddimmery.com/software.html 25 | 2022-05-19T11:03:38.158Z 26 | 27 | 28 | https://ddimmery.com/cv.html 29 | 2022-05-19T11:03:38.415Z 30 | 31 | 32 | https://ddimmery.com/blog.html 33 | 2022-05-19T11:03:38.703Z 34 | 35 | 36 | -------------------------------------------------------------------------------- /_site/social-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/_site/social-card.jpg -------------------------------------------------------------------------------- /_site/software.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Drew Dimmery - Software 11 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 56 | 57 | 58 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |
    82 |
    83 | 113 |
    114 | 115 |
    116 | 117 | 118 | 129 | 130 |
    131 | 132 |
    133 |
    134 |

    Software

    135 |
    136 | 137 | 138 | 139 | 140 | 141 |
    142 | 143 | 144 | 145 |
    146 | 147 | 148 |
    149 | 150 |

    tidyhte

    151 |

    tidyhte provides tidy semantics for estimation of heterogeneous treatment effects through the use of Kennedy’s (n.d.) doubly-robust learner.
    152 | The goal of tidyhte is to use a sort of “recipe” design. This should (hopefully) make it extremely easy to scale an analysis of HTE from the common single-outcome / single-moderator case to many outcomes and many moderators. The configuration of tidyhte should make it extremely easy to perform the same analysis across many outcomes and for a wide-array of moderators. It’s written to be fairly easy to extend to different models and to add additional diagnostics and ways to output information from a set of HTE estimates.

    153 | 154 | 155 | Website 156 | 157 | 158 | Github 159 | 160 |

    regweight

    161 |

    The goal of regweight is to make it easy to diagnose a model using Aronow and Samii (2015) regression weights.
    162 | In short, these weights show which observations are most influential for determining the observed value of a coefficient in a linear regression. If the linear regression is aiming to estimate causal effects, this implies that the OLS estimand may differ from the average treatment effect. These linear regression weights provide, in some sense, the most precise estimate available given a conditioning set (and a linear model). These weights are in expectation the conditional variance of the variable of interest (given the other covariates in the model).

    163 | 164 | 165 | Website 166 | 167 | 168 | Github 169 | 170 | 171 | Package 172 | 173 |

    rdd

    174 |

    Outdated! Users should switch to actively maintained and updated RD tools.
    175 | Provides the tools to undertake estimation in Regression Discontinuity Designs. Both sharp and fuzzy designs are supported. Estimation is accomplished using local linear regression. A provided function will utilize Imbens-Kalyanaraman optimal bandwidth calculation. A function is also included to test the assumption of no-sorting effects.

    176 | 177 | 178 | Github 179 | 180 | 181 | Package 182 | 183 | 184 | 185 | 186 |
    187 | 266 |
    267 | 268 | 269 | 270 | -------------------------------------------------------------------------------- /_site/styles.css: -------------------------------------------------------------------------------- 1 | /* css styles */ 2 | -------------------------------------------------------------------------------- /about.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "About" 3 | --- 4 | 5 | I am the [Professor of Data Science for the Common Good](https://www.hertie-school.org/en/research/faculty-and-researchers/profile/person/dimmery) at the [Hertie School](https://www.hertie-school.org/en/)'s [Data Science Lab](https://www.hertie-school.org/en/datasciencelab). 6 | 7 | ### Research Interests 8 | 9 | - Causal Inference 10 | - Machine Learning 11 | - Data Science 12 | - Experimental Design 13 | 14 | ### Education 15 | 16 | ::: {.d-flex .justify-content-between} 17 | ::: {} 18 | **New York University** 19 | PhD in Political Methodology 20 | Advisors: Cyrus Samii, Neal Beck, Josh Tucker 21 | ::: 22 | ::: {.text-end} 23 | New York, NY 24 | Granted May 2016 25 | ::: 26 | ::: 27 | - Dissertation: *Essays on Causal Inference and Machine Learning with Application to Nonprofits* 28 | - Winner of 2015 Williams Award for Best Dissertation Proposal in Political Methodology from the Society of Political Methodology 29 | 30 | ::: {.d-flex .justify-content-between} 31 | ::: {} 32 | **UNC Chapel Hill** 33 | B.A. in International and Area Studies with distinction 34 | ::: 35 | ::: {.text-end} 36 | Chapel Hill, NC 37 | Granted June 2010 38 | ::: 39 | ::: 40 | 41 | ### Experience 42 | 43 | ::: {.d-flex .justify-content-between} 44 | ::: {} 45 | **Hertie School** 46 | ::: 47 | ::: {.text-end} 48 | January 2024 - present 49 | ::: 50 | ::: 51 | *Professor of Data Science for the Common Good* 52 | 53 | ::: {.d-flex .justify-content-between} 54 | ::: {} 55 | **University of Vienna** 56 | ::: 57 | ::: {.text-end} 58 | April 2021 - December 2023 59 | ::: 60 | ::: 61 | *Scientific Coordinator* 62 | 63 | - Supervisor: Philipp Grohs 64 | 65 | ::: {.d-flex .justify-content-between} 66 | ::: {} 67 | **Facebook Core Data Science** 68 | ::: 69 | ::: {.text-end} 70 | Sept 2016 - March 2021 71 | ::: 72 | ::: 73 | *Research Scientist* 74 | 75 | - Part of Eytan Bakshy's Adaptive Experimentation team 76 | - Developed statistical, machine learning and experimental methodology 77 | - Ran adaptive and contextual field experiments with a variety of product teams 78 | - Integrated advanced methodologies into a toolkit for scalable and automatic experimentation intended for optimization ([Ax](https://ax.dev/)) - [released at F8 2019](https://developers.facebook.com/videos/2019/product-optimization-with-adaptive-experimentation/)) 79 | - Developed scalable methods for robust observational causal inference as the technical lead of our "CausalML" initiative 80 | 81 | ::: {.d-flex .justify-content-between} 82 | ::: {} 83 | **Princeton University** 84 | ::: 85 | ::: {.text-end} 86 | September 2015 - May 2016 87 | ::: 88 | ::: 89 | *Pre-doctoral fellow* 90 | 91 | - Supervised by Kosuke Imai 92 | 93 | ::: {.d-flex .justify-content-between} 94 | ::: {} 95 | **Facebook Core Data Science** 96 | ::: 97 | ::: {.text-end} 98 | Summer 2015 99 | ::: 100 | ::: 101 | *Summer Intern* 102 | 103 | - Statistical and Decision Science Team 104 | - Supervised by Eytan Bakshy 105 | 106 | ### Teaching 107 | 108 | #### Facebook 109 | ::: {.d-flex .justify-content-between} 110 | ::: {} 111 | Internal datacamp class on designing and analyzing experiments 112 | ::: 113 | ::: {.text-end} 114 | 2017-2019 115 | ::: 116 | ::: 117 | 118 | #### NYU Undergraduate 119 | ::: {.d-flex .justify-content-between} 120 | ::: {} 121 | TA for Power and Politics in America (under Jonathan Nagler) 122 | ::: 123 | ::: {.text-end} 124 | Fall 2014 125 | ::: 126 | ::: 127 | 128 | ::: {.d-flex .justify-content-between} 129 | ::: {} 130 | TA for Games, Strategy and Politics (under Steven Brams) 131 | ::: 132 | ::: {.text-end} 133 | Fall 2013 134 | ::: 135 | ::: 136 | 137 | #### NYU Graduate 138 | 139 | ::: {.d-flex .justify-content-between} 140 | ::: {} 141 | TA for Quantitative Methods II (under Nathaniel Beck) 142 | ::: 143 | ::: {.text-end} 144 | Spring 2015 145 | ::: 146 | ::: 147 | 148 | ::: {.d-flex .justify-content-between} 149 | ::: {} 150 | TA for Quantitative Methods II (under Cyrus Samii) 151 | ::: 152 | ::: {.text-end} 153 | Spring 2014 154 | ::: 155 | ::: 156 | 157 | ::: {.d-flex .justify-content-between} 158 | ::: {} 159 | High Performance Computing Talk for NYU Datalab 160 | ::: 161 | ::: {.text-end} 162 | February 2014 163 | ::: 164 | ::: 165 | 166 | ::: {.d-flex .justify-content-between} 167 | ::: {} 168 | Introduction to R for NYU Datalab 169 | ::: 170 | ::: {.text-end} 171 | January 2013 172 | ::: 173 | ::: 174 | -------------------------------------------------------------------------------- /blog.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Blog" 3 | listing: 4 | contents: posts 5 | sort: "date desc" 6 | type: default 7 | categories: true 8 | feed: true 9 | --- -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/favicon.png -------------------------------------------------------------------------------- /headshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/headshot.jpg -------------------------------------------------------------------------------- /includes.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /index.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Drew Dimmery" 3 | description: "Methods in Causal Inference, Data Science and Social Science" 4 | page-layout: full 5 | image: /social-card.jpg 6 | resources: 7 | - "social-card.jpg" 8 | --- 9 | 10 | ::: {.column-page-inset-left} 11 | I am the [Professor of Data Science for the Common Good](https://www.hertie-school.org/en/research/faculty-and-researchers/profile/person/dimmery) at the [Hertie School](https://www.hertie-school.org/en/)'s [Data Science Lab](https://www.hertie-school.org/en/datasciencelab). 12 | 13 | I previously worked on the Adaptive Experimentation team at Facebook Core Data Science in New York, and at the Research Network Data Science at the University of Vienna. 14 | 15 | My research focuses on the intersection of machine learning and causal inference. I work a lot on experimental design and I think hard about how experimentation can be better and more efficient. I’m also interested in better applying the machinery of machine learning to observational causal inference. 16 | 17 | I’m most interested in methodological research useful for the study of social phenomena. 18 | ::: 19 | ::: {.column-margin} 20 | ![](headshot.jpg){.rounded} 21 | ::: 22 | 23 | {{< pagebreak >}} 24 | 25 | ::: {.column-page-inset .text-center} 26 | ```{=html} 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ``` 51 | ::: 52 | 53 | 54 | -------------------------------------------------------------------------------- /papers.yaml: -------------------------------------------------------------------------------- 1 | rl4real: 2 | title: "Real-world Video Adaptation with Reinforcement Learning" 3 | authors: 4 | - Hongzi Mao 5 | - Shannon Chen 6 | - me 7 | - Shaun Singh 8 | - Drew Blaisdell 9 | - Yuandong Tian 10 | - Mohammad Alizadeh 11 | - Eytan Bakshy 12 | year: 2019 13 | preprint: https://openreview.net/forum?id=SJlCkwN8iV 14 | published_url: 15 | venue: ICML Workshop - RL4RealLife 16 | github: 17 | safe_ts: 18 | title: "Thompson Sampling for Contextual Bandit Problems with Auxiliary Safety Constraints" 19 | authors: 20 | - Sam Daulton 21 | - Shaun Singh 22 | - Vashist Avadhanula 23 | - me 24 | - Eytan Bakshy 25 | year: 2019 26 | preprint: https://arxiv.org/abs/1911.00638 27 | venue: NeurIPS Workshop - Safety and Robustness in Decision Making 28 | homog_policy: 29 | title: "Experimentation for Homogenous Policy Change" 30 | authors: 31 | - Molly Offer-Westort 32 | - me 33 | year: 2021 34 | preprint: https://arxiv.org/abs/2101.12318 35 | calib_hte: 36 | title: Calibration of Heterogeneous Treatment Effects in Randomized Experiments 37 | authors: 38 | - Yan Leng 39 | - me 40 | year: 2024 41 | preprint: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3875850 42 | published_url: https://doi.org/10.1287/isre.2021.0343 43 | online_design: 44 | title: Online Balanced Experimental Design 45 | authors: 46 | - David Arbour 47 | - me 48 | - Tung Mai 49 | - Anup Rao 50 | published_url: https://proceedings.mlr.press/v162/arbour22a.html 51 | venue: ICML 52 | year: 2022 53 | preprint: https://arxiv.org/abs/2203.02025 54 | pi0: 55 | title: "A search for single photon events in neutrino interactions" 56 | authors: 57 | - C.T Kullenberg 58 | - S.R. Mishra 59 | - me 60 | - the NOMAD Collaboration 61 | published_url: https://doi.org/10.1016/j.physletb.2011.11.049 62 | venue: Physics Letters B 63 | year: 2012 64 | dark_money: 65 | title: "Shining the Light on Dark Money: Political Spending by Nonprofits" 66 | authors: 67 | - me 68 | - Andrew Peterson 69 | year: 2016 70 | published_url: https://doi.org/10.7758/RSF.2016.2.7.04 71 | venue: "RSF: The Russell Sage Foundation Journal of the Social Sciences" 72 | exp_eb: 73 | title: Shrinkage Estimators in Online Experiments 74 | authors: 75 | - me 76 | - Eytan Bakshy 77 | - Jasjeet Sekhon 78 | year: 2019 79 | venue: KDD 80 | preprint: https://arxiv.org/abs/1904.12918 81 | published_url: https://doi.org/10.1145/3292500.3330771 82 | bope: 83 | title: Balanced off-policy evaluation in general action spaces 84 | authors: 85 | - Arjun Sondhi 86 | - David Arbour 87 | - me 88 | year: 2020 89 | venue: AISTATS 90 | preprint: https://arxiv.org/abs/1906.03694 91 | published_url: https://proceedings.mlr.press/v108/sondhi20a.html 92 | pw: 93 | title: Permutation Weighting 94 | authors: 95 | - David Arbour 96 | - me 97 | - Arjun Sondhi 98 | year: 2021 99 | venue: ICML 100 | preprint: https://arxiv.org/abs/1901.01230 101 | published_url: https://proceedings.mlr.press/v139/arbour21a.html 102 | softblock: 103 | title: Efficient Balanced Treatment Assignments for Experimentation 104 | authors: 105 | - David Arbour 106 | - me 107 | - Anup Rao 108 | year: 2021 109 | venue: AISTATS 110 | preprint: https://arxiv.org/abs/2010.11332 111 | published_url: https://proceedings.mlr.press/v130/arbour21a.html 112 | github: https://github.com/ddimmery/softblock 113 | gen_exp: 114 | title: Designing Transportable Experiments Under S-admissability 115 | authors: 116 | - My Phan 117 | - David Arbour 118 | - me 119 | - Anup Rao 120 | year: 2021 121 | venue: AISTATS 122 | github: https://github.com/myphan9/Designing_Transportable_Experiments 123 | preprint: https://arxiv.org/abs/2009.03860 124 | published_url: https://proceedings.mlr.press/v130/phan21a.html 125 | interp_hte: 126 | title: "Distilling Heterogeneity: From Explanations of Heterogeneous Treatment Effect Models to Interpretable Policies" 127 | authors: 128 | - Han Wu 129 | - Sarah Tan 130 | - Weiwei Li 131 | - Mia Garrard 132 | - Adam Obeng 133 | - me 134 | - Shaun Singh 135 | - Hanson Wang 136 | - Daniel Jiang 137 | - Eytan Bakshy 138 | year: 2022 139 | preprint: https://arxiv.org/abs/2111.03267 140 | published_url: https://dl.acm.org/doi/10.1145/3534678.3539175 141 | chronofeed: 142 | title: "How do social media feed algorithms affect attitudes and behavior in an election campaign?" 143 | authors: 144 | - Andrew Guess 145 | - Neil Malhotra 146 | - Jennifer Pan 147 | - Pablo Barberá 148 | - Hunt Alcott 149 | - Taylor Brown 150 | - Adriana Crespo-Tenorio 151 | - me 152 | - Deen Freelon 153 | - Matthew Gentzkow 154 | - Sandra González-Bailón 155 | - Edward Kennedy 156 | - Young Mie Kim 157 | - David Lazer 158 | - Devra Moehler 159 | - Brendan Nyhan 160 | - Carlos Velasco Rivera 161 | - Jaime Settle 162 | - Daniel Thomas 163 | - Emily Thorson 164 | - Rebekah Tromble 165 | - Arjun Wilkins 166 | - Magdalena Wojcieszak 167 | - Beixian Xiong 168 | - Chad Kiewet de Jong 169 | - Annie Franco 170 | - Winter Mason 171 | - Natalie Jomini Stroud 172 | - Joshua Tucker 173 | year: 2023 174 | venue: Science 175 | published_url: https://doi.org/10.1126/science.abp9364 176 | reshares: 177 | title: "Reshares on social media amplify political news but do not detectably affect beliefs or opinions" 178 | authors: 179 | - Andrew Guess 180 | - Neil Malhotra 181 | - Jennifer Pan 182 | - Pablo Barberá 183 | - Hunt Alcott 184 | - Taylor Brown 185 | - Adriana Crespo-Tenorio 186 | - me 187 | - Deen Freelon 188 | - Matthew Gentzkow 189 | - Sandra González-Bailón 190 | - Edward Kennedy 191 | - Young Mie Kim 192 | - David Lazer 193 | - Devra Moehler 194 | - Brendan Nyhan 195 | - Carlos Velasco Rivera 196 | - Jaime Settle 197 | - Daniel Thomas 198 | - Emily Thorson 199 | - Rebekah Tromble 200 | - Arjun Wilkins 201 | - Magdalena Wojcieszak 202 | - Beixian Xiong 203 | - Chad Kiewet de Jong 204 | - Annie Franco 205 | - Winter Mason 206 | - Natalie Jomini Stroud 207 | - Joshua Tucker 208 | year: 2023 209 | venue: Science 210 | published_url: https://doi.org/10.1126/science.add8424 211 | likeminded: 212 | title: "Like-minded sources on Facebook are prevalent but not polarizing" 213 | authors: 214 | - Brendan Nyhan 215 | - Jaime Settle 216 | - Emily Thorson 217 | - Magdalena Wojcieszak 218 | - Pablo Barberá 219 | - Annie Chen 220 | - Hunt Alcott 221 | - Taylor Brown 222 | - Adriana Crespo-Tenorio 223 | - me 224 | - Deen Freelon 225 | - Matthew Gentzkow 226 | - Sandra González-Bailón 227 | - Andrew Guess 228 | - Edward Kennedy 229 | - Young Mie Kim 230 | - David Lazer 231 | - Neil Malhotra 232 | - Devra Moehler 233 | - Jennifer Pan 234 | - Daniel Thomas 235 | - Rebekah Tromble 236 | - Carlos Velasco Rivera 237 | - Arjun Wilkins 238 | - Beixian Xiong 239 | - Chad Kiewet de Jong 240 | - Annie Franco 241 | - Winter Mason 242 | - Natalie Jomini Stroud 243 | - Joshua Tucker 244 | year: 2023 245 | venue: Nature 246 | published_url: https://doi.org/10.1038/s41586-023-06297-w 247 | ms_repro: 248 | title: "Reproducibility in Management Science" 249 | authors: 250 | - Miloš Fišar 251 | - Ben Greiner 252 | - Christoph Huber 253 | - Elena Katok 254 | - Ali Ozkes 255 | - Management Science Reproducibility Collaboration 256 | year: 2023 257 | preprint: https://osf.io/preprints/osf/mydzv 258 | published_url: https://doi.org/10.1287/mnsc.2023.03556 259 | deactivation: 260 | title: "The effects of Facebook and Instagram on the 2020 election: A deactivation experiment" 261 | authors: 262 | - Hunt Allcott 263 | - Matthew Gentzkow 264 | - Winter Mason 265 | - Arjun Wilkins 266 | - Pablo Barberá 267 | - Taylor Brown 268 | - Juan Carlos Cisneros 269 | - Adriana Crespo-Tenorio 270 | - me 271 | - Deen Freelon 272 | - Sandra González-Bailón 273 | - Andrew M. Guess 274 | - Young Mie Kim 275 | - David Lazer 276 | - Neil Malhotra 277 | - Devra Moehler 278 | - Sameer Nair-Desai 279 | - Houda Nait El Barj 280 | - Brendan Nyhan 281 | - Ana Carolina Paixao de Queiroz 282 | - Jennifer Pan 283 | - Jaime Settle 284 | - Emily Thorson 285 | - Rebekah Tromble 286 | - Carlos Velasco Rivera 287 | - Benjamin Wittenbrink 288 | - Magdalena Wojcieszak 289 | - Saam Zahedian 290 | - Annie Franco 291 | - Chad Kiewiet de Jonge 292 | - Natalie Jomini Stroud 293 | - Joshua A. Tucker 294 | year: 2024 295 | venue: Proceedings of the National Academy of Sciences 296 | published_url: https://doi.org/10.1073/pnas.2321584121 297 | -------------------------------------------------------------------------------- /posts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/posts/.DS_Store -------------------------------------------------------------------------------- /posts/_metadata.yml: -------------------------------------------------------------------------------- 1 | # options apply to all posts in this folder 2 | 3 | # freeze computational output 4 | freeze: auto 5 | 6 | # Make a big title block 7 | title-block-banner: true 8 | 9 | # long dates 10 | date-format: long 11 | 12 | # smooth scroll 13 | smooth-scroll: true 14 | 15 | # Default author 16 | author: 17 | - name: Drew Dimmery 18 | url: https://ddimmery.com 19 | affiliation: Data Science @ University of Vienna 20 | affiliation-url: https://datascience.univie.ac.at/ 21 | 22 | # citation 23 | citation: true 24 | 25 | # Enable CC licence appendix 26 | license: "CC BY" -------------------------------------------------------------------------------- /posts/quarto-website/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/posts/quarto-website/.DS_Store -------------------------------------------------------------------------------- /posts/quarto-website/cv.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/posts/quarto-website/cv.pdf -------------------------------------------------------------------------------- /posts/quarto-website/tobias-meme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/posts/quarto-website/tobias-meme.jpg -------------------------------------------------------------------------------- /posts/softblock-demo/index_cache/html/__packages: -------------------------------------------------------------------------------- 1 | DT 2 | readr 3 | dplyr 4 | sf 5 | distances 6 | quickblock 7 | MASS 8 | purrr 9 | Matrix 10 | glmnet 11 | igraph 12 | FNN 13 | hash 14 | ggplot2 15 | -------------------------------------------------------------------------------- /posts/softblock-demo/index_files/figure-html/hte_plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/posts/softblock-demo/index_files/figure-html/hte_plot-1.png -------------------------------------------------------------------------------- /posts/softblock-demo/index_files/figure-html/plot_fx-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/posts/softblock-demo/index_files/figure-html/plot_fx-1.png -------------------------------------------------------------------------------- /posts/softblock-demo/index_files/figure-html/power_plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/posts/softblock-demo/index_files/figure-html/power_plot-1.png -------------------------------------------------------------------------------- /posts/softblock-demo/three-designs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/posts/softblock-demo/three-designs.jpg -------------------------------------------------------------------------------- /posts/sound-monitoring/index.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Monitoring Sound Levels" 3 | description: | 4 | Sometimes you have to learn basic principles of 5 | sound engineering in order to prove that you're a good 6 | neighbor. 7 | date: "2022-05-18" 8 | categories: 9 | - data science 10 | - misc 11 | code-fold: true 12 | image: /posts/quarto-website/tobias-meme.jpg 13 | draft: true 14 | --- 15 | 16 | # Prelude 17 | 18 | Austria cares about keeping things peaceful and quiet. In Vienna there's a law that quiet hours must be kept between 10pm and 6am every day, and the residents take this extremely seriously. As almost anyone from Vienna and they'll invariably have at least a story or two of their having the police called for a noise disturbance complaint. 19 | 20 | Approximately one day after we moved into our apartment, our neighbor complained to our property manager about the fact that we were too loud. For some additional context, our neighbor's window looks out just below our terrace. -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | jupyter 2 | pyyaml 3 | -------------------------------------------------------------------------------- /research.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Research" 3 | echo: false 4 | jupyter: python3 5 | section-divs: false 6 | keep-md: true 7 | format: html 8 | --- 9 | 10 | ```{python} 11 | import yaml 12 | from IPython.display import display, Markdown, HTML 13 | 14 | def readable_list(_s): 15 | if len(_s) < 3: 16 | return ' and '.join(map(str, _s)) 17 | *a, b = _s 18 | return f"{', '.join(map(str, a))}, and {b}" 19 | 20 | def button(url, str, icon): 21 | icon_base = icon[:2] 22 | return f""" 23 | 24 | {str} 25 | """ 26 | 27 | 28 | 29 | yaml_data = yaml.safe_load(open("papers.yaml")) 30 | pub_strs = {"pubs": {}, "wps": {}} 31 | for _, data in yaml_data.items(): 32 | title_str = data["title"] 33 | authors = data.get("authors", ["me"]) 34 | authors = [aut if aut != "me" else "Drew Dimmery" for aut in authors] 35 | author_str = readable_list(authors) 36 | year_str = data["year"] 37 | 38 | buttons = [] 39 | preprint = data.get("preprint") 40 | if preprint is not None: 41 | buttons.append(button(preprint, "Preprint", "bi-file-earmark-pdf")) 42 | 43 | github = data.get("github") 44 | if github is not None: 45 | buttons.append(button(github, "Github", "bi-github")) 46 | 47 | pub_url = data.get("published_url") 48 | venue = data.get("venue") 49 | working_paper = pub_url is None 50 | 51 | pub_str = f'{author_str}. ({year_str}) "{title_str}."' 52 | 53 | if venue is not None: 54 | pub_str += f" {venue}" 55 | 56 | if working_paper: 57 | if year_str not in pub_strs["wps"]: 58 | pub_strs["wps"][year_str] = [] 59 | pub_strs["wps"][year_str].append( 60 | "
  • " + pub_str + "
    " + " ".join(buttons) + "
  • " 61 | ) 62 | else: 63 | if year_str not in pub_strs["pubs"]: 64 | pub_strs["pubs"][year_str] = [] 65 | buttons.append(button(pub_url, "Published", "ai-archive")) 66 | pub_strs["pubs"][year_str].append( 67 | "
  • " + pub_str + "
    " + " ".join(buttons) + "
  • " 68 | ) 69 | ``` 70 | 71 | ## Published 72 | 73 | ```{python} 74 | #| label: "published-year" 75 | #| id: "published-year" 76 | #| output: asis 77 | for year in sorted(pub_strs["pubs"].keys(), reverse=True): 78 | display(Markdown(f"### {year}" + "{#" + f"published-{year}" + "}")) 79 | display(HTML( 80 | "
      " + '\n'.join(pub_strs["pubs"][year]) + "
    " 81 | )) 82 | ``` 83 | 84 | ## Working Papers / Non-archival 85 | 86 | ```{python} 87 | #| label: "not-published-year" 88 | #| id: "not-published-year" 89 | #| output: asis 90 | for year in sorted(pub_strs["wps"].keys(), reverse=True): 91 | display(Markdown(f"### {year}" + "{#" + f"not-published-{year}" + "}")) 92 | display(HTML( 93 | "
      " + '\n'.join(pub_strs["wps"][year]) + "
    " 94 | )) 95 | ``` 96 | -------------------------------------------------------------------------------- /site_libs/bootstrap/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/site_libs/bootstrap/bootstrap-icons.woff -------------------------------------------------------------------------------- /site_libs/clipboard/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v2.0.10 3 | * https://clipboardjs.com/ 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1.container-fluid.crosstalk-bscols{margin-left:auto;margin-right:auto}.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:inline-block;padding-right:12px;vertical-align:top}@media only screen and (max-width: 480px){.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:block;padding-right:inherit}}.crosstalk-input{margin-bottom:15px}.crosstalk-input .control-label{margin-bottom:0;vertical-align:middle}.crosstalk-input input[type="checkbox"]{margin:4px 0 0;margin-top:1px;line-height:normal}.crosstalk-input .checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.crosstalk-input .checkbox>label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.crosstalk-input .checkbox input[type="checkbox"],.crosstalk-input .checkbox-inline input[type="checkbox"]{position:absolute;margin-top:2px;margin-left:-20px}.crosstalk-input .checkbox+.checkbox{margin-top:-5px}.crosstalk-input .checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.crosstalk-input .checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px} 2 | -------------------------------------------------------------------------------- /site_libs/crosstalk-1.2.0/scss/crosstalk.scss: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | 29 | /* Relevant BS3 styles to make filter_checkbox() look reasonable without Bootstrap */ 30 | .crosstalk-input { 31 | margin-bottom: 15px; /* a la .form-group */ 32 | .control-label { 33 | margin-bottom: 0; 34 | vertical-align: middle; 35 | } 36 | input[type="checkbox"] { 37 | margin: 4px 0 0; 38 | margin-top: 1px; 39 | line-height: normal; 40 | } 41 | .checkbox { 42 | position: relative; 43 | display: block; 44 | margin-top: 10px; 45 | margin-bottom: 10px; 46 | } 47 | .checkbox > label{ 48 | padding-left: 20px; 49 | margin-bottom: 0; 50 | font-weight: 400; 51 | cursor: pointer; 52 | } 53 | .checkbox input[type="checkbox"], 54 | .checkbox-inline input[type="checkbox"] { 55 | position: absolute; 56 | margin-top: 2px; 57 | margin-left: -20px; 58 | } 59 | .checkbox + .checkbox { 60 | margin-top: -5px; 61 | } 62 | .checkbox-inline { 63 | position: relative; 64 | display: inline-block; 65 | padding-left: 20px; 66 | margin-bottom: 0; 67 | font-weight: 400; 68 | vertical-align: middle; 69 | cursor: pointer; 70 | } 71 | .checkbox-inline + .checkbox-inline { 72 | margin-top: 0; 73 | margin-left: 10px; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /site_libs/datatables-css-0.0.0/datatables-crosstalk.css: -------------------------------------------------------------------------------- 1 | .dt-crosstalk-fade { 2 | opacity: 0.2; 3 | } 4 | 5 | html body div.DTS div.dataTables_scrollBody { 6 | background: none; 7 | } 8 | 9 | 10 | /* 11 | Fix https://github.com/rstudio/DT/issues/563 12 | If the `table.display` is set to "block" (e.g., pkgdown), the browser will display 13 | datatable objects strangely. The search panel and the page buttons will still be 14 | in full-width but the table body will be "compact" and shorter. 15 | In therory, having this attributes will affect `dom="t"` 16 | with `display: block` users. But in reality, there should be no one. 17 | We may remove the below lines in the future if the upstream agree to have this there. 18 | See https://github.com/DataTables/DataTablesSrc/issues/160 19 | */ 20 | 21 | table.dataTable { 22 | display: table; 23 | } 24 | -------------------------------------------------------------------------------- /site_libs/dt-core-1.11.3/css/jquery.dataTables.extra.css: -------------------------------------------------------------------------------- 1 | /* Selected rows/cells */ 2 | table.dataTable tr.selected td, table.dataTable td.selected { 3 | background-color: #b0bed9 !important; 4 | } 5 | /* In case of scrollX/Y or FixedHeader */ 6 | .dataTables_scrollBody .dataTables_sizing { 7 | visibility: hidden; 8 | } 9 | 10 | /* The datatables' theme CSS file doesn't define 11 | the color but with white background. It leads to an issue that 12 | when the HTML's body color is set to 'white', the user can't 13 | see the text since the background is white. One case happens in the 14 | RStudio's IDE when inline viewing the DT table inside an Rmd file, 15 | if the IDE theme is set to "Cobalt". 16 | 17 | See https://github.com/rstudio/DT/issues/447 for more info 18 | 19 | This fixes should have little side-effects because all the other elements 20 | of the default theme use the #333 font color. 21 | 22 | TODO: The upstream may use relative colors for both the table background 23 | and the color. It means the table can display well without this patch 24 | then. At that time, we need to remove the below CSS attributes. 25 | */ 26 | div.datatables { 27 | color: #333; 28 | } 29 | -------------------------------------------------------------------------------- /site_libs/quarto-html/anchor.min.js: -------------------------------------------------------------------------------- 1 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 2 | // 3 | // AnchorJS - v4.3.1 - 2021-04-17 4 | // https://www.bryanbraun.com/anchorjs/ 5 | // Copyright (c) 2021 Bryan Braun; Licensed MIT 6 | // 7 | // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat 8 | !function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(this,function(){"use strict";return function(A){function d(A){A.icon=Object.prototype.hasOwnProperty.call(A,"icon")?A.icon:"",A.visible=Object.prototype.hasOwnProperty.call(A,"visible")?A.visible:"hover",A.placement=Object.prototype.hasOwnProperty.call(A,"placement")?A.placement:"right",A.ariaLabel=Object.prototype.hasOwnProperty.call(A,"ariaLabel")?A.ariaLabel:"Anchor",A.class=Object.prototype.hasOwnProperty.call(A,"class")?A.class:"",A.base=Object.prototype.hasOwnProperty.call(A,"base")?A.base:"",A.truncate=Object.prototype.hasOwnProperty.call(A,"truncate")?Math.floor(A.truncate):64,A.titleText=Object.prototype.hasOwnProperty.call(A,"titleText")?A.titleText:""}function w(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new TypeError("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],d(this.options),this.isTouchDevice=function(){return Boolean("ontouchstart"in window||window.TouchEvent||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(A){var e,t,o,i,n,s,a,c,r,l,h,u,p=[];if(d(this.options),"touch"===(l=this.options.visible)&&(l=this.isTouchDevice()?"always":"hover"),0===(e=w(A=A||"h2, h3, h4, h5, h6")).length)return this;for(null===document.head.querySelector("style.anchorjs")&&((u=document.createElement("style")).className="anchorjs",u.appendChild(document.createTextNode("")),void 0===(A=document.head.querySelector('[rel="stylesheet"],style'))?document.head.appendChild(u):document.head.insertBefore(u,A),u.sheet.insertRule(".anchorjs-link{opacity:0;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}",u.sheet.cssRules.length),u.sheet.insertRule(":hover>.anchorjs-link,.anchorjs-link:focus{opacity:1}",u.sheet.cssRules.length),u.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",u.sheet.cssRules.length),u.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',u.sheet.cssRules.length)),u=document.querySelectorAll("[id]"),t=[].map.call(u,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}}); 9 | // @license-end -------------------------------------------------------------------------------- /site_libs/quarto-html/quarto-syntax-highlighting.css: -------------------------------------------------------------------------------- 1 | /* quarto syntax highlight colors */ 2 | :root { 3 | --quarto-hl-ot-color: #8f5902; 4 | --quarto-hl-at-color: #c4a000; 5 | --quarto-hl-ss-color: #4e9a06; 6 | --quarto-hl-an-color: #8f5902; 7 | --quarto-hl-fu-color: #000000; 8 | --quarto-hl-st-color: #4e9a06; 9 | --quarto-hl-cf-color: #204a87; 10 | --quarto-hl-op-color: #ce5c00; 11 | --quarto-hl-er-color: #a40000; 12 | --quarto-hl-bn-color: #0000cf; 13 | --quarto-hl-al-color: #ef2929; 14 | --quarto-hl-va-color: #000000; 15 | --quarto-hl-ex-color: inherit; 16 | --quarto-hl-pp-color: #8f5902; 17 | --quarto-hl-in-color: #8f5902; 18 | --quarto-hl-vs-color: #4e9a06; 19 | --quarto-hl-wa-color: #8f5902; 20 | --quarto-hl-do-color: #8f5902; 21 | --quarto-hl-im-color: inherit; 22 | --quarto-hl-ch-color: #4e9a06; 23 | --quarto-hl-dt-color: #204a87; 24 | --quarto-hl-fl-color: #0000cf; 25 | --quarto-hl-co-color: #8f5902; 26 | --quarto-hl-cv-color: #8f5902; 27 | --quarto-hl-cn-color: #000000; 28 | --quarto-hl-sc-color: #000000; 29 | --quarto-hl-dv-color: #0000cf; 30 | --quarto-hl-kw-color: #204a87; 31 | } 32 | 33 | /* other quarto variables */ 34 | :root { 35 | --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 36 | } 37 | 38 | code span.ot { 39 | color: #8f5902; 40 | } 41 | 42 | code span.at { 43 | color: #c4a000; 44 | } 45 | 46 | code span.ss { 47 | color: #4e9a06; 48 | } 49 | 50 | code span.an { 51 | color: #8f5902; 52 | font-weight: bold; 53 | font-style: italic; 54 | } 55 | 56 | code span.fu { 57 | color: #000000; 58 | } 59 | 60 | code span.st { 61 | color: #4e9a06; 62 | } 63 | 64 | code span.cf { 65 | color: #204a87; 66 | font-weight: bold; 67 | } 68 | 69 | code span.op { 70 | color: #ce5c00; 71 | font-weight: bold; 72 | } 73 | 74 | code span.er { 75 | color: #a40000; 76 | font-weight: bold; 77 | } 78 | 79 | code span.bn { 80 | color: #0000cf; 81 | } 82 | 83 | code span.al { 84 | color: #ef2929; 85 | } 86 | 87 | code span.va { 88 | color: #000000; 89 | } 90 | 91 | code span.pp { 92 | color: #8f5902; 93 | font-style: italic; 94 | } 95 | 96 | code span.in { 97 | color: #8f5902; 98 | font-weight: bold; 99 | font-style: italic; 100 | } 101 | 102 | code span.vs { 103 | color: #4e9a06; 104 | } 105 | 106 | code span.wa { 107 | color: #8f5902; 108 | font-weight: bold; 109 | font-style: italic; 110 | } 111 | 112 | code span.do { 113 | color: #8f5902; 114 | font-weight: bold; 115 | font-style: italic; 116 | } 117 | 118 | code span.ch { 119 | color: #4e9a06; 120 | } 121 | 122 | code span.dt { 123 | color: #204a87; 124 | } 125 | 126 | code span.fl { 127 | color: #0000cf; 128 | } 129 | 130 | code span.co { 131 | color: #8f5902; 132 | font-style: italic; 133 | } 134 | 135 | code span.cv { 136 | color: #8f5902; 137 | font-weight: bold; 138 | font-style: italic; 139 | } 140 | 141 | code span.cn { 142 | color: #000000; 143 | } 144 | 145 | code span.sc { 146 | color: #000000; 147 | } 148 | 149 | code span.dv { 150 | color: #0000cf; 151 | } 152 | 153 | code span.kw { 154 | color: #204a87; 155 | font-weight: bold; 156 | } 157 | 158 | .prevent-inlining { 159 | content: ".tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} -------------------------------------------------------------------------------- /site_libs/quarto-html/zenscroll-min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"function"==typeof define&&define.amd?define([],e()):"object"==typeof module&&module.exports?module.exports=e():function n(){document&&document.body?t.zenscroll=e():setTimeout(n,9)}()}(this,function(){"use strict";var t=function(t){return t&&"getComputedStyle"in window&&"smooth"===window.getComputedStyle(t)["scroll-behavior"]};if("undefined"==typeof window||!("document"in window))return{};var e=function(e,n,o){n=n||999,o||0===o||(o=9);var i,r=function(t){i=t},u=function(){clearTimeout(i),r(0)},c=function(t){return Math.max(0,e.getTopOf(t)-o)},a=function(o,i,c){if(u(),0===i||i&&i<0||t(e.body))e.toY(o),c&&c();else{var a=e.getY(),f=Math.max(0,o)-a,s=(new Date).getTime();i=i||Math.min(Math.abs(f),n),function t(){r(setTimeout(function(){var n=Math.min(1,((new Date).getTime()-s)/i),o=Math.max(0,Math.floor(a+f*(n<.5?2*n*n:n*(4-2*n)-1)));e.toY(o),n<1&&e.getHeight()+os?f(t,n,i):u+o>d?a(u-s+o,n,i):i&&i()},l=function(t,n,o,i){a(Math.max(0,e.getTopOf(t)-e.getHeight()/2+(o||t.getBoundingClientRect().height/2)),n,i)};return{setup:function(t,e){return(0===t||t)&&(n=t),(0===e||e)&&(o=e),{defaultDuration:n,edgeOffset:o}},to:f,toY:a,intoView:s,center:l,stop:u,moving:function(){return!!i},getY:e.getY,getTopOf:e.getTopOf}},n=document.documentElement,o=function(){return window.scrollY||n.scrollTop},i=e({body:document.scrollingElement||document.body,toY:function(t){window.scrollTo(0,t)},getY:o,getHeight:function(){return window.innerHeight||n.clientHeight},getTopOf:function(t){return t.getBoundingClientRect().top+o()-n.offsetTop}});if(i.createScroller=function(t,o,i){return e({body:t,toY:function(e){t.scrollTop=e},getY:function(){return t.scrollTop},getHeight:function(){return Math.min(t.clientHeight,window.innerHeight||n.clientHeight)},getTopOf:function(t){return t.offsetTop}},o,i)},"addEventListener"in window&&!window.noZensmooth&&!t(document.body)){var r="history"in window&&"pushState"in history,u=r&&"scrollRestoration"in history;u&&(history.scrollRestoration="auto"),window.addEventListener("load",function(){u&&(setTimeout(function(){history.scrollRestoration="manual"},9),window.addEventListener("popstate",function(t){t.state&&"zenscrollY"in t.state&&i.toY(t.state.zenscrollY)},!1)),window.location.hash&&setTimeout(function(){var t=i.setup().edgeOffset;if(t){var e=document.getElementById(window.location.href.split("#")[1]);if(e){var n=Math.max(0,i.getTopOf(e)-t),o=i.getY()-n;0<=o&&o<9&&window.scrollTo(0,n)}}},9)},!1);var c=new RegExp("(^|\\s)noZensmooth(\\s|$)");window.addEventListener("click",function(t){for(var e=t.target;e&&"A"!==e.tagName;)e=e.parentNode;if(!(!e||1!==t.which||t.shiftKey||t.metaKey||t.ctrlKey||t.altKey)){if(u){var n=history.state&&"object"==typeof history.state?history.state:{};n.zenscrollY=i.getY();try{history.replaceState(n,"")}catch(t){}}var o=e.getAttribute("href")||"";if(0===o.indexOf("#")&&!c.test(e.className)){var a=0,f=document.getElementById(o.substring(1));if("#"!==o){if(!f)return;a=i.getTopOf(f)}t.preventDefault();var s=function(){window.location=o},l=i.setup().edgeOffset;l&&(a=Math.max(0,a-l),r&&(s=function(){history.pushState({},"",o)})),i.toY(a,null,s)}}},!1)}return i}); -------------------------------------------------------------------------------- /site_libs/quarto-listing/quarto-listing.js: -------------------------------------------------------------------------------- 1 | const kProgressiveAttr = "data-src"; 2 | let categoriesLoaded = false; 3 | 4 | window.quartoListingCategory = (category) => { 5 | if (categoriesLoaded) { 6 | activateCategory(category); 7 | setCategoryHash(category); 8 | } 9 | }; 10 | 11 | window["quarto-listing-loaded"] = () => { 12 | // Process any existing hash 13 | const hash = getHash(); 14 | 15 | if (hash) { 16 | // If there is a category, switch to that 17 | if (hash.category) { 18 | activateCategory(hash.category); 19 | } 20 | // Paginate a specific listing 21 | const listingIds = Object.keys(window["quarto-listings"]); 22 | for (const listingId of listingIds) { 23 | const page = hash[getListingPageKey(listingId)]; 24 | if (page) { 25 | showPage(listingId, page); 26 | } 27 | } 28 | } 29 | 30 | const listingIds = Object.keys(window["quarto-listings"]); 31 | for (const listingId of listingIds) { 32 | // The actual list 33 | const list = window["quarto-listings"][listingId]; 34 | 35 | // Update the handlers for pagination events 36 | refreshPaginationHandlers(listingId); 37 | 38 | // Render any visible items that need it 39 | renderVisibleProgressiveImages(list); 40 | 41 | // Whenever the list is updated, we also need to 42 | // attach handlers to the new pagination elements 43 | // and refresh any newly visible items. 44 | list.on("updated", function () { 45 | renderVisibleProgressiveImages(list); 46 | setTimeout(() => refreshPaginationHandlers(listingId)); 47 | 48 | // Show or hide the no matching message 49 | toggleNoMatchingMessage(list); 50 | }); 51 | } 52 | }; 53 | 54 | window.document.addEventListener("DOMContentLoaded", function (_event) { 55 | // Attach click handlers to categories 56 | const categoryEls = window.document.querySelectorAll( 57 | ".quarto-listing-category .category" 58 | ); 59 | 60 | for (const categoryEl of categoryEls) { 61 | const category = categoryEl.getAttribute("data-category"); 62 | categoryEl.onclick = () => { 63 | activateCategory(category); 64 | setCategoryHash(category); 65 | }; 66 | } 67 | 68 | // Attach a click handler to the category title 69 | // (there should be only one, but since it is a class name, handle N) 70 | const categoryTitleEls = window.document.querySelectorAll( 71 | ".quarto-listing-category-title" 72 | ); 73 | for (const categoryTitleEl of categoryTitleEls) { 74 | categoryTitleEl.onclick = () => { 75 | activateCategory(""); 76 | setCategoryHash(""); 77 | }; 78 | } 79 | 80 | categoriesLoaded = true; 81 | }); 82 | 83 | function toggleNoMatchingMessage(list) { 84 | const selector = `#${list.listContainer.id} .listing-no-matching`; 85 | const noMatchingEl = window.document.querySelector(selector); 86 | if (noMatchingEl) { 87 | if (list.visibleItems.length === 0) { 88 | noMatchingEl.classList.remove("d-none"); 89 | } else { 90 | if (!noMatchingEl.classList.contains("d-none")) { 91 | noMatchingEl.classList.add("d-none"); 92 | } 93 | } 94 | } 95 | } 96 | 97 | function setCategoryHash(category) { 98 | setHash({ category }); 99 | } 100 | 101 | function setPageHash(listingId, page) { 102 | const currentHash = getHash() || {}; 103 | currentHash[getListingPageKey(listingId)] = page; 104 | setHash(currentHash); 105 | } 106 | 107 | function getListingPageKey(listingId) { 108 | return `${listingId}-page`; 109 | } 110 | 111 | function refreshPaginationHandlers(listingId) { 112 | const listingEl = window.document.getElementById(listingId); 113 | const paginationEls = listingEl.querySelectorAll( 114 | ".pagination li.page-item:not(.disabled) .page.page-link" 115 | ); 116 | for (const paginationEl of paginationEls) { 117 | paginationEl.onclick = (sender) => { 118 | setPageHash(listingId, sender.target.getAttribute("data-i")); 119 | showPage(listingId, sender.target.getAttribute("data-i")); 120 | return false; 121 | }; 122 | } 123 | } 124 | 125 | function renderVisibleProgressiveImages(list) { 126 | // Run through the visible items and render any progressive images 127 | for (const item of list.visibleItems) { 128 | const itemEl = item.elm; 129 | if (itemEl) { 130 | const progressiveImgs = itemEl.querySelectorAll( 131 | `img[${kProgressiveAttr}]` 132 | ); 133 | for (const progressiveImg of progressiveImgs) { 134 | const srcValue = progressiveImg.getAttribute(kProgressiveAttr); 135 | if (srcValue) { 136 | progressiveImg.setAttribute("src", srcValue); 137 | } 138 | progressiveImg.removeAttribute(kProgressiveAttr); 139 | } 140 | } 141 | } 142 | } 143 | 144 | function getHash() { 145 | // Hashes are of the form 146 | // #name:value|name1:value1|name2:value2 147 | const currentUrl = new URL(window.location); 148 | const hashRaw = currentUrl.hash ? currentUrl.hash.slice(1) : undefined; 149 | return parseHash(hashRaw); 150 | } 151 | 152 | const kAnd = "&"; 153 | const kEquals = "="; 154 | 155 | function parseHash(hash) { 156 | if (!hash) { 157 | return undefined; 158 | } 159 | const hasValuesStrs = hash.split(kAnd); 160 | const hashValues = hasValuesStrs 161 | .map((hashValueStr) => { 162 | const vals = hashValueStr.split(kEquals); 163 | if (vals.length === 2) { 164 | return { name: vals[0], value: vals[1] }; 165 | } else { 166 | return undefined; 167 | } 168 | }) 169 | .filter((value) => { 170 | return value !== undefined; 171 | }); 172 | 173 | const hashObj = {}; 174 | hashValues.forEach((hashValue) => { 175 | hashObj[hashValue.name] = decodeURIComponent(hashValue.value); 176 | }); 177 | return hashObj; 178 | } 179 | 180 | function makeHash(obj) { 181 | return Object.keys(obj) 182 | .map((key) => { 183 | return `${key}${kEquals}${obj[key]}`; 184 | }) 185 | .join(kAnd); 186 | } 187 | 188 | function setHash(obj) { 189 | const hash = makeHash(obj); 190 | window.history.pushState(null, null, `#${hash}`); 191 | } 192 | 193 | function showPage(listingId, page) { 194 | const list = window["quarto-listings"][listingId]; 195 | if (list) { 196 | list.show((page - 1) * list.page + 1, list.page); 197 | } 198 | } 199 | 200 | function activateCategory(category) { 201 | // Deactivate existing categories 202 | const activeEls = window.document.querySelectorAll( 203 | ".quarto-listing-category .category.active" 204 | ); 205 | for (const activeEl of activeEls) { 206 | activeEl.classList.remove("active"); 207 | } 208 | 209 | // Activate this category 210 | const categoryEl = window.document.querySelector( 211 | `.quarto-listing-category .category[data-category='${category}'` 212 | ); 213 | if (categoryEl) { 214 | categoryEl.classList.add("active"); 215 | } 216 | 217 | // Filter the listings to this category 218 | filterListingCategory(category); 219 | } 220 | 221 | function filterListingCategory(category) { 222 | const listingIds = Object.keys(window["quarto-listings"]); 223 | for (const listingId of listingIds) { 224 | const list = window["quarto-listings"][listingId]; 225 | if (list) { 226 | if (category === "") { 227 | // resets the filter 228 | list.filter(); 229 | } else { 230 | // filter to this category 231 | list.filter(function (item) { 232 | const itemValues = item.values(); 233 | if (itemValues.categories !== null) { 234 | const categories = itemValues.categories.split(","); 235 | return categories.includes(category); 236 | } else { 237 | return false; 238 | } 239 | }); 240 | } 241 | } 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /site_libs/quarto-nav/headroom.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it 3 | * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js 4 | * License: MIT 5 | */ 6 | 7 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s}); 8 | -------------------------------------------------------------------------------- /site_libs/quarto-nav/quarto-nav.js: -------------------------------------------------------------------------------- 1 | const headroomChanged = new CustomEvent("quarto-hrChanged", { 2 | detail: {}, 3 | bubbles: true, 4 | cancelable: false, 5 | composed: false, 6 | }); 7 | 8 | window.document.addEventListener("DOMContentLoaded", function () { 9 | let init = false; 10 | 11 | function throttle(func, wait) { 12 | var timeout; 13 | return function () { 14 | const context = this; 15 | const args = arguments; 16 | const later = function () { 17 | clearTimeout(timeout); 18 | timeout = null; 19 | func.apply(context, args); 20 | }; 21 | 22 | if (!timeout) { 23 | timeout = setTimeout(later, wait); 24 | } 25 | }; 26 | } 27 | 28 | function headerOffset() { 29 | // Set an offset if there is are fixed top navbar 30 | const headerEl = window.document.querySelector("header.fixed-top"); 31 | if (headerEl) { 32 | return headerEl.clientHeight; 33 | } else { 34 | return 0; 35 | } 36 | } 37 | 38 | function footerOffset() { 39 | const footerEl = window.document.querySelector("footer.footer"); 40 | if (footerEl) { 41 | return footerEl.clientHeight; 42 | } else { 43 | return 0; 44 | } 45 | } 46 | 47 | function updateDocumentOffsetWithoutAnimation() { 48 | updateDocumentOffset(false); 49 | } 50 | 51 | function updateDocumentOffset(animated) { 52 | // set body offset 53 | const topOffset = headerOffset(); 54 | const bodyOffset = topOffset + footerOffset(); 55 | const bodyEl = window.document.body; 56 | bodyEl.setAttribute("data-bs-offset", topOffset); 57 | bodyEl.style.paddingTop = topOffset + "px"; 58 | 59 | // deal with sidebar offsets 60 | const sidebars = window.document.querySelectorAll( 61 | ".sidebar, .headroom-target" 62 | ); 63 | sidebars.forEach((sidebar) => { 64 | if (!animated) { 65 | sidebar.classList.add("notransition"); 66 | // Remove the no transition class after the animation has time to complete 67 | setTimeout(function () { 68 | sidebar.classList.remove("notransition"); 69 | }, 201); 70 | } 71 | 72 | if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) { 73 | sidebar.style.top = "0"; 74 | sidebar.style.maxHeight = "100vh"; 75 | } else { 76 | sidebar.style.top = topOffset + "px"; 77 | sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)"; 78 | } 79 | }); 80 | 81 | // allow space for footer 82 | const mainContainer = window.document.querySelector(".quarto-container"); 83 | if (mainContainer) { 84 | mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)"; 85 | } 86 | 87 | // link offset 88 | let linkStyle = window.document.querySelector("#quarto-target-style"); 89 | if (!linkStyle) { 90 | linkStyle = window.document.createElement("style"); 91 | window.document.head.appendChild(linkStyle); 92 | } 93 | while (linkStyle.firstChild) { 94 | linkStyle.removeChild(linkStyle.firstChild); 95 | } 96 | if (topOffset > 0) { 97 | linkStyle.appendChild( 98 | window.document.createTextNode(` 99 | section:target::before { 100 | content: ""; 101 | display: block; 102 | height: ${topOffset}px; 103 | margin: -${topOffset}px 0 0; 104 | }`) 105 | ); 106 | } 107 | if (init) { 108 | window.dispatchEvent(headroomChanged); 109 | } 110 | init = true; 111 | } 112 | 113 | // initialize headroom 114 | var header = window.document.querySelector("#quarto-header"); 115 | if (header && window.Headroom) { 116 | const headroom = new window.Headroom(header, { 117 | tolerance: 5, 118 | onPin: function () { 119 | const sidebars = window.document.querySelectorAll( 120 | ".sidebar, .headroom-target" 121 | ); 122 | sidebars.forEach((sidebar) => { 123 | sidebar.classList.remove("sidebar-unpinned"); 124 | }); 125 | updateDocumentOffset(); 126 | }, 127 | onUnpin: function () { 128 | const sidebars = window.document.querySelectorAll( 129 | ".sidebar, .headroom-target" 130 | ); 131 | sidebars.forEach((sidebar) => { 132 | sidebar.classList.add("sidebar-unpinned"); 133 | }); 134 | updateDocumentOffset(); 135 | }, 136 | }); 137 | headroom.init(); 138 | 139 | let frozen = false; 140 | window.quartoToggleHeadroom = function () { 141 | if (frozen) { 142 | headroom.unfreeze(); 143 | frozen = false; 144 | } else { 145 | headroom.freeze(); 146 | frozen = true; 147 | } 148 | }; 149 | } 150 | 151 | // Observe size changed for the header 152 | const headerEl = window.document.querySelector("header.fixed-top"); 153 | if (headerEl && window.ResizeObserver) { 154 | const observer = new window.ResizeObserver( 155 | throttle(updateDocumentOffsetWithoutAnimation, 50) 156 | ); 157 | observer.observe(headerEl, { 158 | attributes: true, 159 | childList: true, 160 | characterData: true, 161 | }); 162 | } else { 163 | window.addEventListener( 164 | "resize", 165 | throttle(updateDocumentOffsetWithoutAnimation, 50) 166 | ); 167 | setTimeout(updateDocumentOffsetWithoutAnimation, 500); 168 | } 169 | 170 | // fixup index.html links if we aren't on the filesystem 171 | if (window.location.protocol !== "file:") { 172 | const links = window.document.querySelectorAll("a"); 173 | for (let i = 0; i < links.length; i++) { 174 | links[i].href = links[i].href.replace(/\/index\.html/, "/"); 175 | } 176 | 177 | // Fixup any sharing links that require urls 178 | // Append url to any sharing urls 179 | const sharingLinks = window.document.querySelectorAll( 180 | "a.sidebar-tools-main-item" 181 | ); 182 | for (let i = 0; i < sharingLinks.length; i++) { 183 | const sharingLink = sharingLinks[i]; 184 | const href = sharingLink.getAttribute("href"); 185 | if (href) { 186 | sharingLink.setAttribute( 187 | "href", 188 | href.replace("|url|", window.location.href) 189 | ); 190 | } 191 | } 192 | 193 | // Scroll the active navigation item into view, if necessary 194 | const navSidebar = window.document.querySelector("nav#quarto-sidebar"); 195 | if (navSidebar) { 196 | // Find the active item 197 | const activeItem = navSidebar.querySelector("li.sidebar-item a.active"); 198 | if (activeItem) { 199 | // Wait for the scroll height and height to resolve by observing size changes on the 200 | // nav element that is scrollable 201 | const resizeObserver = new ResizeObserver((_entries) => { 202 | // The bottom of the element 203 | const elBottom = activeItem.offsetTop; 204 | const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight; 205 | 206 | // The element height and scroll height are the same, then we are still loading 207 | if (viewBottom !== navSidebar.scrollHeight) { 208 | // Determine if the item isn't visible and scroll to it 209 | if (elBottom >= viewBottom) { 210 | navSidebar.scrollTop = elBottom; 211 | } 212 | 213 | // stop observing now since we've completed the scroll 214 | resizeObserver.unobserve(navSidebar); 215 | } 216 | }); 217 | resizeObserver.observe(navSidebar); 218 | } 219 | } 220 | } 221 | }); 222 | -------------------------------------------------------------------------------- /social-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddimmery/quarto-website/b51f29032f85957da7dc47edc401caec91a99b38/social-card.jpg -------------------------------------------------------------------------------- /software.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Software" 3 | echo: false 4 | jupyter: python3 5 | section-divs: false 6 | --- 7 | 8 | ```{python} 9 | #| label: "software" 10 | #| id: "software" 11 | #| output: asis 12 | import yaml 13 | from IPython.display import display, Markdown, HTML 14 | 15 | def button(url, str, icon): 16 | icon_base = icon[:2] 17 | return f""" 18 | 19 | {str} 20 | """ 21 | 22 | yaml_data = yaml.safe_load(open("software.yaml")) 23 | 24 | for data in yaml_data[::-1]: 25 | display(Markdown("## `" + data["title"] + "` {#" + data["title"] + "}")) 26 | display(Markdown(data["description"])) 27 | buttons = [] 28 | if "website" in data: 29 | buttons.append(button(data['website'], "Website", "bi-info")) 30 | if "github" in data: 31 | buttons.append(button(data['github'], "Github", "bi-github")) 32 | if "package" in data: 33 | buttons.append(button(data['package'], "Package", "bi-box-seam")) 34 | 35 | display(HTML(" ".join(buttons))) 36 | ``` -------------------------------------------------------------------------------- /software.yaml: -------------------------------------------------------------------------------- 1 | - title: "rdd" 2 | description: | 3 | **Outdated!** Users should switch to [actively maintained and updated RD tools](https://rdpackages.github.io/). 4 | Provides the tools to undertake estimation in Regression Discontinuity Designs. Both sharp and fuzzy designs are supported. Estimation is accomplished using local linear regression. A provided function will utilize Imbens-Kalyanaraman optimal bandwidth calculation. A function is also included to test the assumption of no-sorting effects. 5 | github: https://github.com/ddimmery/rdd 6 | package: https://cran.r-project.org/package=rdd 7 | - title: "regweight" 8 | description: | 9 | The goal of `regweight` is to make it easy to diagnose a model using Aronow and Samii (2015) regression weights. 10 | In short, these weights show which observations are most influential for determining the observed value of a coefficient in a linear regression. If the linear regression is aiming to estimate causal effects, this implies that the OLS estimand may differ from the average treatment effect. These linear regression weights provide, in some sense, the most precise estimate available given a conditioning set (and a linear model). These weights are in expectation the conditional variance of the variable of interest (given the other covariates in the model). 11 | website: https://ddimmery.github.io/regweight/ 12 | github: https://github.com/ddimmery/regweight 13 | package: https://cran.r-project.org/package=regweight 14 | - title: "tidyhte" 15 | description: | 16 | `tidyhte` provides tidy semantics for estimation of heterogeneous treatment effects through the use of Kennedy's (n.d.) doubly-robust learner. 17 | The goal of `tidyhte` is to use a sort of “recipe” design. This should (hopefully) make it extremely easy to scale an analysis of HTE from the common single-outcome / single-moderator case to many outcomes and many moderators. The configuration of `tidyhte` should make it extremely easy to perform the same analysis across many outcomes and for a wide-array of moderators. It’s written to be fairly easy to extend to different models and to add additional diagnostics and ways to output information from a set of HTE estimates. 18 | website: https://ddimmery.github.io/tidyhte/ 19 | github: https://github.com/ddimmery/tidyhte -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | /* css styles */ 2 | --------------------------------------------------------------------------------