├── assets ├── images │ ├── preloader.gif │ ├── default-skin.png │ └── default-skin.svg ├── fonts │ ├── inter-roman.woff2 │ ├── eb-garamond-italic.woff2 │ ├── eb-garamond-roman.woff2 │ ├── jetbrains-mono-roman.woff2 │ └── jetbrains-mono-italic.woff2 ├── js │ ├── lib │ │ ├── reframe.min.js │ │ ├── imagesloaded.pkgd.min.js │ │ ├── photoswipe-ui-default.min.js │ │ └── photoswipe.min.js │ ├── main.js │ ├── pagination.js │ ├── dropdown.js │ └── lightbox.js └── built │ └── source.js ├── partials ├── search-toggle.hbs ├── icons │ ├── twitter.hbs │ ├── search.hbs │ ├── arrow.hbs │ ├── rss.hbs │ ├── burger.hbs │ ├── avatar.hbs │ ├── close.hbs │ ├── facebook.hbs │ ├── fire.hbs │ ├── youtube.hbs │ ├── lock.hbs │ ├── bluesky.hbs │ ├── checkmark.hbs │ ├── tiktok.hbs │ ├── loader.hbs │ ├── linkedin.hbs │ ├── mastodon.hbs │ ├── threads.hbs │ └── instagram.hbs ├── email-subscription.hbs ├── typography │ ├── fonts.hbs │ ├── sans.hbs │ ├── serif.hbs │ └── mono.hbs ├── components │ ├── featured.hbs │ ├── header.hbs │ ├── cta.hbs │ ├── footer.hbs │ ├── navigation.hbs │ ├── header-content.hbs │ └── post-list.hbs ├── feature-image.hbs ├── content-cta.hbs ├── lightbox.hbs └── post-card.hbs ├── index.hbs ├── .gitignore ├── home.hbs ├── page.hbs ├── locales ├── zh.json ├── zh-CN.json ├── en.json ├── nl.json ├── uk.json ├── pt-BR.json ├── fr.json ├── sv.json ├── gd.json ├── ga.json ├── de.json └── de-CH.json ├── tag.hbs ├── LICENSE ├── default.hbs ├── post.hbs ├── README.md ├── author.hbs ├── gulpfile.js └── package.json /assets/images/preloader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SourceTheme-i18n/Source/HEAD/assets/images/preloader.gif -------------------------------------------------------------------------------- /assets/fonts/inter-roman.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SourceTheme-i18n/Source/HEAD/assets/fonts/inter-roman.woff2 -------------------------------------------------------------------------------- /assets/images/default-skin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SourceTheme-i18n/Source/HEAD/assets/images/default-skin.png -------------------------------------------------------------------------------- /assets/fonts/eb-garamond-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SourceTheme-i18n/Source/HEAD/assets/fonts/eb-garamond-italic.woff2 -------------------------------------------------------------------------------- /assets/fonts/eb-garamond-roman.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SourceTheme-i18n/Source/HEAD/assets/fonts/eb-garamond-roman.woff2 -------------------------------------------------------------------------------- /assets/fonts/jetbrains-mono-roman.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SourceTheme-i18n/Source/HEAD/assets/fonts/jetbrains-mono-roman.woff2 -------------------------------------------------------------------------------- /assets/fonts/jetbrains-mono-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SourceTheme-i18n/Source/HEAD/assets/fonts/jetbrains-mono-italic.woff2 -------------------------------------------------------------------------------- /partials/search-toggle.hbs: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /partials/icons/twitter.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /partials/icons/search.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /partials/icons/arrow.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /partials/icons/rss.hbs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /partials/icons/burger.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.hbs: -------------------------------------------------------------------------------- 1 | {{!< default}} 2 | {{!-- The tag above means: insert everything in this file into the body of the default.hbs template --}} 3 | 4 |
5 | {{> "components/post-list" feed="index" postFeedStyle=@custom.post_feed_style showTitle=true showSidebar=@custom.show_publication_info_sidebar}} 6 |
-------------------------------------------------------------------------------- /partials/icons/avatar.hbs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /partials/icons/close.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | b-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | npm-debug.log 15 | node_modules 16 | package-lock.json 17 | 18 | .idea/* 19 | *.iml 20 | projectFilesBackup 21 | 22 | .DS_Store 23 | 24 | dist/ 25 | 26 | config.json 27 | changelog.md 28 | changelog.md.bk 29 | -------------------------------------------------------------------------------- /partials/email-subscription.hbs: -------------------------------------------------------------------------------- 1 |
2 | 3 | 8 |

9 |
10 | -------------------------------------------------------------------------------- /home.hbs: -------------------------------------------------------------------------------- 1 | {{!< default}} 2 | {{!-- The tag above means: insert everything in this file into the body of the default.hbs template --}} 3 | 4 | {{> "components/header" headerStyle=@custom.header_style}} 5 | 6 | {{#match @custom.header_style "!=" "Highlight"}} 7 | {{> "components/featured" showFeatured=@custom.show_featured_posts limit=4}} 8 | {{/match}} 9 | 10 | {{> "components/cta"}} 11 | 12 | {{> "components/post-list" feed="home" postFeedStyle=@custom.post_feed_style showTitle=true showSidebar=@custom.show_publication_info_sidebar}} -------------------------------------------------------------------------------- /partials/icons/facebook.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /partials/icons/fire.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /partials/typography/fonts.hbs: -------------------------------------------------------------------------------- 1 | {{!-- Sans-serif font is always loaded, because it's the default font for some part of the theme regardless of the settings --}} 2 | {{> "typography/sans"}} 3 | 4 | {{#match @custom.title_font "Modern sans-serif"}} 5 | {{#match @custom.body_font "Elegant serif"}} 6 | {{> "typography/serif"}} 7 | {{/match}} 8 | {{else match @custom.title_font "Elegant serif"}} 9 | {{> "typography/serif"}} 10 | {{else}} 11 | {{> "typography/mono"}} 12 | {{#match @custom.body_font "Elegant serif"}} 13 | {{> "typography/serif"}} 14 | {{/match}} 15 | {{/match}} -------------------------------------------------------------------------------- /partials/typography/sans.hbs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /partials/components/featured.hbs: -------------------------------------------------------------------------------- 1 | {{#if showFeatured}} 2 | {{#get "posts" filter="featured:true" include="authors" limit=limit as |featured|}} 3 | 13 | {{/get}} 14 | {{/if}} 15 | -------------------------------------------------------------------------------- /partials/components/header.hbs: -------------------------------------------------------------------------------- 1 | {{#match headerStyle "!=" "Off"}} 2 | 3 | {{#match headerStyle "Highlight"}} 4 | {{> "components/header-content"}} 5 | {{else match headerStyle "Magazine"}} 6 | {{> "components/header-content"}} 7 | {{else}} 8 | {{#match headerStyle "Landing"}} 9 | {{#if @site.members_enabled}} 10 | {{#unless @member}} 11 | {{> "components/header-content"}} 12 | {{/unless}} 13 | {{/if}} 14 | {{else}} 15 | {{> "components/header-content"}} 16 | {{/match}} 17 | {{/match}} 18 | 19 | {{/match}} -------------------------------------------------------------------------------- /partials/icons/youtube.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /partials/icons/lock.hbs: -------------------------------------------------------------------------------- 1 | lock-1 -------------------------------------------------------------------------------- /partials/icons/bluesky.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /partials/feature-image.hbs: -------------------------------------------------------------------------------- 1 | {{#if feature_image}} 2 |
3 | {{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}} 13 | {{#if feature_image_caption}} 14 |
{{feature_image_caption}}
15 | {{/if}} 16 |
17 | {{/if}} 18 | -------------------------------------------------------------------------------- /partials/icons/checkmark.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 24 | -------------------------------------------------------------------------------- /page.hbs: -------------------------------------------------------------------------------- 1 | {{!< default}} 2 | {{!-- The tag above means: insert everything in this file into the body of the default.hbs template --}} 3 | 4 | {{#post}} 5 | 6 |
7 |
8 | 9 | {{#match @page.show_title_and_feature_image}} 10 |
11 |

{{title}}

12 | {{#if custom_excerpt}} 13 |

{{custom_excerpt}}

14 | {{/if}} 15 | {{> "feature-image"}} 16 |
17 | {{/match}} 18 | 19 |
20 | {{content}} 21 |
22 | 23 |
24 |
25 | 26 | {{/post}} -------------------------------------------------------------------------------- /locales/zh.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "阅读更多", 3 | "Featured": "精选", 4 | "Powered by {ghostlink}": "由 {ghostlink} 强力驱动", 5 | "Search posts, tags and authors": "搜索文章、标签和作者", 6 | "Subscribe": "订阅", 7 | "Sign in": "登录", 8 | "Account": "账户", 9 | "Latest": "最新", 10 | "Upgrade": "升级", 11 | "Recommendations": "推荐", 12 | "See all": "查看全部", 13 | "Search this site": "搜索本站内容", 14 | "By": "作者", 15 | "Close (Esc)": "关闭 (Esc)", 16 | "Share": "分享", 17 | "Toggle fullscreen": "切换全屏", 18 | "Zoom in/out": "放大/缩小", 19 | "Previous (arrow left)": "上一个 (左箭头)", 20 | "Next (arrow right)": "下一个 (右箭头)", 21 | "1 min read": "阅读时间 1 分钟", 22 | "% min read": "阅读时间 % 分钟", 23 | "This content is for paying subscribers only": "此内容仅供付费订阅用户使用", 24 | "This content is for subscribers only": "此内容仅供订阅用户使用", 25 | "Upgrade your account": "升级你的账户", 26 | "Already member?": "已经是会员了?", 27 | "jamie@example.com": "張偉@範例.com" 28 | } 29 | -------------------------------------------------------------------------------- /locales/zh-CN.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "阅读更多", 3 | "Featured": "精选", 4 | "Powered by {ghostlink}": "由 {ghostlink} 强力驱动", 5 | "Search posts, tags and authors": "搜索文章、标签和作者", 6 | "Subscribe": "订阅", 7 | "Sign in": "登录", 8 | "Account": "账户", 9 | "Latest": "最新", 10 | "Upgrade": "升级", 11 | "Recommendations": "推荐", 12 | "See all": "查看全部", 13 | "Search this site": "搜索本站内容", 14 | "By": "作者", 15 | "Close (Esc)": "关闭 (Esc)", 16 | "Share": "分享", 17 | "Toggle fullscreen": "切换全屏", 18 | "Zoom in/out": "放大/缩小", 19 | "Previous (arrow left)": "上一个 (左箭头)", 20 | "Next (arrow right)": "下一个 (右箭头)", 21 | "1 min read": "阅读时间 1 分钟", 22 | "% min read": "阅读时间 % 分钟", 23 | "This content is for paying subscribers only": "此内容仅供付费订阅用户使用", 24 | "This content is for subscribers only": "此内容仅供订阅用户使用", 25 | "Upgrade your account": "升级你的账户", 26 | "Already member?": "已经是会员了?", 27 | "jamie@example.com": "张伟@示例.com" 28 | } 29 | -------------------------------------------------------------------------------- /tag.hbs: -------------------------------------------------------------------------------- 1 | {{!< default}} 2 | {{!-- The tag above means: insert everything in this file into the body of the default.hbs template --}} 3 | 4 |
5 | 6 | {{#tag}} 7 |
8 |
9 |
10 |

{{name}}

11 | {{#if description}} 12 |

{{description}}

13 | {{/if}} 14 |
15 | {{> "feature-image"}} 16 |
17 |
18 | {{/tag}} 19 | 20 | {{> "components/post-list" feed="archive" postFeedStyle=@custom.post_feed_style showTitle=false showSidebar=@custom.show_publication_info_sidebar}} 21 | 22 |
-------------------------------------------------------------------------------- /partials/content-cta.hbs: -------------------------------------------------------------------------------- 1 | {{{html}}} 2 | 21 | -------------------------------------------------------------------------------- /locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "Read more", 3 | "Featured": "Featured", 4 | "Powered by {ghostlink}": "Powered by {ghostlink}", 5 | "Search posts, tags and authors": "Search posts, tags and authors", 6 | "Subscribe": "Subscribe", 7 | "Sign in": "Sign in", 8 | "Account": "Account", 9 | "Latest": "Latest", 10 | "Upgrade": "Upgrade", 11 | "Recommendations": "Recommendations", 12 | "See all": "See all", 13 | "Search this site": "Search this site", 14 | "By": "By", 15 | "Close (Esc)": "Close (Esc)", 16 | "Share": "Share", 17 | "Toggle fullscreen": "Toggle fullscreen", 18 | "Zoom in/out": "Zoom in/out", 19 | "Previous (arrow left)": "Previous (arrow left)", 20 | "Next (arrow right)": "Next (arrow right)", 21 | "1 min read": "1 min read", 22 | "% min read": "% min read", 23 | "This content is for paying subscribers only": "This content is for paying subscribers only", 24 | "This content is for subscribers only": "This content is for subscribers only", 25 | "Upgrade your account": "Upgrade your account", 26 | "Already member?": "Already member?", 27 | "jamie@example.com": "jamie@example.com" 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2025 Ghost Foundation 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /assets/js/lib/reframe.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).reframe=t()}(this,function(){"use strict";function t(){for(var e=0,t=0,n=arguments.length;t=" 7}} 7 |
8 |
9 |
10 |

11 | {{#if @custom.signup_heading}}{{@custom.signup_heading}}{{else}}{{@site.title}}{{/if}} 12 |

13 |

14 | {{#if @custom.signup_subheading}}{{@custom.signup_subheading}}{{else}}{{@site.description}}{{/if}} 15 |

16 |
17 | {{> "email-subscription" email_field_id="cta-email"}} 18 |
19 |
20 | {{/match}} 21 | {{/match}} 22 | {{/match}} 23 | {{/match}} 24 | {{/unless}} 25 | {{/if}} -------------------------------------------------------------------------------- /locales/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "Читати далі", 3 | "Featured": "Обрані дописи", 4 | "Powered by {ghostlink}": "За підтримки {ghostlink}", 5 | "Search posts, tags and authors": "Пошук дописів, теґів та авторів", 6 | "Subscribe": "Підписатися", 7 | "Sign in": "Увійти", 8 | "Account": "Акаунт", 9 | "Latest": "Останні", 10 | "Upgrade": "Покращити", 11 | "Recommendations": "Рекомендації", 12 | "See all": "Переглянути всі", 13 | "Search this site": "Пошук на сайті", 14 | "By": "Автор", 15 | "Close (Esc)": "Закрити (Esc)", 16 | "Share": "Поділитися", 17 | "Toggle fullscreen": "Повноекранний режим", 18 | "Zoom in/out": "Збільшити/зменшити", 19 | "Previous (arrow left)": "Назад (стрілка вліво)", 20 | "Next (arrow right)": "Далі (стрілка вправо)", 21 | "1 min read": "Читати 1 хв", 22 | "% min read": "Читати % хв", 23 | "This content is for paying subscribers only": "Цей контент доступний лише для платних підписників", 24 | "This content is for subscribers only": "Цей контент доступний лише для підписників", 25 | "Upgrade your account": "Покращити свій обліковий запис", 26 | "Already member?": "Вже є учасником?", 27 | "jamie@example.com": "ivan.koval@приклад.com" 28 | } 29 | -------------------------------------------------------------------------------- /locales/pt-BR.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "Veja mais ", 3 | "Featured": "Em destaque", 4 | "Powered by {ghostlink}": "Alimentado por {ghostlink}", 5 | "Search posts, tags and authors": "Encontrar publicações, tópicos e autores", 6 | "Subscribe": "Inscreva-se", 7 | "Sign in": "Login", 8 | "Account": "Conta", 9 | "Latest": "Recente", 10 | "Upgrade": "Atualizar", 11 | "Recommendations": "Recomendações", 12 | "See all": "Veja todos", 13 | "Search this site": "Encontrar neste site", 14 | "By": "Por", 15 | "Close (Esc)": "Fechar (Esc)", 16 | "Share": "Compartilhar", 17 | "Toggle fullscreen": "Alternar para tela cheia", 18 | "Zoom in/out": "Aumentar/Diminuir zoom", 19 | "Previous (arrow left)": "Anterior (botão esquerdo)", 20 | "Next (arrow right)": "Próximo (botão direito)", 21 | "1 min read": "1 min de leitura", 22 | "% min read": "% min de leitura", 23 | "This content is for paying subscribers only": "Este conteúdo é exclusivo para assinantes", 24 | "This content is for subscribers only": "Este conteúdo é apenas para inscritos", 25 | "Upgrade your account": "Atualize sua conta", 26 | "Already member?": "Já é inscrito?", 27 | "jamie@example.com": "joao.silva@exemplo.com" 28 | } 29 | -------------------------------------------------------------------------------- /partials/typography/serif.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /partials/icons/tiktok.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /partials/typography/mono.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /locales/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "Lire la suite", 3 | "Featured": "En vedette", 4 | "Powered by {ghostlink}": "Propulsé par {ghostlink}", 5 | "Search posts, tags and authors": "Rechercher parmi les posts, tags et auteurs", 6 | "Subscribe": "S'inscrire", 7 | "Sign in": "Connexion", 8 | "Account": "Mon compte", 9 | "Latest": "Nouveautés", 10 | "Upgrade": "Mise à niveau", 11 | "Recommendations": "Recommendations", 12 | "See all": "Voir tout", 13 | "Search this site": "Rechercher sur ce site", 14 | "By": "Par", 15 | "Close (Esc)": "Fermer (Esc)", 16 | "Share": "Partager", 17 | "Toggle fullscreen": "Basculer en plein écran", 18 | "Zoom in/out": "Zoom avant/arrière", 19 | "Previous (arrow left)": "Précédent (flèche gauche)", 20 | "Next (arrow right)": "Suivant (flèche droite)", 21 | "1 min read": "1 min de lecture", 22 | "% min read": "% min de lecture", 23 | "This content is for paying subscribers only": "Ce contenu est réservé aux abonnés payants", 24 | "This content is for subscribers only": "Ce contenu est réservé aux abonnés", 25 | "Upgrade your account": "Mettez votre compte à niveau", 26 | "Already member?": "Déja membre?", 27 | "jamie@example.com": "jean.martin@exemple.com" 28 | } 29 | -------------------------------------------------------------------------------- /locales/sv.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "Läs mer", 3 | "Featured": "Utvalt", 4 | "Powered by {ghostlink}": "Drivs av {ghostlink}", 5 | "Search posts, tags and authors": "Sök inlägg, taggar och författare", 6 | "Subscribe": "Prenumerera", 7 | "Sign in": "Logga in", 8 | "Account": "Konto", 9 | "Latest": "Senaste", 10 | "Upgrade": "Uppgradera", 11 | "Recommendations": "Rekommendationer", 12 | "See all": "Visa alla", 13 | "Search this site": "Sök på webbplatsen", 14 | "By": "Av", 15 | "Close (Esc)": "Stäng (Esc)", 16 | "Share": "Dela", 17 | "Toggle fullscreen": "Växla fullskärm", 18 | "Zoom in/out": "Zooma in/ut", 19 | "Previous (arrow left)": "Föregående (arrow left)", 20 | "Next (arrow right)": "Nästa (arrow right)", 21 | "1 min read": "1 min läsning", 22 | "% min read": "% min läsning", 23 | "This content is for paying subscribers only": "Det här innehållet är endast för betalande medlemmar", 24 | "This content is for subscribers only": "Det här innehållet är endast för medlemmar", 25 | "Upgrade your account": "Uppgradera ditt konto", 26 | "Already member?": "Redan medlem?", 27 | "jamie@example.com": "karl.johansson@exempel.com" 28 | } 29 | 30 | -------------------------------------------------------------------------------- /partials/icons/loader.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 16 | 17 | -------------------------------------------------------------------------------- /locales/gd.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "Barrachd leughaidh", 3 | "Featured": "Brosnaichte", 4 | "Powered by {ghostlink}": "Le cumhachd {ghostlink}", 5 | "Search posts, tags and authors": "Lorg anns na postaichean, tagaichean agus sgrìobhadairean", 6 | "Subscribe": "Fo-sgrìobh", 7 | "Sign in": "Clàraich a-steach", 8 | "Account": "Cunntas", 9 | "Latest": "As ùire", 10 | "Upgrade": "Àrdaich", 11 | "Recommendations": "Molaidhean", 12 | "See all": "Seall na h-uile", 13 | "Search this site": "Rannsaich an làrach-lìn seo", 14 | "By": "Le", 15 | "Close (Esc)": "Dùin (Esc)", 16 | "Share": "Co-roinn", 17 | "Toggle fullscreen": "Toglaich am modh làn-sgrìn", 18 | "Zoom in/out": "Leudaich/Lùghdaich", 19 | "Previous (arrow left)": "Air ais (arrow left)", 20 | "Next (arrow right)": "Air adhart (arrow right)", 21 | "1 min read": "Àm leughaidh: 1m", 22 | "% min read": "Àm leughaidh: %m", 23 | "This content is for paying subscribers only": "Feumar fò-sgrìobhadh paighte airson an t-susbaint seo fhaicinn", 24 | "This content is for subscribers only": "Feumar fò-sgrìobhadh airson an t-susbaint seo fhaicinn", 25 | "Upgrade your account": "Àrdaich ìre a' chunntais agad", 26 | "Already member?": "A bheil thu nad bhall mar thà?", 27 | "jamie@example.com": "alasdair.macdonald@eisimpleir.com" 28 | } 29 | -------------------------------------------------------------------------------- /locales/ga.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "Tuilleadh léitheoireachta", 3 | "Featured": "Aibhsithe", 4 | "Powered by {ghostlink}": "Le cumhacht {ghostlink}", 5 | "Search posts, tags and authors": "Cuardaigh i bpostálacha, clibeanna agus scríbhneoirí", 6 | "Subscribe": "Liostáil", 7 | "Sign in": "Logáil isteach", 8 | "Account": "Cuntas", 9 | "Latest": "Is déanaí", 10 | "Upgrade": "Uasghrádaigh", 11 | "Recommendations": "Moltaí", 12 | "See all": "Taispeáin iad uile", 13 | "Search this site": "Cuardaigh an suíomh gréasáin seo", 14 | "By": "Le", 15 | "Close (Esc)": "Dún (Esc)", 16 | "Share": "Comhroinn", 17 | "Toggle fullscreen": "Scoránaigh an módh lánscáileáin", 18 | "Zoom in/out": "Zúmáil isteach/amach", 19 | "Previous (arrow left)": "Ar ais (arrow left)", 20 | "Next (arrow right)": "Ar aghaidh (arrow right)", 21 | "1 min read": "Am léamha: 1m", 22 | "% min read": "Am léamha: %m", 23 | "This content is for paying subscribers only": "Tá suibscríbhinn íoctha ag teastáil chun an t-ábhar seo a fheiceáil", 24 | "This content is for subscribers only": "Tá suibscríbhinn ag teastáil chun an t-ábhar seo a fheiceáil", 25 | "Upgrade your account": "Uasghrádaigh leibhéal do chuntais", 26 | "Already member?": "An bhfuil tú cláraithe cheana féin?", 27 | "jamie@example.com": "sean.oceallaigh@sampla.com" 28 | } 29 | -------------------------------------------------------------------------------- /locales/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "Lies mehr", 3 | "Featured": "Hervorgehoben", 4 | "Powered by {ghostlink}": "Läuft mit {ghostlink}", 5 | "Search posts, tags and authors": "Suche nach Beiträgen, Schlagwörtern und Autoren", 6 | "Subscribe": "Abonnieren", 7 | "Sign in": "Einloggen", 8 | "Account": "Konto", 9 | "Latest": "Neu", 10 | "Upgrade": "Upgrade", 11 | "Recommendations": "Empfehlungen", 12 | "See all": "Alles ansehen", 13 | "Search this site": "Suche auf dieser Webseite", 14 | "By": "Von", 15 | "Close (Esc)": "Schließen (ESC)", 16 | "Share": "Teilen", 17 | "Toggle fullscreen": "Vollbildanzeige", 18 | "Zoom in/out": "Zoomen", 19 | "Previous (arrow left)": "Vorheriges Bild (Linke Pfeiltaste)", 20 | "Next (arrow right)": "Nächstes Bild (Rechte Pfeiltaste)", 21 | "1 min read": "Lesezeit: 1 Minute", 22 | "% min read": "Lesezeit: % Minuten", 23 | "This content is for paying subscribers only": "Dieser Inhalt ist nur mit bezahltem Abo sichtbar", 24 | "This content is for subscribers only": "Dieser Inhalt ist nur mit Abo sichtbar", 25 | "This content is for subscribers on the following tiers only:": "Dieser Inhalt ist nur für folgende Mitgliedschafts-Stufen sichtbar:", 26 | "Upgrade your account": "Mitgliedschafts-Stufe anpassen", 27 | "Already member?": "Bereits Mitglied?", 28 | "jamie@example.com": "max.mustermann@beispiel.com" 29 | } 30 | -------------------------------------------------------------------------------- /locales/de-CH.json: -------------------------------------------------------------------------------- 1 | { 2 | "Read more": "Lies mehr", 3 | "Featured": "Hervorgehoben", 4 | "Powered by {ghostlink}": "Läuft mit {ghostlink}", 5 | "Search posts, tags and authors": "Suche nach Beiträgen, Schlagwörtern und Autoren", 6 | "Subscribe": "Abonnieren", 7 | "Sign in": "Einloggen", 8 | "Account": "Konto", 9 | "Latest": "Neu", 10 | "Upgrade": "Upgrade", 11 | "Recommendations": "Empfehlungen", 12 | "See all": "Alles ansehen", 13 | "Search this site": "Suche auf dieser Webseite", 14 | "By": "Von", 15 | "Close (Esc)": "Schliessen (ESC)", 16 | "Share": "Teilen", 17 | "Toggle fullscreen": "Vollbildanzeige", 18 | "Zoom in/out": "Zoomen", 19 | "Previous (arrow left)": "Vorheriges Bild (Linke Pfeiltaste)", 20 | "Next (arrow right)": "Nächstes Bild (Rechte Pfeiltaste)", 21 | "1 min read": "Lesezeit: 1 Minute", 22 | "% min read": "Lesezeit: % Minuten", 23 | "This content is for paying subscribers only": "Dieser Inhalt ist nur mit bezahltem Abo sichtbar", 24 | "This content is for subscribers only": "Dieser Inhalt ist nur mit Abo sichtbar", 25 | "This content is for subscribers on the following tiers only:": "Dieser Inhalt ist nur für folgende Mitgliedschafts-Stufen sichtbar:", 26 | "Upgrade your account": "Mitgliedschafts-Stufe anpassen", 27 | "Already member?": "Bereits Mitglied?", 28 | "jamie@example.com": "hans.muster@beispiel.com" 29 | } 30 | -------------------------------------------------------------------------------- /partials/icons/linkedin.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/default-skin.svg: -------------------------------------------------------------------------------- 1 | default-skin 2 -------------------------------------------------------------------------------- /partials/icons/mastodon.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /partials/components/footer.hbs: -------------------------------------------------------------------------------- 1 | 36 | -------------------------------------------------------------------------------- /partials/lightbox.hbs: -------------------------------------------------------------------------------- 1 | 42 | -------------------------------------------------------------------------------- /partials/icons/threads.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/js/main.js: -------------------------------------------------------------------------------- 1 | /* Mobile menu burger toggle */ 2 | (function () { 3 | const navigation = document.querySelector('.gh-navigation'); 4 | const burger = navigation.querySelector('.gh-burger'); 5 | if (!burger) return; 6 | 7 | burger.addEventListener('click', function () { 8 | if (!navigation.classList.contains('is-open')) { 9 | navigation.classList.add('is-open'); 10 | document.documentElement.style.overflowY = 'hidden'; 11 | } else { 12 | navigation.classList.remove('is-open'); 13 | document.documentElement.style.overflowY = null; 14 | } 15 | }); 16 | })(); 17 | 18 | /* Add lightbox to gallery images */ 19 | (function () { 20 | lightbox( 21 | '.kg-image-card > .kg-image[width][height], .kg-gallery-image > img' 22 | ); 23 | })(); 24 | 25 | /* Responsive video in post content */ 26 | (function () { 27 | const sources = [ 28 | '.gh-content iframe[src*="youtube.com"]', 29 | '.gh-content iframe[src*="youtube-nocookie.com"]', 30 | '.gh-content iframe[src*="player.vimeo.com"]', 31 | '.gh-content iframe[src*="kickstarter.com"][src*="video.html"]', 32 | '.gh-content object', 33 | '.gh-content embed', 34 | ]; 35 | reframe(document.querySelectorAll(sources.join(','))); 36 | })(); 37 | 38 | /* Turn the main nav into dropdown menu when there are more than 5 menu items */ 39 | (function () { 40 | dropdown(); 41 | })(); 42 | 43 | /* Infinite scroll pagination */ 44 | (function () { 45 | if (!document.body.classList.contains('home-template') && !document.body.classList.contains('post-template')) { 46 | pagination(); 47 | } 48 | })(); 49 | 50 | /* Responsive HTML table */ 51 | (function () { 52 | const tables = document.querySelectorAll('.gh-content > table:not(.gist table)'); 53 | 54 | tables.forEach(function (table) { 55 | const wrapper = document.createElement('div'); 56 | wrapper.className = 'gh-table'; 57 | table.parentNode.insertBefore(wrapper, table); 58 | wrapper.appendChild(table); 59 | }); 60 | })(); -------------------------------------------------------------------------------- /partials/post-card.hbs: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{#if feature_image}} 4 |
5 | {{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}} 17 |
18 | {{/if}} 19 |
20 | {{#if primary_tag}} 21 |

{{primary_tag.name}}

22 | {{/if}} 23 |

{{title}}

24 | {{#if custom_excerpt}} 25 |

{{custom_excerpt}}

26 | {{/if}} 27 | {{#unless custom_excerpt}} 28 | {{#if excerpt}} 29 |

{{excerpt}}

30 | {{/if}} 31 | {{/unless}} 32 |
33 | {{#unless access}} 34 | {{^has visibility="public"}} 35 | {{> "icons/lock"}} 36 | {{/has}} 37 | {{/unless}}{{#if @custom.show_author}} 39 | {{t "By"}} {{#foreach authors}}{{#if @first}}{{name}}{{else}}, {{name}}{{/if}}{{/foreach}} 40 | {{/if}} 41 | {{#if @custom.show_publish_date}} 42 | 43 | {{/if}}
45 |
46 |
47 |
48 | -------------------------------------------------------------------------------- /partials/components/navigation.hbs: -------------------------------------------------------------------------------- 1 | 54 | -------------------------------------------------------------------------------- /default.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{!-- Basic meta - advanced meta is output with {{ghost_head}} below --}} 6 | {{meta_title}} 7 | 8 | 9 | 10 | {{!-- Preload main styles and scripts for better performance --}} 11 | 12 | 13 | 14 | {{!-- Fonts are preloaded and defined in the default template to avoid layout shift --}} 15 | {{> "typography/fonts"}} 16 | 17 | {{!-- Theme assets - use the {{asset}} helper to reference styles & scripts, this will take care of caching and cache-busting automatically --}} 18 | 19 | 20 | {{!-- Custom background color --}} 21 | 26 | 27 | 45 | 46 | {{!-- This tag outputs all your advanced SEO meta, structured data, and other important settings, it should always be the last tag before the closing head tag --}} 47 | {{ghost_head}} 48 | 49 | 50 | 51 | 52 |
53 | 54 | {{> "components/navigation" navigationLayout=@custom.navigation_layout}} 55 | 56 | {{{body}}} 57 | 58 | {{> "components/footer"}} 59 | 60 |
61 | 62 | {{#is "post, page"}} 63 | {{> "lightbox"}} 64 | {{/is}} 65 | 66 | {{!-- Scripts - handle responsive videos, infinite scroll, and navigation dropdowns --}} 67 | 68 | 69 | {{!-- Ghost outputs required functional scripts with this tag, it should always be the last thing before the closing body tag --}} 70 | {{ghost_foot}} 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /post.hbs: -------------------------------------------------------------------------------- 1 | {{!< default}} 2 | {{!-- The tag above means: insert everything in this file into the body of the default.hbs template --}} 3 | 4 | {{#post}} 5 | 6 |
7 | 8 |
9 | 10 |
11 | 12 | {{#if primary_tag}} 13 | 14 | {{/if}} 15 |

{{title}}

16 | {{#if custom_excerpt}} 17 |

{{custom_excerpt}}

18 | {{/if}} 19 | 20 | {{#if @custom.show_post_metadata}} 21 | 43 | {{/if}} 44 | 45 | {{> "feature-image"}} 46 | 47 |
48 | 49 |
50 | {{content}} 51 |
52 | 53 |
54 | 55 | {{#if comments}} 56 |
57 | {{comments}} 58 |
59 | {{/if}} 60 | 61 |
62 | 63 | {{/post}} 64 | 65 | {{#if @custom.show_related_articles}} 66 | {{#get "posts" include="authors" filter="id:-{{post.id}}" limit="4" as |next|}} 67 | {{#if next}} 68 |
69 |
70 |

{{t "Read more"}}

71 |
72 | {{#foreach next}} 73 | {{> "post-card" lazyLoad=true}} 74 | {{/foreach}} 75 |
76 |
77 |
78 | {{/if}} 79 | {{/get}} 80 | {{/if}} 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Source-i18n 2 | 3 | :warning: This is a fork of the https://github.com/TryGhost/Source theme to add translations. 4 | Only translations are accepted as pull/merge-requests. :warning: 5 | 6 | For other changes, please propose your change to the upstream: 7 | https://github.com/TryGhost/Source 8 | 9 | 10 | # Source 11 | 12 | The default theme for [Ghost](http://github.com/tryghost/ghost/). This is a fork of the development version of Source with some customization. Especially the theme was made translateable. 13 | 14 | If you're just looking to download the original release, head over to the [releases](https://github.com/TryGhost/Source/releases) page. 15 | 16 |   17 | 18 | # First time using a Ghost theme? 19 | 20 | Ghost uses a simple templating language called [Handlebars](http://handlebarsjs.com/) for its themes. 21 | 22 | This theme has lots of code comments to help explain what's going on just by reading the code. Once you feel comfortable with how everything works, we also have full [theme API documentation](https://ghost.org/docs/themes/) which explains every possible Handlebars helper and template. 23 | 24 | **The main files are:** 25 | 26 | - `default.hbs` - The parent template file, which includes your global header/footer 27 | - `home.hbs` - The homepage 28 | - `index.hbs` - The main template to generate a list of posts 29 | - `post.hbs` - The template used to render individual posts 30 | - `page.hbs` - Used for individual pages 31 | - `tag.hbs` - Used for tag archives, eg. "all posts tagged with `news`" 32 | - `author.hbs` - Used for author archives, eg. "all posts written by Jamie" 33 | 34 | One neat trick is that you can also create custom one-off templates by adding the slug of a page to a template file. For example: 35 | 36 | - `page-about.hbs` - Custom template for an `/about/` page 37 | - `tag-news.hbs` - Custom template for `/tag/news/` archive 38 | - `author-ali.hbs` - Custom template for `/author/ali/` archive 39 | 40 | 41 | # Development 42 | 43 | Source styles are compiled using Gulp/PostCSS to polyfill future CSS spec. You'll need [Node](https://nodejs.org/), [Yarn](https://yarnpkg.com/) and [Gulp](https://gulpjs.com) installed globally. After that, from the theme's root directory: 44 | 45 | ```bash 46 | # install dependencies 47 | yarn install 48 | 49 | # run development server 50 | yarn dev 51 | ``` 52 | 53 | Now you can edit `/assets/css/` files, which will be compiled to `/assets/built/` automatically. 54 | 55 | The `zip` Gulp task packages the theme files into `dist/.zip`, which you can then upload to your site. 56 | 57 | ```bash 58 | # create .zip file 59 | yarn zip 60 | ``` 61 | 62 | # PostCSS Features Used 63 | 64 | - Autoprefixer - Don't worry about writing browser prefixes of any kind, it's all done automatically with support for the latest 2 major versions of every browser. 65 | 66 | 67 | # SVG Icons 68 | 69 | Source uses inline SVG icons, included via Handlebars partials. You can find all icons inside `/partials/icons`. To use an icon just include the name of the relevant file, eg. To include the SVG icon in `/partials/icons/rss.hbs` - use `{{> "icons/rss"}}`. 70 | 71 | You can add your own SVG icons in the same manner. 72 | 73 | 74 | # Copyright & License 75 | 76 | Copyright (c) 2013-2025 Ghost Foundation - Released under the [MIT license](LICENSE). 77 | -------------------------------------------------------------------------------- /partials/icons/instagram.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/js/pagination.js: -------------------------------------------------------------------------------- 1 | function pagination(isInfinite = true, done, isMasonry = false) { 2 | const feedElement = document.querySelector('.gh-feed'); 3 | if (!feedElement) return; 4 | 5 | let loading = false; 6 | const target = document.querySelector('.gh-footer'); 7 | const buttonElement = document.querySelector('.gh-loadmore'); 8 | 9 | if (!document.querySelector('link[rel=next]') && buttonElement) { 10 | buttonElement.remove(); 11 | } 12 | 13 | const loadNextPage = async function () { 14 | const nextElement = document.querySelector('link[rel=next]'); 15 | if (!nextElement) return; 16 | 17 | try { 18 | const res = await fetch(nextElement.href); 19 | const html = await res.text(); 20 | const parser = new DOMParser(); 21 | const doc = parser.parseFromString(html, 'text/html'); 22 | 23 | const postElements = doc.querySelectorAll('.gh-feed:not(.gh-featured):not(.gh-related) > *'); 24 | const fragment = document.createDocumentFragment(); 25 | const elems = []; 26 | 27 | postElements.forEach(function (post) { 28 | var clonedItem = document.importNode(post, true); 29 | 30 | if (isMasonry) { 31 | clonedItem.style.visibility = 'hidden'; 32 | } 33 | 34 | fragment.appendChild(clonedItem); 35 | elems.push(clonedItem); 36 | }); 37 | 38 | feedElement.appendChild(fragment); 39 | 40 | if (done) { 41 | done(elems, loadNextWithCheck); 42 | } 43 | 44 | const resNextElement = doc.querySelector('link[rel=next]'); 45 | if (resNextElement && resNextElement.href) { 46 | nextElement.href = resNextElement.href; 47 | } else { 48 | nextElement.remove(); 49 | if (buttonElement) { 50 | buttonElement.remove(); 51 | } 52 | } 53 | } catch (e) { 54 | nextElement.remove(); 55 | throw e; 56 | } 57 | }; 58 | 59 | const loadNextWithCheck = async function () { 60 | if (target.getBoundingClientRect().top <= window.innerHeight && document.querySelector('link[rel=next]')) { 61 | await loadNextPage(); 62 | } 63 | } 64 | 65 | const callback = async function (entries) { 66 | if (loading) return; 67 | 68 | loading = true; 69 | 70 | if (entries[0].isIntersecting) { 71 | // keep loading next page until target is out of the viewport or we've loaded the last page 72 | if (!isMasonry) { 73 | while (target.getBoundingClientRect().top <= window.innerHeight && document.querySelector('link[rel=next]')) { 74 | await loadNextPage(); 75 | } 76 | } else { 77 | await loadNextPage(); 78 | } 79 | } 80 | 81 | loading = false; 82 | 83 | if (!document.querySelector('link[rel=next]')) { 84 | observer.disconnect(); 85 | } 86 | }; 87 | 88 | const observer = new IntersectionObserver(callback); 89 | 90 | if (isInfinite) { 91 | observer.observe(target); 92 | } else { 93 | buttonElement.addEventListener('click', loadNextPage); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /partials/components/header-content.hbs: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{!-- Background image --}} 4 | {{#if @custom.background_image}} 5 | {{#match headerStyle "!=" "Magazine"}} 6 | {{#match headerStyle "!=" "Highlight"}} 7 | {{#if @site.cover_image}} 8 | {{@site.title}} 9 | {{/if}} 10 | {{/match}} 11 | {{/match}} 12 | {{/if}} 13 | 14 |
15 | 16 | {{!-- Highlight layout --}} 17 | {{#match headerStyle "Highlight"}} 18 |
19 | {{#foreach posts limit="1"}} 20 | {{> "post-card" imageSizes="(max-width: 767px) calc(100vw - max(8vmin, 40px)), 640px"}} 21 | {{/foreach}} 22 |
23 |
24 | {{#foreach posts from="2" limit="3"}} 25 | {{> "post-card"}} 26 | {{/foreach}} 27 |
28 |
29 | {{#if @custom.show_featured_posts}} 30 | {{> "components/featured" showFeatured=@custom.show_featured_posts limit=6}} 31 | {{else}} 32 | 37 | {{/if}} 38 |
39 | {{/match}} 40 | 41 | {{!-- Magazine layout --}} 42 | {{#match headerStyle "Magazine"}} 43 | {{#foreach posts limit="7"}} 44 | {{#match @number 2}} 45 |
46 | {{/match}} 47 | {{#match @number 5}} 48 |
49 | {{/match}} 50 | {{#if @first}} 51 | {{> "post-card" imageSizes="640px"}} 52 | {{else}} 53 | {{> "post-card"}} 54 | {{/if}} 55 | {{#match @number 4}} 56 |
57 | {{/match}} 58 | {{#match @number 7}} 59 |
60 | {{/match}} 61 | {{/foreach}} 62 | {{/match}} 63 | 64 | {{!-- Landing layout --}} 65 | {{#match headerStyle "Landing"}} 66 |

{{#if @custom.header_text}}{{@custom.header_text}}{{else}}{{@site.description}}{{/if}}

67 | {{> "email-subscription" email_field_id="header-email"}} 68 | {{/match}} 69 | 70 | {{!-- Search layout --}} 71 | {{#match headerStyle "Search"}} 72 |

{{#if @custom.header_text}}{{@custom.header_text}}{{else}}{{@site.description}}{{/if}}

73 |
74 | {{> "icons/search"}} 75 | 76 |
77 | {{/match}} 78 | 79 |
80 | 81 |
82 | -------------------------------------------------------------------------------- /assets/js/dropdown.js: -------------------------------------------------------------------------------- 1 | function dropdown() { 2 | const mediaQuery = window.matchMedia('(max-width: 767px)'); 3 | 4 | const head = document.querySelector('.gh-navigation'); 5 | const menu = head.querySelector('.gh-navigation-menu'); 6 | const nav = menu?.querySelector('.nav'); 7 | if (!nav) return; 8 | 9 | const logo = document.querySelector('.gh-navigation-logo'); 10 | const navHTML = nav.innerHTML; 11 | 12 | if (mediaQuery.matches) { 13 | const items = nav.querySelectorAll('li'); 14 | items.forEach(function (item, index) { 15 | item.style.transitionDelay = `${0.03 * (index + 1)}s`; 16 | }); 17 | } 18 | 19 | const makeDropdown = function () { 20 | if (mediaQuery.matches) return; 21 | const submenuItems = []; 22 | 23 | while ((nav.offsetWidth + 64) > menu.offsetWidth) { 24 | if (nav.lastElementChild) { 25 | submenuItems.unshift(nav.lastElementChild); 26 | nav.lastElementChild.remove(); 27 | } else { 28 | break; 29 | } 30 | } 31 | 32 | if (!submenuItems.length) { 33 | head.classList.add('is-dropdown-loaded'); 34 | return; 35 | } 36 | 37 | const toggle = document.createElement('button'); 38 | toggle.setAttribute('class', 'gh-more-toggle gh-icon-button'); 39 | toggle.setAttribute('aria-label', 'More'); 40 | toggle.innerHTML = ''; 41 | 42 | const wrapper = document.createElement('div'); 43 | wrapper.setAttribute('class', 'gh-dropdown'); 44 | 45 | if (submenuItems.length >= 10) { 46 | head.classList.add('is-dropdown-mega'); 47 | wrapper.style.gridTemplateRows = `repeat(${Math.ceil(submenuItems.length / 2)}, 1fr)`; 48 | } else { 49 | head.classList.remove('is-dropdown-mega'); 50 | } 51 | 52 | submenuItems.forEach(function (child) { 53 | wrapper.appendChild(child); 54 | }); 55 | 56 | toggle.appendChild(wrapper); 57 | nav.appendChild(toggle); 58 | 59 | const toggleRect = toggle.getBoundingClientRect(); 60 | const documentCenter = window.innerWidth / 2; 61 | 62 | if (toggleRect.left < documentCenter) { 63 | wrapper.classList.add('is-left'); 64 | } 65 | 66 | head.classList.add('is-dropdown-loaded'); 67 | 68 | window.addEventListener('click', function (e) { 69 | if (head.classList.contains('is-dropdown-open')) { 70 | head.classList.remove('is-dropdown-open'); 71 | } else if (toggle.contains(e.target)) { 72 | head.classList.add('is-dropdown-open'); 73 | } 74 | }); 75 | } 76 | 77 | imagesLoaded(logo, function () { 78 | makeDropdown(); 79 | }); 80 | 81 | window.addEventListener('load', function () { 82 | if (!logo) { 83 | makeDropdown(); 84 | } 85 | }); 86 | 87 | window.addEventListener('resize', function () { 88 | setTimeout(() => { 89 | nav.innerHTML = navHTML; 90 | makeDropdown(); 91 | }, 1); 92 | }); 93 | } 94 | -------------------------------------------------------------------------------- /author.hbs: -------------------------------------------------------------------------------- 1 | {{!< default}} 2 | {{!-- The tag above means: insert everything in this file into the body of the default.hbs template --}} 3 | 4 |
5 | 6 | {{#author}} 7 |
8 |
9 |
10 |

11 | {{#if website}} 12 | {{name}} 13 | {{else}} 14 | {{name}} 15 | {{/if}} 16 |

17 | {{#if bio}} 18 |

{{bio}}

19 | {{/if}} 20 | 54 |
55 | {{#if profile_image}} 56 | {{name}} 57 | {{/if}} 58 |
59 |
60 | {{/author}} 61 | 62 | {{> "components/post-list" feed="archive" postFeedStyle=@custom.post_feed_style showTitle=false showSidebar=@custom.show_publication_info_sidebar}} 63 | 64 |
-------------------------------------------------------------------------------- /assets/js/lightbox.js: -------------------------------------------------------------------------------- 1 | function lightbox(trigger) { 2 | var onThumbnailsClick = function (e) { 3 | e.preventDefault(); 4 | 5 | var items = []; 6 | var index = 0; 7 | 8 | var prevSibling = e.target.closest('.kg-card').previousElementSibling; 9 | 10 | while (prevSibling && (prevSibling.classList.contains('kg-image-card') || prevSibling.classList.contains('kg-gallery-card'))) { 11 | var prevItems = []; 12 | 13 | prevSibling.querySelectorAll('img').forEach(function (item) { 14 | prevItems.push({ 15 | src: item.getAttribute('src'), 16 | msrc: item.getAttribute('src'), 17 | w: item.getAttribute('width'), 18 | h: item.getAttribute('height'), 19 | el: item, 20 | }) 21 | 22 | index += 1; 23 | }); 24 | prevSibling = prevSibling.previousElementSibling; 25 | 26 | items = prevItems.concat(items); 27 | } 28 | 29 | if (e.target.classList.contains('kg-image')) { 30 | items.push({ 31 | src: e.target.getAttribute('src'), 32 | msrc: e.target.getAttribute('src'), 33 | w: e.target.getAttribute('width'), 34 | h: e.target.getAttribute('height'), 35 | el: e.target, 36 | }); 37 | } else { 38 | var reachedCurrentItem = false; 39 | 40 | e.target.closest('.kg-gallery-card').querySelectorAll('img').forEach(function (item) { 41 | items.push({ 42 | src: item.getAttribute('src'), 43 | msrc: item.getAttribute('src'), 44 | w: item.getAttribute('width'), 45 | h: item.getAttribute('height'), 46 | el: item, 47 | }); 48 | 49 | if (!reachedCurrentItem && item !== e.target) { 50 | index += 1; 51 | } else { 52 | reachedCurrentItem = true; 53 | } 54 | }); 55 | } 56 | 57 | var nextSibling = e.target.closest('.kg-card').nextElementSibling; 58 | 59 | while (nextSibling && (nextSibling.classList.contains('kg-image-card') || nextSibling.classList.contains('kg-gallery-card'))) { 60 | nextSibling.querySelectorAll('img').forEach(function (item) { 61 | items.push({ 62 | src: item.getAttribute('src'), 63 | msrc: item.getAttribute('src'), 64 | w: item.getAttribute('width'), 65 | h: item.getAttribute('height'), 66 | el: item, 67 | }) 68 | }); 69 | nextSibling = nextSibling.nextElementSibling; 70 | } 71 | 72 | var pswpElement = document.querySelectorAll('.pswp')[0]; 73 | 74 | var options = { 75 | bgOpacity: 0.9, 76 | closeOnScroll: true, 77 | fullscreenEl: false, 78 | history: false, 79 | index: index, 80 | shareEl: false, 81 | zoomEl: false, 82 | getThumbBoundsFn: function(index) { 83 | var thumbnail = items[index].el, 84 | pageYScroll = window.pageYOffset || document.documentElement.scrollTop, 85 | rect = thumbnail.getBoundingClientRect(); 86 | 87 | return {x:rect.left, y:rect.top + pageYScroll, w:rect.width}; 88 | } 89 | } 90 | 91 | var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options); 92 | gallery.init(); 93 | 94 | return false; 95 | }; 96 | 97 | var triggers = document.querySelectorAll(trigger); 98 | triggers.forEach(function (trig) { 99 | trig.addEventListener('click', function (e) { 100 | onThumbnailsClick(e); 101 | }); 102 | }); 103 | } 104 | -------------------------------------------------------------------------------- /assets/js/lib/imagesloaded.pkgd.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * imagesLoaded PACKAGED v4.1.4 3 | * JavaScript is all like "You images are done yet or what?" 4 | * MIT License 5 | */ 6 | 7 | !function(e,t){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",t):"object"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}("undefined"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o { 31 | return function (err) { 32 | if (err) { 33 | beeper(); 34 | } 35 | return done(err); 36 | }; 37 | }; 38 | 39 | function hbs(done) { 40 | pump([ 41 | src(['*.hbs', 'partials/**/*.hbs']), 42 | livereload() 43 | ], handleError(done)); 44 | } 45 | 46 | function css(done) { 47 | pump([ 48 | src('assets/css/screen.css', {sourcemaps: true}), 49 | postcss([ 50 | easyimport, 51 | autoprefixer(), 52 | cssnano() 53 | ]), 54 | dest('assets/built/', {sourcemaps: '.'}), 55 | livereload() 56 | ], handleError(done)); 57 | } 58 | 59 | function js(done) { 60 | pump([ 61 | src([ 62 | // pull in lib files first so our own code can depend on it 63 | 'assets/js/lib/*.js', 64 | 'assets/js/*.js' 65 | ], {sourcemaps: true}), 66 | concat('source.js'), 67 | uglify(), 68 | dest('assets/built/', {sourcemaps: '.'}), 69 | livereload() 70 | ], handleError(done)); 71 | } 72 | 73 | function zipper(done) { 74 | const filename = require('./package.json').name + '.zip'; 75 | 76 | pump([ 77 | src([ 78 | '**', 79 | '!node_modules', '!node_modules/**', 80 | '!dist', '!dist/**', 81 | '!yarn-error.log', 82 | '!yarn.lock', 83 | '!gulpfile.js' 84 | ]), 85 | zip(filename), 86 | dest('dist/') 87 | ], handleError(done)); 88 | } 89 | 90 | const cssWatcher = () => watch('assets/css/**', css); 91 | const jsWatcher = () => watch('assets/js/**', js); 92 | const hbsWatcher = () => watch(['*.hbs', 'partials/**/*.hbs'], hbs); 93 | const watcher = parallel(cssWatcher, jsWatcher, hbsWatcher); 94 | const build = series(css, js); 95 | 96 | exports.build = build; 97 | exports.zip = series(build, zipper); 98 | exports.default = series(build, serve, watcher); 99 | 100 | exports.release = async () => { 101 | // @NOTE: https://yarnpkg.com/lang/en/docs/cli/version/ 102 | // require(./package.json) can run into caching issues, this re-reads from file everytime on release 103 | let packageJSON = JSON.parse(fs.readFileSync('./package.json')); 104 | const newVersion = packageJSON.version; 105 | 106 | if (!newVersion || newVersion === '') { 107 | console.log(`Invalid version: ${newVersion}`); 108 | return; 109 | } 110 | 111 | console.log(`\nCreating release for ${newVersion}...`); 112 | 113 | const githubToken = process.env.GST_TOKEN; 114 | 115 | if (!githubToken) { 116 | console.log('Please configure your environment with a GitHub token located in GST_TOKEN'); 117 | return; 118 | } 119 | 120 | try { 121 | const result = await inquirer.prompt([{ 122 | type: 'input', 123 | name: 'compatibleWithGhost', 124 | message: 'Which version of Ghost is it compatible with?', 125 | default: '5.0.0' 126 | }]); 127 | 128 | const compatibleWithGhost = result.compatibleWithGhost; 129 | 130 | const releasesResponse = await releaseUtils.releases.get({ 131 | userAgent: 'Source', 132 | uri: `https://api.github.com/repos/${REPO_READONLY}/releases` 133 | }); 134 | 135 | if (!releasesResponse || !releasesResponse) { 136 | console.log('No releases found. Skipping...'); 137 | return; 138 | } 139 | 140 | let previousVersion = releasesResponse[0].tag_name || releasesResponse[0].name; 141 | console.log(`Previous version: ${previousVersion}`); 142 | 143 | const changelog = new releaseUtils.Changelog({ 144 | changelogPath: CHANGELOG_PATH, 145 | folder: path.join(process.cwd(), '.') 146 | }); 147 | 148 | changelog 149 | .write({ 150 | githubRepoPath: `https://github.com/${REPO}`, 151 | lastVersion: previousVersion 152 | }) 153 | .sort() 154 | .clean(); 155 | 156 | const newReleaseResponse = await releaseUtils.releases.create({ 157 | draft: true, 158 | preRelease: false, 159 | tagName: 'v' + newVersion, 160 | releaseName: newVersion, 161 | userAgent: 'Source', 162 | uri: `https://api.github.com/repos/${REPO}/releases`, 163 | github: { 164 | token: githubToken 165 | }, 166 | content: [`**Compatible with Ghost ≥ ${compatibleWithGhost}**\n\n`], 167 | changelogPath: CHANGELOG_PATH 168 | }); 169 | console.log(`\nRelease draft generated: ${newReleaseResponse.releaseUrl}\n`); 170 | } catch (err) { 171 | console.error(err); 172 | process.exit(1); 173 | } 174 | }; 175 | -------------------------------------------------------------------------------- /partials/components/post-list.hbs: -------------------------------------------------------------------------------- 1 | {{!-- 2 | Parameters: 3 | * feed (index, home, archive, recent) 4 | * postFeedStyle (list, grid) 5 | * showTitle (true, false) 6 | * showSidebar (true, false) 7 | --}} 8 | 9 |
10 |
11 | 12 | {{#if showTitle}} 13 |

14 | {{#unless title}}{{t "Latest"}}{{else}}{{title}}{{/unless}} 15 |

16 | {{/if}} 17 | 18 |
19 |
20 | 21 | {{!-- Homepage --}} 22 | {{#match feed "home"}} 23 | {{#match @custom.header_style "Highlight"}} 24 | {{#if @custom.show_featured_posts}} 25 | {{#match posts.length ">=" 4}} 26 | {{#get "posts" include="authors" limit="16"}} 27 | {{#foreach posts from="5"}} 28 | {{> "post-card" lazyLoad=true}} 29 | {{/foreach}} 30 | {{/get}} 31 | {{/match}} 32 | {{else}} 33 | {{#match posts.length ">=" 10}} 34 | {{#get "posts" include="authors" limit="22"}} 35 | {{#foreach posts from="11"}} 36 | {{> "post-card" lazyLoad=true}} 37 | {{/foreach}} 38 | {{/get}} 39 | {{/match}} 40 | {{/if}} 41 | {{else match @custom.header_style "Magazine"}} 42 | {{#match posts.length ">=" 7}} 43 | {{#get "posts" include="authors" limit="19"}} 44 | {{#foreach posts from="8"}} 45 | {{> "post-card" lazyLoad=true}} 46 | {{/foreach}} 47 | {{/get}} 48 | {{/match}} 49 | {{else}} 50 | {{#get "posts" include="authors" limit="12"}} 51 | {{#foreach posts}} 52 | {{> "post-card" lazyLoad=true}} 53 | {{/foreach}} 54 | {{/get}} 55 | {{/match}} 56 | {{/match}} 57 | 58 | {{!-- All posts --}} 59 | {{#match feed "index"}} 60 | {{#match pagination.page 2}} 61 | {{#get "posts" include="authors" limit=@config.posts_per_page as |recent|}} 62 | {{#foreach recent}} 63 | {{> "post-card"}} 64 | {{/foreach}} 65 | {{/get}} 66 | {{/match}} 67 | {{#foreach posts}} 68 | {{> "post-card" lazyLoad=true}} 69 | {{/foreach}} 70 | {{/match}} 71 | 72 | {{!-- Tag and author pages --}} 73 | {{#match feed "archive"}} 74 | {{#foreach posts}} 75 | {{> "post-card" lazyLoad=true}} 76 | {{/foreach}} 77 | {{/match}} 78 | 79 |
80 | 81 | {{#match pagination.pages ">" 1}} 82 | 85 | {{/match}} 86 |
87 | 88 | {{#if showSidebar}} 89 | 120 | {{/if}} 121 | 122 |
123 |
124 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "source-i18n", 3 | "description": "A default theme for the Ghost publishing platform", 4 | "demo": "https://source.ghost.io", 5 | "version": "1.5.0-1i18n", 6 | "engines": { 7 | "ghost": ">=5.0.0" 8 | }, 9 | "license": "MIT", 10 | "scripts": { 11 | "dev": "gulp", 12 | "zip": "gulp zip", 13 | "test": "gscan .", 14 | "test:ci": "gscan --fatal --verbose .", 15 | "pretest": "gulp build", 16 | "preship": "yarn test", 17 | "ship": "STATUS=$(git status --porcelain); echo $STATUS; if [ -z \"$STATUS\" ]; then yarn version && git push --follow-tags; else echo \"Uncomitted changes found.\" && exit 1; fi", 18 | "postship": "git fetch && gulp release" 19 | }, 20 | "author": { 21 | "name": "Ghost Foundation", 22 | "email": "hello@ghost.org", 23 | "url": "https://ghost.org/" 24 | }, 25 | "gpm": { 26 | "type": "theme", 27 | "categories": [ 28 | "Minimal", 29 | "Magazine" 30 | ] 31 | }, 32 | "keywords": [ 33 | "ghost", 34 | "theme", 35 | "ghost-theme" 36 | ], 37 | "repository": { 38 | "type": "git", 39 | "url": "https://github.com/TryGhost/Source.git" 40 | }, 41 | "bugs": "https://github.com/TryGhost/Source/issues", 42 | "contributors": "https://github.com/TryGhost/Source/graphs/contributors", 43 | "devDependencies": { 44 | "@tryghost/release-utils": "0.8.1", 45 | "autoprefixer": "10.4.7", 46 | "beeper": "2.1.0", 47 | "cssnano": "5.1.12", 48 | "gscan": "4.48.0", 49 | "gulp": "4.0.2", 50 | "gulp-concat": "2.6.1", 51 | "gulp-livereload": "4.0.2", 52 | "gulp-postcss": "9.0.1", 53 | "gulp-uglify": "3.0.2", 54 | "gulp-zip": "5.1.0", 55 | "inquirer": "8.2.4", 56 | "postcss": "8.2.13", 57 | "postcss-easy-import": "4.0.0", 58 | "pump": "3.0.0" 59 | }, 60 | "browserslist": [ 61 | "defaults" 62 | ], 63 | "config": { 64 | "posts_per_page": 12, 65 | "image_sizes": { 66 | "xs": { 67 | "width": 160 68 | }, 69 | "s": { 70 | "width": 320 71 | }, 72 | "m": { 73 | "width": 600 74 | }, 75 | "l": { 76 | "width": 960 77 | }, 78 | "xl": { 79 | "width": 1200 80 | }, 81 | "xxl": { 82 | "width": 2000 83 | } 84 | }, 85 | "card_assets": true, 86 | "custom": { 87 | "navigation_layout": { 88 | "type": "select", 89 | "options": [ 90 | "Logo in the middle", 91 | "Logo on the left", 92 | "Stacked" 93 | ], 94 | "default": "Logo in the middle" 95 | }, 96 | "site_background_color": { 97 | "type": "color", 98 | "default": "#ffffff" 99 | }, 100 | "header_and_footer_color": { 101 | "type": "select", 102 | "options": [ 103 | "Background color", 104 | "Accent color" 105 | ], 106 | "default": "Background color" 107 | }, 108 | "title_font": { 109 | "type": "select", 110 | "options": [ 111 | "Modern sans-serif", 112 | "Elegant serif", 113 | "Consistent mono" 114 | ], 115 | "default": "Modern sans-serif" 116 | }, 117 | "body_font": { 118 | "type": "select", 119 | "options": [ 120 | "Modern sans-serif", 121 | "Elegant serif" 122 | ], 123 | "default": "Modern sans-serif" 124 | }, 125 | "signup_heading": { 126 | "type": "text", 127 | "description": "Used in your footer across your theme, defaults to site title when empty" 128 | }, 129 | "signup_subheading": { 130 | "type": "text", 131 | "description": "Defaults to site description when empty" 132 | }, 133 | "header_style": { 134 | "type": "select", 135 | "options": [ 136 | "Landing", 137 | "Highlight", 138 | "Magazine", 139 | "Search", 140 | "Off" 141 | ], 142 | "description": "Landing is recommended for all sites, Highlight & Magazine for those with more content", 143 | "default": "Landing", 144 | "group": "homepage" 145 | }, 146 | "header_text": { 147 | "type": "text", 148 | "group": "homepage", 149 | "description": "Defaults to site description when empty", 150 | "visibility": "header_style:[Landing, Search]" 151 | }, 152 | "background_image": { 153 | "type": "boolean", 154 | "default": true, 155 | "description": "Use the publication cover set on the Brand tab as your background", 156 | "group": "homepage", 157 | "visibility": "header_style:[Landing, Search]" 158 | }, 159 | "show_featured_posts": { 160 | "type": "boolean", 161 | "default": false, 162 | "group": "homepage", 163 | "visibility": "header_style:[Highlight, Magazine]" 164 | }, 165 | "post_feed_style": { 166 | "type": "select", 167 | "options": [ 168 | "List", 169 | "Grid" 170 | ], 171 | "default": "List", 172 | "group": "homepage" 173 | }, 174 | "show_images_in_feed": { 175 | "type": "boolean", 176 | "default": true, 177 | "group": "homepage", 178 | "visibility": "post_feed_style:List" 179 | }, 180 | "show_author": { 181 | "type": "boolean", 182 | "default": true, 183 | "group": "homepage" 184 | }, 185 | "show_publish_date": { 186 | "type": "boolean", 187 | "default": true, 188 | "group": "homepage" 189 | }, 190 | "show_publication_info_sidebar": { 191 | "type": "boolean", 192 | "default": false, 193 | "group": "homepage" 194 | }, 195 | "show_post_metadata": { 196 | "type": "boolean", 197 | "default": true, 198 | "group": "post" 199 | }, 200 | "enable_drop_caps_on_posts": { 201 | "type": "boolean", 202 | "default": false, 203 | "group": "post" 204 | }, 205 | "show_related_articles": { 206 | "type": "boolean", 207 | "default": true, 208 | "group": "post" 209 | } 210 | } 211 | }, 212 | "renovate": { 213 | "extends": [ 214 | "@tryghost:theme" 215 | ] 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /assets/js/lib/photoswipe-ui-default.min.js: -------------------------------------------------------------------------------- 1 | /*! PhotoSwipe Default UI - 4.1.3 - 2019-01-08 2 | * http://photoswipe.com 3 | * Copyright (c) 2019 Dmitry Semenov; */ 4 | !function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.PhotoSwipeUI_Default=b()}(this,function(){"use strict";var a=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v=this,w=!1,x=!0,y=!0,z={barsSize:{top:44,bottom:"auto"},closeElClasses:["item","caption","zoom-wrap","ui","top-bar"],timeToIdle:4e3,timeToIdleOutside:1e3,loadingIndicatorDelay:1e3,addCaptionHTMLFn:function(a,b){return a.title?(b.children[0].innerHTML=a.title,!0):(b.children[0].innerHTML="",!1)},closeEl:!0,captionEl:!0,fullscreenEl:!0,zoomEl:!0,shareEl:!0,counterEl:!0,arrowEl:!0,preloaderEl:!0,tapToClose:!1,tapToToggleControls:!0,clickToCloseNonZoomable:!0,shareButtons:[{id:"facebook",label:"Share on Facebook",url:"https://www.facebook.com/sharer/sharer.php?u={{url}}"},{id:"twitter",label:"Tweet",url:"https://twitter.com/intent/tweet?text={{text}}&url={{url}}"},{id:"pinterest",label:"Pin it",url:"http://www.pinterest.com/pin/create/button/?url={{url}}&media={{image_url}}&description={{text}}"},{id:"download",label:"Download image",url:"{{raw_image_url}}",download:!0}],getImageURLForShare:function(){return a.currItem.src||""},getPageURLForShare:function(){return window.location.href},getTextForShare:function(){return a.currItem.title||""},indexIndicatorSep:" / ",fitControlsWidth:1200},A=function(a){if(r)return!0;a=a||window.event,q.timeToIdle&&q.mouseUsed&&!k&&K();for(var c,d,e=a.target||a.srcElement,f=e.getAttribute("class")||"",g=0;g-1&&(c.onTap(),d=!0);if(d){a.stopPropagation&&a.stopPropagation(),r=!0;var h=b.features.isOldAndroid?600:30;s=setTimeout(function(){r=!1},h)}},B=function(){return!a.likelyTouchDevice||q.mouseUsed||screen.width>q.fitControlsWidth},C=function(a,c,d){b[(d?"add":"remove")+"Class"](a,"pswp__"+c)},D=function(){var a=1===q.getNumItemsFn();a!==p&&(C(d,"ui--one-slide",a),p=a)},E=function(){C(i,"share-modal--hidden",y)},F=function(){return y=!y,y?(b.removeClass(i,"pswp__share-modal--fade-in"),setTimeout(function(){y&&E()},300)):(E(),setTimeout(function(){y||b.addClass(i,"pswp__share-modal--fade-in")},30)),y||H(),!1},G=function(b){b=b||window.event;var c=b.target||b.srcElement;return a.shout("shareLinkClick",b,c),!!c.href&&(!!c.hasAttribute("download")||(window.open(c.href,"pswp_share","scrollbars=yes,resizable=yes,toolbar=no,location=yes,width=550,height=420,top=100,left="+(window.screen?Math.round(screen.width/2-275):100)),y||F(),!1))},H=function(){for(var a,b,c,d,e,f="",g=0;g