├── min.cljs.edn
├── resources
└── public
│ ├── images
│ ├── 16x16.png
│ ├── 32x32.png
│ ├── 48x48.png
│ └── 128x128.png
│ ├── test.html
│ ├── cljs-out
│ └── min
│ │ ├── reagent
│ │ ├── impl
│ │ │ ├── protocols.cljs
│ │ │ ├── batching.cljs
│ │ │ ├── protocols.js
│ │ │ ├── input.cljs
│ │ │ ├── input.js
│ │ │ ├── util.cljs
│ │ │ └── batching.js
│ │ ├── debug.cljs
│ │ ├── dom.cljs
│ │ ├── debug.js
│ │ └── dom.js
│ │ ├── cljsc_opts.edn
│ │ ├── cljsc_opts.json
│ │ ├── goog
│ │ ├── flags
│ │ │ └── flags.js
│ │ ├── dom
│ │ │ ├── htmlelement.js
│ │ │ ├── tags.js
│ │ │ ├── nodetype.js
│ │ │ ├── browserfeature.js
│ │ │ ├── asserts.js
│ │ │ └── element.js
│ │ ├── labs
│ │ │ └── useragent
│ │ │ │ ├── highentropy
│ │ │ │ ├── highentropydata.js
│ │ │ │ └── highentropyvalue.js
│ │ │ │ ├── useragent.js
│ │ │ │ ├── engine.js
│ │ │ │ └── util.js
│ │ ├── string
│ │ │ ├── typedstring.js
│ │ │ ├── stringbuffer.js
│ │ │ └── const.js
│ │ ├── html
│ │ │ ├── trustedtypes.js
│ │ │ ├── safescript.js
│ │ │ └── uncheckedconversions.js
│ │ ├── debug
│ │ │ └── error.js
│ │ ├── fs
│ │ │ ├── blob.js
│ │ │ └── url.js
│ │ ├── reflect
│ │ │ └── reflect.js
│ │ ├── collections
│ │ │ └── maps.js
│ │ └── math
│ │ │ ├── size.js
│ │ │ └── coordinate.js
│ │ ├── process
│ │ ├── env.js
│ │ └── env.cljs
│ │ ├── gh_colorful_contributions
│ │ ├── components
│ │ │ ├── header.js
│ │ │ └── footer.js
│ │ ├── core.js
│ │ └── data.js
│ │ └── clojure
│ │ ├── walk.cljs
│ │ ├── set.cljs
│ │ ├── walk.js
│ │ └── string.cljs
│ ├── index.html
│ ├── css
│ └── style.css
│ ├── manifest.json
│ └── js
│ ├── background.js
│ └── content_script.js
├── dev.cljs.edn
├── src
└── gh_colorful_contributions
│ ├── components
│ ├── header.cljs
│ ├── footer.cljs
│ └── panel.cljs
│ ├── core.cljs
│ └── data.cljs
├── target
└── classes
│ └── META-INF
│ └── maven
│ └── github-colorful-contributions-graph
│ └── github-colorful-contributions-graph
│ └── pom.properties
├── test
└── gh_colorful_contributions
│ ├── core_test.cljs
│ └── test_runner.cljs
├── test.cljs.edn
├── deps.edn
├── LICENSE
├── README.md
├── README_EN.md
├── figwheel-main.edn
└── project.clj
/min.cljs.edn:
--------------------------------------------------------------------------------
1 | {:main gh-colorful-contributions.core
2 | :externs ["externs/chrome.js" "externs/chrome_extensions.js"]}
3 |
--------------------------------------------------------------------------------
/resources/public/images/16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenpotatos/better-github-contributions-graph/HEAD/resources/public/images/16x16.png
--------------------------------------------------------------------------------
/resources/public/images/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenpotatos/better-github-contributions-graph/HEAD/resources/public/images/32x32.png
--------------------------------------------------------------------------------
/resources/public/images/48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenpotatos/better-github-contributions-graph/HEAD/resources/public/images/48x48.png
--------------------------------------------------------------------------------
/resources/public/images/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenpotatos/better-github-contributions-graph/HEAD/resources/public/images/128x128.png
--------------------------------------------------------------------------------
/dev.cljs.edn:
--------------------------------------------------------------------------------
1 | ^{:watch-dirs ["test" "src"]
2 | :css-dirs ["resources/public/css"]
3 | :auto-testing true
4 | :open-url false}
5 | {:main gh-colorful-contributions.core}
6 |
--------------------------------------------------------------------------------
/resources/public/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Test host page
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/reagent/impl/protocols.cljs:
--------------------------------------------------------------------------------
1 | (ns reagent.impl.protocols)
2 |
3 | (defprotocol Compiler
4 | (get-id [this])
5 | (parse-tag [this tag-name tag-value])
6 | (as-element [this x])
7 | (make-element [this argv component jsprops first-child]))
8 |
9 |
--------------------------------------------------------------------------------
/src/gh_colorful_contributions/components/header.cljs:
--------------------------------------------------------------------------------
1 | (ns gh-colorful-contributions.components.header)
2 |
3 | (defn header []
4 | [:header.section.gcc-header
5 | [:h1.title.is-4 "Better Github Contribution Gragh"]
6 | [:p.subtitle.is-6 "个性化你的 Github Contribution Gragh"]])
7 |
--------------------------------------------------------------------------------
/target/classes/META-INF/maven/github-colorful-contributions-graph/github-colorful-contributions-graph/pom.properties:
--------------------------------------------------------------------------------
1 | artifactId=github-colorful-contributions-graph
2 | groupId=github-colorful-contributions-graph
3 | revision=2083de9235484021c08de11e2547926a01477469
4 | version=5.0.1
5 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/cljsc_opts.edn:
--------------------------------------------------------------------------------
1 | {:optimizations :advanced, :main gh-colorful-contributions.core, :externs ["externs/chrome.js" "externs/chrome_extensions.js"], :output-to "resources/public/cljs-out/min-main.js", :output-dir "resources/public/cljs-out/min", :asset-path "/cljs-out/min", :aot-cache false}
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/cljsc_opts.json:
--------------------------------------------------------------------------------
1 | {"optimizations":"advanced","main":"gh_colorful_contributions.core","externs":["externs\/chrome.js","externs\/chrome_extensions.js"],"output-to":"resources\/public\/cljs-out\/min-main.js","output-dir":"resources\/public\/cljs-out\/min","asset-path":"\/cljs-out\/min","aot-cache":false}
--------------------------------------------------------------------------------
/test/gh_colorful_contributions/core_test.cljs:
--------------------------------------------------------------------------------
1 | (ns gh-colorful-contributions.core-test
2 | (:require
3 | [cljs.test :refer-macros [deftest is testing]]))
4 |
5 | (defn multiply [a b] (* a b))
6 |
7 | (deftest multiply-test
8 | (is (= (* 1 2) (multiply 1 2))))
9 |
10 | (deftest multiply-test-2
11 | (is (= (* 75 10) (multiply 10 75))))
12 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/flags/flags.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | goog.module('goog.flags');
8 | goog.module.declareLegacyNamespace();
9 |
10 | exports.USE_USER_AGENT_CLIENT_HINTS = false;
11 | exports.ASYNC_THROW_ON_UNICODE_TO_BYTE = false;
12 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/process/env.js:
--------------------------------------------------------------------------------
1 | // Compiled by ClojureScript 1.11.132 {:static-fns true, :optimize-constants true, :optimizations :advanced}
2 | goog.provide('process.env');
3 | goog.require('cljs.core');
4 | goog.require('cljs.core.constants');
5 |
6 | /**
7 | * @define {string}
8 | */
9 | process.env.NODE_ENV = goog.define("process.env.NODE_ENV","development");
10 |
--------------------------------------------------------------------------------
/test/gh_colorful_contributions/test_runner.cljs:
--------------------------------------------------------------------------------
1 | ;; This test runner is intended to be run from the command line
2 | (ns gh-colorful-contributions.test-runner
3 | (:require
4 | ;; require all the namespaces that you want to test
5 | [gh-colorful-contributions.core-test]
6 | [figwheel.main.testing :refer [run-tests-async]]))
7 |
8 | (defn -main [& args]
9 | (run-tests-async 5000))
10 |
--------------------------------------------------------------------------------
/src/gh_colorful_contributions/components/footer.cljs:
--------------------------------------------------------------------------------
1 | (ns gh-colorful-contributions.components.footer)
2 |
3 | (defn footer []
4 | [:footer.section
5 | [:p.has-text-right {:style {:font-size "0.875rem"}}
6 | "Made with ❤️ and fun by "
7 | [:span {:style {:color "seagreen" :cursor "pointer"}
8 | :on-click #(.create (.. js/chrome -tabs)
9 | (clj->js {:url "https://github.com/chenpotatos"}))} "不吃土豆泥."]]])
10 |
--------------------------------------------------------------------------------
/resources/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/resources/public/css/style.css:
--------------------------------------------------------------------------------
1 | [data-theme='dark'] {
2 | background: #0d1117;
3 | }
4 |
5 | .container {
6 | width: 450px;
7 | }
8 |
9 | .gcc-header {
10 | padding-bottom: 0;
11 | }
12 |
13 | .gcc-panel {
14 | padding-top: 0;
15 | padding-bottom: 0;
16 | }
17 |
18 | .fills > div {
19 | display: flex;
20 | margin: 0.5rem 0;
21 | }
22 |
23 | .fills input[type='radio'] {
24 | margin-right: 1rem;
25 | }
26 |
27 | .fills ul {
28 | display: flex;
29 | gap: 8px;
30 | }
31 |
32 | .fills ul > li {
33 | display: inline-block;
34 | width: 24px;
35 | height: 24px;
36 | border-radius: 4px;
37 | }
38 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/process/env.cljs:
--------------------------------------------------------------------------------
1 | ;; Copyright (c) Rich Hickey. All rights reserved.
2 | ;; The use and distribution terms for this software are covered by the
3 | ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 | ;; which can be found in the file epl-v10.html at the root of this distribution.
5 | ;; By using this software in any fashion, you are agreeing to be bound by
6 | ;; the terms of this license.
7 | ;; You must not remove this notice, or any other, from this software.
8 |
9 | (ns process.env
10 | "A shim namespace for the Node.js process library")
11 |
12 | (goog-define NODE_ENV "development")
13 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/dom/htmlelement.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | goog.provide('goog.dom.HtmlElement');
8 |
9 |
10 |
11 | /**
12 | * This subclass of HTMLElement is used when only a HTMLElement is possible and
13 | * not any of its subclasses. Normally, a type can refer to an instance of
14 | * itself or an instance of any subtype. More concretely, if HTMLElement is used
15 | * then the compiler must assume that it might still be e.g. HTMLScriptElement.
16 | * With this, the type check knows that it couldn't be any special element.
17 | *
18 | * @constructor
19 | * @extends {HTMLElement}
20 | */
21 | goog.dom.HtmlElement = function() {};
22 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/reagent/debug.cljs:
--------------------------------------------------------------------------------
1 | (ns reagent.debug
2 | (:require-macros [reagent.debug]))
3 |
4 | (def ^:const has-console (exists? js/console))
5 |
6 | (def ^boolean tracking false)
7 |
8 | (defonce warnings (atom nil))
9 |
10 | (defonce track-console
11 | (let [o #js {}]
12 | (set! (.-warn o)
13 | (fn [& args]
14 | (swap! warnings update-in [:warn] conj (apply str args))))
15 | (set! (.-error o)
16 | (fn [& args]
17 | (swap! warnings update-in [:error] conj (apply str args))))
18 | o))
19 |
20 | (defn track-warnings [f]
21 | (set! tracking true)
22 | (reset! warnings nil)
23 | (f)
24 | (let [warns @warnings]
25 | (reset! warnings nil)
26 | (set! tracking false)
27 | warns))
28 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/labs/useragent/highentropy/highentropydata.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Provides access to high-entropy user agent values.
9 | */
10 |
11 | goog.module('goog.labs.userAgent.highEntropy.highEntropyData');
12 |
13 | const {HighEntropyValue} = goog.require('goog.labs.userAgent.highEntropy.highEntropyValue');
14 |
15 | /**
16 | * @type {!HighEntropyValue|undefined>}
17 | */
18 | const fullVersionList = new HighEntropyValue('fullVersionList');
19 | exports.fullVersionList = fullVersionList;
20 |
21 | /**
22 | * @type {!HighEntropyValue}
23 | */
24 | const platformVersion = new HighEntropyValue('platformVersion');
25 | exports.platformVersion = platformVersion;
--------------------------------------------------------------------------------
/test.cljs.edn:
--------------------------------------------------------------------------------
1 | ^{
2 | ;; use an alternative landing page for the tests so that we don't
3 | ;; launch the application
4 | :open-url "http://[[server-hostname]]:[[server-port]]/test.html"
5 |
6 |
7 | ;; uncomment to launch tests in a headless Firefox environment
8 | ;; you will have to figure out the path to firefox on your system
9 | ;; :launch-js ["/Applications/Firefox.app/Contents/MacOS/firefox" "--headless" "--profile" "/tmp/headless-firefox-cljs-testing-profile" "--no-remote" "--url" :open-url]
10 |
11 | ;; Chrome
12 | ;; folks seem to have issues launching chrome different
13 | ;; environments, these flags seem to help, your milage may vary
14 | ;; :launch-js ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" "--headless" "--disable-gpu" "--disable-dev-shm" "--remote-debugging-port=9222" "--repl" :open-url]
15 |
16 | }
17 | {:main gh-colorful-contributions.test-runner}
18 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/gh_colorful_contributions/components/header.js:
--------------------------------------------------------------------------------
1 | // Compiled by ClojureScript 1.11.132 {:static-fns true, :optimize-constants true, :optimizations :advanced}
2 | goog.provide('gh_colorful_contributions.components.header');
3 | goog.require('cljs.core');
4 | goog.require('cljs.core.constants');
5 | gh_colorful_contributions.components.header.header = (function gh_colorful_contributions$components$header$header(){
6 | return new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$header$section$gcc_DASH_header,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$h1$title$is_DASH_4,"Better Github Contribution Gragh"], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$p$subtitle$is_DASH_6,"\u4E2A\u6027\u5316\u4F60\u7684 Github Contribution Gragh"], null)], null);
7 | });
8 |
--------------------------------------------------------------------------------
/deps.edn:
--------------------------------------------------------------------------------
1 | {:deps {org.clojure/clojure {:mvn/version "1.12.0"}
2 | org.clojure/clojurescript {:mvn/version "1.11.132"}
3 | org.clojure/data.json {:mvn/version "2.5.1"}
4 | cljsjs/react {:mvn/version "18.3.1-1"}
5 | cljsjs/react-dom {:mvn/version "18.3.1-1"}
6 | reagent/reagent {:mvn/version "1.2.0" }}
7 | :paths ["src" "resources"]
8 | :aliases {:fig {:extra-deps
9 | {com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}
10 | com.bhauman/figwheel-main {:mvn/version "0.2.20"}
11 | org.slf4j/slf4j-nop {:mvn/version "2.0.16"}}
12 | :extra-paths ["target" "test"]}
13 | :build {:main-opts ["-m" "figwheel.main" "-b" "dev" "-r"]}
14 | :clean {:main-opts ["-m" "figwheel.main" "--clean" "dev"]}
15 | :min {:main-opts ["-m" "figwheel.main" "-O" "advanced" "-bo" "dev"]}
16 | :test {:main-opts ["-m" "figwheel.main" "-co" "test.cljs.edn" "-m" "gh-colorful-contributions.test-runner"]}}}
17 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/dom/tags.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Utilities for HTML element tag names.
9 | */
10 | goog.provide('goog.dom.tags');
11 |
12 | goog.require('goog.object');
13 |
14 |
15 | /**
16 | * The void elements specified by
17 | * http://www.w3.org/TR/html-markup/syntax.html#void-elements.
18 | * @const @private {!Object}
19 | */
20 | goog.dom.tags.VOID_TAGS_ = goog.object.createSet(
21 | 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input',
22 | 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr');
23 |
24 |
25 | /**
26 | * Checks whether the tag is void (with no contents allowed and no legal end
27 | * tag), for example 'br'.
28 | * @param {string} tagName The tag name in lower case.
29 | * @return {boolean}
30 | */
31 | goog.dom.tags.isVoidTag = function(tagName) {
32 | 'use strict';
33 | return goog.dom.tags.VOID_TAGS_[tagName] === true;
34 | };
35 |
--------------------------------------------------------------------------------
/resources/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "GitHub Colorful Contributions",
3 | "description": "✨个性化你的 Github Contribution Gragh",
4 | "version": "5.0.1",
5 | "manifest_version": 3,
6 | "permissions": [
7 | "declarativeContent",
8 | "storage",
9 | "scripting"
10 | ],
11 | "host_permissions": [
12 | "https://github.com/*"
13 | ],
14 | "background": {
15 | "service_worker": "js/background.js"
16 | },
17 | "action": {
18 | "default_state": "disabled",
19 | "default_popup": "index.html",
20 | "default_icon": {
21 | "16": "images/16x16.png",
22 | "32": "images/32x32.png",
23 | "48": "images/48x48.png",
24 | "128": "images/128x128.png"
25 | }
26 | },
27 | "content_scripts": [
28 | {
29 | "matches": [
30 | "https://github.com/*"
31 | ],
32 | "js": [
33 | "js/obelisk.min.js",
34 | "js/content_script.js"
35 | ]
36 | }
37 | ],
38 | "icons": {
39 | "16": "images/16x16.png",
40 | "32": "images/32x32.png",
41 | "48": "images/48x48.png",
42 | "128": "images/128x128.png"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 落日飞行器
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/dom/nodetype.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Definition of goog.dom.NodeType.
9 | */
10 |
11 | goog.provide('goog.dom.NodeType');
12 |
13 |
14 | /**
15 | * Constants for the nodeType attribute in the Node interface.
16 | *
17 | * These constants match those specified in the Node interface. These are
18 | * usually present on the Node object in recent browsers, but not in older
19 | * browsers (specifically, early IEs) and thus are given here.
20 | *
21 | * In some browsers (early IEs), these are not defined on the Node object,
22 | * so they are provided here.
23 | *
24 | * See http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
25 | * @enum {number}
26 | */
27 | goog.dom.NodeType = {
28 | ELEMENT: 1,
29 | ATTRIBUTE: 2,
30 | TEXT: 3,
31 | CDATA_SECTION: 4,
32 | ENTITY_REFERENCE: 5,
33 | ENTITY: 6,
34 | PROCESSING_INSTRUCTION: 7,
35 | COMMENT: 8,
36 | DOCUMENT: 9,
37 | DOCUMENT_TYPE: 10,
38 | DOCUMENT_FRAGMENT: 11,
39 | NOTATION: 12
40 | };
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # **更好的 Github Contributions Gragh**
2 | ✨个性化你的 Github Contribution Gragh
3 |
4 | English Version of README : [Click Here](https://github.com/chenpotatos/better-github-contributions-graph/blob/main/README_EN.md)
5 | ## 💻 屏幕截图/Sreenshots
6 |
7 | 
8 |
9 |
10 | ## 🔧 二次开发/Development
11 |
12 | **Step1** 在 ./src/gh_colorful_contributions/data.cljs 中编辑
13 |
14 | 示例:
15 | ```
16 | :halloween ["#631c03", "#bd561d", "#fa7a18", "#fddf68"]
17 | ```
18 | 值得一提的是,你需要同时更改 **default-fills** 和 **dark-fills** 来确保在所有情况下脚本都会生效。
19 |
20 | **Step2** 在./resources/public/js/content_script.js 中编辑
21 |
22 | 示例:
23 | ```
24 | halloween: [defaultGreen[0], '#631c03', '#bd561d', '#fa7a18', '#fddf68']
25 | ```
26 | **Step3** 运行./build.sh
27 |
28 | **请确保你的计算机上正确配置且安装了*lein*。**
29 |
30 | 运行完成后,在项目目录下找到 release.zip,此文件为编译后的输出。
31 |
32 | ## 😽 贡献与鸣谢/Contributions
33 |
34 | [不吃土豆泥](https://github.com/chenpotatos) 主体框架与脚本
35 |
36 | [火星猫](https://github.com/Martian14000605) UI和配色建议
37 |
38 | 灵狐 UI和配色建议 **实在找不到泥的个人页面辣qwq,可以私信我把你放上去~**
39 |
40 | 本项目根据 MIT 许可证分发。
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/resources/public/js/background.js:
--------------------------------------------------------------------------------
1 | chrome.runtime.onInstalled.addListener(function () {
2 | chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
3 | chrome.declarativeContent.onPageChanged.addRules([
4 | {
5 | conditions: [
6 | new chrome.declarativeContent.PageStateMatcher({
7 | pageUrl: { hostEquals: 'github.com', schemes: ['https'] },
8 | css: ['.js-yearly-contributions'],
9 | }),
10 | ],
11 | actions: [new chrome.declarativeContent.ShowAction()],
12 | },
13 | ])
14 | })
15 | })
16 |
17 | chrome.storage.local.set({
18 | isInject: false,
19 | })
20 |
21 | chrome.runtime.onMessage.addListener(function (message) {
22 | if (message === 'runInject') {
23 | chrome.storage.local.set(
24 | {
25 | isInject: true,
26 | },
27 | async function () {
28 | const [currentTab] = await chrome.tabs.query({ active: true, currentWindow: true })
29 |
30 | chrome.scripting.executeScript({
31 | target: { tabId: currentTab.id },
32 | files: ['js/content_script.js'],
33 | })
34 | }
35 | )
36 | }
37 | })
38 |
--------------------------------------------------------------------------------
/src/gh_colorful_contributions/core.cljs:
--------------------------------------------------------------------------------
1 | (ns ^:figwheel-hooks gh-colorful-contributions.core
2 | (:require [goog.dom :as gdom]
3 | [reagent.dom :as rdom]
4 | [gh-colorful-contributions.components.header :refer [header]]
5 | [gh-colorful-contributions.components.panel :refer [panel]]
6 | [gh-colorful-contributions.components.footer :refer [footer]]))
7 |
8 | (defn get-app-element []
9 | (gdom/getElement "app"))
10 |
11 | (defn github-colorful-contributions []
12 | [:div.container
13 | [header]
14 | [:hr]
15 | [panel]
16 | [footer]])
17 |
18 | (defn mount [el]
19 | (rdom/render [github-colorful-contributions] el))
20 |
21 | (defn mount-app-element []
22 | (when-let [el (get-app-element)]
23 | (mount el)))
24 |
25 | ;; conditionally start your application based on the presence of an "app" element
26 | ;; this is particularly helpful for testing this ns without launching the app
27 | (mount-app-element)
28 |
29 | ;; specify reload hook with ^:after-load metadata
30 | (defn ^:after-load on-reload []
31 | (mount-app-element)
32 | ;; optionally touch your app-state to force rerendering depending on
33 | ;; your application
34 | ;; (swap! app-state update-in [:__figwheel_counter] inc)
35 | )
36 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | # **Better Github Contributions Gragh**
2 | ✨ Personalize your Github Contribution Gragh
3 |
4 | ## 💻 Sreenshots
5 |
6 | 
7 |
8 |
9 | ## 🔧 Development
10 |
11 | **Step1** Edit in ./src/gh_colorful_contributions/data.cljs
12 |
13 | Example:
14 | ```
15 | :halloween ["#631c03", "#bd561d", "#fa7a18", "#fddf68"]
16 | ```
17 | It's worth mentioning that you'll need to change both **default-fills** and **dark-fills** to make sure the script works in all cases.
18 |
19 | **Step2** Edit in ./resources/public/js/content_script.js
20 |
21 | Example:
22 | ```
23 | halloween: [defaultGreen[0], '#631c03', '#bd561d', '#fa7a18', '#fddf68']
24 | ```
25 | **Step3** Run ./build.sh
26 |
27 | **Make sure that *Lein* is properly configured and installed on your computer. **
28 |
29 | Once the run is complete, find the release.zip in the project directory, which is the compiled output.
30 |
31 | ## 😽 Contributions
32 |
33 | [不吃土豆泥](https://github.com/chenpotatos) Main frame and script
34 |
35 | [火星猫](https://github.com/Martian14000605) UI and color matching recommendations
36 |
37 | 灵狐 UI and color matching recommendations
38 |
39 | This project is distributed under the MIT license.
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/figwheel-main.edn:
--------------------------------------------------------------------------------
1 | ;; Figwheel-main configuration options see: https://figwheel.org/config-options
2 | ;; these will be overriden by the metadata config options in dev.cljs.edn build file
3 | {
4 | ;; Set the server port https://figwheel.org/config-options#ring-server-options
5 | ;; :ring-server-options {:port 9500}
6 |
7 | ;; Target directory https://figwheel.org/config-options#target-dir
8 | ;; you may want to set this to resources if you are using Leiningen
9 | :target-dir "resources"
10 |
11 | ;; Server Ring Handler (optional) https://figwheel.org/docs/ring-handler.html
12 | ;; If you want to embed a ring handler into the figwheel server, this
13 | ;; is for simple ring servers
14 | ;; :ring-handler hello_world.server/handler
15 |
16 | ;; To be able to open files in your editor from the heads up display
17 | ;; you will need to put a script on your path. This script will have
18 | ;; to take a file path and a line number ie.
19 | ;; in ~/bin/myfile-opener:
20 | ;;
21 | ;; #! /bin/sh
22 | ;; emacsclient -n +$2:$3 $1
23 | ;;
24 | ;; :open-file-command "myfile-opener"
25 |
26 | ;; if you are using emacsclient you can just use
27 | ;; :open-file-command "emacsclient"
28 |
29 | ;; Logging output gets printed to the REPL, if you want to redirect it to a file:
30 | ;; :log-file "figwheel-main.log"
31 | }
32 |
--------------------------------------------------------------------------------
/src/gh_colorful_contributions/data.cljs:
--------------------------------------------------------------------------------
1 | (ns gh-colorful-contributions.data)
2 |
3 | (def default-fills {:green ["#aceebb", "#4ac26b", "#2da44e", "#116329"]
4 | :blue [ "#a4c8ff", "#388bfd", "#0366d6", "#00499e"]
5 | :purple ["#d2b4ff", "#a371f7", "#7431d8", "#5b349d"]
6 | :orange ["#ffab70", "#f66a0e", "#c84600", "#b04800"]
7 | :red ["#ff7b72", "#f85149", "#c93c37", "#9c1e1e"]
8 | :pink ["#fdeaea", "#fad5d5", "#f9cacb", "#f8bfc0"]
9 | :halloween ["#631c03", "#bd561d", "#fa7a18", "#fddf68"]})
10 |
11 | (def dark-fills {:green ["#033a16", "#196c2e", "#2ea043", "#56d364"]
12 | :blue [ "#1c3251", "#2d5999", "#4993ff", "#8bb8ff"]
13 | :purple ["#33274d", "#5b3b82", "#8957e5", "#b989ff"]
14 | :orange ["#3d2013", "#7d3a11", "#c45e1c", "#f6854d"]
15 | :red ["#37181a", "#6e2226", "#ae3636", "#f35d5d"]
16 | :pink ["#fdeaea", "#fad5d5", "#f9cacb", "#f8bfc0"]
17 | :halloween ["#631c03", "#bd561d", "#fa7a18", "#fddf68"]})
18 |
19 | (defn reload-content-scripts []
20 | (.sendMessage (.. js/chrome -runtime) "runInject"))
21 |
22 | (defn set-selected-fill [key]
23 | (.set (.. js/chrome -storage -sync)
24 | (clj->js {:gccUserSelectedFills key}))
25 | (reload-content-scripts))
26 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/string/typedstring.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | goog.provide('goog.string.TypedString');
8 |
9 |
10 |
11 | /**
12 | * Wrapper for strings that conform to a data type or language.
13 | *
14 | * Implementations of this interface are wrappers for strings, and typically
15 | * associate a type contract with the wrapped string. Concrete implementations
16 | * of this interface may choose to implement additional run-time type checking,
17 | * see for example `goog.html.SafeHtml`. If available, client code that
18 | * needs to ensure type membership of an object should use the type's function
19 | * to assert type membership, such as `goog.html.SafeHtml.unwrap`.
20 | * @interface
21 | */
22 | goog.string.TypedString = function() {};
23 |
24 |
25 | /**
26 | * Interface marker of the TypedString interface.
27 | *
28 | * This property can be used to determine at runtime whether or not an object
29 | * implements this interface. All implementations of this interface set this
30 | * property to `true`.
31 | * @type {boolean}
32 | */
33 | goog.string.TypedString.prototype.implementsGoogStringTypedString;
34 |
35 |
36 | /**
37 | * Retrieves this wrapped string's value.
38 | * @return {string} The wrapped string's value.
39 | */
40 | goog.string.TypedString.prototype.getTypedStringValue;
41 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/gh_colorful_contributions/components/footer.js:
--------------------------------------------------------------------------------
1 | // Compiled by ClojureScript 1.11.132 {:static-fns true, :optimize-constants true, :optimizations :advanced}
2 | goog.provide('gh_colorful_contributions.components.footer');
3 | goog.require('cljs.core');
4 | goog.require('cljs.core.constants');
5 | gh_colorful_contributions.components.footer.footer = (function gh_colorful_contributions$components$footer$footer(){
6 | return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$footer$section,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$p$has_DASH_text_DASH_right,new cljs.core.PersistentArrayMap(null, 1, [cljs.core.cst$kw$style,new cljs.core.PersistentArrayMap(null, 1, [cljs.core.cst$kw$font_DASH_size,"0.875rem"], null)], null),"Made with \u2764\uFE0F and fun by ",new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$span,new cljs.core.PersistentArrayMap(null, 2, [cljs.core.cst$kw$style,new cljs.core.PersistentArrayMap(null, 2, [cljs.core.cst$kw$color,"seagreen",cljs.core.cst$kw$cursor,"pointer"], null),cljs.core.cst$kw$on_DASH_click,(function (){
7 | return chrome.tabs.create(cljs.core.clj__GT_js(new cljs.core.PersistentArrayMap(null, 1, [cljs.core.cst$kw$url,"https://github.com/chenpotatos"], null)));
8 | })], null),"\u4E0D\u5403\u571F\u8C46\u6CE5."], null)], null)], null);
9 | });
10 |
--------------------------------------------------------------------------------
/project.clj:
--------------------------------------------------------------------------------
1 | (defproject github-colorful-contributions-graph "5.0.1"
2 | :description "✨个性化你的 Github Contribution Gragh"
3 | :url "https://github.com/chenpotatos/better-github-contributions-graph"
4 | :license {:name "Eclipse Public License"
5 | :url "http://www.eclipse.org/legal/epl-v10.html"}
6 |
7 | :min-lein-version "2.7.1"
8 |
9 | :plugins [[dev.weavejester/lein-cljfmt "0.13.0"]]
10 |
11 | :dependencies [[org.clojure/clojure "1.12.0"]
12 | [org.clojure/clojurescript "1.11.132"]
13 | [org.clojure/data.json "2.5.1"]
14 | [cljsjs/react "18.3.1-1"]
15 | [cljsjs/react-dom "18.3.1-1"]
16 | [reagent "1.2.0" ]]
17 |
18 | :source-paths ["src"]
19 |
20 | :aliases {"fig:build" ["trampoline" "run" "-m" "figwheel.main" "-b" "dev" "-r"]
21 | "fig:clean" ["run" "-m" "figwheel.main" "--clean" "dev"]
22 | "fig:min" ["run" "-m" "figwheel.main" "-O" "advanced" "-bo" "min"]
23 | "fig:test" ["run" "-m" "figwheel.main" "-co" "test.cljs.edn" "-m" "gh-colorful-contributions.test-runner"]}
24 |
25 | :profiles {:dev {:dependencies [[org.slf4j/slf4j-nop "2.0.16"]
26 | [com.bhauman/figwheel-main "0.2.20"]
27 | [com.bhauman/rebel-readline-cljs "0.1.4"]]
28 | :resource-paths ["target"]
29 | :clean-targets ^{:protect false} [:target-path "resources/public/cljs-out"]
30 | }})
31 |
--------------------------------------------------------------------------------
/src/gh_colorful_contributions/components/panel.cljs:
--------------------------------------------------------------------------------
1 | (ns gh-colorful-contributions.components.panel
2 | (:require
3 | [reagent.core :as r]
4 | [gh-colorful-contributions.data :refer [default-fills
5 | dark-fills
6 | set-selected-fill]]))
7 |
8 | (defonce page-theme (r/atom "light"))
9 | (defonce user-selected-fill (r/atom "none"))
10 |
11 | (.get
12 | (.. js/chrome -storage -sync)
13 | (clj->js {:theme "light" :gccUserSelectedFills "none"})
14 | (fn [result] (let [clj-result (js->clj result :keywordize-keys true)
15 | theme (:theme clj-result)
16 | s-fill (:gccUserSelectedFills clj-result)]
17 | (.setAttribute (.. js/document -documentElement) "data-theme" theme)
18 | (reset! page-theme theme)
19 | (reset! user-selected-fill s-fill))))
20 |
21 | (defn panel []
22 | [:section.section.gcc-panel
23 | [:h2.title.is-5 "Colors:"]
24 | [:div.fills
25 | (doall (for [[k fill] (if (= @page-theme "light") default-fills dark-fills)]
26 | ^{:key k} [:div.control
27 | [:input {:type "radio"
28 | :value (name k)
29 | :checked (= @user-selected-fill (name k))
30 | :on-change (fn [e]
31 | (reset! user-selected-fill (.. e -target -value))
32 | (set-selected-fill k))}]
33 | [:ul (for [f fill]
34 | ^{:key f}
35 | [:li {:style {:background f}}])]]))]])
36 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/html/trustedtypes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Policy to convert strings to Trusted Types. See
9 | * https://github.com/WICG/trusted-types for details.
10 | */
11 |
12 | goog.provide('goog.html.trustedtypes');
13 |
14 |
15 | /**
16 | * @define {string} Name for the Trusted Types policy used in Closure Safe
17 | * Types. Differs from `goog.TRUSTED_TYPES_POLICY_NAME` in that the latter is
18 | * also used for other purposes like the debug loader. If empty, Closure Safe
19 | * Types will not use Trusted Types. Default is `goog.TRUSTED_TYPES_POLICY_NAME`
20 | * plus the suffix `#html`, unless `goog.TRUSTED_TYPES_POLICY_NAME` is empty.
21 | * @package
22 | */
23 | goog.html.trustedtypes.POLICY_NAME = goog.define(
24 | 'goog.html.trustedtypes.POLICY_NAME',
25 | goog.TRUSTED_TYPES_POLICY_NAME ? goog.TRUSTED_TYPES_POLICY_NAME + '#html' :
26 | '');
27 |
28 |
29 | /**
30 | * Cached result of goog.createTrustedTypesPolicy.
31 | * @type {?TrustedTypePolicy|undefined}
32 | * @private
33 | */
34 | goog.html.trustedtypes.cachedPolicy_;
35 |
36 |
37 | /**
38 | * Creates a (singleton) Trusted Type Policy for Safe HTML Types.
39 | * @return {?TrustedTypePolicy}
40 | * @package
41 | */
42 | goog.html.trustedtypes.getPolicyPrivateDoNotAccessOrElse = function() {
43 | 'use strict';
44 | if (!goog.html.trustedtypes.POLICY_NAME) {
45 | // Binary not configured for Trusted Types.
46 | return null;
47 | }
48 |
49 | if (goog.html.trustedtypes.cachedPolicy_ === undefined) {
50 | goog.html.trustedtypes.cachedPolicy_ =
51 | goog.createTrustedTypesPolicy(goog.html.trustedtypes.POLICY_NAME);
52 | }
53 |
54 | return goog.html.trustedtypes.cachedPolicy_;
55 | };
56 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/debug/error.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Provides a base class for custom Error objects such that the
9 | * stack is correctly maintained.
10 | *
11 | * You should never need to throw DebugError(msg) directly, Error(msg) is
12 | * sufficient.
13 | */
14 |
15 | goog.module('goog.debug.Error');
16 | goog.module.declareLegacyNamespace();
17 |
18 |
19 |
20 | /**
21 | * Base class for custom error objects.
22 | * @param {*=} msg The message associated with the error.
23 | * @param {{
24 | * message: (?|undefined),
25 | * name: (?|undefined),
26 | * lineNumber: (?|undefined),
27 | * fileName: (?|undefined),
28 | * stack: (?|undefined),
29 | * cause: (?|undefined),
30 | * }=} cause The original error object to chain with.
31 | * @constructor
32 | * @extends {Error}
33 | */
34 | function DebugError(msg = undefined, cause = undefined) {
35 | // Attempt to ensure there is a stack trace.
36 | if (Error.captureStackTrace) {
37 | Error.captureStackTrace(this, DebugError);
38 | } else {
39 | const stack = new Error().stack;
40 | if (stack) {
41 | /** @override @type {string} */
42 | this.stack = stack;
43 | }
44 | }
45 |
46 | if (msg) {
47 | /** @override @type {string} */
48 | this.message = String(msg);
49 | }
50 |
51 | if (cause !== undefined) {
52 | /** @type {?} */
53 | this.cause = cause;
54 | }
55 |
56 | /**
57 | * Whether to report this error to the server. Setting this to false will
58 | * cause the error reporter to not report the error back to the server,
59 | * which can be useful if the client knows that the error has already been
60 | * logged on the server.
61 | * @type {boolean}
62 | */
63 | this.reportErrorToServer = true;
64 | }
65 | goog.inherits(DebugError, Error);
66 |
67 |
68 | /** @override @type {string} */
69 | DebugError.prototype.name = 'CustomError';
70 |
71 |
72 | exports = DebugError;
73 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/gh_colorful_contributions/core.js:
--------------------------------------------------------------------------------
1 | // Compiled by ClojureScript 1.11.132 {:static-fns true, :optimize-constants true, :optimizations :advanced}
2 | goog.provide('gh_colorful_contributions.core');
3 | goog.require('cljs.core');
4 | goog.require('cljs.core.constants');
5 | goog.require('goog.dom');
6 | goog.require('reagent.dom');
7 | goog.require('gh_colorful_contributions.components.header');
8 | goog.require('gh_colorful_contributions.components.panel');
9 | goog.require('gh_colorful_contributions.components.footer');
10 | gh_colorful_contributions.core.get_app_element = (function gh_colorful_contributions$core$get_app_element(){
11 | return goog.dom.getElement("app");
12 | });
13 | gh_colorful_contributions.core.github_colorful_contributions = (function gh_colorful_contributions$core$github_colorful_contributions(){
14 | return new cljs.core.PersistentVector(null, 5, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$div$container,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [gh_colorful_contributions.components.header.header], null),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$hr], null),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [gh_colorful_contributions.components.panel.panel], null),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [gh_colorful_contributions.components.footer.footer], null)], null);
15 | });
16 | gh_colorful_contributions.core.mount = (function gh_colorful_contributions$core$mount(el){
17 | return reagent.dom.render.cljs$core$IFn$_invoke$arity$2(new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [gh_colorful_contributions.core.github_colorful_contributions], null),el);
18 | });
19 | gh_colorful_contributions.core.mount_app_element = (function gh_colorful_contributions$core$mount_app_element(){
20 | var temp__5823__auto__ = gh_colorful_contributions.core.get_app_element();
21 | if(cljs.core.truth_(temp__5823__auto__)){
22 | var el = temp__5823__auto__;
23 | return gh_colorful_contributions.core.mount(el);
24 | } else {
25 | return null;
26 | }
27 | });
28 | gh_colorful_contributions.core.mount_app_element();
29 | gh_colorful_contributions.core.on_reload = (function gh_colorful_contributions$core$on_reload(){
30 | return gh_colorful_contributions.core.mount_app_element();
31 | });
32 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/labs/useragent/useragent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Defines for goog.labs.userAgent.
9 | */
10 |
11 | goog.module('goog.labs.userAgent');
12 | goog.module.declareLegacyNamespace();
13 |
14 | const flags = goog.require('goog.flags');
15 |
16 | /**
17 | * @define {string} Optional runtime override for the USE_CLIENT_HINTS flag.
18 | * If this is set (for example, to 'foo.bar') then any value of USE_CLIENT_HINTS
19 | * will be overridden by `globalThis.foo.bar` if it is non-null.
20 | * This flag will be removed in December 2021.
21 | */
22 | const USE_CLIENT_HINTS_OVERRIDE =
23 | goog.define('goog.labs.userAgent.USE_CLIENT_HINTS_OVERRIDE', '');
24 |
25 | /**
26 | * @define {boolean} If true, use navigator.userAgentData. Note: this overrides
27 | * the `USE_USER_AGENT_CLIENT_HINTS` runtime flag. Please prefer the flag when
28 | * possible.
29 | */
30 | const USE_CLIENT_HINTS =
31 | goog.define('goog.labs.userAgent.USE_CLIENT_HINTS', false);
32 |
33 | let forceClientHintsInTests = false;
34 |
35 | /**
36 | * Sets whether to use client hints APIs in tests for codepaths that
37 | * - were originally implemented as checks against the navigator.userAgent
38 | * string.
39 | * - have an alternative implementation that uses Client Hints APIs.
40 | *
41 | * See the jsdoc on useClientHints for cases where this flag will be
42 | * ineffective, and the Client Hints APIs would be used regardless.
43 | * DO NOT call this function in production code - it will cause de-optimization.
44 | * @param {boolean} use Whether or not to use Client Hints API codepaths in
45 | * goog.labs.useragent.* modules.
46 | */
47 | exports.setUseClientHintsForTesting = (use) => {
48 | forceClientHintsInTests = use;
49 | };
50 |
51 | /** @const {boolean} */
52 | const useClientHintsRuntimeOverride = USE_CLIENT_HINTS_OVERRIDE ?
53 | !!goog.getObjectByName(USE_CLIENT_HINTS_OVERRIDE) :
54 | false;
55 |
56 | /**
57 | * Whether to use UserAgent-Client Hints API surfaces in parts of the
58 | * labs.userAgent package that previously only relied on the navigator.userAgent
59 | * string. Newer labs.userAgent API surfaces may ignore the result of this
60 | * function as they are considered opt-in API surfaces.
61 | * @const {function():boolean}
62 | */
63 | exports.useClientHints = () => {
64 | return flags.USE_USER_AGENT_CLIENT_HINTS || USE_CLIENT_HINTS ||
65 | useClientHintsRuntimeOverride || forceClientHintsInTests;
66 | };
67 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/fs/blob.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Wrappers for the HTML5 File API. These wrappers closely mirror
9 | * the underlying APIs, but use Closure-style events and Deferred return values.
10 | * Their existence also makes it possible to mock the FileSystem API for testing
11 | * in browsers that don't support it natively.
12 | *
13 | * When adding public functions to anything under this namespace, be sure to add
14 | * its mock counterpart to goog.testing.fs.
15 | */
16 |
17 | goog.provide('goog.fs.blob');
18 |
19 |
20 |
21 | /**
22 | * Concatenates one or more values together and converts them to a Blob.
23 | *
24 | * @param {...(string|!Blob|!ArrayBuffer)} var_args The values that will make up
25 | * the resulting blob.
26 | * @return {!Blob} The blob.
27 | */
28 | goog.fs.blob.getBlob = function(var_args) {
29 | 'use strict';
30 | const BlobBuilder = goog.global.BlobBuilder || goog.global.WebKitBlobBuilder;
31 |
32 | if (BlobBuilder !== undefined) {
33 | const bb = new BlobBuilder();
34 | for (let i = 0; i < arguments.length; i++) {
35 | bb.append(arguments[i]);
36 | }
37 | return bb.getBlob();
38 | } else {
39 | return goog.fs.blob.getBlobWithProperties(
40 | Array.prototype.slice.call(arguments));
41 | }
42 | };
43 |
44 |
45 | /**
46 | * Creates a blob with the given properties.
47 | * See https://developer.mozilla.org/en-US/docs/Web/API/Blob for more details.
48 | *
49 | * @param {!Array} parts The values that will make up
50 | * the resulting blob (subset supported by both BlobBuilder.append() and
51 | * Blob constructor).
52 | * @param {string=} opt_type The MIME type of the Blob.
53 | * @param {string=} opt_endings Specifies how strings containing newlines are to
54 | * be written out.
55 | * @return {!Blob} The blob.
56 | */
57 | goog.fs.blob.getBlobWithProperties = function(parts, opt_type, opt_endings) {
58 | 'use strict';
59 | const BlobBuilder = goog.global.BlobBuilder || goog.global.WebKitBlobBuilder;
60 |
61 | if (BlobBuilder !== undefined) {
62 | const bb = new BlobBuilder();
63 | for (let i = 0; i < parts.length; i++) {
64 | bb.append(parts[i], opt_endings);
65 | }
66 | return bb.getBlob(opt_type);
67 | } else if (goog.global.Blob !== undefined) {
68 | const properties = {};
69 | if (opt_type) {
70 | properties['type'] = opt_type;
71 | }
72 | if (opt_endings) {
73 | properties['endings'] = opt_endings;
74 | }
75 | return new Blob(parts, properties);
76 | } else {
77 | throw new Error('This browser doesn\'t seem to support creating Blobs');
78 | }
79 | };
80 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/string/stringbuffer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Utility for fast string concatenation.
9 | */
10 |
11 | goog.provide('goog.string.StringBuffer');
12 |
13 |
14 |
15 | /**
16 | * Utility class to facilitate string concatenation.
17 | *
18 | * @param {*=} opt_a1 Optional first initial item to append.
19 | * @param {...*} var_args Other initial items to
20 | * append, e.g., new goog.string.StringBuffer('foo', 'bar').
21 | * @constructor
22 | */
23 | goog.string.StringBuffer = function(opt_a1, var_args) {
24 | 'use strict';
25 | if (opt_a1 != null) {
26 | this.append.apply(this, arguments);
27 | }
28 | };
29 |
30 |
31 | /**
32 | * Internal buffer for the string to be concatenated.
33 | * @type {string}
34 | * @private
35 | */
36 | goog.string.StringBuffer.prototype.buffer_ = '';
37 |
38 |
39 | /**
40 | * Sets the contents of the string buffer object, replacing what's currently
41 | * there.
42 | *
43 | * @param {*} s String to set.
44 | */
45 | goog.string.StringBuffer.prototype.set = function(s) {
46 | 'use strict';
47 | this.buffer_ = '' + s;
48 | };
49 |
50 |
51 | /**
52 | * Appends one or more items to the buffer.
53 | *
54 | * Calling this with null, undefined, or empty arguments is an error.
55 | *
56 | * @param {*} a1 Required first string.
57 | * @param {*=} opt_a2 Optional second string.
58 | * @param {...?} var_args Other items to append,
59 | * e.g., sb.append('foo', 'bar', 'baz').
60 | * @return {!goog.string.StringBuffer} This same StringBuffer object.
61 | * @suppress {duplicate}
62 | */
63 | goog.string.StringBuffer.prototype.append = function(a1, opt_a2, var_args) {
64 | 'use strict';
65 | // Use a1 directly to avoid arguments instantiation for single-arg case.
66 | this.buffer_ += String(a1);
67 | if (opt_a2 != null) { // second argument is undefined (null == undefined)
68 | for (let i = 1; i < arguments.length; i++) {
69 | this.buffer_ += arguments[i];
70 | }
71 | }
72 | return this;
73 | };
74 |
75 |
76 | /**
77 | * Clears the internal buffer.
78 | */
79 | goog.string.StringBuffer.prototype.clear = function() {
80 | 'use strict';
81 | this.buffer_ = '';
82 | };
83 |
84 |
85 | /**
86 | * @return {number} the length of the current contents of the buffer.
87 | */
88 | goog.string.StringBuffer.prototype.getLength = function() {
89 | 'use strict';
90 | return this.buffer_.length;
91 | };
92 |
93 |
94 | /**
95 | * @return {string} The concatenated string.
96 | * @override
97 | */
98 | goog.string.StringBuffer.prototype.toString = function() {
99 | 'use strict';
100 | return this.buffer_;
101 | };
102 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/gh_colorful_contributions/data.js:
--------------------------------------------------------------------------------
1 | // Compiled by ClojureScript 1.11.132 {:static-fns true, :optimize-constants true, :optimizations :advanced}
2 | goog.provide('gh_colorful_contributions.data');
3 | goog.require('cljs.core');
4 | goog.require('cljs.core.constants');
5 | gh_colorful_contributions.data.default_fills = new cljs.core.PersistentArrayMap(null, 7, [cljs.core.cst$kw$green,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#aceebb","#4ac26b","#2da44e","#116329"], null),cljs.core.cst$kw$blue,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#a4c8ff","#388bfd","#0366d6","#00499e"], null),cljs.core.cst$kw$purple,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#d2b4ff","#a371f7","#7431d8","#5b349d"], null),cljs.core.cst$kw$orange,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#ffab70","#f66a0e","#c84600","#b04800"], null),cljs.core.cst$kw$red,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#ff7b72","#f85149","#c93c37","#9c1e1e"], null),cljs.core.cst$kw$pink,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#fdeaea","#fad5d5","#f9cacb","#f8bfc0"], null),cljs.core.cst$kw$halloween,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#631c03","#bd561d","#fa7a18","#fddf68"], null)], null);
6 | gh_colorful_contributions.data.dark_fills = new cljs.core.PersistentArrayMap(null, 7, [cljs.core.cst$kw$green,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#033a16","#196c2e","#2ea043","#56d364"], null),cljs.core.cst$kw$blue,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#1c3251","#2d5999","#4993ff","#8bb8ff"], null),cljs.core.cst$kw$purple,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#33274d","#5b3b82","#8957e5","#b989ff"], null),cljs.core.cst$kw$orange,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#3d2013","#7d3a11","#c45e1c","#f6854d"], null),cljs.core.cst$kw$red,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#37181a","#6e2226","#ae3636","#f35d5d"], null),cljs.core.cst$kw$pink,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#fdeaea","#fad5d5","#f9cacb","#f8bfc0"], null),cljs.core.cst$kw$halloween,new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, ["#631c03","#bd561d","#fa7a18","#fddf68"], null)], null);
7 | gh_colorful_contributions.data.reload_content_scripts = (function gh_colorful_contributions$data$reload_content_scripts(){
8 | return chrome.runtime.sendMessage("runInject");
9 | });
10 | gh_colorful_contributions.data.set_selected_fill = (function gh_colorful_contributions$data$set_selected_fill(key){
11 | chrome.storage.sync.set(cljs.core.clj__GT_js(new cljs.core.PersistentArrayMap(null, 1, [cljs.core.cst$kw$gccUserSelectedFills,key], null)));
12 |
13 | return gh_colorful_contributions.data.reload_content_scripts();
14 | });
15 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/reagent/dom.cljs:
--------------------------------------------------------------------------------
1 | (ns reagent.dom
2 | (:require [react-dom :as react-dom]
3 | [reagent.impl.util :as util]
4 | [reagent.impl.template :as tmpl]
5 | [reagent.impl.batching :as batch]
6 | [reagent.impl.protocols :as p]
7 | [reagent.ratom :as ratom]))
8 |
9 | (defonce ^:private roots (atom {}))
10 |
11 | (defn- unmount-comp [container]
12 | (swap! roots dissoc container)
13 | (react-dom/unmountComponentAtNode container))
14 |
15 | (defn- render-comp [comp container callback]
16 | (binding [util/*always-update* true]
17 | (react-dom/render (comp) container
18 | (fn []
19 | (binding [util/*always-update* false]
20 | (swap! roots assoc container comp)
21 | (batch/flush-after-render)
22 | (if (some? callback)
23 | (callback)))))))
24 |
25 | (defn- re-render-component [comp container]
26 | (render-comp comp container nil))
27 |
28 | (defn render
29 | "Render a Reagent component into the DOM. The first argument may be
30 | either a vector (using Reagent's Hiccup syntax), or a React element.
31 | The second argument should be a DOM node.
32 |
33 | Optionally takes a callback that is called when the component is in place.
34 |
35 | Returns the mounted component instance."
36 | ([comp container]
37 | (render comp container tmpl/*current-default-compiler*))
38 | ([comp container callback-or-compiler]
39 | (ratom/flush!)
40 | (let [[compiler callback] (cond
41 | (map? callback-or-compiler)
42 | [(:compiler callback-or-compiler) (:callback callback-or-compiler)]
43 |
44 | (fn? callback-or-compiler)
45 | [tmpl/*current-default-compiler* callback-or-compiler]
46 |
47 | :else
48 | [callback-or-compiler nil])
49 | f (fn []
50 | (p/as-element compiler (if (fn? comp) (comp) comp)))]
51 | (render-comp f container callback))))
52 |
53 | (defn unmount-component-at-node
54 | "Remove a component from the given DOM node."
55 | [container]
56 | (unmount-comp container))
57 |
58 | (defn dom-node
59 | "Returns the root DOM node of a mounted component."
60 | {:deprecated "1.2.0"}
61 | [this]
62 | (react-dom/findDOMNode this))
63 |
64 | (defn force-update-all
65 | "Force re-rendering of all mounted Reagent components. This is
66 | probably only useful in a development environment, when you want to
67 | update components in response to some dynamic changes to code.
68 |
69 | Note that force-update-all may not update root components. This
70 | happens if a component 'foo' is mounted with `(render [foo])` (since
71 | functions are passed by value, and not by reference, in
72 | ClojureScript). To get around this you'll have to introduce a layer
73 | of indirection, for example by using `(render [#'foo])` instead."
74 | {:deprecated "1.2.0"}
75 | []
76 | (ratom/flush!)
77 | (doseq [[container comp] @roots]
78 | (re-render-component comp container))
79 | (batch/flush-after-render))
80 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/dom/browserfeature.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Browser capability checks for the dom package.
9 | */
10 |
11 |
12 | goog.provide('goog.dom.BrowserFeature');
13 |
14 | goog.require('goog.userAgent');
15 |
16 |
17 | /**
18 | * @define {boolean} Whether we know at compile time that the browser doesn't
19 | * support OffscreenCanvas.
20 | */
21 | goog.dom.BrowserFeature.ASSUME_NO_OFFSCREEN_CANVAS =
22 | goog.define('goog.dom.ASSUME_NO_OFFSCREEN_CANVAS', false);
23 |
24 | /**
25 | * @define {boolean} Whether we know at compile time that the browser supports
26 | * all OffscreenCanvas contexts.
27 | */
28 | // TODO(user): Eventually this should default to "FEATURESET_YEAR >= 202X".
29 | goog.dom.BrowserFeature.ASSUME_OFFSCREEN_CANVAS =
30 | goog.define('goog.dom.ASSUME_OFFSCREEN_CANVAS', false);
31 |
32 | /**
33 | * Detects if a particular OffscreenCanvas context is supported.
34 | * @param {string} contextName name of the context to test.
35 | * @return {boolean} Whether the browser supports this OffscreenCanvas context.
36 | * @private
37 | */
38 | goog.dom.BrowserFeature.detectOffscreenCanvas_ = function(contextName) {
39 | 'use strict';
40 | // This code only gets removed because we forced @nosideeffects on
41 | // the functions. See: b/138802376
42 | try {
43 | return Boolean(new self.OffscreenCanvas(0, 0).getContext(contextName));
44 | } catch (ex) {
45 | }
46 | return false;
47 | };
48 |
49 | /**
50 | * Whether the browser supports OffscreenCanvas 2D context.
51 | * @const {boolean}
52 | */
53 | goog.dom.BrowserFeature.OFFSCREEN_CANVAS_2D =
54 | !goog.dom.BrowserFeature.ASSUME_NO_OFFSCREEN_CANVAS &&
55 | (goog.dom.BrowserFeature.ASSUME_OFFSCREEN_CANVAS ||
56 | goog.dom.BrowserFeature.detectOffscreenCanvas_('2d'));
57 |
58 | /**
59 | * Whether attributes 'name' and 'type' can be added to an element after it's
60 | * created. False in Internet Explorer prior to version 9.
61 | * @const {boolean}
62 | */
63 | goog.dom.BrowserFeature.CAN_ADD_NAME_OR_TYPE_ATTRIBUTES = true;
64 |
65 | /**
66 | * Whether we can use element.children to access an element's Element
67 | * children. Available since Gecko 1.9.1, IE 9. (IE<9 also includes comment
68 | * nodes in the collection.)
69 | * @const {boolean}
70 | */
71 | goog.dom.BrowserFeature.CAN_USE_CHILDREN_ATTRIBUTE = true;
72 |
73 | /**
74 | * Opera, Safari 3, and Internet Explorer 9 all support innerText but they
75 | * include text nodes in script and style tags. Not document-mode-dependent.
76 | * @const {boolean}
77 | */
78 | goog.dom.BrowserFeature.CAN_USE_INNER_TEXT = false;
79 |
80 | /**
81 | * MSIE, Opera, and Safari>=4 support element.parentElement to access an
82 | * element's parent if it is an Element.
83 | * @const {boolean}
84 | */
85 | goog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY =
86 | goog.userAgent.IE || goog.userAgent.WEBKIT;
87 |
88 | /**
89 | * Whether NoScope elements need a scoped element written before them in
90 | * innerHTML.
91 | * MSDN: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx#1
92 | * @const {boolean}
93 | */
94 | goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT = goog.userAgent.IE;
95 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/fs/url.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Wrapper for URL and its createObjectUrl and revokeObjectUrl
9 | * methods that are part of the HTML5 File API.
10 | */
11 |
12 | goog.provide('goog.fs.url');
13 |
14 |
15 | /**
16 | * Creates a blob URL for a blob object.
17 | * Throws an error if the browser does not support Object Urls.
18 | *
19 | * @param {!File|!Blob|!MediaSource|!MediaStream} obj The object for which
20 | * to create the URL.
21 | * @return {string} The URL for the object.
22 | */
23 | goog.fs.url.createObjectUrl = function(obj) {
24 | 'use strict';
25 | return goog.fs.url.getUrlObject_().createObjectURL(obj);
26 | };
27 |
28 |
29 | /**
30 | * Revokes a URL created by {@link goog.fs.url.createObjectUrl}.
31 | * Throws an error if the browser does not support Object Urls.
32 | *
33 | * @param {string} url The URL to revoke.
34 | * @return {void}
35 | */
36 | goog.fs.url.revokeObjectUrl = function(url) {
37 | 'use strict';
38 | goog.fs.url.getUrlObject_().revokeObjectURL(url);
39 | };
40 |
41 |
42 | /**
43 | * @record
44 | * @private
45 | */
46 | goog.fs.url.UrlObject_ = function() {};
47 |
48 | /**
49 | * @param {!File|!Blob|!MediaSource|!MediaStream} arg
50 | * @return {string}
51 | */
52 | goog.fs.url.UrlObject_.prototype.createObjectURL = function(arg) {};
53 |
54 | /**
55 | * @param {string} s
56 | * @return {void}
57 | */
58 | goog.fs.url.UrlObject_.prototype.revokeObjectURL = function(s) {};
59 |
60 |
61 | /**
62 | * Get the object that has the createObjectURL and revokeObjectURL functions for
63 | * this browser.
64 | *
65 | * @return {!goog.fs.url.UrlObject_} The object for this browser.
66 | * @private
67 | */
68 | goog.fs.url.getUrlObject_ = function() {
69 | 'use strict';
70 | const urlObject = goog.fs.url.findUrlObject_();
71 | if (urlObject != null) {
72 | return urlObject;
73 | } else {
74 | throw new Error('This browser doesn\'t seem to support blob URLs');
75 | }
76 | };
77 |
78 |
79 | /**
80 | * Finds the object that has the createObjectURL and revokeObjectURL functions
81 | * for this browser.
82 | *
83 | * @return {?goog.fs.url.UrlObject_} The object for this browser or null if the
84 | * browser does not support Object Urls.
85 | * @private
86 | */
87 | goog.fs.url.findUrlObject_ = function() {
88 | 'use strict';
89 | // This is what the spec says to do
90 | // http://dev.w3.org/2006/webapi/FileAPI/#dfn-createObjectURL
91 | if (goog.global.URL !== undefined &&
92 | goog.global.URL.createObjectURL !== undefined) {
93 | return /** @type {!goog.fs.url.UrlObject_} */ (goog.global.URL);
94 | // This is what the spec used to say to do
95 | } else if (goog.global.createObjectURL !== undefined) {
96 | return /** @type {!goog.fs.url.UrlObject_} */ (goog.global);
97 | } else {
98 | return null;
99 | }
100 | };
101 |
102 |
103 | /**
104 | * Checks whether this browser supports Object Urls. If not, calls to
105 | * createObjectUrl and revokeObjectUrl will result in an error.
106 | *
107 | * @return {boolean} True if this browser supports Object Urls.
108 | */
109 | goog.fs.url.browserSupportsObjectUrls = function() {
110 | 'use strict';
111 | return goog.fs.url.findUrlObject_() != null;
112 | };
113 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/reagent/debug.js:
--------------------------------------------------------------------------------
1 | // Compiled by ClojureScript 1.11.132 {:static-fns true, :optimize-constants true, :optimizations :advanced}
2 | goog.provide('reagent.debug');
3 | goog.require('cljs.core');
4 | goog.require('cljs.core.constants');
5 | reagent.debug.has_console = (typeof console !== 'undefined');
6 | reagent.debug.tracking = false;
7 | if((typeof reagent !== 'undefined') && (typeof reagent.debug !== 'undefined') && (typeof reagent.debug.warnings !== 'undefined')){
8 | } else {
9 | reagent.debug.warnings = cljs.core.atom.cljs$core$IFn$_invoke$arity$1(null);
10 | }
11 | if((typeof reagent !== 'undefined') && (typeof reagent.debug !== 'undefined') && (typeof reagent.debug.track_console !== 'undefined')){
12 | } else {
13 | reagent.debug.track_console = (function (){var o = ({});
14 | (o.warn = (function() {
15 | var G__14463__delegate = function (args){
16 | return cljs.core.swap_BANG_.cljs$core$IFn$_invoke$arity$variadic(reagent.debug.warnings,cljs.core.update_in,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$warn], null),cljs.core.conj,cljs.core.prim_seq.cljs$core$IFn$_invoke$arity$2([cljs.core.apply.cljs$core$IFn$_invoke$arity$2(cljs.core.str,args)], 0));
17 | };
18 | var G__14463 = function (var_args){
19 | var args = null;
20 | if (arguments.length > 0) {
21 | var G__14464__i = 0, G__14464__a = new Array(arguments.length - 0);
22 | while (G__14464__i < G__14464__a.length) {G__14464__a[G__14464__i] = arguments[G__14464__i + 0]; ++G__14464__i;}
23 | args = new cljs.core.IndexedSeq(G__14464__a,0,null);
24 | }
25 | return G__14463__delegate.call(this,args);};
26 | G__14463.cljs$lang$maxFixedArity = 0;
27 | G__14463.cljs$lang$applyTo = (function (arglist__14465){
28 | var args = cljs.core.seq(arglist__14465);
29 | return G__14463__delegate(args);
30 | });
31 | G__14463.cljs$core$IFn$_invoke$arity$variadic = G__14463__delegate;
32 | return G__14463;
33 | })()
34 | );
35 |
36 | (o.error = (function() {
37 | var G__14466__delegate = function (args){
38 | return cljs.core.swap_BANG_.cljs$core$IFn$_invoke$arity$variadic(reagent.debug.warnings,cljs.core.update_in,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.cst$kw$error], null),cljs.core.conj,cljs.core.prim_seq.cljs$core$IFn$_invoke$arity$2([cljs.core.apply.cljs$core$IFn$_invoke$arity$2(cljs.core.str,args)], 0));
39 | };
40 | var G__14466 = function (var_args){
41 | var args = null;
42 | if (arguments.length > 0) {
43 | var G__14467__i = 0, G__14467__a = new Array(arguments.length - 0);
44 | while (G__14467__i < G__14467__a.length) {G__14467__a[G__14467__i] = arguments[G__14467__i + 0]; ++G__14467__i;}
45 | args = new cljs.core.IndexedSeq(G__14467__a,0,null);
46 | }
47 | return G__14466__delegate.call(this,args);};
48 | G__14466.cljs$lang$maxFixedArity = 0;
49 | G__14466.cljs$lang$applyTo = (function (arglist__14468){
50 | var args = cljs.core.seq(arglist__14468);
51 | return G__14466__delegate(args);
52 | });
53 | G__14466.cljs$core$IFn$_invoke$arity$variadic = G__14466__delegate;
54 | return G__14466;
55 | })()
56 | );
57 |
58 | return o;
59 | })();
60 | }
61 | reagent.debug.track_warnings = (function reagent$debug$track_warnings(f){
62 | (reagent.debug.tracking = true);
63 |
64 | cljs.core.reset_BANG_(reagent.debug.warnings,null);
65 |
66 | (f.cljs$core$IFn$_invoke$arity$0 ? f.cljs$core$IFn$_invoke$arity$0() : f.call(null));
67 |
68 | var warns = cljs.core.deref(reagent.debug.warnings);
69 | cljs.core.reset_BANG_(reagent.debug.warnings,null);
70 |
71 | (reagent.debug.tracking = false);
72 |
73 | return warns;
74 | });
75 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/reagent/impl/batching.cljs:
--------------------------------------------------------------------------------
1 | (ns reagent.impl.batching
2 | (:refer-clojure :exclude [flush])
3 | (:require [reagent.debug :refer-macros [assert-some]]
4 | [reagent.impl.util :refer [is-client]]))
5 |
6 | ;;; Update batching
7 |
8 | (defonce mount-count 0)
9 |
10 | (defn next-mount-count []
11 | (set! mount-count (inc mount-count)))
12 |
13 | (defn fake-raf [f]
14 | (js/setTimeout f 16))
15 |
16 | (def next-tick
17 | (if-not is-client
18 | fake-raf
19 | (let [w js/window]
20 | (.bind (or (.-requestAnimationFrame w)
21 | (.-webkitRequestAnimationFrame w)
22 | (.-mozRequestAnimationFrame w)
23 | (.-msRequestAnimationFrame w)
24 | fake-raf)
25 | w))))
26 |
27 | (defn compare-mount-order
28 | [^clj c1 ^clj c2]
29 | (- (.-cljsMountOrder c1)
30 | (.-cljsMountOrder c2)))
31 |
32 | (defn run-queue [a]
33 | ;; sort components by mount order, to make sure parents
34 | ;; are rendered before children
35 | (.sort a compare-mount-order)
36 | (dotimes [i (alength a)]
37 | (let [^js/React.Component c (aget a i)]
38 | (when (true? (.-cljsIsDirty c))
39 | (.forceUpdate c)))))
40 |
41 |
42 | ;; Set from ratom.cljs
43 | (defonce ratom-flush (fn []))
44 |
45 | (defn run-funs [fs]
46 | (dotimes [i (alength fs)]
47 | ((aget fs i))))
48 |
49 | (defn enqueue [^clj queue fs f]
50 | (assert-some f "Enqueued function")
51 | (.push fs f)
52 | (.schedule queue))
53 |
54 | (deftype RenderQueue [^:mutable ^boolean scheduled?]
55 | Object
56 | (schedule [this]
57 | (when-not scheduled?
58 | (set! scheduled? true)
59 | (next-tick #(.run-queues this))))
60 |
61 | (queue-render [this c]
62 | (when (nil? (.-componentQueue this))
63 | (set! (.-componentQueue this) #js []))
64 | (enqueue this (.-componentQueue this) c))
65 |
66 | (add-before-flush [this f]
67 | (when (nil? (.-beforeFlush this))
68 | (set! (.-beforeFlush this) #js []))
69 | (enqueue this (.-beforeFlush this) f))
70 |
71 | (add-after-render [this f]
72 | (when (nil? (.-afterRender this))
73 | (set! (.-afterRender this) #js []))
74 | (enqueue this (.-afterRender this) f))
75 |
76 | (run-queues [this]
77 | (set! scheduled? false)
78 | (.flush-queues this))
79 |
80 | (flush-before-flush [this]
81 | (when-some [fs (.-beforeFlush this)]
82 | (set! (.-beforeFlush this) nil)
83 | (run-funs fs)))
84 |
85 | (flush-render [this]
86 | (when-some [fs (.-componentQueue this)]
87 | (set! (.-componentQueue this) nil)
88 | (run-queue fs)))
89 |
90 | (flush-after-render [this]
91 | (when-some [fs (.-afterRender this)]
92 | (set! (.-afterRender this) nil)
93 | (run-funs fs)))
94 |
95 | (flush-queues [this]
96 | (.flush-before-flush this)
97 | (ratom-flush)
98 | (.flush-render this)
99 | (.flush-after-render this)))
100 |
101 | (defonce render-queue (->RenderQueue false))
102 |
103 | (defn flush []
104 | (.flush-queues render-queue))
105 |
106 | (defn flush-after-render []
107 | (.flush-after-render render-queue))
108 |
109 | (defn queue-render [^clj c]
110 | (when-not (.-cljsIsDirty c)
111 | (set! (.-cljsIsDirty c) true)
112 | (.queue-render render-queue c)))
113 |
114 | (defn mark-rendered [^clj c]
115 | (set! (.-cljsIsDirty c) false))
116 |
117 | (defn do-before-flush [f]
118 | (.add-before-flush render-queue f))
119 |
120 | (defn do-after-render [f]
121 | (.add-after-render render-queue f))
122 |
123 | (defn schedule []
124 | (when (false? (.-scheduled? render-queue))
125 | (.schedule render-queue)))
126 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/clojure/walk.cljs:
--------------------------------------------------------------------------------
1 | ; Copyright (c) Rich Hickey. All rights reserved.
2 | ; The use and distribution terms for this software are covered by the
3 | ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 | ; which can be found in the file epl-v10.html at the root of this distribution.
5 | ; By using this software in any fashion, you are agreeing to be bound by
6 | ; the terms of this license.
7 | ; You must not remove this notice, or any other, from this software.
8 |
9 | ;;; walk.cljs - generic tree walker with replacement
10 |
11 | ;; by Stuart Sierra
12 | ;; Jul5 17, 2011
13 |
14 | ;; CHANGE LOG:
15 | ;;
16 | ;; * July 17, 2011: Port to ClojureScript
17 | ;;
18 | ;; * December 15, 2008: replaced 'walk' with 'prewalk' & 'postwalk'
19 | ;;
20 | ;; * December 9, 2008: first version
21 |
22 |
23 | (ns
24 | ^{:author "Stuart Sierra",
25 | :doc "This file defines a generic tree walker for Clojure data
26 | structures. It takes any data structure (list, vector, map, set,
27 | seq), calls a function on every element, and uses the return value
28 | of the function in place of the original. This makes it fairly
29 | easy to write recursive search-and-replace functions, as shown in
30 | the examples.
31 |
32 | Note: \"walk\" supports all Clojure data structures EXCEPT maps
33 | created with sorted-map-by. There is no (obvious) way to retrieve
34 | the sorting function."}
35 | clojure.walk)
36 |
37 | (defn walk
38 | "Traverses form, an arbitrary data structure. inner and outer are
39 | functions. Applies inner to each element of form, building up a
40 | data structure of the same type, then applies outer to the result.
41 | Recognizes all Clojure data structures. Consumes seqs as with doall."
42 |
43 | {:added "1.1"}
44 | [inner outer form]
45 | (cond
46 | (list? form) (outer (apply list (map inner form)))
47 | (map-entry? form)
48 | (outer (MapEntry. (inner (key form)) (inner (val form)) nil))
49 | (seq? form) (outer (doall (map inner form)))
50 | (record? form) (outer (reduce (fn [r x] (conj r (inner x))) form form))
51 | (coll? form) (outer (into (empty form) (map inner form)))
52 | :else (outer form)))
53 |
54 | (defn postwalk
55 | "Performs a depth-first, post-order traversal of form. Calls f on
56 | each sub-form, uses f's return value in place of the original.
57 | Recognizes all Clojure data structures. Consumes seqs as with doall."
58 | {:added "1.1"}
59 | [f form]
60 | (walk (partial postwalk f) f form))
61 |
62 | (defn prewalk
63 | "Like postwalk, but does pre-order traversal."
64 | {:added "1.1"}
65 | [f form]
66 | (walk (partial prewalk f) identity (f form)))
67 |
68 | (defn keywordize-keys
69 | "Recursively transforms all map keys from strings to keywords."
70 | {:added "1.1"}
71 | [m]
72 | (let [f (fn [[k v]] (if (string? k) [(keyword k) v] [k v]))]
73 | ;; only apply to maps
74 | (postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
75 |
76 | (defn stringify-keys
77 | "Recursively transforms all map keys from keywords to strings."
78 | {:added "1.1"}
79 | [m]
80 | (let [f (fn [[k v]] (if (keyword? k) [(name k) v] [k v]))]
81 | ;; only apply to maps
82 | (postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
83 |
84 | (defn prewalk-replace
85 | "Recursively transforms form by replacing keys in smap with their
86 | values. Like clojure/replace but works on any data structure. Does
87 | replacement at the root of the tree first."
88 | {:added "1.1"}
89 | [smap form]
90 | (prewalk (fn [x] (if (contains? smap x) (smap x) x)) form))
91 |
92 | (defn postwalk-replace
93 | "Recursively transforms form by replacing keys in smap with their
94 | values. Like clojure/replace but works on any data structure. Does
95 | replacement at the leaves of the tree first."
96 | {:added "1.1"}
97 | [smap form]
98 | (postwalk (fn [x] (if (contains? smap x) (smap x) x)) form))
99 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/labs/useragent/engine.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Closure user agent detection.
9 | * @see http://en.wikipedia.org/wiki/User_agent
10 | * For more information on browser brand, platform, or device see the other
11 | * sub-namespaces in goog.labs.userAgent (browser, platform, and device).
12 | */
13 |
14 | goog.module('goog.labs.userAgent.engine');
15 | goog.module.declareLegacyNamespace();
16 |
17 | const googArray = goog.require('goog.array');
18 | const googString = goog.require('goog.string.internal');
19 | const util = goog.require('goog.labs.userAgent.util');
20 |
21 | /**
22 | * @return {boolean} Whether the rendering engine is Presto.
23 | */
24 | function isPresto() {
25 | return util.matchUserAgent('Presto');
26 | }
27 |
28 | /**
29 | * @return {boolean} Whether the rendering engine is Trident.
30 | */
31 | function isTrident() {
32 | // IE only started including the Trident token in IE8.
33 | return util.matchUserAgent('Trident') || util.matchUserAgent('MSIE');
34 | }
35 |
36 | /**
37 | * @return {boolean} Whether the rendering engine is EdgeHTML.
38 | */
39 | function isEdge() {
40 | return util.matchUserAgent('Edge');
41 | }
42 |
43 | /**
44 | * @return {boolean} Whether the rendering engine is WebKit. This will return
45 | * true for Chrome, Blink-based Opera (15+), Edge Chromium and Safari.
46 | */
47 | function isWebKit() {
48 | return util.matchUserAgentIgnoreCase('WebKit') && !isEdge();
49 | }
50 |
51 | /**
52 | * @return {boolean} Whether the rendering engine is Gecko.
53 | */
54 | function isGecko() {
55 | return util.matchUserAgent('Gecko') && !isWebKit() && !isTrident() &&
56 | !isEdge();
57 | }
58 |
59 | /**
60 | * @return {string} The rendering engine's version or empty string if version
61 | * can't be determined.
62 | */
63 | function getVersion() {
64 | const userAgentString = util.getUserAgent();
65 | if (userAgentString) {
66 | const tuples = util.extractVersionTuples(userAgentString);
67 |
68 | const engineTuple = getEngineTuple(tuples);
69 | if (engineTuple) {
70 | // In Gecko, the version string is either in the browser info or the
71 | // Firefox version. See Gecko user agent string reference:
72 | // http://goo.gl/mULqa
73 | if (engineTuple[0] == 'Gecko') {
74 | return getVersionForKey(tuples, 'Firefox');
75 | }
76 |
77 | return engineTuple[1];
78 | }
79 |
80 | // MSIE has only one version identifier, and the Trident version is
81 | // specified in the parenthetical. IE Edge is covered in the engine tuple
82 | // detection.
83 | const browserTuple = tuples[0];
84 | let info;
85 | if (browserTuple && (info = browserTuple[2])) {
86 | const match = /Trident\/([^\s;]+)/.exec(info);
87 | if (match) {
88 | return match[1];
89 | }
90 | }
91 | }
92 | return '';
93 | }
94 |
95 | /**
96 | * @param {!Array>} tuples Extracted version tuples.
97 | * @return {!Array|undefined} The engine tuple or undefined if not
98 | * found.
99 | */
100 | function getEngineTuple(tuples) {
101 | if (!isEdge()) {
102 | return tuples[1];
103 | }
104 | for (let i = 0; i < tuples.length; i++) {
105 | const tuple = tuples[i];
106 | if (tuple[0] == 'Edge') {
107 | return tuple;
108 | }
109 | }
110 | }
111 |
112 | /**
113 | * @param {string|number} version The version to check.
114 | * @return {boolean} Whether the rendering engine version is higher or the same
115 | * as the given version.
116 | */
117 | function isVersionOrHigher(version) {
118 | return googString.compareVersions(getVersion(), version) >= 0;
119 | }
120 |
121 | /**
122 | * @param {!Array>} tuples Version tuples.
123 | * @param {string} key The key to look for.
124 | * @return {string} The version string of the given key, if present.
125 | * Otherwise, the empty string.
126 | */
127 | function getVersionForKey(tuples, key) {
128 | // TODO(nnaze): Move to util if useful elsewhere.
129 |
130 | const pair = googArray.find(tuples, function(pair) {
131 | return key == pair[0];
132 | });
133 |
134 | return pair && pair[1] || '';
135 | }
136 |
137 | exports = {
138 | getVersion,
139 | isEdge,
140 | isGecko,
141 | isPresto,
142 | isTrident,
143 | isVersionOrHigher,
144 | isWebKit,
145 | };
146 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/reflect/reflect.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Useful compiler idioms.
9 | */
10 |
11 | goog.provide('goog.reflect');
12 |
13 |
14 | /**
15 | * Syntax for object literal casts.
16 | * @see http://go/jscompiler-renaming
17 | * @see https://goo.gl/CRs09P
18 | *
19 | * Use this if you have an object literal whose keys need to have the same names
20 | * as the properties of some class even after they are renamed by the compiler.
21 | *
22 | * @param {!Function} type Type to cast to.
23 | * @param {Object} object Object literal to cast.
24 | * @return {Object} The object literal.
25 | */
26 | goog.reflect.object = function(type, object) {
27 | 'use strict';
28 | return object;
29 | };
30 |
31 | /**
32 | * Syntax for renaming property strings.
33 | * @see http://go/jscompiler-renaming
34 | * @see https://goo.gl/CRs09P
35 | *
36 | * Use this if you have an need to access a property as a string, but want
37 | * to also have the property renamed by the compiler. In contrast to
38 | * goog.reflect.object, this method takes an instance of an object.
39 | *
40 | * Properties must be simple names (not qualified names).
41 | *
42 | * @param {string} prop Name of the property
43 | * @param {!Object} object Instance of the object whose type will be used
44 | * for renaming
45 | * @return {string} The renamed property.
46 | */
47 | goog.reflect.objectProperty = function(prop, object) {
48 | 'use strict';
49 | return prop;
50 | };
51 |
52 | /**
53 | * To assert to the compiler that an operation is needed when it would
54 | * otherwise be stripped. For example:
55 | *
56 | * // Force a layout
57 | * goog.reflect.sinkValue(dialog.offsetHeight);
58 | *
59 | * @param {T} x
60 | * @return {T}
61 | * @template T
62 | */
63 | goog.reflect.sinkValue = function(x) {
64 | 'use strict';
65 | goog.reflect.sinkValue[' '](x);
66 | return x;
67 | };
68 |
69 |
70 | /**
71 | * The compiler should optimize this function away iff no one ever uses
72 | * goog.reflect.sinkValue.
73 | */
74 | goog.reflect.sinkValue[' '] = function() {};
75 |
76 |
77 | /**
78 | * Check if a property can be accessed without throwing an exception.
79 | * @param {Object} obj The owner of the property.
80 | * @param {string} prop The property name.
81 | * @return {boolean} Whether the property is accessible. Will also return true
82 | * if obj is null.
83 | */
84 | goog.reflect.canAccessProperty = function(obj, prop) {
85 | 'use strict';
86 | try {
87 | goog.reflect.sinkValue(obj[prop]);
88 | return true;
89 | } catch (e) {
90 | }
91 | return false;
92 | };
93 |
94 |
95 | /**
96 | * Retrieves a value from a cache given a key. The compiler provides special
97 | * consideration for this call such that it is generally considered side-effect
98 | * free. However, if the `opt_keyFn` or `valueFn` have side-effects
99 | * then the entire call is considered to have side-effects.
100 | *
101 | * Conventionally storing the value on the cache would be considered a
102 | * side-effect and preclude unused calls from being pruned, ie. even if
103 | * the value was never used, it would still always be stored in the cache.
104 | *
105 | * Providing a side-effect free `valueFn` and `opt_keyFn`
106 | * allows unused calls to `goog.reflect.cache` to be pruned.
107 | *
108 | * @param {!Object} cacheObj The object that contains the cached values.
109 | * @param {?} key The key to lookup in the cache. If it is not string or number
110 | * then a `opt_keyFn` should be provided. The key is also used as the
111 | * parameter to the `valueFn`.
112 | * @param {function(?):V} valueFn The value provider to use to calculate the
113 | * value to store in the cache. This function should be side-effect free
114 | * to take advantage of the optimization.
115 | * @param {function(?):K=} opt_keyFn The key provider to determine the cache
116 | * map key. This should be used if the given key is not a string or number.
117 | * If not provided then the given key is used. This function should be
118 | * side-effect free to take advantage of the optimization.
119 | * @return {V} The cached or calculated value.
120 | * @template K
121 | * @template V
122 | */
123 | goog.reflect.cache = function(cacheObj, key, valueFn, opt_keyFn) {
124 | 'use strict';
125 | const storedKey = opt_keyFn ? opt_keyFn(key) : key;
126 |
127 | if (Object.prototype.hasOwnProperty.call(cacheObj, storedKey)) {
128 | return cacheObj[storedKey];
129 | }
130 |
131 | return (cacheObj[storedKey] = valueFn(key));
132 | };
133 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/labs/useragent/highentropy/highentropyvalue.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /**
8 | * @fileoverview Provides helper classes and objects to work with High Entropy
9 | * user agent values.
10 | */
11 |
12 | goog.module('goog.labs.userAgent.highEntropy.highEntropyValue');
13 |
14 | const util = goog.require('goog.labs.userAgent.util');
15 | const {compareVersions} = goog.require('goog.string.internal');
16 |
17 | /**
18 | * Represents a value that can be asynchronously loaded.
19 | * @interface
20 | * @template VALUE_TYPE
21 | */
22 | class AsyncValue {
23 | /**
24 | * Get the value represented by this AsyncValue instance, if it was
25 | * previously requested.
26 | * @return {VALUE_TYPE|undefined}
27 | */
28 | getIfLoaded() {}
29 |
30 | /**
31 | * Request the value represented by this AsyncValue instance.
32 | * @return {!Promise}
33 | */
34 | load() {}
35 | }
36 | exports.AsyncValue = AsyncValue;
37 |
38 | /**
39 | * Represents a high-entropy value.
40 | * High-entropy values must be specifically requested from the Promise-based
41 | * Client Hints API.
42 | * @template VALUE_TYPE The type of the value wrapped by this HighEntropyValue
43 | * instance.
44 | * @implements {AsyncValue}
45 | */
46 | class HighEntropyValue {
47 | /**
48 | * Constructs a new HighEntropyValue instance.
49 | * @param {string} key The name of the high-entropy value, used when
50 | * requesting it from the browser.
51 | */
52 | constructor(key) {
53 | /**
54 | * The key used to request the high-entropy value from the browser.
55 | * @const {string}
56 | * @private
57 | */
58 | this.key_ = key;
59 |
60 | /**
61 | * The value represented by this HighEntropyValue instance. If it hasn't
62 | * been successfully requested yet, its value will be undefined.
63 | * @type {VALUE_TYPE|undefined}
64 | * @protected
65 | */
66 | this.value_ = undefined;
67 |
68 | /**
69 | * The high-entropy value request. If it hasn't been requested yet, this
70 | * value will be undefined.
71 | * @type {!Promise|undefined}
72 | * @private
73 | */
74 | this.promise_ = undefined;
75 |
76 | this.pending_ = false;
77 | }
78 |
79 | /**
80 | * @return {VALUE_TYPE|undefined}
81 | * @override
82 | */
83 | getIfLoaded() {
84 | const userAgentData = util.getUserAgentData();
85 | if (!userAgentData) {
86 | return undefined;
87 | }
88 | return this.value_;
89 | }
90 |
91 | /**
92 | * @return {!Promise}
93 | * @override
94 | */
95 | async load() {
96 | const userAgentData = util.getUserAgentData();
97 | if (!userAgentData) return undefined;
98 | if (!this.promise_) {
99 | this.pending_ = true;
100 | this.promise_ = (async () => {
101 | try {
102 | const dataValues =
103 | await userAgentData.getHighEntropyValues([this.key_]);
104 | this.value_ =
105 | /** @type {!Object} */ (
106 | dataValues)[this.key_];
107 | return this.value_;
108 | } finally {
109 | this.pending_ = false;
110 | }
111 | })();
112 | }
113 | return await this.promise_;
114 | }
115 |
116 | resetForTesting() {
117 | if (this.pending_) {
118 | // There is a pending request that may set this.value_ at any time.
119 | // Therefore, it can't be guaranteed that this object is actually in a
120 | // clean state.
121 | throw new Error('Unsafe call to resetForTesting');
122 | }
123 | this.promise_ = undefined;
124 | this.value_ = undefined;
125 | this.pending_ = false;
126 | }
127 | }
128 | exports.HighEntropyValue = HighEntropyValue;
129 |
130 | /**
131 | * An object that wraps a version string.
132 | * This allows for easy version comparisons.
133 | */
134 | class Version {
135 | /**
136 | * @param {string} versionString The underlying version string.
137 | */
138 | constructor(versionString) {
139 | /**
140 | * @const {string}
141 | * @private
142 | */
143 | this.versionString_ = versionString;
144 | }
145 |
146 | /**
147 | * Returns the underlying version string.
148 | * @return {string}
149 | */
150 | toVersionStringForLogging() {
151 | return this.versionString_;
152 | }
153 |
154 | /**
155 | * Returns true if the underlying version string is equal to or greater than
156 | * the given version.
157 | * @param {string} version The version to compare against.
158 | * @return {boolean}
159 | */
160 | isAtLeast(version) {
161 | return compareVersions(this.versionString_, version) >= 0;
162 | }
163 | }
164 | exports.Version = Version;
165 |
--------------------------------------------------------------------------------
/resources/public/cljs-out/min/goog/dom/asserts.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright The Closure Library Authors.
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | goog.provide('goog.dom.asserts');
8 |
9 | goog.require('goog.asserts');
10 |
11 | /**
12 | * @fileoverview Custom assertions to ensure that an element has the appropriate
13 | * type.
14 | *
15 | * Using a goog.dom.safe wrapper on an object on the incorrect type (via an
16 | * incorrect static type cast) can result in security bugs: For instance,
17 | * g.d.s.setAnchorHref ensures that the URL assigned to the .href attribute
18 | * satisfies the SafeUrl contract, i.e., is safe to dereference as a hyperlink.
19 | * However, the value assigned to a HTMLLinkElement's .href property requires
20 | * the stronger TrustedResourceUrl contract, since it can refer to a stylesheet.
21 | * Thus, using g.d.s.setAnchorHref on an (incorrectly statically typed) object
22 | * of type HTMLLinkElement can result in a security vulnerability.
23 | * Assertions of the correct run-time type help prevent such incorrect use.
24 | *
25 | * In some cases, code using the DOM API is tested using mock objects (e.g., a
26 | * plain object such as {'href': url} instead of an actual Location object).
27 | * To allow such mocking, the assertions permit objects of types that are not
28 | * relevant DOM API objects at all (for instance, not Element or Location).
29 | *
30 | * Note that instanceof checks don't work straightforwardly in older versions of
31 | * IE, or across frames (see,
32 | * http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object,
33 | * http://stackoverflow.com/questions/26248599/instanceof-htmlelement-in-iframe-is-not-element-or-object).
34 | *
35 | * Hence, these assertions may pass vacuously in such scenarios. The resulting
36 | * risk of security bugs is limited by the following factors:
37 | * - A bug can only arise in scenarios involving incorrect static typing (the
38 | * wrapper methods are statically typed to demand objects of the appropriate,
39 | * precise type).
40 | * - Typically, code is tested and exercised in multiple browsers.
41 | */
42 |
43 | /**
44 | * Asserts that a given object is a Location.
45 | *
46 | * To permit this assertion to pass in the context of tests where DOM APIs might
47 | * be mocked, also accepts any other type except for subtypes of {!Element}.
48 | * This is to ensure that, for instance, HTMLLinkElement is not being used in
49 | * place of a Location, since this could result in security bugs due to stronger
50 | * contracts required for assignments to the href property of the latter.
51 | *
52 | * @param {?Object} o The object whose type to assert.
53 | * @return {!Location}
54 | */
55 | goog.dom.asserts.assertIsLocation = function(o) {
56 | 'use strict';
57 | if (goog.asserts.ENABLE_ASSERTS) {
58 | var win = goog.dom.asserts.getWindow_(o);
59 | if (win) {
60 | if (!o || (!(o instanceof win.Location) && o instanceof win.Element)) {
61 | goog.asserts.fail(
62 | 'Argument is not a Location (or a non-Element mock); got: %s',
63 | goog.dom.asserts.debugStringForType_(o));
64 | }
65 | }
66 | }
67 | return /** @type {!Location} */ (o);
68 | };
69 |
70 |
71 | /**
72 | * Returns a string representation of a value's type.
73 | *
74 | * @param {*} value An object, or primitive.
75 | * @return {string} The best display name for the value.
76 | * @private
77 | */
78 | goog.dom.asserts.debugStringForType_ = function(value) {
79 | 'use strict';
80 | if (goog.isObject(value)) {
81 | try {
82 | return /** @type {string|undefined} */ (value.constructor.displayName) ||
83 | value.constructor.name || Object.prototype.toString.call(value);
84 | } catch (e) {
85 | return '