{"id":20675113,"url":"https://github.com/kaizhu256/node-jose-lite","last_synced_at":"2026-04-17T23:37:03.381Z","repository":{"id":57281676,"uuid":"216056899","full_name":"kaizhu256/node-jose-lite","owner":"kaizhu256","description":"this zero-dependency package will provide a standalone solution to encrypt/decrypt json-web-tokens in both browser/node","archived":false,"fork":false,"pushed_at":"2019-10-28T16:01:27.000Z","size":14619,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"beta","last_synced_at":"2025-08-09T08:59:08.975Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kaizhu256.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-18T15:41:15.000Z","updated_at":"2019-12-27T06:54:01.000Z","dependencies_parsed_at":"2022-08-31T10:50:35.495Z","dependency_job_id":null,"html_url":"https://github.com/kaizhu256/node-jose-lite","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/kaizhu256/node-jose-lite","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaizhu256%2Fnode-jose-lite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaizhu256%2Fnode-jose-lite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaizhu256%2Fnode-jose-lite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaizhu256%2Fnode-jose-lite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaizhu256","download_url":"https://codeload.github.com/kaizhu256/node-jose-lite/tar.gz/refs/heads/beta","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaizhu256%2Fnode-jose-lite/sbom","scorecard":{"id":547903,"data":{"date":"2025-08-11","repo":{"name":"github.com/kaizhu256/node-jose-lite","commit":"1c81a59de1d80ad866f10e8d057bdab45e8ea5b0"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.8,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/7 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: npmCommand not pinned by hash: npm_scripts.sh:31","Info:   0 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'beta'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-20T09:59:58.413Z","repository_id":57281676,"created_at":"2025-08-20T09:59:58.413Z","updated_at":"2025-08-20T09:59:58.413Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31950804,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T17:29:20.459Z","status":"ssl_error","status_checked_at":"2026-04-17T17:28:47.801Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T21:08:39.348Z","updated_at":"2026-04-17T23:37:03.350Z","avatar_url":"https://github.com/kaizhu256.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jose-lite\nthis zero-dependency package will provide a standalone solution to encrypt/decrypt json-web-tokens in both browser/node\n\n# live web demo\n- [https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/app](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/app)\n\n\n\n[![travis-ci.org build-status](https://api.travis-ci.org/kaizhu256/node-jose-lite.svg)](https://travis-ci.org/kaizhu256/node-jose-lite) [![coverage](https://kaizhu256.github.io/node-jose-lite/build/coverage.badge.svg)](https://kaizhu256.github.io/node-jose-lite/build/coverage.html/index.html)\n\n[![NPM](https://nodei.co/npm/jose-lite.png?downloads=true)](https://www.npmjs.com/package/jose-lite)\n\n[![build commit status](https://kaizhu256.github.io/node-jose-lite/build/build.badge.svg)](https://travis-ci.org/kaizhu256/node-jose-lite)\n\n| git-branch : | [master](https://github.com/kaizhu256/node-jose-lite/tree/master) | [beta](https://github.com/kaizhu256/node-jose-lite/tree/beta) | [alpha](https://github.com/kaizhu256/node-jose-lite/tree/alpha)|\n|--:|:--|:--|:--|\n| test-server-github : | [![github.com test-server](https://kaizhu256.github.io/node-jose-lite/GitHub-Mark-32px.png)](https://kaizhu256.github.io/node-jose-lite/build..master..travis-ci.org/app) | [![github.com test-server](https://kaizhu256.github.io/node-jose-lite/GitHub-Mark-32px.png)](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/app) | [![github.com test-server](https://kaizhu256.github.io/node-jose-lite/GitHub-Mark-32px.png)](https://kaizhu256.github.io/node-jose-lite/build..alpha..travis-ci.org/app)|\n| test-report : | [![test-report](https://kaizhu256.github.io/node-jose-lite/build..master..travis-ci.org/test-report.badge.svg)](https://kaizhu256.github.io/node-jose-lite/build..master..travis-ci.org/test-report.html) | [![test-report](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/test-report.badge.svg)](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/test-report.html) | [![test-report](https://kaizhu256.github.io/node-jose-lite/build..alpha..travis-ci.org/test-report.badge.svg)](https://kaizhu256.github.io/node-jose-lite/build..alpha..travis-ci.org/test-report.html)|\n| coverage : | [![coverage](https://kaizhu256.github.io/node-jose-lite/build..master..travis-ci.org/coverage.badge.svg)](https://kaizhu256.github.io/node-jose-lite/build..master..travis-ci.org/coverage.html/index.html) | [![coverage](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/coverage.badge.svg)](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/coverage.html/index.html) | [![coverage](https://kaizhu256.github.io/node-jose-lite/build..alpha..travis-ci.org/coverage.badge.svg)](https://kaizhu256.github.io/node-jose-lite/build..alpha..travis-ci.org/coverage.html/index.html)|\n| build-artifacts : | [![build-artifacts](https://kaizhu256.github.io/node-jose-lite/glyphicons_144_folder_open.png)](https://github.com/kaizhu256/node-jose-lite/tree/gh-pages/build..master..travis-ci.org) | [![build-artifacts](https://kaizhu256.github.io/node-jose-lite/glyphicons_144_folder_open.png)](https://github.com/kaizhu256/node-jose-lite/tree/gh-pages/build..beta..travis-ci.org) | [![build-artifacts](https://kaizhu256.github.io/node-jose-lite/glyphicons_144_folder_open.png)](https://github.com/kaizhu256/node-jose-lite/tree/gh-pages/build..alpha..travis-ci.org)|\n\n[![npmPackageListing](https://kaizhu256.github.io/node-jose-lite/build/screenshot.npmPackageListing.svg)](https://github.com/kaizhu256/node-jose-lite)\n\n![npmPackageDependencyTree](https://kaizhu256.github.io/node-jose-lite/build/screenshot.npmPackageDependencyTree.svg)\n\n\n\n# table of contents\n1. [cdn download](#cdn-download)\n1. [documentation](#documentation)\n1. [quickstart standalone app](#quickstart-standalone-app)\n1. [quickstart example.js](#quickstart-examplejs)\n1. [extra screenshots](#extra-screenshots)\n1. [package.json](#packagejson)\n1. [changelog of last 50 commits](#changelog-of-last-50-commits)\n1. [internal build script](#internal-build-script)\n1. [misc](#misc)\n\n\n\n# cdn download\n- [https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/app/assets.jose.js](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/app/assets.jose.js)\n\n\n\n# documentation\n#### api doc\n- [https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/apidoc.html](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/apidoc.html)\n\n[![apidoc](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Fapidoc.html.png)](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/apidoc.html)\n\n#### cli help\n![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.npmPackageCliHelp.svg)\n\n#### todo\n- none\n\n#### changelog 2019.10.25\n- npm publish 2019.10.25\n- rename lib jose_lite to jose\n- add and test function jweDecrypt, jweEncrypt, jweValidate, jwsDecode, jwsEncode, jwsValidate\n- update build\n- none\n\n#### this package requires\n- darwin or linux os\n\n\n\n# quickstart standalone app\n#### to run this example, follow instruction in script below\n- [assets.app.js](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/app/assets.app.js)\n```shell\n# example.sh\n\n# this shell script will download and run a web-demo of jose-lite as a standalone app\n\n# 1. download standalone app\ncurl -O https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/app/assets.app.js\n# 2. run standalone app\nPORT=8081 node ./assets.app.js\n# 3. open a browser to http://127.0.0.1:8081 and play with web-demo\n# 4. edit file assets.app.js to suit your needs\n```\n\n#### output from browser\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleSh.browser.%252F.png)](https://kaizhu256.github.io/node-jose-lite/build/app/assets.example.html)\n\n#### output from shell\n![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleSh.svg)\n\n\n\n# quickstart example.js\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleJs.browser.%252F.png)](https://kaizhu256.github.io/node-jose-lite/build/app/assets.example.html)\n\n#### to run this example, follow instruction in script below\n- [example.js](https://kaizhu256.github.io/node-jose-lite/build..beta..travis-ci.org/example.js)\n```javascript\n/*\nexample.js\n\nthis script will run a web-demo of jose-lite\n\ninstruction\n    1. save this script as example.js\n    2. run shell-command:\n        $ npm install jose-lite \u0026\u0026 \\\n            PORT=8081 node example.js\n    3. open a browser to http://127.0.0.1:8081 and play with web-demo\n    4. edit this script to suit your needs\n*/\n\n\n\n// assets.utility2.header.js - start\n/* istanbul ignore next */\n/* jslint utility2:true */\n(function (globalThis) {\n    \"use strict\";\n    let ArrayPrototypeFlat;\n    let TextXxcoder;\n    let consoleError;\n    let debugName;\n    let local;\n    debugName = \"debug\" + String(\"Inline\");\n    // init globalThis\n    globalThis.globalThis = globalThis.globalThis || globalThis;\n    // init debug_inline\n    if (!globalThis[debugName]) {\n        consoleError = console.error;\n        globalThis[debugName] = function (...argList) {\n        /*\n         * this function will both print \u003cargList\u003e to stderr\n         * and return \u003cargList\u003e[0]\n         */\n            consoleError(\"\\n\\n\" + debugName);\n            consoleError.apply(console, argList);\n            consoleError(\"\\n\");\n            // return arg0 for inspection\n            return argList[0];\n        };\n    }\n    // polyfill\n    ArrayPrototypeFlat = function (depth) {\n    /*\n     * this function will polyfill Array.prototype.flat\n     * https://github.com/jonathantneal/array-flat-polyfill\n     */\n        depth = (\n            globalThis.isNaN(depth)\n            ? 1\n            : Number(depth)\n        );\n        if (!depth) {\n            return Array.prototype.slice.call(this);\n        }\n        return Array.prototype.reduce.call(this, function (acc, cur) {\n            if (Array.isArray(cur)) {\n                // recurse\n                acc.push.apply(acc, ArrayPrototypeFlat.call(cur, depth - 1));\n            } else {\n                acc.push(cur);\n            }\n            return acc;\n        }, []);\n    };\n    Array.prototype.flat = Array.prototype.flat || ArrayPrototypeFlat;\n    Array.prototype.flatMap = Array.prototype.flatMap || function flatMap(\n        ...argList\n    ) {\n    /*\n     * this function will polyfill Array.prototype.flatMap\n     * https://github.com/jonathantneal/array-flat-polyfill\n     */\n        return this.map(...argList).flat();\n    };\n    String.prototype.trimEnd = (\n        String.prototype.trimEnd || String.prototype.trimRight\n    );\n    String.prototype.trimStart = (\n        String.prototype.trimStart || String.prototype.trimLeft\n    );\n    (function () {\n        try {\n            globalThis.TextDecoder = (\n                globalThis.TextDecoder || require(\"util\").TextDecoder\n            );\n            globalThis.TextEncoder = (\n                globalThis.TextEncoder || require(\"util\").TextEncoder\n            );\n        } catch (ignore) {}\n    }());\n    TextXxcoder = function () {\n    /*\n     * this function will polyfill TextDecoder/TextEncoder\n     * https://gist.github.com/Yaffle/5458286\n     */\n        return;\n    };\n    TextXxcoder.prototype.decode = function (octets) {\n    /*\n     * this function will polyfill TextDecoder.prototype.decode\n     * https://gist.github.com/Yaffle/5458286\n     */\n        let bytesNeeded;\n        let codePoint;\n        let ii;\n        let kk;\n        let octet;\n        let string;\n        string = \"\";\n        ii = 0;\n        while (ii \u003c octets.length) {\n            octet = octets[ii];\n            bytesNeeded = 0;\n            codePoint = 0;\n            if (octet \u003c= 0x7F) {\n                bytesNeeded = 0;\n                codePoint = octet \u0026 0xFF;\n            } else if (octet \u003c= 0xDF) {\n                bytesNeeded = 1;\n                codePoint = octet \u0026 0x1F;\n            } else if (octet \u003c= 0xEF) {\n                bytesNeeded = 2;\n                codePoint = octet \u0026 0x0F;\n            } else if (octet \u003c= 0xF4) {\n                bytesNeeded = 3;\n                codePoint = octet \u0026 0x07;\n            }\n            if (octets.length - ii - bytesNeeded \u003e 0) {\n                kk = 0;\n                while (kk \u003c bytesNeeded) {\n                    octet = octets[ii + kk + 1];\n                    codePoint = (codePoint \u003c\u003c 6) | (octet \u0026 0x3F);\n                    kk += 1;\n                }\n            } else {\n                codePoint = 0xFFFD;\n                bytesNeeded = octets.length - ii;\n            }\n            string += String.fromCodePoint(codePoint);\n            ii += bytesNeeded + 1;\n        }\n        return string;\n    };\n    TextXxcoder.prototype.encode = function (string) {\n    /*\n     * this function will polyfill TextEncoder.prototype.encode\n     * https://gist.github.com/Yaffle/5458286\n     */\n        let bits;\n        let cc;\n        let codePoint;\n        let ii;\n        let length;\n        let octets;\n        octets = [];\n        length = string.length;\n        ii = 0;\n        while (ii \u003c length) {\n            codePoint = string.codePointAt(ii);\n            cc = 0;\n            bits = 0;\n            if (codePoint \u003c= 0x0000007F) {\n                cc = 0;\n                bits = 0x00;\n            } else if (codePoint \u003c= 0x000007FF) {\n                cc = 6;\n                bits = 0xC0;\n            } else if (codePoint \u003c= 0x0000FFFF) {\n                cc = 12;\n                bits = 0xE0;\n            } else if (codePoint \u003c= 0x001FFFFF) {\n                cc = 18;\n                bits = 0xF0;\n            }\n            octets.push(bits | (codePoint \u003e\u003e cc));\n            cc -= 6;\n            while (cc \u003e= 0) {\n                octets.push(0x80 | ((codePoint \u003e\u003e cc) \u0026 0x3F));\n                cc -= 6;\n            }\n            ii += (\n                codePoint \u003e= 0x10000\n                ? 2\n                : 1\n            );\n        }\n        return octets;\n    };\n    globalThis.TextDecoder = globalThis.TextDecoder || TextXxcoder;\n    globalThis.TextEncoder = globalThis.TextEncoder || TextXxcoder;\n    // init local\n    local = {};\n    local.local = local;\n    globalThis.globalLocal = local;\n    // init isBrowser\n    local.isBrowser = (\n        typeof globalThis.XMLHttpRequest === \"function\"\n        \u0026\u0026 globalThis.navigator\n        \u0026\u0026 typeof globalThis.navigator.userAgent === \"string\"\n    );\n    // init isWebWorker\n    local.isWebWorker = (\n        local.isBrowser \u0026\u0026 typeof globalThis.importScript === \"function\"\n    );\n    // init function\n    local.assertOrThrow = function (passed, message) {\n    /*\n     * this function will throw err.\u003cmessage\u003e if \u003cpassed\u003e is falsy\n     */\n        let err;\n        if (passed) {\n            return;\n        }\n        err = (\n            (\n                message\n                \u0026\u0026 typeof message.message === \"string\"\n                \u0026\u0026 typeof message.stack === \"string\"\n            )\n            // if message is errObj, then leave as is\n            ? message\n            : new Error(\n                typeof message === \"string\"\n                // if message is a string, then leave as is\n                ? message\n                // else JSON.stringify message\n                : JSON.stringify(message, undefined, 4)\n            )\n        );\n        throw err;\n    };\n    local.coalesce = function (...argList) {\n    /*\n     * this function will coalesce null, undefined, or \"\" in \u003cargList\u003e\n     */\n        let arg;\n        let ii;\n        ii = 0;\n        while (ii \u003c argList.length) {\n            arg = argList[ii];\n            if (arg !== null \u0026\u0026 arg !== undefined \u0026\u0026 arg !== \"\") {\n                break;\n            }\n            ii += 1;\n        }\n        return arg;\n    };\n    local.fsRmrfSync = function (dir) {\n    /*\n     * this function will sync \"rm -rf\" \u003cdir\u003e\n     */\n        let child_process;\n        try {\n            child_process = require(\"child_process\");\n        } catch (ignore) {\n            return;\n        }\n        child_process.spawnSync(\"rm\", [\n            \"-rf\", dir\n        ], {\n            stdio: [\n                \"ignore\", 1, 2\n            ]\n        });\n    };\n    local.fsWriteFileWithMkdirpSync = function (file, data) {\n    /*\n     * this function will sync write \u003cdata\u003e to \u003cfile\u003e with \"mkdir -p\"\n     */\n        let fs;\n        try {\n            fs = require(\"fs\");\n        } catch (ignore) {\n            return;\n        }\n        // try to write file\n        try {\n            fs.writeFileSync(file, data);\n        } catch (ignore) {\n            // mkdir -p\n            require(\"child_process\").spawnSync(\n                \"mkdir\",\n                [\n                    \"-p\", require(\"path\").dirname(file)\n                ],\n                {\n                    stdio: [\n                        \"ignore\", 1, 2\n                    ]\n                }\n            );\n            // rewrite file\n            fs.writeFileSync(file, data);\n        }\n    };\n    local.functionOrNop = function (fnc) {\n    /*\n     * this function will if \u003cfnc\u003e exists,\n     * return \u003cfnc\u003e,\n     * else return \u003cnop\u003e\n     */\n        return fnc || local.nop;\n    };\n    local.identity = function (val) {\n    /*\n     * this function will return \u003cval\u003e\n     */\n        return val;\n    };\n    local.nop = function () {\n    /*\n     * this function will do nothing\n     */\n        return;\n    };\n    local.objectAssignDefault = function (target, source) {\n    /*\n     * this function will if items from \u003ctarget\u003e are null, undefined, or \"\",\n     * then overwrite them with items from \u003csource\u003e\n     */\n        target = target || {};\n        Object.keys(source || {}).forEach(function (key) {\n            if (\n                target[key] === null\n                || target[key] === undefined\n                || target[key] === \"\"\n            ) {\n                target[key] = target[key] || source[key];\n            }\n        });\n        return target;\n    };\n    local.querySelector = function (selectors) {\n    /*\n     * this function will return first dom-elem that match \u003cselectors\u003e\n     */\n        return (\n            typeof document === \"object\" \u0026\u0026 document\n            \u0026\u0026 typeof document.querySelector === \"function\"\n            \u0026\u0026 document.querySelector(selectors)\n        ) || {};\n    };\n    local.querySelectorAll = function (selectors) {\n    /*\n     * this function will return dom-elem-list that match \u003cselectors\u003e\n     */\n        return (\n            typeof document === \"object\" \u0026\u0026 document\n            \u0026\u0026 typeof document.querySelectorAll === \"function\"\n            \u0026\u0026 Array.from(document.querySelectorAll(selectors))\n        ) || [];\n    };\n    // require builtin\n    if (!local.isBrowser) {\n        local.assert = require(\"assert\");\n        local.buffer = require(\"buffer\");\n        local.child_process = require(\"child_process\");\n        local.cluster = require(\"cluster\");\n        local.crypto = require(\"crypto\");\n        local.dgram = require(\"dgram\");\n        local.dns = require(\"dns\");\n        local.domain = require(\"domain\");\n        local.events = require(\"events\");\n        local.fs = require(\"fs\");\n        local.http = require(\"http\");\n        local.https = require(\"https\");\n        local.net = require(\"net\");\n        local.os = require(\"os\");\n        local.path = require(\"path\");\n        local.querystring = require(\"querystring\");\n        local.readline = require(\"readline\");\n        local.repl = require(\"repl\");\n        local.stream = require(\"stream\");\n        local.string_decoder = require(\"string_decoder\");\n        local.timers = require(\"timers\");\n        local.tls = require(\"tls\");\n        local.tty = require(\"tty\");\n        local.url = require(\"url\");\n        local.util = require(\"util\");\n        local.vm = require(\"vm\");\n        local.zlib = require(\"zlib\");\n    }\n}((typeof globalThis === \"object\" \u0026\u0026 globalThis) || (function () {\n    return Function(\"return this\")(); // jslint ignore:line\n}())));\n// assets.utility2.header.js - end\n\n\n\n/* jslint utility2:true */\n(function (local) {\n\"use strict\";\n\n\n\n// run shared js-env code - init-before\n(function () {\n// init local\nlocal = (\n    globalThis.utility2_rollup\n    || globalThis.utility2_jose\n    || require(\"jose-lite\")\n);\n// init exports\nglobalThis.local = local;\n}());\n\n\n\n// run browser js-env code - init-test\n(function () {\nif (!local.isBrowser) {\n    return;\n}\n// log stderr and stdout to #outputStdout1\n[\"error\", \"log\"].forEach(function (key) {\n    let elem;\n    let fnc;\n    elem = local.querySelector(\"#outputStdout1\");\n    if (!elem) {\n        return;\n    }\n    fnc = console[key];\n    console[key] = function (...argList) {\n        fnc.apply(console, argList);\n        // append text to #outputStdout1\n        elem.textContent += argList.map(function (arg) {\n            return (\n                typeof arg === \"string\"\n                ? arg\n                : JSON.stringify(arg, undefined, 4)\n            );\n        }).join(\" \").replace((\n            /\\u001b\\[\\d*m/g\n        ), \"\") + \"\\n\";\n        // scroll textarea to bottom\n        elem.scrollTop = elem.scrollHeight;\n    };\n});\nlocal.objectAssignDefault(local, globalThis.domOnEventDelegateDict);\nglobalThis.domOnEventDelegateDict = local;\n}());\n\n\n\n// run node js-env code - init-test\n(function () {\nif (local.isBrowser) {\n    return;\n}\n// init exports\nmodule.exports = local;\n// init assetsDict\nlocal.assetsDict = local.assetsDict || {};\n[\n    \"assets.swgg.swagger.json\",\n    \"assets.swgg.swagger.server.json\"\n].forEach(function (file) {\n    file = \"/\" + file;\n    local.assetsDict[file] = local.assetsDict[file] || \"\";\n    if (local.fs.existsSync(local.__dirname + file)) {\n        local.assetsDict[file] = local.fs.readFileSync(\n            local.__dirname + file,\n            \"utf8\"\n        );\n    }\n});\n/* jslint ignore:start */\nlocal.assetsDict[\"/assets.index.template.html\"] = '\\\n\u003c!doctype html\u003e\\n\\\n\u003chtml lang=\"en\"\u003e\\n\\\n\u003chead\u003e\\n\\\n\u003cmeta charset=\"utf-8\"\u003e\\n\\\n\u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\\n\\\n\u003c!-- \"assets.utility2.template.html\" --\u003e\\n\\\n\u003ctitle\u003e{{env.npm_package_name}} ({{env.npm_package_version}})\u003c/title\u003e\\n\\\n\u003cstyle\u003e\\n\\\n/* jslint utility2:true */\\n\\\n/*csslint\\n\\\n*/\\n\\\n/* csslint ignore:start */\\n\\\n*,\\n\\\n*:after,\\n\\\n*:before {\\n\\\n    box-sizing: border-box;\\n\\\n}\\n\\\n/* csslint ignore:end */\\n\\\n@keyframes uiAnimateSpin {\\n\\\n0% {\\n\\\n    transform: rotate(0deg);\\n\\\n}\\n\\\n100% {\\n\\\n    transform: rotate(360deg);\\n\\\n}\\n\\\n}\\n\\\na {\\n\\\n    overflow-wrap: break-word;\\n\\\n}\\n\\\nbody {\\n\\\n    background: #f7f7f7;\\n\\\n    font-family: Arial, Helvetica, sans-serif;\\n\\\n    font-size: small;\\n\\\n    margin: 0 40px;\\n\\\n}\\n\\\nbody \u003e div,\\n\\\nbody \u003e input,\\n\\\nbody \u003e pre,\\n\\\nbody \u003e .button,\\n\\\nbody \u003e .textarea {\\n\\\n    margin-bottom: 20px;\\n\\\n    margin-top: 0;\\n\\\n}\\n\\\nbody \u003e input,\\n\\\nbody \u003e .button {\\n\\\n    width: 20rem;\\n\\\n}\\n\\\nbody \u003e .readonly {\\n\\\n    background: #ddd;\\n\\\n}\\n\\\nbody \u003e .textarea {\\n\\\n    height: 10rem;\\n\\\n    resize: vertical;\\n\\\n    width: 100%;\\n\\\n}\\n\\\ncode,\\n\\\npre,\\n\\\n.textarea {\\n\\\n    font-family: Consolas, Menlo, monospace;\\n\\\n    font-size: smaller;\\n\\\n}\\n\\\npre {\\n\\\n    overflow-wrap: break-word;\\n\\\n    white-space: pre-wrap;\\n\\\n}\\n\\\n.button {\\n\\\n    background: #ddd;\\n\\\n    border: 1px solid #999;\\n\\\n    color: #000;\\n\\\n    cursor: pointer;\\n\\\n    display: inline-block;\\n\\\n    padding: 2px 5px;\\n\\\n    text-align: center;\\n\\\n    text-decoration: none;\\n\\\n}\\n\\\n.button:hover {\\n\\\n    background: #bbb;\\n\\\n}\\n\\\n.colorError {\\n\\\n    color: #d00;\\n\\\n}\\n\\\n.textarea {\\n\\\n    background: #fff;\\n\\\n    border: 1px solid #999;\\n\\\n    border-radius: 0;\\n\\\n    cursor: auto;\\n\\\n    overflow: auto;\\n\\\n    padding: 2px;\\n\\\n}\\n\\\n.uiAnimateSlide {\\n\\\n    overflow-y: hidden;\\n\\\n    transition: max-height ease-in 250ms, min-height ease-in 250ms, padding-bottom ease-in 250ms, padding-top ease-in 250ms;\\n\\\n}\\n\\\n.zeroPixel {\\n\\\n    border: 0;\\n\\\n    height: 0;\\n\\\n    margin: 0;\\n\\\n    padding: 0;\\n\\\n    width: 0;\\n\\\n}\\n\\\n\u003c/style\u003e\\n\\\n\u003c/head\u003e\\n\\\n\u003cbody\u003e\\n\\\n\u003cdiv class=\"uiAnimateSpin\" style=\"animation: uiAnimateSpin 2s linear infinite; border: 5px solid #999; border-radius: 50%; border-top: 5px solid #7d7; display: none; height: 25px; vertical-align: middle; width: 25px;\"\u003e\u003c/div\u003e\\n\\\n\u003cscript\u003e\\n\\\n/* jslint utility2:true */\\n\\\n// init domOnEventWindowOnloadTimeElapsed\\n\\\n(function () {\\n\\\n/*\\n\\\n * this function will measure and print time-elapsed for window.onload\\n\\\n */\\n\\\n    \"use strict\";\\n\\\n    if (!(\\n\\\n        typeof window === \"object\" \u0026\u0026 window \u0026\u0026 window.document\\n\\\n        \u0026\u0026 typeof document.addEventListener === \"function\"\\n\\\n    ) || window.domOnEventWindowOnloadTimeElapsed) {\\n\\\n        return;\\n\\\n    }\\n\\\n    window.domOnEventWindowOnloadTimeElapsed = Date.now() + 100;\\n\\\n    window.addEventListener(\"load\", function () {\\n\\\n        setTimeout(function () {\\n\\\n            window.domOnEventWindowOnloadTimeElapsed = (\\n\\\n                Date.now()\\n\\\n                - window.domOnEventWindowOnloadTimeElapsed\\n\\\n            );\\n\\\n            console.error(\\n\\\n                \"domOnEventWindowOnloadTimeElapsed = \"\\n\\\n                + window.domOnEventWindowOnloadTimeElapsed\\n\\\n            );\\n\\\n        }, 100);\\n\\\n    });\\n\\\n}());\\n\\\n\\n\\\n\\n\\\n\\n\\\n// init domOnEventAjaxProgressUpdate\\n\\\n(function () {\\n\\\n/*\\n\\\n * this function will display incrementing ajax-progress-bar\\n\\\n */\\n\\\n    \"use strict\";\\n\\\n    let opt;\\n\\\n    if (!(\\n\\\n        typeof window === \"object\" \u0026\u0026 window \u0026\u0026 window.document\\n\\\n        \u0026\u0026 typeof document.addEventListener === \"function\"\\n\\\n    ) || window.domOnEventAjaxProgressUpdate) {\\n\\\n        return;\\n\\\n    }\\n\\\n    window.domOnEventAjaxProgressUpdate = function (gotoState, onError) {\\n\\\n        gotoState = (gotoState | 0) + 1;\\n\\\n        switch (gotoState) {\\n\\\n        // ajaxProgress - show\\n\\\n        case 1:\\n\\\n            // init timerInterval and timerTimeout\\n\\\n            opt.timerInterval = (\\n\\\n                opt.timerInterval || setInterval(opt, 2000, 1, onError)\\n\\\n            );\\n\\\n            opt.timerTimeout = (\\n\\\n                opt.timerTimeout || setTimeout(opt, 30000, 2, onError)\\n\\\n            );\\n\\\n            // show ajaxProgress\\n\\\n            if (opt.width !== -1) {\\n\\\n                opt.style.background = opt.background;\\n\\\n            }\\n\\\n            setTimeout(opt, 50, gotoState, onError);\\n\\\n            break;\\n\\\n        // ajaxProgress - increment\\n\\\n        case 2:\\n\\\n            // show ajaxProgress\\n\\\n            if (opt.width === -1) {\\n\\\n                return;\\n\\\n            }\\n\\\n            opt.style.background = opt.background;\\n\\\n            // reset ajaxProgress if it goes too high\\n\\\n            if ((opt.style.width.slice(0, -1) | 0) \u003e 95) {\\n\\\n                opt.width = 0;\\n\\\n            }\\n\\\n            // this algorithm will indefinitely increment ajaxProgress\\n\\\n            // with successively smaller increments without reaching 100%\\n\\\n            opt.width += 1;\\n\\\n            opt.style.width = Math.max(\\n\\\n                100 - 75 * Math.exp(-0.125 * opt.width),\\n\\\n                opt.style.width.slice(0, -1) | 0\\n\\\n            ) + \"%\";\\n\\\n            if (!opt.counter) {\\n\\\n                setTimeout(opt, 0, gotoState, onError);\\n\\\n            }\\n\\\n            break;\\n\\\n        // ajaxProgress - 100%\\n\\\n        case 3:\\n\\\n            opt.width = -1;\\n\\\n            opt.style.width = \"100%\";\\n\\\n            setTimeout(opt, 1000, gotoState, onError);\\n\\\n            break;\\n\\\n        // ajaxProgress - hide\\n\\\n        case 4:\\n\\\n            // cleanup timerInterval and timerTimeout\\n\\\n            clearInterval(opt.timerInterval);\\n\\\n            opt.timerInterval = null;\\n\\\n            clearTimeout(opt.timerTimeout);\\n\\\n            opt.timerTimeout = null;\\n\\\n            // hide ajaxProgress\\n\\\n            opt.style.background = \"transparent\";\\n\\\n            if (onError) {\\n\\\n                onError();\\n\\\n            }\\n\\\n            setTimeout(opt, 250, gotoState);\\n\\\n            break;\\n\\\n        // ajaxProgress - reset\\n\\\n        default:\\n\\\n            // reset ajaxProgress\\n\\\n            opt.counter = 0;\\n\\\n            opt.width = 0;\\n\\\n            opt.style.width = \"0%\";\\n\\\n        }\\n\\\n    };\\n\\\n    opt = window.domOnEventAjaxProgressUpdate;\\n\\\n    opt.end = function (onError) {\\n\\\n        opt.counter = 0;\\n\\\n        window.domOnEventAjaxProgressUpdate(2, onError);\\n\\\n    };\\n\\\n    opt.elem = document.getElementById(\"domElementAjaxProgress1\");\\n\\\n    if (!opt.elem) {\\n\\\n        opt.elem = document.createElement(\"div\");\\n\\\n        setTimeout(function () {\\n\\\n            document.body.insertBefore(opt.elem, document.body.firstChild);\\n\\\n        });\\n\\\n    }\\n\\\n    opt.elem.id = \"domElementAjaxProgress1\";\\n\\\n    opt.style = opt.elem.style;\\n\\\n    // init style\\n\\\n    Object.entries({\\n\\\n        background: \"#d00\",\\n\\\n        height: \"2px\",\\n\\\n        left: \"0\",\\n\\\n        margin: \"0\",\\n\\\n        padding: \"0\",\\n\\\n        position: \"fixed\",\\n\\\n        top: \"0\",\\n\\\n        transition: \"background 250ms, width 750ms\",\\n\\\n        width: \"0%\",\\n\\\n        \"z-index\": \"1\"\\n\\\n    }).forEach(function (entry) {\\n\\\n        opt.style[entry[0]] = opt.style[entry[0]] || entry[1];\\n\\\n    });\\n\\\n    // init state\\n\\\n    opt.background = opt.style.background;\\n\\\n    opt.counter = 0;\\n\\\n    opt.width = 0;\\n\\\n}());\\n\\\n\\n\\\n\\n\\\n\\n\\\n// init domOnEventDelegateDict\\n\\\n(function () {\\n\\\n/*\\n\\\n * this function will handle delegated dom-evt\\n\\\n */\\n\\\n    \"use strict\";\\n\\\n    let debounce;\\n\\\n    let timerTimeout;\\n\\\n    debounce = function () {\\n\\\n        return setTimeout(function () {\\n\\\n            timerTimeout = undefined;\\n\\\n        }, 30);\\n\\\n    };\\n\\\n    if (!(\\n\\\n        typeof window === \"object\" \u0026\u0026 window \u0026\u0026 window.document\\n\\\n        \u0026\u0026 typeof document.addEventListener === \"function\"\\n\\\n    ) || window.domOnEventDelegateDict) {\\n\\\n        return;\\n\\\n    }\\n\\\n    window.domOnEventDelegateDict = {};\\n\\\n    window.domOnEventDelegateDict.domOnEventDelegate = function (evt) {\\n\\\n        evt.targetOnEvent = evt.target.closest(\"[data-onevent]\");\\n\\\n        if (\\n\\\n            !evt.targetOnEvent\\n\\\n            || evt.targetOnEvent.dataset.onevent === \"domOnEventNop\"\\n\\\n            || evt.target.closest(\".disabled,.readonly\")\\n\\\n        ) {\\n\\\n            return;\\n\\\n        }\\n\\\n        // filter evt-change\\n\\\n        switch (evt.type !== \"change\" \u0026\u0026 evt.target.type) {\\n\\\n        case \"checkbox\":\\n\\\n        case \"file\":\\n\\\n        case \"select-one\":\\n\\\n        case \"radio\":\\n\\\n            return;\\n\\\n        }\\n\\\n        // filter evt-keyup\\n\\\n        switch (evt.type) {\\n\\\n        case \"keyup\":\\n\\\n            if (!timerTimeout \u0026\u0026 (\\n\\\n                evt.target.tagName === \"INPUT\"\\n\\\n                || evt.target.tagName === \"TEXTAREA\"\\n\\\n            )) {\\n\\\n                timerTimeout = debounce();\\n\\\n                if (evt.target.dataset.valueOld !== evt.target.value) {\\n\\\n                    evt.target.dataset.valueOld = evt.target.value;\\n\\\n                    break;\\n\\\n                }\\n\\\n            }\\n\\\n            return;\\n\\\n        }\\n\\\n        switch (evt.targetOnEvent.tagName) {\\n\\\n        case \"BUTTON\":\\n\\\n        case \"FORM\":\\n\\\n            evt.preventDefault();\\n\\\n            break;\\n\\\n        }\\n\\\n        evt.stopPropagation();\\n\\\n        // handle domOnEventClickTarget\\n\\\n        if (evt.targetOnEvent.dataset.onevent === \"domOnEventClickTarget\") {\\n\\\n            document.querySelector(\\n\\\n                evt.targetOnEvent.dataset.clickTarget\\n\\\n            ).click();\\n\\\n            return;\\n\\\n        }\\n\\\n        window.domOnEventDelegateDict[evt.targetOnEvent.dataset.onevent](evt);\\n\\\n    };\\n\\\n    // handle evt\\n\\\n    [\\n\\\n        \"change\",\\n\\\n        \"click\",\\n\\\n        \"keyup\",\\n\\\n        \"submit\"\\n\\\n    ].forEach(function (eventType) {\\n\\\n        document.addEventListener(\\n\\\n            eventType,\\n\\\n            window.domOnEventDelegateDict.domOnEventDelegate\\n\\\n        );\\n\\\n    });\\n\\\n}());\\n\\\n\\n\\\n\\n\\\n\\n\\\n// init domOnEventSelectAllWithinPre\\n\\\n(function () {\\n\\\n/*\\n\\\n * this function will limit select-all within \u003cpre tabIndex=\"0\"\u003e elem\\n\\\n * https://stackoverflow.com/questions/985272/selecting-text-in-an-element-akin-to-highlighting-with-your-mouse\\n\\\n */\\n\\\n    \"use strict\";\\n\\\n    if (!(\\n\\\n        typeof window === \"object\" \u0026\u0026 window \u0026\u0026 window.document\\n\\\n        \u0026\u0026 typeof document.addEventListener === \"function\"\\n\\\n    ) || window.domOnEventSelectAllWithinPre) {\\n\\\n        return;\\n\\\n    }\\n\\\n    window.domOnEventSelectAllWithinPre = function (evt) {\\n\\\n        let range;\\n\\\n        let selection;\\n\\\n        if (\\n\\\n            evt \u0026\u0026 (evt.ctrlKey || evt.metaKey) \u0026\u0026 evt.key === \"a\"\\n\\\n            \u0026\u0026 evt.target.closest(\"pre\")\\n\\\n        ) {\\n\\\n            range = document.createRange();\\n\\\n            range.selectNodeContents(evt.target.closest(\"pre\"));\\n\\\n            selection = window.getSelection();\\n\\\n            selection.removeAllRanges();\\n\\\n            selection.addRange(range);\\n\\\n            evt.preventDefault();\\n\\\n        }\\n\\\n    };\\n\\\n    // handle evt\\n\\\n    document.addEventListener(\\n\\\n        \"keydown\",\\n\\\n        window.domOnEventSelectAllWithinPre\\n\\\n    );\\n\\\n}());\\n\\\n\u003c/script\u003e\\n\\\n\u003ch1\u003e\\n\\\n\u003c!-- utility2-comment\\n\\\n\u003ca\\n\\\n    {{#if env.npm_package_homepage}}\\n\\\n    href=\"{{env.npm_package_homepage}}\"\\n\\\n    {{/if env.npm_package_homepage}}\\n\\\n    target=\"_blank\"\\n\\\n\u003e\\n\\\nutility2-comment --\u003e\\n\\\n    {{env.npm_package_name}} ({{env.npm_package_version}})\\n\\\n\u003c!-- utility2-comment\\n\\\n\u003c/a\u003e\\n\\\nutility2-comment --\u003e\\n\\\n\u003c/h1\u003e\\n\\\n\u003ch3\u003e{{env.npm_package_description}}\u003c/h3\u003e\\n\\\n\u003c!-- utility2-comment\\n\\\n\u003ca class=\"button\" download href=\"assets.app.js\"\u003edownload standalone app\u003c/a\u003e\u003cbr\u003e\\n\\\n\u003cbutton class=\"button\" data-onevent=\"testRunBrowser\" id=\"buttonTestRun1\"\u003erun browser-tests\u003c/button\u003e\u003cbr\u003e\\n\\\n\u003cdiv class=\"uiAnimateSlide\" id=\"htmlTestReport1\" style=\"border-bottom: 0; border-top: 0; margin-bottom: 0; margin-top: 0; max-height: 0; padding-bottom: 0; padding-top: 0;\"\u003e\u003c/div\u003e\\n\\\nutility2-comment --\u003e\\n\\\n\\n\\\n\\n\\\n\\n\\\n\u003c!-- custom-html-start --\u003e\\n\\\n\u003clabel\u003estderr and stdout\u003c/label\u003e\\n\\\n\u003ctextarea class=\"onevent-reset-output readonly textarea\" id=\"outputStdout1\" readonly\u003e\u003c/textarea\u003e\\n\\\n\u003c!-- custom-html-end --\u003e\\n\\\n\\n\\\n\\n\\\n\\n\\\n\u003c!-- utility2-comment\\n\\\n{{#if isRollup}}\\n\\\n\u003cscript src=\"assets.app.js\"\u003e\u003c/script\u003e\\n\\\n{{#unless isRollup}}\\n\\\n\u003cscript src=\"assets.utility2.rollup.js\"\u003e\u003c/script\u003e\\n\\\n\u003cscript\u003ewindow.utility2_onReadyBefore.counter += 1;\u003c/script\u003e\\n\\\n\u003cscript src=\"jsonp.utility2.stateInit?callback=window.utility2.stateInit\"\u003e\u003c/script\u003e\\n\\\nutility2-comment --\u003e\\n\\\n\u003cscript src=\"assets.jose.js\"\u003e\u003c/script\u003e\\n\\\n\u003cscript src=\"assets.example.js\"\u003e\u003c/script\u003e\\n\\\n\u003cscript src=\"assets.test.js\"\u003e\u003c/script\u003e\\n\\\n\u003cscript\u003e\\n\\\nif (window.utility2_onReadyBefore) {\\n\\\n    window.utility2_onReadyBefore();\\n\\\n}\\n\\\n\u003c/script\u003e\\n\\\n\u003c!-- utility2-comment\\n\\\n{{/if isRollup}}\\n\\\nutility2-comment --\u003e\\n\\\n\u003cdiv style=\"text-align: center;\"\u003e\\n\\\n    [\\n\\\n    this app was created with\\n\\\n    \u003ca\\n\\\n        href=\"https://github.com/kaizhu256/node-utility2\" target=\"_blank\"\\n\\\n    \u003eutility2\u003c/a\u003e\\n\\\n    ]\\n\\\n\u003c/div\u003e\\n\\\n\u003c/body\u003e\\n\\\n\u003c/html\u003e\\n\\\n';\n/* jslint ignore:end */\nlocal.assetsDict[\"/assets.jose.js\"] = (\n    local.assetsDict[\"/assets.jose.js\"]\n    || local.fs.readFileSync(\n        local.__dirname + \"/lib.jose.js\",\n        \"utf8\"\n    ).replace((\n        /^#!\\//\n    ), \"// \")\n);\n/* validateLineSortedReset */\nlocal.assetsDict[\"/\"] = local.assetsDict[\n    \"/assets.index.template.html\"\n].replace((\n    /\\{\\{env\\.(\\w+?)\\}\\}/g\n), function (match0, match1) {\n    switch (match1) {\n    case \"npm_package_description\":\n        return \"the greatest app in the world!\";\n    case \"npm_package_name\":\n        return \"jose-lite\";\n    case \"npm_package_nameLib\":\n        return \"jose\";\n    case \"npm_package_version\":\n        return \"0.0.1\";\n    default:\n        return match0;\n    }\n});\nlocal.assetsDict[\"/assets.example.html\"] = local.assetsDict[\"/\"];\n// init cli\nif (module !== require.main || globalThis.utility2_rollup) {\n    return;\n}\nlocal.assetsDict[\"/assets.example.js\"] = (\n    local.assetsDict[\"/assets.example.js\"]\n    || local.fs.readFileSync(__filename, \"utf8\")\n);\nlocal.assetsDict[\"/favicon.ico\"] = local.assetsDict[\"/favicon.ico\"] || \"\";\nlocal.assetsDict[\"/index.html\"] = local.assetsDict[\"/\"];\n// if $npm_config_timeout_exit exists,\n// then exit this process after $npm_config_timeout_exit ms\nif (Number(process.env.npm_config_timeout_exit)) {\n    setTimeout(process.exit, Number(process.env.npm_config_timeout_exit));\n}\n// start server\nif (globalThis.utility2_serverHttp1) {\n    return;\n}\nprocess.env.PORT = process.env.PORT || \"8081\";\nconsole.error(\"http-server listening on port \" + process.env.PORT);\nlocal.http.createServer(function (req, res) {\n    req.urlParsed = local.url.parse(req.url);\n    if (local.assetsDict[req.urlParsed.pathname] !== undefined) {\n        res.end(local.assetsDict[req.urlParsed.pathname]);\n        return;\n    }\n    res.statusCode = 404;\n    res.end();\n}).listen(process.env.PORT);\n}());\n}());\n```\n\n#### output from browser\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleJs.browser.%252F.png)](https://kaizhu256.github.io/node-jose-lite/build/app/assets.example.html)\n\n#### output from shell\n![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleJs.svg)\n\n\n\n# extra screenshots\n1. [https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Fapidoc.html.png](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Fapidoc.html.png)\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Fapidoc.html.png)](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Fapidoc.html.png)\n\n1. [https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Fcoverage.lib.html.png](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Fcoverage.lib.html.png)\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Fcoverage.lib.html.png)](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Fcoverage.lib.html.png)\n\n1. [https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Ftest-report.html.png](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Ftest-report.html.png)\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Ftest-report.html.png)](https://kaizhu256.github.io/node-jose-lite/build/screenshot.buildCi.browser.%252Ftmp%252Fbuild%252Ftest-report.html.png)\n\n1. [https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithub.browser.%252Fnode-jose-lite%252Fbuild%252Fapp%252Fassets.swgg.html.png](https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithub.browser.%252Fnode-jose-lite%252Fbuild%252Fapp%252Fassets.swgg.html.png)\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithub.browser.%252Fnode-jose-lite%252Fbuild%252Fapp%252Fassets.swgg.html.png)](https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithub.browser.%252Fnode-jose-lite%252Fbuild%252Fapp%252Fassets.swgg.html.png)\n\n1. [https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithub.browser.%252Fnode-jose-lite%252Fbuild%252Fapp.png](https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithub.browser.%252Fnode-jose-lite%252Fbuild%252Fapp.png)\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithub.browser.%252Fnode-jose-lite%252Fbuild%252Fapp.png)](https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithub.browser.%252Fnode-jose-lite%252Fbuild%252Fapp.png)\n\n1. [https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithubTest.browser.%252Fnode-jose-lite%252Fbuild%252Fapp.png](https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithubTest.browser.%252Fnode-jose-lite%252Fbuild%252Fapp.png)\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithubTest.browser.%252Fnode-jose-lite%252Fbuild%252Fapp.png)](https://kaizhu256.github.io/node-jose-lite/build/screenshot.deployGithubTest.browser.%252Fnode-jose-lite%252Fbuild%252Fapp.png)\n\n\n\n1. [https://kaizhu256.github.io/node-jose-lite/build/screenshot.npmTest.browser.%252F.png](https://kaizhu256.github.io/node-jose-lite/build/screenshot.npmTest.browser.%252F.png)\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.npmTest.browser.%252F.png)](https://kaizhu256.github.io/node-jose-lite/build/screenshot.npmTest.browser.%252F.png)\n\n1. [https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleJs.browser.%252F.png](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleJs.browser.%252F.png)\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleJs.browser.%252F.png)](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleJs.browser.%252F.png)\n\n1. [https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleSh.browser.%252F.png](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleSh.browser.%252F.png)\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleSh.browser.%252F.png)](https://kaizhu256.github.io/node-jose-lite/build/screenshot.testExampleSh.browser.%252F.png)\n\n\n\n# package.json\n```json\n{\n    \"author\": \"kai zhu \u003ckaizhu256@gmail.com\u003e\",\n    \"description\": \"this zero-dependency package will provide a standalone solution to encrypt/decrypt json-web-tokens in both browser/node\",\n    \"devDependencies\": {\n        \"utility2\": \"kaizhu256/node-utility2#alpha\"\n    },\n    \"engines\": {\n        \"node\": \"\u003e=10.0\"\n    },\n    \"homepage\": \"https://github.com/kaizhu256/node-jose-lite\",\n    \"keywords\": [\n        \"jwe\",\n        \"jws\",\n        \"jwt\"\n    ],\n    \"license\": \"MIT\",\n    \"main\": \"lib.jose.js\",\n    \"name\": \"jose-lite\",\n    \"nameAliasPublish\": \"\",\n    \"nameLib\": \"jose\",\n    \"nameOriginal\": \"jose-lite\",\n    \"os\": [\n        \"darwin\",\n        \"linux\"\n    ],\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/kaizhu256/node-jose-lite.git\"\n    },\n    \"scripts\": {\n        \"build-ci\": \"./npm_scripts.sh\",\n        \"env\": \"env\",\n        \"eval\": \"./npm_scripts.sh\",\n        \"heroku-postbuild\": \"./npm_scripts.sh\",\n        \"postinstall\": \"./npm_scripts.sh\",\n        \"start\": \"./npm_scripts.sh\",\n        \"test\": \"./npm_scripts.sh\",\n        \"utility2\": \"./npm_scripts.sh\"\n    },\n    \"version\": \"2019.10.25\"\n}\n```\n\n\n\n# changelog of last 50 commits\n[![screenshot](https://kaizhu256.github.io/node-jose-lite/build/screenshot.gitLog.svg)](https://github.com/kaizhu256/node-jose-lite/commits)\n\n\n\n# internal build script\n- build_ci.sh\n```shell\n# build_ci.sh\n\n# this shell script will run the build for this package\n\nshBuildCiAfter () {(set -e\n    # shDeployCustom\n    shDeployGithub\n    # shDeployHeroku\n    shReadmeTest example.sh\n)}\n\nshBuildCiBefore () {(set -e\n    shNpmTestPublished\n    shReadmeTest example.js\n)}\n\n# run shBuildCi\neval \"$(utility2 source)\"\nshBuildCi\n```\n\n\n\n# misc\n- this package was created with [utility2](https://github.com/kaizhu256/node-utility2)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaizhu256%2Fnode-jose-lite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaizhu256%2Fnode-jose-lite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaizhu256%2Fnode-jose-lite/lists"}