{"action":"created","comment":{"url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/comments/40861683","id":40861683,"diff_hunk":"@@ -0,0 +1,76 @@\n+---\n+comments: true\n+date: 2015-09-28 14:00:00\n+layout: post\n+slug: rx-scala-js\n+title: Using Reactive Extensions for data binding in Scala.js\n+summary: In the last post we have written a simple Scala.js app. Now we will look how we can limit the number of moving parts by adding Scala.rx\n+author: Patryk Jażdżewski\n+feed_group: scala\n+tags:\n+- Scala\n+- Scala.js\n+- Frontend\n+---\n+\n+## <a name=\"problem\" href=\"#problem\">The Problem</a>\n+\n+In my previous [post](/2015/09/24/scala_js.html) we have written a simple app with Scala.js. In the end we managed to do everything we wanted to, but as we added more and more code a problem appeared - state management, the real app killer. Although our app didn't do anything advanced, state handling and UI updates forced us to write a lot of additional code. \n+\n+That post has shown that Scala.js allows us to write browser apps, but it also demonstrated that these apps can be vulnerable to other ills of frontend programming. To fix this issue we need to simplify our codebase. One way to do that is by adding a binding between the UI and what data our app holds. This way if the data changes in one place it will be automatically propagated to the other. We will implement this using Reactive Extensions. \n+\n+## <a name=\"rx\" href=\"#rx\">What are Reactive Extensions?</a>\n+\n+<img src=\"https://raw.githubusercontent.com/pjazdzewski1990/scala-js-organizer-example/master/images/Reactive-Extensions.png\" alt=\"Rx\" style=\"width: 90%; height: 90%; display: block; margin-left: auto; margin-right: auto;\"/>\n+\n+Reactive Extensions (Rx for short) is library originally introduced by Erik Meijer to the .NET framework. Rx aims to allow the composition of asynchronous and event-based programs using Observables. It might sound confusing at first, but the idea gets intuitive after you try it out. Observable can be seen as a source of events, hence \"event-based\". We don't know when an event might happen, that's why it's \"asynchronous\". We can observe the source and react on events, thus sources are called Observable. \n+\n+Consider an app that counts the number of clicks on a button. The button will be our Observable and it will emit a \"Click\" event each time it gets clicked. Using Rx we can create a stream of \"Click\" events where each will update a counter. This is the idea behind Reactive Extensions in a nutshell.\n+\n+After being introduced to .NET the idea quickly spread across other languages, including Scala. In our post we will use Scala.Rx created by Li Haoyi. We've chosen this implementation as it's fully compatible with Scala.js. It's no surprise if you consider that creator of Scala.Rx is also the person behind Scala.js.\n+\n+## <a name=\"implementation\" href=\"#implementation\">Reactive Implementation</a>\n+\n+To simplify our organizer we want to create an graph that will propagate changes in our data from one side of the app to another. We will aim to create a graph as depicted below.\n+\n+<img src=\"https://raw.githubusercontent.com/pjazdzewski1990/scala-js-organizer-example/7485bcfbaffccb97111cb829bdc3e09a4bd88edc/images/Final.png\" alt=\"Flow\" style=\"width: 80%; height: 80%; display: block; margin-left: auto; margin-right: auto;\"/>\n+\n+Round shapes represent event sources of various kinds - time, user input, web. Even our TODO data might be used as an event source. Events are then passed to calculations - block shapes with round edges. Based on the calculated values we update the UI. I will explain it step by step. Let's start from our sources. In Scala.Rx we create them using `Var`s as follows:\n+\n+<script src=\"https://gist.github.com/pjazdzewski1990/39c1c302974aac08012e.js\"></script>\n+[\\[ScalaJSExample.scala\\]](https://github.com/pjazdzewski1990/scala-js-organizer-example/blob/1b104db61ecffe5582f0e04fa0e17431ce86eb4f/src/main/scala/example/ScalaJSExample.scala#L24)\n+\n+It get's slightly more complicated with other `Var`s, so let's define a helper trait. \n+\n+<script src=\"https://gist.github.com/pjazdzewski1990/2b87b85eaf411301e172.js\"></script>\n+[\\[Reactive.scala\\]](https://github.com/pjazdzewski1990/scala-js-organizer-example/blob/1b104db61ecffe5582f0e04fa0e17431ce86eb4f/src/main/scala/example/Reactive.scala)\n+\n+That looks quite complicated at first glance, but really it isn't. All we do here is create a `Var` that updates when a browser event happens - interval tick or elements `onClick` handler. We will put those helpers to good use in our main code. \n+\n+<script src=\"https://gist.github.com/pjazdzewski1990/3c3b317e1877b0fa84e5.js\"></script>\n+[\\[ScalaJSExample.scala\\]](https://github.com/pjazdzewski1990/scala-js-organizer-example/blob/1b104db61ecffe5582f0e04fa0e17431ce86eb4f/src/main/scala/example/ScalaJSExample.scala)\n+\n+Having that in place, we can add dependent calculations. In order to make Scala.Rx do it's magic we need to put all calculations depending on sources inside `Rx` blocks or `Obs`. It's as simple as: \n+\n+<script src=\"https://gist.github.com/pjazdzewski1990/a23d3988759aa8b32ca7.js\"></script>\n+[\\[ScalaJSExample.scala\\]](https://github.com/pjazdzewski1990/scala-js-organizer-example/blob/1b104db61ecffe5582f0e04fa0e17431ce86eb4f/src/main/scala/example/ScalaJSExample.scala)\n+\n+If you compare this new solution with the diagram above, you will find out that they are basically the same. Thanks to Rx we turned a stateful spaghetti code into a simple flow. Neat. \n+\n+> What is the difference between `Rx` and `Obs`?\n+>\n+> `Rx` is a definition that automatically captures `Var`s and other `Rx`s in it's block. When those captured elements change, the capturing block is evaluated again with the new values and the capturing `Rx` is updated. \n+> `Obs` can be thought as a more advanced `Rx`. You can do a few more tricks with it - like perform side effects and explicitly define dependencies (which we use in this example).   \n+\n+## <a name=\"summary\" href=\"#summary\">Summary</a>\n+\n+As you can see Rx was immensely useful for reducing boilerplate code and creating a simple flow of values in the system. Reactive Extensions have proven their worth. \n+\n+Creating this bidirectional flow is a step in the right direction - it helped us to manage state. Still when the app grows so does the graph and potentially it may get big and complicated later on. Modern frontend apps deal with this issue by using encapsulated components and unidirectional flows ... but it's something for another post.","path":"_posts/2015-09-21-rx_scala_js.md","position":69,"original_position":69,"commit_id":"d314daab2a7d83fec54f8c6b1779feb52762cec2","original_commit_id":"d314daab2a7d83fec54f8c6b1779feb52762cec2","user":{"login":"lkuczera","id":192549,"avatar_url":"https://avatars.githubusercontent.com/u/192549?v=3","gravatar_id":"","url":"https://api.github.com/users/lkuczera","html_url":"https://github.com/lkuczera","followers_url":"https://api.github.com/users/lkuczera/followers","following_url":"https://api.github.com/users/lkuczera/following{/other_user}","gists_url":"https://api.github.com/users/lkuczera/gists{/gist_id}","starred_url":"https://api.github.com/users/lkuczera/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lkuczera/subscriptions","organizations_url":"https://api.github.com/users/lkuczera/orgs","repos_url":"https://api.github.com/users/lkuczera/repos","events_url":"https://api.github.com/users/lkuczera/events{/privacy}","received_events_url":"https://api.github.com/users/lkuczera/received_events","type":"User","site_admin":false},"body":"I don't read your mind, but the current form is bit awkward but... compared to you I'll write what I think :smile: \r\nThis sentence is to be either chopped into two or rephrased because you don't know what is the intention. I had to scratch my head and read it twice to fully understand the implications. ","created_at":"2015-09-30T22:39:19Z","updated_at":"2015-09-30T22:39:19Z","html_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io/pull/75#discussion_r40861683","pull_request_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/75","_links":{"self":{"href":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/comments/40861683"},"html":{"href":"https://github.com/ScalaConsultants/ScalaConsultants.github.io/pull/75#discussion_r40861683"},"pull_request":{"href":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/75"}}},"pull_request":{"url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/75","id":45711954,"html_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io/pull/75","diff_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io/pull/75.diff","patch_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io/pull/75.patch","issue_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues/75","number":75,"state":"open","locked":false,"title":"Rx Scala.js","user":{"login":"pjazdzewski1990","id":1136843,"avatar_url":"https://avatars.githubusercontent.com/u/1136843?v=3","gravatar_id":"","url":"https://api.github.com/users/pjazdzewski1990","html_url":"https://github.com/pjazdzewski1990","followers_url":"https://api.github.com/users/pjazdzewski1990/followers","following_url":"https://api.github.com/users/pjazdzewski1990/following{/other_user}","gists_url":"https://api.github.com/users/pjazdzewski1990/gists{/gist_id}","starred_url":"https://api.github.com/users/pjazdzewski1990/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pjazdzewski1990/subscriptions","organizations_url":"https://api.github.com/users/pjazdzewski1990/orgs","repos_url":"https://api.github.com/users/pjazdzewski1990/repos","events_url":"https://api.github.com/users/pjazdzewski1990/events{/privacy}","received_events_url":"https://api.github.com/users/pjazdzewski1990/received_events","type":"User","site_admin":false},"body":"To be pushed on 2015-09-25","created_at":"2015-09-22T20:23:12Z","updated_at":"2015-09-30T22:39:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3e850217ea3e31704f60c50a38e808e669a3d3c5","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/75/commits","review_comments_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/75/comments","review_comment_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues/75/comments","statuses_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/statuses/d314daab2a7d83fec54f8c6b1779feb52762cec2","head":{"label":"ScalaConsultants:rx_scala_js","ref":"rx_scala_js","sha":"d314daab2a7d83fec54f8c6b1779feb52762cec2","user":{"login":"ScalaConsultants","id":6207831,"avatar_url":"https://avatars.githubusercontent.com/u/6207831?v=3","gravatar_id":"","url":"https://api.github.com/users/ScalaConsultants","html_url":"https://github.com/ScalaConsultants","followers_url":"https://api.github.com/users/ScalaConsultants/followers","following_url":"https://api.github.com/users/ScalaConsultants/following{/other_user}","gists_url":"https://api.github.com/users/ScalaConsultants/gists{/gist_id}","starred_url":"https://api.github.com/users/ScalaConsultants/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ScalaConsultants/subscriptions","organizations_url":"https://api.github.com/users/ScalaConsultants/orgs","repos_url":"https://api.github.com/users/ScalaConsultants/repos","events_url":"https://api.github.com/users/ScalaConsultants/events{/privacy}","received_events_url":"https://api.github.com/users/ScalaConsultants/received_events","type":"Organization","site_admin":false},"repo":{"id":15366666,"name":"ScalaConsultants.github.io","full_name":"ScalaConsultants/ScalaConsultants.github.io","owner":{"login":"ScalaConsultants","id":6207831,"avatar_url":"https://avatars.githubusercontent.com/u/6207831?v=3","gravatar_id":"","url":"https://api.github.com/users/ScalaConsultants","html_url":"https://github.com/ScalaConsultants","followers_url":"https://api.github.com/users/ScalaConsultants/followers","following_url":"https://api.github.com/users/ScalaConsultants/following{/other_user}","gists_url":"https://api.github.com/users/ScalaConsultants/gists{/gist_id}","starred_url":"https://api.github.com/users/ScalaConsultants/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ScalaConsultants/subscriptions","organizations_url":"https://api.github.com/users/ScalaConsultants/orgs","repos_url":"https://api.github.com/users/ScalaConsultants/repos","events_url":"https://api.github.com/users/ScalaConsultants/events{/privacy}","received_events_url":"https://api.github.com/users/ScalaConsultants/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io","description":"Scalac blog","fork":false,"url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io","forks_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/forks","keys_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/teams","hooks_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/hooks","issue_events_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues/events{/number}","events_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/events","assignees_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/assignees{/user}","branches_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/branches{/branch}","tags_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/tags","blobs_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/statuses/{sha}","languages_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/languages","stargazers_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/stargazers","contributors_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/contributors","subscribers_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/subscribers","subscription_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/subscription","commits_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/contents/{+path}","compare_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/merges","archive_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/downloads","issues_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues{/number}","pulls_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls{/number}","milestones_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/milestones{/number}","notifications_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/labels{/name}","releases_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/releases{/id}","created_at":"2013-12-21T22:28:57Z","updated_at":"2015-08-26T10:49:35Z","pushed_at":"2015-09-30T21:31:05Z","git_url":"git://github.com/ScalaConsultants/ScalaConsultants.github.io.git","ssh_url":"git@github.com:ScalaConsultants/ScalaConsultants.github.io.git","clone_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io.git","svn_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io","homepage":null,"size":4594,"stargazers_count":1,"watchers_count":1,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":9,"mirror_url":null,"open_issues_count":3,"forks":9,"open_issues":3,"watchers":1,"default_branch":"master"}},"base":{"label":"ScalaConsultants:master","ref":"master","sha":"298cb4939eb2cc4a648eca9b665c39991412038c","user":{"login":"ScalaConsultants","id":6207831,"avatar_url":"https://avatars.githubusercontent.com/u/6207831?v=3","gravatar_id":"","url":"https://api.github.com/users/ScalaConsultants","html_url":"https://github.com/ScalaConsultants","followers_url":"https://api.github.com/users/ScalaConsultants/followers","following_url":"https://api.github.com/users/ScalaConsultants/following{/other_user}","gists_url":"https://api.github.com/users/ScalaConsultants/gists{/gist_id}","starred_url":"https://api.github.com/users/ScalaConsultants/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ScalaConsultants/subscriptions","organizations_url":"https://api.github.com/users/ScalaConsultants/orgs","repos_url":"https://api.github.com/users/ScalaConsultants/repos","events_url":"https://api.github.com/users/ScalaConsultants/events{/privacy}","received_events_url":"https://api.github.com/users/ScalaConsultants/received_events","type":"Organization","site_admin":false},"repo":{"id":15366666,"name":"ScalaConsultants.github.io","full_name":"ScalaConsultants/ScalaConsultants.github.io","owner":{"login":"ScalaConsultants","id":6207831,"avatar_url":"https://avatars.githubusercontent.com/u/6207831?v=3","gravatar_id":"","url":"https://api.github.com/users/ScalaConsultants","html_url":"https://github.com/ScalaConsultants","followers_url":"https://api.github.com/users/ScalaConsultants/followers","following_url":"https://api.github.com/users/ScalaConsultants/following{/other_user}","gists_url":"https://api.github.com/users/ScalaConsultants/gists{/gist_id}","starred_url":"https://api.github.com/users/ScalaConsultants/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ScalaConsultants/subscriptions","organizations_url":"https://api.github.com/users/ScalaConsultants/orgs","repos_url":"https://api.github.com/users/ScalaConsultants/repos","events_url":"https://api.github.com/users/ScalaConsultants/events{/privacy}","received_events_url":"https://api.github.com/users/ScalaConsultants/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io","description":"Scalac blog","fork":false,"url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io","forks_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/forks","keys_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/teams","hooks_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/hooks","issue_events_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues/events{/number}","events_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/events","assignees_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/assignees{/user}","branches_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/branches{/branch}","tags_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/tags","blobs_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/statuses/{sha}","languages_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/languages","stargazers_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/stargazers","contributors_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/contributors","subscribers_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/subscribers","subscription_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/subscription","commits_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/contents/{+path}","compare_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/merges","archive_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/downloads","issues_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues{/number}","pulls_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls{/number}","milestones_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/milestones{/number}","notifications_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/labels{/name}","releases_url":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/releases{/id}","created_at":"2013-12-21T22:28:57Z","updated_at":"2015-08-26T10:49:35Z","pushed_at":"2015-09-30T21:31:05Z","git_url":"git://github.com/ScalaConsultants/ScalaConsultants.github.io.git","ssh_url":"git@github.com:ScalaConsultants/ScalaConsultants.github.io.git","clone_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io.git","svn_url":"https://github.com/ScalaConsultants/ScalaConsultants.github.io","homepage":null,"size":4594,"stargazers_count":1,"watchers_count":1,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":9,"mirror_url":null,"open_issues_count":3,"forks":9,"open_issues":3,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/75"},"html":{"href":"https://github.com/ScalaConsultants/ScalaConsultants.github.io/pull/75"},"issue":{"href":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues/75"},"comments":{"href":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/issues/75/comments"},"review_comments":{"href":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/75/comments"},"review_comment":{"href":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/pulls/75/commits"},"statuses":{"href":"https://api.github.com/repos/ScalaConsultants/ScalaConsultants.github.io/statuses/d314daab2a7d83fec54f8c6b1779feb52762cec2"}}}}