{"action":"created","comment":{"url":"https://api.github.com/repos/plotly/plotly.js/pulls/comments/84483250","pull_request_review_id":5260261,"id":84483250,"diff_hunk":"@@ -0,0 +1,477 @@\n+var Plotly = require('@lib/index');\n+var PlotlyInternal = require('@src/plotly');\n+var Plots = Plotly.Plots;\n+var createGraphDiv = require('../assets/create_graph_div');\n+var destroyGraphDiv = require('../assets/destroy_graph_div');\n+var fail = require('../assets/fail_test');\n+var Lib = require('@src/lib');\n+\n+describe('Plots.executeAPICommand', function() {\n+    'use strict';\n+\n+    var gd;\n+\n+    beforeEach(function() {\n+        gd = createGraphDiv();\n+    });\n+\n+    afterEach(function() {\n+        destroyGraphDiv(gd);\n+    });\n+\n+    describe('with a successful API command', function() {\n+        beforeEach(function() {\n+            spyOn(PlotlyInternal, 'restyle').and.callFake(function() {\n+                return Promise.resolve('resolution');\n+            });\n+        });\n+\n+        it('calls the API method and resolves', function(done) {\n+            Plots.executeAPICommand(gd, 'restyle', ['foo', 'bar']).then(function(value) {\n+                var m = PlotlyInternal.restyle;\n+                expect(m).toHaveBeenCalled();\n+                expect(m.calls.count()).toEqual(1);\n+                expect(m.calls.argsFor(0)).toEqual([gd, 'foo', 'bar']);\n+\n+                expect(value).toEqual('resolution');\n+            }).catch(fail).then(done);\n+        });\n+\n+    });\n+\n+    describe('with an unsuccessful command', function() {\n+        beforeEach(function() {\n+            spyOn(PlotlyInternal, 'restyle').and.callFake(function() {\n+                return Promise.reject('rejection');\n+            });\n+        });\n+\n+        it('calls the API method and rejects', function(done) {\n+            Plots.executeAPICommand(gd, 'restyle', ['foo', 'bar']).then(fail, function(value) {\n+                var m = PlotlyInternal.restyle;\n+                expect(m).toHaveBeenCalled();\n+                expect(m.calls.count()).toEqual(1);\n+                expect(m.calls.argsFor(0)).toEqual([gd, 'foo', 'bar']);\n+\n+                expect(value).toEqual('rejection');\n+            }).catch(fail).then(done);\n+        });\n+\n+    });\n+});\n+\n+describe('Plots.hasSimpleAPICommandBindings', function() {\n+    'use strict';\n+    var gd;\n+    beforeEach(function() {\n+        gd = createGraphDiv();\n+\n+        Plotly.plot(gd, [\n+            {x: [1, 2, 3], y: [1, 2, 3]},\n+            {x: [1, 2, 3], y: [4, 5, 6]},\n+        ]);\n+    });\n+\n+    afterEach(function() {\n+        destroyGraphDiv(gd);\n+    });\n+\n+    it('return the binding when bindings are simple', function() {\n+        var isSimple = Plots.hasSimpleAPICommandBindings(gd, [{\n+            method: 'restyle',\n+            args: [{'marker.size': 10}]\n+        }, {\n+            method: 'restyle',\n+            args: [{'marker.size': 20}]\n+        }]);\n+\n+        expect(isSimple).toEqual({\n+            type: 'data',\n+            prop: 'marker.size',\n+            traces: null,\n+            value: 10\n+        });\n+    });\n+\n+    it('return false when properties are not the same', function() {\n+        var isSimple = Plots.hasSimpleAPICommandBindings(gd, [{\n+            method: 'restyle',\n+            args: [{'marker.size': 10}]\n+        }, {\n+            method: 'restyle',\n+            args: [{'marker.color': 20}]\n+        }]);\n+\n+        expect(isSimple).toBe(false);\n+    });\n+\n+    it('return false when a command binds to more than one property', function() {\n+        var isSimple = Plots.hasSimpleAPICommandBindings(gd, [{\n+            method: 'restyle',\n+            args: [{'marker.color': 10, 'marker.size': 12}]\n+        }, {\n+            method: 'restyle',\n+            args: [{'marker.color': 20}]\n+        }]);\n+\n+        expect(isSimple).toBe(false);\n+    });\n+\n+    it('return false when commands affect different traces', function() {\n+        var isSimple = Plots.hasSimpleAPICommandBindings(gd, [{\n+            method: 'restyle',\n+            args: [{'marker.color': 10}, [0]]\n+        }, {\n+            method: 'restyle',\n+            args: [{'marker.color': 20}, [1]]\n+        }]);\n+\n+        expect(isSimple).toBe(false);\n+    });\n+\n+    it('return the binding when commands affect the same traces', function() {\n+        var isSimple = Plots.hasSimpleAPICommandBindings(gd, [{\n+            method: 'restyle',\n+            args: [{'marker.color': 10}, [1]]\n+        }, {\n+            method: 'restyle',\n+            args: [{'marker.color': 20}, [1]]\n+        }]);\n+\n+        expect(isSimple).toEqual({\n+            type: 'data',\n+            prop: 'marker.color',\n+            traces: [ 1 ],\n+            value: [ 10 ]\n+        });\n+    });\n+\n+    it('return the binding when commands affect the same traces in different order', function() {\n+        var isSimple = Plots.hasSimpleAPICommandBindings(gd, [{\n+            method: 'restyle',\n+            args: [{'marker.color': 10}, [1, 2]]\n+        }, {\n+            method: 'restyle',\n+            args: [{'marker.color': 20}, [2, 1]]\n+        }]);\n+\n+        expect(isSimple).toEqual({\n+            type: 'data',\n+            prop: 'marker.color',\n+            traces: [ 1, 2 ],\n+            value: [ 10, 10 ]\n+        });\n+    });\n+});\n+\n+describe('Plots.computeAPICommandBindings', function() {\n+    'use strict';\n+\n+    var gd;\n+\n+    beforeEach(function() {\n+        gd = createGraphDiv();\n+\n+        Plotly.plot(gd, [\n+            {x: [1, 2, 3], y: [1, 2, 3]},\n+            {x: [1, 2, 3], y: [4, 5, 6]},\n+        ]);\n+    });\n+\n+    afterEach(function() {\n+        destroyGraphDiv(gd);\n+    });\n+\n+    describe('restyle', function() {\n+        describe('with invalid notation', function() {\n+            it('with a scalar value', function() {\n+                var result = Plots.computeAPICommandBindings(gd, 'restyle', [['x']]);\n+                expect(result).toEqual([]);\n+            });\n+        });\n+\n+        describe('with astr + val notation', function() {\n+            describe('and a single attribute', function() {\n+                it('with a scalar value', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', ['marker.size', 7]);\n+                    expect(result).toEqual([{prop: 'marker.size', traces: null, type: 'data', value: 7}]);\n+                });\n+\n+                it('with an array value and no trace specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', ['marker.size', [7]]);\n+                    expect(result).toEqual([{prop: 'marker.size', traces: [0], type: 'data', value: [7]}]);\n+                });\n+\n+                it('with trace specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', ['marker.size', 7, [0]]);\n+                    expect(result).toEqual([{prop: 'marker.size', traces: [0], type: 'data', value: [7]}]);\n+                });\n+\n+                it('with a different trace specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', ['marker.size', 7, [0]]);\n+                    expect(result).toEqual([{prop: 'marker.size', traces: [0], type: 'data', value: [7]}]);\n+                });\n+\n+                it('with an array value', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', ['marker.size', [7], [1]]);\n+                    expect(result).toEqual([{prop: 'marker.size', traces: [1], type: 'data', value: [7]}]);\n+                });\n+\n+                it('with two array values and two traces specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', ['marker.size', [7, 5], [0, 1]]);\n+                    expect(result).toEqual([{prop: 'marker.size', traces: [0, 1], type: 'data', value: [7, 5]}]);\n+                });\n+\n+                it('with traces specified in reverse order', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', ['marker.size', [7, 5], [1, 0]]);\n+                    expect(result).toEqual([{prop: 'marker.size', traces: [1, 0], type: 'data', value: [7, 5]}]);\n+                });\n+\n+                it('with two values and a single trace specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', ['marker.size', [7, 5], [0]]);\n+                    expect(result).toEqual([{prop: 'marker.size', traces: [0], type: 'data', value: [7]}]);\n+                });\n+\n+                it('with two values and a different trace specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', ['marker.size', [7, 5], [1]]);\n+                    expect(result).toEqual([{prop: 'marker.size', traces: [1], type: 'data', value: [7]}]);\n+                });\n+            });\n+        });\n+\n+\n+        describe('with aobj notation', function() {\n+            describe('and a single attribute', function() {\n+                it('with a scalar value', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', [{'marker.size': 7}]);\n+                    expect(result).toEqual([{type: 'data', prop: 'marker.size', traces: null, value: 7}]);\n+                });\n+\n+                it('with trace specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', [{'marker.size': 7}, [0]]);\n+                    expect(result).toEqual([{type: 'data', prop: 'marker.size', traces: [0], value: [7]}]);\n+                });\n+\n+                it('with a different trace specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', [{'marker.size': 7}, [1]]);\n+                    expect(result).toEqual([{type: 'data', prop: 'marker.size', traces: [1], value: [7]}]);\n+                });\n+\n+                it('with an array value', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', [{'marker.size': [7]}, [1]]);\n+                    expect(result).toEqual([{type: 'data', prop: 'marker.size', traces: [1], value: [7]}]);\n+                });\n+\n+                it('with two array values and two traces specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', [{'marker.size': [7, 5]}, [0, 1]]);\n+                    expect(result).toEqual([{type: 'data', prop: 'marker.size', traces: [0, 1], value: [7, 5]}]);\n+                });\n+\n+                it('with traces specified in reverse order', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', [{'marker.size': [7, 5]}, [1, 0]]);\n+                    expect(result).toEqual([{type: 'data', prop: 'marker.size', traces: [1, 0], value: [7, 5]}]);\n+                });\n+\n+                it('with two values and a single trace specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', [{'marker.size': [7, 5]}, [0]]);\n+                    expect(result).toEqual([{type: 'data', prop: 'marker.size', traces: [0], value: [7]}]);\n+                });\n+\n+                it('with two values and a different trace specified', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', [{'marker.size': [7, 5]}, [1]]);\n+                    expect(result).toEqual([{type: 'data', prop: 'marker.size', traces: [1], value: [7]}]);\n+                });\n+            });\n+\n+            describe('and multiple attributes', function() {\n+                it('with a scalar value', function() {\n+                    var result = Plots.computeAPICommandBindings(gd, 'restyle', [{'marker.size': 7, 'text.color': 'blue'}]);\n+                    expect(result).toEqual([\n+                        {type: 'data', prop: 'marker.size', traces: null, value: 7},\n+                        {type: 'data', prop: 'text.color', traces: null, value: 'blue'}\n+                    ]);\n+                });\n+            });\n+        });\n+\n+        describe('with mixed notation', function() {\n+            it('and nested object and nested attr', function() {\n+                var result = Plots.computeAPICommandBindings(gd, 'restyle', [{\n+                    y: [[3, 4, 5]],\n+                    'marker.size': [10, 20, 25],\n+                    'line.color': 'red',\n+                    line: {\n+                        width: [2, 8]\n+                    }\n+                }]);\n+\n+                // The results are definitely not completely intuitive, so this\n+                // is based upon empirical results with a codepen example:\n+                expect(result).toEqual([\n+                    {type: 'data', prop: 'y', traces: [0], value: [[3, 4, 5]]},\n+                    {type: 'data', prop: 'marker.size', traces: [0, 1], value: [10, 20]},\n+                    {type: 'data', prop: 'line.color', traces: null, value: 'red'},\n+                    {type: 'data', prop: 'line.width', traces: [0, 1], value: [2, 8]}\n+                ]);\n+            });\n+\n+            it('and traces specified', function() {\n+                var result = Plots.computeAPICommandBindings(gd, 'restyle', [{\n+                    y: [[3, 4, 5]],\n+                    'marker.size': [10, 20, 25],\n+                    'line.color': 'red',\n+                    line: {","path":"test/jasmine/tests/command_test.js","position":303,"original_position":323,"commit_id":"26ad1ff46c0ae24ac0827fcd9017f48696b7cf35","original_commit_id":"26ad1ff46c0ae24ac0827fcd9017f48696b7cf35","user":{"login":"etpinard","id":6675409,"avatar_url":"https://avatars.githubusercontent.com/u/6675409?v=3","gravatar_id":"","url":"https://api.github.com/users/etpinard","html_url":"https://github.com/etpinard","followers_url":"https://api.github.com/users/etpinard/followers","following_url":"https://api.github.com/users/etpinard/following{/other_user}","gists_url":"https://api.github.com/users/etpinard/gists{/gist_id}","starred_url":"https://api.github.com/users/etpinard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/etpinard/subscriptions","organizations_url":"https://api.github.com/users/etpinard/orgs","repos_url":"https://api.github.com/users/etpinard/repos","events_url":"https://api.github.com/users/etpinard/events{/privacy}","received_events_url":"https://api.github.com/users/etpinard/received_events","type":"User","site_admin":false},"body":"> otherwise I'm fine documenting it and moving on\r\n\r\nI'm fine with that also.","created_at":"2016-10-21T13:53:51Z","updated_at":"2016-10-21T13:53:51Z","html_url":"https://github.com/plotly/plotly.js/pull/1016#discussion_r84483250","pull_request_url":"https://api.github.com/repos/plotly/plotly.js/pulls/1016","_links":{"self":{"href":"https://api.github.com/repos/plotly/plotly.js/pulls/comments/84483250"},"html":{"href":"https://github.com/plotly/plotly.js/pull/1016#discussion_r84483250"},"pull_request":{"href":"https://api.github.com/repos/plotly/plotly.js/pulls/1016"}}},"pull_request":{"url":"https://api.github.com/repos/plotly/plotly.js/pulls/1016","id":88287684,"html_url":"https://github.com/plotly/plotly.js/pull/1016","diff_url":"https://github.com/plotly/plotly.js/pull/1016.diff","patch_url":"https://github.com/plotly/plotly.js/pull/1016.patch","issue_url":"https://api.github.com/repos/plotly/plotly.js/issues/1016","number":1016,"state":"open","locked":false,"title":"Common interface to interpret and execute API methods","user":{"login":"rreusser","id":572717,"avatar_url":"https://avatars.githubusercontent.com/u/572717?v=3","gravatar_id":"","url":"https://api.github.com/users/rreusser","html_url":"https://github.com/rreusser","followers_url":"https://api.github.com/users/rreusser/followers","following_url":"https://api.github.com/users/rreusser/following{/other_user}","gists_url":"https://api.github.com/users/rreusser/gists{/gist_id}","starred_url":"https://api.github.com/users/rreusser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rreusser/subscriptions","organizations_url":"https://api.github.com/users/rreusser/orgs","repos_url":"https://api.github.com/users/rreusser/repos","events_url":"https://api.github.com/users/rreusser/events{/privacy}","received_events_url":"https://api.github.com/users/rreusser/received_events","type":"User","site_admin":false},"body":"This PR works toward a common interface for executing commands. This includes:\r\n\r\n- [x] `Plots.executeAPICommand(gd, method, args)` which executes a command (i.e. from components)\r\n- [x] `Plots.computeAPICommandBindings(gd, method, args)` which interprets the intent of a command and returns a list of properties which affect the value of the component.\r\n- [x] cache and check values for bound values\r\n\r\nCompletion of this feature will complete the implementation of sliders (#986) with two-way binding and will be applicable to other components.","created_at":"2016-10-06T15:40:38Z","updated_at":"2016-10-21T13:53:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6e3bd73c593168f328c8b1b911a57312f21c8d2b","assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/plotly/plotly.js/milestones/12","html_url":"https://github.com/plotly/plotly.js/milestones/v1.19.0","labels_url":"https://api.github.com/repos/plotly/plotly.js/milestones/12/labels","id":2068037,"number":12,"title":"v1.19.0","description":"","creator":{"login":"etpinard","id":6675409,"avatar_url":"https://avatars.githubusercontent.com/u/6675409?v=3","gravatar_id":"","url":"https://api.github.com/users/etpinard","html_url":"https://github.com/etpinard","followers_url":"https://api.github.com/users/etpinard/followers","following_url":"https://api.github.com/users/etpinard/following{/other_user}","gists_url":"https://api.github.com/users/etpinard/gists{/gist_id}","starred_url":"https://api.github.com/users/etpinard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/etpinard/subscriptions","organizations_url":"https://api.github.com/users/etpinard/orgs","repos_url":"https://api.github.com/users/etpinard/repos","events_url":"https://api.github.com/users/etpinard/events{/privacy}","received_events_url":"https://api.github.com/users/etpinard/received_events","type":"User","site_admin":false},"open_issues":14,"closed_issues":3,"state":"open","created_at":"2016-10-13T14:45:23Z","updated_at":"2016-10-20T21:21:20Z","due_on":"2016-10-27T00:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/plotly/plotly.js/pulls/1016/commits","review_comments_url":"https://api.github.com/repos/plotly/plotly.js/pulls/1016/comments","review_comment_url":"https://api.github.com/repos/plotly/plotly.js/pulls/comments{/number}","comments_url":"https://api.github.com/repos/plotly/plotly.js/issues/1016/comments","statuses_url":"https://api.github.com/repos/plotly/plotly.js/statuses/26ad1ff46c0ae24ac0827fcd9017f48696b7cf35","head":{"label":"plotly:lib-commands","ref":"lib-commands","sha":"26ad1ff46c0ae24ac0827fcd9017f48696b7cf35","user":{"login":"plotly","id":5997976,"avatar_url":"https://avatars.githubusercontent.com/u/5997976?v=3","gravatar_id":"","url":"https://api.github.com/users/plotly","html_url":"https://github.com/plotly","followers_url":"https://api.github.com/users/plotly/followers","following_url":"https://api.github.com/users/plotly/following{/other_user}","gists_url":"https://api.github.com/users/plotly/gists{/gist_id}","starred_url":"https://api.github.com/users/plotly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plotly/subscriptions","organizations_url":"https://api.github.com/users/plotly/orgs","repos_url":"https://api.github.com/users/plotly/repos","events_url":"https://api.github.com/users/plotly/events{/privacy}","received_events_url":"https://api.github.com/users/plotly/received_events","type":"Organization","site_admin":false},"repo":{"id":45646037,"name":"plotly.js","full_name":"plotly/plotly.js","owner":{"login":"plotly","id":5997976,"avatar_url":"https://avatars.githubusercontent.com/u/5997976?v=3","gravatar_id":"","url":"https://api.github.com/users/plotly","html_url":"https://github.com/plotly","followers_url":"https://api.github.com/users/plotly/followers","following_url":"https://api.github.com/users/plotly/following{/other_user}","gists_url":"https://api.github.com/users/plotly/gists{/gist_id}","starred_url":"https://api.github.com/users/plotly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plotly/subscriptions","organizations_url":"https://api.github.com/users/plotly/orgs","repos_url":"https://api.github.com/users/plotly/repos","events_url":"https://api.github.com/users/plotly/events{/privacy}","received_events_url":"https://api.github.com/users/plotly/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/plotly/plotly.js","description":"The open source javascript graphing library that powers plotly","fork":false,"url":"https://api.github.com/repos/plotly/plotly.js","forks_url":"https://api.github.com/repos/plotly/plotly.js/forks","keys_url":"https://api.github.com/repos/plotly/plotly.js/keys{/key_id}","collaborators_url":"https://api.github.com/repos/plotly/plotly.js/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/plotly/plotly.js/teams","hooks_url":"https://api.github.com/repos/plotly/plotly.js/hooks","issue_events_url":"https://api.github.com/repos/plotly/plotly.js/issues/events{/number}","events_url":"https://api.github.com/repos/plotly/plotly.js/events","assignees_url":"https://api.github.com/repos/plotly/plotly.js/assignees{/user}","branches_url":"https://api.github.com/repos/plotly/plotly.js/branches{/branch}","tags_url":"https://api.github.com/repos/plotly/plotly.js/tags","blobs_url":"https://api.github.com/repos/plotly/plotly.js/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/plotly/plotly.js/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/plotly/plotly.js/git/refs{/sha}","trees_url":"https://api.github.com/repos/plotly/plotly.js/git/trees{/sha}","statuses_url":"https://api.github.com/repos/plotly/plotly.js/statuses/{sha}","languages_url":"https://api.github.com/repos/plotly/plotly.js/languages","stargazers_url":"https://api.github.com/repos/plotly/plotly.js/stargazers","contributors_url":"https://api.github.com/repos/plotly/plotly.js/contributors","subscribers_url":"https://api.github.com/repos/plotly/plotly.js/subscribers","subscription_url":"https://api.github.com/repos/plotly/plotly.js/subscription","commits_url":"https://api.github.com/repos/plotly/plotly.js/commits{/sha}","git_commits_url":"https://api.github.com/repos/plotly/plotly.js/git/commits{/sha}","comments_url":"https://api.github.com/repos/plotly/plotly.js/comments{/number}","issue_comment_url":"https://api.github.com/repos/plotly/plotly.js/issues/comments{/number}","contents_url":"https://api.github.com/repos/plotly/plotly.js/contents/{+path}","compare_url":"https://api.github.com/repos/plotly/plotly.js/compare/{base}...{head}","merges_url":"https://api.github.com/repos/plotly/plotly.js/merges","archive_url":"https://api.github.com/repos/plotly/plotly.js/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/plotly/plotly.js/downloads","issues_url":"https://api.github.com/repos/plotly/plotly.js/issues{/number}","pulls_url":"https://api.github.com/repos/plotly/plotly.js/pulls{/number}","milestones_url":"https://api.github.com/repos/plotly/plotly.js/milestones{/number}","notifications_url":"https://api.github.com/repos/plotly/plotly.js/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/plotly/plotly.js/labels{/name}","releases_url":"https://api.github.com/repos/plotly/plotly.js/releases{/id}","deployments_url":"https://api.github.com/repos/plotly/plotly.js/deployments","created_at":"2015-11-05T23:27:17Z","updated_at":"2016-10-21T10:56:07Z","pushed_at":"2016-10-20T21:21:20Z","git_url":"git://github.com/plotly/plotly.js.git","ssh_url":"git@github.com:plotly/plotly.js.git","clone_url":"https://github.com/plotly/plotly.js.git","svn_url":"https://github.com/plotly/plotly.js","homepage":"https://plot.ly/javascript/","size":152812,"stargazers_count":5472,"watchers_count":5472,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":504,"mirror_url":null,"open_issues_count":231,"forks":504,"open_issues":231,"watchers":5472,"default_branch":"master"}},"base":{"label":"plotly:master","ref":"master","sha":"d90d4e171ec0df47b2fe3a1843cbabb025b9c7c4","user":{"login":"plotly","id":5997976,"avatar_url":"https://avatars.githubusercontent.com/u/5997976?v=3","gravatar_id":"","url":"https://api.github.com/users/plotly","html_url":"https://github.com/plotly","followers_url":"https://api.github.com/users/plotly/followers","following_url":"https://api.github.com/users/plotly/following{/other_user}","gists_url":"https://api.github.com/users/plotly/gists{/gist_id}","starred_url":"https://api.github.com/users/plotly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plotly/subscriptions","organizations_url":"https://api.github.com/users/plotly/orgs","repos_url":"https://api.github.com/users/plotly/repos","events_url":"https://api.github.com/users/plotly/events{/privacy}","received_events_url":"https://api.github.com/users/plotly/received_events","type":"Organization","site_admin":false},"repo":{"id":45646037,"name":"plotly.js","full_name":"plotly/plotly.js","owner":{"login":"plotly","id":5997976,"avatar_url":"https://avatars.githubusercontent.com/u/5997976?v=3","gravatar_id":"","url":"https://api.github.com/users/plotly","html_url":"https://github.com/plotly","followers_url":"https://api.github.com/users/plotly/followers","following_url":"https://api.github.com/users/plotly/following{/other_user}","gists_url":"https://api.github.com/users/plotly/gists{/gist_id}","starred_url":"https://api.github.com/users/plotly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plotly/subscriptions","organizations_url":"https://api.github.com/users/plotly/orgs","repos_url":"https://api.github.com/users/plotly/repos","events_url":"https://api.github.com/users/plotly/events{/privacy}","received_events_url":"https://api.github.com/users/plotly/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/plotly/plotly.js","description":"The open source javascript graphing library that powers plotly","fork":false,"url":"https://api.github.com/repos/plotly/plotly.js","forks_url":"https://api.github.com/repos/plotly/plotly.js/forks","keys_url":"https://api.github.com/repos/plotly/plotly.js/keys{/key_id}","collaborators_url":"https://api.github.com/repos/plotly/plotly.js/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/plotly/plotly.js/teams","hooks_url":"https://api.github.com/repos/plotly/plotly.js/hooks","issue_events_url":"https://api.github.com/repos/plotly/plotly.js/issues/events{/number}","events_url":"https://api.github.com/repos/plotly/plotly.js/events","assignees_url":"https://api.github.com/repos/plotly/plotly.js/assignees{/user}","branches_url":"https://api.github.com/repos/plotly/plotly.js/branches{/branch}","tags_url":"https://api.github.com/repos/plotly/plotly.js/tags","blobs_url":"https://api.github.com/repos/plotly/plotly.js/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/plotly/plotly.js/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/plotly/plotly.js/git/refs{/sha}","trees_url":"https://api.github.com/repos/plotly/plotly.js/git/trees{/sha}","statuses_url":"https://api.github.com/repos/plotly/plotly.js/statuses/{sha}","languages_url":"https://api.github.com/repos/plotly/plotly.js/languages","stargazers_url":"https://api.github.com/repos/plotly/plotly.js/stargazers","contributors_url":"https://api.github.com/repos/plotly/plotly.js/contributors","subscribers_url":"https://api.github.com/repos/plotly/plotly.js/subscribers","subscription_url":"https://api.github.com/repos/plotly/plotly.js/subscription","commits_url":"https://api.github.com/repos/plotly/plotly.js/commits{/sha}","git_commits_url":"https://api.github.com/repos/plotly/plotly.js/git/commits{/sha}","comments_url":"https://api.github.com/repos/plotly/plotly.js/comments{/number}","issue_comment_url":"https://api.github.com/repos/plotly/plotly.js/issues/comments{/number}","contents_url":"https://api.github.com/repos/plotly/plotly.js/contents/{+path}","compare_url":"https://api.github.com/repos/plotly/plotly.js/compare/{base}...{head}","merges_url":"https://api.github.com/repos/plotly/plotly.js/merges","archive_url":"https://api.github.com/repos/plotly/plotly.js/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/plotly/plotly.js/downloads","issues_url":"https://api.github.com/repos/plotly/plotly.js/issues{/number}","pulls_url":"https://api.github.com/repos/plotly/plotly.js/pulls{/number}","milestones_url":"https://api.github.com/repos/plotly/plotly.js/milestones{/number}","notifications_url":"https://api.github.com/repos/plotly/plotly.js/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/plotly/plotly.js/labels{/name}","releases_url":"https://api.github.com/repos/plotly/plotly.js/releases{/id}","deployments_url":"https://api.github.com/repos/plotly/plotly.js/deployments","created_at":"2015-11-05T23:27:17Z","updated_at":"2016-10-21T10:56:07Z","pushed_at":"2016-10-20T21:21:20Z","git_url":"git://github.com/plotly/plotly.js.git","ssh_url":"git@github.com:plotly/plotly.js.git","clone_url":"https://github.com/plotly/plotly.js.git","svn_url":"https://github.com/plotly/plotly.js","homepage":"https://plot.ly/javascript/","size":152812,"stargazers_count":5472,"watchers_count":5472,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":504,"mirror_url":null,"open_issues_count":231,"forks":504,"open_issues":231,"watchers":5472,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/plotly/plotly.js/pulls/1016"},"html":{"href":"https://github.com/plotly/plotly.js/pull/1016"},"issue":{"href":"https://api.github.com/repos/plotly/plotly.js/issues/1016"},"comments":{"href":"https://api.github.com/repos/plotly/plotly.js/issues/1016/comments"},"review_comments":{"href":"https://api.github.com/repos/plotly/plotly.js/pulls/1016/comments"},"review_comment":{"href":"https://api.github.com/repos/plotly/plotly.js/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/plotly/plotly.js/pulls/1016/commits"},"statuses":{"href":"https://api.github.com/repos/plotly/plotly.js/statuses/26ad1ff46c0ae24ac0827fcd9017f48696b7cf35"}}}}
{"actor":{"display_login":"etpinard"}}