diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index bc7e8194..00000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,97 +0,0 @@
-version: 2
-jobs:
- install:
- macos:
- xcode: "9.2.0"
- working_directory: ~/repo
- steps:
- - checkout
- - restore_cache:
- key: cache-{{ checksum "yarn.lock" }}
- - run:
- name: Installing Dependencies
- command: yarn --ignore-engines
- - save_cache:
- key: cache-{{ checksum "yarn.lock" }}
- paths:
- - node_modules
- - run:
- name: Getting build icon
- command: if [[ $CIRCLE_BRANCH == canary ]]; then cp build/canary.icns build/icon.icns; fi
- - persist_to_workspace:
- root: .
- paths:
- - node_modules
-
- test:
- macos:
- xcode: "9.2.0"
- steps:
- - checkout
- - attach_workspace:
- at: .
- - run:
- name: Testing
- command: yarn test
-
- build:
- macos:
- xcode: "9.2.0"
- steps:
- - checkout
- - attach_workspace:
- at: .
- - run:
- name: Building
- command: yarn dist --publish 'never'
- - store_artifacts:
- path: dist
- - persist_to_workspace:
- root: .
- paths:
- - dist
-
- release:
- macos:
- xcode: "9.2.0"
- steps:
- - checkout
- - attach_workspace:
- at: .
- - run:
- name: Deploying to GitHub
- command: yarn dist
-
-
-workflows:
- version: 2
- build:
- jobs:
- - install:
- filters:
- tags:
- only: /.*/
- - test:
- requires:
- - install
- filters:
- tags:
- only: /.*/
- - build:
- requires:
- - test
- filters:
- branches:
- only:
- - master
- - canary
- tags:
- ignore: /.*/
- - release:
- requires:
- - test
- filters:
- tags:
- only: /.*/
- branches:
- ignore: /.*/
diff --git a/.eslintignore b/.eslintignore
index 9344d5af..5f94ba00 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -4,7 +4,9 @@ app/static
app/bin
app/dist
app/node_modules
+app/typings
assets
website
bin
-dist
\ No newline at end of file
+dist
+target
\ No newline at end of file
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 00000000..02af8b96
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,113 @@
+{
+ "plugins": [
+ "react",
+ "prettier",
+ "@typescript-eslint",
+ "eslint-comments"
+ ],
+ "extends": [
+ "eslint:recommended",
+ "plugin:react/recommended",
+ "plugin:prettier/recommended",
+ "plugin:eslint-comments/recommended"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "ecmaVersion": 8,
+ "sourceType": "module",
+ "ecmaFeatures": {
+ "jsx": true,
+ "impliedStrict": true,
+ "experimentalObjectRestSpread": true
+ },
+ "allowImportExportEverywhere": true,
+ "project": [
+ "./tsconfig.eslint.json"
+ ]
+ },
+ "env": {
+ "es6": true,
+ "browser": true,
+ "node": true
+ },
+ "settings": {
+ "react": {
+ "version": "detect"
+ }
+ },
+ "rules": {
+ "func-names": [
+ "error",
+ "as-needed"
+ ],
+ "no-shadow": "error",
+ "no-extra-semi": 0,
+ "react/prop-types": 0,
+ "react/react-in-jsx-scope": 0,
+ "react/no-unescaped-entities": 0,
+ "react/jsx-no-target-blank": 0,
+ "react/no-string-refs": 0,
+ "prettier/prettier": [
+ "error",
+ {
+ "printWidth": 120,
+ "tabWidth": 2,
+ "singleQuote": true,
+ "trailingComma": "none",
+ "bracketSpacing": false,
+ "semi": true,
+ "useTabs": false,
+ "jsxBracketSameLine": false
+ }
+ ],
+ "eslint-comments/no-unused-disable": "error"
+ },
+ "overrides": [
+ {
+ "files": [
+ "app/config/config-default.js",
+ ".hyper.js"
+ ],
+ "rules": {
+ "prettier/prettier": [
+ "error",
+ {
+ "printWidth": 120,
+ "tabWidth": 2,
+ "singleQuote": true,
+ "trailingComma": "es5",
+ "bracketSpacing": false,
+ "semi": true,
+ "useTabs": false,
+ "parser": "babel",
+ "jsxBracketSameLine": false
+ }
+ ]
+ }
+ },
+ {
+ "files": [
+ "**.ts",
+ "**.tsx"
+ ],
+ "extends": [
+ "plugin:@typescript-eslint/recommended",
+ "plugin:@typescript-eslint/recommended-requiring-type-checking",
+ "prettier"
+ ],
+ "rules": {
+ "@typescript-eslint/explicit-function-return-type": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ "@typescript-eslint/prefer-optional-chain": "error",
+ "@typescript-eslint/ban-types": "off",
+ "no-shadow": "off",
+ "@typescript-eslint/no-shadow": ["error"],
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-member-access": "off",
+ "@typescript-eslint/restrict-template-expressions": "off"
+ }
+ }
+ ]
+}
diff --git a/.gitattributes b/.gitattributes
index 391f0a4e..97c115ec 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,5 @@
* text=auto
*.js text eol=lf
+*.ts text eol=lf
+*.tsx text eol=lf
+bin/* linguist-vendored
diff --git a/.github/issue_template.md b/.github/ISSUE_TEMPLATE/bug_report.md
similarity index 74%
rename from .github/issue_template.md
rename to .github/ISSUE_TEMPLATE/bug_report.md
index b7bef5b2..3e772142 100644
--- a/.github/issue_template.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,14 +1,23 @@
+---
+name: Bug report
+about: Create a report to help Hyper improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
-- [ ] I am on the [latest](https://github.com/zeit/hyper/releases/latest) Hyper.app version
-- [ ] I have searched the [issues](https://github.com/zeit/hyper/issues) of this repo and believe that this is not a duplicate
+- [ ] I am on the [latest](https://github.com/vercel/hyper/releases/latest) Hyper.app version
+- [ ] I have searched the [issues](https://github.com/vercel/hyper/issues) of this repo and believe that this is not a duplicate
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 00000000..07532e5e
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,67 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ canary ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ canary ]
+ schedule:
+ - cron: '37 6 * * 5'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'javascript' ]
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
+ # Learn more:
+ # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
+
+ # âšī¸ Command-line programs to run using the OS shell.
+ # đ https://git.io/JvXDl
+
+ # âī¸ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
new file mode 100644
index 00000000..40901325
--- /dev/null
+++ b/.github/workflows/nodejs.yml
@@ -0,0 +1,76 @@
+name: Node CI
+on:
+ push:
+ branches:
+ - master
+ - canary
+ pull_request:
+defaults:
+ run:
+ shell: bash
+jobs:
+ build:
+ runs-on: ${{matrix.os}}
+ strategy:
+ matrix:
+ node-version: [14.x]
+ os: [macos-11.0, ubuntu-latest, windows-latest]
+ fail-fast: false
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+ - name: Install
+ run: yarn install
+ - name: Test
+ run: yarn run test
+ - name: Getting Build Icon
+ if: github.ref == 'refs/heads/canary' || github.base_ref == 'canary'
+ run: |
+ cp build/canary.ico build/icon.ico
+ cp build/canary.icns build/icon.icns
+ - name: Build (pr)
+ if: github.event_name == 'pull_request'
+ run: yarn run dist --publish=never
+ - name: Build (push)
+ if: github.event_name == 'push'
+ run: yarn run dist
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ CSC_LINK: ${{ secrets.MAC_CERT_P12_BASE64 }}
+ CSC_KEY_PASSWORD: ${{ secrets.MAC_CERT_P12_PASSWORD }}
+ WIN_CSC_LINK: ${{ secrets.WIN_CERT_P12_BASE64 }}
+ WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CERT_P12_PASSWORD }}
+ - name: Test Spectron
+ if: runner.os != 'Linux'
+ run: yarn run test:spectron
+ - name: Archive Spectron test screenshot
+ if: runner.os != 'Linux'
+ uses: actions/upload-artifact@v2
+ with:
+ name: spectron
+ path: dist/tmp/*.png
+ - name: Archive Build Artifacts
+ uses: LabhanshAgrawal/upload-artifact@v3
+ with:
+ path: |
+ dist/*.dmg
+ dist/*.snap
+ dist/*.AppImage
+ dist/*.deb
+ dist/*.rpm
+ dist/*.exe
+ - name: Save the pr number in an artifact
+ if: github.event_name == 'pull_request'
+ env:
+ PR_NUM: ${{ github.event.number }}
+ run: echo $PR_NUM > pr_num.txt
+ - name: Upload the pr num
+ uses: actions/upload-artifact@v2
+ if: github.event_name == 'pull_request'
+ with:
+ name: pr_num
+ path: ./pr_num.txt
diff --git a/.github/workflows/spectron_comment.yml b/.github/workflows/spectron_comment.yml
new file mode 100644
index 00000000..d2f5ac4c
--- /dev/null
+++ b/.github/workflows/spectron_comment.yml
@@ -0,0 +1,56 @@
+name: Comment spectron screenshots on PR
+on:
+ workflow_run:
+ workflows: ['Node CI']
+ types:
+ - completed
+jobs:
+ spectron_comment:
+ runs-on: ubuntu-latest
+ if: github.event.workflow_run.event == 'pull_request'
+ steps:
+ - name: Dump Workflow run info from GitHub context
+ env:
+ WORKFLOW_RUN_INFO: ${{ toJSON(github.event.workflow_run) }}
+ run: echo "$WORKFLOW_RUN_INFO"
+ - name: Download Artifacts
+ uses: dawidd6/action-download-artifact@v2.11.0
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ workflow: nodejs.yml
+ run_id: ${{ github.event.workflow_run.id }}
+ name: spectron
+ - name: Get PR number
+ uses: dawidd6/action-download-artifact@v2.11.0
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ workflow: nodejs.yml
+ run_id: ${{ github.event.workflow_run.id }}
+ name: pr_num
+ - name: Read the pr_num file
+ id: pr_num_reader
+ uses: juliangruber/read-file-action@v1.0.0
+ with:
+ path: ./pr_num.txt
+ - name: List images
+ run: ls -al
+ - name: Upload images to imgur
+ id: upload_screenshots
+ uses: devicons/public-upload-to-imgur@v2.2.1
+ with:
+ path: ./*.png
+ client_id: ${{ secrets.IMGUR_CLIENT_ID }}
+ - name: Comment on the PR
+ uses: jungwinter/comment@v1
+ env:
+ IMG_MARKDOWN: ${{ join(fromJSON(steps.upload_screenshots.outputs.markdown_urls), '') }}
+ MESSAGE: |
+ Hi there,
+ Here are screenshots of Hyper built from this pr.
+ {0}
+ Thank you for contributing to Hyper!
+ with:
+ type: create
+ issue_number: ${{ steps.pr_num_reader.outputs.content }}
+ token: ${{ secrets.GITHUB_TOKEN }}
+ body: ${{ format(env.MESSAGE, env.IMG_MARKDOWN) }}
diff --git a/.gitignore b/.gitignore
index b5ec510d..ef95864f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
# build output
dist
app/renderer
+target
bin/cli.*
# dependencies
@@ -15,3 +16,6 @@ yarn-error.log
.hyper_plugins
.DS_Store
+.vscode/*
+!.vscode/launch.json
+.idea
diff --git a/.husky/.gitignore b/.husky/.gitignore
new file mode 100644
index 00000000..31354ec1
--- /dev/null
+++ b/.husky/.gitignore
@@ -0,0 +1 @@
+_
diff --git a/.husky/pre-push b/.husky/pre-push
new file mode 100755
index 00000000..f077c917
--- /dev/null
+++ b/.husky/pre-push
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+yarn test
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 9a4b1cae..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-sudo: required
-dist: trusty
-
-language: node_js
-
-matrix:
- include:
- - os: linux
- node_js: 10.2.0
- env: CC=clang CXX=clang++ npm_config_clang=1
- compiler: clang
-
-addons:
- apt:
- packages:
- - gcc-multilib
- - g++-multilib
- - libgnome-keyring-dev
- - icnsutils
- - graphicsmagick
- - xz-utils
- - rpm
- - bsdtar
- - snapd
-
-before_install:
- - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo snap install snapcraft --classic; fi
- - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start; sleep 3; fi
-
-cache: yarn
-
-install:
- - yarn
-
-after_success:
- - (git branch --contains $TRAVIS_COMMIT | grep canary > /dev/null || [[ "$TRAVIS_BRANCH" == "canary" ]] ) && (cd build; cp canary.icns icon.icns; cp canary.ico icon.ico)
- - yarn run dist
-
-branches:
- except:
- - "/^v\\d+\\.\\d+\\.\\d+$/"
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 9f50ef8f..747bb7b0 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -6,7 +6,7 @@
"request": "launch",
"name": "Launch Hyper",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
- "program": "${workspaceRoot}/app/index.js",
+ "program": "${workspaceRoot}/target/index.js",
"protocol": "inspector"
},
{
diff --git a/.yarnrc b/.yarnrc
index 3d567722..45291c13 100644
--- a/.yarnrc
+++ b/.yarnrc
@@ -1 +1 @@
-save-exact true
+registry "https://registry.npmjs.org/"
diff --git a/LICENSE b/LICENSE
index 89491ddb..fe231dc9 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
# MIT License
-Copyright (c) 2018 ZEIT, Inc.
+Copyright (c) 2018 Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/PLUGINS.md b/PLUGINS.md
index 3516119f..d266854d 100644
--- a/PLUGINS.md
+++ b/PLUGINS.md
@@ -3,11 +3,11 @@
## Workflow
### Run Hyper in dev mode
-Hyper can be run in dev mode by cloning this repository and following the ["Contributing" section of our README](https://github.com/zeit/hyper#contribute).
+Hyper can be run in dev mode by cloning this repository and following the ["Contributing" section of our README](https://github.com/vercel/hyper#contribute).
In dev mode you'll get more ouput and access to React/Redux dev-tools in Electron.
-Prerequisites and steps are described in the ["Contributing" section of our README](https://github.com/zeit/hyper#contribute).
+Prerequisites and steps are described in the ["Contributing" section of our README](https://github.com/vercel/hyper#contribute).
Be sure to use the `canary` branch.
### Create a dev config file
@@ -30,7 +30,7 @@ module.exports = {
```
### Running your plugin
-To load, your plugin should expose at least one API method. All possible methods are listed [here](https://github.com/zeit/hyper/blob/canary/app/plugins/extensions.js).
+To load, your plugin should expose at least one API method. All possible methods are listed [here](https://github.com/vercel/hyper/blob/canary/app/plugins/extensions.ts).
After launching Hyper in dev mode, run `yarn run app`, it should log that your plugin has been correcty loaded: `Plugin hyper-awesome-plugin (0.1.0) loaded.`. Name and version printed are the ones in your plugins `package.json` file.
@@ -41,7 +41,7 @@ Almost all available API methods can be found on https://hyper.is.
If there's any missing, let us know or submit a PR to document it!
### Components
-You can decorate almost all Hyper components with a Higher-Order Component (HOC). To understand their architecture, the easiest way is to use React dev-tools to dig in to their hierachy.
+You can decorate almost all Hyper components with a Higher-Order Component (HOC). To understand their architecture, the easiest way is to use React dev-tools to dig in to their hierarchy.
Multiple plugins can decorate the same Hyper component. Thus, `Component` passed as first argument to your decorator function could possibly not be an original Hyper component but a HOC of a previous plugin. If you need to retrieve a reference to a real Hyper component, you can pass down a `onDecorated` handler.
```js
@@ -70,7 +70,7 @@ exports.decorateTerms = (Terms, {React}) => {
//
+
+
+
+
-
- ${JSON.stringify(getConfig(), null, 2)}
-
- ${JSON.stringify(getPlugins(), null, 2)}
-
-
- >(p+=this.DB-k);
- }
- else {
- d = (this[i]>>(p-=k))&km;
- if(p <= 0) { p += this.DB; --i; }
- }
- if(d > 0) m = true;
- if(m) r += int2char(d);
- }
- }
- return m?r:"0";
- }
-
- // (public) -this
- function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
-
- // (public) |this|
- function bnAbs() { return (this.s<0)?this.negate():this; }
-
- // (public) return + if this > a, - if this < a, 0 if equal
- function bnCompareTo(a) {
- var r = this.s-a.s;
- if(r != 0) return r;
- var i = this.t;
- r = i-a.t;
- if(r != 0) return (this.s<0)?-r:r;
- while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
- return 0;
- }
-
- // returns bit length of the integer x
- function nbits(x) {
- var r = 1, t;
- if((t=x>>>16) != 0) { x = t; r += 16; }
- if((t=x>>8) != 0) { x = t; r += 8; }
- if((t=x>>4) != 0) { x = t; r += 4; }
- if((t=x>>2) != 0) { x = t; r += 2; }
- if((t=x>>1) != 0) { x = t; r += 1; }
- return r;
- }
-
- // (public) return the number of bits in "this"
- function bnBitLength() {
- if(this.t <= 0) return 0;
- return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
- }
-
- // (protected) r = this << n*DB
- function bnpDLShiftTo(n,r) {
- var i;
- for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
- for(i = n-1; i >= 0; --i) r[i] = 0;
- r.t = this.t+n;
- r.s = this.s;
- }
-
- // (protected) r = this >> n*DB
- function bnpDRShiftTo(n,r) {
- for(var i = n; i < this.t; ++i) r[i-n] = this[i];
- r.t = Math.max(this.t-n,0);
- r.s = this.s;
- }
-
- // (protected) r = this << n
- function bnpLShiftTo(n,r) {
- var bs = n%this.DB;
- var cbs = this.DB-bs;
- var bm = (1< >(p+=this.DB-8);
- }
- else {
- d = (this[i]>>(p-=8))&0xff;
- if(p <= 0) { p += this.DB; --i; }
- }
- if((d&0x80) != 0) d |= -256;
- if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
- if(k > 0 || d != this.s) r[k++] = d;
- }
- }
- return r;
- }
-
- function bnEquals(a) { return(this.compareTo(a)==0); }
- function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
- function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
-
- // (protected) r = this op a (bitwise)
- function bnpBitwiseTo(a,op,r) {
- var i, f, m = Math.min(a.t,this.t);
- for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
- if(a.t < this.t) {
- f = a.s&this.DM;
- for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
- r.t = this.t;
- }
- else {
- f = this.s&this.DM;
- for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
- r.t = a.t;
- }
- r.s = op(this.s,a.s);
- r.clamp();
- }
-
- // (public) this & a
- function op_and(x,y) { return x&y; }
- function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
-
- // (public) this | a
- function op_or(x,y) { return x|y; }
- function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
-
- // (public) this ^ a
- function op_xor(x,y) { return x^y; }
- function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
-
- // (public) this & ~a
- function op_andnot(x,y) { return x&~y; }
- function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
-
- // (public) ~this
- function bnNot() {
- var r = nbi();
- for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
- r.t = this.t;
- r.s = ~this.s;
- return r;
- }
-
- // (public) this << n
- function bnShiftLeft(n) {
- var r = nbi();
- if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
- return r;
- }
-
- // (public) this >> n
- function bnShiftRight(n) {
- var r = nbi();
- if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
- return r;
- }
-
- // return index of lowest 1-bit in x, x < 2^31
- function lbit(x) {
- if(x == 0) return -1;
- var r = 0;
- if((x&0xffff) == 0) { x >>= 16; r += 16; }
- if((x&0xff) == 0) { x >>= 8; r += 8; }
- if((x&0xf) == 0) { x >>= 4; r += 4; }
- if((x&3) == 0) { x >>= 2; r += 2; }
- if((x&1) == 0) ++r;
- return r;
- }
-
- // (public) returns index of lowest 1-bit (or -1 if none)
- function bnGetLowestSetBit() {
- for(var i = 0; i < this.t; ++i)
- if(this[i] != 0) return i*this.DB+lbit(this[i]);
- if(this.s < 0) return this.t*this.DB;
- return -1;
- }
-
- // return number of 1 bits in x
- function cbit(x) {
- var r = 0;
- while(x != 0) { x &= x-1; ++r; }
- return r;
- }
-
- // (public) return number of set bits
- function bnBitCount() {
- var r = 0, x = this.s&this.DM;
- for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
- return r;
- }
-
- // (public) true iff nth bit is set
- function bnTestBit(n) {
- var j = Math.floor(n/this.DB);
- if(j >= this.t) return(this.s!=0);
- return((this[j]&(1<<(n%this.DB)))!=0);
- }
-
- // (protected) this op (1<
- * This core code is extracted from Michele Bini's curve255.js implementation,
- * which is used as a base for Curve25519 ECDH and Ed25519 EdDSA operations.
- * >(p+=this.DB-k);
+ }
+ else {
+ d = (this[i]>>(p-=k))&km;
+ if(p <= 0) { p += this.DB; --i; }
+ }
+ if(d > 0) m = true;
+ if(m) r += int2char(d);
+ }
+ }
+ return m?r:"0";
+ }
+
+ // (public) -this
+ function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
+
+ // (public) |this|
+ function bnAbs() { return (this.s<0)?this.negate():this; }
+
+ // (public) return + if this > a, - if this < a, 0 if equal
+ function bnCompareTo(a) {
+ var r = this.s-a.s;
+ if(r != 0) return r;
+ var i = this.t;
+ r = i-a.t;
+ if(r != 0) return (this.s<0)?-r:r;
+ while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
+ return 0;
+ }
+
+ // returns bit length of the integer x
+ function nbits(x) {
+ var r = 1, t;
+ if((t=x>>>16) != 0) { x = t; r += 16; }
+ if((t=x>>8) != 0) { x = t; r += 8; }
+ if((t=x>>4) != 0) { x = t; r += 4; }
+ if((t=x>>2) != 0) { x = t; r += 2; }
+ if((t=x>>1) != 0) { x = t; r += 1; }
+ return r;
+ }
+
+ // (public) return the number of bits in "this"
+ function bnBitLength() {
+ if(this.t <= 0) return 0;
+ return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
+ }
+
+ // (protected) r = this << n*DB
+ function bnpDLShiftTo(n,r) {
+ var i;
+ for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
+ for(i = n-1; i >= 0; --i) r[i] = 0;
+ r.t = this.t+n;
+ r.s = this.s;
+ }
+
+ // (protected) r = this >> n*DB
+ function bnpDRShiftTo(n,r) {
+ for(var i = n; i < this.t; ++i) r[i-n] = this[i];
+ r.t = Math.max(this.t-n,0);
+ r.s = this.s;
+ }
+
+ // (protected) r = this << n
+ function bnpLShiftTo(n,r) {
+ var bs = n%this.DB;
+ var cbs = this.DB-bs;
+ var bm = (1< >(p+=this.DB-8);
+ }
+ else {
+ d = (this[i]>>(p-=8))&0xff;
+ if(p <= 0) { p += this.DB; --i; }
+ }
+ if((d&0x80) != 0) d |= -256;
+ if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
+ if(k > 0 || d != this.s) r[k++] = d;
+ }
+ }
+ return r;
+ }
+
+ function bnEquals(a) { return(this.compareTo(a)==0); }
+ function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
+ function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
+
+ // (protected) r = this op a (bitwise)
+ function bnpBitwiseTo(a,op,r) {
+ var i, f, m = Math.min(a.t,this.t);
+ for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
+ if(a.t < this.t) {
+ f = a.s&this.DM;
+ for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
+ r.t = this.t;
+ }
+ else {
+ f = this.s&this.DM;
+ for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
+ r.t = a.t;
+ }
+ r.s = op(this.s,a.s);
+ r.clamp();
+ }
+
+ // (public) this & a
+ function op_and(x,y) { return x&y; }
+ function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
+
+ // (public) this | a
+ function op_or(x,y) { return x|y; }
+ function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
+
+ // (public) this ^ a
+ function op_xor(x,y) { return x^y; }
+ function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
+
+ // (public) this & ~a
+ function op_andnot(x,y) { return x&~y; }
+ function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
+
+ // (public) ~this
+ function bnNot() {
+ var r = nbi();
+ for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
+ r.t = this.t;
+ r.s = ~this.s;
+ return r;
+ }
+
+ // (public) this << n
+ function bnShiftLeft(n) {
+ var r = nbi();
+ if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
+ return r;
+ }
+
+ // (public) this >> n
+ function bnShiftRight(n) {
+ var r = nbi();
+ if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
+ return r;
+ }
+
+ // return index of lowest 1-bit in x, x < 2^31
+ function lbit(x) {
+ if(x == 0) return -1;
+ var r = 0;
+ if((x&0xffff) == 0) { x >>= 16; r += 16; }
+ if((x&0xff) == 0) { x >>= 8; r += 8; }
+ if((x&0xf) == 0) { x >>= 4; r += 4; }
+ if((x&3) == 0) { x >>= 2; r += 2; }
+ if((x&1) == 0) ++r;
+ return r;
+ }
+
+ // (public) returns index of lowest 1-bit (or -1 if none)
+ function bnGetLowestSetBit() {
+ for(var i = 0; i < this.t; ++i)
+ if(this[i] != 0) return i*this.DB+lbit(this[i]);
+ if(this.s < 0) return this.t*this.DB;
+ return -1;
+ }
+
+ // return number of 1 bits in x
+ function cbit(x) {
+ var r = 0;
+ while(x != 0) { x &= x-1; ++r; }
+ return r;
+ }
+
+ // (public) return number of set bits
+ function bnBitCount() {
+ var r = 0, x = this.s&this.DM;
+ for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
+ return r;
+ }
+
+ // (public) true iff nth bit is set
+ function bnTestBit(n) {
+ var j = Math.floor(n/this.DB);
+ if(j >= this.t) return(this.s!=0);
+ return((this[j]&(1<<(n%this.DB)))!=0);
+ }
+
+ // (protected) this op (1<
- * This code is adapted from fast-djbec.js, a faster but more complicated
- * version of the Ed25519 encryption scheme (as compared to djbec.js).
- * It uses two different representations for big integers: The jsbn
- * BigInteger class, which can represent arbitrary-length numbers, and a
- * special fixed-length representation optimised for 256-bit integers.
- * The reason both are needed is that the Ed25519 algorithm requires some
- * 512-bit numbers. Note: Seeds should be a byte string, not a unicode string containing
- * multi-byte characters. Notes: Note: Unicode messages need to be converted to a byte representation
- * (e. g. UTF-8).
- *
- *
- * @function
- * @param message {string}
- * Message in the form of a byte string.
- * @param keySeed {string}
- * Private key seed in the form of a byte string.
- * @param publicKey {string}
- * Public key as byte string (if not present, it will be computed from
- * the private key seed).
- * @returns {string}
- * Detached message signature in the form of a byte string (64 bytes).
- */
- ns.sign = function(message, keySeed, publicKey) {
- if (publicKey === undefined) {
- publicKey = _publickey(keySeed);
- } else {
- publicKey = utils.string2bytes(publicKey);
- }
- var a = _bi(_get_a(keySeed).toString(), 16);
- var hs = _stringhash(keySeed);
- var r = _bytehash(hs.slice(32, 64) + message);
- var rp = _scalarmultBytes(_bp, r);
- var erp = _encodepoint(rp);
- r = _bi(r).mod(_bi(1, 10).shiftLeft(512));
- var s = _map(_chr, erp).join('') + _map(_chr, publicKey).join('') + message;
- s = _inthash_mod_l(s).multiply(a).add(r).mod(_L_BI);
- return utils.bytes2string(erp.concat(_encodeint(s)));
- };
-
-
- /**
- * Verifies an EdDSA signature of a message with the public key.
- *
- *