├── cloneDeep
├── .gitignore
├── README.md
├── test
│ ├── 5.test.js
│ ├── clone1.test.js
│ ├── 2.test.js
│ ├── 3.test.js
│ ├── 7.test.js
│ ├── 6.test.js
│ ├── clone3.test.js
│ ├── 4.test.js
│ ├── 1.test.js
│ ├── clone2.test.js
│ ├── clone4.test.js
│ └── 8.test.js
├── src
│ ├── clone1.js
│ ├── clone2.js
│ ├── clone3.js
│ └── clone4.js
├── package.json
└── package-lock.json
├── pnpm
├── 01-npm@2
│ ├── .gitignore
│ ├── node_modules
│ │ ├── demo-baz
│ │ │ ├── index.js
│ │ │ ├── node_modules
│ │ │ │ └── demo-bar
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── package.json
│ │ │ └── package.json
│ │ └── demo-foo
│ │ │ ├── index.js
│ │ │ ├── node_modules
│ │ │ └── demo-bar
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ └── package.json
│ ├── README.md
│ └── package.json
├── 02-yarn
│ ├── .gitignore
│ ├── node_modules
│ │ ├── demo-bar
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── demo-baz
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── demo-foo
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ └── .yarn-integrity
│ ├── README.md
│ └── package.json
├── 03-npm-doppelgangers
│ ├── .gitignore
│ ├── node_modules
│ │ ├── demo-bar
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── demo-baz
│ │ │ ├── index.js
│ │ │ ├── node_modules
│ │ │ │ └── demo-bar
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── package.json
│ │ │ └── package.json
│ │ ├── demo-foo
│ │ │ ├── index.js
│ │ │ ├── node_modules
│ │ │ │ └── demo-bar
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── package.json
│ │ │ └── package.json
│ │ └── .yarn-integrity
│ ├── README.md
│ └── package.json
├── 00-demos-packages
│ ├── demo-bar-1.0.0
│ │ ├── index.js
│ │ └── package.json
│ ├── demo-bar-1.0.1
│ │ ├── index.js
│ │ └── package.json
│ ├── demo-baz-1.0.0
│ │ ├── index.js
│ │ └── package.json
│ ├── demo-foo-1.0.0
│ │ ├── index.js
│ │ └── package.json
│ └── demo-foo-1.0.1
│ │ ├── index.js
│ │ └── package.json
└── 04-pnpm
│ ├── README.md
│ ├── package.json
│ └── pnpm-lock.yaml
├── gulp-demo
├── .gitignore
├── dist
│ ├── images
│ │ ├── 1.jpg
│ │ ├── 2.jpg
│ │ ├── 3.jpg
│ │ ├── 4.jpg
│ │ ├── 5.jpg
│ │ ├── 6.jpg
│ │ ├── 7.jpg
│ │ ├── 8.jpg
│ │ ├── 9.jpg
│ │ ├── 10.jpg
│ │ ├── 11.jpg
│ │ └── 12.jpg
│ ├── rev-manifest.json
│ ├── css
│ │ ├── public.css
│ │ └── public-5c001c53f6.css
│ └── index.html
├── src
│ ├── images
│ │ ├── 1.jpg
│ │ ├── 10.jpg
│ │ ├── 11.jpg
│ │ ├── 12.jpg
│ │ ├── 2.jpg
│ │ ├── 3.jpg
│ │ ├── 4.jpg
│ │ ├── 5.jpg
│ │ ├── 6.jpg
│ │ ├── 7.jpg
│ │ ├── 8.jpg
│ │ └── 9.jpg
│ ├── js
│ │ └── myAlbum.js
│ ├── css
│ │ └── myAlbum.css
│ ├── less
│ │ └── myAlbum.less
│ └── index.html
├── README.md
├── package.json
└── gulpfile.js
├── .gitignore
├── browserCache
├── README.md
├── src
│ ├── cacheControl.js
│ ├── expries.js
│ ├── pragma.js
│ ├── utils.js
│ ├── priority.js
│ ├── eTag.js
│ └── lastModified.js
├── package.json
├── index.js
└── static
│ └── index.html
├── lazyLoad
├── loading.jpg
├── README.md
└── index.html
├── amplifier
├── Images
│ ├── big.jpg
│ └── small.jpg
├── README.md
└── index.html
├── vueDataBind
├── README.md
├── index.html
└── Vue.js
├── promise
├── README.md
├── test
│ ├── promise3.test.js
│ ├── promise4.test.js
│ ├── promise1.test.js
│ ├── promise2.test.js
│ └── promise5.test.js
├── package.json
├── src
│ ├── promise1.js
│ ├── promise2.js
│ ├── promise3.js
│ ├── promise4.js
│ └── promise5.js
└── package-lock.json
├── typescript
├── README.md
├── package.json
├── tsconfig.json
├── 03-sample.ts
├── 04-sample.ts
├── 01-sample.ts
├── 02-sample.ts
└── yarn.lock
└── README.md
/cloneDeep/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/pnpm/01-npm@2/.gitignore:
--------------------------------------------------------------------------------
1 | !node_modules
--------------------------------------------------------------------------------
/pnpm/02-yarn/.gitignore:
--------------------------------------------------------------------------------
1 | !node_modules
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/.gitignore:
--------------------------------------------------------------------------------
1 | !node_modules
--------------------------------------------------------------------------------
/gulp-demo/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | package-lock.json
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | yarn-error.log
3 | npm-debug.log
--------------------------------------------------------------------------------
/pnpm/02-yarn/node_modules/demo-bar/index.js:
--------------------------------------------------------------------------------
1 |
2 | console.log('bar')
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-bar-1.0.0/index.js:
--------------------------------------------------------------------------------
1 |
2 | console.log('bar')
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-bar-1.0.1/index.js:
--------------------------------------------------------------------------------
1 |
2 | console.log('bar')
--------------------------------------------------------------------------------
/browserCache/README.md:
--------------------------------------------------------------------------------
1 | ## step
2 |
3 | - `npm install`
4 | - `npm start`
5 |
6 |
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-bar/index.js:
--------------------------------------------------------------------------------
1 |
2 | console.log('bar')
--------------------------------------------------------------------------------
/pnpm/01-npm@2/node_modules/demo-baz/index.js:
--------------------------------------------------------------------------------
1 | require('demo-bar')
2 | console.log('baz')
--------------------------------------------------------------------------------
/pnpm/02-yarn/node_modules/demo-baz/index.js:
--------------------------------------------------------------------------------
1 | require('demo-bar')
2 | console.log('baz')
--------------------------------------------------------------------------------
/lazyLoad/loading.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/lazyLoad/loading.jpg
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-baz-1.0.0/index.js:
--------------------------------------------------------------------------------
1 | require('demo-bar')
2 | console.log('baz')
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-foo-1.0.0/index.js:
--------------------------------------------------------------------------------
1 | require('example-bar')
2 | console.log('foo')
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-foo-1.0.1/index.js:
--------------------------------------------------------------------------------
1 | require('demo-bar')
2 | console.log('foo')
--------------------------------------------------------------------------------
/pnpm/01-npm@2/node_modules/demo-baz/node_modules/demo-bar/index.js:
--------------------------------------------------------------------------------
1 |
2 | console.log('bar')
--------------------------------------------------------------------------------
/pnpm/01-npm@2/node_modules/demo-foo/index.js:
--------------------------------------------------------------------------------
1 | require('example-bar')
2 | console.log('foo')
--------------------------------------------------------------------------------
/pnpm/01-npm@2/node_modules/demo-foo/node_modules/demo-bar/index.js:
--------------------------------------------------------------------------------
1 |
2 | console.log('bar')
--------------------------------------------------------------------------------
/pnpm/02-yarn/node_modules/demo-foo/index.js:
--------------------------------------------------------------------------------
1 | require('example-bar')
2 | console.log('foo')
--------------------------------------------------------------------------------
/amplifier/Images/big.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/amplifier/Images/big.jpg
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-baz/index.js:
--------------------------------------------------------------------------------
1 | require('demo-bar')
2 | console.log('baz')
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-baz/node_modules/demo-bar/index.js:
--------------------------------------------------------------------------------
1 |
2 | console.log('bar')
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-foo/index.js:
--------------------------------------------------------------------------------
1 | require('example-bar')
2 | console.log('foo')
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-foo/node_modules/demo-bar/index.js:
--------------------------------------------------------------------------------
1 |
2 | console.log('bar')
--------------------------------------------------------------------------------
/amplifier/Images/small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/amplifier/Images/small.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/1.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/2.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/3.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/4.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/5.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/6.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/7.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/8.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/9.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/1.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/10.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/11.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/12.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/2.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/3.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/4.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/5.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/6.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/7.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/8.jpg
--------------------------------------------------------------------------------
/gulp-demo/src/images/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/9.jpg
--------------------------------------------------------------------------------
/lazyLoad/README.md:
--------------------------------------------------------------------------------
1 | # lazyLoad
2 |
3 | - [image lazyload demo](https://lvqq.github.io/blog-samples/lazyLoad/)
--------------------------------------------------------------------------------
/gulp-demo/dist/images/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/10.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/11.jpg
--------------------------------------------------------------------------------
/gulp-demo/dist/images/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/12.jpg
--------------------------------------------------------------------------------
/vueDataBind/README.md:
--------------------------------------------------------------------------------
1 | # vueDataBind
2 |
3 | - [Vue bind demo](https://lvqq.github.io/blog-samples/vueDataBind/)
--------------------------------------------------------------------------------
/pnpm/01-npm@2/README.md:
--------------------------------------------------------------------------------
1 | # Steps
2 |
3 | 1. Use Nodejs 4.9.1, for example: `nvm use 4.9.1`
4 | 2. Run `npm install`
--------------------------------------------------------------------------------
/pnpm/04-pnpm/README.md:
--------------------------------------------------------------------------------
1 | # Steps
2 |
3 | 1. Install `pnpm`, run `npm install -g pnpm`
4 | 2. Run `pnpm install`
5 |
--------------------------------------------------------------------------------
/gulp-demo/dist/rev-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "public.css": "public-5c001c53f6.css",
3 | "public.js": "public-93c275a836.js"
4 | }
--------------------------------------------------------------------------------
/promise/README.md:
--------------------------------------------------------------------------------
1 | # promise
2 |
3 | - [how to implement a promise](https://www.chlorine.site/posts/2020/04/01/_06-promise.html)
4 |
--------------------------------------------------------------------------------
/cloneDeep/README.md:
--------------------------------------------------------------------------------
1 | # cloneDeep
2 |
3 | - [implement cloneDeep](https://www.nicksonlvqq.cn/blogs/posts/2019/09/16/_06-clonedeep.html)
4 |
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/README.md:
--------------------------------------------------------------------------------
1 | # Steps
2 |
3 | 1. Install `yarn`, run `npm install -g yarn`
4 | 2. Run `yarn --no-lockfile`
5 |
--------------------------------------------------------------------------------
/gulp-demo/README.md:
--------------------------------------------------------------------------------
1 | # gulp-demo
2 | - [implement font-end automation by using gulp](https://www.chlorine.site/posts/2018/11/22/_01-gulp.html)
--------------------------------------------------------------------------------
/cloneDeep/test/5.test.js:
--------------------------------------------------------------------------------
1 | // 循环引用,验证栈溢出
2 | const cloneDeep = require('../src/clone2')
3 |
4 | const a = {}
5 | a.a = a
6 |
7 | cloneDeep(a)
8 |
--------------------------------------------------------------------------------
/browserCache/src/cacheControl.js:
--------------------------------------------------------------------------------
1 | module.exports = (req, res) => {
2 | res.setHeader('Cache-Control', 'public,max-age=10')
3 | res.end('ok')
4 | }
5 |
--------------------------------------------------------------------------------
/pnpm/02-yarn/README.md:
--------------------------------------------------------------------------------
1 | # Steps
2 |
3 | Use `yarn` or `npm@3+`
4 |
5 | 1. Install `yarn`, run `npm install -g yarn`
6 | 2. Run `yarn install --no-lockfile`
7 |
--------------------------------------------------------------------------------
/browserCache/src/expries.js:
--------------------------------------------------------------------------------
1 | const { getGMT } = require('./utils')
2 |
3 | module.exports = (req, res) => {
4 | res.setHeader('Expires', getGMT(10));
5 | res.end('ok');
6 | }
7 |
--------------------------------------------------------------------------------
/amplifier/README.md:
--------------------------------------------------------------------------------
1 | # amplifier
2 |
3 | - [amplifier demo](https://lvqq.github.io/blog-samples/amplifier/)
4 | - [implement a amplifier](https://www.nicksonlvqq.cn/blogs/posts/2017/12/06/_01-amplifier.html)
--------------------------------------------------------------------------------
/pnpm/02-yarn/node_modules/demo-bar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-bar",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC"
11 | }
12 |
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-bar-1.0.0/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-bar",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC"
11 | }
12 |
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-bar-1.0.1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-bar",
3 | "version": "1.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC"
11 | }
12 |
--------------------------------------------------------------------------------
/cloneDeep/test/clone1.test.js:
--------------------------------------------------------------------------------
1 | // 简单深拷贝验证
2 | const cloneDeep = require('../src/clone1')
3 |
4 | const data = {
5 | str: 'test',
6 | obj: {
7 | foo: 'test'
8 | },
9 | arr: ['test', {foo: 'test'}]
10 | }
11 |
12 | const dataCopy = cloneDeep(data)
13 |
14 | console.log('dataCopy:\n', dataCopy)
15 |
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-bar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-bar",
3 | "version": "1.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC"
11 | }
12 |
--------------------------------------------------------------------------------
/cloneDeep/src/clone1.js:
--------------------------------------------------------------------------------
1 | // 简单深拷贝
2 | function cloneDeep(data) {
3 | if(!data || typeof data !== 'object') return data
4 | const retVal = Array.isArray(data) ? [] : {}
5 | for(let key in data) {
6 | retVal[key] = cloneDeep(data[key])
7 | }
8 | return retVal
9 | }
10 |
11 | module.exports = cloneDeep
12 |
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-baz/node_modules/demo-bar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-bar",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC"
11 | }
12 |
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-foo/node_modules/demo-bar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-bar",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC"
11 | }
12 |
--------------------------------------------------------------------------------
/cloneDeep/test/2.test.js:
--------------------------------------------------------------------------------
1 | // 验证 JSON.parse(JSON.stringify(data))
2 | // 当 data 的子数据为基本类型
3 | const data = {
4 | a: 1,
5 | b: 'str',
6 | c: true,
7 | d: null,
8 | e: undefined,
9 | f: NaN,
10 | g: Infinity,
11 | }
12 |
13 | const dataCopy = JSON.parse(JSON.stringify(data))
14 |
15 | console.log('dataCopy:\n', dataCopy)
16 |
--------------------------------------------------------------------------------
/typescript/README.md:
--------------------------------------------------------------------------------
1 | # TypeScript
2 | [TypeScript Summary](https://www.chlorine.site/posts/2022/08/22/_08-typescript.html)
3 |
4 | # Usage
5 |
6 | Enter `typescript` directory and install
7 | ```bash
8 | yarn
9 | ```
10 |
11 | Run `ts-node` scripts:
12 | ```bash
13 | yarn tsc1
14 |
15 | yarn tsc2
16 |
17 | yarn tsc3
18 |
19 | yarn tsc4
20 | ```
--------------------------------------------------------------------------------
/promise/test/promise3.test.js:
--------------------------------------------------------------------------------
1 | const MyPromise = require('../src/promise3')
2 |
3 | const promise = new MyPromise((resolve) => {
4 | setTimeout(() => {
5 | resolve(1)
6 | }, 100)
7 | })
8 |
9 | promise.then((value) => {
10 | console.log('value1', value);
11 | return 2
12 | })
13 | .then((value) => {
14 | console.log('value2', value);
15 | })
--------------------------------------------------------------------------------
/browserCache/src/pragma.js:
--------------------------------------------------------------------------------
1 | // pragma 请求头部
2 | exports.request = (req, res) => {
3 | res.setHeader('Cache-Control', 'public,max-age=1000')
4 | res.end('ok')
5 | }
6 |
7 | // pragma 响应头部
8 | exports.response = (req, res) => {
9 | res.setHeader('Pragma', 'no-cache')
10 | // res.setHeader('Cache-Control', 'public,max-age=1000')
11 | res.end('ok')
12 | }
--------------------------------------------------------------------------------
/pnpm/02-yarn/node_modules/demo-baz/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-baz",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-bar": "1.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/pnpm/02-yarn/node_modules/demo-foo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-foo",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-bar": "1.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/promise/test/promise4.test.js:
--------------------------------------------------------------------------------
1 | // 运行 npm run test4 进行测试
2 | const MyPromise = require('../src/promise4')
3 |
4 | MyPromise.defer = MyPromise.deferred = () => {
5 | let d = {}
6 | d.promise = new MyPromise((resolve, reject) => {
7 | d.resolve = resolve;
8 | d.reject = reject;
9 | });
10 | return d;
11 | }
12 |
13 | module.exports = MyPromise
14 |
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-baz-1.0.0/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-baz",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-bar": "1.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-foo-1.0.0/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-foo",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-bar": "1.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/pnpm/00-demos-packages/demo-foo-1.0.1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-foo",
3 | "version": "1.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-bar": "1.0.1"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/pnpm/01-npm@2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-baz": "1.0.0",
13 | "demo-foo": "1.0.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/pnpm/02-yarn/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-foo": "1.0.0",
13 | "demo-baz": "1.0.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/pnpm/04-pnpm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-foo": "1.0.1",
13 | "demo-baz": "1.0.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-baz/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-baz",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-bar": "1.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/demo-foo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-foo",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-bar": "1.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/cloneDeep/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clonedeep",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "jquery": "^3.4.1",
13 | "jsdom": "^15.1.1",
14 | "loadsh": "0.0.4"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/browserCache/src/utils.js:
--------------------------------------------------------------------------------
1 | const moment = require('moment');
2 | const crypto = require('crypto');
3 |
4 | // GMT 格式时间转化
5 | exports.getGMT = (second = 10) => `${moment().utc().add(second, 's').format('ddd, DD MMM YYYY HH:mm:ss')} GMT`;
6 |
7 | // 创建 md5 加密
8 | exports.cryptoFile = (file) => {
9 | const md5 = crypto.createHash('md5');
10 | return md5.update(file).digest('hex');
11 | }
12 |
--------------------------------------------------------------------------------
/cloneDeep/test/3.test.js:
--------------------------------------------------------------------------------
1 | // 验证 JSON.parse(JSON.stringify(data))
2 | // 当 data 的子数据为引用类型
3 | const data = {
4 | a: [1, 2, 3],
5 | b: {foo: 'obj'},
6 | c: new Date('2019-08-28'),
7 | d: /^abc$/g,
8 | e: function() {},
9 | f: new Set([1, 2, 3]),
10 | g: new Map([['foo', 'map']]),
11 | }
12 |
13 | const dataCopy = JSON.parse(JSON.stringify(data))
14 |
15 | console.log('dataCopy:\n', dataCopy)
16 |
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-foo": "1.0.0",
13 | "demo-baz": "1.0.0",
14 | "demo-bar": "1.0.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/cloneDeep/test/7.test.js:
--------------------------------------------------------------------------------
1 | // 验证层级过深递归栈溢出
2 | const cloneDeep = require('../src/clone3')
3 |
4 | function create(depth, breadth) {
5 | const data = {}
6 | let temp = data
7 | let i = j = 0
8 | while(i < depth) {
9 | temp = temp['data'] = {}
10 | while(j < breadth) {
11 | temp[j] = j
12 | j++
13 | }
14 | i++
15 | }
16 | return data
17 | }
18 |
19 | const data = create(10000, 100)
20 |
21 | console.log(cloneDeep(data))
--------------------------------------------------------------------------------
/typescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "typescript",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "tsc1": "ts-node 01-sample",
8 | "tsc2": "ts-node 02-sample",
9 | "tsc3": "ts-node 03-sample",
10 | "tsc4": "ts-node 04-sample"
11 | },
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "typescript": "^4.7.4",
16 | "ts-node": "^10.9.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/promise/test/promise1.test.js:
--------------------------------------------------------------------------------
1 | const MyPromise = require('../src/promise1')
2 |
3 | // 同步
4 | const promise1 = new MyPromise((resolve, reject) => {
5 | resolve(1)
6 | })
7 |
8 | promise1.then((value) => {
9 | console.log('value1', value)
10 | })
11 |
12 | // 异步
13 | const promise2 = new MyPromise((resolve, reject) => {
14 | setTimeout(() => {
15 | resolve(1)
16 | }, 2000)
17 | })
18 |
19 | promise2.then((value) => {
20 | console.log('value2', value)
21 | })
--------------------------------------------------------------------------------
/promise/test/promise2.test.js:
--------------------------------------------------------------------------------
1 | const MyPromise = require('../src/promise2')
2 |
3 | // 同步
4 | const promise1 = new MyPromise((resolve, reject) => {
5 | resolve(1)
6 | })
7 |
8 | promise1.then((value) => {
9 | console.log('value1', value)
10 | })
11 |
12 | // 异步
13 | const promise2 = new MyPromise((resolve, reject) => {
14 | setTimeout(() => {
15 | resolve(1)
16 | }, 2000)
17 | })
18 |
19 | promise2.then((value) => {
20 | console.log('value2', value)
21 | })
--------------------------------------------------------------------------------
/browserCache/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "browsercache",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "nodemon index.js",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1",
14 | "moment": "^2.24.0"
15 | },
16 | "devDependencies": {
17 | "nodemon": "^2.0.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/browserCache/src/priority.js:
--------------------------------------------------------------------------------
1 | // 优先级
2 | const { getGMT } = require('./utils')
3 |
4 | // Pragma > Cache-Control
5 | exports.priority1 = (req, res) => {
6 | res.setHeader('Pragma', 'no-cache');
7 | res.setHeader('Cache-Control', 'public,max-age=1000');
8 | res.end('ok');
9 | }
10 |
11 | // Cache-Control > Expries
12 | exports.priority2 = (req, res) => {
13 | res.setHeader('Cache-Control', 'no-cache');
14 | res.setHeader('Expries', getGMT(1000))
15 | res.end('ok');
16 | }
17 |
--------------------------------------------------------------------------------
/cloneDeep/test/6.test.js:
--------------------------------------------------------------------------------
1 | // 循环引用 验证解除引用
2 | const cloneDeep = require('../src/clone2')
3 |
4 | const temp = {}
5 | const data = {
6 | a: temp,
7 | b: temp,
8 | }
9 | const dataJson = JSON.parse(JSON.stringify(data))
10 | const dataClone = cloneDeep(data)
11 |
12 | // 验证对于其他数据的引用关系
13 | console.log('data.a === data.b: ', data.a === data.b)
14 | console.log('dataJson.a === dataJson.b: ', dataJson.a === dataJson.b)
15 | console.log('dataClone.a === dataClone.b: ', dataClone.a === dataClone.b)
--------------------------------------------------------------------------------
/promise/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "promise",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "scripts": {
10 | "test1": "node ./test/promise1.test.js",
11 | "test2": "node ./test/promise2.test.js",
12 | "test3": "node ./test/promise3.test.js",
13 | "test4": "promises-aplus-tests ./test/promise4.test.js",
14 | "test5": "node ./test/promise5.test.js"
15 | },
16 | "author": "",
17 | "license": "ISC",
18 | "devDependencies": {
19 | "promises-aplus-tests": "^2.1.2"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/browserCache/src/eTag.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const { cryptoFile } = require('./utils')
4 |
5 | const filePath = path.join(__dirname, '../static/index.html')
6 |
7 | module.exports = (req, res) => {
8 | const file = fs.readFileSync(filePath);
9 | const eTag = cryptoFile(file)
10 |
11 | res.setHeader('Cache-Control', 'public,max-age=10');
12 |
13 | if (eTag === req.headers['if-none-match']) {
14 | res.writeHead(304, 'Not Modified');
15 | res.end();
16 | } else {
17 | res.setHeader('ETag', eTag);
18 | res.writeHead(200, 'OK');
19 | res.end(file);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/browserCache/src/lastModified.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const filePath = path.join(__dirname, '../static/index.html')
5 |
6 | module.exports = (req, res) => {
7 | const stat = fs.statSync(filePath);
8 | const file = fs.readFileSync(filePath);
9 | const lastModified = stat.mtime.toUTCString();
10 |
11 | res.setHeader('Cache-Control', 'public,max-age=10');
12 |
13 | if (lastModified === req.headers['if-modified-since']) {
14 | res.writeHead(304, 'Not Modified');
15 | res.end();
16 | } else {
17 | res.setHeader('Last-Modified', lastModified);
18 | res.writeHead(200, 'OK');
19 | res.end(file);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/cloneDeep/test/clone3.test.js:
--------------------------------------------------------------------------------
1 | // 验证循环引用
2 | const cloneDeep = require('../src/clone3')
3 |
4 | const temp = {}
5 | const data = {
6 | a: temp,
7 | b: temp,
8 | }
9 | const dataClone = cloneDeep(data)
10 |
11 | const obj = {}
12 | obj.obj = obj
13 |
14 | const arr = []
15 | arr[0] = arr
16 |
17 | const set = new Set()
18 | set.add(set)
19 |
20 | const map = new Map()
21 | map.set(map, map)
22 |
23 | // 验证引用关系
24 | console.log('dataClone.a === dataClone.b: ', dataClone.a === dataClone.b) // true
25 |
26 | // 验证环
27 | console.log('obj:\n', cloneDeep(obj))
28 | console.log('arr:\n', cloneDeep(arr))
29 | console.log('set:\n', cloneDeep(set))
30 | console.log('map:\n', cloneDeep(map))
31 |
--------------------------------------------------------------------------------
/cloneDeep/test/4.test.js:
--------------------------------------------------------------------------------
1 | // 验证 JSON.parse(JSON.stringify(data))
2 | // 当 data 为自定义构造函数的实例对象
3 |
4 | function Person(name) {
5 | // 构造函数实例属性name
6 | this.name = name
7 | // 构造函数实例方法getName
8 | this.getName = function () {
9 | return this.name
10 | }
11 | }
12 | // 构造函数原型属性age
13 | Person.prototype.age = 18
14 |
15 | const person = new Person('xxx')
16 | const personCopy = JSON.parse(JSON.stringify(person))
17 |
18 | console.log('person: ', person)
19 | console.log('personCopy: ', personCopy)
20 | console.log('person.age: ', person.age)
21 | console.log('personCopy.age: ', personCopy.age)
22 | console.log('person.constructor:\n', person.constructor)
23 | console.log('personCopy.constructor:\n', personCopy.constructor)
24 |
--------------------------------------------------------------------------------
/cloneDeep/test/1.test.js:
--------------------------------------------------------------------------------
1 | // 验证原生浅拷贝方法
2 | const arr = ['test', { foo: 'test' }]
3 |
4 | const obj = {
5 | str: 'test',
6 | obj: {
7 | foo: 'test'
8 | }
9 | }
10 |
11 | const arr1 = arr.slice()
12 | const arr2 = arr.concat()
13 | const arr3 = Array.from(arr)
14 | const arr4 = [...arr]
15 |
16 | const obj1 = Object.assign({}, obj)
17 | const obj2 = {...obj}
18 |
19 | //修改arr
20 | arr[0] = 'test1'
21 | arr[1].foo = 'test1'
22 | // 修改obj
23 | obj.str = 'test1'
24 | obj.obj.foo = 'test1'
25 |
26 | //验证引用关系
27 | console.log('arr: ', arr)
28 | console.log('arr1: ', arr1)
29 | console.log('arr2: ', arr2)
30 | console.log('arr3: ', arr3)
31 | console.log('arr4: ', arr4)
32 | console.log('obj: ', obj)
33 | console.log('obj1: ', obj1)
34 | console.log('obj2: ', obj2)
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Samples
2 | - [Pnpm](https://github.com/lvqq/blog-samples/tree/master/pnpm)
3 | - [TypeScript](https://github.com/lvqq/blog-samples/tree/master/typescript)
4 | - [Vue data-bind](https://github.com/lvqq/blog-samples/tree/master/vueDataBind)
5 | - [Promise](https://github.com/lvqq/blog-samples/tree/master/promise)
6 | - [Browser cache](https://github.com/lvqq/blog-samples/tree/master/browserCache)
7 | - [CloneDeep](https://github.com/lvqq/blog-samples/tree/master/cloneDeep)
8 | - [Gulp](https://github.com/lvqq/blog-samples/tree/master/gulp-demo)
9 | - [Lazyload](https://github.com/lvqq/blog-samples/tree/master/lazyLoad)
10 | - [Amplifier](https://github.com/lvqq/blog-samples/tree/master/amplifier)
11 |
12 | ## Blog Repository
13 | - [Blogs](https://github.com/lvqq/blog)
14 |
--------------------------------------------------------------------------------
/pnpm/02-yarn/node_modules/.yarn-integrity:
--------------------------------------------------------------------------------
1 | {
2 | "systemParams": "win32-x64-83",
3 | "modulesFolders": [
4 | "node_modules"
5 | ],
6 | "flags": [],
7 | "linkedModules": [
8 | "@oyo\\aries",
9 | "aries",
10 | "yarn"
11 | ],
12 | "topLevelPatterns": [
13 | "demo-baz@1.0.0",
14 | "demo-foo@1.0.0"
15 | ],
16 | "lockfileEntries": {
17 | "demo-bar@1.0.0": "https://registry.yarnpkg.com/demo-bar/-/demo-bar-1.0.0.tgz#842e7e2c482ade053a886a38b8bebd9d47356c7b",
18 | "demo-baz@1.0.0": "https://registry.yarnpkg.com/demo-baz/-/demo-baz-1.0.0.tgz#0ce32889e87a71064481fa3504274fee5b46983c",
19 | "demo-foo@1.0.0": "https://registry.yarnpkg.com/demo-foo/-/demo-foo-1.0.0.tgz#53a114df5a7cdd0137fb68b01f0a6f0882d0c6b3"
20 | },
21 | "files": [],
22 | "artifacts": {}
23 | }
--------------------------------------------------------------------------------
/vueDataBind/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 双向绑定demo
7 |
8 |
9 |
10 | 姓名:{{ name }}
11 |
请输入姓名
12 | 年龄 {{ age }}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
32 |
33 |
--------------------------------------------------------------------------------
/gulp-demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gulp-demo",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1",
7 | "build": "gulp clean && gulp revision && gulp build && echo \"Sever Build Success ...\""
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "gulp": "^3.9.1",
13 | "gulp-clean": "^0.4.0",
14 | "gulp-concat": "^2.6.1",
15 | "gulp-connect": "^5.6.1",
16 | "gulp-csso": "^3.0.1",
17 | "gulp-if": "^2.0.2",
18 | "gulp-imagemin": "^5.0.3",
19 | "gulp-jshint": "^2.1.0",
20 | "gulp-less": "^4.0.1",
21 | "gulp-rev": "^9.0.0",
22 | "gulp-rev-replace": "^0.4.4",
23 | "gulp-uglify": "^3.0.1",
24 | "gulp-useref": "^3.1.6",
25 | "jshint": "^2.9.6"
26 | },
27 | "dependencies": {},
28 | "description": ""
29 | }
30 |
--------------------------------------------------------------------------------
/browserCache/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const express = require('express');
4 | const pragma = require('./src/pragma');
5 | const priority = require('./src/priority');
6 |
7 | const app = express();
8 | const port = 2200;
9 |
10 | app.get('/', (req, res) => res.end(fs.readFileSync(path.join(__dirname, './static/index.html'))));
11 |
12 | app.get('/expries', require('./src/expries'));
13 | app.get('/cacheControl', require('./src/cacheControl'));
14 | app.get('/lastModified', require('./src/lastModified'));
15 | app.get('/eTag', require('./src/eTag'));
16 |
17 | app.get('/pragmaRequest', pragma.request);
18 | app.get('/pragmaResponse', pragma.response);
19 |
20 | app.get('/priority1', priority.priority1)
21 | app.get('/priority2', priority.priority2)
22 |
23 | app.listen(port, () => {
24 | console.log(`server running on port ${port}!`);
25 | })
26 |
--------------------------------------------------------------------------------
/pnpm/03-npm-doppelgangers/node_modules/.yarn-integrity:
--------------------------------------------------------------------------------
1 | {
2 | "systemParams": "win32-x64-83",
3 | "modulesFolders": [
4 | "node_modules"
5 | ],
6 | "flags": [],
7 | "linkedModules": [
8 | "@oyo\\aries",
9 | "aries",
10 | "yarn"
11 | ],
12 | "topLevelPatterns": [
13 | "demo-bar@1.0.1",
14 | "demo-baz@1.0.0",
15 | "demo-foo@1.0.0"
16 | ],
17 | "lockfileEntries": {
18 | "demo-bar@1.0.0": "https://registry.yarnpkg.com/demo-bar/-/demo-bar-1.0.0.tgz#842e7e2c482ade053a886a38b8bebd9d47356c7b",
19 | "demo-bar@1.0.1": "https://registry.yarnpkg.com/demo-bar/-/demo-bar-1.0.1.tgz#d52167539f54d515f1830b0313669cbcbac1f66a",
20 | "demo-baz@1.0.0": "https://registry.yarnpkg.com/demo-baz/-/demo-baz-1.0.0.tgz#0ce32889e87a71064481fa3504274fee5b46983c",
21 | "demo-foo@1.0.0": "https://registry.yarnpkg.com/demo-foo/-/demo-foo-1.0.0.tgz#53a114df5a7cdd0137fb68b01f0a6f0882d0c6b3"
22 | },
23 | "files": [],
24 | "artifacts": {}
25 | }
--------------------------------------------------------------------------------
/pnpm/04-pnpm/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: 5.4
2 |
3 | specifiers:
4 | demo-baz: 1.0.0
5 | demo-foo: 1.0.1
6 |
7 | dependencies:
8 | demo-baz: 1.0.0
9 | demo-foo: 1.0.1
10 |
11 | packages:
12 |
13 | /demo-bar/1.0.0:
14 | resolution: {integrity: sha512-M32T7z7T8L6+YNWtLhWi2Cul7K6U5yAziWME2fhPHX36XWFUdVyCy6PJD3XdFBKy0cacfWSfEJTWmBkB5f4iEw==}
15 | dev: false
16 |
17 | /demo-bar/1.0.1:
18 | resolution: {integrity: sha512-lz5T/6ZnugMaiiG60H0vDuCcPtIu7HNF4Q9MQHXoqYRno0NSgR7MLRrGtNwFZ584XKix/pV+a0nWBOE8LdAajQ==}
19 | dev: false
20 |
21 | /demo-baz/1.0.0:
22 | resolution: {integrity: sha512-Q5WJf+3qk2kZ+wV8Y+EiJNqN9uATjfSR29Ml7HUMLFSoGP/OeG8MYe3lvlEmidmE5GKBAszzCW5wUVJU3t5RQg==}
23 | dependencies:
24 | demo-bar: 1.0.0
25 | dev: false
26 |
27 | /demo-foo/1.0.1:
28 | resolution: {integrity: sha512-fnUHFEsantdtmml6hBlskQ156CVbe2XXPMT9ec80E2ja597yxcK25Z53qb4pfGGLoLzWWr9MRT/6WG2IfGjS6g==}
29 | dependencies:
30 | demo-bar: 1.0.1
31 | dev: false
32 |
--------------------------------------------------------------------------------
/cloneDeep/test/clone2.test.js:
--------------------------------------------------------------------------------
1 | // 验证其他数据类型处理
2 | const cloneDeep = require('../src/clone2')
3 |
4 | const data = {
5 | obj: {},
6 | arr: [],
7 | reg: /reg/g,
8 | date: new Date('2019'),
9 | person: new Person('xxx'),
10 | set: new Set([{foo: 'set'}]),
11 | map: new Map([[{key: 'map'}, {value: 'map'}]])
12 | }
13 |
14 | function Person(name) {
15 | this.name = name
16 | }
17 |
18 | const dataClone = cloneDeep(data)
19 |
20 | console.log('dataClone:\n', dataClone)
21 |
22 | // 比较引用地址
23 | console.log(data.obj === dataClone.obj) // false
24 | console.log(data.arr === dataClone.arr) // false
25 | console.log(data.reg === dataClone.reg) // false
26 | console.log(data.date === dataClone.date) // false
27 | console.log(data.func === dataClone.func) // true
28 | console.log([...data.set][0] === [...dataClone.set][0]) // false
29 | console.log([...data.map.keys()][0] === [...dataClone.map.keys()][0]) // false
30 | console.log([...data.map.values()][0] === [...dataClone.map.values()][0]) // false
31 |
--------------------------------------------------------------------------------
/promise/src/promise1.js:
--------------------------------------------------------------------------------
1 | // 基本实现
2 |
3 | const STATE = {
4 | PENDING: 'pending',
5 | FULFILLED: 'fulfilled',
6 | REJECTED: 'rejected'
7 | }
8 |
9 | class MyPromise {
10 | constructor(fn) {
11 | // 初始化
12 | this.state = STATE.PENDING
13 | this.value = null
14 | this.reason = null
15 |
16 | // 成功
17 | const fulfill = (value) => {
18 | // 只有 state 为 pending 时,才可以更改状态
19 | if (this.state === STATE.PENDING) {
20 | this.state = STATE.FULFILLED
21 | this.value = value
22 | }
23 | }
24 |
25 | // 失败
26 | const reject = (reason) => {
27 | if (this.state === STATE.PENDING) {
28 | this.state = STATE.REJECTED
29 | this.reason = reason
30 | }
31 | }
32 | // 执行函数出错时调用 reject
33 | try {
34 | fn(fulfill, reject)
35 | } catch (e) {
36 | reject(e)
37 | }
38 | }
39 |
40 | then(onFulfilled, onRejected) {
41 | if (this.state === STATE.FULFILLED) {
42 | onFulfilled(this.value)
43 | }
44 | if (this.state === STATE.REJECTED) {
45 | onRejected(this.reason)
46 | }
47 | }
48 | }
49 |
50 | module.exports = MyPromise
--------------------------------------------------------------------------------
/promise/src/promise2.js:
--------------------------------------------------------------------------------
1 | // 解决异步
2 |
3 | const STATE = {
4 | PENDING: 'pending',
5 | FULFILLED: 'fulfilled',
6 | REJECTED: 'rejected'
7 | }
8 |
9 | class MyPromise {
10 | constructor(fn) {
11 | // 初始化
12 | this.state = STATE.PENDING
13 | this.value = null
14 | this.reason = null
15 | // 保存数组
16 | this.fulfilledCallbacks = []
17 | this.rejectedCallbacks = []
18 | // 成功
19 | const fulfill = (value) => {
20 | // 只有 state 为 pending 时,才可以更改状态
21 | if (this.state === STATE.PENDING) {
22 | this.state = STATE.FULFILLED
23 | this.value = value
24 | this.fulfilledCallbacks.forEach(cb => cb())
25 | }
26 | }
27 |
28 | // 失败
29 | const reject = (reason) => {
30 | if (this.state === STATE.PENDING) {
31 | this.state = STATE.REJECTED
32 | this.reason = reason
33 | this.rejectedCallbacks.forEach(cb => cb())
34 | }
35 | }
36 | // 执行函数出错时调用 reject
37 | try {
38 | fn(fulfill, reject)
39 | } catch (e) {
40 | reject(e)
41 | }
42 | }
43 |
44 | then(onFulfilled, onRejected) {
45 | if (this.state === STATE.FULFILLED) {
46 | onFulfilled(this.value)
47 | }
48 | if (this.state === STATE.REJECTED) {
49 | onRejected(this.reason)
50 | }
51 | // 当 then 是 pending 时,将这两个状态写入数组中
52 | if (this.state === STATE.PENDING) {
53 | this.fulfilledCallbacks.push(() => {
54 | onFulfilled(this.value)
55 | })
56 | this.rejectedCallbacks.push(() => {
57 | onRejected(this.reason)
58 | })
59 | }
60 | }
61 | }
62 |
63 | module.exports = MyPromise
--------------------------------------------------------------------------------
/cloneDeep/test/clone4.test.js:
--------------------------------------------------------------------------------
1 | // 验证非递归深拷贝
2 |
3 | const cloneDeep = require('../src/clone4')
4 |
5 | const symbol = Symbol('sym')
6 |
7 | const data = {
8 | obj: {},
9 | arr: [],
10 | reg: /reg/g,
11 | date: new Date('2019'),
12 | person: new Person('xxx'),
13 | [symbol]: 'symbol',
14 | set: new Set([{foo: 'set'}]),
15 | map: new Map([[{key: 'map'}, {value: 'map'}]])
16 | }
17 |
18 | function Person(name) {
19 | this.name = name
20 | }
21 |
22 | const dataClone = cloneDeep(data)
23 |
24 | console.log('dataClone:\n', dataClone)
25 |
26 | // 验证引用关系
27 | console.log(data.obj === dataClone.obj) // false
28 | console.log(data.arr === dataClone.arr) // false
29 | console.log(data.reg === dataClone.reg) // false
30 | console.log(data.date === dataClone.date) // false
31 | console.log(data.func === dataClone.func) // true
32 | console.log([...data.set][0] === [...dataClone.set][0]) // false
33 | console.log([...data.map.keys()][0] === [...dataClone.map.keys()][0]) // false
34 | console.log([...data.map.values()][0] === [...dataClone.map.values()][0]) // false
35 |
36 | const temp = {}
37 | const data1 = {
38 | a: temp,
39 | b: temp,
40 | }
41 | const dataClone1 = cloneDeep(data1)
42 |
43 | const obj = {}
44 | obj.obj = obj
45 |
46 | const arr = []
47 | arr[0] = arr
48 |
49 | const set = new Set()
50 | set.add(set)
51 |
52 | const map = new Map()
53 | map.set(map, map)
54 |
55 | // 验证引用关系
56 | console.log('dataClone1.a === dataClone1.b: ', dataClone1.a === dataClone1.b) // true
57 |
58 | // 验证循环引用
59 | console.log('obj:\n', cloneDeep(obj))
60 | console.log('arr:\n', cloneDeep(arr))
61 | console.log('set:\n', cloneDeep(set))
62 | console.log('map:\n', cloneDeep(map))
--------------------------------------------------------------------------------
/cloneDeep/src/clone2.js:
--------------------------------------------------------------------------------
1 | // 处理其他数据类型
2 |
3 | const TYPE = {
4 | Object: 'Object',
5 | Array: 'Array',
6 | Date: 'Date',
7 | RegExp: 'RegExp',
8 | Set: 'Set',
9 | Map: 'Map',
10 | }
11 |
12 | // 获取数据类型
13 | const getType = (data) => Object.prototype.toString.call(data).slice(8, -1)
14 |
15 | // 深拷贝
16 | const cloneDeep = (data) => {
17 | if (!data || typeof data !== 'object') return data
18 | let cloneData = data
19 | const Constructor = data.constructor;
20 | const dataType = getType(data)
21 | // data 初始化
22 | if (dataType === TYPE.Array) {
23 | cloneData = []
24 | } else if (dataType === TYPE.Object) {
25 | // 获取原对象的原型
26 | cloneData = Object.create(Object.getPrototypeOf(data))
27 | } else if (dataType === TYPE.Date) {
28 | cloneData = new Constructor(data.getTime())
29 | } else if (dataType === TYPE.RegExp) {
30 | const reFlags = /\w*$/
31 | // 特殊处理regexp,拷贝过程中lastIndex属性会丢失
32 | cloneData = new Constructor(data.source, reFlags.exec(data))
33 | cloneData.lastIndex = data.lastIndex
34 | } else if (dataType === TYPE.Set || dataType === TYPE.Map) {
35 | cloneData = new Constructor()
36 | }
37 |
38 | // 遍历 data
39 | if (dataType === TYPE.Set) {
40 | for (let value of data) {
41 | cloneData.add(cloneDeep(value))
42 | }
43 | } else if (dataType === TYPE.Map) {
44 | for (let [mapKey, mapValue] of data) {
45 | // Map的键、值都可以是引用类型,因此都需要拷贝
46 | cloneData.set(cloneDeep(mapKey), cloneDeep(mapValue))
47 | }
48 | } else {
49 | for (let key in data) {
50 | // 不考虑继承的属性
51 | if (data.hasOwnProperty(key)) {
52 | cloneData[key] = cloneDeep(data[key])
53 | }
54 | }
55 | }
56 | return cloneData
57 | }
58 |
59 | module.exports = cloneDeep
60 |
--------------------------------------------------------------------------------
/vueDataBind/Vue.js:
--------------------------------------------------------------------------------
1 | class Vue extends EventTarget{
2 | constructor(options) {
3 | super();
4 | this.options = options;
5 | this._data = this.options.data;
6 | this.el = document.getElementById(this.options.el);
7 | this.render(this.el);
8 | this.observe(this._data);
9 | }
10 |
11 | observe(data) {
12 | const _this = this
13 | this._data = new Proxy(data, {
14 | set: (target, name, value) => {
15 | // 定义自定义事件,传递数据更新后的值
16 | const event = new CustomEvent(name, {
17 | detail: value,
18 | });
19 | // 发布事件
20 | _this.dispatchEvent(event);
21 | return Reflect.set(...arguments);
22 | }
23 | })
24 | }
25 |
26 | render(el) {
27 | let childs = el.childNodes;
28 | [...childs].forEach(node => {
29 | // 文本节点
30 | if (node.nodeType === 3) {
31 | const text = node.textContent;
32 | const reg = /\{\{\s*([^\s\{\}]+)\s*\}\}/g;
33 | // 匹配 {{ name }}
34 | if (reg.test(text)) {
35 | const $1 = RegExp.$1;
36 | if (this._data[$1]) {
37 | node.textContent = text.replace(reg, this._data[$1])
38 | // 监听自定义事件
39 | this.addEventListener($1, e => {
40 | node.textContent = text.replace(reg, e.detail)
41 | })
42 | }
43 | }
44 | } else if(node.nodeType === 1) {
45 | // dom 节点
46 | const attrs = node.attributes;
47 | if (attrs.hasOwnProperty('v-model')) {
48 | const key = attrs['v-model'].nodeValue;
49 | node.value = this._data[key];
50 | // 监听输入框输入,更新数据
51 | node.addEventListener('input', e => {
52 | this._data[key] = node.value
53 | })
54 | }
55 | this.render(node);
56 | }
57 | })
58 | }
59 | }
--------------------------------------------------------------------------------
/cloneDeep/test/8.test.js:
--------------------------------------------------------------------------------
1 | // 比较不同深拷贝方法耗时
2 | const { JSDOM } = require('jsdom')
3 | const { window } = new JSDOM(``)
4 | const $ = require('jquery')(window)
5 | const _ = require('loadsh')
6 | const cloneDeep = require('../src/clone3')
7 |
8 | // 创建深度为depth,广度为breadth的数组
9 | function create(depth, breadth) {
10 | const data = {}
11 | let temp = data
12 | let i = j = 0
13 | while(i < depth) {
14 | temp = temp['data'] = {}
15 | while(j < breadth) {
16 | temp[j] = j
17 | j++
18 | }
19 | i++
20 | }
21 | return data
22 | }
23 |
24 | const data = create(1000, 1000)
25 | const counts = 10000 // 循环次数
26 | let i
27 |
28 | // JSON
29 | i = 0
30 | const jsonStart = new Date().getTime()
31 | while(i < counts) {
32 | JSON.parse(JSON.stringify(data))
33 | i++
34 | }
35 | const jsonEnd = new Date().getTime()
36 | console.log('Running JSON 10000 times cost:')
37 | console.log(`${jsonEnd - jsonStart} ms`)
38 |
39 |
40 | // $.extend
41 | i = 0
42 | const extendStart = new Date().getTime()
43 | while(i < counts) {
44 | $.extend(true, {}, data)
45 | i++
46 | }
47 | const extendEnd = new Date().getTime()
48 | console.log('Running $.extend 10000 times cost:')
49 | console.log(`${extendEnd - extendStart} ms`)
50 |
51 | // cloneDeep
52 | i = 0
53 | const cloneStart = new Date().getTime()
54 | while(i < counts) {
55 | cloneDeep(data)
56 | i++
57 | }
58 | const cloneEnd = new Date().getTime()
59 | console.log('Running cloneDeep 10000 times cost:')
60 | console.log(`${cloneEnd - cloneStart} ms`)
61 |
62 |
63 | // _.cloneDeep
64 | i = 0
65 | const _cloneStart = new Date().getTime()
66 | while(i < counts) {
67 | _.cloneDeep(data)
68 | i++
69 | }
70 | const _cloneEnd = new Date().getTime()
71 | console.log('Running cloneDeep 10000 times cost:')
72 | console.log(`${_cloneEnd - _cloneStart} ms`)
--------------------------------------------------------------------------------
/promise/src/promise3.js:
--------------------------------------------------------------------------------
1 | // 实现了链式调用、传递返回值
2 |
3 | const STATE = {
4 | PENDING: 'pending',
5 | FULFILLED: 'fulfilled',
6 | REJECTED: 'rejected'
7 | }
8 |
9 | class MyPromise {
10 | constructor(fn) {
11 | // 初始化
12 | this.state = STATE.PENDING
13 | this.value = null
14 | this.reason = null
15 | // 保存数组
16 | this.fulfilledCallbacks = []
17 | this.rejectedCallbacks = []
18 | // 成功
19 | const fulfill = (value) => {
20 | // 只有 state 为 pending 时,才可以更改状态
21 | if (this.state === STATE.PENDING) {
22 | this.state = STATE.FULFILLED
23 | this.value = value
24 | this.fulfilledCallbacks.forEach(cb => cb())
25 | }
26 | }
27 |
28 | // 失败
29 | const reject = (reason) => {
30 | if (this.state === STATE.PENDING) {
31 | this.state = STATE.REJECTED
32 | this.reason = reason
33 | this.rejectedCallbacks.forEach(cb => cb())
34 | }
35 | }
36 | // 执行函数出错时调用 reject
37 | try {
38 | fn(fulfill, reject)
39 | } catch (e) {
40 | reject(e)
41 | }
42 | }
43 |
44 | then(onFulfilled, onRejected) {
45 | return new MyPromise((fulfill, reject) => {
46 | if (this.state === STATE.FULFILLED) {
47 | // 将返回值传入下一个 fulfill 中
48 | fulfill(onFulfilled(this.value))
49 | }
50 | if (this.state === STATE.REJECTED) {
51 | // 将返回值传入下一个 reject 中
52 | reject(onRejected(this.reason))
53 | }
54 | // 当 then 是 pending 时,将这两个状态写入数组中
55 | if (this.state === STATE.PENDING) {
56 | this.fulfilledCallbacks.push(() => {
57 | fulfill(onFulfilled(this.value))
58 | })
59 | this.rejectedCallbacks.push(() => {
60 | reject(onRejected(this.reason))
61 | })
62 | }
63 | })
64 | }
65 | }
66 |
67 | module.exports = MyPromise
68 |
--------------------------------------------------------------------------------
/cloneDeep/src/clone3.js:
--------------------------------------------------------------------------------
1 | // 处理循环引用
2 |
3 | const TYPE = {
4 | Object: 'Object',
5 | Array: 'Array',
6 | Date: 'Date',
7 | RegExp: 'RegExp',
8 | Set: 'Set',
9 | Map: 'Map',
10 | }
11 |
12 | // 获取数据类型
13 | const getType = (data) => Object.prototype.toString.call(data).slice(8, -1)
14 |
15 | // 深拷贝
16 | const cloneDeep = (data, hash = new WeakMap()) => {
17 | if (!data || typeof data !== 'object') return data
18 | // 查询是否已拷贝
19 | if(hash.has(data)) return hash.get(data)
20 | let cloneData = data
21 | const Constructor = data.constructor;
22 | const dataType = getType(data)
23 | // data 初始化
24 | if (dataType === TYPE.Array) {
25 | cloneData = []
26 | } else if (dataType === TYPE.Object) {
27 | // 获取原对象的原型
28 | cloneData = Object.create(Object.getPrototypeOf(data))
29 | } else if (dataType === TYPE.Date) {
30 | cloneData = new Constructor(data.getTime())
31 | } else if (dataType === TYPE.RegExp) {
32 | const reFlags = /\w*$/
33 | // 特殊处理regexp,拷贝过程中lastIndex属性会丢失
34 | cloneData = new Constructor(data.source, reFlags.exec(data))
35 | cloneData.lastIndex = data.lastIndex
36 | } else if (dataType === TYPE.Set || dataType === TYPE.Map) {
37 | cloneData = new Constructor()
38 | }
39 | // 写入 hash
40 | hash.set(data, cloneData)
41 | // 遍历 data
42 | if (dataType === TYPE.Set) {
43 | for (let value of data) {
44 | cloneData.add(cloneDeep(value, hash))
45 | }
46 | } else if (dataType === TYPE.Map) {
47 | for (let [mapKey, mapValue] of data) {
48 | // Map的键、值都可以是引用类型,因此都需要拷贝
49 | cloneData.set(cloneDeep(mapKey, hash), cloneDeep(mapValue, hash))
50 | }
51 | } else {
52 | for (let key in data) {
53 | // 不考虑继承的属性
54 | if (data.hasOwnProperty(key)) {
55 | cloneData[key] = cloneDeep(data[key], hash)
56 | }
57 | }
58 | }
59 | return cloneData
60 | }
61 |
62 | module.exports = cloneDeep
63 |
--------------------------------------------------------------------------------
/promise/test/promise5.test.js:
--------------------------------------------------------------------------------
1 | const MyPromise = require('../src/promise5')
2 |
3 | const promise = new MyPromise((resolve) => {
4 | setTimeout(() => {
5 | resolve(1)
6 | }, 100)
7 | })
8 |
9 | // catch、finally test
10 | promise.then((value) => {
11 | console.log('value1', value);
12 | return new MyPromise((resolve, reject) => {
13 | setTimeout(() => {
14 | reject(2)
15 | }, 100)
16 | })
17 | })
18 | .then((value) => {
19 | console.log('value2', value);
20 | })
21 | .catch(e => {
22 | console.log('err', e);
23 | })
24 | .finally(() => {
25 | console.log('fin');
26 | })
27 |
28 | // resolve test
29 | const thenable = {
30 | then: function(resolve, reject) {
31 | resolve(42);
32 | }
33 | };
34 |
35 | MyPromise.resolve(thenable)
36 | .then(val => {
37 | console.log('resolve1', val);
38 | })
39 |
40 | console.log('resolve2', MyPromise.resolve(1))
41 |
42 | // race test
43 | MyPromise.race([new MyPromise((resolve) => {
44 | setTimeout(() => {
45 | resolve(1)
46 | }, 1000)
47 | }), new MyPromise((resolve) => {
48 | setTimeout(() => {
49 | resolve(2)
50 | }, 500)
51 | }), 3])
52 | .then(val => {
53 | console.log('race', val);
54 | })
55 |
56 | // all test
57 | MyPromise.all([new MyPromise((resolve) => {
58 | setTimeout(() => {
59 | resolve(1)
60 | }, 1000)
61 | }), new MyPromise((resolve) => {
62 | setTimeout(() => {
63 | resolve(2)
64 | }, 500)
65 | })])
66 | .then(val => {
67 | console.log('all1', val);
68 | })
69 |
70 | MyPromise.all([new MyPromise((resolve) => {
71 | setTimeout(() => {
72 | resolve(1)
73 | }, 1000)
74 | }), new MyPromise((resolve, reject) => {
75 | setTimeout(() => {
76 | reject(2)
77 | }, 500)
78 | })])
79 | .catch(e => {
80 | console.log('all2', e);
81 | })
82 |
83 | MyPromise.allSettled([new MyPromise((resolve) => {
84 | setTimeout(() => {
85 | resolve(1)
86 | }, 1000)
87 | }), new MyPromise((resolve, reject) => {
88 | setTimeout(() => {
89 | reject(2)
90 | }, 500)
91 | })])
92 | .then(arr => {
93 | console.log('allSettled', arr);
94 | })
95 |
--------------------------------------------------------------------------------
/typescript/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* 构建、工程化选项 */
4 |
5 | // baseUrl: 解析的根目录
6 | "baseUrl": "src",
7 | // target: 编译代码到目标 ECMAScript 版本,一般是 es5/es6
8 | "target": "es5",
9 | // lib: 运行时环境支持的语法,默认与 tagert 的值相关联
10 | "lib": ["dom", "es5", "es6", "esnext"],
11 | // module: 编译产物对应的模块化标准,常用值包括 commonjs/es6/esnext 等
12 | "module": "esnext",
13 | // moduleResolution: 模块解析策略,支持 node/classic,后者基本不推荐使用
14 | "moduleResolution": "node",
15 | // allowJs:是否允许引入 .js 文件
16 | "allowJs": true,
17 | // checkJs: 是否检查 .js 文件中的错误
18 | "checkJs": true,
19 | // declaration: 是否生成对应的 .d.ts 类型文件,一般作为 npm 包提供时需要开启
20 | "declaration": false,
21 | // sourceMap: 是否生成对应的 .map 文件
22 | "sourceMap": true,
23 | // noEmit: 是否将构建产物写入文件系统,一个常见的实践是只用 tsc 进行类型检查,使用单独的打包工具进行打包
24 | "noEmit": true,
25 | // jsx: 如何处理 .tsx 文件中对于 jsx 的生成,常用值包括:react/preserve
26 | // 详细比对:https://www.typescriptlang.org/tsconfig#jsx
27 | "jsx": "preserve",
28 | // esModuleInterop: 开启后会生成辅助函数以兼容处理在 esm 中导入 cjs 的情况
29 | "esModuleInterop": true,
30 | // allowSyntheticDefaultImports: 在 cjs 没有默认导出时进行兼容,配合 esModuleInterop 使用
31 | "allowSyntheticDefaultImports": true,
32 | // forceConsistentCasingInFileNames: 是否强制导入文件时与系统文件的大小写一致
33 | "forceConsistentCasingInFileNames": true,
34 | // resolveJsonModule:是否支持导入 json 文件,并做类型推导和检查
35 | "resolveJsonModule": true,
36 | // experimentalDecorators: 是否支持装饰器实验性语法
37 | "experimentalDecorators": true,
38 |
39 | /* 类型检查选项 */
40 |
41 | // strict: 是否启动严格的类型检查,包含一系列选项:https://www.typescriptlang.org/tsconfig#strict
42 | "strict": true,
43 | // skipLibCheck: 是否跳过非源代码中所有类型声明文件(.d.ts)的检查
44 | "skipLibCheck": true,
45 | // strictNullChecks: 是否启用严格的 null 检查
46 | "strictNullChecks": true,
47 | // noImplicitAny: 包含隐式 any 声明时是否报错
48 | "noImplicitAny": true,
49 | // noImplicitReturns: 是否要求所有函数执行路径中都有返回值
50 | "noImplicitReturns": true,
51 | // noUnusedLocals: 存在未使用的变量时是否报错
52 | "noUnusedLocals": false,
53 | // noUnusedParameters: 存在未使用的参数时是否报错
54 | "noUnusedParameters": false,
55 | }
56 | }
--------------------------------------------------------------------------------
/cloneDeep/src/clone4.js:
--------------------------------------------------------------------------------
1 | // 使用非递归实现cloneDeep
2 |
3 | const TYPE = {
4 | Object: 'Object',
5 | Array: 'Array',
6 | Date: 'Date',
7 | RegExp: 'RegExp',
8 | Set: 'Set',
9 | Map: 'Map',
10 | }
11 |
12 | // 获取数据类型
13 | const getType = (data) => Object.prototype.toString.call(data).slice(8, -1)
14 |
15 | // 初始化item并入栈
16 | function generate(item, stack, hash) {
17 | if (!item || typeof item !== 'object') return item
18 | if(hash.has(item)) return hash.get(item)
19 | let cloneItem = item
20 | const Constructor = item.constructor
21 | const itemType = getType(item)
22 | // data 初始化
23 | if (itemType === TYPE.Array) {
24 | cloneItem = []
25 | } else if (itemType === TYPE.Object) {
26 | // 获取原对象的原型
27 | cloneItem = Object.create(Object.getPrototypeOf(item))
28 | } else if (itemType === TYPE.Date) {
29 | cloneItem = new Constructor(item.getTime())
30 | } else if (itemType === TYPE.RegExp) {
31 | const reFlags = /\w*$/
32 | // 特殊处理regexp,拷贝过程中lastIndex属性会丢失
33 | cloneItem = new Constructor(item.source, reFlags.exec(item))
34 | cloneItem.lastIndex = item.lastIndex
35 | } else if (itemType === TYPE.Set || itemType === TYPE.Map) {
36 | cloneItem = new Constructor()
37 | }
38 | stack.push({
39 | target: cloneItem,
40 | source: item,
41 | })
42 | hash.set(item, cloneItem)
43 | return cloneItem
44 | }
45 |
46 | function cloneDeep(data) {
47 | // 初始化hash
48 | const hash = new WeakMap()
49 | // 初始化stack
50 | const stack = []
51 | const cloneData = generate(data, stack, hash)
52 | while(stack.length > 0) {
53 | // 栈顶节点出栈
54 | const node = stack.pop()
55 | const { target, source } = node
56 | const type = getType(source)
57 | // 遍历 source
58 | if (type === TYPE.Set) {
59 | for (let value of source) {
60 | target.add(generate(value, stack, hash))
61 | }
62 | } else if (type === TYPE.Map) {
63 | for (let [mapKey, mapValue] of source) {
64 | target.set(generate(mapKey, stack, hash), generate(mapValue, stack, hash))
65 | }
66 | } else {
67 | for (let key in source) {
68 | // 不考虑继承的属性
69 | if (source.hasOwnProperty(key)) {
70 | target[key] = generate(source[key], stack, hash)
71 | }
72 | }
73 | }
74 | }
75 | return cloneData
76 | }
77 |
78 | module.exports = cloneDeep
79 |
--------------------------------------------------------------------------------
/pnpm/01-npm@2/node_modules/demo-baz/node_modules/demo-bar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-bar",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "author": "",
9 | "license": "ISC",
10 | "_id": "demo-bar@1.0.0",
11 | "_nodeVersion": "14.20.1",
12 | "_npmVersion": "6.14.17",
13 | "dist": {
14 | "integrity": "sha512-M32T7z7T8L6+YNWtLhWi2Cul7K6U5yAziWME2fhPHX36XWFUdVyCy6PJD3XdFBKy0cacfWSfEJTWmBkB5f4iEw==",
15 | "shasum": "842e7e2c482ade053a886a38b8bebd9d47356c7b",
16 | "tarball": "https://registry.npmjs.org/demo-bar/-/demo-bar-1.0.0.tgz",
17 | "fileCount": 2,
18 | "unpackedSize": 224,
19 | "signatures": [
20 | {
21 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
22 | "sig": "MEYCIQDQgiDnizuY+1qhVZMnGJEFBrbet1T7qhmFOBiePsLn/AIhAK+EyJD49lvxdsC37qE2vfM4ODxhx70ILuMbAkSMagML"
23 | }
24 | ],
25 | "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjVT+dACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrGqQ/9FK+dxAeizFGD49fOjRnV+leoW68Mdk5FBKmFztrDqGTFmKpJ\r\npJZ858TKrZpf2gjZLcYkCwdUvJZV8xAkdd8zFwasIkd4rd5CZ4ToNzOvwrVT\r\nvWNimGfSyHkGYgBNB1kDwtjDDKQ8+9USUWTjhPEMuadCMW8V5uzAPevA17+g\r\nNSKz+Db1oMlSRzd4UYiYirUgO2qAU6Gg4LXE4pYl8GStPBj8p7nF1XlnWcrd\r\n3AkvH40ed9W7P1b2Pf7hclUV/1Hdx2Jlpys9PcheL5Bf8kCIA7wnb7IaHK1F\r\nRqGLeoRNg5IgE4AOqXcQ8iw4Y7+f8W1QYFBO9VzSEpj755NS0u2fyiUs66EO\r\n/+AzO0kP5s9ARnbP7NRFXg8PHIeQAvrqT65QNPbzHgMTT6GrO6Imz7SGREeP\r\n4XwWcC6iZ8HT002Uf32mA6DeYK3i+9uzRpbsyNcvNClgEh2P+KD52XtQp9bY\r\naEi+I6PJutZ5npLS7Yn0bFArh8rkzvgQ6fZY47MT0PxPs9LiEkZFrUdvVtfp\r\n1mzUa87oEsQPoHl/VBiYV2E9YfkMiM8xZhP0wzD2PdNibo0b1JIohWr3bZ2n\r\n/jSBGGg0yqSWn/Sy3l3bncssjQreKqQ9W125cJyaH3CRW2eNwTPZHqmF3Cju\r\n0sOPuznK0qp/u8FRH+tlpKAQO15xHsz0bCw=\r\n=EERK\r\n-----END PGP SIGNATURE-----\r\n"
26 | },
27 | "_npmUser": {
28 | "name": "lvqq",
29 | "email": "nicksonlvqq@gmail.com"
30 | },
31 | "directories": {},
32 | "maintainers": [
33 | {
34 | "name": "lvqq",
35 | "email": "nicksonlvqq@gmail.com"
36 | }
37 | ],
38 | "_npmOperationalInternal": {
39 | "host": "s3://npm-registry-packages",
40 | "tmp": "tmp/demo-bar_1.0.0_1666531228971_0.3777985296894073"
41 | },
42 | "_hasShrinkwrap": false,
43 | "_shasum": "842e7e2c482ade053a886a38b8bebd9d47356c7b",
44 | "_resolved": "https://registry.npmjs.org/demo-bar/-/demo-bar-1.0.0.tgz",
45 | "_from": "demo-bar@1.0.0",
46 | "readme": "ERROR: No README data found!"
47 | }
48 |
--------------------------------------------------------------------------------
/pnpm/01-npm@2/node_modules/demo-foo/node_modules/demo-bar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-bar",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "author": "",
9 | "license": "ISC",
10 | "_id": "demo-bar@1.0.0",
11 | "_nodeVersion": "14.20.1",
12 | "_npmVersion": "6.14.17",
13 | "dist": {
14 | "integrity": "sha512-M32T7z7T8L6+YNWtLhWi2Cul7K6U5yAziWME2fhPHX36XWFUdVyCy6PJD3XdFBKy0cacfWSfEJTWmBkB5f4iEw==",
15 | "shasum": "842e7e2c482ade053a886a38b8bebd9d47356c7b",
16 | "tarball": "https://registry.npmjs.org/demo-bar/-/demo-bar-1.0.0.tgz",
17 | "fileCount": 2,
18 | "unpackedSize": 224,
19 | "signatures": [
20 | {
21 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
22 | "sig": "MEYCIQDQgiDnizuY+1qhVZMnGJEFBrbet1T7qhmFOBiePsLn/AIhAK+EyJD49lvxdsC37qE2vfM4ODxhx70ILuMbAkSMagML"
23 | }
24 | ],
25 | "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjVT+dACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrGqQ/9FK+dxAeizFGD49fOjRnV+leoW68Mdk5FBKmFztrDqGTFmKpJ\r\npJZ858TKrZpf2gjZLcYkCwdUvJZV8xAkdd8zFwasIkd4rd5CZ4ToNzOvwrVT\r\nvWNimGfSyHkGYgBNB1kDwtjDDKQ8+9USUWTjhPEMuadCMW8V5uzAPevA17+g\r\nNSKz+Db1oMlSRzd4UYiYirUgO2qAU6Gg4LXE4pYl8GStPBj8p7nF1XlnWcrd\r\n3AkvH40ed9W7P1b2Pf7hclUV/1Hdx2Jlpys9PcheL5Bf8kCIA7wnb7IaHK1F\r\nRqGLeoRNg5IgE4AOqXcQ8iw4Y7+f8W1QYFBO9VzSEpj755NS0u2fyiUs66EO\r\n/+AzO0kP5s9ARnbP7NRFXg8PHIeQAvrqT65QNPbzHgMTT6GrO6Imz7SGREeP\r\n4XwWcC6iZ8HT002Uf32mA6DeYK3i+9uzRpbsyNcvNClgEh2P+KD52XtQp9bY\r\naEi+I6PJutZ5npLS7Yn0bFArh8rkzvgQ6fZY47MT0PxPs9LiEkZFrUdvVtfp\r\n1mzUa87oEsQPoHl/VBiYV2E9YfkMiM8xZhP0wzD2PdNibo0b1JIohWr3bZ2n\r\n/jSBGGg0yqSWn/Sy3l3bncssjQreKqQ9W125cJyaH3CRW2eNwTPZHqmF3Cju\r\n0sOPuznK0qp/u8FRH+tlpKAQO15xHsz0bCw=\r\n=EERK\r\n-----END PGP SIGNATURE-----\r\n"
26 | },
27 | "_npmUser": {
28 | "name": "lvqq",
29 | "email": "nicksonlvqq@gmail.com"
30 | },
31 | "directories": {},
32 | "maintainers": [
33 | {
34 | "name": "lvqq",
35 | "email": "nicksonlvqq@gmail.com"
36 | }
37 | ],
38 | "_npmOperationalInternal": {
39 | "host": "s3://npm-registry-packages",
40 | "tmp": "tmp/demo-bar_1.0.0_1666531228971_0.3777985296894073"
41 | },
42 | "_hasShrinkwrap": false,
43 | "_shasum": "842e7e2c482ade053a886a38b8bebd9d47356c7b",
44 | "_resolved": "https://registry.npmjs.org/demo-bar/-/demo-bar-1.0.0.tgz",
45 | "_from": "demo-bar@1.0.0",
46 | "readme": "ERROR: No README data found!"
47 | }
48 |
--------------------------------------------------------------------------------
/pnpm/01-npm@2/node_modules/demo-baz/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-baz",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-bar": "1.0.0"
13 | },
14 | "_id": "demo-baz@1.0.0",
15 | "_nodeVersion": "14.20.1",
16 | "_npmVersion": "6.14.17",
17 | "dist": {
18 | "integrity": "sha512-Q5WJf+3qk2kZ+wV8Y+EiJNqN9uATjfSR29Ml7HUMLFSoGP/OeG8MYe3lvlEmidmE5GKBAszzCW5wUVJU3t5RQg==",
19 | "shasum": "0ce32889e87a71064481fa3504274fee5b46983c",
20 | "tarball": "https://registry.npmjs.org/demo-baz/-/demo-baz-1.0.0.tgz",
21 | "fileCount": 2,
22 | "unpackedSize": 292,
23 | "signatures": [
24 | {
25 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
26 | "sig": "MEQCIARPX99sII5IcNOifCUuicyu5/qqZtNHurt6uazFSw8vAiBm7zuiw0QKbnJfRbQaX5+NDXSE1sy0U3afObWg0GvAJw=="
27 | }
28 | ],
29 | "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjVUWGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp/hg//TS0dGWr1XbKYhx6nKZOot76kBaluLTTHC6DiabsZnrXaRKko\r\nIklHVGL7EBndqbasRQVK/8rOkYv88NyZBkbbLK8J5oT7HTpktUCcg1TzEORz\r\nGyvuEJYWKG9U2khn5dfJFF7z8hqTS/v23zuqJRHHXrKXb2TjIC3YwcE9RUPx\r\nafGEdqNZIfCHL1lXckBjXDoyrCLNa5qa6x1PZE6Ot2EkQjgqFPNIZ7k0wPCH\r\nTdPQhOTsMAWpyysg3Y4MabjXMYGRb6oG2FnnElOUWsMVSs4HtiSUcPntnfuz\r\naFXOwCIxIhmsD2/gdgoHGBn7i29AUqzNuMADe7+wbebYW/adAgHWlI9qspNk\r\nUv0Uo2/mq8poZYJsTfZ3LugNsZ/hc0AsKP92QMT99ALKqk5n1EL+rO4zBtRq\r\nY1tf59dpqckeXJ8+7UUKibew94GhGSYyewhvkX8pV12emeZOUyJUfNQjM3Kp\r\nUG2izMynfsFW/CECc+fwQos1wT8MsWZMhJ2qAT/5hyN2oVpcojg04LIBVcYm\r\nOy0fDm9lFWoIQoPIBabcoXKR+bvstZisgt12OJuhZ/7QyboJC4Q34JwxeDjj\r\nnL+ve3P8q49Ed4Ia0rY1uBlwTAMr1UIFYwNtVjEgB7w5Q8Fgb+AGyZnow/UC\r\nqg+YgBla6+tvW1n28MTwR3ffUeT6Etpa+I0=\r\n=69V5\r\n-----END PGP SIGNATURE-----\r\n"
30 | },
31 | "_npmUser": {
32 | "name": "lvqq",
33 | "email": "nicksonlvqq@gmail.com"
34 | },
35 | "directories": {},
36 | "maintainers": [
37 | {
38 | "name": "lvqq",
39 | "email": "nicksonlvqq@gmail.com"
40 | }
41 | ],
42 | "_npmOperationalInternal": {
43 | "host": "s3://npm-registry-packages",
44 | "tmp": "tmp/demo-baz_1.0.0_1666532742593_0.743925781059384"
45 | },
46 | "_hasShrinkwrap": false,
47 | "_shasum": "0ce32889e87a71064481fa3504274fee5b46983c",
48 | "_resolved": "https://registry.npmjs.org/demo-baz/-/demo-baz-1.0.0.tgz",
49 | "_from": "demo-baz@1.0.0",
50 | "readme": "ERROR: No README data found!"
51 | }
52 |
--------------------------------------------------------------------------------
/pnpm/01-npm@2/node_modules/demo-foo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo-foo",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "demo-bar": "1.0.0"
13 | },
14 | "_id": "demo-foo@1.0.0",
15 | "_nodeVersion": "14.20.1",
16 | "_npmVersion": "6.14.17",
17 | "dist": {
18 | "integrity": "sha512-VeRVrfGWqCvZLL9BTq7ZDNroR9ve7Yh3n7DI/RI1CcdQpCzTbxmAaT3YdKv4/lAQGGLws9Wwrx+PQCszCX+n6g==",
19 | "shasum": "53a114df5a7cdd0137fb68b01f0a6f0882d0c6b3",
20 | "tarball": "https://registry.npmjs.org/demo-foo/-/demo-foo-1.0.0.tgz",
21 | "fileCount": 2,
22 | "unpackedSize": 295,
23 | "signatures": [
24 | {
25 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
26 | "sig": "MEUCIHJmeXOtnC5spuTeeLlsokRoyXzONuw46MAYbZOOI72ZAiEA1/oaP4ca+ouVwmYotxcDbuDNSmdEAZUQbEahxjMeM94="
27 | }
28 | ],
29 | "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjVT/FACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo32g/9FO6s72IhxXX+OM0blQnVBBV8lfAvVS8M7mKBXnenzRsmkLnR\r\noVfC7a/X+s0vR3RWEoVufXeWfZywrRBngU/3q4WePAtKOgQG9PQepmj/pUxX\r\nP0RbNqCnCsMhWNeu8WKRMIvdfPaSqZgB3nCw8j/k+/qAit0qNpWWmCkUWpQs\r\nCfzR4bAjMNhihALEmjaztuYPElQFbyeZq/DshNAqbyL/L+yUZu5jg1xv1cQd\r\n++cLCA3rn7sjPT5gYQW79EAgPSlwbvoA/5PN6A5bdlE99ZQmf+Wv2Kv6LPSl\r\nOyMLko/uigvn79tKXxEdMryRBtX1sOx00eKY3xgE3gpMlLz+cu9gQkTFjl4A\r\n3Cm3RpJdHsvote0SZdBVerURA6f8VWV+1Ecfj9wpXa/ukJpDZxLOwQawmtYc\r\n78KbEHqyRqmshIUZvo1rT5X5ReCYCXHmctoezew3kx/ejwzWMhESsNzvkpjt\r\niF1Bz8HgIqjfKQ2L6Pn7JmUCBUvlTMnF977UzucG1ZBNAROpYQb3EzKLdIej\r\n2DH8lk09p2IlHMOsCY25Ty8juU5ZitfAJOaIpI9zrno9qY7KWIuM9EfpXGUs\r\nsjVUhuuEOnohSuogLy/7l9vzYFg9NmfvRd6INyHDr5jor9AsMAURQ7NgPh3+\r\n6A7QtjHqAf4cV66nKLQzovqX7JMXZ8dffKk=\r\n=kpbO\r\n-----END PGP SIGNATURE-----\r\n"
30 | },
31 | "_npmUser": {
32 | "name": "lvqq",
33 | "email": "nicksonlvqq@gmail.com"
34 | },
35 | "directories": {},
36 | "maintainers": [
37 | {
38 | "name": "lvqq",
39 | "email": "nicksonlvqq@gmail.com"
40 | }
41 | ],
42 | "_npmOperationalInternal": {
43 | "host": "s3://npm-registry-packages",
44 | "tmp": "tmp/demo-foo_1.0.0_1666531269124_0.18467285083543294"
45 | },
46 | "_hasShrinkwrap": false,
47 | "_shasum": "53a114df5a7cdd0137fb68b01f0a6f0882d0c6b3",
48 | "_resolved": "https://registry.npmjs.org/demo-foo/-/demo-foo-1.0.0.tgz",
49 | "_from": "demo-foo@1.0.0",
50 | "readme": "ERROR: No README data found!"
51 | }
52 |
--------------------------------------------------------------------------------
/amplifier/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 放大器
6 |
7 |
37 |
38 |
39 |

40 |
41 |
42 |
43 |

44 |
45 |
46 |
93 |
--------------------------------------------------------------------------------
/browserCache/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | -
23 | 缓存优先级:
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
35 |
99 |
100 |
--------------------------------------------------------------------------------
/gulp-demo/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp'),
2 | less = require('gulp-less'), //less 转 css
3 | csso = require('gulp-csso'), //css压缩
4 | concat = require('gulp-concat'), //合并文件
5 | uglify = require('gulp-uglify'), //js 压缩
6 | jshint = require('gulp-jshint'), //js 检查
7 | clean = require('gulp-clean'), //清除文件
8 | imagemin = require('gulp-imagemin'), //图片压缩
9 | rev = require('gulp-rev'), //添加版本号
10 | revReplace = require('gulp-rev-replace'), //版本号替换
11 | useref = require('gulp-useref'), //解析html资源定位
12 | gulpif = require('gulp-if'), //if语句
13 | connect = require('gulp-connect'); //创建web服务器
14 |
15 | //图片压缩
16 | gulp.task('dist:img', () => {
17 | gulp.src(['./src/**/*.jpg', './src/**/*.png'])
18 | .pipe(imagemin())
19 | .pipe(gulp.dest('dist/'))
20 | })
21 |
22 | //less转css压缩合并
23 | gulp.task('dist:css', () => {
24 | gulp.src('dist/css/*.css').pipe(clean());
25 | return gulp.src('./src/less/*.less')
26 | .pipe(less())
27 | .pipe(csso())
28 | .pipe(concat('public.css'))
29 | .pipe(gulp.dest('dist/css/'));
30 | });
31 |
32 | //less转css
33 | gulp.task('src:css', () => {
34 | gulp.src('src/css/*.css').pipe(clean());
35 | return gulp.src('./src/less/*.less')
36 | .pipe(less())
37 | .pipe(gulp.dest('src/css/'));
38 | });
39 |
40 | //js压缩合并
41 | gulp.task('dist:js', () => {
42 | gulp.src('dist/js/*.js').pipe(clean());
43 | return gulp.src('./src/js/*.js')
44 | .pipe(jshint())
45 | .pipe(jshint.reporter('default'))
46 | .pipe(uglify())
47 | .pipe(concat('public.js'))
48 | .pipe(gulp.dest('dist/js/'))
49 | });
50 |
51 | //添加版本号
52 | gulp.task('revision', ['dist:css', 'dist:js'], () => {
53 | return gulp.src(["dist/css/*.css", "dist/js/*.js"])
54 | .pipe(rev())
55 | .pipe(gulpif('*.css', gulp.dest('dist/css'), gulp.dest('dist/js')))
56 | .pipe(rev.manifest())
57 | .pipe(gulp.dest('dist'))
58 | })
59 |
60 | //替换html
61 | gulp.task('build', ['dist:img'], () => {
62 | var manifest = gulp.src('dist/rev-manifest.json');
63 | return gulp.src('src/index.html')
64 | .pipe(revReplace({
65 | manifest: manifest
66 | }))
67 | .pipe(useref())
68 | .pipe(gulp.dest('dist/'))
69 | })
70 |
71 | //创建本地服务器
72 | gulp.task('connect', () => {
73 | connect.server({
74 | root: 'src',
75 | livereload: true,
76 | port: 8888
77 | })
78 | })
79 |
80 | //设置自动刷新
81 | gulp.task('reload', () => {
82 | gulp.src('src/*.html')
83 | .pipe(connect.reload())
84 | })
85 |
86 | //监听src变化
87 | gulp.task('watch', () => {
88 | gulp.watch('src/**/*', ['src:css', 'reload'])
89 | })
90 |
91 | //清除
92 | gulp.task('clean', () => {
93 | gulp.src('dist/*', {read: false})
94 | .pipe(clean())
95 | })
96 |
97 | gulp.task('default', ['connect','watch']);
--------------------------------------------------------------------------------
/typescript/03-sample.ts:
--------------------------------------------------------------------------------
1 | /* =============== 泛型 =============== */
2 |
3 |
4 | // 定义
5 | type Test3 = T | string;
6 | // 使用
7 | const test: Test3 = 1
8 | // react 中的例子
9 | // const [state, setState] = useState(0)
10 |
11 |
12 |
13 | // 函数式声明
14 | function func3(param: T): T {
15 | return param;
16 | }
17 |
18 | // 表达式声明
19 | const func4: (param: T) => T = (param) => {
20 | return param;
21 | }
22 |
23 |
24 | /* =============== typeof =============== */
25 |
26 | const str4 = 'text'
27 | type Str = typeof str // string
28 |
29 |
30 |
31 |
32 | const obj = {
33 | field1: 'text',
34 | field2: 1,
35 | field3: {
36 | field: 'text'
37 | }
38 | }
39 |
40 | type ObjType = typeof obj
41 | // {
42 | // field1: string;
43 | // field2: number;
44 | // field3: {
45 | // field: string;
46 | // };
47 | // }
48 |
49 |
50 | /* =============== keyof =============== */
51 | interface Test4 {
52 | field1: string;
53 | field2: number;
54 | }
55 |
56 | type Fields1 = keyof Test4
57 | // "field1" | "field2"
58 |
59 |
60 | /* =============== in =============== */
61 |
62 | type Fields2 = 'field1' | 'field2'
63 | type Test5 = {
64 | [key in Fields2]: string
65 | }
66 | // Test: { field1: string; field2: string }
67 |
68 |
69 |
70 | /* =============== extends =============== */
71 |
72 |
73 | type Test6 = T[]
74 | type TestExtends1 = Test6 // success
75 | type TestExtends2 = Test6 // Type 'boolean' does not satisfy the constraint 'string | number'.
76 |
77 |
78 |
79 | type Test7 = T extends string | number ? T[] : T
80 | type TestExtends3 = Test7 // string[]
81 | type TestExtends4 = Test7 // boolean
82 |
83 |
84 |
85 | /* =============== infer =============== */
86 | type MyReturnType any> = T extends (
87 | ...args: any
88 | ) => infer R ? R : any
89 |
90 |
91 | /* =============== 索引类型 =============== */
92 |
93 | interface Test8 {
94 | [key: string]: string;
95 | }
96 |
97 |
98 |
99 | interface Test9 {
100 | // Error: Property 'field' of type 'number' is not assignable to 'string' index type 'string'
101 | field: number;
102 | [key: string]: string;
103 | }
104 |
105 |
106 |
107 | interface Test10 {
108 | field1: string;
109 | field2: number;
110 | }
111 |
112 | type Fields3 = keyof Test10
113 | // "field1" | "field2"
114 |
115 |
116 |
117 | interface Test11 {
118 | field1: string;
119 | field2: number
120 | }
121 |
122 | type Field1 = Test11["field1"] // string
123 | type Field2 = Test11["field2"] // number
124 | // 配合 keyof,可以获取索引签名对应类型的联合类型
125 | type Fields4 = Test11[keyof Test11] // string | number
126 |
127 |
128 |
129 | interface Test12 {
130 | [key: string]: number;
131 | }
132 |
133 | type Field3 = Test12[string] // number
134 |
135 |
136 |
137 | /* =============== 映射类型 =============== */
138 |
139 | type ToString = {
140 | [key in keyof T]: string
141 | }
142 |
143 | interface Test13 {
144 | field1: string;
145 | field2: number;
146 | field3: boolean;
147 | }
148 |
149 | type Fields5 = ToString
150 |
--------------------------------------------------------------------------------
/typescript/04-sample.ts:
--------------------------------------------------------------------------------
1 | /* =============== Partial =============== */
2 |
3 | type MyPartial = {
4 | [P in keyof T]?: T[P] | undefined;
5 | }
6 |
7 |
8 |
9 | interface Person7 {
10 | name: string;
11 | age?: number;
12 | }
13 | type PersonPartial = Partial
14 | // { name?: string | undefined; age?: number | undefined }
15 |
16 |
17 |
18 | type DeepPartial = {
19 | [P in keyof T]?: T[P] extends object ? DeepPartial : T[P] | undefined
20 | }
21 |
22 | /* =============== Required =============== */
23 |
24 | type MyRequired = {
25 | [P in keyof T]-?: T[P];
26 | }
27 |
28 |
29 |
30 | interface Person8 {
31 | name: string;
32 | age?: number;
33 | }
34 |
35 | type PersonRequired = Required
36 | // { name: string; age: number }
37 |
38 | /* =============== Readonly =============== */
39 | type MyReadonly = {
40 | readonly [P in keyof T]: T[P];
41 | }
42 |
43 |
44 |
45 | interface Person9 {
46 | name: string;
47 | age?: number;
48 | }
49 |
50 | type PersonReadonly = Readonly
51 | // { readonly name: string; readonly age?: number | undefined }
52 |
53 |
54 | /* =============== Record =============== */
55 | type MyRecord = {
56 | [P in K]: T;
57 | }
58 |
59 | /* =============== Exclude =============== */
60 | type MyExclude = T extends U ? never : T
61 |
62 |
63 |
64 | type Test14 = string | number
65 | type TestExclude = Exclude // number
66 |
67 | /* =============== Extract =============== */
68 | type MyExtract = T extends U ? T : never
69 |
70 |
71 | type Test15 = string | number
72 | type TestExtract = Extract // string
73 |
74 | /* =============== NonNullable =============== */
75 | type MyNonNullable = T extends null | undefined ? never : T
76 |
77 |
78 | type Test16 = string | number | null | undefined
79 | type TestNonNullable = NonNullable // string | number
80 |
81 | /* =============== Pick =============== */
82 | type MyPick = {
83 | [P in K]: T[P];
84 | }
85 |
86 |
87 |
88 | interface Person10 {
89 | name: string;
90 | age?: number;
91 | }
92 |
93 | type PersonPick = Pick
94 | // { age?: number }
95 |
96 | /* =============== Omit =============== */
97 | type MyOmit = {
98 | [P in Exclude]: T[P];
99 | }
100 |
101 |
102 | interface Person11 {
103 | name: string;
104 | age?: number;
105 | }
106 |
107 | type PersonOmit = Omit
108 | // { age?: number }
109 |
110 | /* =============== Parameters =============== */
111 |
112 | type MyParameters any> = T extends (
113 | ...args: infer P
114 | ) => any ? P : never
115 |
116 |
117 |
118 | type Func1 = (param: string) => string[]
119 | type FuncParam = Parameters // [param: string]
120 |
121 | /* =============== ReturnType =============== */
122 |
123 | type MyReturnType2 any> = T extends (
124 | ...args: any
125 | ) => infer R ? R : any
126 |
127 | type Func2 = (param: string) => string[]
128 | type FuncReturn = ReturnType // string[]
--------------------------------------------------------------------------------
/gulp-demo/src/js/myAlbum.js:
--------------------------------------------------------------------------------
1 | window.onload = function(){
2 | var x,y,nX,nY;
3 | var sumX = 0, sumY = 0;
4 | var page = document.querySelector(".page");
5 | var album = document.querySelector(".album");
6 | var change = document.querySelectorAll(".change");
7 | var change2 = document.querySelectorAll(".change2");
8 |
9 | /* 设置延时绑定事件,不影响开场动画 */
10 | setTimeout(function(){
11 | document.addEventListener("mousedown",start);
12 | },3000);
13 |
14 | /* 设置图片背景 */
15 | var mainHold = document.querySelectorAll(".main-hold");
16 | for(var i = 0;i<12;i++) {
17 | mainHold[i].setAttribute("style","background-image:url(./images/"+(i+1)+".jpg)");
18 | }
19 |
20 | var top = document.querySelector(".top");
21 | var bottom =document.querySelector(".bottom");
22 | function start(event) {
23 | if(event.button == 0) {
24 | //阻止浏览器默认事件
25 | stopDefault(event);
26 |
27 | //使橙色方块隐藏
28 | top.setAttribute("style","animation:orange-hide 3s linear forwards");
29 | bottom.setAttribute("style","animation:orange-hide 3s linear forwards");
30 |
31 |
32 | nX = event.clientX;
33 | nY = event.clientY;
34 | document.addEventListener("mousemove",move);
35 | document.addEventListener("mouseup",end);
36 | }
37 | return false;
38 | }
39 |
40 | function move(event) {
41 | //设置绕Y轴旋转
42 | x = nX - event.clientX;
43 | sumX = sumX + 0.1*x;
44 |
45 | //设置绕X轴旋转
46 | y = nY - event.clientY;
47 | sumY = 0.1*y;
48 |
49 | /*划定边界*/
50 | if(sumY >= 10) {
51 | sumY = 10;
52 | }
53 | else if(sumY <= -10){
54 | sumY = -10;
55 | }
56 |
57 | album.setAttribute("style","transform: translateZ(460px) rotateY("+ sumX +"deg) rotate3d(100,0,0,"+ sumY +"deg)");
58 |
59 | //保存当前clientX的值以便下次调用
60 | nX = event.clientX;
61 |
62 | //设置颜色变换
63 | change[0].setAttribute("style","animation-play-state:running");
64 | change[1].setAttribute("style","animation-play-state:running");
65 | change2[0].setAttribute("style","animation-play-state:running");
66 | change2[1].setAttribute("style","animation-play-state:running");
67 |
68 | return false;
69 | }
70 |
71 | function end() {
72 | album.setAttribute("style","transform: translateZ(460px) rotateY("+ sumX +"deg)");
73 |
74 | //停止颜色变换
75 | change[0].setAttribute("style","animation-play-state:paused");
76 | change[1].setAttribute("style","animation-play-state:paused");
77 | change2[0].setAttribute("style","animation-play-state:paused");
78 | change2[1].setAttribute("style","animation-play-state:paused");
79 |
80 |
81 | document.removeEventListener("mousemove",move);
82 | document.removeEventListener("mouseup",end);
83 | }
84 |
85 | //阻止浏览器默认行为触发的通用方法
86 | function stopDefault(e){
87 | //防止浏览器默认行为(W3C)
88 | if(e && e.preventDefault){
89 | e.preventDefault();
90 | }
91 | //IE中组织浏览器行为
92 | else{
93 | window.event.returnValue=fale;
94 | return false;
95 | }
96 | }
97 |
98 | };
99 |
--------------------------------------------------------------------------------
/typescript/01-sample.ts:
--------------------------------------------------------------------------------
1 | /* =============== 原始数据类型 =============== */
2 | const str: string = 'text'
3 | const num: number = 1
4 | const bool: boolean = true
5 | const undef: undefined = undefined
6 | const empty: null = null
7 | const symb: symbol = Symbol('symb')
8 | const bigint: bigint = BigInt(9007199254740993)
9 |
10 | /* object */
11 |
12 | let demo: object
13 | demo = []
14 | demo = {}
15 | demo = () => {}
16 | demo = 1 // Error: Type 'number' is not assignable to type 'object'
17 |
18 | /* =============== Object 与 {} =============== */
19 |
20 | let demo1: Object
21 | demo1 = []
22 | demo1 = {}
23 | demo1 = 1
24 | // null, undefined 需要在 strictNullChecks=false 时才可以
25 | demo1 = null
26 | demo1 = undefined
27 |
28 | let demo2: {}
29 | demo2 = []
30 | demo2 = {}
31 | demo2 = 1
32 | demo2 = null // Error: Type 'null' is not assignable to type '{}'
33 | demo2 = undefined // Error: Type 'undefined' is not assignable to type '{}'
34 |
35 |
36 | /* =============== 数组 =============== */
37 |
38 | const arr1: string[] = []
39 | // 等价于
40 | const arr2: Array = []
41 |
42 | /* =============== 元组 =============== */
43 |
44 | const tup: [string, number] = ['LiHua', 18]
45 |
46 | // 支持可选
47 | const tup1: [string, number?] = ['LiHua']
48 | // 支持对属性命名
49 | const tup2: [name: string, age?: number] = ['LiHua']
50 |
51 | /* =============== 函数 =============== */
52 |
53 | // 函数式声明
54 | function test1(x: number, y: number): number {
55 | return x + y
56 | }
57 | // 表达式声明
58 | const test2: (x: number, y: number) => number = (x, y) => {
59 | return x + y
60 | }
61 | // 或
62 | const test3 = (x: number, y: number): number => {
63 | return x + y
64 | }
65 |
66 | /* =============== void =============== */
67 |
68 |
69 | // case 1
70 | function test4() {}
71 |
72 | // case 2
73 | function test5() {
74 | return;
75 | }
76 |
77 | // case 3
78 | function test6() {
79 | return undefined;
80 | }
81 |
82 |
83 | /* =============== any 与 unknown =============== */
84 |
85 | let type1: any
86 | // 被任意类型赋值
87 | type1 = 1
88 | // 赋值给任意类型
89 | let type2: number = type1
90 |
91 | let type3: unknown
92 | // 被任意类型赋值
93 | type3 = 1
94 | // 赋值给任意类型
95 | let type4: number = type3 // Error: Type 'unknown' is not assignable to type 'number'
96 |
97 |
98 |
99 | let str1: unknown = 'string';
100 | str1.slice(0, 1) // Error: Object is of type 'unknown'.
101 |
102 | let str2: any = 'string';
103 | str2.slice(0, 1) // Success
104 |
105 |
106 |
107 | let str3: unknown = 'string';
108 | // 1. 通过 as 类型断言
109 | (str3 as string).slice(0, 1)
110 |
111 | // 2. 通过 typeof 类型推断
112 | if (typeof str3 === 'string') {
113 | str3.slice(0, 1)
114 | }
115 |
116 | /* =============== never =============== */
117 |
118 | // 1.抛出异常
119 | function test7(): never {
120 | throw new Error('err')
121 | }
122 |
123 | // 2. 死循环
124 | function test8(): never {
125 | while(true) {}
126 | }
127 |
128 |
129 |
130 | const checkValueType = (value: string | number) => {
131 | if (typeof value === 'string') {
132 | // do something
133 | } else if (typeof value === 'number') {
134 | // do something
135 | } else {
136 | const check: never = value
137 | // do something
138 | }
139 | }
140 |
141 |
142 |
143 | const checkValueType1 = (value: string | number | boolean) => {
144 | if (typeof value === 'string') {
145 | // do something
146 | } else if (typeof value === 'number') {
147 | // do something
148 | } else {
149 | const check: never = value // Error: Type 'boolean' is not assignable to type 'never'.
150 | // do something
151 | }
152 | }
--------------------------------------------------------------------------------
/lazyLoad/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
31 |
32 |
33 |
34 |
35 |
36 | 
37 | 
38 | 
39 | 
40 | 
41 | 
42 | 
43 | 
44 | 
45 | 
46 | 
47 | 
48 |
49 |
50 |
51 |
52 |
95 |
96 |
--------------------------------------------------------------------------------
/gulp-demo/dist/css/public.css:
--------------------------------------------------------------------------------
1 | @keyframes closer{0%{transform:translateZ(-800px)}to{transform:translateZ(460px)}}@keyframes color{0%,to{background-color:#fff}50%{background-color:#868686}}@keyframes color2{0%,to{background-color:#868686}50%{background-color:#fff}}@keyframes orange-hide{0%{opacity:1}to{opacity:0}}body{margin:0;padding:0;font-family:"Microsoft Yahei"}.page,body,html{height:100%}.page{width:100%;overflow:hidden;background-color:#fff;perspective:550px;cursor:move}.page .album{position:relative;margin:0 auto;margin-top:40vh;transform-style:preserve-3d;text-align:center;width:800px;height:200px;animation:closer 3s ease;transform:translateZ(460px)}.page .album .gallery{width:100%;height:100%;position:absolute;left:0;top:0;backface-visibility:hidden;display:flex}.page .album .gallery.left{transform:rotateY(90deg) translateZ(-400px)}.page .album .gallery.current{transform:translateZ(-400px)}.page .album .gallery.right{transform:rotateY(-90deg) translateZ(-400px)}.page .album .gallery.back{transform:rotateY(180deg) translateZ(-400px)}.page .album .gallery.change{background-color:#fff;animation:color 8s linear infinite;animation-play-state:paused}.page .album .gallery.change2{background-color:#868686;animation:color2 8s linear infinite;animation-play-state:paused}.page .album .gallery .photo{flex:1;perspective:550px;height:100%;transform-style:preserve-3d}.page .album .gallery .photo .back-photo,.page .album .gallery .photo .main-photo{width:40%;height:90%;margin:10% auto 0;transform-style:preserve-3d}.page .album .gallery .photo .main-photo .top-hold{width:4px;height:10%;background-color:#000;margin:0 auto}.page .album .gallery .photo .main-photo .main-hold{width:100%;height:70%;background-repeat:no-repeat;background-size:cover}.page .album .gallery .photo .main-photo .bottom-hold{width:4px;height:25%;background-color:#000;margin:0 auto}.page .album .gallery .photo .main-photo .side-hold{width:20px;height:40px;background-color:#000;margin:0 auto}.page .album .gallery .photo .back-photo .center-back{width:100%;height:70%;background-color:#ccc}.page .album .gallery .photo .back-photo .bottom-back{height:15%;width:8px;background-color:#ccc;margin:0 auto}.page .album .gallery .photo .back-photo .side-back{height:35px;width:8px;background-color:#ccc;margin:0 auto;transform-origin:top}.page .album .gallery .photo.left-photo .side-hold{transform:translateY(-50%) rotateX(90deg) skew(-15deg)}.page .album .gallery .photo.left-photo .back-photo{transform:translateX(35%) translateY(-98%) translateZ(-30px)}.page .album .gallery .photo.left-photo .back-photo .side-back{transform:rotateX(90deg) skew(-43deg)}.page .album .gallery .photo.center-photo .side-hold{transform:translateY(-50%) rotateX(90deg)}.page .album .gallery .photo.center-photo .back-photo{transform:translateZ(-30px) translateY(-98%)}.page .album .gallery .photo.center-photo .back-photo .side-back{transform:rotateX(90deg)}.page .album .gallery .photo.right-photo .side-hold{transform:translateY(-50%) rotateX(90deg) skew(15deg)}.page .album .gallery .photo.right-photo .back-photo{transform:translateX(-35%) translateY(-98%) translateZ(-30px)}.page .album .gallery .photo.right-photo .back-photo .side-back{transform:rotateX(90deg) skew(43deg)}.page .album .bottom,.page .album .top{position:absolute;left:0;top:0;display:flex;width:100%;height:800px;perspective:none}.page .album .bottom .diamonds,.page .album .top .diamonds{flex:1;display:flex;flex-direction:column}.page .album .bottom .diamonds .diamond,.page .album .top .diamonds .diamond{flex:1}.page .album .bottom .diamonds .diamond .orange,.page .album .top .diamonds .diamond .orange{width:20px;height:30px;margin:43% auto 0;background-color:#ff8000}.page .album .bottom{transform:translateY(-180px) rotateX(90deg)}.page .album .top{transform:translateY(-200px) rotateX(90deg) translateZ(220px)}
--------------------------------------------------------------------------------
/typescript/02-sample.ts:
--------------------------------------------------------------------------------
1 | /* =============== 字面量类型 =============== */
2 |
3 | const num_literal: 1 | 2 = 1
4 | const str_literal: "text1" | "text2" = "text1"
5 |
6 |
7 | /* =============== 枚举 =============== */
8 |
9 | enum TestEnum {
10 | key1 = 'value1',
11 | key2 = 2
12 | }
13 |
14 | // 常量枚举
15 | const enum TestEnum1 {
16 | key1 = 'value1',
17 | key2 = 2
18 | }
19 | const val = TestEnum1.key2
20 |
21 |
22 | /* =============== 接口 =============== */
23 |
24 | // 可选
25 | interface Person {
26 | name: string
27 | addr?: string
28 | }
29 |
30 | /* =============== readonly =============== */
31 |
32 | interface Person {
33 | name: string
34 | readonly age: number
35 | }
36 |
37 | const person: Person = { name: 'LiHua', age: 18 }
38 | person.age = 20 // Cannot assign to 'age' because it is a read-only property
39 |
40 | const list: readonly number[] = [1, 2]
41 | list.push(3) // Property 'push' does not exist on type 'readonly number[]'.
42 | list[0] = 2 // Index signature in type 'readonly number[]' only permits reading
43 |
44 |
45 | /* =============== 类型别名 =============== */
46 |
47 | type Person1 = {
48 | name: string;
49 | readonly age: number;
50 | addr?: string;
51 | }
52 |
53 |
54 | /* =============== 定义对象与扩展 =============== */
55 |
56 | type Person2 = {
57 | name: string
58 | }
59 |
60 | // 接口通过继承的方式实现类型扩展:
61 | interface Person3 extends Person2 {
62 | age: number
63 | }
64 |
65 | // 类型别名通过交叉类型的方式实现类型扩展:
66 | type Person4 = Person2 & {
67 | age: number
68 | }
69 |
70 |
71 | type str = string
72 | type num = number
73 | type union = string | number
74 | type tup = [string, number]
75 |
76 |
77 | /* =============== 类型合并 =============== */
78 |
79 | interface Person5 {
80 | name: string
81 | }
82 | interface Person5 {
83 | age: string
84 | }
85 | let person1: Person5 // { name: string; age: string }
86 | type Person6 {
87 | name: string
88 | }
89 | // Error: Duplicate identifier 'Person2'
90 | type Person6 {
91 | age: string
92 | }
93 |
94 |
95 | /* =============== 索引签名问题 =============== */
96 | interface Test1 {
97 | name: string
98 | }
99 | type Test2 = {
100 | name: string
101 | }
102 | const data1: Test1 = { name: 'name1' }
103 | const data2: Test2 = { name: 'name2' }
104 | interface PropType {
105 | [key: string]: string
106 | }
107 | let prop: PropType
108 | prop = data1 // Error: Type 'Test2' is not assignable to type 'PropType'. Index signature for type 'string' is missing in type 'Test2'
109 | prop = data2 // success
110 |
111 |
112 | /* =============== 联合类型 =============== */
113 | const union: string | number = 'text'
114 |
115 | /* =============== 交叉类型 =============== */
116 | interface A {
117 | field1: string
118 | }
119 |
120 | interface B {
121 | field2: number
122 | }
123 |
124 | const test9: A & B = { field1: 'text', field2: 1 };
125 |
126 | /* =============== 类型不存在 =============== */
127 |
128 | type A1 = number
129 | type B1 = string
130 | type Union = A1 & B1 // never
131 |
132 |
133 | /* =============== 同名属性交叉 =============== */
134 |
135 | interface A2 {
136 | field1: string
137 | common: {
138 | fieldA: string
139 | }
140 | }
141 |
142 | interface B2 {
143 | field2: number
144 | common: {
145 | fieldB: number
146 | }
147 | }
148 |
149 | const fields: A2 & B2 = {
150 | field1: 'text1',
151 | field2: 1,
152 | common: { fieldA: 'text2', fieldB: 2 }
153 | }
154 | // success
155 |
156 | /* =============== 鸭子类型 =============== */
157 |
158 | interface Param {
159 | field1: string
160 | }
161 |
162 | const func = (param: Param) => param
163 | func({ field1: '111', field2: 2 }) // Error
164 |
165 | const param1 = { field1: '111', field2: 2 }
166 | func(param1); // success
167 |
168 |
169 | /* =============== 类型断言 =============== */
170 |
171 |
172 | interface Param {
173 | field1: string
174 | }
175 |
176 | const func1 = (param: Param) => param
177 | func1({ field1: '111', field2: 2 } as Param) // success
178 |
179 |
180 |
181 | const func2 = (str: string) => str
182 | const param = ['text1', 'text2'].find(str => str === 'text1')
183 | func2(param) // Error
184 | func2(param!) // success
185 |
--------------------------------------------------------------------------------
/promise/src/promise4.js:
--------------------------------------------------------------------------------
1 | // 完整版 promise
2 | // 实现 promise/A+ 规范
3 |
4 | const STATE = {
5 | PENDING: 'pending',
6 | FULFILLED: 'fulfilled',
7 | REJECTED: 'rejected'
8 | }
9 |
10 | const generatePromise = (promise2, x, fulfill, reject) => {
11 | if (promise2 === x) {
12 | return reject(new TypeError('Chaining cycle detected for promise'))
13 | }
14 | // 如果 x 是 promise,调用它的 then 方法继续遍历
15 | if (x instanceof MyPromise) {
16 | x.then((value) => {
17 | generatePromise(promise2, value, fulfill, reject)
18 | }, (e) => {
19 | reject(e)
20 | })
21 | } else if (x != null && (typeof x === 'object' || typeof x === 'function')) {
22 | // 防止重复调用,成功和失败只能调用一次
23 | let called;
24 | // 如果 x 是对象或函数
25 | try {
26 | const then = x.then
27 | if (typeof then === 'function') {
28 | then.call(x, (y) => {
29 | if (called) return;
30 | called = true;
31 | // 说明 y是 promise,继续遍历
32 | generatePromise(promise2, y, fulfill, reject)
33 | }, (r) => {
34 | if (called) return;
35 | called = true;
36 | reject(r)
37 | })
38 | } else {
39 | fulfill(x)
40 | }
41 | } catch(e) {
42 | if (called) return
43 | called = true
44 | reject(e)
45 | }
46 | } else {
47 | fulfill(x)
48 | }
49 | }
50 |
51 | class MyPromise {
52 | constructor(fn) {
53 | // 初始化
54 | this.state = STATE.PENDING
55 | this.value = null
56 | this.reason = null
57 | // 保存数组
58 | this.fulfilledCallbacks = []
59 | this.rejectedCallbacks = []
60 | // 成功
61 | const fulfill = (value) => {
62 | // 只有 state 为 pending 时,才可以更改状态
63 | if (this.state === STATE.PENDING) {
64 | this.state = STATE.FULFILLED
65 | this.value = value
66 | this.fulfilledCallbacks.forEach(cb => cb())
67 | }
68 | }
69 |
70 | // 失败
71 | const reject = (reason) => {
72 | if (this.state === STATE.PENDING) {
73 | this.state = STATE.REJECTED
74 | this.reason = reason
75 | this.rejectedCallbacks.forEach(cb => cb())
76 | }
77 | }
78 | // 执行函数出错时调用 reject
79 | try {
80 | fn(fulfill, reject)
81 | } catch (e) {
82 | reject(e)
83 | }
84 | }
85 |
86 | then(onFulfilled, onRejected) {
87 | // Promises/A+ 规范规定:
88 | // 如果 onFulfilled 不是函数且 promise1 成功执行, promise2 必须成功执行并返回相同的值
89 | // 如果 onRejected 不是函数且 promise1 拒绝执行, promise2 必须拒绝执行并返回相同的拒因
90 | onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
91 | onRejected = typeof onRejected === 'function' ? onRejected : e => { throw e }
92 | const promise2 = new MyPromise((fulfill, reject) => {
93 | // setTimeout 宏任务,确保onFulfilled 和 onRejected 异步执行
94 | if (this.state === STATE.FULFILLED) {
95 | setTimeout(() => {
96 | try {
97 | const x = onFulfilled(this.value)
98 | generatePromise(promise2, x, fulfill, reject)
99 | } catch (e) {
100 | reject(e)
101 | }
102 | }, 0)
103 | }
104 | if (this.state === STATE.REJECTED) {
105 | setTimeout(() => {
106 | try {
107 | const x = onRejected(this.reason)
108 | generatePromise(promise2, x, fulfill, reject)
109 | } catch (e) {
110 | reject(e)
111 | }
112 | }, 0)
113 | }
114 | // 当 then 是 pending 时,将这两个状态写入数组中
115 | if (this.state === STATE.PENDING) {
116 | this.fulfilledCallbacks.push(() => {
117 | setTimeout(() => {
118 | try {
119 | const x = onFulfilled(this.value)
120 | generatePromise(promise2, x, fulfill, reject)
121 | } catch(e) {
122 | reject(e)
123 | }
124 | }, 0)
125 | })
126 | this.rejectedCallbacks.push(() => {
127 | setTimeout(() => {
128 | try {
129 | const x = onRejected(this.reason)
130 | generatePromise(promise2, x, fulfill, reject)
131 | } catch (e) {
132 | reject(e)
133 | }
134 | }, 0)
135 | })
136 | }
137 | })
138 | return promise2
139 | }
140 | }
141 |
142 | module.exports = MyPromise
143 |
--------------------------------------------------------------------------------
/typescript/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@cspotcode/source-map-support@^0.8.0":
6 | version "0.8.1"
7 | resolved "http://bnpm.byted.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
8 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
9 | dependencies:
10 | "@jridgewell/trace-mapping" "0.3.9"
11 |
12 | "@jridgewell/resolve-uri@^3.0.3":
13 | version "3.1.0"
14 | resolved "http://bnpm.byted.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
15 | integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
16 |
17 | "@jridgewell/sourcemap-codec@^1.4.10":
18 | version "1.4.14"
19 | resolved "http://bnpm.byted.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
20 | integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
21 |
22 | "@jridgewell/trace-mapping@0.3.9":
23 | version "0.3.9"
24 | resolved "http://bnpm.byted.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
25 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
26 | dependencies:
27 | "@jridgewell/resolve-uri" "^3.0.3"
28 | "@jridgewell/sourcemap-codec" "^1.4.10"
29 |
30 | "@tsconfig/node10@^1.0.7":
31 | version "1.0.9"
32 | resolved "http://bnpm.byted.org/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
33 | integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
34 |
35 | "@tsconfig/node12@^1.0.7":
36 | version "1.0.11"
37 | resolved "http://bnpm.byted.org/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
38 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
39 |
40 | "@tsconfig/node14@^1.0.0":
41 | version "1.0.3"
42 | resolved "http://bnpm.byted.org/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
43 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
44 |
45 | "@tsconfig/node16@^1.0.2":
46 | version "1.0.3"
47 | resolved "http://bnpm.byted.org/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
48 | integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
49 |
50 | acorn-walk@^8.1.1:
51 | version "8.2.0"
52 | resolved "http://bnpm.byted.org/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
53 | integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
54 |
55 | acorn@^8.4.1:
56 | version "8.8.0"
57 | resolved "http://bnpm.byted.org/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
58 | integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
59 |
60 | arg@^4.1.0:
61 | version "4.1.3"
62 | resolved "http://bnpm.byted.org/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
63 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
64 |
65 | create-require@^1.1.0:
66 | version "1.1.1"
67 | resolved "http://bnpm.byted.org/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
68 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
69 |
70 | diff@^4.0.1:
71 | version "4.0.2"
72 | resolved "http://bnpm.byted.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
73 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
74 |
75 | make-error@^1.1.1:
76 | version "1.3.6"
77 | resolved "http://bnpm.byted.org/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
78 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
79 |
80 | ts-node@^10.9.1:
81 | version "10.9.1"
82 | resolved "http://bnpm.byted.org/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
83 | integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
84 | dependencies:
85 | "@cspotcode/source-map-support" "^0.8.0"
86 | "@tsconfig/node10" "^1.0.7"
87 | "@tsconfig/node12" "^1.0.7"
88 | "@tsconfig/node14" "^1.0.0"
89 | "@tsconfig/node16" "^1.0.2"
90 | acorn "^8.4.1"
91 | acorn-walk "^8.1.1"
92 | arg "^4.1.0"
93 | create-require "^1.1.0"
94 | diff "^4.0.1"
95 | make-error "^1.1.1"
96 | v8-compile-cache-lib "^3.0.1"
97 | yn "3.1.1"
98 |
99 | typescript@^4.7.4:
100 | version "4.7.4"
101 | resolved "http://bnpm.byted.org/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
102 | integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
103 |
104 | v8-compile-cache-lib@^3.0.1:
105 | version "3.0.1"
106 | resolved "http://bnpm.byted.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
107 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
108 |
109 | yn@3.1.1:
110 | version "3.1.1"
111 | resolved "http://bnpm.byted.org/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
112 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
113 |
--------------------------------------------------------------------------------
/gulp-demo/src/css/myAlbum.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: "Microsoft Yahei";
5 | }
6 | body,
7 | html {
8 | height: 100%;
9 | }
10 | .page {
11 | width: 100%;
12 | height: 100%;
13 | overflow: hidden;
14 | background-color: #fff;
15 | perspective: 550px;
16 | cursor: move;
17 | }
18 | .page .album {
19 | position: relative;
20 | margin: 0 auto;
21 | margin-top: 40vh;
22 | transform-style: preserve-3d;
23 | text-align: center;
24 | width: 800px;
25 | height: 200px;
26 | animation: closer 3s ease;
27 | transform: translateZ(460px);
28 | }
29 | .page .album .gallery {
30 | width: 100%;
31 | height: 100%;
32 | position: absolute;
33 | left: 0;
34 | top: 0;
35 | backface-visibility: hidden;
36 | display: flex;
37 | }
38 | .page .album .gallery.left {
39 | transform: rotateY(90deg) translateZ(-400px);
40 | }
41 | .page .album .gallery.current {
42 | transform: translateZ(-400px);
43 | }
44 | .page .album .gallery.right {
45 | transform: rotateY(-90deg) translateZ(-400px);
46 | }
47 | .page .album .gallery.back {
48 | transform: rotateY(180deg) translateZ(-400px);
49 | }
50 | .page .album .gallery.change {
51 | background-color: #fff;
52 | animation: color 8s linear infinite;
53 | animation-play-state: paused;
54 | }
55 | .page .album .gallery.change2 {
56 | background-color: #868686;
57 | animation: color2 8s linear infinite;
58 | animation-play-state: paused;
59 | }
60 | .page .album .gallery .photo {
61 | flex: 1;
62 | perspective: 550px;
63 | height: 100%;
64 | transform-style: preserve-3d;
65 | }
66 | .page .album .gallery .photo .main-photo {
67 | width: 40%;
68 | height: 90%;
69 | margin: 0 auto;
70 | margin-top: 10%;
71 | transform-style: preserve-3d;
72 | }
73 | .page .album .gallery .photo .main-photo .top-hold {
74 | width: 4px;
75 | height: 10%;
76 | background-color: #000;
77 | margin: 0 auto;
78 | }
79 | .page .album .gallery .photo .main-photo .main-hold {
80 | width: 100%;
81 | height: 70%;
82 | background-repeat: no-repeat;
83 | background-size: cover;
84 | }
85 | .page .album .gallery .photo .main-photo .bottom-hold {
86 | width: 4px;
87 | height: 25%;
88 | background-color: #000;
89 | margin: 0 auto;
90 | }
91 | .page .album .gallery .photo .main-photo .side-hold {
92 | width: 20px;
93 | height: 40px;
94 | background-color: #000;
95 | margin: 0 auto;
96 | /* transform-style: preserve-3d;
97 | position: relative; */
98 | }
99 | .page .album .gallery .photo .back-photo {
100 | width: 40%;
101 | height: 90%;
102 | margin: 0 auto;
103 | margin-top: 10%;
104 | transform-style: preserve-3d;
105 | }
106 | .page .album .gallery .photo .back-photo .center-back {
107 | width: 100%;
108 | height: 70%;
109 | background-color: #ccc;
110 | }
111 | .page .album .gallery .photo .back-photo .bottom-back {
112 | height: 15%;
113 | width: 8px;
114 | background-color: #ccc;
115 | margin: 0 auto;
116 | }
117 | .page .album .gallery .photo .back-photo .side-back {
118 | height: 35px;
119 | width: 8px;
120 | background-color: #ccc;
121 | margin: 0 auto;
122 | transform-origin: top;
123 | }
124 | .page .album .gallery .photo.left-photo .side-hold {
125 | transform: translateY(-50%) rotateX(90deg) skew(-15deg);
126 | }
127 | .page .album .gallery .photo.left-photo .back-photo {
128 | transform: translateX(35%) translateY(-98%) translateZ(-30px);
129 | }
130 | .page .album .gallery .photo.left-photo .back-photo .side-back {
131 | transform: rotateX(90deg) skew(-43deg);
132 | }
133 | .page .album .gallery .photo.center-photo .side-hold {
134 | transform: translateY(-50%) rotateX(90deg);
135 | }
136 | .page .album .gallery .photo.center-photo .back-photo {
137 | transform: translateZ(-30px) translateY(-98%);
138 | }
139 | .page .album .gallery .photo.center-photo .back-photo .side-back {
140 | transform: rotateX(90deg);
141 | }
142 | .page .album .gallery .photo.right-photo .side-hold {
143 | transform: translateY(-50%) rotateX(90deg) skew(15deg);
144 | }
145 | .page .album .gallery .photo.right-photo .back-photo {
146 | transform: translateX(-35%) translateY(-98%) translateZ(-30px);
147 | }
148 | .page .album .gallery .photo.right-photo .back-photo .side-back {
149 | transform: rotateX(90deg) skew(43deg);
150 | }
151 | .page .album .top,
152 | .page .album .bottom {
153 | position: absolute;
154 | left: 0;
155 | top: 0;
156 | display: flex;
157 | width: 100%;
158 | height: 800px;
159 | perspective: none;
160 | }
161 | .page .album .top .diamonds,
162 | .page .album .bottom .diamonds {
163 | flex: 1;
164 | display: flex;
165 | flex-direction: column;
166 | }
167 | .page .album .top .diamonds .diamond,
168 | .page .album .bottom .diamonds .diamond {
169 | flex: 1;
170 | }
171 | .page .album .top .diamonds .diamond .orange,
172 | .page .album .bottom .diamonds .diamond .orange {
173 | width: 20px;
174 | height: 30px;
175 | margin: 0 auto;
176 | margin-top: 43%;
177 | background-color: #ff8000;
178 | }
179 | .page .album .bottom {
180 | transform: translateY(-180px) rotateX(90deg);
181 | }
182 | .page .album .top {
183 | transform: translateY(-200px) rotateX(90deg) translateZ(220px);
184 | }
185 | @keyframes closer {
186 | 0% {
187 | transform: translateZ(-800px);
188 | }
189 | 100% {
190 | transform: translateZ(460px);
191 | }
192 | }
193 | @keyframes color {
194 | 0% {
195 | background-color: #fff;
196 | }
197 | 50% {
198 | background-color: #868686;
199 | }
200 | 100% {
201 | background-color: #fff;
202 | }
203 | }
204 | @keyframes color2 {
205 | 0% {
206 | background-color: #868686;
207 | }
208 | 50% {
209 | background-color: #fff;
210 | }
211 | 100% {
212 | background-color: #868686;
213 | }
214 | }
215 | @keyframes orange-hide {
216 | 0% {
217 | opacity: 1;
218 | }
219 | 100% {
220 | opacity: 0;
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/gulp-demo/dist/css/public-5c001c53f6.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: "Microsoft Yahei";
5 | }
6 | body,
7 | html {
8 | height: 100%;
9 | }
10 | .page {
11 | width: 100%;
12 | height: 100%;
13 | overflow: hidden;
14 | background-color: #fff;
15 | perspective: 550px;
16 | cursor: move;
17 | }
18 | .page .album {
19 | position: relative;
20 | margin: 0 auto;
21 | margin-top: 40vh;
22 | transform-style: preserve-3d;
23 | text-align: center;
24 | width: 800px;
25 | height: 200px;
26 | animation: closer 3s ease;
27 | transform: translateZ(460px);
28 | }
29 | .page .album .gallery {
30 | width: 100%;
31 | height: 100%;
32 | position: absolute;
33 | left: 0;
34 | top: 0;
35 | backface-visibility: hidden;
36 | display: flex;
37 | }
38 | .page .album .gallery.left {
39 | transform: rotateY(90deg) translateZ(-400px);
40 | }
41 | .page .album .gallery.current {
42 | transform: translateZ(-400px);
43 | }
44 | .page .album .gallery.right {
45 | transform: rotateY(-90deg) translateZ(-400px);
46 | }
47 | .page .album .gallery.back {
48 | transform: rotateY(180deg) translateZ(-400px);
49 | }
50 | .page .album .gallery.change {
51 | background-color: #fff;
52 | animation: color 8s linear infinite;
53 | animation-play-state: paused;
54 | }
55 | .page .album .gallery.change2 {
56 | background-color: #868686;
57 | animation: color2 8s linear infinite;
58 | animation-play-state: paused;
59 | }
60 | .page .album .gallery .photo {
61 | flex: 1;
62 | perspective: 550px;
63 | height: 100%;
64 | transform-style: preserve-3d;
65 | }
66 | .page .album .gallery .photo .main-photo {
67 | width: 40%;
68 | height: 90%;
69 | margin: 0 auto;
70 | margin-top: 10%;
71 | transform-style: preserve-3d;
72 | }
73 | .page .album .gallery .photo .main-photo .top-hold {
74 | width: 4px;
75 | height: 10%;
76 | background-color: #000;
77 | margin: 0 auto;
78 | }
79 | .page .album .gallery .photo .main-photo .main-hold {
80 | width: 100%;
81 | height: 70%;
82 | background-repeat: no-repeat;
83 | background-size: cover;
84 | }
85 | .page .album .gallery .photo .main-photo .bottom-hold {
86 | width: 4px;
87 | height: 25%;
88 | background-color: #000;
89 | margin: 0 auto;
90 | }
91 | .page .album .gallery .photo .main-photo .side-hold {
92 | width: 20px;
93 | height: 40px;
94 | background-color: #000;
95 | margin: 0 auto;
96 | /* transform-style: preserve-3d;
97 | position: relative; */
98 | }
99 | .page .album .gallery .photo .back-photo {
100 | width: 40%;
101 | height: 90%;
102 | margin: 0 auto;
103 | margin-top: 10%;
104 | transform-style: preserve-3d;
105 | }
106 | .page .album .gallery .photo .back-photo .center-back {
107 | width: 100%;
108 | height: 70%;
109 | background-color: #ccc;
110 | }
111 | .page .album .gallery .photo .back-photo .bottom-back {
112 | height: 15%;
113 | width: 8px;
114 | background-color: #ccc;
115 | margin: 0 auto;
116 | }
117 | .page .album .gallery .photo .back-photo .side-back {
118 | height: 35px;
119 | width: 8px;
120 | background-color: #ccc;
121 | margin: 0 auto;
122 | transform-origin: top;
123 | }
124 | .page .album .gallery .photo.left-photo .side-hold {
125 | transform: translateY(-50%) rotateX(90deg) skew(-15deg);
126 | }
127 | .page .album .gallery .photo.left-photo .back-photo {
128 | transform: translateX(35%) translateY(-98%) translateZ(-30px);
129 | }
130 | .page .album .gallery .photo.left-photo .back-photo .side-back {
131 | transform: rotateX(90deg) skew(-43deg);
132 | }
133 | .page .album .gallery .photo.center-photo .side-hold {
134 | transform: translateY(-50%) rotateX(90deg);
135 | }
136 | .page .album .gallery .photo.center-photo .back-photo {
137 | transform: translateZ(-30px) translateY(-98%);
138 | }
139 | .page .album .gallery .photo.center-photo .back-photo .side-back {
140 | transform: rotateX(90deg);
141 | }
142 | .page .album .gallery .photo.right-photo .side-hold {
143 | transform: translateY(-50%) rotateX(90deg) skew(15deg);
144 | }
145 | .page .album .gallery .photo.right-photo .back-photo {
146 | transform: translateX(-35%) translateY(-98%) translateZ(-30px);
147 | }
148 | .page .album .gallery .photo.right-photo .back-photo .side-back {
149 | transform: rotateX(90deg) skew(43deg);
150 | }
151 | .page .album .top,
152 | .page .album .bottom {
153 | position: absolute;
154 | left: 0;
155 | top: 0;
156 | display: flex;
157 | width: 100%;
158 | height: 800px;
159 | perspective: none;
160 | }
161 | .page .album .top .diamonds,
162 | .page .album .bottom .diamonds {
163 | flex: 1;
164 | display: flex;
165 | flex-direction: column;
166 | }
167 | .page .album .top .diamonds .diamond,
168 | .page .album .bottom .diamonds .diamond {
169 | flex: 1;
170 | }
171 | .page .album .top .diamonds .diamond .orange,
172 | .page .album .bottom .diamonds .diamond .orange {
173 | width: 20px;
174 | height: 30px;
175 | margin: 0 auto;
176 | margin-top: 43%;
177 | background-color: #ff8000;
178 | }
179 | .page .album .bottom {
180 | transform: translateY(-180px) rotateX(90deg);
181 | }
182 | .page .album .top {
183 | transform: translateY(-200px) rotateX(90deg) translateZ(220px);
184 | }
185 | @keyframes closer {
186 | 0% {
187 | transform: translateZ(-800px);
188 | }
189 | 100% {
190 | transform: translateZ(460px);
191 | }
192 | }
193 | @keyframes color {
194 | 0% {
195 | background-color: #fff;
196 | }
197 | 50% {
198 | background-color: #868686;
199 | }
200 | 100% {
201 | background-color: #fff;
202 | }
203 | }
204 | @keyframes color2 {
205 | 0% {
206 | background-color: #868686;
207 | }
208 | 50% {
209 | background-color: #fff;
210 | }
211 | 100% {
212 | background-color: #868686;
213 | }
214 | }
215 | @keyframes orange-hide {
216 | 0% {
217 | opacity: 1;
218 | }
219 | 100% {
220 | opacity: 0;
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/promise/src/promise5.js:
--------------------------------------------------------------------------------
1 | // 完整版 promise
2 | // 实现 promise 链式调用、异步执行
3 | // 实现 catch、finally
4 | // 实现 resolve、reject、race、all
5 |
6 | const STATE = {
7 | PENDING: 'pending',
8 | FULFILLED: 'fulfilled',
9 | REJECTED: 'rejected'
10 | }
11 |
12 | class MyPromise {
13 | constructor(fn) {
14 | // 初始化
15 | this.state = STATE.PENDING
16 | this.value = null
17 | this.reason = null
18 | // 保存数组
19 | this.fulfilledCallbacks = []
20 | this.rejectedCallbacks = []
21 | // 成功
22 | const fulfill = (value) => {
23 | // 只有 state 为 pending 时,才可以更改状态
24 | if (this.state === STATE.PENDING) {
25 | this.state = STATE.FULFILLED
26 | this.value = value
27 | this.fulfilledCallbacks.forEach(cb => cb())
28 | }
29 | }
30 |
31 | // 失败
32 | const reject = (reason) => {
33 | if (this.state === STATE.PENDING) {
34 | this.state = STATE.REJECTED
35 | this.reason = reason
36 | this.rejectedCallbacks.forEach(cb => cb())
37 | }
38 | }
39 | // 执行函数出错时调用 reject
40 | try {
41 | fn(fulfill, reject)
42 | } catch (e) {
43 | reject(e)
44 | }
45 | }
46 |
47 | then(onFulfilled, onRejected) {
48 | // Promises/A+ 规范规定:
49 | // 如果 onFulfilled 不是函数且 promise1 成功执行, promise2 必须成功执行并返回相同的值
50 | // 如果 onRejected 不是函数且 promise1 拒绝执行, promise2 必须拒绝执行并返回相同的拒因
51 | onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
52 | onRejected = typeof onRejected === 'function' ? onRejected : e => { throw e }
53 | const promise2 = new MyPromise((fulfill, reject) => {
54 | // setTimeout 宏任务,确保onFulfilled 和 onRejected 异步执行
55 | setTimeout(() => {
56 | if (this.state === STATE.FULFILLED) {
57 | try {
58 | const x = onFulfilled(this.value)
59 | generatePromise(promise2, x, fulfill, reject)
60 | } catch (e) {
61 | reject(e)
62 | }
63 | }
64 | if (this.state === STATE.REJECTED) {
65 | try {
66 | const x = onRejected(this.reason)
67 | generatePromise(promise2, x, fulfill, reject)
68 | } catch (e) {
69 | reject(e)
70 | }
71 | }
72 | // 当 then 是 pending 时,将这两个状态写入数组中
73 | if (this.state === STATE.PENDING) {
74 | this.fulfilledCallbacks.push(() => {
75 | const x = onFulfilled(this.value)
76 | generatePromise(promise2, x, fulfill, reject)
77 | })
78 | this.rejectedCallbacks.push(() => {
79 | try {
80 | const x = onRejected(this.reason)
81 | generatePromise(promise2, x, fulfill, reject)
82 | } catch (e) {
83 | reject(e)
84 | }
85 | })
86 | }
87 | }, 0)
88 | })
89 | return promise2
90 | }
91 | catch(onRejected) {
92 | return this.then(null, onRejected)
93 | }
94 | finally(callback) {
95 | return this.then(callback, callback)
96 | }
97 | }
98 |
99 | function generatePromise(promise2, x, fulfill, reject) {
100 | if (promise2 === x) {
101 | return reject(new TypeError('Chaining cycle detected for promise'))
102 | }
103 | // 如果 x 是 promise,继续遍历
104 | if (x instanceof MyPromise) {
105 | x.then((value) => {
106 | generatePromise(promise2, value, fulfill, reject)
107 | }, (e) => {
108 | reject(e)
109 | })
110 | } else if (x != null && (typeof x === 'object' || typeof x === 'function')) {
111 | // 防止重复调用,成功和失败只能调用一次
112 | let called;
113 | // 如果 x 是对象或函数
114 | try {
115 | const then = x.then
116 | if (typeof then === 'function') {
117 | then.call(x, (y) => {
118 | if (called) return;
119 | called = true;
120 | // 说明 y是 promise,继续遍历
121 | generatePromise(promise2, y, fulfill, reject)
122 | }, (r) => {
123 | if (called) return;
124 | called = true;
125 | reject(r)
126 | })
127 | } else {
128 | fulfill(x)
129 | }
130 | } catch(e) {
131 | if (called) return
132 | called = true
133 | reject(e)
134 | }
135 | } else {
136 | fulfill(x)
137 | }
138 | }
139 |
140 | MyPromise.resolve = (value) => {
141 | // 传入 promise 类型直接返回
142 | if (value instanceof MyPromise) return value
143 | // 传入 thenable 对象时,立即执行 then 方法
144 | if (value !== null && typeof value === 'object') {
145 | const then = value.then
146 | if (then && typeof then === 'function') return new MyPromise(value.then)
147 | }
148 | return new MyPromise((resolve) => {
149 | resolve(value)
150 | })
151 | }
152 |
153 | MyPromise.reject = (reason) => {
154 | // 传入 promise 类型直接返回
155 | if (reason instanceof MyPromise) return reason
156 | return new MyPromise((resolve, reject) => {
157 | reject(reason)
158 | })
159 | }
160 |
161 | MyPromise.race = (promises) => {
162 | return new MyPromise((resolve, reject) => {
163 | // promises 可以不是数组,但必须存在 Iterator 接口,因此采用 for...of 遍历
164 | for(let promise of promises) {
165 | // 如果当前值不是 Promise,通过 resolve 方法转为 promise
166 | if (promise instanceof MyPromise) {
167 | promise.then(resolve, reject)
168 | } else {
169 | MyPromise.resolve(promise).then(resolve, reject)
170 | }
171 | }
172 | })
173 | }
174 |
175 | MyPromise.all = (promises) => {
176 | return new MyPromise((resolve, reject) => {
177 | const arr = []
178 | // 已返回数
179 | let count = 0
180 | // 当前索引
181 | let index = 0
182 | // promises 可以不是数组,但必须存在 Iterator 接口,因此采用 for...of 遍历
183 | for(let promise of promises) {
184 | // 如果当前值不是 Promise,通过 resolve 方法转为 promise
185 | if (!(promise instanceof MyPromise)) {
186 | promise = MyPromise.resolve(promise)
187 | }
188 | // 使用闭包保证异步返回数组顺序
189 | ((i) => {
190 | promise.then((value) => {
191 | arr[i] = value
192 | count += 1
193 | if (count === promises.length || count === promises.size) {
194 | resolve(arr)
195 | }
196 | }, reject)
197 | })(index)
198 | // index 递增
199 | index += 1
200 | }
201 | })
202 | }
203 |
204 | MyPromise.allSettled = (promises) => {
205 | return new MyPromise((resolve, reject) => {
206 | const arr = []
207 | // 已返回数
208 | let count = 0
209 | // 当前索引
210 | let index = 0
211 | // promises 可以不是数组,但必须存在 Iterator 接口,因此采用 for...of 遍历
212 | for(let promise of promises) {
213 | // 如果当前值不是 Promise,通过 resolve 方法转为 promise
214 | if (!(promise instanceof MyPromise)) {
215 | promise = MyPromise.resolve(promise)
216 | }
217 | // 使用闭包保证异步返回数组顺序
218 | ((i) => {
219 | promise.then((value) => {
220 | arr[i] = value
221 | count += 1
222 | if (count === promises.length || count === promises.size) {
223 | resolve(arr)
224 | }
225 | }, (err) => {
226 | arr[i] = err
227 | count += 1
228 | if (count === promises.length || count === promises.size) {
229 | resolve(arr)
230 | }
231 | })
232 | })(index)
233 | // index 递增
234 | index += 1
235 | }
236 | })
237 | }
238 |
239 | module.exports = MyPromise
--------------------------------------------------------------------------------
/gulp-demo/src/less/myAlbum.less:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: "Microsoft Yahei";
5 | }
6 |
7 | body,html {
8 | height: 100%;
9 | }
10 |
11 | .page {
12 | width: 100%;
13 | height: 100%;
14 | overflow: hidden;
15 | background-color: #fff;
16 | perspective: 550px;
17 | cursor: move;
18 | .album {
19 | position: relative;
20 | margin: 0 auto;
21 | margin-top: 40vh;
22 | transform-style: preserve-3d;
23 | text-align: center;
24 | width: 800px;
25 | height: 200px;
26 | animation: closer 3s ease;
27 |
28 | transform: translateZ(460px);
29 | .gallery {
30 | width: 100%;
31 | height: 100%;
32 | position: absolute;
33 | left: 0;
34 | top: 0;
35 | backface-visibility: hidden;
36 | display: flex;
37 | &.left {
38 | transform: rotateY(90deg) translateZ(-400px);
39 | }
40 | &.current {
41 | transform: translateZ(-400px);
42 | }
43 | &.right {
44 | transform: rotateY(-90deg) translateZ(-400px);
45 | }
46 | &.back {
47 | transform: rotateY(180deg) translateZ(-400px);
48 | }
49 | &.change {
50 | background-color: #fff;
51 | animation: color 8s linear infinite;
52 | animation-play-state: paused;
53 | }
54 | &.change2 {
55 | background-color: #868686;
56 | animation: color2 8s linear infinite;
57 | animation-play-state: paused;
58 | }
59 | .photo{
60 | flex: 1;
61 | perspective: 550px;
62 | height: 100%;
63 | transform-style: preserve-3d;
64 |
65 | .main-photo {
66 | width: 40%;
67 | height: 90%;
68 | margin:0 auto;
69 | margin-top: 10%;
70 | transform-style: preserve-3d;
71 | .top-hold {
72 | width: 4px;
73 | height: 10%;
74 | background-color: #000;
75 | margin: 0 auto;
76 | }
77 |
78 | .main-hold {
79 | width: 100%;
80 | height: 70%;
81 | background-repeat: no-repeat;
82 | background-size: cover;
83 | }
84 |
85 | .bottom-hold {
86 | width: 4px;
87 | height: 25%;
88 | background-color: #000;
89 | margin: 0 auto;
90 | }
91 |
92 | .side-hold {
93 | width: 20px;
94 | height: 40px;
95 | background-color: #000;
96 | margin: 0 auto;
97 | /* transform-style: preserve-3d;
98 | position: relative; */
99 | }
100 | }
101 |
102 | .back-photo {
103 | width: 40%;
104 | height: 90%;
105 | margin:0 auto;
106 | margin-top: 10%;
107 | transform-style: preserve-3d;
108 | .center-back {
109 | width: 100%;
110 | height: 70%;
111 | background-color: #ccc;
112 | }
113 |
114 | .bottom-back {
115 | height: 15%;
116 | width: 8px;
117 | background-color: #ccc;
118 | margin: 0 auto;
119 | }
120 |
121 | .side-back {
122 | height: 35px;
123 | width: 8px;
124 | background-color: #ccc;
125 | margin: 0 auto;
126 | transform-origin: top;
127 | }
128 | }
129 |
130 | &.left-photo {
131 | .side-hold {
132 | transform: translateY(-50%) rotateX(90deg) skew(-15deg);
133 | }
134 | .back-photo {
135 | transform: translateX(35%) translateY(-98%) translateZ(-30px);
136 | .side-back {
137 | transform: rotateX(90deg) skew(-43deg);
138 | }
139 | }
140 | }
141 |
142 | &.center-photo {
143 | .side-hold {
144 | transform: translateY(-50%) rotateX(90deg);
145 | }
146 | .back-photo {
147 | transform: translateZ(-30px) translateY(-98%);
148 | .side-back {
149 | transform: rotateX(90deg);
150 | }
151 | }
152 | }
153 |
154 | &.right-photo {
155 | .side-hold {
156 | transform: translateY(-50%) rotateX(90deg) skew(15deg);
157 | }
158 | .back-photo {
159 | transform: translateX(-35%) translateY(-98%) translateZ(-30px);
160 | .side-back {
161 | transform: rotateX(90deg) skew(43deg);
162 | }
163 | }
164 | }
165 | }
166 | }
167 | .top,
168 | .bottom {
169 | position: absolute;
170 | left: 0;
171 | top: 0;
172 | display: flex;
173 | width: 100%;
174 | height: 800px;
175 | perspective: none;
176 | .diamonds {
177 | flex: 1;
178 | display: flex;
179 | flex-direction: column;
180 | .diamond {
181 | flex: 1;
182 | .orange {
183 | width: 20px;
184 | height: 30px;
185 | margin: 0 auto;
186 | margin-top: 43%;
187 | background-color: #ff8000;
188 | }
189 | }
190 | }
191 | }
192 | .bottom {
193 | transform: translateY(-180px) rotateX(90deg);
194 | }
195 |
196 | .top {
197 | transform: translateY(-200px) rotateX(90deg) translateZ(220px);
198 | }
199 | }
200 | }
201 |
202 | @keyframes closer {
203 | 0% {
204 | transform: translateZ(-800px);
205 | }
206 |
207 | 100% {
208 | transform: translateZ(460px);
209 | }
210 | }
211 |
212 | @keyframes color {
213 | 0% {
214 | background-color: #fff;
215 | }
216 |
217 | 50% {
218 | background-color: #868686;
219 | }
220 |
221 | 100% {
222 | background-color: #fff;
223 | }
224 | }
225 |
226 | @keyframes color2 {
227 | 0% {
228 | background-color: #868686;
229 | }
230 |
231 | 50% {
232 | background-color: #fff;
233 | }
234 |
235 | 100% {
236 | background-color: #868686;
237 | }
238 | }
239 |
240 | @keyframes orange-hide {
241 | 0% {
242 | opacity: 1;
243 | }
244 | 100% {
245 | opacity: 0;
246 | }
247 | }
--------------------------------------------------------------------------------
/promise/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "promise",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "commander": {
8 | "version": "2.3.0",
9 | "resolved": "https://registry.npm.taobao.org/commander/download/commander-2.3.0.tgz",
10 | "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=",
11 | "dev": true
12 | },
13 | "debug": {
14 | "version": "2.2.0",
15 | "resolved": "http://registry.npm.taobao.org/debug/download/debug-2.2.0.tgz",
16 | "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
17 | "dev": true,
18 | "requires": {
19 | "ms": "0.7.1"
20 | }
21 | },
22 | "diff": {
23 | "version": "1.4.0",
24 | "resolved": "https://registry.npm.taobao.org/diff/download/diff-1.4.0.tgz?cache=0&sync_timestamp=1578890967183&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff%2Fdownload%2Fdiff-1.4.0.tgz",
25 | "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=",
26 | "dev": true
27 | },
28 | "escape-string-regexp": {
29 | "version": "1.0.2",
30 | "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.2.tgz",
31 | "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=",
32 | "dev": true
33 | },
34 | "formatio": {
35 | "version": "1.1.1",
36 | "resolved": "https://registry.npm.taobao.org/formatio/download/formatio-1.1.1.tgz",
37 | "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=",
38 | "dev": true,
39 | "requires": {
40 | "samsam": "~1.1"
41 | }
42 | },
43 | "glob": {
44 | "version": "3.2.11",
45 | "resolved": "https://registry.npm.taobao.org/glob/download/glob-3.2.11.tgz",
46 | "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
47 | "dev": true,
48 | "requires": {
49 | "inherits": "2",
50 | "minimatch": "0.3"
51 | }
52 | },
53 | "growl": {
54 | "version": "1.9.2",
55 | "resolved": "https://registry.npm.taobao.org/growl/download/growl-1.9.2.tgz",
56 | "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=",
57 | "dev": true
58 | },
59 | "inherits": {
60 | "version": "2.0.4",
61 | "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.4.tgz",
62 | "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=",
63 | "dev": true
64 | },
65 | "is-arguments": {
66 | "version": "1.0.4",
67 | "resolved": "https://registry.npm.taobao.org/is-arguments/download/is-arguments-1.0.4.tgz",
68 | "integrity": "sha1-P6+WbHy6D/Q3+zH2JQCC/PBEjPM=",
69 | "dev": true
70 | },
71 | "is-generator-function": {
72 | "version": "1.0.7",
73 | "resolved": "https://registry.npm.taobao.org/is-generator-function/download/is-generator-function-1.0.7.tgz",
74 | "integrity": "sha1-0hMuUpuwAAp/gHlNS99c1eWBNSI=",
75 | "dev": true
76 | },
77 | "jade": {
78 | "version": "0.26.3",
79 | "resolved": "https://registry.npm.taobao.org/jade/download/jade-0.26.3.tgz",
80 | "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=",
81 | "dev": true,
82 | "requires": {
83 | "commander": "0.6.1",
84 | "mkdirp": "0.3.0"
85 | },
86 | "dependencies": {
87 | "commander": {
88 | "version": "0.6.1",
89 | "resolved": "https://registry.npm.taobao.org/commander/download/commander-0.6.1.tgz",
90 | "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=",
91 | "dev": true
92 | },
93 | "mkdirp": {
94 | "version": "0.3.0",
95 | "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.3.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.3.0.tgz",
96 | "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=",
97 | "dev": true
98 | }
99 | }
100 | },
101 | "lolex": {
102 | "version": "1.3.2",
103 | "resolved": "https://registry.npm.taobao.org/lolex/download/lolex-1.3.2.tgz",
104 | "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=",
105 | "dev": true
106 | },
107 | "lru-cache": {
108 | "version": "2.7.3",
109 | "resolved": "http://registry.npm.taobao.org/lru-cache/download/lru-cache-2.7.3.tgz",
110 | "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
111 | "dev": true
112 | },
113 | "minimatch": {
114 | "version": "0.3.0",
115 | "resolved": "http://registry.npm.taobao.org/minimatch/download/minimatch-0.3.0.tgz",
116 | "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
117 | "dev": true,
118 | "requires": {
119 | "lru-cache": "2",
120 | "sigmund": "~1.0.0"
121 | }
122 | },
123 | "minimist": {
124 | "version": "0.0.8",
125 | "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-0.0.8.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimist%2Fdownload%2Fminimist-0.0.8.tgz",
126 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
127 | "dev": true
128 | },
129 | "mkdirp": {
130 | "version": "0.5.1",
131 | "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.5.1.tgz",
132 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
133 | "dev": true,
134 | "requires": {
135 | "minimist": "0.0.8"
136 | }
137 | },
138 | "mocha": {
139 | "version": "2.5.3",
140 | "resolved": "https://registry.npm.taobao.org/mocha/download/mocha-2.5.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmocha%2Fdownload%2Fmocha-2.5.3.tgz",
141 | "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=",
142 | "dev": true,
143 | "requires": {
144 | "commander": "2.3.0",
145 | "debug": "2.2.0",
146 | "diff": "1.4.0",
147 | "escape-string-regexp": "1.0.2",
148 | "glob": "3.2.11",
149 | "growl": "1.9.2",
150 | "jade": "0.26.3",
151 | "mkdirp": "0.5.1",
152 | "supports-color": "1.2.0",
153 | "to-iso-string": "0.0.2"
154 | }
155 | },
156 | "ms": {
157 | "version": "0.7.1",
158 | "resolved": "https://registry.npm.taobao.org/ms/download/ms-0.7.1.tgz",
159 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
160 | "dev": true
161 | },
162 | "promises-aplus-tests": {
163 | "version": "2.1.2",
164 | "resolved": "https://registry.npm.taobao.org/promises-aplus-tests/download/promises-aplus-tests-2.1.2.tgz",
165 | "integrity": "sha1-drfFY4locghhlpz7zYeVr9J0iFw=",
166 | "dev": true,
167 | "requires": {
168 | "mocha": "^2.5.3",
169 | "sinon": "^1.10.3",
170 | "underscore": "~1.8.3"
171 | }
172 | },
173 | "safe-buffer": {
174 | "version": "5.2.0",
175 | "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.0.tgz?cache=0&sync_timestamp=1562377642757&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafe-buffer%2Fdownload%2Fsafe-buffer-5.2.0.tgz",
176 | "integrity": "sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk=",
177 | "dev": true
178 | },
179 | "samsam": {
180 | "version": "1.1.2",
181 | "resolved": "https://registry.npm.taobao.org/samsam/download/samsam-1.1.2.tgz",
182 | "integrity": "sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc=",
183 | "dev": true
184 | },
185 | "sigmund": {
186 | "version": "1.0.1",
187 | "resolved": "http://registry.npm.taobao.org/sigmund/download/sigmund-1.0.1.tgz",
188 | "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
189 | "dev": true
190 | },
191 | "sinon": {
192 | "version": "1.17.7",
193 | "resolved": "https://registry.npm.taobao.org/sinon/download/sinon-1.17.7.tgz",
194 | "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=",
195 | "dev": true,
196 | "requires": {
197 | "formatio": "1.1.1",
198 | "lolex": "1.3.2",
199 | "samsam": "1.1.2",
200 | "util": ">=0.10.3 <1"
201 | }
202 | },
203 | "supports-color": {
204 | "version": "1.2.0",
205 | "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-1.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-1.2.0.tgz",
206 | "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=",
207 | "dev": true
208 | },
209 | "to-iso-string": {
210 | "version": "0.0.2",
211 | "resolved": "https://registry.npm.taobao.org/to-iso-string/download/to-iso-string-0.0.2.tgz",
212 | "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=",
213 | "dev": true
214 | },
215 | "underscore": {
216 | "version": "1.8.3",
217 | "resolved": "https://registry.npm.taobao.org/underscore/download/underscore-1.8.3.tgz?cache=0&sync_timestamp=1578351586223&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funderscore%2Fdownload%2Funderscore-1.8.3.tgz",
218 | "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=",
219 | "dev": true
220 | },
221 | "util": {
222 | "version": "0.12.2",
223 | "resolved": "https://registry.npm.taobao.org/util/download/util-0.12.2.tgz?cache=0&sync_timestamp=1582534720131&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Futil%2Fdownload%2Futil-0.12.2.tgz",
224 | "integrity": "sha1-VK22NMnnx0hwevK/Wox6tkDLuis=",
225 | "dev": true,
226 | "requires": {
227 | "inherits": "^2.0.3",
228 | "is-arguments": "^1.0.4",
229 | "is-generator-function": "^1.0.7",
230 | "safe-buffer": "^5.1.2"
231 | }
232 | }
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/gulp-demo/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | my 3d album
9 |
10 |
11 |
12 |
13 |
54 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
175 |
176 |
177 |
178 |
189 |
190 |
193 |
194 |
195 |
198 |
199 |
210 |
211 |
212 |
223 |
224 |
227 |
228 |
229 |
232 |
233 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
--------------------------------------------------------------------------------
/gulp-demo/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | my 3d album
11 |
12 |
13 |
14 |
15 |
56 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
177 |
178 |
179 |
180 |
191 |
192 |
195 |
196 |
197 |
200 |
201 |
212 |
213 |
214 |
225 |
226 |
229 |
230 |
231 |
234 |
235 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
--------------------------------------------------------------------------------
/cloneDeep/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clonedeep",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "abab": {
8 | "version": "2.0.1",
9 | "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.1.tgz",
10 | "integrity": "sha512-1zSbbCuoIjafKZ3mblY5ikvAb0ODUbqBnFuUb7f6uLeQhhGJ0vEV4ntmtxKLT2WgXCO94E07BjunsIw1jOMPZw=="
11 | },
12 | "acorn": {
13 | "version": "6.4.2",
14 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
15 | "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ=="
16 | },
17 | "acorn-globals": {
18 | "version": "4.3.4",
19 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
20 | "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
21 | "requires": {
22 | "acorn": "^6.0.1",
23 | "acorn-walk": "^6.0.1"
24 | }
25 | },
26 | "acorn-walk": {
27 | "version": "6.2.0",
28 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
29 | "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA=="
30 | },
31 | "ajv": {
32 | "version": "6.10.2",
33 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
34 | "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
35 | "requires": {
36 | "fast-deep-equal": "^2.0.1",
37 | "fast-json-stable-stringify": "^2.0.0",
38 | "json-schema-traverse": "^0.4.1",
39 | "uri-js": "^4.2.2"
40 | }
41 | },
42 | "array-equal": {
43 | "version": "1.0.0",
44 | "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
45 | "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM="
46 | },
47 | "asn1": {
48 | "version": "0.2.4",
49 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
50 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
51 | "requires": {
52 | "safer-buffer": "~2.1.0"
53 | }
54 | },
55 | "assert-plus": {
56 | "version": "1.0.0",
57 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
58 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
59 | },
60 | "async-limiter": {
61 | "version": "1.0.1",
62 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
63 | "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
64 | },
65 | "asynckit": {
66 | "version": "0.4.0",
67 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
68 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
69 | },
70 | "aws-sign2": {
71 | "version": "0.7.0",
72 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
73 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
74 | },
75 | "aws4": {
76 | "version": "1.8.0",
77 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
78 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
79 | },
80 | "bcrypt-pbkdf": {
81 | "version": "1.0.2",
82 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
83 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
84 | "requires": {
85 | "tweetnacl": "^0.14.3"
86 | }
87 | },
88 | "browser-process-hrtime": {
89 | "version": "0.1.3",
90 | "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz",
91 | "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw=="
92 | },
93 | "caseless": {
94 | "version": "0.12.0",
95 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
96 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
97 | },
98 | "combined-stream": {
99 | "version": "1.0.8",
100 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
101 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
102 | "requires": {
103 | "delayed-stream": "~1.0.0"
104 | }
105 | },
106 | "core-util-is": {
107 | "version": "1.0.2",
108 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
109 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
110 | },
111 | "cssom": {
112 | "version": "0.3.8",
113 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
114 | "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
115 | },
116 | "cssstyle": {
117 | "version": "1.4.0",
118 | "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz",
119 | "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
120 | "requires": {
121 | "cssom": "0.3.x"
122 | }
123 | },
124 | "dashdash": {
125 | "version": "1.14.1",
126 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
127 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
128 | "requires": {
129 | "assert-plus": "^1.0.0"
130 | }
131 | },
132 | "data-urls": {
133 | "version": "1.1.0",
134 | "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
135 | "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
136 | "requires": {
137 | "abab": "^2.0.0",
138 | "whatwg-mimetype": "^2.2.0",
139 | "whatwg-url": "^7.0.0"
140 | }
141 | },
142 | "deep-is": {
143 | "version": "0.1.3",
144 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
145 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
146 | },
147 | "delayed-stream": {
148 | "version": "1.0.0",
149 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
150 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
151 | },
152 | "domexception": {
153 | "version": "1.0.1",
154 | "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
155 | "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
156 | "requires": {
157 | "webidl-conversions": "^4.0.2"
158 | }
159 | },
160 | "ecc-jsbn": {
161 | "version": "0.1.2",
162 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
163 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
164 | "requires": {
165 | "jsbn": "~0.1.0",
166 | "safer-buffer": "^2.1.0"
167 | }
168 | },
169 | "escodegen": {
170 | "version": "1.12.0",
171 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz",
172 | "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==",
173 | "requires": {
174 | "esprima": "^3.1.3",
175 | "estraverse": "^4.2.0",
176 | "esutils": "^2.0.2",
177 | "optionator": "^0.8.1",
178 | "source-map": "~0.6.1"
179 | }
180 | },
181 | "esprima": {
182 | "version": "3.1.3",
183 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
184 | "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
185 | },
186 | "estraverse": {
187 | "version": "4.3.0",
188 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
189 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
190 | },
191 | "esutils": {
192 | "version": "2.0.3",
193 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
194 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
195 | },
196 | "extend": {
197 | "version": "3.0.2",
198 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
199 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
200 | },
201 | "extsprintf": {
202 | "version": "1.3.0",
203 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
204 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
205 | },
206 | "fast-deep-equal": {
207 | "version": "2.0.1",
208 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
209 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
210 | },
211 | "fast-json-stable-stringify": {
212 | "version": "2.0.0",
213 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
214 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
215 | },
216 | "fast-levenshtein": {
217 | "version": "2.0.6",
218 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
219 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
220 | },
221 | "forever-agent": {
222 | "version": "0.6.1",
223 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
224 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
225 | },
226 | "form-data": {
227 | "version": "2.3.3",
228 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
229 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
230 | "requires": {
231 | "asynckit": "^0.4.0",
232 | "combined-stream": "^1.0.6",
233 | "mime-types": "^2.1.12"
234 | }
235 | },
236 | "getpass": {
237 | "version": "0.1.7",
238 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
239 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
240 | "requires": {
241 | "assert-plus": "^1.0.0"
242 | }
243 | },
244 | "har-schema": {
245 | "version": "2.0.0",
246 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
247 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
248 | },
249 | "har-validator": {
250 | "version": "5.1.3",
251 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
252 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
253 | "requires": {
254 | "ajv": "^6.5.5",
255 | "har-schema": "^2.0.0"
256 | }
257 | },
258 | "html-encoding-sniffer": {
259 | "version": "1.0.2",
260 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
261 | "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
262 | "requires": {
263 | "whatwg-encoding": "^1.0.1"
264 | }
265 | },
266 | "http-signature": {
267 | "version": "1.2.0",
268 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
269 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
270 | "requires": {
271 | "assert-plus": "^1.0.0",
272 | "jsprim": "^1.2.2",
273 | "sshpk": "^1.7.0"
274 | }
275 | },
276 | "iconv-lite": {
277 | "version": "0.4.24",
278 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
279 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
280 | "requires": {
281 | "safer-buffer": ">= 2.1.2 < 3"
282 | }
283 | },
284 | "ip-regex": {
285 | "version": "2.1.0",
286 | "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
287 | "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk="
288 | },
289 | "is-typedarray": {
290 | "version": "1.0.0",
291 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
292 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
293 | },
294 | "isstream": {
295 | "version": "0.1.2",
296 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
297 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
298 | },
299 | "jquery": {
300 | "version": "3.5.0",
301 | "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz",
302 | "integrity": "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ=="
303 | },
304 | "jsbn": {
305 | "version": "0.1.1",
306 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
307 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
308 | },
309 | "jsdom": {
310 | "version": "15.1.1",
311 | "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.1.1.tgz",
312 | "integrity": "sha512-cQZRBB33arrDAeCrAEWn1U3SvrvC8XysBua9Oqg1yWrsY/gYcusloJC3RZJXuY5eehSCmws8f2YeliCqGSkrtQ==",
313 | "requires": {
314 | "abab": "^2.0.0",
315 | "acorn": "^6.1.1",
316 | "acorn-globals": "^4.3.2",
317 | "array-equal": "^1.0.0",
318 | "cssom": "^0.3.6",
319 | "cssstyle": "^1.2.2",
320 | "data-urls": "^1.1.0",
321 | "domexception": "^1.0.1",
322 | "escodegen": "^1.11.1",
323 | "html-encoding-sniffer": "^1.0.2",
324 | "nwsapi": "^2.1.4",
325 | "parse5": "5.1.0",
326 | "pn": "^1.1.0",
327 | "request": "^2.88.0",
328 | "request-promise-native": "^1.0.7",
329 | "saxes": "^3.1.9",
330 | "symbol-tree": "^3.2.2",
331 | "tough-cookie": "^3.0.1",
332 | "w3c-hr-time": "^1.0.1",
333 | "w3c-xmlserializer": "^1.1.2",
334 | "webidl-conversions": "^4.0.2",
335 | "whatwg-encoding": "^1.0.5",
336 | "whatwg-mimetype": "^2.3.0",
337 | "whatwg-url": "^7.0.0",
338 | "ws": "^7.0.0",
339 | "xml-name-validator": "^3.0.0"
340 | }
341 | },
342 | "json-schema": {
343 | "version": "0.2.3",
344 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
345 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
346 | },
347 | "json-schema-traverse": {
348 | "version": "0.4.1",
349 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
350 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
351 | },
352 | "json-stringify-safe": {
353 | "version": "5.0.1",
354 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
355 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
356 | },
357 | "jsprim": {
358 | "version": "1.4.1",
359 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
360 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
361 | "requires": {
362 | "assert-plus": "1.0.0",
363 | "extsprintf": "1.3.0",
364 | "json-schema": "0.2.3",
365 | "verror": "1.10.0"
366 | }
367 | },
368 | "levn": {
369 | "version": "0.3.0",
370 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
371 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
372 | "requires": {
373 | "prelude-ls": "~1.1.2",
374 | "type-check": "~0.3.2"
375 | }
376 | },
377 | "loadsh": {
378 | "version": "0.0.4",
379 | "resolved": "https://registry.npmjs.org/loadsh/-/loadsh-0.0.4.tgz",
380 | "integrity": "sha512-U+wLL8InpfRalWrr+0SuhWgGt10M4OyAk6G8xCYo2rwpiHtxZkWiFpjei0vO463ghW8LPCdhqQxXlMy2qicAEw=="
381 | },
382 | "lodash": {
383 | "version": "4.17.19",
384 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
385 | "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
386 | },
387 | "lodash.sortby": {
388 | "version": "4.7.0",
389 | "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
390 | "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
391 | },
392 | "mime-db": {
393 | "version": "1.40.0",
394 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
395 | "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
396 | },
397 | "mime-types": {
398 | "version": "2.1.24",
399 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
400 | "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
401 | "requires": {
402 | "mime-db": "1.40.0"
403 | }
404 | },
405 | "nwsapi": {
406 | "version": "2.1.4",
407 | "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz",
408 | "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw=="
409 | },
410 | "oauth-sign": {
411 | "version": "0.9.0",
412 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
413 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
414 | },
415 | "optionator": {
416 | "version": "0.8.2",
417 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
418 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
419 | "requires": {
420 | "deep-is": "~0.1.3",
421 | "fast-levenshtein": "~2.0.4",
422 | "levn": "~0.3.0",
423 | "prelude-ls": "~1.1.2",
424 | "type-check": "~0.3.2",
425 | "wordwrap": "~1.0.0"
426 | }
427 | },
428 | "parse5": {
429 | "version": "5.1.0",
430 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
431 | "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ=="
432 | },
433 | "performance-now": {
434 | "version": "2.1.0",
435 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
436 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
437 | },
438 | "pn": {
439 | "version": "1.1.0",
440 | "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
441 | "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
442 | },
443 | "prelude-ls": {
444 | "version": "1.1.2",
445 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
446 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
447 | },
448 | "psl": {
449 | "version": "1.4.0",
450 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz",
451 | "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw=="
452 | },
453 | "punycode": {
454 | "version": "2.1.1",
455 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
456 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
457 | },
458 | "qs": {
459 | "version": "6.5.2",
460 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
461 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
462 | },
463 | "request": {
464 | "version": "2.88.0",
465 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
466 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
467 | "requires": {
468 | "aws-sign2": "~0.7.0",
469 | "aws4": "^1.8.0",
470 | "caseless": "~0.12.0",
471 | "combined-stream": "~1.0.6",
472 | "extend": "~3.0.2",
473 | "forever-agent": "~0.6.1",
474 | "form-data": "~2.3.2",
475 | "har-validator": "~5.1.0",
476 | "http-signature": "~1.2.0",
477 | "is-typedarray": "~1.0.0",
478 | "isstream": "~0.1.2",
479 | "json-stringify-safe": "~5.0.1",
480 | "mime-types": "~2.1.19",
481 | "oauth-sign": "~0.9.0",
482 | "performance-now": "^2.1.0",
483 | "qs": "~6.5.2",
484 | "safe-buffer": "^5.1.2",
485 | "tough-cookie": "~2.4.3",
486 | "tunnel-agent": "^0.6.0",
487 | "uuid": "^3.3.2"
488 | },
489 | "dependencies": {
490 | "punycode": {
491 | "version": "1.4.1",
492 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
493 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
494 | },
495 | "tough-cookie": {
496 | "version": "2.4.3",
497 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
498 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
499 | "requires": {
500 | "psl": "^1.1.24",
501 | "punycode": "^1.4.1"
502 | }
503 | }
504 | }
505 | },
506 | "request-promise-core": {
507 | "version": "1.1.2",
508 | "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
509 | "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
510 | "requires": {
511 | "lodash": "^4.17.11"
512 | }
513 | },
514 | "request-promise-native": {
515 | "version": "1.0.7",
516 | "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz",
517 | "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==",
518 | "requires": {
519 | "request-promise-core": "1.1.2",
520 | "stealthy-require": "^1.1.1",
521 | "tough-cookie": "^2.3.3"
522 | },
523 | "dependencies": {
524 | "tough-cookie": {
525 | "version": "2.5.0",
526 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
527 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
528 | "requires": {
529 | "psl": "^1.1.28",
530 | "punycode": "^2.1.1"
531 | }
532 | }
533 | }
534 | },
535 | "safe-buffer": {
536 | "version": "5.2.0",
537 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
538 | "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
539 | },
540 | "safer-buffer": {
541 | "version": "2.1.2",
542 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
543 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
544 | },
545 | "saxes": {
546 | "version": "3.1.11",
547 | "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz",
548 | "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
549 | "requires": {
550 | "xmlchars": "^2.1.1"
551 | }
552 | },
553 | "source-map": {
554 | "version": "0.6.1",
555 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
556 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
557 | "optional": true
558 | },
559 | "sshpk": {
560 | "version": "1.16.1",
561 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
562 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
563 | "requires": {
564 | "asn1": "~0.2.3",
565 | "assert-plus": "^1.0.0",
566 | "bcrypt-pbkdf": "^1.0.0",
567 | "dashdash": "^1.12.0",
568 | "ecc-jsbn": "~0.1.1",
569 | "getpass": "^0.1.1",
570 | "jsbn": "~0.1.0",
571 | "safer-buffer": "^2.0.2",
572 | "tweetnacl": "~0.14.0"
573 | }
574 | },
575 | "stealthy-require": {
576 | "version": "1.1.1",
577 | "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
578 | "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
579 | },
580 | "symbol-tree": {
581 | "version": "3.2.4",
582 | "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
583 | "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
584 | },
585 | "tough-cookie": {
586 | "version": "3.0.1",
587 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
588 | "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
589 | "requires": {
590 | "ip-regex": "^2.1.0",
591 | "psl": "^1.1.28",
592 | "punycode": "^2.1.1"
593 | }
594 | },
595 | "tr46": {
596 | "version": "1.0.1",
597 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
598 | "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
599 | "requires": {
600 | "punycode": "^2.1.0"
601 | }
602 | },
603 | "tunnel-agent": {
604 | "version": "0.6.0",
605 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
606 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
607 | "requires": {
608 | "safe-buffer": "^5.0.1"
609 | }
610 | },
611 | "tweetnacl": {
612 | "version": "0.14.5",
613 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
614 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
615 | },
616 | "type-check": {
617 | "version": "0.3.2",
618 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
619 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
620 | "requires": {
621 | "prelude-ls": "~1.1.2"
622 | }
623 | },
624 | "uri-js": {
625 | "version": "4.2.2",
626 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
627 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
628 | "requires": {
629 | "punycode": "^2.1.0"
630 | }
631 | },
632 | "uuid": {
633 | "version": "3.3.3",
634 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
635 | "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
636 | },
637 | "verror": {
638 | "version": "1.10.0",
639 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
640 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
641 | "requires": {
642 | "assert-plus": "^1.0.0",
643 | "core-util-is": "1.0.2",
644 | "extsprintf": "^1.2.0"
645 | }
646 | },
647 | "w3c-hr-time": {
648 | "version": "1.0.1",
649 | "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
650 | "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
651 | "requires": {
652 | "browser-process-hrtime": "^0.1.2"
653 | }
654 | },
655 | "w3c-xmlserializer": {
656 | "version": "1.1.2",
657 | "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz",
658 | "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
659 | "requires": {
660 | "domexception": "^1.0.1",
661 | "webidl-conversions": "^4.0.2",
662 | "xml-name-validator": "^3.0.0"
663 | }
664 | },
665 | "webidl-conversions": {
666 | "version": "4.0.2",
667 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
668 | "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
669 | },
670 | "whatwg-encoding": {
671 | "version": "1.0.5",
672 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
673 | "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
674 | "requires": {
675 | "iconv-lite": "0.4.24"
676 | }
677 | },
678 | "whatwg-mimetype": {
679 | "version": "2.3.0",
680 | "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
681 | "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g=="
682 | },
683 | "whatwg-url": {
684 | "version": "7.0.0",
685 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz",
686 | "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==",
687 | "requires": {
688 | "lodash.sortby": "^4.7.0",
689 | "tr46": "^1.0.1",
690 | "webidl-conversions": "^4.0.2"
691 | }
692 | },
693 | "wordwrap": {
694 | "version": "1.0.0",
695 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
696 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
697 | },
698 | "ws": {
699 | "version": "7.1.2",
700 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.1.2.tgz",
701 | "integrity": "sha512-gftXq3XI81cJCgkUiAVixA0raD9IVmXqsylCrjRygw4+UOOGzPoxnQ6r/CnVL9i+mDncJo94tSkyrtuuQVBmrg==",
702 | "requires": {
703 | "async-limiter": "^1.0.0"
704 | }
705 | },
706 | "xml-name-validator": {
707 | "version": "3.0.0",
708 | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
709 | "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
710 | },
711 | "xmlchars": {
712 | "version": "2.2.0",
713 | "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
714 | "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
715 | }
716 | }
717 | }
718 |
--------------------------------------------------------------------------------