From 0ff52b71f2c0e970b1f0d43793c019bbed93e112 Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Wed, 27 Dec 2023 11:23:52 +0100 Subject: [chore] Refactor HTML templates and CSS (#2480) * [chore] Refactor HTML templates and CSS * eslint * ignore "Local" * rss tests * fiddle with OG just a tiny bit * dick around with polls a bit more so SR stops saying "clickable" * remove break * oh lord * don't lazy load avatar * fix ogmeta tests * clean up some cruft * catch remaining calls to c.HTML * fix error rendering + stack overflow in tag * allow templating attributes * fix indent * set aria-hidden on status complementary content, since it's already present in the label anyway * tidy up templating calls a little * try to make styling a bit more consistent + readable * fix up some remaining CSS issues * fix up reports --- web/source/.eslintignore | 4 +- web/source/css/_colors.css | 8 +- web/source/css/about.css | 39 ++ web/source/css/base.css | 560 +++++++++++------------- web/source/css/index.css | 89 +++- web/source/css/page.css | 107 +++++ web/source/css/prism.css | 5 + web/source/css/profile.css | 220 +++++----- web/source/css/status.css | 252 ++++++----- web/source/css/thread.css | 56 +++ web/source/frontend/index.js | 4 + web/source/frontend/prism.js | 42 ++ web/source/settings/admin/reports/detail.jsx | 42 +- web/source/settings/admin/reports/index.jsx | 2 +- web/source/settings/components/fake-profile.jsx | 29 +- web/source/settings/components/fake-toot.jsx | 33 +- web/source/settings/style.css | 89 +++- web/template/404.tmpl | 40 +- web/template/about.tmpl | 220 ++++++---- web/template/authorize.tmpl | 44 +- web/template/confirmed.tmpl | 13 +- web/template/domain-blocklist.tmpl | 62 +-- web/template/error.tmpl | 22 +- web/template/finalize.tmpl | 59 ++- web/template/footer.tmpl | 46 -- web/template/frontend.tmpl | 7 +- web/template/header.tmpl | 122 ------ web/template/index.tmpl | 74 +--- web/template/index_apps.tmpl | 115 +++++ web/template/oob.tmpl | 14 +- web/template/page.tmpl | 85 ++++ web/template/page_footer.tmpl | 67 +++ web/template/page_header.tmpl | 72 +++ web/template/page_ogmeta.tmpl | 57 +++ web/template/page_stylesheets.tmpl | 41 ++ web/template/profile.tmpl | 242 +++++----- web/template/profile_fields.tmpl | 32 ++ web/template/sign-in.tmpl | 10 +- web/template/status.tmpl | 154 +++---- web/template/status_attachments.tmpl | 184 +++++--- web/template/status_attributes.tmpl | 55 +++ web/template/status_header.tmpl | 56 +++ web/template/status_info.tmpl | 74 ++++ web/template/status_poll.tmpl | 105 +++-- web/template/tag.tmpl | 16 +- web/template/thread.tmpl | 59 ++- 46 files changed, 2297 insertions(+), 1431 deletions(-) create mode 100644 web/source/css/about.css create mode 100644 web/source/css/page.css create mode 100644 web/source/css/prism.css create mode 100644 web/source/css/thread.css create mode 100644 web/source/frontend/prism.js delete mode 100644 web/template/footer.tmpl delete mode 100644 web/template/header.tmpl create mode 100644 web/template/index_apps.tmpl create mode 100644 web/template/page.tmpl create mode 100644 web/template/page_footer.tmpl create mode 100644 web/template/page_header.tmpl create mode 100644 web/template/page_ogmeta.tmpl create mode 100644 web/template/page_stylesheets.tmpl create mode 100644 web/template/profile_fields.tmpl create mode 100644 web/template/status_attributes.tmpl create mode 100644 web/template/status_header.tmpl create mode 100644 web/template/status_info.tmpl (limited to 'web') diff --git a/web/source/.eslintignore b/web/source/.eslintignore index b512c09d4..46d39d131 100644 --- a/web/source/.eslintignore +++ b/web/source/.eslintignore @@ -1 +1,3 @@ -node_modules \ No newline at end of file +node_modules +prism.js +prism.css \ No newline at end of file diff --git a/web/source/css/_colors.css b/web/source/css/_colors.css index 79acf988c..87022c559 100644 --- a/web/source/css/_colors.css +++ b/web/source/css/_colors.css @@ -82,11 +82,11 @@ $button-danger-bg: $error3; $button-danger-fg: $white1; $button-danger-hover-bg: $error2; -$toot-bg: $gray3; -$toot-info-bg: $gray2; +$status-bg: $gray3; +$status-info-bg: $gray2; -$toot-focus-bg: $gray5; -$toot-focus-info-bg: $gray4; +$status-focus-bg: $gray5; +$status-focus-info-bg: $gray4; $no-img-desc-bg: $orange1; $no-img-desc-fg: $gray1; diff --git a/web/source/css/about.css b/web/source/css/about.css new file mode 100644 index 000000000..55318572c --- /dev/null +++ b/web/source/css/about.css @@ -0,0 +1,39 @@ +/* + GoToSocial + Copyright (C) 2021-2023 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +.about { + display: flex; + flex-direction: column; + gap: 2rem; + padding: 2rem; + + background: $bg-accent; + box-shadow: $boxshadow; + border: $boxshadow-border; + border-radius: $br; + + .about-section { + ul, ol { + margin-top: 0; + } + + h3, h4 { + margin-top: 0; + } + } +} diff --git a/web/source/css/base.css b/web/source/css/base.css index 5cd2cd047..0d3c436c8 100644 --- a/web/source/css/base.css +++ b/web/source/css/base.css @@ -20,35 +20,52 @@ /* noto-sans-regular - latin */ @font-face { - font-family: "Noto Sans"; - font-weight: 400; - font-display: swap; - font-style: normal; - src: url('../fonts/noto-sans-v27-latin-regular.woff2') format('woff2'), - url('../fonts/noto-sans-v27-latin-regular.woff') format('woff'); + font-family: "Noto Sans"; + font-weight: 400; + font-display: swap; + font-style: normal; + src: url('../fonts/noto-sans-v27-latin-regular.woff2') format('woff2'), + url('../fonts/noto-sans-v27-latin-regular.woff') format('woff'); } /* noto-sans-700 - latin */ @font-face { - font-family: "Noto Sans"; - font-weight: 700; - font-display: swap; - font-style: normal; - src: url('../fonts/noto-sans-v27-latin-700.woff2') format('woff2'), - url('../fonts/noto-sans-v27-latin-700.woff') format('woff'); + font-family: "Noto Sans"; + font-weight: 700; + font-display: swap; + font-style: normal; + src: url('../fonts/noto-sans-v27-latin-700.woff2') format('woff2'), + url('../fonts/noto-sans-v27-latin-700.woff') format('woff'); } -/* standard border radius for nice squircles */ +/************************************* +***** SECTION 1: HANDY VARIABLES ***** +**************************************/ + +/* + Standard border radius + for nice squircles. +*/ $br: 0.4rem; -/* border radius for items that are framed/bordered - inside something with $br, eg avatar, header img */ + +/* + Border radius for items that + are framed/bordered inside + something with $br, eg avatar, + header img, etc. +*/ $br-inner: 0.2rem; -/* Fork-Awesome 'fa-fw' fixed icon width - keep in sync with https://github.com/ForkAwesome/Fork-Awesome/blob/a99579ae3e735ee70e51ed62dfcee3172b5b2db7/css/fork-awesome.css#L50 +/* + Fork-Awesome 'fa-fw' fixed icon width; + keep in sync with https://github.com/ForkAwesome/Fork-Awesome/blob/a99579ae3e735ee70e51ed62dfcee3172b5b2db7/css/fork-awesome.css#L50 */ $fa-fw: 1.28571429em; +/****************************************** +***** SECTION 2: BASIC GLOBAL STYLING ***** +*******************************************/ + html, body { padding: 0; margin: 0; @@ -63,90 +80,28 @@ body { position: relative; } -.hidden { - display: none; -} - -.page { - display: grid; - min-height: 100vh; - - grid-template-columns: 1fr minmax(auto, 50rem) 1fr; - grid-template-columns: 1fr min(92%, 50rem) 1fr; - grid-template-rows: auto 1fr auto; -} - -h1 { - margin: 0; - line-height: 2.4rem; -} - a { color: $link-fg; } -header, footer { - grid-column: 1 / span 3; -} - -.content { - grid-column: 2; - align-self: start; -} - -header { - display: flex; - justify-content: center; -} - -header a { - display: flex; - flex-wrap: wrap; - margin: 1.5rem; - gap: 1rem; - justify-content: center; - - img { - align-self: center; - height: 3rem; - } - - h1 { - flex-grow: 1; - align-self: center; - text-align: center; - - font-size: 1.5rem; - word-wrap: anywhere; - color: $fg; - } -} - -.excerpt-top { - margin-bottom: 2rem; - font-style: italic; - font-weight: normal; - text-align: center; - font-size: 1.2rem; - - .count { - font-weight: bold; - color: $fg-accent; - } -} - +/* + Normalize margins of first and last children. + We generally don't want to open a paragraph or + paragraph-like element with a top margin or + close it with a bottom margin. +*/ main { - p:first-child { + p:first-child, ol:first-child, ul:first-child { margin-top: 0; } - p:last-child { + p:last-child, ol:last-child, ul:last-child { margin-bottom: 0; } } .button, button { - border-radius: 0.2rem; + border-radius: $br-inner; color: $button-fg; background: $button-bg; box-shadow: $boxshadow; @@ -184,6 +139,166 @@ main { } } +/* + Form styling - used in settings frontend as well. +*/ +input, select, textarea, .input { + box-sizing: border-box; + border: 0.15rem solid $input-border; + border-radius: 0.1rem; + color: $fg; + background: $input-bg; + width: 100%; + font-family: 'Noto Sans', sans-serif; + font-size: 1rem; + padding: 0.3rem; + + &:focus, &:active { + border-color: $input-focus-border; + } + + &:invalid, .invalid & { + border-color: $input-error-border; + } + + &:disabled { + background: transparent; + } + + &::placeholder { + opacity: 1; + color: $fg-reduced + } +} + +/* + Squeeze emojis so they fit inline in text. +*/ +.emoji { + width: 1.45em; + height: 1.45em; + margin: -0.2em 0.02em 0; + object-fit: contain; + vertical-align: middle; + transition: 0.1s; + + /* + Enlarge emojis on hover to give + viewer a good look at them. + */ + &:hover, &:active { + transform: scale(2); + background-color: $bg; + box-shadow: $boxshadow; + border: $boxshadow-border; + border-radius: $br-inner; + } +} + +/* + Restyle unordered lists; outdent + and replace dot with orange dot. +*/ +ul { + padding-left: 2.5rem; + list-style: none; + + li::before { + content: "\2022"; + color: $border-accent; + font-weight: bold; + display: inline-block; + width: 1.5rem; + margin-left: -1.5rem; + } +} + +/* + Mirror the same styling a little bit + for ordered lists by making marker bold. +*/ +ol { + padding-left: 2.5rem; + + li::marker { + font-weight: bold; + } +} + +/* + Outdent block quotes a bit; use + orange stripe for left border. +*/ +blockquote { + padding: 0.5rem 0 0.5rem 0.5rem; + border-left: 0.2rem solid $border-accent; + margin: 0; + font-style: italic; +} + +/* + Nice dashed orange line + for horizontal rules. +*/ +hr { + border: 0; + border-top: 1px dashed $border-accent; +} + +/* + Don't indent definition + lists and definitions. +*/ +dl { + margin: 0; + + dd { + margin-left: 0; + } +} + +label { + cursor: pointer; +} + +/************************************* +***** SECTION 3: UTILITY CLASSES ***** +**************************************/ + +/* + Column header that appears at the top + of threads, at the top of sections of + profiles (About, Pinned Posts, etc). +*/ +.col-header { + display: grid; + grid-template-columns: auto 1fr; + gap: 1rem; + + justify-content: start; + align-items: center; + + margin: 0; + background: $profile-bg; + border-top-left-radius: $br; + border-top-right-radius: $br; + padding: 0.75rem; + + a { + justify-self: end; + } + + h1, h2, h3, h4 { + font-size: 1.2rem; + line-height: 1.3rem; + margin: 0; + } +} + +.hidden { + display: none; +} + .nounderline { text-decoration: none; } @@ -192,57 +307,37 @@ main { color: $acc1; } -.logo { - justify-self: center; - img { - height: 30vh; - } +.text-cutoff { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; } -section.apps { - align-self: start; - - .applist { - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: 0.5rem; - align-content: start; - - .entry { - display: grid; - grid-template-columns: 25% 1fr; - gap: 1.5rem; - padding: 0.5rem; - background: $bg-accent; - border-radius: 0.5rem; - - .logo { - align-self: center; - width: 100%; - object-fit: contain; - flex: 1 1 auto; - } - - .logo.redraw { - fill: $fg; - stroke: $fg; - } - - a { - font-weight: bold; - } - - div { - padding: 0; - h3 { - margin-top: 0; - } - } - } +/* + Class for lists that don't + want the orange dot. +*/ +.nodot { + li::before { + content: initial; } } -section.login { +/*********************************** +***** SECTION 4: SHAMEFUL MESS ***** +************************************/ + +/* + EVERYTHING BELOW THIS POINT: + Should be moved somewhere else + to avoid cluttering up this file. +*/ + +/* + Below section stylings are used + in transient/error templates. +*/ +section.sign-in { form { display: flex; flex-direction: column; @@ -291,98 +386,11 @@ section.oob-token { } } -.error-text { - color: $error1; - background: $error2; - border-radius: 0.1rem; - font-weight: bold; -} - -input, select, textarea, .input { - box-sizing: border-box; - border: 0.15rem solid $input-border; - border-radius: 0.1rem; - color: $fg; - background: $input-bg; - width: 100%; - font-family: 'Noto Sans', sans-serif; - font-size: 1rem; - padding: 0.3rem; - - &:focus, &:active { - border-color: $input-focus-border; - } - - &:invalid, .invalid & { - border-color: $input-error-border; - } - - &:disabled { - background: transparent; - } -} - -::placeholder { - opacity: 1; - color: $fg-reduced -} - -hr { - color: transparent; - width: 100%; - border-bottom: 0.02rem solid $border-accent; -} - -footer { - align-self: end; - padding: 2rem 0 1rem 0; - - display: flex; - flex-wrap: wrap; - justify-content: center; - - div { - text-align: center; - padding: 1rem; - flex-grow: 1; - } - - a { - font-weight: bold; - } -} - -@media screen and (max-width: 600px) { - header { - text-align: center; - } - - footer { - grid-template-columns: 1fr; - - div { - text-align: initial; - width: 100%; - } - } - - section.apps .applist { - grid-template-columns: 1fr; - } -} - -.emoji { - width: 1.45em; - height: 1.45em; - margin: -0.2em 0.02em 0; - object-fit: contain; - vertical-align: middle; -} - -.monospace { - font-family: monospace; -} - +/* + TODO: This is only used in the "finalize" + template for new signups; move this elsewhere + when that stuff is finished up. +*/ .callout { margin: 1.5rem 0; border: .05rem solid $border-accent; @@ -397,22 +405,11 @@ footer { } } -label { - cursor: pointer; -} - -@media (prefers-reduced-motion) { - .fa-spin { - animation: none; - } -} - -.text-cutoff { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - +/* + TODO: list and blocklist are only used + in settings panel and on blocklist page; + consider moving them somewhere else. +*/ .list { display: flex; flex-direction: column; @@ -495,21 +492,18 @@ label { } } -.about { - display: flex; - flex-direction: column; - gap: 1rem; - - h2 { - margin: 0.5rem 0; - } - - ul { - margin-bottom: 0; +@media screen and (max-width: 30rem) { + .domain-blocklist .entry { + grid-template-columns: 1fr; + gap: 0; } - } +/* + TODO: this is only used on About + page and in settings application; + consider moving it somewhere else. +*/ .account-card { display: inline-grid; grid-template-columns: auto 1fr; @@ -541,61 +535,3 @@ label { grid-row: 1 / span 2; } } - -.instance-rules { - list-style-position: inside; - margin: 0; - padding: 0; - - a.rule { - display: grid; - grid-template-columns: 1fr auto; - align-items: center; - color: $fg; - text-decoration: none; - background: $toot-bg; - padding: 1rem; - margin: 0.5rem 0; - border-radius: $br; - line-height: 2rem; - position: relative; - - &:hover { - color: $fg-accent; - - .edit-icon { - display: inline; - } - } - - .edit-icon { - display: none; - font-size: 1rem; - line-height: 1.5rem; - } - - li { - font-size: 1.75rem; - padding: 0; - margin: 0; - - h2 { - margin: 0; - margin-top: 0 !important; - display: inline-block; - font-size: 1.5rem; - } - } - - span { - color: $fg-reduced; - } - } -} - -@media screen and (max-width: 30rem) { - .domain-blocklist .entry { - grid-template-columns: 1fr; - gap: 0; - } -} \ No newline at end of file diff --git a/web/source/css/index.css b/web/source/css/index.css index b4ad1bd1c..4ea3b78e1 100644 --- a/web/source/css/index.css +++ b/web/source/css/index.css @@ -16,26 +16,85 @@ along with this program. If not, see . */ -header a { - margin: 2rem; +/* + Render instance title a + bit bigger on index page. +*/ +.page-header a h1 { + font-size: 2rem; + line-height: 2rem; +} + +/* + Reuse about styling, but rework it + to separate sections a bit more. +*/ +.about { + display: flex; + flex-direction: column; gap: 2rem; + padding: 0; + + background: initial; + box-shadow: initial; + border: initial; + border-radius: initial; - img { - height: 6rem; + .about-section { + padding: 2rem; + background: $bg-accent; + box-shadow: $boxshadow; + border: $boxshadow-border; + border-radius: $br; } +} - h1 { - font-size: 2rem; +.apps { + align-self: start; + + .applist { + margin: 0; + padding: 0; + + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 0.5rem; + align-content: start; + + .applist-entry { + display: grid; + grid-template-columns: 25% 1fr; + grid-template-areas: "logo text"; + gap: 1.5rem; + padding: 0.5rem; + + .applist-logo { + grid-area: logo; + align-self: center; + justify-self: center; + width: 100%; + object-fit: contain; + flex: 1 1 auto; + } + + .applist-logo.redraw { + fill: $fg; + stroke: $fg; + } + + .applist-text { + grid-area: text; + + a { + font-weight: bold; + } + } + } } } -main { - section { - background: $bg-accent; - box-shadow: $boxshadow; - border: $boxshadow-border; - border-radius: $br; - padding: 2rem; - margin-bottom: 2rem; +@media screen and (max-width: 600px) { + .apps .applist { + grid-template-columns: 1fr; } -} \ No newline at end of file +} diff --git a/web/source/css/page.css b/web/source/css/page.css new file mode 100644 index 000000000..d60dbe9c8 --- /dev/null +++ b/web/source/css/page.css @@ -0,0 +1,107 @@ +/* + GoToSocial + Copyright (C) 2021-2023 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +.page { + display: grid; + min-height: 100vh; + + grid-template-columns: 1fr minmax(auto, 50rem) 1fr; + grid-template-columns: 1fr min(92%, 50rem) 1fr; + grid-template-rows: auto 1fr auto; +} + +.page-header, .page-footer { + grid-column: 1 / span 3; +} + +.page-content { + grid-column: 2; + align-self: start; +} + +.page-header { + display: flex; + flex-direction: column; + justify-content: center; + padding: 1.5rem; + gap: 1rem; + + a { + display: flex; + flex-wrap: wrap; + gap: 1rem; + justify-content: center; + + img { + align-self: center; + } + + h1 { + align-self: center; + text-align: center; + + font-size: 1.5rem; + line-height: 1.5rem; + word-wrap: anywhere; + color: $fg; + } + } + + aside { + margin: 0; + font-style: italic; + font-weight: normal; + text-align: center; + font-size: 1.2rem; + + .count { + font-weight: bold; + color: $fg-accent; + } + } +} + +.page-footer { + align-self: end; + + nav ul { + display: flex; + flex-wrap: wrap; + justify-content: space-around; + + /* Override list styling */ + list-style-type: none; + padding-left: 0; + + li { + text-align: center; + padding: 1rem; + flex-grow: 1; + + a { + font-weight: bold; + } + } + } +} + +@media screen and (max-width: 600px) { + .page-header { + text-align: center; + } +} diff --git a/web/source/css/prism.css b/web/source/css/prism.css new file mode 100644 index 000000000..c1d369a9c --- /dev/null +++ b/web/source/css/prism.css @@ -0,0 +1,5 @@ +/* PrismJS 1.29.0 +https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+bash+c+csharp+cpp+docker+elixir+erlang+go+go-module+ini+java+json+kotlin+lua+makefile+markup-templating+nginx+nix+perl+php+promql+python+r+jsx+tsx+ruby+rust+scala+sql+swift+typescript&plugins=show-invisibles+show-language+toolbar+copy-to-clipboard */ +code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green} +.token.cr,.token.lf,.token.space,.token.tab:not(:empty){position:relative}.token.cr:before,.token.lf:before,.token.space:before,.token.tab:not(:empty):before{color:grey;opacity:.6;position:absolute}.token.tab:not(:empty):before{content:'\21E5'}.token.cr:before{content:'\240D'}.token.crlf:before{content:'\240D\240A'}.token.lf:before{content:'\240A'}.token.space:before{content:'\00B7'} +div.code-toolbar{position:relative}div.code-toolbar>.toolbar{position:absolute;z-index:10;top:.3em;right:.2em;transition:opacity .3s ease-in-out;opacity:0}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{color:#bbb;font-size:.8em;padding:0 .5em;background:#f5f2f0;background:rgba(224,224,224,.2);box-shadow:0 2px 0 0 rgba(0,0,0,.2);border-radius:.5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;text-decoration:none} diff --git a/web/source/css/profile.css b/web/source/css/profile.css index bc1a32a5d..06c93e6e0 100644 --- a/web/source/css/profile.css +++ b/web/source/css/profile.css @@ -17,28 +17,27 @@ */ .page { - grid-template-columns: 1fr minmax(auto, 60rem) 1fr; /* fallback for lack of min() support */ + /* + Profile page can be a little wider than default + page, since we're using a side-by-side column view. + */ + grid-template-columns: 1fr minmax(auto, 60rem) 1fr; grid-template-columns: 1fr min(92%, 65rem) 1fr; } -.profile { - padding: 0.5rem; - border-radius: $br; - - .column-split { - display: flex; - flex-wrap: wrap; - gap: 1rem; - } +.profile .column-split { + display: flex; + flex-wrap: wrap; + gap: 1rem; } -.profile .header { +.profile .profile-header { background: $profile-bg; border-radius: $br; overflow: hidden; margin-bottom: 1rem; - .header-image { + .header-image-wrapper { position: relative; padding-top: 33.33%; /* aspect-ratio 1/3 */ @@ -55,12 +54,11 @@ /* Basic info container has the user's avatar, display- and username, and role - It's partially overlapped over the header image, by a negative margin-top + It's partially overlapped over the header image, by a negative margin-top. */ $avatar-size: 8.5rem; $name-size: 3rem; $username-size: 2rem; - $overlap: calc($avatar-size - $name-size - $username-size); .basic-info { @@ -71,8 +69,8 @@ grid-template-rows: $overlap $name-size auto; grid-template-areas: "avatar . ." - "avatar displayname displayname" - "avatar username role"; + "avatar namerole namerole" + "avatar namerole namerole"; margin: 1rem; margin-top: calc(-1 * $overlap); @@ -93,131 +91,119 @@ } } - .displayname { - grid-area: displayname; - line-height: $name-size; - font-size: 1.5rem; - font-weight: bold; - } - - .username { - min-width: 0; - grid-area: username; - line-height: $username-size; + .namerole { + grid-area: namerole; - font-size: 1rem; - font-weight: bold; - color: $fg-accent; - user-select: all; - } - - .role { - background: $bg; - color: $fg; - border: 0.13rem solid $bg; - - grid-area: role; - align-self: center; - justify-self: start; - border-radius: $br; - padding: 0.3rem; - - line-height: 1.1rem; - font-size: 0.9rem; - font-variant: small-caps; - font-weight: bold; + display: grid; + gap: 0 1rem; + box-sizing: border-box; + grid-template-columns: auto 1fr; + grid-template-rows: $name-size auto; + grid-template-areas: + "displayname displayname" + "username role"; - &.admin { - color: $role-admin; - border-color: $role-admin; + .displayname { + grid-area: displayname; + line-height: $name-size; + font-size: 1.5rem; + font-weight: bold; } - - &.moderator { - color: $role-mod; - border-color: $role-mod; + + .username { + min-width: 0; + grid-area: username; + line-height: $username-size; + + font-size: 1rem; + font-weight: bold; + color: $fg-accent; + user-select: all; + } + + .role { + background: $bg; + color: $fg; + border: 0.13rem solid $bg; + + grid-area: role; + align-self: center; + justify-self: start; + border-radius: $br; + padding: 0.3rem; + + line-height: 1.1rem; + font-size: 0.9rem; + font-variant: small-caps; + font-weight: bold; + + &.admin { + color: $role-admin; + border-color: $role-admin; + } + + &.moderator { + color: $role-mod; + border-color: $role-mod; + } } } } } @media screen and (max-width: 750px) { - .profile .header { + .profile .profile-header { .basic-info { grid-template-columns: auto 1fr; grid-template-rows: $avatar-size $name-size auto; grid-template-areas: "avatar avatar" - "displayname displayname" - "username role"; - - .displayname { - font-size: 1.4rem; + "namerole namerole" + "namerole namerole"; + + .namerole { + grid-template-columns: 1fr; + grid-template-rows: $name-size auto; + grid-template-areas: + "displayname displayname" + "username role"; + + .displayname { + font-size: 1.4rem; + } } } } } -.profile .col-header { - display: flex; - justify-content: start; - gap: 2rem; - align-items: center; - - margin: 0; - background: $profile-bg; - border-top-left-radius: $br; - border-top-right-radius: $br; - padding: 0.75rem; - - h1, h2 { - font-size: 1.2rem; - line-height: 1.3rem; - margin: 0; - } -} - -.profile .toots { +.profile .statuses-wrapper { flex: 65 25rem; display: flex; flex-direction: column; gap: 0.4rem; min-width: 0%; +} - .col-header { - display: grid; - grid-template-columns: auto 1fr; - gap: 1rem; - - a { - justify-self: end; - } - - .rss-icon { - display: block; - margin: -0.25rem 0; - - .fa { - font-size: 2rem; - object-fit: contain; - vertical-align: middle; - color: $orange2; - /* can't size a single-color background, so we use a linear-gradient that's effectively white */ - background: linear-gradient(to right, $white1 100%, transparent 0) no-repeat center center; - background-size: 1.2rem 1.4rem; - } - } - } - - .toot { - border-radius: 0; - - .info { - padding: 0.3rem 0.75rem; - } +.profile .statuses { + display: flex; + flex-direction: column; + gap: 0.4rem; - &:last-child { - border-bottom-left-radius: $br; - border-bottom-right-radius: $br; + .rss-icon { + display: block; + margin: -0.25rem 0; + + .fa { + font-size: 2rem; + object-fit: contain; + vertical-align: middle; + color: $orange2; + /* + Can't size a single-color background, so we use + a linear-gradient that's effectively white. + */ + background: linear-gradient(to right, $white1 100%, transparent 0) no-repeat center center; + background-size: 1.2rem 1.4rem; } } @@ -240,6 +226,10 @@ margin-bottom: -0.25rem; } + dt { + font-weight: bold; + } + .fields { background: $profile-bg; display: flex; diff --git a/web/source/css/status.css b/web/source/css/status.css index cbe8c04d2..019fbd0b4 100644 --- a/web/source/css/status.css +++ b/web/source/css/status.css @@ -19,25 +19,19 @@ @import "photoswipe/dist/photoswipe.css"; @import "photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.css"; @import "plyr/dist/plyr.css"; +@import "./prism.css"; main { background: transparent; grid-auto-rows: auto; } -.thread { - display: flex; - flex-direction: column; - border-radius: $br; -} - -.toot { - background: $toot-bg; +.status { + background: $status-bg; box-shadow: $boxshadow; border: $boxshadow-border; border-radius: $br; position: relative; - margin-bottom: $br; padding-top: 0.75rem; a { @@ -47,66 +41,75 @@ main { text-decoration: none; } - .author > a { - padding: 0 0.75rem; - display: grid; - grid-template-columns: 3.5rem 1fr auto; - grid-template-rows: auto auto; - grid-template-areas: - "avatar display date" - "avatar user ."; - gap: 0 0.5rem; - - .avatar { - grid-area: avatar; - height: 3.5rem; - width: 3.5rem; - object-fit: cover; - - border: 0.15rem solid $avatar-border; - border-radius: $br; - overflow: hidden; /* hides corners from img overflowing */ - - img { - height: 100%; - width: 100%; + .status-header > address { + /* + Avoid stretching so wide that user + can't click on open thread link that's + behind the status header link. + */ + width: fit-content; + + > a { + padding: 0 0.75rem; + display: grid; + grid-template-columns: 3.5rem 1fr auto; + grid-template-rows: auto auto; + grid-template-areas: + "avatar author-strap author-strap" + "avatar author-strap author-strap"; + gap: 0 0.5rem; + font-style: normal; + + .avatar { + grid-area: avatar; + height: 3.5rem; + width: 3.5rem; object-fit: cover; - background: $bg; + + border: 0.15rem solid $avatar-border; + border-radius: $br; + overflow: hidden; /* hides corners from img overflowing */ + + img { + height: 100%; + width: 100%; + object-fit: cover; + background: $bg; + } } - } - - .displayname, .username { - justify-self: start; - align-self: start; - - max-width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - .displayname { - grid-area: display; - font-weight: bold; - font-size: 1rem; - line-height: 1.3rem; - /* margin-top: -0.5rem; */ - } - - .username { - grid-area: user; - color: $link-fg; - font-size: 1rem; - line-height: 1.3rem; - } - - .timestamp { - grid-area: date; - color: $fg-reduced; + .author-strap { + grid-area: author-strap; + display: grid; + grid-template-columns: 1fr auto; + grid-template-rows: auto; + grid-template-areas: + "display display" + "user user"; + gap: 0 0.5rem; + + .displayname, .username { + justify-self: start; + align-self: start; + max-width: 100%; + font-size: 1rem; + line-height: 1.3rem; + } + + .displayname { + grid-area: display; + font-weight: bold; + } + + .username { + grid-area: user; + color: $link-fg; + } + } } } - .body { + .status-body { padding: 0.5rem 0.75rem; display: flex; flex-direction: column; @@ -157,6 +160,10 @@ main { line-height: 1.6rem; width: 100%; + /* + Normalize header sizes to fit better + with the line-height we use for statuses. + */ h1 { margin: 0; font-size: 1.8rem; @@ -187,35 +194,63 @@ main { line-height: initial; } - blockquote { - padding: 0.5rem 0 0.5rem 0.5rem; - border-left: 0.2rem solid $border-accent; - margin: 0; - font-style: italic; - } - - hr { - border: 1px dashed $border-accent; - } - pre, code { background-color: $gray2; } + /* + Just code on its own inside status + content, ie, `here is some code`. + */ code { padding: 0.25rem; border-radius: $br-inner; + white-space: pre-wrap; } - pre { + /* + Restyle Prism code highlighting toolbar + plugin buttons to our own button style. + */ + .code-toolbar .toolbar { + margin-right: 0.5rem; display: flex; + gap: 0.25rem; + + .toolbar-item { + span, button { + color: $button-fg; + background: $button-bg; + font-weight: bold; + } + + .copy-to-clipboard-button, span { + box-shadow: $boxshadow; + } + + .copy-to-clipboard-button:hover, .copy-to-clipboard-button:hover span { + background: $button-hover-bg; + } + } + } + + pre, pre[class*="language-"] { border-radius: $br; padding: 0.5rem; + white-space: pre; + overflow-x: auto; - code { - padding: 0.5rem; + /* + Code inside a pre block, ie., + + ``` + here is some code + ``` + */ + code { + width: 100%; + padding: 0; white-space: pre; - border-radius: 0; overflow-x: auto; -webkit-overflow-scrolling: touch; } @@ -230,18 +265,6 @@ main { } } - .emoji { - transition: 0.1s; - } - - .emoji:hover, .emoji:active { - transform: scale(2); - background-color: $bg; - box-shadow: $boxshadow; - border: $boxshadow-border; - border-radius: $br-inner; - } - .poll { background-color: $gray2; z-index: 2; @@ -451,41 +474,41 @@ main { } } - .info { - display: flex; - background: $toot-info-bg; + .status-info { + background: $status-info-bg; color: $fg-reduced; - border-top: 0.15rem solid $toot-info-border; + border-top: 0.15rem solid $status-info-border; padding: 0.5rem 0.75rem; - time { - padding-right: 1rem; - } - - .stats { - display: inline-flex; - flex: 1; + .status-stats { + display: flex; gap: 1rem; - + + .stats-grouping { + display: flex; + flex-wrap: wrap; + column-gap: 1rem; + } + .stats-item { - span { - white-space: nowrap; - } + display: flex; + gap: 0.4rem; } - .language { - margin-left: auto; + .stats-item:not(.published-at) { z-index: 1; - cursor: pointer; user-select: none; } + + .language { + margin-left: auto; + } } grid-column: span 3; - flex-wrap: wrap; } - .toot-link { + .status-link { top: 0; right: 0; bottom: 0; @@ -508,15 +531,12 @@ main { /* bottom left, bottom right */ border-bottom-left-radius: $br; border-bottom-right-radius: $br; - margin-bottom: 0; } &.expanded { - background: $toot-focus-bg; - padding-bottom: 0; - - .info { - background: $toot-focus-info-bg; + background: $status-focus-bg; + .status-info { + background: $status-focus-info-bg; } } } diff --git a/web/source/css/thread.css b/web/source/css/thread.css new file mode 100644 index 000000000..fca998b3c --- /dev/null +++ b/web/source/css/thread.css @@ -0,0 +1,56 @@ +/* + GoToSocial + Copyright (C) 2021-2023 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +.thread { + display: flex; + flex-direction: column; + gap: 0.4rem; + + /* + This column header might contain + quite some info, so let it wrap. + */ + .col-header { + display: flex; + flex-direction: row; + flex-wrap: wrap; + column-gap: 1rem; + row-gap: 0.5rem; + + box-shadow: $boxshadow; + border: $boxshadow-border; + + h2 { + margin-right: auto; + } + } + + .status { + border-radius: 0; + + &:last-child { + border-bottom-left-radius: $br; + border-bottom-right-radius: $br; + + .status-info { + border-bottom-left-radius: $br; + border-bottom-right-radius: $br; + } + } + } +} \ No newline at end of file diff --git a/web/source/frontend/index.js b/web/source/frontend/index.js index faeb35ce4..74cb28460 100644 --- a/web/source/frontend/index.js +++ b/web/source/frontend/index.js @@ -21,6 +21,10 @@ const Photoswipe = require("photoswipe/dist/umd/photoswipe.umd.min.js"); const PhotoswipeLightbox = require("photoswipe/dist/umd/photoswipe-lightbox.umd.min.js"); const PhotoswipeCaptionPlugin = require("photoswipe-dynamic-caption-plugin").default; const Plyr = require("plyr"); +const Prism = require("./prism.js"); + +Prism.manual = true; +Prism.highlightAll(); let [_, _user, type, id] = window.location.pathname.split("/"); if (type == "statuses") { diff --git a/web/source/frontend/prism.js b/web/source/frontend/prism.js new file mode 100644 index 000000000..b1eb83385 --- /dev/null +++ b/web/source/frontend/prism.js @@ -0,0 +1,42 @@ +/* PrismJS 1.29.0 +https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+bash+c+csharp+cpp+docker+elixir+erlang+go+go-module+ini+java+json+kotlin+lua+makefile+markup-templating+nginx+nix+perl+php+promql+python+r+jsx+tsx+ruby+rust+scala+sql+swift+typescript&plugins=show-invisibles+show-language+toolbar+copy-to-clipboard */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=g.reach);A+=w.value.length,w=w.next){var E=w.value;if(n.length>e.length)return;if(!(E instanceof i)){var P,L=1;if(y){if(!(P=l(b,A,e,m))||P.index>=e.length)break;var S=P.index,O=P.index+P[0].length,j=A;for(j+=w.value.length;S>=j;)j+=(w=w.next).value.length;if(A=j-=w.value.length,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(jg.reach&&(g.reach=W);var z=w.prev;if(_&&(z=u(n,z,_),A+=_.length),c(n,z,L),w=u(n,z,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),L>1){var I={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,I),g&&I.reach>g.reach&&(g.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a"+i.content+""},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",(function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var t={"included-cdata":{pattern://i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:))*\\]\\]>|(?!)".replace(/__/g,(function(){return a})),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; +!function(s){var e=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:[^;{\\s\"']|\\s+(?!\\s)|"+e.source+")*?(?:;|(?=\\s*\\{))"),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp("(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])"),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp("((?:^|[^$\\w\\xA0-\\uFFFF.\"'\\])\\s]|\\b(?:return|yield))\\s*)/(?:(?:\\[(?:[^\\]\\\\\r\n]|\\\\.)*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}|(?:\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.)*\\])*\\])*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\s|/\\*(?:[^*]|\\*(?!/))*\\*/)*(?:$|[\r\n,.;:})\\]]|//))"),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute("on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)","javascript")),Prism.languages.js=Prism.languages.javascript; +!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",a={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},n={bash:a,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:n},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:a}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:n},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:n.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:n.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},a.inside=e.languages.bash;for(var s=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=n.variable[1].inside,i=0;i>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),Prism.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},Prism.languages.c.string],char:Prism.languages.c.char,comment:Prism.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:Prism.languages.c}}}}),Prism.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete Prism.languages.c.boolean; +!function(e){function n(e,n){return e.replace(/<<(\d+)>>/g,(function(e,s){return"(?:"+n[+s]+")"}))}function s(e,s,a){return RegExp(n(e,s),a||"")}function a(e,n){for(var s=0;s>/g,(function(){return"(?:"+e+")"}));return e.replace(/<>/g,"[^\\s\\S]")}var t="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",r="class enum interface record struct",i="add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",o="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var d=l(r),p=RegExp(l(t+" "+r+" "+i+" "+o)),c=l(r+" "+i+" "+o),u=l(t+" "+r+" "+o),g=a("<(?:[^<>;=+\\-*/%&|^]|<>)*>",2),b=a("\\((?:[^()]|<>)*\\)",2),h="@?\\b[A-Za-z_]\\w*\\b",f=n("<<0>>(?:\\s*<<1>>)?",[h,g]),m=n("(?!<<0>>)<<1>>(?:\\s*\\.\\s*<<1>>)*",[c,f]),k="\\[\\s*(?:,\\s*)*\\]",y=n("<<0>>(?:\\s*(?:\\?\\s*)?<<1>>)*(?:\\s*\\?)?",[m,k]),w=n("[^,()<>[\\];=+\\-*/%&|^]|<<0>>|<<1>>|<<2>>",[g,b,k]),v=n("\\(<<0>>+(?:,<<0>>+)+\\)",[w]),x=n("(?:<<0>>|<<1>>)(?:\\s*(?:\\?\\s*)?<<2>>)*(?:\\s*\\?)?",[v,m,k]),$={keyword:p,punctuation:/[<>()?,.:[\]]/},_="'(?:[^\r\n'\\\\]|\\\\.|\\\\[Uux][\\da-fA-F]{1,8})'",B='"(?:\\\\.|[^\\\\"\r\n])*"';e.languages.csharp=e.languages.extend("clike",{string:[{pattern:s("(^|[^$\\\\])<<0>>",['@"(?:""|\\\\[^]|[^\\\\"])*"(?!")']),lookbehind:!0,greedy:!0},{pattern:s("(^|[^@$\\\\])<<0>>",[B]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:s("(\\busing\\s+static\\s+)<<0>>(?=\\s*;)",[m]),lookbehind:!0,inside:$},{pattern:s("(\\busing\\s+<<0>>\\s*=\\s*)<<1>>(?=\\s*;)",[h,x]),lookbehind:!0,inside:$},{pattern:s("(\\busing\\s+)<<0>>(?=\\s*=)",[h]),lookbehind:!0},{pattern:s("(\\b<<0>>\\s+)<<1>>",[d,f]),lookbehind:!0,inside:$},{pattern:s("(\\bcatch\\s*\\(\\s*)<<0>>",[m]),lookbehind:!0,inside:$},{pattern:s("(\\bwhere\\s+)<<0>>",[h]),lookbehind:!0},{pattern:s("(\\b(?:is(?:\\s+not)?|as)\\s+)<<0>>",[y]),lookbehind:!0,inside:$},{pattern:s("\\b<<0>>(?=\\s+(?!<<1>>|with\\s*\\{)<<2>>(?:\\s*[=,;:{)\\]]|\\s+(?:in|when)\\b))",[x,u,h]),inside:$}],keyword:p,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),e.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),e.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:s("([(,]\\s*)<<0>>(?=\\s*:)",[h]),lookbehind:!0,alias:"punctuation"}}),e.languages.insertBefore("csharp","class-name",{namespace:{pattern:s("(\\b(?:namespace|using)\\s+)<<0>>(?:\\s*\\.\\s*<<0>>)*(?=\\s*[;{])",[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:s("(\\b(?:default|sizeof|typeof)\\s*\\(\\s*(?!\\s))(?:[^()\\s]|\\s(?!\\s)|<<0>>)*(?=\\s*\\))",[b]),lookbehind:!0,alias:"class-name",inside:$},"return-type":{pattern:s("<<0>>(?=\\s+(?:<<1>>\\s*(?:=>|[({]|\\.\\s*this\\s*\\[)|this\\s*\\[))",[x,m]),inside:$,alias:"class-name"},"constructor-invocation":{pattern:s("(\\bnew\\s+)<<0>>(?=\\s*[[({])",[x]),lookbehind:!0,inside:$,alias:"class-name"},"generic-method":{pattern:s("<<0>>\\s*<<1>>(?=\\s*\\()",[h,g]),inside:{function:s("^<<0>>",[h]),generic:{pattern:RegExp(g),alias:"class-name",inside:$}}},"type-list":{pattern:s("\\b((?:<<0>>\\s+<<1>>|record\\s+<<1>>\\s*<<5>>|where\\s+<<2>>)\\s*:\\s*)(?:<<3>>|<<4>>|<<1>>\\s*<<5>>|<<6>>)(?:\\s*,\\s*(?:<<3>>|<<4>>|<<6>>))*(?=\\s*(?:where|[{;]|=>|$))",[d,f,h,x,p.source,b,"\\bnew\\s*\\(\\s*\\)"]),lookbehind:!0,inside:{"record-arguments":{pattern:s("(^(?!new\\s*\\()<<0>>\\s*)<<1>>",[f,b]),lookbehind:!0,greedy:!0,inside:e.languages.csharp},keyword:p,"class-name":{pattern:RegExp(x),greedy:!0,inside:$},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var E=B+"|"+_,R=n("/(?![*/])|//[^\r\n]*[\r\n]|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>",[E]),z=a(n("[^\"'/()]|<<0>>|\\(<>*\\)",[R]),2),S="\\b(?:assembly|event|field|method|module|param|property|return|type)\\b",j=n("<<0>>(?:\\s*\\(<<1>>*\\))?",[m,z]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:s("((?:^|[^\\s\\w>)?])\\s*\\[\\s*)(?:<<0>>\\s*:\\s*)?<<1>>(?:\\s*,\\s*<<1>>)*(?=\\s*\\])",[S,j]),lookbehind:!0,greedy:!0,inside:{target:{pattern:s("^<<0>>(?=\\s*:)",[S]),alias:"keyword"},"attribute-arguments":{pattern:s("\\(<<0>>*\\)",[z]),inside:e.languages.csharp},"class-name":{pattern:RegExp(m),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var A=":[^}\r\n]+",F=a(n("[^\"'/()]|<<0>>|\\(<>*\\)",[R]),2),P=n("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[F,A]),U=a(n("[^\"'/()]|/(?!\\*)|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>|\\(<>*\\)",[E]),2),Z=n("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[U,A]);function q(n,a){return{interpolation:{pattern:s("((?:^|[^{])(?:\\{\\{)*)<<0>>",[n]),lookbehind:!0,inside:{"format-string":{pattern:s("(^\\{(?:(?![}:])<<0>>)*)<<1>>(?=\\}$)",[a,A]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:e.languages.csharp}}},string:/[\s\S]+/}}e.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:s('(^|[^\\\\])(?:\\$@|@\\$)"(?:""|\\\\[^]|\\{\\{|<<0>>|[^\\\\{"])*"',[P]),lookbehind:!0,greedy:!0,inside:q(P,F)},{pattern:s('(^|[^@\\\\])\\$"(?:\\\\.|\\{\\{|<<0>>|[^\\\\"{])*"',[Z]),lookbehind:!0,greedy:!0,inside:q(Z,U)}],char:{pattern:RegExp(_),greedy:!0}}),e.languages.dotnet=e.languages.cs=e.languages.csharp}(Prism); +!function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n="\\b(?!)\\w+(?:\\s*\\.\\s*\\w+)*\\b".replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp("(\\b(?:class|concept|enum|struct|typename)\\s+)(?!)\\w+".replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp('(\\b(?:import|module)\\s+)(?:"(?:\\\\(?:\r\n|[^])|[^"\\\\\r\n])*"|<[^<>\r\n]*>|'+"(?:\\s*:\\s*)?|:\\s*".replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(Prism); +!function(e){var n="(?:[ \t]+(?![ \t])(?:)?|)".replace(//g,(function(){return"\\\\[\r\n](?:\\s|\\\\[\r\n]|#.*(?!.))*(?![\\s#]|\\\\[\r\n])"})),r="\"(?:[^\"\\\\\r\n]|\\\\(?:\r\n|[^]))*\"|'(?:[^'\\\\\r\n]|\\\\(?:\r\n|[^]))*'",t="--[\\w-]+=(?:|(?![\"'])(?:[^\\s\\\\]|\\\\.)+)".replace(//g,(function(){return r})),o={pattern:RegExp(r),greedy:!0},i={pattern:/(^[ \t]*)#.*/m,lookbehind:!0,greedy:!0};function a(e,r){return e=e.replace(//g,(function(){return t})).replace(//g,(function(){return n})),RegExp(e,r)}e.languages.docker={instruction:{pattern:/(^[ \t]*)(?:ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|ONBUILD|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR)(?=\s)(?:\\.|[^\r\n\\])*(?:\\$(?:\s|#.*$)*(?![\s#])(?:\\.|[^\r\n\\])*)*/im,lookbehind:!0,greedy:!0,inside:{options:{pattern:a("(^(?:ONBUILD)?\\w+)(?:)*","i"),lookbehind:!0,greedy:!0,inside:{property:{pattern:/(^|\s)--[\w-]+/,lookbehind:!0},string:[o,{pattern:/(=)(?!["'])(?:[^\s\\]|\\.)+/,lookbehind:!0}],operator:/\\$/m,punctuation:/=/}},keyword:[{pattern:a("(^(?:ONBUILD)?HEALTHCHECK(?:)*)(?:CMD|NONE)\\b","i"),lookbehind:!0,greedy:!0},{pattern:a("(^(?:ONBUILD)?FROM(?:)*(?!--)[^ \t\\\\]+)AS","i"),lookbehind:!0,greedy:!0},{pattern:a("(^ONBUILD)\\w+","i"),lookbehind:!0,greedy:!0},{pattern:/^\w+/,greedy:!0}],comment:i,string:o,variable:/\$(?:\w+|\{[^{}"'\\]*\})/,operator:/\\$/m}},comment:i},e.languages.dockerfile=e.languages.docker}(Prism); +Prism.languages.elixir={doc:{pattern:/@(?:doc|moduledoc)\s+(?:("""|''')[\s\S]*?\1|("|')(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2)/,inside:{attribute:/^@\w+/,string:/['"][\s\S]+/}},comment:{pattern:/#.*/,greedy:!0},regex:{pattern:/~[rR](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[uismxfr]*/,greedy:!0},string:[{pattern:/~[cCsSwW](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|#\{[^}]+\}|#(?!\{)|[^#\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[csa]?/,greedy:!0,inside:{}},{pattern:/("""|''')[\s\S]*?\1/,greedy:!0,inside:{}},{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{}}],atom:{pattern:/(^|[^:]):\w+/,lookbehind:!0,alias:"symbol"},module:{pattern:/\b[A-Z]\w*\b/,alias:"class-name"},"attr-name":/\b\w+\??:(?!:)/,argument:{pattern:/(^|[^&])&\d+/,lookbehind:!0,alias:"variable"},attribute:{pattern:/@\w+/,alias:"variable"},function:/\b[_a-zA-Z]\w*[?!]?(?:(?=\s*(?:\.\s*)?\()|(?=\/\d))/,number:/\b(?:0[box][a-f\d_]+|\d[\d_]*)(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?\b/i,keyword:/\b(?:after|alias|and|case|catch|cond|def(?:callback|delegate|exception|impl|macro|module|n|np|p|protocol|struct)?|do|else|end|fn|for|if|import|not|or|quote|raise|require|rescue|try|unless|unquote|use|when)\b/,boolean:/\b(?:false|nil|true)\b/,operator:[/\bin\b|&&?|\|[|>]?|\\\\|::|\.\.\.?|\+\+?|-[->]?|<[-=>]|>=|!==?|\B!|=(?:==?|[>~])?|[*\/^]/,{pattern:/([^<])<(?!<)/,lookbehind:!0},{pattern:/([^>])>(?!>)/,lookbehind:!0}],punctuation:/<<|>>|[.,%\[\]{}()]/},Prism.languages.elixir.string.forEach((function(e){e.inside={interpolation:{pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"},rest:Prism.languages.elixir}}}})); +Prism.languages.erlang={comment:/%.+/,string:{pattern:/"(?:\\.|[^\\"\r\n])*"/,greedy:!0},"quoted-function":{pattern:/'(?:\\.|[^\\'\r\n])+'(?=\()/,alias:"function"},"quoted-atom":{pattern:/'(?:\\.|[^\\'\r\n])+'/,alias:"atom"},boolean:/\b(?:false|true)\b/,keyword:/\b(?:after|begin|case|catch|end|fun|if|of|receive|try|when)\b/,number:[/\$\\?./,/\b\d+#[a-z0-9]+/i,/(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i],function:/\b[a-z][\w@]*(?=\()/,variable:{pattern:/(^|[^@])(?:\b|\?)[A-Z_][\w@]*/,lookbehind:!0},operator:[/[=\/<>:]=|=[:\/]=|\+\+?|--?|[=*\/!]|\b(?:and|andalso|band|bnot|bor|bsl|bsr|bxor|div|not|or|orelse|rem|xor)\b/,{pattern:/(^|[^<])<(?!<)/,lookbehind:!0},{pattern:/(^|[^>])>(?!>)/,lookbehind:!0}],atom:/\b[a-z][\w@]*/,punctuation:/[()[\]{}:;,.#|]|<<|>>/}; +Prism.languages.go=Prism.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),Prism.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete Prism.languages.go["class-name"]; +Prism.languages["go-mod"]=Prism.languages["go-module"]={comment:{pattern:/\/\/.*/,greedy:!0},version:{pattern:/(^|[\s()[\],])v\d+\.\d+\.\d+(?:[+-][-+.\w]*)?(?![^\s()[\],])/,lookbehind:!0,alias:"number"},"go-version":{pattern:/((?:^|\s)go\s+)\d+(?:\.\d+){1,2}/,lookbehind:!0,alias:"number"},keyword:{pattern:/^([ \t]*)(?:exclude|go|module|replace|require|retract)\b/m,lookbehind:!0},operator:/=>/,punctuation:/[()[\],]/}; +Prism.languages.ini={comment:{pattern:/(^[ \f\t\v]*)[#;][^\n\r]*/m,lookbehind:!0},section:{pattern:/(^[ \f\t\v]*)\[[^\n\r\]]*\]?/m,lookbehind:!0,inside:{"section-name":{pattern:/(^\[[ \f\t\v]*)[^ \f\t\v\]]+(?:[ \f\t\v]+[^ \f\t\v\]]+)*/,lookbehind:!0,alias:"selector"},punctuation:/\[|\]/}},key:{pattern:/(^[ \f\t\v]*)[^ \f\n\r\t\v=]+(?:[ \f\t\v]+[^ \f\n\r\t\v=]+)*(?=[ \f\t\v]*=)/m,lookbehind:!0,alias:"attr-name"},value:{pattern:/(=[ \f\t\v]*)[^ \f\n\r\t\v]+(?:[ \f\t\v]+[^ \f\n\r\t\v]+)*/,lookbehind:!0,alias:"attr-value",inside:{"inner-value":{pattern:/^("|').+(?=\1$)/,lookbehind:!0}}},punctuation:/=/}; +!function(e){var n=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,t="(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",s={pattern:RegExp("(^|[^\\w.])"+t+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[s,{pattern:RegExp("(^|[^\\w.])"+t+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=()]|\\s*(?:\\[[\\s,]*\\]\\s*)?::\\s*new\\b)"),lookbehind:!0,inside:s.inside},{pattern:RegExp("(\\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\\s+)"+t+"[A-Z]\\w*\\b"),lookbehind:!0,inside:s.inside}],keyword:n,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":s,keyword:n,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp("(\\bimport\\s+)"+t+"(?:[A-Z]\\w*|\\*)(?=\\s*;)"),lookbehind:!0,inside:{namespace:s.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp("(\\bimport\\s+static\\s+)"+t+"(?:\\w+|\\*)(?=\\s*;)"),lookbehind:!0,alias:"static",inside:{namespace:s.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(//g,(function(){return n.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism); +Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json; +!function(n){n.languages.kotlin=n.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete n.languages.kotlin["class-name"];var e={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:n.languages.kotlin}};n.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:e},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:e},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete n.languages.kotlin.string,n.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),n.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),n.languages.kt=n.languages.kotlin,n.languages.kts=n.languages.kotlin}(Prism); +Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,function:/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/}; +Prism.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/}; +!function(e){function n(e,n){return"___"+e.toUpperCase()+n+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(t,a,r,o){if(t.language===a){var c=t.tokenStack=[];t.code=t.code.replace(r,(function(e){if("function"==typeof o&&!o(e))return e;for(var r,i=c.length;-1!==t.code.indexOf(r=n(a,i));)++i;return c[i]=e,r})),t.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(t,a){if(t.language===a&&t.tokenStack){t.grammar=e.languages[a];var r=0,o=Object.keys(t.tokenStack);!function c(i){for(var u=0;u=o.length);u++){var g=i[u];if("string"==typeof g||g.content&&"string"==typeof g.content){var l=o[r],s=t.tokenStack[l],f="string"==typeof g?g:g.content,p=n(a,l),k=f.indexOf(p);if(k>-1){++r;var m=f.substring(0,k),d=new e.Token(a,e.tokenize(s,t.grammar),"language-"+a,s),h=f.substring(k+p.length),v=[];m&&v.push.apply(v,c([m])),v.push(d),h&&v.push.apply(v,c([h])),"string"==typeof g?i.splice.apply(i,[u,1].concat(v)):g.content=v}}else g.content&&c(g.content)}return i}(t.tokens)}}}})}(Prism); +!function(e){var n=/\$(?:\w[a-z\d]*(?:_[^\x00-\x1F\s"'\\()$]*)?|\{[^}\s"'\\]+\})/i;e.languages.nginx={comment:{pattern:/(^|[\s{};])#.*/,lookbehind:!0,greedy:!0},directive:{pattern:/(^|\s)\w(?:[^;{}"'\\\s]|\\.|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\s+(?:#.*(?!.)|(?![#\s])))*?(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:{string:{pattern:/((?:^|[^\\])(?:\\\\)*)(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/,lookbehind:!0,greedy:!0,inside:{escape:{pattern:/\\["'\\nrt]/,alias:"entity"},variable:n}},comment:{pattern:/(\s)#.*/,lookbehind:!0,greedy:!0},keyword:{pattern:/^\S+/,greedy:!0},boolean:{pattern:/(\s)(?:off|on)(?!\S)/,lookbehind:!0},number:{pattern:/(\s)\d+[a-z]*(?!\S)/i,lookbehind:!0},variable:n}},punctuation:/[{};]/}}(Prism); +Prism.languages.nix={comment:{pattern:/\/\*[\s\S]*?\*\/|#.*/,greedy:!0},string:{pattern:/"(?:[^"\\]|\\[\s\S])*"|''(?:(?!'')[\s\S]|''(?:'|\\|\$\{))*''/,greedy:!0,inside:{interpolation:{pattern:/(^|(?:^|(?!'').)[^\\])\$\{(?:[^{}]|\{[^}]*\})*\}/,lookbehind:!0,inside:null}}},url:[/\b(?:[a-z]{3,7}:\/\/)[\w\-+%~\/.:#=?&]+/,{pattern:/([^\/])(?:[\w\-+%~.:#=?&]*(?!\/\/)[\w\-+%~\/.:#=?&])?(?!\/\/)\/[\w\-+%~\/.:#=?&]*/,lookbehind:!0}],antiquotation:{pattern:/\$(?=\{)/,alias:"important"},number:/\b\d+\b/,keyword:/\b(?:assert|builtins|else|if|in|inherit|let|null|or|then|with)\b/,function:/\b(?:abort|add|all|any|attrNames|attrValues|baseNameOf|compareVersions|concatLists|currentSystem|deepSeq|derivation|dirOf|div|elem(?:At)?|fetch(?:Tarball|url)|filter(?:Source)?|fromJSON|genList|getAttr|getEnv|hasAttr|hashString|head|import|intersectAttrs|is(?:Attrs|Bool|Function|Int|List|Null|String)|length|lessThan|listToAttrs|map|mul|parseDrvName|pathExists|read(?:Dir|File)|removeAttrs|replaceStrings|seq|sort|stringLength|sub(?:string)?|tail|throw|to(?:File|JSON|Path|String|XML)|trace|typeOf)\b|\bfoldl'\B/,boolean:/\b(?:false|true)\b/,operator:/[=!<>]=?|\+\+?|\|\||&&|\/\/|->?|[?@]/,punctuation:/[{}()[\].,:;]/},Prism.languages.nix.string.inside.interpolation.inside=Prism.languages.nix; +!function(e){var n="(?:\\((?:[^()\\\\]|\\\\[^])*\\)|\\{(?:[^{}\\\\]|\\\\[^])*\\}|\\[(?:[^[\\]\\\\]|\\\\[^])*\\]|<(?:[^<>\\\\]|\\\\[^])*>)";e.languages.perl={comment:[{pattern:/(^\s*)=\w[\s\S]*?=cut.*/m,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\$])#.*/,lookbehind:!0,greedy:!0}],string:[{pattern:RegExp("\\b(?:q|qq|qw|qx)(?![a-zA-Z0-9])\\s*(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","([a-zA-Z0-9])(?:(?!\\2)[^\\\\]|\\\\[^])*\\2",n].join("|")+")"),greedy:!0},{pattern:/("|`)(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0},{pattern:/'(?:[^'\\\r\n]|\\.)*'/,greedy:!0}],regex:[{pattern:RegExp("\\b(?:m|qr)(?![a-zA-Z0-9])\\s*(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","([a-zA-Z0-9])(?:(?!\\2)[^\\\\]|\\\\[^])*\\2",n].join("|")+")[msixpodualngc]*"),greedy:!0},{pattern:RegExp("(^|[^-])\\b(?:s|tr|y)(?![a-zA-Z0-9])\\s*(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\2)[^\\\\]|\\\\[^])*\\2(?:(?!\\2)[^\\\\]|\\\\[^])*\\2","([a-zA-Z0-9])(?:(?!\\3)[^\\\\]|\\\\[^])*\\3(?:(?!\\3)[^\\\\]|\\\\[^])*\\3",n+"\\s*"+n].join("|")+")[msixpodualngcer]*"),lookbehind:!0,greedy:!0},{pattern:/\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|x|xor)\b))/,greedy:!0}],variable:[/[&*$@%]\{\^[A-Z]+\}/,/[&*$@%]\^[A-Z_]/,/[&*$@%]#?(?=\{)/,/[&*$@%]#?(?:(?:::)*'?(?!\d)[\w$]+(?![\w$]))+(?:::)*/,/[&*$@%]\d+/,/(?!%=)[$@%][!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/],filehandle:{pattern:/<(?![<=])\S*?>|\b_\b/,alias:"symbol"},"v-string":{pattern:/v\d+(?:\.\d+)*|\d+(?:\.\d+){2,}/,alias:"string"},function:{pattern:/(\bsub[ \t]+)\w+/,lookbehind:!0},keyword:/\b(?:any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|return|say|state|sub|switch|undef|unless|until|use|when|while)\b/,number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,operator:/-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)\b/,punctuation:/[{}[\];(),:]/}}(Prism); +!function(e){var a=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,t=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],i=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,n=/|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,s=/[{}\[\](),:;]/;e.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:a,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:t,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:i,operator:n,punctuation:s};var l={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:e.languages.php},r=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:l}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:l}}];e.languages.insertBefore("php","variable",{string:r,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:a,string:r,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:t,number:i,operator:n,punctuation:s}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),e.hooks.add("before-tokenize",(function(a){/<\?/.test(a.code)&&e.languages["markup-templating"].buildPlaceholders(a,"php",/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g)})),e.hooks.add("after-tokenize",(function(a){e.languages["markup-templating"].tokenizePlaceholders(a,"php")}))}(Prism); +!function(t){var n=["on","ignoring","group_right","group_left","by","without"],a=["sum","min","max","avg","group","stddev","stdvar","count","count_values","bottomk","topk","quantile"].concat(n,["offset"]);t.languages.promql={comment:{pattern:/(^[ \t]*)#.*/m,lookbehind:!0},"vector-match":{pattern:new RegExp("((?:"+n.join("|")+")\\s*)\\([^)]*\\)"),lookbehind:!0,inside:{"label-key":{pattern:/\b[^,]+\b/,alias:"attr-name"},punctuation:/[(),]/}},"context-labels":{pattern:/\{[^{}]*\}/,inside:{"label-key":{pattern:/\b[a-z_]\w*(?=\s*(?:=|![=~]))/,alias:"attr-name"},"label-value":{pattern:/(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,greedy:!0,alias:"attr-value"},punctuation:/\{|\}|=~?|![=~]|,/}},"context-range":[{pattern:/\[[\w\s:]+\]/,inside:{punctuation:/\[|\]|:/,"range-duration":{pattern:/\b(?:\d+(?:[smhdwy]|ms))+\b/i,alias:"number"}}},{pattern:/(\boffset\s+)\w+/,lookbehind:!0,inside:{"range-duration":{pattern:/\b(?:\d+(?:[smhdwy]|ms))+\b/i,alias:"number"}}}],keyword:new RegExp("\\b(?:"+a.join("|")+")\\b","i"),function:/\b[a-z_]\w*(?=\s*\()/i,number:/[-+]?(?:(?:\b\d+(?:\.\d+)?|\B\.\d+)(?:e[-+]?\d+)?\b|\b(?:0x[0-9a-f]+|nan|inf)\b)/i,operator:/[\^*/%+-]|==|!=|<=|<|>=|>|\b(?:and|or|unless)\b/i,punctuation:/[{};()`,.[\]]/}}(Prism); +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python; +Prism.languages.r={comment:/#.*/,string:{pattern:/(['"])(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},"percent-operator":{pattern:/%[^%\s]*%/,alias:"operator"},boolean:/\b(?:FALSE|TRUE)\b/,ellipsis:/\.\.(?:\.|\d+)/,number:[/\b(?:Inf|NaN)\b/,/(?:\b0x[\dA-Fa-f]+(?:\.\d*)?|\b\d+(?:\.\d*)?|\B\.\d+)(?:[EePp][+-]?\d+)?[iL]?/],keyword:/\b(?:NA|NA_character_|NA_complex_|NA_integer_|NA_real_|NULL|break|else|for|function|if|in|next|repeat|while)\b/,operator:/->?>?|<(?:=|=!]=?|::?|&&?|\|\|?|[+*\/^$@~]/,punctuation:/[(){}\[\],;]/}; +!function(t){var n=t.util.clone(t.languages.javascript),e="(?:\\{*\\.{3}(?:[^{}]|)*\\})";function a(t,n){return t=t.replace(//g,(function(){return"(?:\\s|//.*(?!.)|/\\*(?:[^*]|\\*(?!/))\\*/)"})).replace(//g,(function(){return"(?:\\{(?:\\{(?:\\{[^{}]*\\}|[^{}])*\\}|[^{}])*\\})"})).replace(//g,(function(){return e})),RegExp(t,n)}e=a(e).source,t.languages.jsx=t.languages.extend("markup",n),t.languages.jsx.tag.pattern=a("+(?:[\\w.:$-]+(?:=(?:\"(?:\\\\[^]|[^\\\\\"])*\"|'(?:\\\\[^]|[^\\\\'])*'|[^\\s{'\"/>=]+|))?|))**/?)?>"),t.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,t.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,t.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,t.languages.jsx.tag.inside.comment=n.comment,t.languages.insertBefore("inside","attr-name",{spread:{pattern:a(""),inside:t.languages.jsx}},t.languages.jsx.tag),t.languages.insertBefore("inside","special-attr",{script:{pattern:a("="),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:t.languages.jsx}}},t.languages.jsx.tag);var s=function(t){return t?"string"==typeof t?t:"string"==typeof t.content?t.content:t.content.map(s).join(""):""},g=function(n){for(var e=[],a=0;a0&&e[e.length-1].tagName===s(o.content[0].content[1])&&e.pop():"/>"===o.content[o.content.length-1].content||e.push({tagName:s(o.content[0].content[1]),openedBraces:0}):e.length>0&&"punctuation"===o.type&&"{"===o.content?e[e.length-1].openedBraces++:e.length>0&&e[e.length-1].openedBraces>0&&"punctuation"===o.type&&"}"===o.content?e[e.length-1].openedBraces--:i=!0),(i||"string"==typeof o)&&e.length>0&&0===e[e.length-1].openedBraces){var r=s(o);a0&&("string"==typeof n[a-1]||"plain-text"===n[a-1].type)&&(r=s(n[a-1])+r,n.splice(a-1,1),a--),n[a]=new t.Token("plain-text",r,null,r)}o.content&&"string"!=typeof o.content&&g(o.content)}};t.hooks.add("after-tokenize",(function(t){"jsx"!==t.language&&"tsx"!==t.language||g(t.tokens)}))}(Prism); +!function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var s=e.languages.extend("typescript",{});delete s["class-name"],e.languages.typescript["class-name"].inside=s,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:s}}}}),e.languages.ts=e.languages.typescript}(Prism); +!function(e){var a=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",a),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var t=e.languages.tsx.tag;t.pattern=RegExp("(^|[^\\w$]|(?=|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var n={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var t="(?:"+["([^a-zA-Z0-9\\s{(\\[<=])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^]|\\((?:[^()\\\\]|\\\\[^])*\\))*\\)","\\{(?:[^{}\\\\]|\\\\[^]|\\{(?:[^{}\\\\]|\\\\[^])*\\})*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^]|\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\])*\\]","<(?:[^<>\\\\]|\\\\[^]|<(?:[^<>\\\\]|\\\\[^])*>)*>"].join("|")+")",i='(?:"(?:\\\\.|[^"\\\\\r\n])*"|(?:\\b[a-zA-Z_]\\w*|[^\\s\0-\\x7F]+)[?!]?|\\$.)';e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp("%r"+t+"[egimnosux]{0,6}"),greedy:!0,inside:{interpolation:n,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:n,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp("(^|[^:]):"+i),lookbehind:!0,greedy:!0},{pattern:RegExp("([\r\n{(,][ \t]*)"+i+"(?=:(?!:))"),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp("%[qQiIwWs]?"+t),greedy:!0,inside:{interpolation:n,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:n,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:n,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp("%x"+t),greedy:!0,inside:{interpolation:n,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:n,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(Prism); +!function(e){for(var a="/\\*(?:[^*/]|\\*(?!/)|/(?!\\*)|)*\\*/",t=0;t<2;t++)a=a.replace(//g,(function(){return a}));a=a.replace(//g,(function(){return"[^\\s\\S]"})),e.languages.rust={comment:[{pattern:RegExp("(^|[^\\\\])"+a),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism); +Prism.languages.scala=Prism.languages.extend("java",{"triple-quoted-string":{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string"},string:{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},keyword:/<-|=>|\b(?:abstract|case|catch|class|def|derives|do|else|enum|extends|extension|final|finally|for|forSome|given|if|implicit|import|infix|inline|lazy|match|new|null|object|opaque|open|override|package|private|protected|return|sealed|self|super|this|throw|trait|transparent|try|type|using|val|var|while|with|yield)\b/,number:/\b0x(?:[\da-f]*\.)?[\da-f]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e\d+)?[dfl]?/i,builtin:/\b(?:Any|AnyRef|AnyVal|Boolean|Byte|Char|Double|Float|Int|Long|Nothing|Short|String|Unit)\b/,symbol:/'[^\d\s\\]\w*/}),Prism.languages.insertBefore("scala","triple-quoted-string",{"string-interpolation":{pattern:/\b[a-z]\w*(?:"""(?:[^$]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*?"""|"(?:[^$"\r\n]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*")/i,greedy:!0,inside:{id:{pattern:/^\w+/,greedy:!0,alias:"function"},escape:{pattern:/\\\$"|\$[$"]/,greedy:!0,alias:"symbol"},interpolation:{pattern:/\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,greedy:!0,inside:{punctuation:/^\$\{?|\}$/,expression:{pattern:/[\s\S]+/,inside:Prism.languages.scala}}},string:/[\s\S]+/}}}),delete Prism.languages.scala["class-name"],delete Prism.languages.scala.function,delete Prism.languages.scala.constant; +Prism.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/}; +Prism.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp('(^|[^"#])(?:"(?:\\\\(?:\\((?:[^()]|\\([^()]*\\))*\\)|\r\n|[^(])|[^\\\\\r\n"])*"|"""(?:\\\\(?:\\((?:[^()]|\\([^()]*\\))*\\)|[^(])|[^\\\\"]|"(?!""))*""")(?!["#])'),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp('(^|[^"#])(#+)(?:"(?:\\\\(?:#+\\((?:[^()]|\\([^()]*\\))*\\)|\r\n|[^#])|[^\\\\\r\n])*?"|"""(?:\\\\(?:#+\\((?:[^()]|\\([^()]*\\))*\\)|[^#])|[^\\\\])*?""")\\2'),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp("#(?:(?:elseif|if)\\b(?:[ \t]*(?:![ \t]*)?(?:\\b\\w+\\b(?:[ \t]*\\((?:[^()]|\\([^()]*\\))*\\))?|\\((?:[^()]|\\([^()]*\\))*\\))(?:[ \t]*(?:&&|\\|\\|))?)+|(?:else|endif)\\b)"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},Prism.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=Prism.languages.swift})); +!function(){if("undefined"!=typeof Prism){var r={tab:/\t/,crlf:/\r\n/,lf:/\n/,cr:/\r/,space:/ /};Prism.hooks.add("before-highlight",(function(r){i(r.grammar)}))}function e(r,a){var n=r[a];switch(Prism.util.type(n)){case"RegExp":var t={};r[a]={pattern:n,inside:t},i(t);break;case"Array":for(var f=0,s=n.length;f -
- - - - {account.display_name.trim().length > 0 ? account.display_name : account.username} - . - - @{account.username} - -
-
+ ); diff --git a/web/source/settings/admin/reports/index.jsx b/web/source/settings/admin/reports/index.jsx index 5ffbfd3a0..58fca998d 100644 --- a/web/source/settings/admin/reports/index.jsx +++ b/web/source/settings/admin/reports/index.jsx @@ -83,7 +83,7 @@ function ReportEntry({ report }) {
reported
-

+

{report.action_taken ? "Resolved" : "Open"}

diff --git a/web/source/settings/components/fake-profile.jsx b/web/source/settings/components/fake-profile.jsx index d1f28f36c..6cb8d0187 100644 --- a/web/source/settings/components/fake-profile.jsx +++ b/web/source/settings/components/fake-profile.jsx @@ -22,24 +22,29 @@ const React = require("react"); module.exports = function FakeProfile({ avatar, header, display_name, username, role }) { return ( // Keep in sync with web/template/profile.tmpl
-
-
+
+
{header
diff --git a/web/source/settings/components/fake-toot.jsx b/web/source/settings/components/fake-toot.jsx index 7c2e40454..08f806008 100644 --- a/web/source/settings/components/fake-toot.jsx +++ b/web/source/settings/components/fake-toot.jsx @@ -29,20 +29,27 @@ module.exports = function FakeToot({ children }) { } } = query.useVerifyCredentialsQuery(); return ( -
-
- - - - {account.display_name.trim().length > 0 ? account.display_name : account.username} - . - - @{account.username} - -
-
+ diff --git a/web/source/settings/style.css b/web/source/settings/style.css index 524f5e4ab..13642dd0c 100644 --- a/web/source/settings/style.css +++ b/web/source/settings/style.css @@ -20,26 +20,14 @@ body { grid-template-rows: auto 1fr; } -.content { +.page-content { grid-column: 1 / span 3; /* stretch entire width, to fit panel + sidebar nav */ width: 100%; } -header { - justify-content: start; - - a { - margin: 1.5rem; - gap: 1rem; - - h1 { - font-size: 1.5rem; - } - - img { - height: 3rem; - } - } +/* Don't inherit orange dot from base.css. */ +ul li::before { + content: initial; } #root { @@ -1007,7 +995,7 @@ button.with-padding { grid-template-columns: 1fr auto; gap: 0.5rem; - .status { + .report-status { color: $border-accent; } } @@ -1029,7 +1017,7 @@ button.with-padding { color: $fg-reduced; border-left: 0.4rem solid $bg; - .byline .status { + .byline .report-status { color: $fg-reduced; } @@ -1141,11 +1129,62 @@ button.with-padding { } } +.instance-rules { + list-style-position: inside; + margin: 0; + padding: 0; + + a.rule { + display: grid; + grid-template-columns: 1fr auto; + align-items: center; + color: $fg; + text-decoration: none; + background: $status-bg; + padding: 1rem; + margin: 0.5rem 0; + border-radius: $br; + line-height: 2rem; + position: relative; + + &:hover { + color: $fg-accent; + + .edit-icon { + display: inline; + } + } + + .edit-icon { + display: none; + font-size: 1rem; + line-height: 1.5rem; + } + + li { + font-size: 1.75rem; + padding: 0; + margin: 0; + + h2 { + margin: 0; + margin-top: 0 !important; + display: inline-block; + font-size: 1.5rem; + } + } + + span { + color: $fg-reduced; + } + } +} + @media screen and (orientation: portrait) { .reports .report .byline { grid-template-columns: 1fr; - .status { + .report-status { grid-row: 1; } } @@ -1162,4 +1201,14 @@ button.with-padding { to { opacity: 0; } -} \ No newline at end of file +} + +@media (prefers-reduced-motion) { + .fa-spin { + animation: none; + } +} + +.monospace { + font-family: monospace; +} diff --git a/web/template/404.tmpl b/web/template/404.tmpl index 2269d667b..cbad36091 100644 --- a/web/template/404.tmpl +++ b/web/template/404.tmpl @@ -17,23 +17,27 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} +{{- with . }}
-
-

404: Page Not Found

-

- GoToSocial only serves Public statuses via the web. - If you reached this page by clicking on a status link, - it's possible that the status is not Public, has been - deleted by the author, you don't have permission to see - it, or it just doesn't exist at all. -

-

- If you believe this 404 was an error, you can contact - the instance admin. Provide them with the following request - Request ID: {{.requestID}}. -

-
+
+

404: Not Found

+

+ GoToSocial only serves Public statuses via the web. +

+

+ If you reached this page by clicking on a status link, + it's likely that the status is not Public. You can try + entering the status URL in your client's search bar, + to view the status from your account. If that doesn't + work, it's possible that the status has been deleted by + the author, you don't have permission to view it, or it + doesn't exist at all. +

+

+ If you believe this 404 was an error, you can contact + the instance admin. Provide them with the following + request ID: {{- .requestID -}}. +

+
- -{{ template "footer.tmpl" .}} \ No newline at end of file +{{- end }} \ No newline at end of file diff --git a/web/template/about.tmpl b/web/template/about.tmpl index 6579f492f..a23dfa953 100644 --- a/web/template/about.tmpl +++ b/web/template/about.tmpl @@ -17,105 +17,133 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} -
-
-

About

-
- {{.instance.Description |noescape}} -
+{{- define "description" -}} +{{- if .instance.Description }} +{{ .instance.Description | noescape }} +{{- else }} +

No description has yet been set for this instance.

+{{- end }} +{{- end -}} -

-

Languages

-

- {{ if .languages }} - This instance prefers the following languages: -

    - {{range .languages}} -
  1. {{.}}
  2. - {{end}} -
- {{ else }} - This instance does not have any preferred languages. - {{ end }} -

-
+{{- define "registrationLimits" -}} +{{- if .instance.Registrations -}} + Registration is enabled; new signups can be submitted to this instance.
+ {{- if .instance.ApprovalRequired -}} + Admin approval is required for new registrations. + {{- else -}} + Admin approval is not required for registrations; new signups will be automatically approved (pending email confirmation). + {{- end -}} +{{- else -}} + Registration is disabled; new signups are currently closed for this instance. +{{- end -}} +{{- end -}} - +{{- define "customCSSLimits" -}} +{{- if .instance.Configuration.Accounts.AllowCustomCSS -}} +Users are allowed to set Custom CSS for their profiles. +{{- else -}} +Custom CSS is not enabled for user profiles. +{{- end -}} +{{- end -}} -
-

Rules

-
    - {{range .instance.Rules}} -
  1. {{.Text}}
  2. - {{end}} -
-
+{{- define "statusLimits" -}} +Statuses can contain up to  +{{- .instance.Configuration.Statuses.MaxCharacters }} characters, and  +{{- .instance.Configuration.Statuses.MaxMediaAttachments }} media attachments. +{{- end -}} -
-

Features

-
    -
  • - Registration is - {{if .instance.Registrations}} - enabled{{if .instance.ApprovalRequired}}, but requires admin approval{{end}}. - {{else}} - disabled. - {{end}} -
  • - {{if .instance.Configuration.Accounts.AllowCustomCSS}} -
  • - Users are allowed to set Custom CSS for their profiles. -
  • - {{end}} -
  • - Toots can contain up to {{.instance.Configuration.Statuses.MaxCharacters}} characters and - {{.instance.Configuration.Statuses.MaxMediaAttachments}} media attachments. -
  • -
  • - Polls can have up to {{.instance.Configuration.Polls.MaxOptions}} options, with - {{.instance.Configuration.Polls.MaxCharactersPerOption}} characters each. -
  • -
-
+{{- define "pollLimits" -}} +Polls can have up to  +{{- .instance.Configuration.Polls.MaxOptions }} options, with  +{{- .instance.Configuration.Polls.MaxCharactersPerOption }} characters per option. +{{- end -}} -
-

Moderated servers

-

- ActivityPub instances exchange (federate) data with other instances, including accounts and toots. - This can be prevented for specific domains by suspending them. None of their content is stored, - and interaction with their users is blocked both ways.
- {{if .blocklistExposed}} - View the list of suspended domains - {{else}} - This instance does not publically share this list. - {{end}} -

-
- -
-

Instance Statistics

-
    -
  • Users: {{.instance.Stats.user_count}}
  • -
  • Posts: {{.instance.Stats.status_count}}
  • -
  • Federates with: {{.instance.Stats.domain_count}} instances
  • -
-
-
+{{- with . }} +
+
+

About {{ .instance.Title -}}

+ {{- with . }} + {{- include "description" . | indent 2 }} + {{- end }} +
+
+

Admin Contact

+ {{- if .instance.ContactAccount }} + + {{- else }} +

This instance has not yet set a contact account.

+ {{- end }} + {{- if .instance.Email }} +

Email: {{- .instance.Email -}}

+ {{- else }} +

This instance has not yet set a contact email address.

+ {{- end }} +
+
+

Languages

+ {{- if .languages }} +

This instance prefers the following languages:

+
    + {{- range .languages }} +
  1. {{- . -}}
  2. + {{- end }} +
+ {{- else }} +

This instance does not have any preferred languages.

+ {{- end }} +
+
+

Instance Rules

+

This instance has the following rules:

+ {{- if .instance.Rules }} +
    + {{- range .instance.Rules }} +
  1. {{- .Text -}}
  2. + {{- end }} +
+ {{- else }} +

This instance has not yet set any rules.

+ {{- end }} +
+
+

Instance Features

+
    +
  • {{- template "registrationLimits" . -}}
  • +
  • {{- template "customCSSLimits" . -}}
  • +
  • {{- template "statusLimits" . -}}
  • +
  • {{- template "pollLimits" . -}}
  • +
+
+
+

Moderated servers

+

+ ActivityPub instances federate with other instances by exchanging data with them over the network. + Exchanged data includes things like accounts, statuses, likes, boosts, and media attachments. + This exchange of data can prevented for instances on specific domains via a domain block created + by an instance admin. When an instance is domain blocked by another instance: +

+
    +
  • Any existing data from the blocked instance is deleted from the storage of the instance doing the blocking.
  • +
  • Interaction between the two instances is cut off in both directions; neither instance can interact with the other.
  • +
  • No new data from the blocked instance will be created on the instance that blocks it.
  • +
+

+ {{- if .blocklistExposed }} + View the list of domains blocked by this instance + {{- else }} + This instance does not publically share their list of blocked domains. + {{- end }} +

+
-{{ template "footer.tmpl" .}} \ No newline at end of file +{{- end }} \ No newline at end of file diff --git a/web/template/authorize.tmpl b/web/template/authorize.tmpl index ada078968..9be094137 100644 --- a/web/template/authorize.tmpl +++ b/web/template/authorize.tmpl @@ -17,26 +17,24 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} -
-
-

Hi {{.user}}!

-

- Application {{.appname}} - {{if len .appwebsite | eq 0 | not}} - ({{.appwebsite}}) - {{end}} - would like to perform actions on your behalf, with scope {{.scope}}. -

-

The application will redirect to {{.redirect}} to continue.

-

- -

-
-
-{{ template "footer.tmpl" .}} \ No newline at end of file +{{- with . }} +
+
+

Hi {{ .user -}}!

+

+ Application + {{- if .appwebsite }} + {{- .appname -}} + {{- else }} + {{- .appname -}} + {{- end }} + would like to perform actions on your behalf, with scope + {{- .scope -}}. +

+

+ To continue, the application will redirect to: {{- .redirect -}} +

+ +
+
+{{- end }} \ No newline at end of file diff --git a/web/template/confirmed.tmpl b/web/template/confirmed.tmpl index 3cf5b7ac9..c1633a8fb 100644 --- a/web/template/confirmed.tmpl +++ b/web/template/confirmed.tmpl @@ -17,12 +17,11 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} +{{- with . }}
-
-

Email Address Confirmed

-

Thanks {{.username}}! Your email address {{.email}} has been confirmed.

-

+
+

Email Address Confirmed

+

Thanks {{ .username -}}! Your email address {{- .email -}} has been confirmed.

+

- -{{ template "footer.tmpl" .}} \ No newline at end of file +{{- end }} \ No newline at end of file diff --git a/web/template/domain-blocklist.tmpl b/web/template/domain-blocklist.tmpl index def1b990e..9a21796f9 100644 --- a/web/template/domain-blocklist.tmpl +++ b/web/template/domain-blocklist.tmpl @@ -17,36 +17,36 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} +{{- with . }}
-
-

Suspended Instances

-

- The following list of domains have been suspended by the administrator(s) of this server. -

-

- All current and future accounts on these instances are blocked, and no more data is federated to the remote - servers. - This extends to subdomains, so an entry for 'example.com' includes 'social.example.com' as well. -

-
-
-
Domain
-
Public comment
-
- {{range .blocklist}} -
- -
-

- {{.PublicComment}} -

-
-
- {{end}} -
-
+
+

Suspended Instances

+

+ The following list of domains have been suspended + by the administrator(s) of this server. +

+

+ All current and future accounts on these instances are + blocked, and no more data is federated to the remote servers. + This extends to subdomains, so an entry for 'example.com' + includes 'social.example.com' as well. +

+
+
+
Domain
+
Public comment
+
+ {{- range .blocklist }} +
+ +
+

{{- .PublicComment -}}

+
+
+ {{- end }} +
+
-{{ template "footer.tmpl" .}} \ No newline at end of file +{{- end }} \ No newline at end of file diff --git a/web/template/error.tmpl b/web/template/error.tmpl index dc0713e43..816062e27 100644 --- a/web/template/error.tmpl +++ b/web/template/error.tmpl @@ -17,16 +17,16 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} +{{- with . }}
-
-

An error occured:

-
{{.error}}
- {{if .requestID}} -
- Request ID: {{.requestID}} -
- {{end}} -
+
+

An error occured:

+
{{- .error -}}
+ {{- if .requestID }} +
+ Request ID: {{- .requestID -}} +
+ {{- end }} +
-{{ template "footer.tmpl" .}} \ No newline at end of file +{{- end }} \ No newline at end of file diff --git a/web/template/finalize.tmpl b/web/template/finalize.tmpl index e0d880db7..56ab677e5 100644 --- a/web/template/finalize.tmpl +++ b/web/template/finalize.tmpl @@ -17,34 +17,31 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} -
-
-

Hi {{.name}}!

-

- You are about to sign-up to {{ .instance.Title }} ({{ .instance.URI }}) -
- To ensure the best experience for you, we need you to provide some additional details. -

- {{if .error}} -
-
{{.error}}
-
- {{end}} -
-

Important

-

Due to the way the ActivityPub standard works, you cannot change your username after it has been set.

-
-
- - -
- - -
-
-{{ template "footer.tmpl" .}} +{{- with . }} +
+
+

Hi {{ .name -}}!

+

+ You are about to sign-up to {{ .instance.Title -}}. + To ensure the best experience for you, we need you to provide some additional details. +

+
+

Important

+

Due to the way the ActivityPub standard works, you cannot change your username after it has been set.

+
+
+ + +
+ + +
+
+{{- end }} \ No newline at end of file diff --git a/web/template/footer.tmpl b/web/template/footer.tmpl deleted file mode 100644 index 028a27ffb..000000000 --- a/web/template/footer.tmpl +++ /dev/null @@ -1,46 +0,0 @@ -{{- /* -// GoToSocial -// Copyright (C) GoToSocial Authors admin@gotosocial.org -// SPDX-License-Identifier: AGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -*/ -}} - - -
- -
- {{ if .javascript }} - {{ range .javascript }} - - {{ end }} - {{ end }} - - \ No newline at end of file diff --git a/web/template/frontend.tmpl b/web/template/frontend.tmpl index 977a7fab4..8e5267f4a 100644 --- a/web/template/frontend.tmpl +++ b/web/template/frontend.tmpl @@ -17,9 +17,8 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} +{{- with . }}
-
-
+
-{{ template "footer.tmpl" .}} \ No newline at end of file +{{- end }} \ No newline at end of file diff --git a/web/template/header.tmpl b/web/template/header.tmpl deleted file mode 100644 index 2759ab804..000000000 --- a/web/template/header.tmpl +++ /dev/null @@ -1,122 +0,0 @@ -{{- /* -// GoToSocial -// Copyright (C) GoToSocial Authors admin@gotosocial.org -// SPDX-License-Identifier: AGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -*/ -}} - - -{{- /* - NESTED TEMPLATE DECLARATIONS - If some if/else macro is used multiple times, declare it once here instead. - When invoking these nested templates, remember to pass in the values passed - to the executing template, ie., use '{{ template "example" . }}' not - '{{ template "example" }}', otherwise you'll end up with empty variables. -*/ -}} -{{ define "thumbnailType" }}{{ if .instance.ThumbnailType }}{{ .instance.ThumbnailType }}{{ else }}image/png{{ end }}{{ end }} -{{ define "instanceTitle" }}{{ if .ogMeta }}{{ .ogMeta.Title }}{{ else }}{{ .instance.Title }} - GoToSocial{{ end }}{{ end }} - -{{- /* - BOILERPLATE GOES HERE -*/ -}} - - - - - - - - - {{- /* - ROBOTS META TAGS - If this template was provided with a specific robots meta policy, use that. - Otherwise, fall back to a default restrictive policy. - See: https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag - */ -}} - - - {{- /* - OPEN GRAPH META TAGS - To enable fancy previews of links to GtS posts/profiles shared via instant - messaging, or other social media, parse out provided Open Graph meta tags. - */ -}} - {{ if .ogMeta -}} - {{ if .ogMeta.Locale }}{{ end }} - - - - - - {{ if .ogMeta.ArticlePublisher }} - - - - - {{ end }} - {{ if .ogMeta.ProfileUsername }}{{ end }} - - {{ if .ogMeta.ImageAlt }}{{ end }} - {{ if .ogMeta.ImageWidth }} - - - {{ end }} - {{- end }} - - {{- /* - ICON - For icon, provide a link to the instance thumbnail. If the instance admin has - set a custom thumbnail, use the type they uploaded, else assume image/png. - See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel#icon - */ -}} - - - - - {{- /* - RSS FEED - To enable automatic rss feed discovery for feed readers, provide the 'alternate' - link only if rss is enabled. - See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel#alternate - */ -}} - {{ if .rssFeed -}} - - {{- end }} - - {{- /* - STYLESHEET STUFF - To try to speed up rendering a little bit, offer a preload for each stylesheet. - See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload. - */ -}} - - - {{ range .stylesheets }}{{ end }} - - - {{ range .stylesheets }}{{ end }} - {{ template "instanceTitle" . }} - - - -
-
- - {{ if .instance.ThumbnailDescription }}{{ .instance.ThumbnailDescription }}{{ else }}Instance Logo{{ end }} -

- {{ .instance.Title }} -

-
-
-
\ No newline at end of file diff --git a/web/template/index.tmpl b/web/template/index.tmpl index 665ce7a7e..f27cf8570 100644 --- a/web/template/index.tmpl +++ b/web/template/index.tmpl @@ -17,61 +17,21 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} -
- home to {{.instance.Stats.user_count}} users - who posted {{.instance.Stats.status_count}} statuses, - federating with {{.instance.Stats.domain_count}} other instances. -
-
-
-
- {{.instance.ShortDescription |noescape}} -
-
-
-

- GoToSocial does not provide its own webclient, but implements the Mastodon client API. - You can use this server through a variety of other clients: -

-
-
- -
-

Semaphore

-

Semaphore is a web client designed for speed and simplicity.

- Use Semaphore -
-
-
- -
-

Tusky

-

Tusky is a lightweight mobile client for Android.

- Get Tusky -
-
-
- -
-

Feditext

-

Feditext (beta) is a beautiful client for iOS, iPadOS and macOS.

- Get Feditext -
-
-
- -
-

More clients

-

Or try one of the clients listed on the official Mastodon page.

- Get Mastodon apps -
-
-
-
+{{- define "shortDescription" -}} +{{- if .instance.ShortDescription }} +{{ .instance.ShortDescription | noescape }} +{{- else }} +

No short description has yet been set for this instance.

+{{- end }} +{{- end -}} + +{{- with . }} +

+
+

About this instance

+ {{- include "shortDescription" . | indent 2 }} + See more details +
+ {{- include "index_apps.tmpl" . | indent 1 }}
-{{ template "footer.tmpl" .}} +{{- end }} \ No newline at end of file diff --git a/web/template/index_apps.tmpl b/web/template/index_apps.tmpl new file mode 100644 index 000000000..05a4a9517 --- /dev/null +++ b/web/template/index_apps.tmpl @@ -0,0 +1,115 @@ +{{- /* +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ -}} + +{{- with . }} +
+

Client applications

+

+ GoToSocial does not provide its own webclient, but implements the Mastodon client API. + You can use this server through a variety of other clients: +

+
    +
  • +
    +

    Semaphore is a web client designed for speed and simplicity.

    + + Use Semaphore + +
    + +
  • +
  • +
    +

    Tusky is a lightweight mobile client for Android.

    + + Get Tusky + +
    + +
  • +
  • +
    +

    Feditext (beta) is a beautiful client for iOS, iPadOS and macOS.

    + + Get Feditext + +
    + +
  • +
  • +
    +

    Or try one of the Mastodon clients listed on the official Mastodon page.

    + + Get Mastodon apps + +
    + +
  • +
+
+{{- end }} \ No newline at end of file diff --git a/web/template/oob.tmpl b/web/template/oob.tmpl index 0f183c350..ff36582e7 100644 --- a/web/template/oob.tmpl +++ b/web/template/oob.tmpl @@ -17,12 +17,12 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} +{{- with . }}
-
-

Hi {{ .user }}!

-

Here's your out-of-band token with scope "{{.scope}}", use it wisely:

- {{ .oobToken }} -
+
+

Hi {{ .user -}}!

+

Here's your out-of-band token with scope "{{- .scope -}}", use it wisely:

+ {{- .oobToken -}} +
-{{ template "footer.tmpl" .}} \ No newline at end of file +{{- end }} \ No newline at end of file diff --git a/web/template/page.tmpl b/web/template/page.tmpl new file mode 100644 index 000000000..347caf33e --- /dev/null +++ b/web/template/page.tmpl @@ -0,0 +1,85 @@ +{{- /* +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ -}} + +{{- /* + NESTED TEMPLATE DECLARATIONS + If some if/else macro is used multiple times, declare it once here instead. + When invoking these nested templates, remember to pass in the values passed + to the executing template, ie., use '{{ template "example" . }}' not + '{{ template "example" }}', otherwise you'll end up with empty variables. +*/ -}} + +{{- define "thumbnailType" -}} +{{- if .instance.ThumbnailType -}} +{{- .instance.ThumbnailType -}} +{{- else -}} +image/png +{{- end -}} +{{- end -}} + +{{- define "instanceTitle" -}} +{{- if .ogMeta -}} +{{- demojify .ogMeta.Title | noescape -}} +{{- else -}} +{{- .instance.Title }} - GoToSocial +{{- end -}} +{{- end -}} + + + + + + + + + {{- if .ogMeta }} + {{- include "page_ogmeta.tmpl" . | indent 2 }} + {{- else }} + {{- end }} + {{- if .rssFeed }} + + {{- else }} + {{- end }} + {{- if .account }} + + {{- else if .status }} + + {{- else }} + {{- end }} + + + + {{- include "page_stylesheets.tmpl" . | indent 2 }} + {{- range .javascript }} + + {{- end }} + {{- template "instanceTitle" . -}} + + + +
+ {{- include .pageContent . | indent 3 | outdentPre }} +
+
+ {{- include "page_footer.tmpl" . | indent 3 }} +
+ + \ No newline at end of file diff --git a/web/template/page_footer.tmpl b/web/template/page_footer.tmpl new file mode 100644 index 000000000..a00f4dfde --- /dev/null +++ b/web/template/page_footer.tmpl @@ -0,0 +1,67 @@ +{{- /* +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ -}} + +{{- with . }} + +{{- end }} \ No newline at end of file diff --git a/web/template/page_header.tmpl b/web/template/page_header.tmpl new file mode 100644 index 000000000..dc727d144 --- /dev/null +++ b/web/template/page_header.tmpl @@ -0,0 +1,72 @@ +{{- /* +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ -}} + +{{- define "thumbnailDescription" -}} +{{- if .instance.ThumbnailDescription -}} +{{- .instance.ThumbnailDescription -}} +{{- else -}} +Instance Logo +{{- end -}} +{{- end -}} + +{{- define "strapUsers" -}} +{{- with .instance.Stats.user_count -}} + {{- if eq . 1 -}} + {{- . -}} user + {{- else -}} + {{- . -}} users + {{- end -}} +{{- end -}} +{{- end -}} + +{{- define "strapPosts" -}} +{{- with .instance.Stats.status_count -}} + {{- if eq . 1 -}} + {{- . -}} post + {{- else -}} + {{- . -}} posts + {{- end -}} +{{- end -}} +{{- end -}} + +{{- define "strapInstances" -}} +{{- with .instance.Stats.domain_count -}} + {{- if eq . 1 -}} + {{- . -}} other instance + {{- else -}} + {{- . -}} other instances + {{- end -}} +{{- end -}} +{{- end -}} + +{{- with . }} + + {{- template +

{{- .instance.Title -}}

+
+{{- if .showStrap }} + +{{- end }} +{{- end }} \ No newline at end of file diff --git a/web/template/page_ogmeta.tmpl b/web/template/page_ogmeta.tmpl new file mode 100644 index 000000000..82bb4bbfb --- /dev/null +++ b/web/template/page_ogmeta.tmpl @@ -0,0 +1,57 @@ +{{- /* +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ -}} + +{{- /* + OPEN GRAPH META TAGS + To enable fancy previews of links to GtS posts/profiles shared via instant + messaging, or other social media, parse out provided Open Graph meta tags. +*/ -}} + +{{- with .ogMeta }} +{{- if .Locale }} + +{{- else }} +{{- end }} + + + + + +{{- if .ArticlePublisher }} + + + + +{{- else }} +{{- end }} +{{- if .ProfileUsername }} + +{{- else }} +{{- end }} + +{{- if .ImageAlt }} + +{{- else }} +{{- end }} +{{- if .ImageWidth }} + + +{{- else }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/web/template/page_stylesheets.tmpl b/web/template/page_stylesheets.tmpl new file mode 100644 index 000000000..9234607f8 --- /dev/null +++ b/web/template/page_stylesheets.tmpl @@ -0,0 +1,41 @@ +{{- /* +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ -}} + +{{- /* + Order of stylesheet loading is important: _colors and base should always be loaded + before any other provided sheets, since the latter cascade from the former. + + To try to speed up rendering a little bit, offer a preload for each stylesheet. + See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload. +*/ -}} + +{{- with . }} + + + +{{- range .stylesheets }} + +{{- end }} + + + +{{- range .stylesheets }} + +{{- end }} +{{- end }} \ No newline at end of file diff --git a/web/template/profile.tmpl b/web/template/profile.tmpl index 4207b39e8..0b079db10 100644 --- a/web/template/profile.tmpl +++ b/web/template/profile.tmpl @@ -17,129 +17,123 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} - +{{- with . }}
-
-
- {{ if .account.Header }} - - {{ end }} -
- -
- Profile for - {{if .account.DisplayName}}{{.account.DisplayName}}{{else}}{{.account.Username}}{{end}}. - Username @{{.account.Username}}, {{.instance.AccountDomain}}. - {{ if and (.account.Role) (ne .account.Role.Name "user") }} - Role: {{ .account.Role.Name }} - {{ end }} -
-
- -
- -
-
-

About

-
- -
- {{ range .account.Fields }} -
- {{emojify $.account.Emojis (noescape .Name)}} - {{emojify $.account.Emojis (noescape .Value)}} -
- {{ end }} -
- -
- {{ if .account.Note }} - {{emojify .account.Emojis (noescape .account.Note)}} - {{else}} - This GoToSocial user hasn't written a bio yet! - {{end}} -
- -
- Joined on {{.account.CreatedAt | timestampVague}}. - {{.account.StatusesCount}} post{{if .account.StatusesCount | eq 1 | not}}s{{end}}. - Followed by {{.account.FollowersCount}}. - Following {{.account.FollowingCount}}. -
- - -
- -
- {{ if .pinned_statuses }} -
-

Pinned posts

- jump to recent -
-
- {{ range .pinned_statuses }} -
- {{ template "status.tmpl" .}} -
- {{ end }} -
- {{ end }} - -
-

Recent posts

- {{ if .rssFeed }} - - - - {{ end }} -
- -
- {{ if not .statuses }} -
Nothing here!
- {{ else }} - {{ range .statuses }} -
- {{ template "status.tmpl" .}} -
- {{ end }} - {{ end }} -
- - -
-
+

Profile for {{ .account.Username -}}

+
+
+ Header for {{ .account.Username -}} +
+
+ + Avatar for {{ .account.Username -}} + +
+
Display name
+
+ {{- if .account.DisplayName -}} + {{- emojify .account.Emojis (escape .account.DisplayName) -}} + {{- else -}} + {{- .account.Username -}} + {{- end -}} +
+
Username
+
@{{- .account.Username -}}@{{- .instance.AccountDomain -}}
+ {{- if and (.account.Role) (ne .account.Role.Name "user") }} +
Role
+
{{- .account.Role.Name -}}
+ {{- end }} +
+
+
+
+
+
+

About {{- .account.Username -}}

+
+ {{- if .account.Fields }} + {{- include "profile_fields.tmpl" . | indent 3 }} + {{- end }} +

Bio

+
+ {{- if .account.Note }} + {{ emojify .account.Emojis (noescape .account.Note) }} + {{- else }} +

This GoToSocial user hasn't written a bio yet!

+ {{- end }} +
+

Stats

+
+
Joined
+
+
Posts
+
{{- .account.StatusesCount -}}
+
Followed by
+
{{- .account.FollowersCount -}}
+
Following
+
{{- .account.FollowingCount -}}
+
+
+
+ {{- if .pinned_statuses }} +
+
+

Pinned posts

+ jump to recent +
+
+ {{- range .pinned_statuses }} +
+ {{- include "status.tmpl" . | indent 6 }} +
+ {{- end }} +
+
+ {{- end }} +
+
+

Recent posts

+ {{- if .rssFeed }} + + + + {{- end }} +
+
+ {{- if not .statuses }} +
Nothing here!
+ {{- else }} + {{- range .statuses }} +
+ {{- include "status.tmpl" . | indent 6 }} +
+ {{- end }} + {{- end }} +
+ +
+
+
- -{{ template "footer.tmpl" .}} \ No newline at end of file +{{- end }} \ No newline at end of file diff --git a/web/template/profile_fields.tmpl b/web/template/profile_fields.tmpl new file mode 100644 index 000000000..e9005d4c9 --- /dev/null +++ b/web/template/profile_fields.tmpl @@ -0,0 +1,32 @@ +{{- /* +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +*/ -}} + +{{- with . }} +
+

Fields

+
+ {{- range .account.Fields }} +
+
{{- emojify $.account.Emojis (noescape .Name) -}}
+
{{- emojify $.account.Emojis (noescape .Value) -}}
+
+ {{- end }} +
+
+{{- end }} \ No newline at end of file diff --git a/web/template/sign-in.tmpl b/web/template/sign-in.tmpl index e2a985b9c..916d6942f 100644 --- a/web/template/sign-in.tmpl +++ b/web/template/sign-in.tmpl @@ -17,10 +17,10 @@ // along with this program. If not, see . */ -}} -{{ template "header.tmpl" .}} +{{- with . }}
-
-{{ template "footer.tmpl" .}} +{{- end }} \ No newline at end of file diff --git a/web/template/status.tmpl b/web/template/status.tmpl index eb6c6a6c6..de2167d88 100644 --- a/web/template/status.tmpl +++ b/web/template/status.tmpl @@ -17,88 +17,74 @@ // along with this program. If not, see . */ -}} -Open thread -
- - - - - - {{- if .Account.DisplayName -}} - {{- emojify .Account.Emojis (escape .Account.DisplayName) -}}. Username: @{{ .Account.Acct -}}. - {{- else -}} - @{{- .Account.Acct -}}. - {{- end -}} - - -
-
- {{- if .SpoilerText }} -
- - {{- emojify .Emojis (escape .SpoilerText) -}} - Toggle visibility - -
-
- {{ emojify .Emojis (noescape .Content) }} -
- {{- if .Poll }} - {{ template "status_poll.tmpl" . }} - {{- end }} -
-
- {{- else }} -
-
- {{ emojify .Emojis (noescape .Content) }} -
- {{- if .Poll }} - {{ template "status_poll.tmpl" . }} - {{- end }} -
- {{- end }} - {{- if .MediaAttachments }} - {{ template "status_attachments.tmpl" . }} - {{- end }} -
-