├── .babelrc ├── .eslintrc ├── .gitignore ├── .npmignore ├── README.md ├── __tests__ ├── basicProxyBehaviorTest.js ├── createMakeProxyFunctionTest.js ├── generateReduxReportTest.js └── trackObjectUseTest.js ├── images ├── breakpoint.gif └── redux-usage.gif ├── package.json ├── src ├── generateReduxReport.js ├── index.js ├── lib │ └── browser-source-map-support.js ├── monitor │ ├── Info.js │ ├── ReduxTree.js │ ├── index.js │ └── theme.js ├── saveReport.js ├── trackObjectUse.js └── utility.js ├── todomvc-example ├── .gitignore ├── README.md ├── config │ ├── env.js │ ├── jest │ │ ├── cssTransform.js │ │ └── fileTransform.js │ ├── paths.js │ ├── polyfills.js │ ├── webpack.config.dev.js │ ├── webpack.config.prod.js │ └── webpackDevServer.config.js ├── package-lock.json ├── package.json ├── public │ └── index.html ├── scripts │ ├── build.js │ └── start.js ├── src │ ├── actions │ │ └── index.js │ ├── components │ │ ├── Footer.js │ │ ├── Header.js │ │ ├── MainSection.js │ │ ├── TodoItem.js │ │ └── TodoTextInput.js │ ├── constants │ │ ├── ActionTypes.js │ │ └── TodoFilters.js │ ├── containers │ │ ├── App.js │ │ └── DevTools.js │ ├── index.js │ └── reducers │ │ ├── demoArray.js │ │ ├── index.js │ │ └── todos.js └── yarn.lock └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env", "react"], 3 | "plugins": ["transform-class-properties", "transform-object-rest-spread", "transform-runtime"] 4 | } 5 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "react-app" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | 4 | .yarn-integrity 5 | 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | 11 | redux_report--unused.json 12 | redux_report--used.json 13 | 14 | .cache 15 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | todomvc-example 3 | node_modules 4 | .babelrc 5 | .vscode 6 | .cache 7 | .yarn-error.log 8 | __tests__ 9 | .eslintrc 10 | images 11 | 12 | redux_report--unused.json 13 | redux_report--used.json 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Redux Usage Report 2 | 3 | This library tracks the way your app is actually using the data in your Redux store. By setting up the monitor in devtools you can see a live view of when different parts of your store are accessed: 4 | 5 | ![Redux usage monitor in action](./images/redux-usage.gif) 6 | 7 | To find out exactly when a certain value is being accessed, you can [set a breakpoint](#set-a-breakpoint) to explore the call stack when the app touches that particular value. 8 | 9 | You can also use `redux-usage-report` as a performance tool to [find unnecessarily fetched data in your app.](#find-unused-data) 10 | 11 | 12 | ## Demo 13 | [Try it out on the TodoMVC app here.](https://elite-orange.surge.sh/?debug_session=test) 14 | 15 | ## Quickstart 16 | 17 | 18 | ### 1. Install the required libs 19 | 20 | ```js 21 | yarn add redux-usage-report redux-devtools redux-devtools-dock-monitor 22 | ``` 23 | 24 | ### 2. Create the DevTools component 25 | 26 | Create a file called `DevTools.js` (or whatever you'd like to call it) and paste the following code in: 27 | ```js 28 | import React from "react"; 29 | import { createDevTools } from "redux-devtools"; 30 | import DockMonitor from "redux-devtools-dock-monitor"; 31 | import { UsageMonitor } from "redux-usage-report"; 32 | 33 | export default createDevTools( 34 | 39 | 40 | 41 | ); 42 | 43 | ``` 44 | 45 | ### 3. Add the `generateReduxReport` and the `DevTools.instrument` store enhancers to your store: 46 | 47 | *Make sure to put the `DevTools.instrument()` call last in the order of composed functions.* 48 | 49 | Your code might look something like this: 50 | 51 | `configureStore.js` 52 | ```js 53 | import { createStore, applyMiddleware, compose } from "redux" 54 | import thunk from 'redux-thunk' 55 | import generateReduxReport from "redux-usage-report" 56 | 57 | import rootReducer from "./reducers" 58 | import DevTools from './DevTools'; 59 | 60 | const enhancer = compose( 61 | applyMiddleware(thunk), 62 | generateReduxReport(), 63 | // DevTools.instrument() must go last 64 | DevTools.instrument() 65 | ) 66 | 67 | const store = createStore(rootReducer, initialState, enhancer) 68 | ``` 69 | 70 | ### 3. Render `` into the app 71 | 72 | The easiest way to do this is just render the `` component in your App component. 73 | 74 | [Read more about setting up redux devtools in the official documentation.](https://github.com/gaearon/redux-devtools/blob/master/docs/Walkthrough.md) 75 | 76 | Please make sure to [only include the devtools for your development build!](https://github.com/gaearon/redux-devtools/blob/master/docs/Walkthrough.md#exclude-devtools-from-production-builds) 77 | 78 | 79 | ### 4. Temporarily disable the Redux Devtools browser extension 80 | For the in-app `Redux Devtools` monitor to work, your `Redux DevTools` browser extension must be disabled (otherwise there are 2 copies trying to run at the same time). 81 | 82 | ## How to use it 83 | 84 | The json view of your store will show the parts that have been not accessed at reduced opacity, as well as an estimate of the total percentage of your store that has been used so far by your app. (The percentage is calculated by comparing the string length of the `json` comprising the used portion of the store, with the `json` string containing the entire store.) 85 | 86 | ## Set a breakpoint 87 | 88 | You can set a breakpoint by doing `shift + click` on any key in the json view. The next time the key is accessed, the debugger will stop execution. Feel free to reload the page, the breakpoint will persist until you remove it by holding `shift` and clicking it again. 89 | 90 | ![Setting a breakpoint](./images/breakpoint.gif) 91 | 92 | 93 | ## Find unused data 94 | 95 | *Note: This works best in Chrome.* 96 | 97 | Load the monitor in the app as described above, and visit all pages you want to test. Make sure to perform any required UI interactions to trigger data fetching or data usage. Then, open your browser console and type 98 | 99 | ```js 100 | copy(reduxReport.generate().unused) 101 | ``` 102 | 103 | You can now paste that `JSON` object into a file to see which parts of your redux store have remained completely untouched. You might be able to get rid of some data fetching entirely, or simply be more thoughtful about when data is fetched, in order to speed up your app. 104 | 105 | 106 | 107 | ## How it works 108 | 109 | The `generateReduxReport` enhancer wraps the store in a proxy, so that each object access can be tracked. 110 | 111 | It tries to be smart about ignoring object accesses that come from outside your app's code. For instance, if you're also using the `persistStore` Devtools plugin, even though that plugin accesses every key in your store, you shouldn't see that reflected in the Usage Report monitor. The monitor attempts to filter out object access that originates in any module located in the `node_modules` folder or from a browser extension. This filtering logic only works in Chrome, or failing that, if you are using something like the [eval option](https://webpack.js.org/configuration/devtool/#development) or some other lightweight type of source map that preserves file pathnames in stacktraces. 112 | 113 | If you are curious as to why a value is marked "accessed", you can always `shift + click` the relevant key in the monitor to set a breakpoint. 114 | 115 | ## Performance 116 | If you notice any performance issues, (you probably will in an app with a larger redux store) you can speed things up by turning off the most expensive check (whether to ignore object access that originates from `node_modules`) by typing in the console: 117 | ``` 118 | reduxReport.__skipAccessOriginCheck = true 119 | ``` 120 | -------------------------------------------------------------------------------- /__tests__/basicProxyBehaviorTest.js: -------------------------------------------------------------------------------- 1 | describe("basic proxy behavior", () => { 2 | it("if a proxied object is proxied again, both proxies will be active, rather than the second proxy simply overriding the first", () => { 3 | const handler1 = { 4 | get(target, propKey) { 5 | return "proxied get" 6 | } 7 | } 8 | 9 | const handler2 = { 10 | get(target, propKey) { 11 | return `${target[propKey]} is wrapped with an outer proxy` 12 | } 13 | } 14 | const proxy = new Proxy({ test: 1 }, handler1) 15 | const wrappedProxy = new Proxy(proxy, handler2) 16 | expect(proxy.test).toBe("proxied get") 17 | expect(wrappedProxy.test).toBe("proxied get is wrapped with an outer proxy") 18 | }) 19 | 20 | it("there can be a special hidden key that just returns the unproxied target to avoid this proxy nesting", () => { 21 | const handler1 = { 22 | get(target, propKey) { 23 | if (propKey === "__initialVal") return target 24 | if (target.__initialVal !== undefined) return target.__initialVal[propKey] 25 | return "proxied get" 26 | } 27 | } 28 | 29 | const handler2 = { 30 | get(target, propKey) { 31 | const value = 32 | target.__initialVal !== undefined ? target.__initialVal[propKey] : target[propKey] 33 | return `${value} is wrapped with an outer proxy` 34 | } 35 | } 36 | const proxy = new Proxy({ test: 1 }, handler1) 37 | const wrappedProxy = new Proxy(proxy, handler2) 38 | expect(proxy.test).toBe("proxied get") 39 | expect(proxy.__initialVal.test).toBe(1) 40 | expect(wrappedProxy.test).toBe("1 is wrapped with an outer proxy") 41 | }) 42 | 43 | it("JSON.parse(JSON.stringify(obj)) will return a non-proxied object from a proxied object, after calling the proxy's get methods", () => { 44 | const handler1 = { 45 | get: jest.fn(function(target, propKey) { 46 | return "proxied get" 47 | }) 48 | } 49 | 50 | const proxy = new Proxy({ test: 1 }, handler1) 51 | const copied = JSON.parse(JSON.stringify(proxy)) 52 | expect(handler1.get.mock.calls.length).toBe(2) 53 | expect(copied.test).toBe("proxied get") 54 | expect(handler1.get.mock.calls.length).toBe(2) 55 | }) 56 | }) 57 | -------------------------------------------------------------------------------- /__tests__/createMakeProxyFunctionTest.js: -------------------------------------------------------------------------------- 1 | import { createMakeProxyFunction, getChildObject, UNPROXIED_OBJ_KEY } from "../src/trackObjectUse" 2 | import { isObjectOrArray } from "../src/utility" 3 | describe("getChildObject", () => { 4 | const testObj = { 5 | a: 1, 6 | b: { 7 | c: { 8 | d: [ 9 | 1, 10 | 2, 11 | { 12 | e: { f: "g" } 13 | } 14 | ] 15 | } 16 | } 17 | } 18 | 19 | it("returns the part of the object indicated by the provided string of keys", () => { 20 | expect(getChildObject(testObj, "b.c.d.2.e")).toEqual({ f: "g" }) 21 | }) 22 | it("returns the object if the key list is empty", () => { 23 | expect(getChildObject(testObj, "")).toEqual(testObj) 24 | }) 25 | }) 26 | 27 | describe("createMakeProxyFunction", () => { 28 | const isProxy = obj => isObjectOrArray(obj[UNPROXIED_OBJ_KEY]) 29 | const isDoubleProxied = obj => 30 | isObjectOrArray(obj[UNPROXIED_OBJ_KEY]) && 31 | isObjectOrArray(obj[UNPROXIED_OBJ_KEY][UNPROXIED_OBJ_KEY]) 32 | 33 | it("returns a function that creates a proxy to track object use", () => { 34 | const accessedProperties = {} 35 | const makeProxy = createMakeProxyFunction({ accessedProperties }) 36 | const object = { a: { b: "c" }, d: [1, 2, 3, 4, 5] } 37 | const proxy = makeProxy(object) 38 | 39 | const test1 = proxy.a.b 40 | const test2 = proxy.d[2] 41 | expect(accessedProperties).toEqual({ 42 | a: { b: "c" }, 43 | d: [undefined, undefined, 3] 44 | }) 45 | }) 46 | 47 | it("will create proxies of child objects when they are accessed", () => { 48 | const accessedProperties = {} 49 | const makeProxy = createMakeProxyFunction({ accessedProperties }) 50 | const object = { a: { b: "c" }, d: [1, 2, 3, 4, 5] } 51 | const proxy = makeProxy(object) 52 | 53 | const test1 = proxy.a.b 54 | 55 | expect(isProxy(proxy.a)).toBe(true) 56 | // the original child is preserved as a non-proxy 57 | expect(isProxy(object.a)).toBe(false) 58 | }) 59 | 60 | it("does not try to proxy non-object or non-array values", () => { 61 | const accessedProperties = {} 62 | const makeProxy = createMakeProxyFunction({ accessedProperties }) 63 | const object = { a: { b: "c" }, d: [1, 2, 3, 4, 5] } 64 | const proxy = makeProxy(object) 65 | 66 | const test1 = proxy.a.b 67 | 68 | expect(isProxy(proxy.a.b)).toBe(false) 69 | }) 70 | 71 | it("updates values in accessed properties if they change and are accessed again", () => { 72 | const accessedProperties = {} 73 | const makeProxy = createMakeProxyFunction({ accessedProperties }) 74 | const object = { a: { b: "c" }, d: [1, 2, 3, 4, 5] } 75 | const proxy = makeProxy(object) 76 | 77 | const test1 = proxy.a.b 78 | expect(accessedProperties).toEqual({ 79 | a: { b: "c" } 80 | }) 81 | 82 | object.a.b = "e" 83 | const test2 = proxy.a.b 84 | expect(accessedProperties).toEqual({ 85 | a: { b: "e" } 86 | }) 87 | }) 88 | 89 | it("will not augment the accessedProperties object if shouldSkipProxy argument returns true", () => { 90 | const accessedProperties = {} 91 | const makeProxy = createMakeProxyFunction({ 92 | accessedProperties, 93 | shouldSkipProxy: () => true 94 | }) 95 | const object = { a: { b: "c" }, d: [1, 2, 3, 4, 5] } 96 | const proxy = makeProxy(object) 97 | 98 | const test1 = proxy.a.b 99 | expect(accessedProperties).toEqual({}) 100 | }) 101 | 102 | it("just returns the value if the key is not on the objects prototype", () => { 103 | const accessedProperties = {} 104 | const makeProxy = createMakeProxyFunction({ accessedProperties }) 105 | const object = { a: { b: "c" }, d: [1, 2, 3, 4, 5] } 106 | const proxy = makeProxy(object) 107 | 108 | const isPrototypeOf = proxy.isPrototypeOf 109 | expect(accessedProperties).toEqual({}) 110 | }) 111 | 112 | it("has a hidden key for accessing the unproxied object from the proxy", () => { 113 | const accessedProperties = {} 114 | const makeProxy = createMakeProxyFunction({ accessedProperties }) 115 | const object = { a: { b: "c" }, d: [1, 2, 3, 4, 5] } 116 | const proxy = makeProxy(object) 117 | 118 | expect(isProxy(proxy)).toBe(true) 119 | expect(isProxy(proxy[UNPROXIED_OBJ_KEY])).toBe(false) 120 | expect(object).toEqual(proxy[UNPROXIED_OBJ_KEY]) 121 | }) 122 | 123 | it("makes sure never to proxy an already-proxied object", () => { 124 | const accessedProperties = {} 125 | const makeProxy = createMakeProxyFunction({ accessedProperties }) 126 | const object = { a: { b: "c" }, d: [1, 2, 3, 4, 5] } 127 | const doubleProxy = makeProxy(makeProxy(object)) 128 | 129 | expect(isProxy(doubleProxy)).toBe(true) 130 | expect(isDoubleProxied(doubleProxy)).toBe(false) 131 | }) 132 | }) 133 | -------------------------------------------------------------------------------- /__tests__/generateReduxReportTest.js: -------------------------------------------------------------------------------- 1 | import { createStore } from 'redux' 2 | import generateReduxReport from '../src/index' 3 | import saveReport from '../src/saveReport' 4 | 5 | // a tiny Redux store for testing 6 | 7 | const rootReducer = (state = {}, action) => { 8 | switch (action.type) { 9 | case 'SET_DATA': 10 | return Object.assign({}, state, action.payload) 11 | default: 12 | return state 13 | } 14 | } 15 | 16 | const getStore = initialState => 17 | createStore(rootReducer, JSON.parse(JSON.stringify(initialState)), generateReduxReport(global)) 18 | 19 | describe('generateReduxReport', () => { 20 | const mockStore = { 21 | a: { 22 | b: { 23 | c: [1, 2, 3, 4] 24 | }, 25 | d: { 26 | e: [1, 2, 3, 4, 5] 27 | } 28 | }, 29 | f: [5, 4, 3, 2, 1], 30 | g: [{ h: 1 }, { i: 2 }, { j: 3 }], 31 | k: {}, 32 | l: 1, 33 | m: 2, 34 | o: 3 35 | } 36 | 37 | it('should track accessed properties', () => { 38 | const store = getStore(mockStore) 39 | 40 | // access some properties 41 | const val1 = store.getState().a.b.c[2] 42 | const val2 = store.getState().f.slice(0, 1) 43 | const val3 = store.getState().a.d 44 | const val4 = store.getState().g[2].j 45 | 46 | const expectedUsed = { 47 | a: { 48 | b: { 49 | c: [null, null, 3] 50 | }, 51 | d: {} 52 | }, 53 | f: [5, null, null, null, null], 54 | g: [ 55 | null, 56 | null, 57 | { 58 | j: 3 59 | } 60 | ] 61 | } 62 | 63 | const expectedUnused = { 64 | k: null, 65 | l: null, 66 | m: null, 67 | o: null, 68 | a: { 69 | b: { 70 | c: { 71 | '0': null, 72 | '1': null, 73 | '3': null 74 | } 75 | }, 76 | d: { 77 | e: null 78 | } 79 | }, 80 | f: { 81 | '1': null, 82 | '2': null, 83 | '3': null, 84 | '4': null 85 | }, 86 | g: { 87 | '0': null, 88 | '1': null 89 | } 90 | } 91 | expect(global.reduxReport.generate().used).toEqual(expectedUsed) 92 | expect(global.reduxReport.generate().unused).toEqual(expectedUnused) 93 | }) 94 | it('should be able to save the report to a file', () => { 95 | saveReport(global) 96 | // I guess just check that saved to a file (?) 97 | }) 98 | }) 99 | -------------------------------------------------------------------------------- /__tests__/trackObjectUseTest.js: -------------------------------------------------------------------------------- 1 | import { trackObjectUse } from '../src/index' 2 | 3 | describe('trackObjectUse', () => { 4 | const obj = { 5 | a: [1, 2, 3, 4], 6 | b: { 7 | c: { d: [1, 2, 3, 4] } 8 | }, 9 | e: [1, 2, 3, 4] 10 | } 11 | it('returns an object with only the parts of the original object that have been accessed', () => { 12 | const toTrack = JSON.parse(JSON.stringify(obj)) 13 | const { trackedObject, accessedProperties } = trackObjectUse(toTrack) 14 | 15 | const test1 = trackedObject.a[2] 16 | const test2 = trackedObject.b.c.d[0] 17 | const test3 = trackedObject.b.c 18 | const test4 = trackedObject.b.c.d[3] 19 | 20 | const expected = { a: [undefined, undefined, 3], b: { c: { d: [1, undefined, undefined, 4] } } } 21 | 22 | expect(accessedProperties).toEqual(expected) 23 | }) 24 | 25 | it('does not contain unaccessed nested properties of accessed parent properties ', () => { 26 | const obj = { 27 | a: [1, 2, 3, 4], 28 | b: { 29 | e: [1, 2, 3, 4], 30 | c: { d: [1, 2, 3, 4] } 31 | } 32 | } 33 | const { trackedObject, accessedProperties } = trackObjectUse(obj) 34 | 35 | const access1 = trackedObject.a[0] 36 | const access2 = trackedObject.b.c.d[2] 37 | 38 | const expected = { a: [1], b: { c: { d: [undefined, undefined, 3] } } } 39 | 40 | expect(accessedProperties).toEqual(expected) 41 | }) 42 | 43 | it('ignores sets, and only tracks gets', () => { 44 | const toTrack = JSON.parse(JSON.stringify(obj)) 45 | const { trackedObject, accessedProperties } = trackObjectUse(toTrack) 46 | 47 | trackedObject.a = 'test' 48 | const test2 = trackedObject.b.c.d[0] 49 | const test3 = trackedObject.b.c 50 | const test4 = trackedObject.b.c.d[3] 51 | 52 | expect(accessedProperties).toEqual({ b: { c: { d: [1, undefined, undefined, 4] } } }) 53 | }) 54 | }) 55 | -------------------------------------------------------------------------------- /images/breakpoint.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aholachek/redux-usage-report/b7f760c52beb760fd87aaa4d0374d4b51d66f349/images/breakpoint.gif -------------------------------------------------------------------------------- /images/redux-usage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aholachek/redux-usage-report/b7f760c52beb760fd87aaa4d0374d4b51d66f349/images/redux-usage.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redux-usage-report", 3 | "version": "1.3.1", 4 | "description": "A Redux devtools monitor focused on your app's usage of the Redux store", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "test": "NODE_ENV=test jest", 8 | "build": "NODE_ENV=production ./node_modules/.bin/babel src -d dist --ignore node_modules,src/lib; cp -r src/lib dist/", 9 | "prepublish": "npm run build" 10 | }, 11 | "author": "Alex Holachek", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/aholachek/redux-usage-report" 15 | }, 16 | "license": "ISC", 17 | "dependencies": { 18 | "deep-object-diff": "^1.0.4", 19 | "lodash.debounce": "^4.0.8", 20 | "lodash.isequal": "^4.5.0", 21 | "prop-types": "^15.6.0", 22 | "react": "^16.2.0", 23 | "react-json-tree": "^0.11.0", 24 | "redux": "^3.7.2", 25 | "stacktrace-js": "^2.0.0", 26 | "styled-components": "^3.1.6" 27 | }, 28 | "devDependencies": { 29 | "babel-cli": "^6.26.0", 30 | "babel-eslint": "^7.2.3", 31 | "babel-jest": "^22.0.3", 32 | "babel-plugin-transform-class-properties": "^6.24.1", 33 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 34 | "babel-plugin-transform-runtime": "^6.23.0", 35 | "babel-preset-env": "^1.6.1", 36 | "babel-preset-react": "^6.24.1", 37 | "babel-runtime": "^6.26.0", 38 | "eslint": "^4.1.1", 39 | "eslint-config-react-app": "^2.1.0", 40 | "eslint-plugin-flowtype": "^2.34.1", 41 | "eslint-plugin-import": "^2.6.0", 42 | "eslint-plugin-jsx-a11y": "^5.1.1", 43 | "eslint-plugin-node": "^5.2.1", 44 | "eslint-plugin-promise": "^3.6.0", 45 | "eslint-plugin-react": "^7.1.0", 46 | "jest": "^22.0.1" 47 | }, 48 | "jest": { 49 | "transform": { 50 | "^.+\\.jsx?$": "babel-jest" 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/generateReduxReport.js: -------------------------------------------------------------------------------- 1 | import { diff } from "deep-object-diff" 2 | import StackTrace from "stacktrace-js" 3 | import { isObjectOrArray } from "./utility" 4 | import { createMakeProxyFunction } from "./trackObjectUse" 5 | import debounce from "lodash.debounce" 6 | 7 | // we need source maps for the stack traces 8 | // or else we won't know whether to ignore object access 9 | // from non-local code (e.g node_modules, browser extensions...) 10 | // this takes the stack trace file name from e.g. 11 | // fileName: "http://localhost:3001/static/js/bundle.js", 12 | // to "http://localhost:3000/Users/alexholachek/Desktop/work/redux-usage-report/todomvc-example/src/containers/App.js 13 | // this raises an error during jest tests so limit to development 14 | if (process.env.NODE_ENV === "development") { 15 | require("./lib/browser-source-map-support") 16 | sourceMapSupport.install() // eslint-disable-line 17 | } 18 | 19 | const localStorageKey = "reduxUsageReportBreakpoints" 20 | 21 | // so that JSON.stringify doesn't remove all undefined fields 22 | function replaceUndefinedWithNull(obj) { 23 | Object.keys(obj).forEach(k => { 24 | const val = obj[k] 25 | if (val === undefined) { 26 | obj[k] = null 27 | } 28 | if (isObjectOrArray(val)) { 29 | replaceUndefinedWithNull(val) 30 | } 31 | }) 32 | } 33 | 34 | let globalObjectCache 35 | 36 | const shouldSkipProxy = () => { 37 | if (global.reduxReport.__inProgress || global.reduxReport.__reducerInProgress) return true 38 | 39 | if (!global.reduxReport.__skipAccessOriginCheck) { 40 | const stackFrames = StackTrace.getSync() 41 | const initiatingFunc = 42 | stackFrames[stackFrames.findIndex(s => s.functionName === "Object.get") + 1] 43 | 44 | const initiatingFuncNotLocal = 45 | !!initiatingFunc && 46 | initiatingFunc.fileName && 47 | (initiatingFunc.fileName.match(/\.\/~\/|\/node_modules\//) || 48 | initiatingFunc.fileName.match(/extension:\/\//)) 49 | 50 | if (!!initiatingFuncNotLocal) return true 51 | } 52 | return false 53 | } 54 | 55 | // this function takes a reducer and returns 56 | // an augmented reducer that tracks redux usage 57 | function generateReduxReport(global, rootReducer) { 58 | globalObjectCache = globalObjectCache || global 59 | global.reduxReport = global.reduxReport || { 60 | accessedState: {}, 61 | state: {}, 62 | setOnChangeCallback(cb) { 63 | global.reduxReport.onChangeCallback = debounce(cb, 10) 64 | }, 65 | removeOnChangeCallback() { 66 | global.reduxReport.onChangeCallback = undefined 67 | }, 68 | setBreakpoint: function(breakpoint) { 69 | if (!global.localStorage) return 70 | global.localStorage.setItem(localStorageKey, breakpoint) 71 | }, 72 | clearBreakpoint: function() { 73 | if (!global.localStorage) return 74 | global.localStorage.setItem(localStorageKey, null) 75 | }, 76 | generate() { 77 | global.reduxReport.__inProgress = true 78 | const used = JSON.parse(JSON.stringify(this.accessedState)) 79 | const stateCopy = JSON.parse(JSON.stringify(this.state)) 80 | const unused = diff(stateCopy, used) 81 | replaceUndefinedWithNull(unused) 82 | const report = { 83 | used, 84 | unused, 85 | stateCopy 86 | } 87 | global.reduxReport.__inProgress = false 88 | return report 89 | } 90 | } 91 | 92 | const makeProxy = createMakeProxyFunction({ 93 | shouldSkipProxy, 94 | accessedProperties: global.reduxReport.accessedState, 95 | getBreakpoint: () => global.localStorage && global.localStorage.getItem(localStorageKey), 96 | onChange: stateLocation => 97 | global.reduxReport.onChangeCallback && global.reduxReport.onChangeCallback(stateLocation) 98 | }) 99 | 100 | // this function replaces the previous root reducer 101 | // it will break if the DevTools.instrument() call came before generateReduxReport 102 | // in the compose order 103 | return (prevState, action) => { 104 | global.reduxReport.__reducerInProgress = true 105 | const state = rootReducer(prevState, action) 106 | const proxiedState = makeProxy(state) 107 | global.reduxReport.__reducerInProgress = false 108 | 109 | global.reduxReport.state = proxiedState 110 | if (global.reduxReport.onChangeCallback) 111 | setTimeout(() => global.reduxReport.onChangeCallback(""), 1) 112 | return proxiedState 113 | } 114 | } 115 | 116 | // "next" is either createStore or a wrapped version from another enhancer 117 | const storeEnhancer = (global = window) => next => (reducer, ...args) => { 118 | const wrappedReducer = generateReduxReport(global, reducer) 119 | const store = next(wrappedReducer, ...args) 120 | return { ...store, replaceReducer: nextReducer => generateReduxReport(global, nextReducer) } 121 | } 122 | 123 | export default storeEnhancer 124 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export { default } from "./generateReduxReport" 2 | export { default as trackObjectUse } from "./trackObjectUse" 3 | export { default as UsageMonitor } from "./monitor" 4 | -------------------------------------------------------------------------------- /src/lib/browser-source-map-support.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Support for source maps in V8 stack traces 3 | * https://github.com/evanw/node-source-map-support 4 | */ 5 | /* 6 | The buffer module from node.js, for the browser. 7 | 8 | @author Feross Aboukhadijeh 9 | license MIT 10 | */ 11 | ;(this.define || 12 | function(N, O) { 13 | this.sourceMapSupport = O() 14 | })("browser-source-map-support", function(N) { 15 | ;(function b(q, v, h) { 16 | function e(d, a) { 17 | if (!v[d]) { 18 | if (!q[d]) { 19 | var l = "function" == typeof require && require 20 | if (!a && l) return l(d, !0) 21 | if (k) return k(d, !0) 22 | throw Error("Cannot find module '" + d + "'") 23 | } 24 | l = v[d] = { exports: {} } 25 | q[d][0].call( 26 | l.exports, 27 | function(a) { 28 | var b = q[d][1][a] 29 | return e(b ? b : a) 30 | }, 31 | l, 32 | l.exports, 33 | b, 34 | q, 35 | v, 36 | h 37 | ) 38 | } 39 | return v[d].exports 40 | } 41 | for (var k = "function" == typeof require && require, n = 0; n < h.length; n++) e(h[n]) 42 | return e 43 | })( 44 | { 45 | 1: [ 46 | function(q, v, h) { 47 | N = q("./source-map-support") 48 | }, 49 | { "./source-map-support": 19 } 50 | ], 51 | 2: [ 52 | function(q, v, h) { 53 | ;(function(b) { 54 | function e(b) { 55 | b = b.charCodeAt(0) 56 | if (43 === b || 45 === b) return 62 57 | if (47 === b || 95 === b) return 63 58 | if (48 > b) return -1 59 | if (58 > b) return b - 48 + 52 60 | if (91 > b) return b - 65 61 | if (123 > b) return b - 97 + 26 62 | } 63 | var k = "undefined" !== typeof Uint8Array ? Uint8Array : Array 64 | b.toByteArray = function(b) { 65 | function d(a) { 66 | u[t++] = a 67 | } 68 | if (0 < b.length % 4) throw Error("Invalid string. Length must be a multiple of 4") 69 | var a = b.length 70 | var l = "=" === b.charAt(a - 2) ? 2 : "=" === b.charAt(a - 1) ? 1 : 0 71 | var u = new k(3 * b.length / 4 - l) 72 | var r = 0 < l ? b.length - 4 : b.length 73 | var t = 0 74 | for (a = 0; a < r; a += 4) { 75 | var z = 76 | (e(b.charAt(a)) << 18) | 77 | (e(b.charAt(a + 1)) << 12) | 78 | (e(b.charAt(a + 2)) << 6) | 79 | e(b.charAt(a + 3)) 80 | d((z & 16711680) >> 16) 81 | d((z & 65280) >> 8) 82 | d(z & 255) 83 | } 84 | 2 === l 85 | ? ((z = (e(b.charAt(a)) << 2) | (e(b.charAt(a + 1)) >> 4)), d(z & 255)) 86 | : 1 === l && 87 | ((z = 88 | (e(b.charAt(a)) << 10) | (e(b.charAt(a + 1)) << 4) | (e(b.charAt(a + 2)) >> 2)), 89 | d((z >> 8) & 255), 90 | d(z & 255)) 91 | return u 92 | } 93 | b.fromByteArray = function(b) { 94 | var d = b.length % 3, 95 | a = "", 96 | l 97 | var e = 0 98 | for (l = b.length - d; e < l; e += 3) { 99 | var r = (b[e] << 16) + (b[e + 1] << 8) + b[e + 2] 100 | r = 101 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( 102 | (r >> 18) & 63 103 | ) + 104 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( 105 | (r >> 12) & 63 106 | ) + 107 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( 108 | (r >> 6) & 63 109 | ) + 110 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r & 63) 111 | a += r 112 | } 113 | switch (d) { 114 | case 1: 115 | r = b[b.length - 1] 116 | a += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( 117 | r >> 2 118 | ) 119 | a += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( 120 | (r << 4) & 63 121 | ) 122 | a += "==" 123 | break 124 | case 2: 125 | ;(r = (b[b.length - 2] << 8) + b[b.length - 1]), 126 | (a += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( 127 | r >> 10 128 | )), 129 | (a += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( 130 | (r >> 4) & 63 131 | )), 132 | (a += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt( 133 | (r << 2) & 63 134 | )), 135 | (a += "=") 136 | } 137 | return a 138 | } 139 | })("undefined" === typeof h ? (this.base64js = {}) : h) 140 | }, 141 | {} 142 | ], 143 | 3: [function(q, v, h) {}, {}], 144 | 4: [ 145 | function(q, v, h) { 146 | function b(f, g, w) { 147 | if (!(this instanceof b)) return new b(f, g, w) 148 | var a = typeof f 149 | if ("base64" === g && "string" === a) 150 | for (f = f.trim ? f.trim() : f.replace(/^\s+|\s+$/g, ""); 0 !== f.length % 4; ) 151 | f += "=" 152 | if ("number" === a) var c = D(f) 153 | else if ("string" === a) c = b.byteLength(f, g) 154 | else if ("object" === a) c = D(f.length) 155 | else throw Error("First argument needs to be a number, array or string.") 156 | if (b._useTypedArrays) var d = b._augment(new Uint8Array(c)) 157 | else (d = this), (d.length = c), (d._isBuffer = !0) 158 | if (b._useTypedArrays && "number" === typeof f.byteLength) d._set(f) 159 | else { 160 | var m = f 161 | if ( 162 | M(m) || 163 | b.isBuffer(m) || 164 | (m && "object" === typeof m && "number" === typeof m.length) 165 | ) 166 | for (g = 0; g < c; g++) b.isBuffer(f) ? (d[g] = f.readUInt8(g)) : (d[g] = f[g]) 167 | else if ("string" === a) d.write(f, 0, g) 168 | else if ("number" === a && !b._useTypedArrays && !w) for (g = 0; g < c; g++) d[g] = 0 169 | } 170 | return d 171 | } 172 | function e(f, g, w) { 173 | var a = "" 174 | for (w = Math.min(f.length, w); g < w; g++) a += String.fromCharCode(f[g]) 175 | return a 176 | } 177 | function k(f, g, w, a) { 178 | a || 179 | (p("boolean" === typeof w, "missing or invalid endian"), 180 | p(void 0 !== g && null !== g, "missing offset"), 181 | p(g + 1 < f.length, "Trying to read beyond buffer length")) 182 | a = f.length 183 | if (!(g >= a)) 184 | return ( 185 | w 186 | ? ((w = f[g]), g + 1 < a && (w |= f[g + 1] << 8)) 187 | : ((w = f[g] << 8), g + 1 < a && (w |= f[g + 1])), 188 | w 189 | ) 190 | } 191 | function n(f, g, a, c) { 192 | c || 193 | (p("boolean" === typeof a, "missing or invalid endian"), 194 | p(void 0 !== g && null !== g, "missing offset"), 195 | p(g + 3 < f.length, "Trying to read beyond buffer length")) 196 | c = f.length 197 | if (!(g >= c)) { 198 | var w 199 | a 200 | ? (g + 2 < c && (w = f[g + 2] << 16), 201 | g + 1 < c && (w |= f[g + 1] << 8), 202 | (w |= f[g]), 203 | g + 3 < c && (w += (f[g + 3] << 24) >>> 0)) 204 | : (g + 1 < c && (w = f[g + 1] << 16), 205 | g + 2 < c && (w |= f[g + 2] << 8), 206 | g + 3 < c && (w |= f[g + 3]), 207 | (w += (f[g] << 24) >>> 0)) 208 | return w 209 | } 210 | } 211 | function d(f, g, w, a) { 212 | a || 213 | (p("boolean" === typeof w, "missing or invalid endian"), 214 | p(void 0 !== g && null !== g, "missing offset"), 215 | p(g + 1 < f.length, "Trying to read beyond buffer length")) 216 | if (!(g >= f.length)) return (f = k(f, g, w, !0)), f & 32768 ? -1 * (65535 - f + 1) : f 217 | } 218 | function a(f, g, w, a) { 219 | a || 220 | (p("boolean" === typeof w, "missing or invalid endian"), 221 | p(void 0 !== g && null !== g, "missing offset"), 222 | p(g + 3 < f.length, "Trying to read beyond buffer length")) 223 | if (!(g >= f.length)) 224 | return (f = n(f, g, w, !0)), f & 2147483648 ? -1 * (4294967295 - f + 1) : f 225 | } 226 | function l(f, g, a, c) { 227 | c || 228 | (p("boolean" === typeof a, "missing or invalid endian"), 229 | p(g + 3 < f.length, "Trying to read beyond buffer length")) 230 | return I.read(f, g, a, 23, 4) 231 | } 232 | function u(f, g, a, c) { 233 | c || 234 | (p("boolean" === typeof a, "missing or invalid endian"), 235 | p(g + 7 < f.length, "Trying to read beyond buffer length")) 236 | return I.read(f, g, a, 52, 8) 237 | } 238 | function r(f, g, a, c, b) { 239 | b || 240 | (p(void 0 !== g && null !== g, "missing value"), 241 | p("boolean" === typeof c, "missing or invalid endian"), 242 | p(void 0 !== a && null !== a, "missing offset"), 243 | p(a + 1 < f.length, "trying to write beyond buffer length"), 244 | H(g, 65535)) 245 | var w = f.length 246 | if (!(a >= w)) 247 | for (b = 0, w = Math.min(w - a, 2); b < w; b++) 248 | f[a + b] = (g & (255 << (8 * (c ? b : 1 - b)))) >>> (8 * (c ? b : 1 - b)) 249 | } 250 | function t(f, g, a, c, b) { 251 | b || 252 | (p(void 0 !== g && null !== g, "missing value"), 253 | p("boolean" === typeof c, "missing or invalid endian"), 254 | p(void 0 !== a && null !== a, "missing offset"), 255 | p(a + 3 < f.length, "trying to write beyond buffer length"), 256 | H(g, 4294967295)) 257 | var w = f.length 258 | if (!(a >= w)) 259 | for (b = 0, w = Math.min(w - a, 4); b < w; b++) 260 | f[a + b] = (g >>> (8 * (c ? b : 3 - b))) & 255 261 | } 262 | function z(f, g, a, c, b) { 263 | b || 264 | (p(void 0 !== g && null !== g, "missing value"), 265 | p("boolean" === typeof c, "missing or invalid endian"), 266 | p(void 0 !== a && null !== a, "missing offset"), 267 | p(a + 1 < f.length, "Trying to write beyond buffer length"), 268 | A(g, 32767, -32768)) 269 | a >= f.length || (0 <= g ? r(f, g, a, c, b) : r(f, 65535 + g + 1, a, c, b)) 270 | } 271 | function c(f, g, a, c, b) { 272 | b || 273 | (p(void 0 !== g && null !== g, "missing value"), 274 | p("boolean" === typeof c, "missing or invalid endian"), 275 | p(void 0 !== a && null !== a, "missing offset"), 276 | p(a + 3 < f.length, "Trying to write beyond buffer length"), 277 | A(g, 2147483647, -2147483648)) 278 | a >= f.length || (0 <= g ? t(f, g, a, c, b) : t(f, 4294967295 + g + 1, a, c, b)) 279 | } 280 | function m(f, g, a, c, b) { 281 | b || 282 | (p(void 0 !== g && null !== g, "missing value"), 283 | p("boolean" === typeof c, "missing or invalid endian"), 284 | p(void 0 !== a && null !== a, "missing offset"), 285 | p(a + 3 < f.length, "Trying to write beyond buffer length"), 286 | F(g, 3.4028234663852886e38, -3.4028234663852886e38)) 287 | a >= f.length || I.write(f, g, a, c, 23, 4) 288 | } 289 | function y(f, g, a, c, b) { 290 | b || 291 | (p(void 0 !== g && null !== g, "missing value"), 292 | p("boolean" === typeof c, "missing or invalid endian"), 293 | p(void 0 !== a && null !== a, "missing offset"), 294 | p(a + 7 < f.length, "Trying to write beyond buffer length"), 295 | F(g, 1.7976931348623157e308, -1.7976931348623157e308)) 296 | a >= f.length || I.write(f, g, a, c, 52, 8) 297 | } 298 | function C(f, g, a) { 299 | if ("number" !== typeof f) return a 300 | f = ~~f 301 | if (f >= g) return g 302 | if (0 <= f) return f 303 | f += g 304 | return 0 <= f ? f : 0 305 | } 306 | function D(f) { 307 | f = ~~Math.ceil(+f) 308 | return 0 > f ? 0 : f 309 | } 310 | function M(f) { 311 | return (Array.isArray || 312 | function(f) { 313 | return "[object Array]" === Object.prototype.toString.call(f) 314 | })(f) 315 | } 316 | function K(f) { 317 | return 16 > f ? "0" + f.toString(16) : f.toString(16) 318 | } 319 | function L(f) { 320 | for (var g = [], a = 0; a < f.length; a++) { 321 | var c = f.charCodeAt(a) 322 | if (127 >= c) g.push(f.charCodeAt(a)) 323 | else { 324 | var b = a 325 | 55296 <= c && 57343 >= c && a++ 326 | c = encodeURIComponent(f.slice(b, a + 1)) 327 | .substr(1) 328 | .split("%") 329 | for (b = 0; b < c.length; b++) g.push(parseInt(c[b], 16)) 330 | } 331 | } 332 | return g 333 | } 334 | function J(f) { 335 | for (var a = [], c = 0; c < f.length; c++) a.push(f.charCodeAt(c) & 255) 336 | return a 337 | } 338 | function B(f, a, c, b) { 339 | for (var g = 0; g < b && !(g + c >= a.length || g >= f.length); g++) a[g + c] = f[g] 340 | return g 341 | } 342 | function G(f) { 343 | try { 344 | return decodeURIComponent(f) 345 | } catch (g) { 346 | return String.fromCharCode(65533) 347 | } 348 | } 349 | function H(f, a) { 350 | p("number" === typeof f, "cannot write a non-number as a number") 351 | p(0 <= f, "specified a negative value for writing an unsigned value") 352 | p(f <= a, "value is larger than maximum value for type") 353 | p(Math.floor(f) === f, "value has a fractional component") 354 | } 355 | function A(f, a, c) { 356 | p("number" === typeof f, "cannot write a non-number as a number") 357 | p(f <= a, "value larger than maximum allowed value") 358 | p(f >= c, "value smaller than minimum allowed value") 359 | p(Math.floor(f) === f, "value has a fractional component") 360 | } 361 | function F(f, a, c) { 362 | p("number" === typeof f, "cannot write a non-number as a number") 363 | p(f <= a, "value larger than maximum allowed value") 364 | p(f >= c, "value smaller than minimum allowed value") 365 | } 366 | function p(f, a) { 367 | if (!f) throw Error(a || "Failed assertion") 368 | } 369 | var E = q("base64-js"), 370 | I = q("ieee754") 371 | h.Buffer = b 372 | h.SlowBuffer = b 373 | h.INSPECT_MAX_BYTES = 50 374 | b.poolSize = 8192 375 | b._useTypedArrays = (function() { 376 | try { 377 | var f = new ArrayBuffer(0), 378 | a = new Uint8Array(f) 379 | a.foo = function() { 380 | return 42 381 | } 382 | return 42 === a.foo() && "function" === typeof a.subarray 383 | } catch (w) { 384 | return !1 385 | } 386 | })() 387 | b.isEncoding = function(f) { 388 | switch (String(f).toLowerCase()) { 389 | case "hex": 390 | case "utf8": 391 | case "utf-8": 392 | case "ascii": 393 | case "binary": 394 | case "base64": 395 | case "raw": 396 | case "ucs2": 397 | case "ucs-2": 398 | case "utf16le": 399 | case "utf-16le": 400 | return !0 401 | default: 402 | return !1 403 | } 404 | } 405 | b.isBuffer = function(f) { 406 | return !(null === f || void 0 === f || !f._isBuffer) 407 | } 408 | b.byteLength = function(f, a) { 409 | f += "" 410 | switch (a || "utf8") { 411 | case "hex": 412 | var g = f.length / 2 413 | break 414 | case "utf8": 415 | case "utf-8": 416 | g = L(f).length 417 | break 418 | case "ascii": 419 | case "binary": 420 | case "raw": 421 | g = f.length 422 | break 423 | case "base64": 424 | g = E.toByteArray(f).length 425 | break 426 | case "ucs2": 427 | case "ucs-2": 428 | case "utf16le": 429 | case "utf-16le": 430 | g = 2 * f.length 431 | break 432 | default: 433 | throw Error("Unknown encoding") 434 | } 435 | return g 436 | } 437 | b.concat = function(f, a) { 438 | p(M(f), "Usage: Buffer.concat(list, [totalLength])\nlist should be an Array.") 439 | if (0 === f.length) return new b(0) 440 | if (1 === f.length) return f[0] 441 | var g 442 | if ("number" !== typeof a) for (g = a = 0; g < f.length; g++) a += f[g].length 443 | var c = new b(a), 444 | d = 0 445 | for (g = 0; g < f.length; g++) { 446 | var m = f[g] 447 | m.copy(c, d) 448 | d += m.length 449 | } 450 | return c 451 | } 452 | b.prototype.write = function(f, a, c, d) { 453 | if (isFinite(a)) isFinite(c) || ((d = c), (c = void 0)) 454 | else { 455 | var g = d 456 | d = a 457 | a = c 458 | c = g 459 | } 460 | a = Number(a) || 0 461 | g = this.length - a 462 | c ? ((c = Number(c)), c > g && (c = g)) : (c = g) 463 | d = String(d || "utf8").toLowerCase() 464 | switch (d) { 465 | case "hex": 466 | a = Number(a) || 0 467 | d = this.length - a 468 | c ? ((c = Number(c)), c > d && (c = d)) : (c = d) 469 | d = f.length 470 | p(0 === d % 2, "Invalid hex string") 471 | c > d / 2 && (c = d / 2) 472 | for (d = 0; d < c; d++) 473 | (g = parseInt(f.substr(2 * d, 2), 16)), 474 | p(!isNaN(g), "Invalid hex string"), 475 | (this[a + d] = g) 476 | b._charsWritten = 2 * d 477 | f = d 478 | break 479 | case "utf8": 480 | case "utf-8": 481 | f = b._charsWritten = B(L(f), this, a, c) 482 | break 483 | case "ascii": 484 | f = b._charsWritten = B(J(f), this, a, c) 485 | break 486 | case "binary": 487 | f = b._charsWritten = B(J(f), this, a, c) 488 | break 489 | case "base64": 490 | f = b._charsWritten = B(E.toByteArray(f), this, a, c) 491 | break 492 | case "ucs2": 493 | case "ucs-2": 494 | case "utf16le": 495 | case "utf-16le": 496 | g = [] 497 | for (var m = 0; m < f.length; m++) { 498 | var t = f.charCodeAt(m) 499 | d = t >> 8 500 | t %= 256 501 | g.push(t) 502 | g.push(d) 503 | } 504 | f = b._charsWritten = B(g, this, a, c) 505 | break 506 | default: 507 | throw Error("Unknown encoding") 508 | } 509 | return f 510 | } 511 | b.prototype.toString = function(f, a, c) { 512 | f = String(f || "utf8").toLowerCase() 513 | a = Number(a) || 0 514 | c = void 0 !== c ? Number(c) : (c = this.length) 515 | if (c === a) return "" 516 | switch (f) { 517 | case "hex": 518 | f = this.length 519 | if (!a || 0 > a) a = 0 520 | if (!c || 0 > c || c > f) c = f 521 | for (f = ""; a < c; a++) f += K(this[a]) 522 | c = f 523 | break 524 | case "utf8": 525 | case "utf-8": 526 | var g = (f = "") 527 | for (c = Math.min(this.length, c); a < c; a++) 528 | 127 >= this[a] 529 | ? ((f += G(g) + String.fromCharCode(this[a])), (g = "")) 530 | : (g += "%" + this[a].toString(16)) 531 | c = f + G(g) 532 | break 533 | case "ascii": 534 | c = e(this, a, c) 535 | break 536 | case "binary": 537 | c = e(this, a, c) 538 | break 539 | case "base64": 540 | c = 541 | 0 === a && c === this.length 542 | ? E.fromByteArray(this) 543 | : E.fromByteArray(this.slice(a, c)) 544 | break 545 | case "ucs2": 546 | case "ucs-2": 547 | case "utf16le": 548 | case "utf-16le": 549 | c = this.slice(a, c) 550 | a = "" 551 | for (f = 0; f < c.length; f += 2) a += String.fromCharCode(c[f] + 256 * c[f + 1]) 552 | c = a 553 | break 554 | default: 555 | throw Error("Unknown encoding") 556 | } 557 | return c 558 | } 559 | b.prototype.toJSON = function() { 560 | return { 561 | type: "Buffer", 562 | data: Array.prototype.slice.call(this._arr || this, 0) 563 | } 564 | } 565 | b.prototype.copy = function(f, a, c, d) { 566 | c || (c = 0) 567 | d || 0 === d || (d = this.length) 568 | a || (a = 0) 569 | if (d !== c && 0 !== f.length && 0 !== this.length) 570 | if ( 571 | (p(d >= c, "sourceEnd < sourceStart"), 572 | p(0 <= a && a < f.length, "targetStart out of bounds"), 573 | p(0 <= c && c < this.length, "sourceStart out of bounds"), 574 | p(0 <= d && d <= this.length, "sourceEnd out of bounds"), 575 | d > this.length && (d = this.length), 576 | f.length - a < d - c && (d = f.length - a + c), 577 | (d -= c), 578 | 100 > d || !b._useTypedArrays) 579 | ) 580 | for (var g = 0; g < d; g++) f[g + a] = this[g + c] 581 | else f._set(this.subarray(c, c + d), a) 582 | } 583 | b.prototype.slice = function(f, a) { 584 | var c = this.length 585 | f = C(f, c, 0) 586 | a = C(a, c, c) 587 | if (b._useTypedArrays) return b._augment(this.subarray(f, a)) 588 | c = a - f 589 | for (var g = new b(c, void 0, !0), d = 0; d < c; d++) g[d] = this[d + f] 590 | return g 591 | } 592 | b.prototype.get = function(f) { 593 | console.log(".get() is deprecated. Access using array indexes instead.") 594 | return this.readUInt8(f) 595 | } 596 | b.prototype.set = function(f, a) { 597 | console.log(".set() is deprecated. Access using array indexes instead.") 598 | return this.writeUInt8(f, a) 599 | } 600 | b.prototype.readUInt8 = function(f, a) { 601 | a || 602 | (p(void 0 !== f && null !== f, "missing offset"), 603 | p(f < this.length, "Trying to read beyond buffer length")) 604 | if (!(f >= this.length)) return this[f] 605 | } 606 | b.prototype.readUInt16LE = function(f, a) { 607 | return k(this, f, !0, a) 608 | } 609 | b.prototype.readUInt16BE = function(a, c) { 610 | return k(this, a, !1, c) 611 | } 612 | b.prototype.readUInt32LE = function(a, c) { 613 | return n(this, a, !0, c) 614 | } 615 | b.prototype.readUInt32BE = function(a, c) { 616 | return n(this, a, !1, c) 617 | } 618 | b.prototype.readInt8 = function(a, c) { 619 | c || 620 | (p(void 0 !== a && null !== a, "missing offset"), 621 | p(a < this.length, "Trying to read beyond buffer length")) 622 | if (!(a >= this.length)) return this[a] & 128 ? -1 * (255 - this[a] + 1) : this[a] 623 | } 624 | b.prototype.readInt16LE = function(a, c) { 625 | return d(this, a, !0, c) 626 | } 627 | b.prototype.readInt16BE = function(a, c) { 628 | return d(this, a, !1, c) 629 | } 630 | b.prototype.readInt32LE = function(f, c) { 631 | return a(this, f, !0, c) 632 | } 633 | b.prototype.readInt32BE = function(c, g) { 634 | return a(this, c, !1, g) 635 | } 636 | b.prototype.readFloatLE = function(a, c) { 637 | return l(this, a, !0, c) 638 | } 639 | b.prototype.readFloatBE = function(a, c) { 640 | return l(this, a, !1, c) 641 | } 642 | b.prototype.readDoubleLE = function(a, c) { 643 | return u(this, a, !0, c) 644 | } 645 | b.prototype.readDoubleBE = function(a, c) { 646 | return u(this, a, !1, c) 647 | } 648 | b.prototype.writeUInt8 = function(a, c, b) { 649 | b || 650 | (p(void 0 !== a && null !== a, "missing value"), 651 | p(void 0 !== c && null !== c, "missing offset"), 652 | p(c < this.length, "trying to write beyond buffer length"), 653 | H(a, 255)) 654 | c >= this.length || (this[c] = a) 655 | } 656 | b.prototype.writeUInt16LE = function(a, c, b) { 657 | r(this, a, c, !0, b) 658 | } 659 | b.prototype.writeUInt16BE = function(a, c, b) { 660 | r(this, a, c, !1, b) 661 | } 662 | b.prototype.writeUInt32LE = function(a, c, b) { 663 | t(this, a, c, !0, b) 664 | } 665 | b.prototype.writeUInt32BE = function(a, c, b) { 666 | t(this, a, c, !1, b) 667 | } 668 | b.prototype.writeInt8 = function(a, c, b) { 669 | b || 670 | (p(void 0 !== a && null !== a, "missing value"), 671 | p(void 0 !== c && null !== c, "missing offset"), 672 | p(c < this.length, "Trying to write beyond buffer length"), 673 | A(a, 127, -128)) 674 | c >= this.length || 675 | (0 <= a ? this.writeUInt8(a, c, b) : this.writeUInt8(255 + a + 1, c, b)) 676 | } 677 | b.prototype.writeInt16LE = function(a, c, b) { 678 | z(this, a, c, !0, b) 679 | } 680 | b.prototype.writeInt16BE = function(a, c, b) { 681 | z(this, a, c, !1, b) 682 | } 683 | b.prototype.writeInt32LE = function(a, b, d) { 684 | c(this, a, b, !0, d) 685 | } 686 | b.prototype.writeInt32BE = function(a, b, d) { 687 | c(this, a, b, !1, d) 688 | } 689 | b.prototype.writeFloatLE = function(a, c, b) { 690 | m(this, a, c, !0, b) 691 | } 692 | b.prototype.writeFloatBE = function(a, c, b) { 693 | m(this, a, c, !1, b) 694 | } 695 | b.prototype.writeDoubleLE = function(a, c, b) { 696 | y(this, a, c, !0, b) 697 | } 698 | b.prototype.writeDoubleBE = function(a, c, b) { 699 | y(this, a, c, !1, b) 700 | } 701 | b.prototype.fill = function(a, c, b) { 702 | a || (a = 0) 703 | c || (c = 0) 704 | b || (b = this.length) 705 | "string" === typeof a && (a = a.charCodeAt(0)) 706 | p("number" === typeof a && !isNaN(a), "value is not a number") 707 | p(b >= c, "end < start") 708 | if (b !== c && 0 !== this.length) 709 | for ( 710 | p(0 <= c && c < this.length, "start out of bounds"), 711 | p(0 <= b && b <= this.length, "end out of bounds"); 712 | c < b; 713 | c++ 714 | ) 715 | this[c] = a 716 | } 717 | b.prototype.inspect = function() { 718 | for (var a = [], c = this.length, b = 0; b < c; b++) 719 | if (((a[b] = K(this[b])), b === h.INSPECT_MAX_BYTES)) { 720 | a[b + 1] = "..." 721 | break 722 | } 723 | return "" 724 | } 725 | b.prototype.toArrayBuffer = function() { 726 | if ("undefined" !== typeof Uint8Array) { 727 | if (b._useTypedArrays) return new b(this).buffer 728 | for (var a = new Uint8Array(this.length), c = 0, d = a.length; c < d; c += 1) 729 | a[c] = this[c] 730 | return a.buffer 731 | } 732 | throw Error("Buffer.toArrayBuffer not supported in this browser") 733 | } 734 | var x = b.prototype 735 | b._augment = function(a) { 736 | a._isBuffer = !0 737 | a._get = a.get 738 | a._set = a.set 739 | a.get = x.get 740 | a.set = x.set 741 | a.write = x.write 742 | a.toString = x.toString 743 | a.toLocaleString = x.toString 744 | a.toJSON = x.toJSON 745 | a.copy = x.copy 746 | a.slice = x.slice 747 | a.readUInt8 = x.readUInt8 748 | a.readUInt16LE = x.readUInt16LE 749 | a.readUInt16BE = x.readUInt16BE 750 | a.readUInt32LE = x.readUInt32LE 751 | a.readUInt32BE = x.readUInt32BE 752 | a.readInt8 = x.readInt8 753 | a.readInt16LE = x.readInt16LE 754 | a.readInt16BE = x.readInt16BE 755 | a.readInt32LE = x.readInt32LE 756 | a.readInt32BE = x.readInt32BE 757 | a.readFloatLE = x.readFloatLE 758 | a.readFloatBE = x.readFloatBE 759 | a.readDoubleLE = x.readDoubleLE 760 | a.readDoubleBE = x.readDoubleBE 761 | a.writeUInt8 = x.writeUInt8 762 | a.writeUInt16LE = x.writeUInt16LE 763 | a.writeUInt16BE = x.writeUInt16BE 764 | a.writeUInt32LE = x.writeUInt32LE 765 | a.writeUInt32BE = x.writeUInt32BE 766 | a.writeInt8 = x.writeInt8 767 | a.writeInt16LE = x.writeInt16LE 768 | a.writeInt16BE = x.writeInt16BE 769 | a.writeInt32LE = x.writeInt32LE 770 | a.writeInt32BE = x.writeInt32BE 771 | a.writeFloatLE = x.writeFloatLE 772 | a.writeFloatBE = x.writeFloatBE 773 | a.writeDoubleLE = x.writeDoubleLE 774 | a.writeDoubleBE = x.writeDoubleBE 775 | a.fill = x.fill 776 | a.inspect = x.inspect 777 | a.toArrayBuffer = x.toArrayBuffer 778 | return a 779 | } 780 | }, 781 | { "base64-js": 2, ieee754: 5 } 782 | ], 783 | 5: [ 784 | function(q, v, h) { 785 | h.read = function(b, e, k, n, d) { 786 | var a = 8 * d - n - 1 787 | var l = (1 << a) - 1, 788 | u = l >> 1, 789 | r = -7 790 | d = k ? d - 1 : 0 791 | var t = k ? -1 : 1, 792 | z = b[e + d] 793 | d += t 794 | k = z & ((1 << -r) - 1) 795 | z >>= -r 796 | for (r += a; 0 < r; k = 256 * k + b[e + d], d += t, r -= 8); 797 | a = k & ((1 << -r) - 1) 798 | k >>= -r 799 | for (r += n; 0 < r; a = 256 * a + b[e + d], d += t, r -= 8); 800 | if (0 === k) k = 1 - u 801 | else { 802 | if (k === l) return a ? NaN : Infinity * (z ? -1 : 1) 803 | a += Math.pow(2, n) 804 | k -= u 805 | } 806 | return (z ? -1 : 1) * a * Math.pow(2, k - n) 807 | } 808 | h.write = function(b, e, k, n, d, a) { 809 | var l, 810 | u = 8 * a - d - 1, 811 | r = (1 << u) - 1, 812 | t = r >> 1, 813 | z = 23 === d ? Math.pow(2, -24) - Math.pow(2, -77) : 0 814 | a = n ? 0 : a - 1 815 | var c = n ? 1 : -1, 816 | m = 0 > e || (0 === e && 0 > 1 / e) ? 1 : 0 817 | e = Math.abs(e) 818 | isNaN(e) || Infinity === e 819 | ? ((e = isNaN(e) ? 1 : 0), (n = r)) 820 | : ((n = Math.floor(Math.log(e) / Math.LN2)), 821 | 1 > e * (l = Math.pow(2, -n)) && (n--, (l *= 2)), 822 | (e = 1 <= n + t ? e + z / l : e + z * Math.pow(2, 1 - t)), 823 | 2 <= e * l && (n++, (l /= 2)), 824 | n + t >= r 825 | ? ((e = 0), (n = r)) 826 | : 1 <= n + t 827 | ? ((e = (e * l - 1) * Math.pow(2, d)), (n += t)) 828 | : ((e = e * Math.pow(2, t - 1) * Math.pow(2, d)), (n = 0))) 829 | for (; 8 <= d; b[k + a] = e & 255, a += c, e /= 256, d -= 8); 830 | n = (n << d) | e 831 | for (u += d; 0 < u; b[k + a] = n & 255, a += c, n /= 256, u -= 8); 832 | b[k + a - c] |= 128 * m 833 | } 834 | }, 835 | {} 836 | ], 837 | 6: [ 838 | function(q, v, h) { 839 | ;(function(b) { 840 | function e(a, b) { 841 | for (var d = 0, l = a.length - 1; 0 <= l; l--) { 842 | var t = a[l] 843 | "." === t 844 | ? a.splice(l, 1) 845 | : ".." === t ? (a.splice(l, 1), d++) : d && (a.splice(l, 1), d--) 846 | } 847 | if (b) for (; d--; d) a.unshift("..") 848 | return a 849 | } 850 | function k(a, b) { 851 | if (a.filter) return a.filter(b) 852 | for (var d = [], l = 0; l < a.length; l++) b(a[l], l, a) && d.push(a[l]) 853 | return d 854 | } 855 | var n = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/ 856 | h.resolve = function() { 857 | for (var a = "", d = !1, u = arguments.length - 1; -1 <= u && !d; u--) { 858 | var r = 0 <= u ? arguments[u] : b.cwd() 859 | if ("string" !== typeof r) 860 | throw new TypeError("Arguments to path.resolve must be strings") 861 | r && ((a = r + "/" + a), (d = "/" === r.charAt(0))) 862 | } 863 | a = e( 864 | k(a.split("/"), function(a) { 865 | return !!a 866 | }), 867 | !d 868 | ).join("/") 869 | return (d ? "/" : "") + a || "." 870 | } 871 | h.normalize = function(a) { 872 | var b = h.isAbsolute(a), 873 | u = "/" === d(a, -1) 874 | ;(a = e( 875 | k(a.split("/"), function(a) { 876 | return !!a 877 | }), 878 | !b 879 | ).join("/")) || 880 | b || 881 | (a = ".") 882 | a && u && (a += "/") 883 | return (b ? "/" : "") + a 884 | } 885 | h.isAbsolute = function(a) { 886 | return "/" === a.charAt(0) 887 | } 888 | h.join = function() { 889 | var a = Array.prototype.slice.call(arguments, 0) 890 | return h.normalize( 891 | k(a, function(a, b) { 892 | if ("string" !== typeof a) 893 | throw new TypeError("Arguments to path.join must be strings") 894 | return a 895 | }).join("/") 896 | ) 897 | } 898 | h.relative = function(a, b) { 899 | function d(a) { 900 | for (var c = 0; c < a.length && "" === a[c]; c++); 901 | for (var b = a.length - 1; 0 <= b && "" === a[b]; b--); 902 | return c > b ? [] : a.slice(c, b - c + 1) 903 | } 904 | a = h.resolve(a).substr(1) 905 | b = h.resolve(b).substr(1) 906 | for ( 907 | var l = d(a.split("/")), 908 | t = d(b.split("/")), 909 | e = Math.min(l.length, t.length), 910 | c = e, 911 | m = 0; 912 | m < e; 913 | m++ 914 | ) 915 | if (l[m] !== t[m]) { 916 | c = m 917 | break 918 | } 919 | e = [] 920 | for (m = c; m < l.length; m++) e.push("..") 921 | e = e.concat(t.slice(c)) 922 | return e.join("/") 923 | } 924 | h.sep = "/" 925 | h.delimiter = ":" 926 | h.dirname = function(a) { 927 | var b = n.exec(a).slice(1) 928 | a = b[0] 929 | b = b[1] 930 | if (!a && !b) return "." 931 | b && (b = b.substr(0, b.length - 1)) 932 | return a + b 933 | } 934 | h.basename = function(a, b) { 935 | var d = n.exec(a).slice(1)[2] 936 | b && d.substr(-1 * b.length) === b && (d = d.substr(0, d.length - b.length)) 937 | return d 938 | } 939 | h.extname = function(a) { 940 | return n.exec(a).slice(1)[3] 941 | } 942 | var d = 943 | "b" === "ab".substr(-1) 944 | ? function(a, b, d) { 945 | return a.substr(b, d) 946 | } 947 | : function(a, b, d) { 948 | 0 > b && (b = a.length + b) 949 | return a.substr(b, d) 950 | } 951 | }.call(this, q("node_modules/process/browser.js"))) 952 | }, 953 | { "node_modules/process/browser.js": 7 } 954 | ], 955 | 7: [ 956 | function(q, v, h) { 957 | function b() {} 958 | q = v.exports = {} 959 | q.nextTick = (function() { 960 | if ("undefined" !== typeof window && window.setImmediate) 961 | return function(b) { 962 | return window.setImmediate(b) 963 | } 964 | if ("undefined" !== typeof window && window.postMessage && window.addEventListener) { 965 | var b = [] 966 | window.addEventListener( 967 | "message", 968 | function(e) { 969 | var k = e.source 970 | ;(k !== window && null !== k) || 971 | "process-tick" !== e.data || 972 | (e.stopPropagation(), 0 < b.length && b.shift()()) 973 | }, 974 | !0 975 | ) 976 | return function(e) { 977 | b.push(e) 978 | window.postMessage("process-tick", "*") 979 | } 980 | } 981 | return function(b) { 982 | setTimeout(b, 0) 983 | } 984 | })() 985 | q.title = "browser" 986 | q.browser = !0 987 | q.env = {} 988 | q.argv = [] 989 | q.on = b 990 | q.once = b 991 | q.off = b 992 | q.emit = b 993 | q.binding = function(b) { 994 | throw Error("process.binding is not supported") 995 | } 996 | q.cwd = function() { 997 | return "/" 998 | } 999 | q.chdir = function(b) { 1000 | throw Error("process.chdir is not supported") 1001 | } 1002 | }, 1003 | {} 1004 | ], 1005 | 8: [ 1006 | function(q, v, h) { 1007 | function b() { 1008 | this._array = [] 1009 | this._set = n ? new Map() : Object.create(null) 1010 | } 1011 | var e = q("./util"), 1012 | k = Object.prototype.hasOwnProperty, 1013 | n = "undefined" !== typeof Map 1014 | b.fromArray = function(d, a) { 1015 | for (var e = new b(), k = 0, r = d.length; k < r; k++) e.add(d[k], a) 1016 | return e 1017 | } 1018 | b.prototype.size = function() { 1019 | return n ? this._set.size : Object.getOwnPropertyNames(this._set).length 1020 | } 1021 | b.prototype.add = function(b, a) { 1022 | var d = n ? b : e.toSetString(b), 1023 | u = n ? this.has(b) : k.call(this._set, d), 1024 | r = this._array.length 1025 | ;(u && !a) || this._array.push(b) 1026 | u || (n ? this._set.set(b, r) : (this._set[d] = r)) 1027 | } 1028 | b.prototype.has = function(b) { 1029 | if (n) return this._set.has(b) 1030 | b = e.toSetString(b) 1031 | return k.call(this._set, b) 1032 | } 1033 | b.prototype.indexOf = function(b) { 1034 | if (n) { 1035 | var a = this._set.get(b) 1036 | if (0 <= a) return a 1037 | } else if (((a = e.toSetString(b)), k.call(this._set, a))) return this._set[a] 1038 | throw Error('"' + b + '" is not in the set.') 1039 | } 1040 | b.prototype.at = function(b) { 1041 | if (0 <= b && b < this._array.length) return this._array[b] 1042 | throw Error("No element indexed by " + b) 1043 | } 1044 | b.prototype.toArray = function() { 1045 | return this._array.slice() 1046 | } 1047 | h.ArraySet = b 1048 | }, 1049 | { "./util": 17 } 1050 | ], 1051 | 9: [ 1052 | function(q, v, h) { 1053 | var b = q("./base64") 1054 | h.encode = function(e) { 1055 | var k = "", 1056 | n = 0 > e ? (-e << 1) + 1 : e << 1 1057 | do (e = n & 31), (n >>>= 5), 0 < n && (e |= 32), (k += b.encode(e)) 1058 | while (0 < n) 1059 | return k 1060 | } 1061 | h.decode = function(e, k, n) { 1062 | var d = e.length, 1063 | a = 0, 1064 | l = 0 1065 | do { 1066 | if (k >= d) throw Error("Expected more digits in base 64 VLQ value.") 1067 | var u = b.decode(e.charCodeAt(k++)) 1068 | if (-1 === u) throw Error("Invalid base64 digit: " + e.charAt(k - 1)) 1069 | var r = !!(u & 32) 1070 | u &= 31 1071 | a += u << l 1072 | l += 5 1073 | } while (r) 1074 | e = a >> 1 1075 | n.value = 1 === (a & 1) ? -e : e 1076 | n.rest = k 1077 | } 1078 | }, 1079 | { "./base64": 10 } 1080 | ], 1081 | 10: [ 1082 | function(q, v, h) { 1083 | var b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("") 1084 | h.encode = function(e) { 1085 | if (0 <= e && e < b.length) return b[e] 1086 | throw new TypeError("Must be between 0 and 63: " + e) 1087 | } 1088 | h.decode = function(b) { 1089 | return 65 <= b && 90 >= b 1090 | ? b - 65 1091 | : 97 <= b && 122 >= b 1092 | ? b - 97 + 26 1093 | : 48 <= b && 57 >= b ? b - 48 + 52 : 43 == b ? 62 : 47 == b ? 63 : -1 1094 | } 1095 | }, 1096 | {} 1097 | ], 1098 | 11: [ 1099 | function(q, v, h) { 1100 | function b(e, k, n, d, a, l) { 1101 | var u = Math.floor((k - e) / 2) + e, 1102 | r = a(n, d[u], !0) 1103 | return 0 === r 1104 | ? u 1105 | : 0 < r 1106 | ? 1 < k - u 1107 | ? b(u, k, n, d, a, l) 1108 | : l == h.LEAST_UPPER_BOUND ? (k < d.length ? k : -1) : u 1109 | : 1 < u - e ? b(e, u, n, d, a, l) : l == h.LEAST_UPPER_BOUND ? u : 0 > e ? -1 : e 1110 | } 1111 | h.GREATEST_LOWER_BOUND = 1 1112 | h.LEAST_UPPER_BOUND = 2 1113 | h.search = function(e, k, n, d) { 1114 | if (0 === k.length) return -1 1115 | e = b(-1, k.length, e, k, n, d || h.GREATEST_LOWER_BOUND) 1116 | if (0 > e) return -1 1117 | for (; 0 <= e - 1 && 0 === n(k[e], k[e - 1], !0); ) --e 1118 | return e 1119 | } 1120 | }, 1121 | {} 1122 | ], 1123 | 12: [ 1124 | function(q, v, h) { 1125 | function b() { 1126 | this._array = [] 1127 | this._sorted = !0 1128 | this._last = { generatedLine: -1, generatedColumn: 0 } 1129 | } 1130 | var e = q("./util") 1131 | b.prototype.unsortedForEach = function(b, e) { 1132 | this._array.forEach(b, e) 1133 | } 1134 | b.prototype.add = function(b) { 1135 | var k = this._last, 1136 | d = k.generatedLine, 1137 | a = b.generatedLine, 1138 | l = k.generatedColumn, 1139 | u = b.generatedColumn 1140 | a > d || (a == d && u >= l) || 0 >= e.compareByGeneratedPositionsInflated(k, b) 1141 | ? (this._last = b) 1142 | : (this._sorted = !1) 1143 | this._array.push(b) 1144 | } 1145 | b.prototype.toArray = function() { 1146 | this._sorted || 1147 | (this._array.sort(e.compareByGeneratedPositionsInflated), (this._sorted = !0)) 1148 | return this._array 1149 | } 1150 | h.MappingList = b 1151 | }, 1152 | { "./util": 17 } 1153 | ], 1154 | 13: [ 1155 | function(q, v, h) { 1156 | function b(b, e, d) { 1157 | var a = b[e] 1158 | b[e] = b[d] 1159 | b[d] = a 1160 | } 1161 | function e(k, n, d, a) { 1162 | if (d < a) { 1163 | var l = d - 1 1164 | b(k, Math.round(d + Math.random() * (a - d)), a) 1165 | for (var u = k[a], r = d; r < a; r++) 0 >= n(k[r], u) && ((l += 1), b(k, l, r)) 1166 | b(k, l + 1, r) 1167 | l += 1 1168 | e(k, n, d, l - 1) 1169 | e(k, n, l + 1, a) 1170 | } 1171 | } 1172 | h.quickSort = function(b, n) { 1173 | e(b, n, 0, b.length - 1) 1174 | } 1175 | }, 1176 | {} 1177 | ], 1178 | 14: [ 1179 | function(q, v, h) { 1180 | function b(a, b) { 1181 | var c = a 1182 | "string" === typeof a && (c = d.parseSourceMapInput(a)) 1183 | return null != c.sections ? new n(c, b) : new e(c, b) 1184 | } 1185 | function e(a, b) { 1186 | var c = a 1187 | "string" === typeof a && (c = d.parseSourceMapInput(a)) 1188 | var m = d.getArg(c, "version"), 1189 | t = d.getArg(c, "sources"), 1190 | e = d.getArg(c, "names", []), 1191 | r = d.getArg(c, "sourceRoot", null), 1192 | k = d.getArg(c, "sourcesContent", null), 1193 | u = d.getArg(c, "mappings") 1194 | c = d.getArg(c, "file", null) 1195 | if (m != this._version) throw Error("Unsupported version: " + m) 1196 | r && (r = d.normalize(r)) 1197 | t = t 1198 | .map(String) 1199 | .map(d.normalize) 1200 | .map(function(a) { 1201 | return r && d.isAbsolute(r) && d.isAbsolute(a) ? d.relative(r, a) : a 1202 | }) 1203 | this._names = l.fromArray(e.map(String), !0) 1204 | this._sources = l.fromArray(t, !0) 1205 | this.sourceRoot = r 1206 | this.sourcesContent = k 1207 | this._mappings = u 1208 | this._sourceMapURL = b 1209 | this.file = c 1210 | } 1211 | function k() { 1212 | this.generatedColumn = this.generatedLine = 0 1213 | this.name = this.originalColumn = this.originalLine = this.source = null 1214 | } 1215 | function n(a, e) { 1216 | var c = a 1217 | "string" === typeof a && (c = d.parseSourceMapInput(a)) 1218 | var m = d.getArg(c, "version") 1219 | c = d.getArg(c, "sections") 1220 | if (m != this._version) throw Error("Unsupported version: " + m) 1221 | this._sources = new l() 1222 | this._names = new l() 1223 | var t = { line: -1, column: 0 } 1224 | this._sections = c.map(function(a) { 1225 | if (a.url) throw Error("Support for url field in sections not implemented.") 1226 | var c = d.getArg(a, "offset"), 1227 | m = d.getArg(c, "line"), 1228 | l = d.getArg(c, "column") 1229 | if (m < t.line || (m === t.line && l < t.column)) 1230 | throw Error("Section offsets must be ordered and non-overlapping.") 1231 | t = c 1232 | return { 1233 | generatedOffset: { generatedLine: m + 1, generatedColumn: l + 1 }, 1234 | consumer: new b(d.getArg(a, "map"), e) 1235 | } 1236 | }) 1237 | } 1238 | var d = q("./util"), 1239 | a = q("./binary-search"), 1240 | l = q("./array-set").ArraySet, 1241 | u = q("./base64-vlq"), 1242 | r = q("./quick-sort").quickSort 1243 | b.fromSourceMap = function(a) { 1244 | return e.fromSourceMap(a) 1245 | } 1246 | b.prototype._version = 3 1247 | b.prototype.__generatedMappings = null 1248 | Object.defineProperty(b.prototype, "_generatedMappings", { 1249 | configurable: !0, 1250 | enumerable: !0, 1251 | get: function() { 1252 | this.__generatedMappings || this._parseMappings(this._mappings, this.sourceRoot) 1253 | return this.__generatedMappings 1254 | } 1255 | }) 1256 | b.prototype.__originalMappings = null 1257 | Object.defineProperty(b.prototype, "_originalMappings", { 1258 | configurable: !0, 1259 | enumerable: !0, 1260 | get: function() { 1261 | this.__originalMappings || this._parseMappings(this._mappings, this.sourceRoot) 1262 | return this.__originalMappings 1263 | } 1264 | }) 1265 | b.prototype._charIsMappingSeparator = function(a, b) { 1266 | var c = a.charAt(b) 1267 | return ";" === c || "," === c 1268 | } 1269 | b.prototype._parseMappings = function(a, b) { 1270 | throw Error("Subclasses must implement _parseMappings") 1271 | } 1272 | b.GENERATED_ORDER = 1 1273 | b.ORIGINAL_ORDER = 2 1274 | b.GREATEST_LOWER_BOUND = 1 1275 | b.LEAST_UPPER_BOUND = 2 1276 | b.prototype.eachMapping = function(a, e, c) { 1277 | e = e || null 1278 | switch (c || b.GENERATED_ORDER) { 1279 | case b.GENERATED_ORDER: 1280 | c = this._generatedMappings 1281 | break 1282 | case b.ORIGINAL_ORDER: 1283 | c = this._originalMappings 1284 | break 1285 | default: 1286 | throw Error("Unknown order of iteration.") 1287 | } 1288 | var m = this.sourceRoot 1289 | c 1290 | .map(function(a) { 1291 | var c = null === a.source ? null : this._sources.at(a.source) 1292 | c = d.computeSourceURL(m, c, this._sourceMapURL) 1293 | return { 1294 | source: c, 1295 | generatedLine: a.generatedLine, 1296 | generatedColumn: a.generatedColumn, 1297 | originalLine: a.originalLine, 1298 | originalColumn: a.originalColumn, 1299 | name: null === a.name ? null : this._names.at(a.name) 1300 | } 1301 | }, this) 1302 | .forEach(a, e) 1303 | } 1304 | b.prototype.allGeneratedPositionsFor = function(b) { 1305 | var e = d.getArg(b, "line"), 1306 | c = { 1307 | source: d.getArg(b, "source"), 1308 | originalLine: e, 1309 | originalColumn: d.getArg(b, "column", 0) 1310 | } 1311 | null != this.sourceRoot && (c.source = d.relative(this.sourceRoot, c.source)) 1312 | if (!this._sources.has(c.source)) return [] 1313 | c.source = this._sources.indexOf(c.source) 1314 | var m = [] 1315 | c = this._findMapping( 1316 | c, 1317 | this._originalMappings, 1318 | "originalLine", 1319 | "originalColumn", 1320 | d.compareByOriginalPositions, 1321 | a.LEAST_UPPER_BOUND 1322 | ) 1323 | if (0 <= c) { 1324 | var t = this._originalMappings[c] 1325 | if (void 0 === b.column) 1326 | for (e = t.originalLine; t && t.originalLine === e; ) 1327 | m.push({ 1328 | line: d.getArg(t, "generatedLine", null), 1329 | column: d.getArg(t, "generatedColumn", null), 1330 | lastColumn: d.getArg(t, "lastGeneratedColumn", null) 1331 | }), 1332 | (t = this._originalMappings[++c]) 1333 | else 1334 | for (b = t.originalColumn; t && t.originalLine === e && t.originalColumn == b; ) 1335 | m.push({ 1336 | line: d.getArg(t, "generatedLine", null), 1337 | column: d.getArg(t, "generatedColumn", null), 1338 | lastColumn: d.getArg(t, "lastGeneratedColumn", null) 1339 | }), 1340 | (t = this._originalMappings[++c]) 1341 | } 1342 | return m 1343 | } 1344 | h.SourceMapConsumer = b 1345 | e.prototype = Object.create(b.prototype) 1346 | e.prototype.consumer = b 1347 | e.fromSourceMap = function(a, b) { 1348 | var c = Object.create(e.prototype), 1349 | m = (c._names = l.fromArray(a._names.toArray(), !0)), 1350 | t = (c._sources = l.fromArray(a._sources.toArray(), !0)) 1351 | c.sourceRoot = a._sourceRoot 1352 | c.sourcesContent = a._generateSourcesContent(c._sources.toArray(), c.sourceRoot) 1353 | c.file = a._file 1354 | c._sourceMapURL = b 1355 | for ( 1356 | var u = a._mappings.toArray().slice(), 1357 | z = (c.__generatedMappings = []), 1358 | n = (c.__originalMappings = []), 1359 | h = 0, 1360 | q = u.length; 1361 | h < q; 1362 | h++ 1363 | ) { 1364 | var v = u[h], 1365 | B = new k() 1366 | B.generatedLine = v.generatedLine 1367 | B.generatedColumn = v.generatedColumn 1368 | v.source && 1369 | ((B.source = t.indexOf(v.source)), 1370 | (B.originalLine = v.originalLine), 1371 | (B.originalColumn = v.originalColumn), 1372 | v.name && (B.name = m.indexOf(v.name)), 1373 | n.push(B)) 1374 | z.push(B) 1375 | } 1376 | r(c.__originalMappings, d.compareByOriginalPositions) 1377 | return c 1378 | } 1379 | e.prototype._version = 3 1380 | Object.defineProperty(e.prototype, "sources", { 1381 | get: function() { 1382 | return this._sources.toArray().map(function(a) { 1383 | return d.computeSourceURL(this.sourceRoot, a, this._sourceMapURL) 1384 | }, this) 1385 | } 1386 | }) 1387 | e.prototype._parseMappings = function(a, b) { 1388 | for ( 1389 | var c = 1, 1390 | m = 0, 1391 | e = 0, 1392 | t = 0, 1393 | l = 0, 1394 | z = 0, 1395 | n = a.length, 1396 | h = 0, 1397 | q = {}, 1398 | v = {}, 1399 | G = [], 1400 | H = [], 1401 | A, 1402 | F, 1403 | p, 1404 | E, 1405 | I; 1406 | h < n; 1407 | 1408 | ) 1409 | if (";" === a.charAt(h)) c++, h++, (m = 0) 1410 | else if ("," === a.charAt(h)) h++ 1411 | else { 1412 | A = new k() 1413 | A.generatedLine = c 1414 | for (E = h; E < n && !this._charIsMappingSeparator(a, E); E++); 1415 | F = a.slice(h, E) 1416 | if ((p = q[F])) h += F.length 1417 | else { 1418 | for (p = []; h < E; ) u.decode(a, h, v), (I = v.value), (h = v.rest), p.push(I) 1419 | if (2 === p.length) throw Error("Found a source, but no line and column") 1420 | if (3 === p.length) throw Error("Found a source and line, but no column") 1421 | q[F] = p 1422 | } 1423 | A.generatedColumn = m + p[0] 1424 | m = A.generatedColumn 1425 | 1 < p.length && 1426 | ((A.source = l + p[1]), 1427 | (l += p[1]), 1428 | (A.originalLine = e + p[2]), 1429 | (e = A.originalLine), 1430 | (A.originalLine += 1), 1431 | (A.originalColumn = t + p[3]), 1432 | (t = A.originalColumn), 1433 | 4 < p.length && ((A.name = z + p[4]), (z += p[4]))) 1434 | H.push(A) 1435 | "number" === typeof A.originalLine && G.push(A) 1436 | } 1437 | r(H, d.compareByGeneratedPositionsDeflated) 1438 | this.__generatedMappings = H 1439 | r(G, d.compareByOriginalPositions) 1440 | this.__originalMappings = G 1441 | } 1442 | e.prototype._findMapping = function(b, d, c, m, e, l) { 1443 | if (0 >= b[c]) 1444 | throw new TypeError("Line must be greater than or equal to 1, got " + b[c]) 1445 | if (0 > b[m]) 1446 | throw new TypeError("Column must be greater than or equal to 0, got " + b[m]) 1447 | return a.search(b, d, e, l) 1448 | } 1449 | e.prototype.computeColumnSpans = function() { 1450 | for (var a = 0; a < this._generatedMappings.length; ++a) { 1451 | var b = this._generatedMappings[a] 1452 | if (a + 1 < this._generatedMappings.length) { 1453 | var c = this._generatedMappings[a + 1] 1454 | if (b.generatedLine === c.generatedLine) { 1455 | b.lastGeneratedColumn = c.generatedColumn - 1 1456 | continue 1457 | } 1458 | } 1459 | b.lastGeneratedColumn = Infinity 1460 | } 1461 | } 1462 | e.prototype.originalPositionFor = function(a) { 1463 | var e = { generatedLine: d.getArg(a, "line"), generatedColumn: d.getArg(a, "column") } 1464 | a = this._findMapping( 1465 | e, 1466 | this._generatedMappings, 1467 | "generatedLine", 1468 | "generatedColumn", 1469 | d.compareByGeneratedPositionsDeflated, 1470 | d.getArg(a, "bias", b.GREATEST_LOWER_BOUND) 1471 | ) 1472 | if (0 <= a && ((a = this._generatedMappings[a]), a.generatedLine === e.generatedLine)) { 1473 | e = d.getArg(a, "source", null) 1474 | null !== e && 1475 | ((e = this._sources.at(e)), 1476 | (e = d.computeSourceURL(this.sourceRoot, e, this._sourceMapURL))) 1477 | var c = d.getArg(a, "name", null) 1478 | null !== c && (c = this._names.at(c)) 1479 | return { 1480 | source: e, 1481 | line: d.getArg(a, "originalLine", null), 1482 | column: d.getArg(a, "originalColumn", null), 1483 | name: c 1484 | } 1485 | } 1486 | return { 1487 | source: null, 1488 | line: null, 1489 | column: null, 1490 | name: null 1491 | } 1492 | } 1493 | e.prototype.hasContentsOfAllSources = function() { 1494 | return this.sourcesContent 1495 | ? this.sourcesContent.length >= this._sources.size() && 1496 | !this.sourcesContent.some(function(a) { 1497 | return null == a 1498 | }) 1499 | : !1 1500 | } 1501 | e.prototype.sourceContentFor = function(a, b) { 1502 | if (!this.sourcesContent) return null 1503 | var c = a 1504 | null != this.sourceRoot && (c = d.relative(this.sourceRoot, c)) 1505 | if (this._sources.has(c)) return this.sourcesContent[this._sources.indexOf(c)] 1506 | var m = this.sources, 1507 | e 1508 | for (e = 0; e < m.length; ++e) if (m[e] == a) return this.sourcesContent[e] 1509 | var l 1510 | if (null != this.sourceRoot && (l = d.urlParse(this.sourceRoot))) { 1511 | m = c.replace(/^file:\/\//, "") 1512 | if ("file" == l.scheme && this._sources.has(m)) 1513 | return this.sourcesContent[this._sources.indexOf(m)] 1514 | if ((!l.path || "/" == l.path) && this._sources.has("/" + c)) 1515 | return this.sourcesContent[this._sources.indexOf("/" + c)] 1516 | } 1517 | if (b) return null 1518 | throw Error('"' + c + '" is not in the SourceMap.') 1519 | } 1520 | e.prototype.generatedPositionFor = function(a) { 1521 | var e = d.getArg(a, "source") 1522 | null != this.sourceRoot && (e = d.relative(this.sourceRoot, e)) 1523 | if (!this._sources.has(e)) 1524 | return { 1525 | line: null, 1526 | column: null, 1527 | lastColumn: null 1528 | } 1529 | e = this._sources.indexOf(e) 1530 | e = { 1531 | source: e, 1532 | originalLine: d.getArg(a, "line"), 1533 | originalColumn: d.getArg(a, "column") 1534 | } 1535 | a = this._findMapping( 1536 | e, 1537 | this._originalMappings, 1538 | "originalLine", 1539 | "originalColumn", 1540 | d.compareByOriginalPositions, 1541 | d.getArg(a, "bias", b.GREATEST_LOWER_BOUND) 1542 | ) 1543 | return 0 <= a && ((a = this._originalMappings[a]), a.source === e.source) 1544 | ? { 1545 | line: d.getArg(a, "generatedLine", null), 1546 | column: d.getArg(a, "generatedColumn", null), 1547 | lastColumn: d.getArg(a, "lastGeneratedColumn", null) 1548 | } 1549 | : { 1550 | line: null, 1551 | column: null, 1552 | lastColumn: null 1553 | } 1554 | } 1555 | h.BasicSourceMapConsumer = e 1556 | n.prototype = Object.create(b.prototype) 1557 | n.prototype.constructor = b 1558 | n.prototype._version = 3 1559 | Object.defineProperty(n.prototype, "sources", { 1560 | get: function() { 1561 | for (var a = [], b = 0; b < this._sections.length; b++) 1562 | for (var c = 0; c < this._sections[b].consumer.sources.length; c++) 1563 | a.push(this._sections[b].consumer.sources[c]) 1564 | return a 1565 | } 1566 | }) 1567 | n.prototype.originalPositionFor = function(b) { 1568 | var e = { generatedLine: d.getArg(b, "line"), generatedColumn: d.getArg(b, "column") }, 1569 | c = a.search(e, this._sections, function(a, c) { 1570 | var b = a.generatedLine - c.generatedOffset.generatedLine 1571 | return b ? b : a.generatedColumn - c.generatedOffset.generatedColumn 1572 | }) 1573 | return (c = this._sections[c]) 1574 | ? c.consumer.originalPositionFor({ 1575 | line: e.generatedLine - (c.generatedOffset.generatedLine - 1), 1576 | column: 1577 | e.generatedColumn - 1578 | (c.generatedOffset.generatedLine === e.generatedLine 1579 | ? c.generatedOffset.generatedColumn - 1 1580 | : 0), 1581 | bias: b.bias 1582 | }) 1583 | : { source: null, line: null, column: null, name: null } 1584 | } 1585 | n.prototype.hasContentsOfAllSources = function() { 1586 | return this._sections.every(function(a) { 1587 | return a.consumer.hasContentsOfAllSources() 1588 | }) 1589 | } 1590 | n.prototype.sourceContentFor = function(a, b) { 1591 | for (var c = 0; c < this._sections.length; c++) { 1592 | var d = this._sections[c].consumer.sourceContentFor(a, !0) 1593 | if (d) return d 1594 | } 1595 | if (b) return null 1596 | throw Error('"' + a + '" is not in the SourceMap.') 1597 | } 1598 | n.prototype.generatedPositionFor = function(a) { 1599 | for (var b = 0; b < this._sections.length; b++) { 1600 | var c = this._sections[b] 1601 | if (-1 !== c.consumer.sources.indexOf(d.getArg(a, "source"))) { 1602 | var m = c.consumer.generatedPositionFor(a) 1603 | if (m) 1604 | return { 1605 | line: m.line + (c.generatedOffset.generatedLine - 1), 1606 | column: 1607 | m.column + 1608 | (c.generatedOffset.generatedLine === m.line 1609 | ? c.generatedOffset.generatedColumn - 1 1610 | : 0) 1611 | } 1612 | } 1613 | } 1614 | return { line: null, column: null } 1615 | } 1616 | n.prototype._parseMappings = function(a, b) { 1617 | this.__generatedMappings = [] 1618 | this.__originalMappings = [] 1619 | for (var c = 0; c < this._sections.length; c++) 1620 | for ( 1621 | var m = this._sections[c], e = m.consumer._generatedMappings, l = 0; 1622 | l < e.length; 1623 | l++ 1624 | ) { 1625 | var u = e[l], 1626 | k = m.consumer._sources.at(u.source) 1627 | k = d.computeSourceURL(m.consumer.sourceRoot, k, this._sourceMapURL) 1628 | this._sources.add(k) 1629 | k = this._sources.indexOf(k) 1630 | var t = null 1631 | u.name && 1632 | ((t = m.consumer._names.at(u.name)), 1633 | this._names.add(t), 1634 | (t = this._names.indexOf(t))) 1635 | u = { 1636 | source: k, 1637 | generatedLine: u.generatedLine + (m.generatedOffset.generatedLine - 1), 1638 | generatedColumn: 1639 | u.generatedColumn + 1640 | (m.generatedOffset.generatedLine === u.generatedLine 1641 | ? m.generatedOffset.generatedColumn - 1 1642 | : 0), 1643 | originalLine: u.originalLine, 1644 | originalColumn: u.originalColumn, 1645 | name: t 1646 | } 1647 | this.__generatedMappings.push(u) 1648 | "number" === typeof u.originalLine && this.__originalMappings.push(u) 1649 | } 1650 | r(this.__generatedMappings, d.compareByGeneratedPositionsDeflated) 1651 | r(this.__originalMappings, d.compareByOriginalPositions) 1652 | } 1653 | h.IndexedSourceMapConsumer = n 1654 | }, 1655 | { 1656 | "./array-set": 8, 1657 | "./base64-vlq": 9, 1658 | "./binary-search": 11, 1659 | "./quick-sort": 13, 1660 | "./util": 17 1661 | } 1662 | ], 1663 | 15: [ 1664 | function(q, v, h) { 1665 | function b(a) { 1666 | a || (a = {}) 1667 | this._file = k.getArg(a, "file", null) 1668 | this._sourceRoot = k.getArg(a, "sourceRoot", null) 1669 | this._skipValidation = k.getArg(a, "skipValidation", !1) 1670 | this._sources = new n() 1671 | this._names = new n() 1672 | this._mappings = new d() 1673 | this._sourcesContents = null 1674 | } 1675 | var e = q("./base64-vlq"), 1676 | k = q("./util"), 1677 | n = q("./array-set").ArraySet, 1678 | d = q("./mapping-list").MappingList 1679 | b.prototype._version = 3 1680 | b.fromSourceMap = function(a) { 1681 | var d = a.sourceRoot, 1682 | e = new b({ file: a.file, sourceRoot: d }) 1683 | a.eachMapping(function(a) { 1684 | var b = { generated: { line: a.generatedLine, column: a.generatedColumn } } 1685 | null != a.source && 1686 | ((b.source = a.source), 1687 | null != d && (b.source = k.relative(d, b.source)), 1688 | (b.original = { line: a.originalLine, column: a.originalColumn }), 1689 | null != a.name && (b.name = a.name)) 1690 | e.addMapping(b) 1691 | }) 1692 | a.sources.forEach(function(b) { 1693 | var l = b 1694 | null !== d && (l = k.relative(d, b)) 1695 | e._sources.has(l) || e._sources.add(l) 1696 | l = a.sourceContentFor(b) 1697 | null != l && e.setSourceContent(b, l) 1698 | }) 1699 | return e 1700 | } 1701 | b.prototype.addMapping = function(a) { 1702 | var b = k.getArg(a, "generated"), 1703 | d = k.getArg(a, "original", null), 1704 | e = k.getArg(a, "source", null) 1705 | a = k.getArg(a, "name", null) 1706 | this._skipValidation || this._validateMapping(b, d, e, a) 1707 | null != e && ((e = String(e)), this._sources.has(e) || this._sources.add(e)) 1708 | null != a && ((a = String(a)), this._names.has(a) || this._names.add(a)) 1709 | this._mappings.add({ 1710 | generatedLine: b.line, 1711 | generatedColumn: b.column, 1712 | originalLine: null != d && d.line, 1713 | originalColumn: null != d && d.column, 1714 | source: e, 1715 | name: a 1716 | }) 1717 | } 1718 | b.prototype.setSourceContent = function(a, b) { 1719 | var d = a 1720 | null != this._sourceRoot && (d = k.relative(this._sourceRoot, d)) 1721 | null != b 1722 | ? (this._sourcesContents || (this._sourcesContents = Object.create(null)), 1723 | (this._sourcesContents[k.toSetString(d)] = b)) 1724 | : this._sourcesContents && 1725 | (delete this._sourcesContents[k.toSetString(d)], 1726 | 0 === Object.keys(this._sourcesContents).length && (this._sourcesContents = null)) 1727 | } 1728 | b.prototype.applySourceMap = function(a, b, d) { 1729 | var e = b 1730 | if (null == b) { 1731 | if (null == a.file) 1732 | throw Error( 1733 | 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.' 1734 | ) 1735 | e = a.file 1736 | } 1737 | var l = this._sourceRoot 1738 | null != l && (e = k.relative(l, e)) 1739 | var u = new n(), 1740 | c = new n() 1741 | this._mappings.unsortedForEach(function(b) { 1742 | if (b.source === e && null != b.originalLine) { 1743 | var m = a.originalPositionFor({ line: b.originalLine, column: b.originalColumn }) 1744 | null != m.source && 1745 | ((b.source = m.source), 1746 | null != d && (b.source = k.join(d, b.source)), 1747 | null != l && (b.source = k.relative(l, b.source)), 1748 | (b.originalLine = m.line), 1749 | (b.originalColumn = m.column), 1750 | null != m.name && (b.name = m.name)) 1751 | } 1752 | m = b.source 1753 | null == m || u.has(m) || u.add(m) 1754 | b = b.name 1755 | null == b || c.has(b) || c.add(b) 1756 | }, this) 1757 | this._sources = u 1758 | this._names = c 1759 | a.sources.forEach(function(b) { 1760 | var c = a.sourceContentFor(b) 1761 | null != c && 1762 | (null != d && (b = k.join(d, b)), 1763 | null != l && (b = k.relative(l, b)), 1764 | this.setSourceContent(b, c)) 1765 | }, this) 1766 | } 1767 | b.prototype._validateMapping = function(a, b, d, e) { 1768 | if (b && "number" !== typeof b.line && "number" !== typeof b.column) 1769 | throw Error( 1770 | "original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values." 1771 | ) 1772 | if ( 1773 | !( 1774 | (a && 1775 | "line" in a && 1776 | "column" in a && 1777 | 0 < a.line && 1778 | 0 <= a.column && 1779 | !b && 1780 | !d && 1781 | !e) || 1782 | (a && 1783 | "line" in a && 1784 | "column" in a && 1785 | b && 1786 | "line" in b && 1787 | "column" in b && 1788 | 0 < a.line && 1789 | 0 <= a.column && 1790 | 0 < b.line && 1791 | 0 <= b.column && 1792 | d) 1793 | ) 1794 | ) 1795 | throw Error( 1796 | "Invalid mapping: " + 1797 | JSON.stringify({ generated: a, source: d, original: b, name: e }) 1798 | ) 1799 | } 1800 | b.prototype._serializeMappings = function() { 1801 | for ( 1802 | var a = 0, 1803 | b = 1, 1804 | d = 0, 1805 | h = 0, 1806 | n = 0, 1807 | q = 0, 1808 | c = "", 1809 | m, 1810 | y, 1811 | C, 1812 | D = this._mappings.toArray(), 1813 | v = 0, 1814 | K = D.length; 1815 | v < K; 1816 | v++ 1817 | ) { 1818 | y = D[v] 1819 | m = "" 1820 | if (y.generatedLine !== b) for (a = 0; y.generatedLine !== b; ) (m += ";"), b++ 1821 | else if (0 < v) { 1822 | if (!k.compareByGeneratedPositionsInflated(y, D[v - 1])) continue 1823 | m += "," 1824 | } 1825 | m += e.encode(y.generatedColumn - a) 1826 | a = y.generatedColumn 1827 | null != y.source && 1828 | ((C = this._sources.indexOf(y.source)), 1829 | (m += e.encode(C - q)), 1830 | (q = C), 1831 | (m += e.encode(y.originalLine - 1 - h)), 1832 | (h = y.originalLine - 1), 1833 | (m += e.encode(y.originalColumn - d)), 1834 | (d = y.originalColumn), 1835 | null != y.name && 1836 | ((y = this._names.indexOf(y.name)), (m += e.encode(y - n)), (n = y))) 1837 | c += m 1838 | } 1839 | return c 1840 | } 1841 | b.prototype._generateSourcesContent = function(a, b) { 1842 | return a.map(function(a) { 1843 | if (!this._sourcesContents) return null 1844 | null != b && (a = k.relative(b, a)) 1845 | a = k.toSetString(a) 1846 | return Object.prototype.hasOwnProperty.call(this._sourcesContents, a) 1847 | ? this._sourcesContents[a] 1848 | : null 1849 | }, this) 1850 | } 1851 | b.prototype.toJSON = function() { 1852 | var a = { 1853 | version: this._version, 1854 | sources: this._sources.toArray(), 1855 | names: this._names.toArray(), 1856 | mappings: this._serializeMappings() 1857 | } 1858 | null != this._file && (a.file = this._file) 1859 | null != this._sourceRoot && (a.sourceRoot = this._sourceRoot) 1860 | this._sourcesContents && 1861 | (a.sourcesContent = this._generateSourcesContent(a.sources, a.sourceRoot)) 1862 | return a 1863 | } 1864 | b.prototype.toString = function() { 1865 | return JSON.stringify(this.toJSON()) 1866 | } 1867 | h.SourceMapGenerator = b 1868 | }, 1869 | { 1870 | "./array-set": 8, 1871 | "./base64-vlq": 9, 1872 | "./mapping-list": 12, 1873 | "./util": 17 1874 | } 1875 | ], 1876 | 16: [ 1877 | function(q, v, h) { 1878 | function b(b, a, e, k, h) { 1879 | this.children = [] 1880 | this.sourceContents = {} 1881 | this.line = null == b ? null : b 1882 | this.column = null == a ? null : a 1883 | this.source = null == e ? null : e 1884 | this.name = null == h ? null : h 1885 | this.$$$isSourceNode$$$ = !0 1886 | null != k && this.add(k) 1887 | } 1888 | var e = q("./source-map-generator").SourceMapGenerator, 1889 | k = q("./util"), 1890 | n = /(\r?\n)/ 1891 | b.fromStringWithSourceMap = function(d, a, e) { 1892 | function l(a, c) { 1893 | if (null === a || void 0 === a.source) h.add(c) 1894 | else { 1895 | var d = e ? k.join(e, a.source) : a.source 1896 | h.add(new b(a.originalLine, a.originalColumn, d, c, a.name)) 1897 | } 1898 | } 1899 | var h = new b(), 1900 | t = d.split(n), 1901 | q = 0, 1902 | c = function() { 1903 | var a = q < t.length ? t[q++] : void 0, 1904 | b = (q < t.length ? t[q++] : void 0) || "" 1905 | return a + b 1906 | }, 1907 | m = 1, 1908 | y = 0, 1909 | C = null 1910 | a.eachMapping(function(a) { 1911 | if (null !== C) 1912 | if (m < a.generatedLine) l(C, c()), m++, (y = 0) 1913 | else { 1914 | var b = t[q] || "", 1915 | d = b.substr(0, a.generatedColumn - y) 1916 | t[q] = b.substr(a.generatedColumn - y) 1917 | y = a.generatedColumn 1918 | l(C, d) 1919 | C = a 1920 | return 1921 | } 1922 | for (; m < a.generatedLine; ) h.add(c()), m++ 1923 | y < a.generatedColumn && 1924 | ((b = t[q] || ""), 1925 | h.add(b.substr(0, a.generatedColumn)), 1926 | (t[q] = b.substr(a.generatedColumn)), 1927 | (y = a.generatedColumn)) 1928 | C = a 1929 | }, this) 1930 | q < t.length && (C && l(C, c()), h.add(t.splice(q).join(""))) 1931 | a.sources.forEach(function(b) { 1932 | var c = a.sourceContentFor(b) 1933 | null != c && (null != e && (b = k.join(e, b)), h.setSourceContent(b, c)) 1934 | }) 1935 | return h 1936 | } 1937 | b.prototype.add = function(b) { 1938 | if (Array.isArray(b)) 1939 | b.forEach(function(a) { 1940 | this.add(a) 1941 | }, this) 1942 | else if (b.$$$isSourceNode$$$ || "string" === typeof b) b && this.children.push(b) 1943 | else 1944 | throw new TypeError( 1945 | "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + b 1946 | ) 1947 | return this 1948 | } 1949 | b.prototype.prepend = function(b) { 1950 | if (Array.isArray(b)) for (var a = b.length - 1; 0 <= a; a--) this.prepend(b[a]) 1951 | else if (b.$$$isSourceNode$$$ || "string" === typeof b) this.children.unshift(b) 1952 | else 1953 | throw new TypeError( 1954 | "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + b 1955 | ) 1956 | return this 1957 | } 1958 | b.prototype.walk = function(b) { 1959 | for (var a, d = 0, e = this.children.length; d < e; d++) 1960 | (a = this.children[d]), 1961 | a.$$$isSourceNode$$$ 1962 | ? a.walk(b) 1963 | : "" !== a && 1964 | b(a, { 1965 | source: this.source, 1966 | line: this.line, 1967 | column: this.column, 1968 | name: this.name 1969 | }) 1970 | } 1971 | b.prototype.join = function(b) { 1972 | var a, 1973 | d = this.children.length 1974 | if (0 < d) { 1975 | var e = [] 1976 | for (a = 0; a < d - 1; a++) e.push(this.children[a]), e.push(b) 1977 | e.push(this.children[a]) 1978 | this.children = e 1979 | } 1980 | return this 1981 | } 1982 | b.prototype.replaceRight = function(b, a) { 1983 | var d = this.children[this.children.length - 1] 1984 | d.$$$isSourceNode$$$ 1985 | ? d.replaceRight(b, a) 1986 | : "string" === typeof d 1987 | ? (this.children[this.children.length - 1] = d.replace(b, a)) 1988 | : this.children.push("".replace(b, a)) 1989 | return this 1990 | } 1991 | b.prototype.setSourceContent = function(b, a) { 1992 | this.sourceContents[k.toSetString(b)] = a 1993 | } 1994 | b.prototype.walkSourceContents = function(b) { 1995 | for (var a = 0, d = this.children.length; a < d; a++) 1996 | this.children[a].$$$isSourceNode$$$ && this.children[a].walkSourceContents(b) 1997 | var e = Object.keys(this.sourceContents) 1998 | a = 0 1999 | for (d = e.length; a < d; a++) b(k.fromSetString(e[a]), this.sourceContents[e[a]]) 2000 | } 2001 | b.prototype.toString = function() { 2002 | var b = "" 2003 | this.walk(function(a) { 2004 | b += a 2005 | }) 2006 | return b 2007 | } 2008 | b.prototype.toStringWithSourceMap = function(b) { 2009 | var a = "", 2010 | d = 1, 2011 | k = 0, 2012 | h = new e(b), 2013 | n = !1, 2014 | q = null, 2015 | c = null, 2016 | m = null, 2017 | y = null 2018 | this.walk(function(b, e) { 2019 | a += b 2020 | null !== e.source && null !== e.line && null !== e.column 2021 | ? ((q === e.source && c === e.line && m === e.column && y === e.name) || 2022 | h.addMapping({ 2023 | source: e.source, 2024 | original: { line: e.line, column: e.column }, 2025 | generated: { line: d, column: k }, 2026 | name: e.name 2027 | }), 2028 | (q = e.source), 2029 | (c = e.line), 2030 | (m = e.column), 2031 | (y = e.name), 2032 | (n = !0)) 2033 | : n && (h.addMapping({ generated: { line: d, column: k } }), (q = null), (n = !1)) 2034 | for (var l = 0, r = b.length; l < r; l++) 2035 | 10 === b.charCodeAt(l) 2036 | ? (d++, 2037 | (k = 0), 2038 | l + 1 === r 2039 | ? ((q = null), (n = !1)) 2040 | : n && 2041 | h.addMapping({ 2042 | source: e.source, 2043 | original: { line: e.line, column: e.column }, 2044 | generated: { line: d, column: k }, 2045 | name: e.name 2046 | })) 2047 | : k++ 2048 | }) 2049 | this.walkSourceContents(function(a, b) { 2050 | h.setSourceContent(a, b) 2051 | }) 2052 | return { code: a, map: h } 2053 | } 2054 | h.SourceNode = b 2055 | }, 2056 | { "./source-map-generator": 15, "./util": 17 } 2057 | ], 2058 | 17: [ 2059 | function(q, v, h) { 2060 | function b(a) { 2061 | return (a = a.match(t)) 2062 | ? { scheme: a[1], auth: a[2], host: a[3], port: a[4], path: a[5] } 2063 | : null 2064 | } 2065 | function e(a) { 2066 | var b = "" 2067 | a.scheme && (b += a.scheme + ":") 2068 | b += "//" 2069 | a.auth && (b += a.auth + "@") 2070 | a.host && (b += a.host) 2071 | a.port && (b += ":" + a.port) 2072 | a.path && (b += a.path) 2073 | return b 2074 | } 2075 | function k(a) { 2076 | var c = a, 2077 | d = b(a) 2078 | if (d) { 2079 | if (!d.path) return a 2080 | c = d.path 2081 | } 2082 | a = h.isAbsolute(c) 2083 | c = c.split(/\/+/) 2084 | for (var k, l = 0, n = c.length - 1; 0 <= n; n--) 2085 | (k = c[n]), 2086 | "." === k 2087 | ? c.splice(n, 1) 2088 | : ".." === k 2089 | ? l++ 2090 | : 0 < l && ("" === k ? (c.splice(n + 1, l), (l = 0)) : (c.splice(n, 2), l--)) 2091 | c = c.join("/") 2092 | "" === c && (c = a ? "/" : ".") 2093 | return d ? ((d.path = c), e(d)) : c 2094 | } 2095 | function n(a, d) { 2096 | "" === a && (a = ".") 2097 | "" === d && (d = ".") 2098 | var c = b(d), 2099 | m = b(a) 2100 | m && (a = m.path || "/") 2101 | if (c && !c.scheme) return m && (c.scheme = m.scheme), e(c) 2102 | if (c || d.match(z)) return d 2103 | if (m && !m.host && !m.path) return (m.host = d), e(m) 2104 | c = "/" === d.charAt(0) ? d : k(a.replace(/\/+$/, "") + "/" + d) 2105 | return m ? ((m.path = c), e(m)) : c 2106 | } 2107 | function d(a) { 2108 | return a 2109 | } 2110 | function a(a) { 2111 | return u(a) ? "$" + a : a 2112 | } 2113 | function l(a) { 2114 | return u(a) ? a.slice(1) : a 2115 | } 2116 | function u(a) { 2117 | if (!a) return !1 2118 | var b = a.length 2119 | if ( 2120 | 9 > b || 2121 | 95 !== a.charCodeAt(b - 1) || 2122 | 95 !== a.charCodeAt(b - 2) || 2123 | 111 !== a.charCodeAt(b - 3) || 2124 | 116 !== a.charCodeAt(b - 4) || 2125 | 111 !== a.charCodeAt(b - 5) || 2126 | 114 !== a.charCodeAt(b - 6) || 2127 | 112 !== a.charCodeAt(b - 7) || 2128 | 95 !== a.charCodeAt(b - 8) || 2129 | 95 !== a.charCodeAt(b - 9) 2130 | ) 2131 | return !1 2132 | for (b -= 10; 0 <= b; b--) if (36 !== a.charCodeAt(b)) return !1 2133 | return !0 2134 | } 2135 | function r(a, b) { 2136 | return a === b ? 0 : null === a ? 1 : null === b ? -1 : a > b ? 1 : -1 2137 | } 2138 | h.getArg = function(a, b, d) { 2139 | if (b in a) return a[b] 2140 | if (3 === arguments.length) return d 2141 | throw Error('"' + b + '" is a required argument.') 2142 | } 2143 | var t = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/, 2144 | z = /^data:.+,.+$/ 2145 | h.urlParse = b 2146 | h.urlGenerate = e 2147 | h.normalize = k 2148 | h.join = n 2149 | h.isAbsolute = function(a) { 2150 | return "/" === a.charAt(0) || t.test(a) 2151 | } 2152 | h.relative = function(a, b) { 2153 | "" === a && (a = ".") 2154 | a = a.replace(/\/$/, "") 2155 | for (var c = 0; 0 !== b.indexOf(a + "/"); ) { 2156 | var d = a.lastIndexOf("/") 2157 | if (0 > d) return b 2158 | a = a.slice(0, d) 2159 | if (a.match(/^([^\/]+:\/)?\/*$/)) return b 2160 | ++c 2161 | } 2162 | return Array(c + 1).join("../") + b.substr(a.length + 1) 2163 | } 2164 | q = !("__proto__" in Object.create(null)) 2165 | h.toSetString = q ? d : a 2166 | h.fromSetString = q ? d : l 2167 | h.compareByOriginalPositions = function(a, b, d) { 2168 | var c = r(a.source, b.source) 2169 | if (0 !== c) return c 2170 | c = a.originalLine - b.originalLine 2171 | if (0 !== c) return c 2172 | c = a.originalColumn - b.originalColumn 2173 | if (0 !== c || d) return c 2174 | c = a.generatedColumn - b.generatedColumn 2175 | if (0 !== c) return c 2176 | c = a.generatedLine - b.generatedLine 2177 | return 0 !== c ? c : r(a.name, b.name) 2178 | } 2179 | h.compareByGeneratedPositionsDeflated = function(a, b, d) { 2180 | var c = a.generatedLine - b.generatedLine 2181 | if (0 !== c) return c 2182 | c = a.generatedColumn - b.generatedColumn 2183 | if (0 !== c || d) return c 2184 | c = r(a.source, b.source) 2185 | if (0 !== c) return c 2186 | c = a.originalLine - b.originalLine 2187 | if (0 !== c) return c 2188 | c = a.originalColumn - b.originalColumn 2189 | return 0 !== c ? c : r(a.name, b.name) 2190 | } 2191 | h.compareByGeneratedPositionsInflated = function(a, b) { 2192 | var c = a.generatedLine - b.generatedLine 2193 | if (0 !== c) return c 2194 | c = a.generatedColumn - b.generatedColumn 2195 | if (0 !== c) return c 2196 | c = r(a.source, b.source) 2197 | if (0 !== c) return c 2198 | c = a.originalLine - b.originalLine 2199 | if (0 !== c) return c 2200 | c = a.originalColumn - b.originalColumn 2201 | return 0 !== c ? c : r(a.name, b.name) 2202 | } 2203 | h.parseSourceMapInput = function(a) { 2204 | return JSON.parse(a.replace(/^\)]}'[^\n]*\n/, "")) 2205 | } 2206 | h.computeSourceURL = function(a, d, h) { 2207 | d = d || "" 2208 | a && ("/" !== a[a.length - 1] && "/" !== d[0] && (a += "/"), (d = a + d)) 2209 | if (h) { 2210 | a = b(h) 2211 | if (!a) throw Error("sourceMapURL could not be parsed") 2212 | a.path && 2213 | ((h = a.path.lastIndexOf("/")), 0 <= h && (a.path = a.path.substring(0, h + 1))) 2214 | d = n(e(a), d) 2215 | } 2216 | return k(d) 2217 | } 2218 | }, 2219 | {} 2220 | ], 2221 | 18: [ 2222 | function(q, v, h) { 2223 | h.SourceMapGenerator = q("./lib/source-map-generator").SourceMapGenerator 2224 | h.SourceMapConsumer = q("./lib/source-map-consumer").SourceMapConsumer 2225 | h.SourceNode = q("./lib/source-node").SourceNode 2226 | }, 2227 | { 2228 | "./lib/source-map-consumer": 14, 2229 | "./lib/source-map-generator": 15, 2230 | "./lib/source-node": 16 2231 | } 2232 | ], 2233 | 19: [ 2234 | function(q, v, h) { 2235 | ;(function(b, e) { 2236 | function k() { 2237 | return "browser" === J 2238 | ? !0 2239 | : "node" === J 2240 | ? !1 2241 | : "undefined" !== typeof window && 2242 | "function" === typeof XMLHttpRequest && 2243 | !( 2244 | window.require && 2245 | window.module && 2246 | window.process && 2247 | "renderer" === window.process.type 2248 | ) 2249 | } 2250 | function n(a) { 2251 | return function(b) { 2252 | for (var c = 0; c < a.length; c++) { 2253 | var d = a[c](b) 2254 | if (d) return d 2255 | } 2256 | return null 2257 | } 2258 | } 2259 | function d(a, b) { 2260 | if (!a) return b 2261 | var c = C.dirname(a), 2262 | d = /^\w+:\/\/[^\/]*/.exec(c) 2263 | d = d ? d[0] : "" 2264 | var e = c.slice(d.length) 2265 | return d && /^\/\w:/.test(e) 2266 | ? ((d += "/"), d + C.resolve(c.slice(d.length), b).replace(/\\/g, "/")) 2267 | : d + C.resolve(c.slice(d.length), b) 2268 | } 2269 | function a(a) { 2270 | var b = G[a.source] 2271 | if (!b) { 2272 | var c = E(a.source) 2273 | c 2274 | ? ((b = G[a.source] = { url: c.url, map: new y(c.map) }), 2275 | b.map.sourcesContent && 2276 | b.map.sources.forEach(function(a, c) { 2277 | var e = b.map.sourcesContent[c] 2278 | if (e) { 2279 | var f = d(b.url, a) 2280 | B[f] = e 2281 | } 2282 | })) 2283 | : (b = G[a.source] = { url: null, map: null }) 2284 | } 2285 | return b && b.map && ((c = b.map.originalPositionFor(a)), null !== c.source) 2286 | ? ((c.source = d(b.url, c.source)), c) 2287 | : a 2288 | } 2289 | function l(b) { 2290 | var c = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(b) 2291 | return c 2292 | ? ((b = a({ source: c[2], line: +c[3], column: c[4] - 1 })), 2293 | "eval at " + c[1] + " (" + b.source + ":" + b.line + ":" + (b.column + 1) + ")") 2294 | : (c = /^eval at ([^(]+) \((.+)\)$/.exec(b)) 2295 | ? "eval at " + c[1] + " (" + l(c[2]) + ")" 2296 | : b 2297 | } 2298 | function u() { 2299 | var a = "" 2300 | if (this.isNative()) a = "native" 2301 | else { 2302 | var b = this.getScriptNameOrSourceURL() 2303 | !b && this.isEval() && ((a = this.getEvalOrigin()), (a += ", ")) 2304 | a = b ? a + b : a + "" 2305 | b = this.getLineNumber() 2306 | null != b && ((a += ":" + b), (b = this.getColumnNumber()) && (a += ":" + b)) 2307 | } 2308 | b = "" 2309 | var c = this.getFunctionName(), 2310 | d = !0, 2311 | e = this.isConstructor() 2312 | if (this.isToplevel() || e) 2313 | e ? (b += "new " + (c || "")) : c ? (b += c) : ((b += a), (d = !1)) 2314 | else { 2315 | e = this.getTypeName() 2316 | "[object Object]" === e && (e = "null") 2317 | var k = this.getMethodName() 2318 | c 2319 | ? (e && 0 != c.indexOf(e) && (b += e + "."), 2320 | (b += c), 2321 | k && c.indexOf("." + k) != c.length - k.length - 1 && (b += " [as " + k + "]")) 2322 | : (b += e + "." + (k || "")) 2323 | } 2324 | d && (b += " (" + a + ")") 2325 | return b 2326 | } 2327 | function r(a) { 2328 | var b = {} 2329 | Object.getOwnPropertyNames(Object.getPrototypeOf(a)).forEach(function(c) { 2330 | b[c] = /^(?:is|get)/.test(c) 2331 | ? function() { 2332 | return a[c].call(a) 2333 | } 2334 | : a[c] 2335 | }) 2336 | b.toString = u 2337 | return b 2338 | } 2339 | function t(b) { 2340 | if (b.isNative()) return b 2341 | var c = b.getFileName() || b.getScriptNameOrSourceURL() 2342 | if (c) { 2343 | var d = b.getLineNumber(), 2344 | e = b.getColumnNumber() - 1 2345 | 1 === d && 62 < e && !k() && !b.isEval() && (e -= 62) 2346 | var h = a({ source: c, line: d, column: e }) 2347 | b = r(b) 2348 | b.getFileName = function() { 2349 | return h.source 2350 | } 2351 | b.getLineNumber = function() { 2352 | return h.line 2353 | } 2354 | b.getColumnNumber = function() { 2355 | return h.column + 1 2356 | } 2357 | b.getScriptNameOrSourceURL = function() { 2358 | return h.source 2359 | } 2360 | return b 2361 | } 2362 | var m = b.isEval() && b.getEvalOrigin() 2363 | m && 2364 | ((m = l(m)), 2365 | (b = r(b)), 2366 | (b.getEvalOrigin = function() { 2367 | return m 2368 | })) 2369 | return b 2370 | } 2371 | function v(a, b) { 2372 | L && ((B = {}), (G = {})) 2373 | return ( 2374 | a + 2375 | b 2376 | .map(function(a) { 2377 | return "\n at " + t(a) 2378 | }) 2379 | .join("") 2380 | ) 2381 | } 2382 | function c(a) { 2383 | var b = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(a.stack) 2384 | if (b) { 2385 | a = b[1] 2386 | var c = +b[2] 2387 | b = +b[3] 2388 | var d = B[a] 2389 | if (!d && D && D.existsSync(a)) 2390 | try { 2391 | d = D.readFileSync(a, "utf8") 2392 | } catch (w) { 2393 | d = "" 2394 | } 2395 | if (d && (d = d.split(/(?:\r\n|\r|\n)/)[c - 1])) 2396 | return a + ":" + c + "\n" + d + "\n" + Array(b).join(" ") + "^" 2397 | } 2398 | return null 2399 | } 2400 | function m() { 2401 | var a = b.emit 2402 | b.emit = function(d) { 2403 | if ("uncaughtException" === d) { 2404 | var e = arguments[1] && arguments[1].stack, 2405 | g = 0 < this.listeners(d).length 2406 | if (e && !g) { 2407 | e = arguments[1] 2408 | if ((g = c(e))) console.error(), console.error(g) 2409 | console.error(e.stack) 2410 | b.exit(1) 2411 | return 2412 | } 2413 | } 2414 | return a.apply(this, arguments) 2415 | } 2416 | } 2417 | var y = q("source-map").SourceMapConsumer, 2418 | C = q("path") 2419 | try { 2420 | var D = q("fs") 2421 | ;(D.existsSync && D.readFileSync) || (D = null) 2422 | } catch (I) {} 2423 | var M = !1, 2424 | K = !1, 2425 | L = !1, 2426 | J = "auto", 2427 | B = {}, 2428 | G = {}, 2429 | H = /^data:application\/json[^,]+base64,/, 2430 | A = [], 2431 | F = [], 2432 | p = n(A) 2433 | A.push(function(a) { 2434 | a = a.trim() 2435 | ;/^file:/.test(a) && 2436 | (a = a.replace(/file:\/\/\/(\w:)?/, function(a, b) { 2437 | return b ? "" : "/" 2438 | })) 2439 | if (a in B) return B[a] 2440 | var b = null 2441 | if (!D) { 2442 | var c = new XMLHttpRequest() 2443 | c.open("GET", a, !1) 2444 | c.send(null) 2445 | b = null 2446 | 4 === c.readyState && 200 === c.status && (b = c.responseText) 2447 | } else if (D.existsSync(a)) 2448 | try { 2449 | b = D.readFileSync(a, "utf8") 2450 | } catch (g) { 2451 | b = "" 2452 | } 2453 | return (B[a] = b) 2454 | }) 2455 | var E = n(F) 2456 | F.push(function(a) { 2457 | a: { 2458 | if (k()) 2459 | try { 2460 | // this isnt necessary and it causes browser console warnings 2461 | // var b = new XMLHttpRequest() 2462 | // b.open("GET", a, !1) 2463 | // b.send(null) 2464 | // var c = b.getResponseHeader("SourceMap") || b.getResponseHeader("X-SourceMap") 2465 | // if (c) { 2466 | // var g = c 2467 | // break a 2468 | // } 2469 | } catch (P) {} 2470 | g = p(a) 2471 | b = /(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^\*]+?)[ \t]*(?:\*\/)[ \t]*$)/gm 2472 | for (var h; (c = b.exec(g)); ) h = c 2473 | g = h ? h[1] : null 2474 | } 2475 | if (!g) return null 2476 | H.test(g) 2477 | ? ((h = g.slice(g.indexOf(",") + 1)), (h = new e(h, "base64").toString()), (g = a)) 2478 | : ((g = d(a, g)), (h = p(g))) 2479 | return h ? { url: g, map: h } : null 2480 | }) 2481 | h.wrapCallSite = t 2482 | h.getErrorSource = c 2483 | h.mapSourcePosition = a 2484 | h.retrieveSourceMap = E 2485 | h.install = function(a) { 2486 | a = a || {} 2487 | if ( 2488 | a.environment && 2489 | ((J = a.environment), -1 === ["node", "browser", "auto"].indexOf(J)) 2490 | ) 2491 | throw Error( 2492 | "environment " + J + " was unknown. Available options are {auto, browser, node}" 2493 | ) 2494 | a.retrieveFile && 2495 | (a.overrideRetrieveFile && (A.length = 0), A.unshift(a.retrieveFile)) 2496 | a.retrieveSourceMap && 2497 | (a.overrideRetrieveSourceMap && (F.length = 0), F.unshift(a.retrieveSourceMap)) 2498 | if (a.hookRequire && !k()) { 2499 | try { 2500 | var c = q("module") 2501 | } catch (g) {} 2502 | var d = c.prototype._compile 2503 | d.__sourceMapSupport || 2504 | ((c.prototype._compile = function(a, b) { 2505 | B[b] = a 2506 | G[b] = void 0 2507 | return d.call(this, a, b) 2508 | }), 2509 | (c.prototype._compile.__sourceMapSupport = !0)) 2510 | } 2511 | L || (L = "emptyCacheBetweenOperations" in a ? a.emptyCacheBetweenOperations : !1) 2512 | M || ((M = !0), (Error.prepareStackTrace = v)) 2513 | !K && 2514 | ("handleUncaughtExceptions" in a ? a.handleUncaughtExceptions : 1) && 2515 | "object" === typeof b && 2516 | null !== b && 2517 | "function" === typeof b.on && 2518 | ((K = !0), m()) 2519 | } 2520 | }.call(this, q("node_modules/process/browser.js"), q("buffer").Buffer)) 2521 | }, 2522 | { 2523 | "node_modules/process/browser.js": 7, 2524 | buffer: 4, 2525 | fs: 3, 2526 | module: 3, 2527 | path: 6, 2528 | "source-map": 18 2529 | } 2530 | ] 2531 | }, 2532 | {}, 2533 | [1] 2534 | ) 2535 | return N 2536 | }) 2537 | -------------------------------------------------------------------------------- /src/monitor/Info.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import PropTypes from "prop-types" 3 | import styled from "styled-components" 4 | 5 | const propTypes = { 6 | currentBreakpoint: PropTypes.string, 7 | setBreakpoint: PropTypes.func.isRequired, 8 | theme: PropTypes.object.isRequired 9 | } 10 | 11 | const Header = styled.h3` 12 | font-size: 1.1rem; 13 | margin-top: 1.5rem; 14 | line-height: 1.3; 15 | margin-bottom: 1rem; 16 | font-weight: bold; 17 | color: ${props => props.theme.base05}; 18 | ` 19 | 20 | const Button = styled.button` 21 | margin: 0 0 1rem 0; 22 | padding: 0; 23 | border: 0; 24 | border-radius: 3px; 25 | background: none; 26 | font-size: 100%; 27 | vertical-align: baseline; 28 | font-family: inherit; 29 | font-weight: inherit; 30 | color: ${props => props.theme.base00}; 31 | -webkit-appearance: none; 32 | -moz-appearance: none; 33 | appearance: none; 34 | -webkit-font-smoothing: antialiased; 35 | background-color: ${props => props.theme.base0D}; 36 | padding: 8px 12px; 37 | font-weight: bold; 38 | cursor: pointer; 39 | &:hover, 40 | &:focus { 41 | background-color: ${props => props.theme.base0D}; 42 | } 43 | ` 44 | 45 | const SpacingWrapper = styled.div` 46 | margin-top: 1rem; 47 | margin-bottom: 1rem; 48 | ` 49 | 50 | const Info = ({ currentBreakpoint, setBreakpoint, theme }) => { 51 | const removeBreakpoint = () => setBreakpoint("") 52 | 53 | return ( 54 |
55 |
About this tool
56 |
57 |

58 | This monitor shows you a view of your Redux store based on what parts of it your code has 59 | actually touched. Values that have not been accessed are faded out. To learn more, check 60 | out{" "} 61 | 62 | the README. 63 | 64 |

65 |
66 |
Setting a breakpoint
67 |
68 | {!!currentBreakpoint && ( 69 |
70 | There is currently a breakpoint set at{" "} 71 | 72 |
73 |                 {currentBreakpoint}
74 |               
75 |
76 | 79 |
80 | )} 81 |

Shift + click a key in the "Redux Usage" view to set a breakpoint.

82 |

83 | You can reload the page with your devtools open and execution will stop whenever that 84 | value in your store is accessed by your app. 85 |

86 |
87 |
88 | ) 89 | } 90 | 91 | Info.propTypes = propTypes 92 | 93 | export default Info 94 | -------------------------------------------------------------------------------- /src/monitor/ReduxTree.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react" 2 | import PropTypes from "prop-types" 3 | import JSONTree from "react-json-tree" 4 | import styled from "styled-components" 5 | 6 | const FadeSpan = styled.span` 7 | opacity: ${props => (props.fullOpacity ? 1 : 0.3)}; 8 | font-size: 16.5px; 9 | line-height: 1.4; 10 | ` 11 | 12 | const KeySpan = FadeSpan.extend` 13 | position: relative; 14 | color: ${props => (props.breakpointActive ? "red" : null)}; 15 | font-weight: ${props => (props.breakpointActive ? "bold" : "normal")}; 16 | cursor: pointer; 17 | ` 18 | 19 | const InfoContainer = styled.div` 20 | margin-top: 1.5rem; 21 | margin-bottom: 1rem; 22 | ` 23 | 24 | class ReduxTree extends Component { 25 | static propTypes = { 26 | theme: PropTypes.object.isRequired, 27 | currentBreakpoint: PropTypes.string, 28 | setBreakpoint: PropTypes.func.isRequired, 29 | used: PropTypes.object.isRequired, 30 | stateCopy: PropTypes.object.isRequired 31 | } 32 | 33 | isUsed(path) { 34 | let used = this.props.used 35 | for (let i = 0; i < path.length; i++) { 36 | used = used[path[i]] 37 | // null is used as placeholders in arrays 38 | if (used === undefined || used === null) return false 39 | } 40 | return true 41 | } 42 | 43 | setBreakpointOnClick = breakpointPath => e => { 44 | if (!e.shiftKey) return 45 | if (breakpointPath === this.props.currentBreakpoint) { 46 | this.props.setBreakpoint("") 47 | } else { 48 | this.props.setBreakpoint(breakpointPath) 49 | } 50 | e.stopPropagation() 51 | } 52 | 53 | getItemString = (type, data, itemType, itemString) => {itemType} 54 | 55 | valueRenderer = (val, ...args) => { 56 | const isUsed = this.isUsed(args.slice(1).reverse()) 57 | return {val} 58 | } 59 | 60 | labelRenderer = (keyPath, type) => { 61 | const isUsed = this.isUsed(keyPath.slice().reverse()) 62 | const breakpointPath = keyPath 63 | .slice() 64 | .reverse() 65 | .join(".") 66 | 67 | const breakpointActive = breakpointPath === this.props.currentBreakpoint 68 | 69 | return ( 70 | 75 | {keyPath[0]} 76 | 77 | ) 78 | } 79 | 80 | render() { 81 | const { used, stateCopy, theme, currentBreakpoint } = this.props 82 | const usedLength = JSON.stringify(used).length 83 | const totalLength = JSON.stringify(stateCopy).length 84 | const percentUsed = usedLength > 2 ? `${Math.round(usedLength / totalLength * 100)}%` : "N/A" 85 | 86 | return ( 87 |
88 | 89 | Estimated percentage used: {percentUsed} 90 | 91 | 104 |
105 | ) 106 | } 107 | } 108 | 109 | export default ReduxTree 110 | -------------------------------------------------------------------------------- /src/monitor/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react" 2 | import PropTypes from "prop-types" 3 | import styled from "styled-components" 4 | import isEqual from "lodash.isequal" 5 | import theme from "./theme" 6 | import Info from "./Info" 7 | import ReduxTree from "./ReduxTree" 8 | 9 | const localStorageKey = "reduxUsageReportBreakpoints" 10 | 11 | const Container = styled.div` 12 | background-color: ${props => props.theme.base00}; 13 | position: absolute; 14 | top: 0; 15 | left: 0; 16 | right: 0; 17 | bottom: 0; 18 | overflow-y: auto; 19 | font-size: 16px; 20 | font-weight: normal; 21 | color: ${props => props.theme.base05}; 22 | 23 | p { 24 | line-height: 1.5; 25 | } 26 | 27 | a { 28 | color: ${props => props.theme.base0D}; 29 | font-weight: bold; 30 | text-decoration: none; 31 | &:hover, 32 | &:focus { 33 | text-decoration: underline; 34 | } 35 | } 36 | ` 37 | 38 | const TabContainer = styled.ul` 39 | display: flex; 40 | padding: 0; 41 | margin: 0; 42 | list-style: none; 43 | li { 44 | flex: 1; 45 | } 46 | a { 47 | font-weight: normal; 48 | } 49 | ` 50 | 51 | const Tab = styled.a` 52 | display: block; 53 | text-decoration: none !important; 54 | text-align: center; 55 | font-weight: ${props => (props.active ? "bold" : "normal")}; 56 | background-color: ${props => `fade-out(${props.theme.base07}, 0.9)`}; 57 | padding: 1rem; 58 | color: ${props => (props.active ? `${props.theme.base07} !important` : props.theme.base0D)}; 59 | border-bottom: 3px solid transparent; 60 | border-color: ${props => (props.active ? props.theme.base0D : props.theme.base02)}; 61 | background-color: ${props => (props.active ? "hsla(0, 0%, 100%, 0.08)" : null)}; 62 | &:hover { 63 | background-color: ${props => 64 | props.active ? "hsla(0, 0%, 100%, 0.08)" : "hsla(0, 0%, 100%, 0.03)"}; 65 | } 66 | ` 67 | 68 | const ContentContainer = styled.div` 69 | padding: 0 1.5rem 0 1.5rem; 70 | ` 71 | 72 | class ReduxUsageMonitor extends Component { 73 | static propTypes = { 74 | computedStates: PropTypes.array 75 | } 76 | 77 | static update = function() {} 78 | 79 | state = { 80 | showInfo: false, 81 | currentBreakpoint: localStorage[localStorageKey], 82 | used: {}, 83 | stateCopy: {} 84 | } 85 | 86 | componentDidMount() { 87 | this.updateReport() 88 | // not sure why this bind is necessary 89 | window.reduxReport.setOnChangeCallback(this.updateReport.bind(this)) 90 | } 91 | 92 | componentWillUnmount() { 93 | window.reduxReport.removeOnChangeCallback() 94 | } 95 | 96 | updateReport = () => { 97 | const report = window.reduxReport.generate() 98 | if (isEqual(report.used, this.state.used) && isEqual(report.stateCopy, this.state.stateCopy)) 99 | return 100 | this.setState({ 101 | used: report.used, 102 | stateCopy: report.stateCopy 103 | }) 104 | } 105 | 106 | setBreakpoint = breakpointPath => { 107 | window.reduxReport.setBreakpoint(breakpointPath) 108 | this.setState({ currentBreakpoint: breakpointPath }) 109 | } 110 | 111 | showInfo = () => { 112 | this.setState({ showInfo: true }) 113 | } 114 | hideInfo = () => { 115 | this.setState({ showInfo: false }) 116 | } 117 | 118 | render() { 119 | return ( 120 | 121 | 122 |
  • 123 | 124 | Redux Usage 125 | 126 |
  • 127 |
  • 128 | 129 | More Info 130 | 131 |
  • 132 |
    133 | 134 | 135 |
    136 | 144 |
    145 |
    146 | 153 |
    154 |
    155 |
    156 | ) 157 | } 158 | } 159 | 160 | export default ReduxUsageMonitor 161 | -------------------------------------------------------------------------------- /src/monitor/theme.js: -------------------------------------------------------------------------------- 1 | export default { 2 | scheme: "nicinabox", 3 | author: "nicinabox (http://github.com/nicinabox)", 4 | base00: "#2A2F3A", 5 | base01: "#3C444F", 6 | base02: "#4F5A65", 7 | base03: "#BEBEBE", 8 | base04: "#b0b0b0", // based on ocean theme 9 | base05: "#d0d0d0", // based on ocean theme 10 | base06: "#FFFFFF", 11 | base07: "#f5f5f5", // based on ocean theme 12 | base08: "#fb9fb1", // based on ocean theme 13 | base09: "#FC6D24", 14 | base0A: "#ddb26f", // based on ocean theme 15 | base0B: "#A1C659", 16 | base0C: "#12cfc0", // based on ocean theme 17 | base0D: "#6FB3D2", 18 | base0E: "#D381C3", 19 | base0F: "#deaf8f" // based on ocean theme 20 | } 21 | -------------------------------------------------------------------------------- /src/saveReport.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | export default function saveReport (global) { 4 | const report = global.reduxReport.generate() 5 | if (!fs || !report) throw new Error('Could not save redux use report') 6 | 7 | const reportTypes = ['used', 'unused'] 8 | reportTypes.forEach(descriptor => { 9 | fs.writeFile(`./redux_report--${descriptor}.json`, JSON.stringify(report[descriptor]), err => { 10 | if (err) throw err 11 | console.log(`The ${descriptor} redux report has been saved!`) 12 | }) 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /src/trackObjectUse.js: -------------------------------------------------------------------------------- 1 | import { isObjectOrArray, isUndefined } from "./utility" 2 | 3 | export const UNPROXIED_OBJ_KEY = "**__GET_INITIAL_PROXY_VAL__**" 4 | 5 | const getUnproxiedObject = target => 6 | target[UNPROXIED_OBJ_KEY] !== undefined ? target[UNPROXIED_OBJ_KEY] : target 7 | 8 | export const getChildObject = (obj, stateLocation) => { 9 | if (!stateLocation) return obj 10 | return stateLocation.split(".").reduce((acc, key) => { 11 | return acc[key] 12 | }, obj) 13 | } 14 | 15 | export const createMakeProxyFunction = ({ 16 | accessedProperties, 17 | keepOriginalValues = false, 18 | shouldSkipProxy = () => false, 19 | getBreakpoint = () => {}, 20 | onChange = () => {} 21 | }) => { 22 | return function makeProxy(obj, stateLocation = "") { 23 | const handler = { 24 | get(target, propKey) { 25 | if (propKey === UNPROXIED_OBJ_KEY) return target 26 | const value = target[propKey] 27 | 28 | if ( 29 | !Object.hasOwnProperty.call(target, propKey) || 30 | (Array.isArray(target) && propKey === "length") 31 | ) 32 | return value 33 | 34 | if (shouldSkipProxy()) return value 35 | 36 | const newStateLocation = stateLocation ? stateLocation + "." + propKey : propKey 37 | 38 | // allow people to examine the stack at certain access points 39 | if (getBreakpoint() === newStateLocation) { 40 | // explore the callstack to see when your app accesses a value 41 | debugger 42 | } 43 | 44 | const accessedPropertiesPointer = getChildObject(accessedProperties, stateLocation) 45 | 46 | if (isObjectOrArray(value)) { 47 | if (isUndefined(accessedPropertiesPointer[propKey])) { 48 | accessedPropertiesPointer[propKey] = Array.isArray(value) ? [] : {} 49 | onChange(newStateLocation) 50 | } 51 | return makeProxy(value, newStateLocation) 52 | } else { 53 | if ( 54 | isUndefined(accessedPropertiesPointer[propKey]) || 55 | (!keepOriginalValues && value !== accessedPropertiesPointer[propKey]) 56 | ) { 57 | accessedPropertiesPointer[propKey] = value 58 | onChange(newStateLocation) 59 | } 60 | return value 61 | } 62 | } 63 | } 64 | // prevent double-wrapping proxies 65 | const unproxiedObj = getUnproxiedObject(obj) 66 | return new Proxy(unproxiedObj, handler) 67 | } 68 | } 69 | 70 | export default function trackObjectUse(obj, { keepOriginalValues = true } = {}) { 71 | const accessedProperties = {} 72 | const makeProxy = createMakeProxyFunction({ accessedProperties, keepOriginalValues }) 73 | const trackedObject = makeProxy(obj) 74 | return { trackedObject, accessedProperties } 75 | } 76 | -------------------------------------------------------------------------------- /src/utility.js: -------------------------------------------------------------------------------- 1 | export const isObjectOrArray = x => x === Object(x) && typeof x !== 'function' 2 | export const isUndefined = x => x === undefined 3 | -------------------------------------------------------------------------------- /todomvc-example/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # production 7 | build 8 | 9 | # misc 10 | .DS_Store 11 | npm-debug.log 12 | 13 | redux-usage-report 14 | -------------------------------------------------------------------------------- /todomvc-example/README.md: -------------------------------------------------------------------------------- 1 | # Redux TodoMVC Example 2 | 3 | This project template was built with [Create React App](https://github.com/facebookincubator/create-react-app), which provides a simple way to start React projects with no build configuration needed. 4 | 5 | Projects built with Create-React-App include support for ES6 syntax, as well as several unofficial / not-yet-final forms of Javascript syntax such as Class Properties and JSX. See the list of [language features and polyfills supported by Create-React-App](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#supported-language-features-and-polyfills) for more information. 6 | 7 | ## Available Scripts 8 | 9 | In the project directory, you can run: 10 | 11 | ### `npm start` 12 | 13 | Runs the app in the development mode.
    14 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 15 | 16 | The page will reload if you make edits.
    17 | You will also see any lint errors in the console. 18 | 19 | ### `npm run build` 20 | 21 | Builds the app for production to the `build` folder.
    22 | It correctly bundles React in production mode and optimizes the build for the best performance. 23 | 24 | The build is minified and the filenames include the hashes.
    25 | Your app is ready to be deployed! 26 | 27 | ### `npm run eject` 28 | 29 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 30 | 31 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 32 | 33 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 34 | 35 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 36 | -------------------------------------------------------------------------------- /todomvc-example/config/env.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const paths = require('./paths'); 6 | 7 | // Make sure that including paths.js after env.js will read .env variables. 8 | delete require.cache[require.resolve('./paths')]; 9 | 10 | const NODE_ENV = process.env.NODE_ENV; 11 | if (!NODE_ENV) { 12 | throw new Error( 13 | 'The NODE_ENV environment variable is required but was not specified.' 14 | ); 15 | } 16 | 17 | // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use 18 | var dotenvFiles = [ 19 | `${paths.dotenv}.${NODE_ENV}.local`, 20 | `${paths.dotenv}.${NODE_ENV}`, 21 | // Don't include `.env.local` for `test` environment 22 | // since normally you expect tests to produce the same 23 | // results for everyone 24 | NODE_ENV !== 'test' && `${paths.dotenv}.local`, 25 | paths.dotenv, 26 | ].filter(Boolean); 27 | 28 | // Load environment variables from .env* files. Suppress warnings using silent 29 | // if this file is missing. dotenv will never modify any environment variables 30 | // that have already been set. Variable expansion is supported in .env files. 31 | // https://github.com/motdotla/dotenv 32 | // https://github.com/motdotla/dotenv-expand 33 | dotenvFiles.forEach(dotenvFile => { 34 | if (fs.existsSync(dotenvFile)) { 35 | require('dotenv-expand')( 36 | require('dotenv').config({ 37 | path: dotenvFile, 38 | }) 39 | ); 40 | } 41 | }); 42 | 43 | // We support resolving modules according to `NODE_PATH`. 44 | // This lets you use absolute paths in imports inside large monorepos: 45 | // https://github.com/facebookincubator/create-react-app/issues/253. 46 | // It works similar to `NODE_PATH` in Node itself: 47 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders 48 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. 49 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. 50 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421 51 | // We also resolve them to make sure all tools using them work consistently. 52 | const appDirectory = fs.realpathSync(process.cwd()); 53 | process.env.NODE_PATH = (process.env.NODE_PATH || '') 54 | .split(path.delimiter) 55 | .filter(folder => folder && !path.isAbsolute(folder)) 56 | .map(folder => path.resolve(appDirectory, folder)) 57 | .join(path.delimiter); 58 | 59 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be 60 | // injected into the application via DefinePlugin in Webpack configuration. 61 | const REACT_APP = /^REACT_APP_/i; 62 | 63 | function getClientEnvironment(publicUrl) { 64 | const raw = Object.keys(process.env) 65 | .filter(key => REACT_APP.test(key)) 66 | .reduce( 67 | (env, key) => { 68 | env[key] = process.env[key]; 69 | return env; 70 | }, 71 | { 72 | // Useful for determining whether we’re running in production mode. 73 | // Most importantly, it switches React into the correct mode. 74 | NODE_ENV: process.env.NODE_ENV || 'development', 75 | // Useful for resolving the correct path to static assets in `public`. 76 | // For example, . 77 | // This should only be used as an escape hatch. Normally you would put 78 | // images into the `src` and `import` them in code to get their paths. 79 | PUBLIC_URL: publicUrl, 80 | } 81 | ); 82 | // Stringify all values so we can feed into Webpack DefinePlugin 83 | const stringified = { 84 | 'process.env': Object.keys(raw).reduce((env, key) => { 85 | env[key] = JSON.stringify(raw[key]); 86 | return env; 87 | }, {}), 88 | }; 89 | 90 | return { raw, stringified }; 91 | } 92 | 93 | module.exports = getClientEnvironment; 94 | -------------------------------------------------------------------------------- /todomvc-example/config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/en/webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /todomvc-example/config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | // This is a custom Jest transformer turning file imports into filenames. 6 | // http://facebook.github.io/jest/docs/en/webpack.html 7 | 8 | module.exports = { 9 | process(src, filename) { 10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`; 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /todomvc-example/config/paths.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const url = require('url'); 6 | 7 | // Make sure any symlinks in the project folder are resolved: 8 | // https://github.com/facebookincubator/create-react-app/issues/637 9 | const appDirectory = fs.realpathSync(process.cwd()); 10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath); 11 | 12 | const envPublicUrl = process.env.PUBLIC_URL; 13 | 14 | function ensureSlash(path, needsSlash) { 15 | const hasSlash = path.endsWith('/'); 16 | if (hasSlash && !needsSlash) { 17 | return path.substr(path, path.length - 1); 18 | } else if (!hasSlash && needsSlash) { 19 | return `${path}/`; 20 | } else { 21 | return path; 22 | } 23 | } 24 | 25 | const getPublicUrl = appPackageJson => 26 | envPublicUrl || require(appPackageJson).homepage; 27 | 28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer 29 | // "public path" at which the app is served. 30 | // Webpack needs to know it to put the right