{"action":"created","comment":{"url":"https://api.github.com/repos/highfidelity/hifi/pulls/comments/38806851","id":38806851,"diff_hunk":"@@ -21,88 +21,80 @@\n #include <QtCore/QSet>\n #include <QtCore/QUuid>\n \n-#include \"UUID.h\"\n-\n-// NOTE: if adding a new packet packetType, you can replace one marked usable or add at the end\n-// NOTE: if you want the name of the packet packetType to be available for debugging or logging, update nameForPacketType() as well\n-\n-namespace PacketType {\n-    enum Value {\n-        Unknown,\n-        StunResponse,\n-        DomainList,\n-        Ping,\n-        PingReply,\n-        KillAvatar,\n-        AvatarData,\n-        InjectAudio,\n-        MixedAudio,\n-        MicrophoneAudioNoEcho,\n-        MicrophoneAudioWithEcho,\n-        BulkAvatarData,\n-        SilentAudioFrame,\n-        DomainListRequest,\n-        RequestAssignment,\n-        CreateAssignment,\n-        DomainConnectionDenied,\n-        MuteEnvironment,\n-        AudioStreamStats,\n-        DomainServerPathQuery,\n-        DomainServerPathResponse,\n-        DomainServerAddedNode,\n-        ICEServerPeerInformation,\n-        ICEServerQuery,\n-        OctreeStats,\n-        Jurisdiction,\n-        JurisdictionRequest,\n-        AssignmentClientStatus,\n-        NoisyMute,\n-        AvatarIdentity,\n-        AvatarBillboard,\n-        DomainConnectRequest,\n-        DomainServerRequireDTLS,\n-        NodeJsonStats,\n-        OctreeDataNack,\n-        StopNode,\n-        AudioEnvironment,\n-        EntityEditNack,\n-        ICEServerHeartbeat,\n-        ICEPing,\n-        ICEPingReply,\n-        EntityData,\n-        EntityQuery,\n-        EntityAdd,\n-        EntityErase,\n-        EntityEdit,\n-        DomainServerConnectionToken\n-    };\n+// If adding a new packet packetType, you can replace one marked usable or add at the end.\n+// If you want the name of the packet packetType to be available for debugging or logging, update nameForPacketType() as well\n+// This enum must hold 256 or fewer packet types (so the value is <= 255) since it is statically typed as a uint8_t\n+enum class PacketType : uint8_t {\n+    Unknown,\n+    StunResponse,\n+    DomainList,\n+    Ping,\n+    PingReply,\n+    KillAvatar,\n+    AvatarData,\n+    InjectAudio,\n+    MixedAudio,\n+    MicrophoneAudioNoEcho,\n+    MicrophoneAudioWithEcho,\n+    BulkAvatarData,\n+    SilentAudioFrame,\n+    DomainListRequest,\n+    RequestAssignment,\n+    CreateAssignment,\n+    DomainConnectionDenied,\n+    MuteEnvironment,\n+    AudioStreamStats,\n+    DomainServerPathQuery,\n+    DomainServerPathResponse,\n+    DomainServerAddedNode,\n+    ICEServerPeerInformation,\n+    ICEServerQuery,\n+    OctreeStats,\n+    Jurisdiction,\n+    JurisdictionRequest,\n+    AssignmentClientStatus,\n+    NoisyMute,\n+    AvatarIdentity,\n+    AvatarBillboard,\n+    DomainConnectRequest,\n+    DomainServerRequireDTLS,\n+    NodeJsonStats,\n+    OctreeDataNack,\n+    StopNode,\n+    AudioEnvironment,\n+    EntityEditNack,\n+    ICEServerHeartbeat,\n+    ICEPing,\n+    ICEPingReply,\n+    EntityData,\n+    EntityQuery,\n+    EntityAdd,\n+    EntityErase,\n+    EntityEdit,\n+    DomainServerConnectionToken,\n+    DomainSettingsRequest,\n+    DomainSettings,\n+    AssetGet,\n+    AssetGetReply,\n+    AssetUpload,\n+    AssetUploadReply,\n+    AssetGetInfo,\n+    AssetGetInfoReply\n };\n \n const int NUM_BYTES_MD5_HASH = 16;\n \n-const int MAX_PACKET_SIZE = 1450;\n-const int MAX_PACKET_HEADER_BYTES = 4 + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH;\n-\n typedef char PacketVersion;\n \n-typedef uint16_t PacketSequenceNumber;","path":"libraries/networking/src/udt/PacketHeaders.h","position":127,"original_position":127,"commit_id":"875d10575f50575bf0f5eccd64b130afcb78e591","original_commit_id":"875d10575f50575bf0f5eccd64b130afcb78e591","user":{"login":"ZappoMan","id":2093195,"avatar_url":"https://avatars.githubusercontent.com/u/2093195?v=3","gravatar_id":"","url":"https://api.github.com/users/ZappoMan","html_url":"https://github.com/ZappoMan","followers_url":"https://api.github.com/users/ZappoMan/followers","following_url":"https://api.github.com/users/ZappoMan/following{/other_user}","gists_url":"https://api.github.com/users/ZappoMan/gists{/gist_id}","starred_url":"https://api.github.com/users/ZappoMan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ZappoMan/subscriptions","organizations_url":"https://api.github.com/users/ZappoMan/orgs","repos_url":"https://api.github.com/users/ZappoMan/repos","events_url":"https://api.github.com/users/ZappoMan/events{/privacy}","received_events_url":"https://api.github.com/users/ZappoMan/received_events","type":"User","site_admin":false},"body":"why get rid of this typedef, isn't using PacketSequenceNumber more informative to the reader than uint16_t?","created_at":"2015-09-05T03:29:50Z","updated_at":"2015-09-05T03:29:50Z","html_url":"https://github.com/highfidelity/hifi/pull/5694#discussion_r38806851","pull_request_url":"https://api.github.com/repos/highfidelity/hifi/pulls/5694","_links":{"self":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/comments/38806851"},"html":{"href":"https://github.com/highfidelity/hifi/pull/5694#discussion_r38806851"},"pull_request":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/5694"}}},"pull_request":{"url":"https://api.github.com/repos/highfidelity/hifi/pulls/5694","id":43923872,"html_url":"https://github.com/highfidelity/hifi/pull/5694","diff_url":"https://github.com/highfidelity/hifi/pull/5694.diff","patch_url":"https://github.com/highfidelity/hifi/pull/5694.patch","issue_url":"https://api.github.com/repos/highfidelity/hifi/issues/5694","number":5694,"state":"open","locked":false,"title":"Asset Transfer Protocol and UDT in networking layer","user":{"login":"huffman","id":167747,"avatar_url":"https://avatars.githubusercontent.com/u/167747?v=3","gravatar_id":"","url":"https://api.github.com/users/huffman","html_url":"https://github.com/huffman","followers_url":"https://api.github.com/users/huffman/followers","following_url":"https://api.github.com/users/huffman/following{/other_user}","gists_url":"https://api.github.com/users/huffman/gists{/gist_id}","starred_url":"https://api.github.com/users/huffman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/huffman/subscriptions","organizations_url":"https://api.github.com/users/huffman/orgs","repos_url":"https://api.github.com/users/huffman/repos","events_url":"https://api.github.com/users/huffman/events{/privacy}","received_events_url":"https://api.github.com/users/huffman/received_events","type":"User","site_admin":false},"body":"Summary of the features added by this PR:\r\n- UDT layer in networking library for reliable congestion and rate controlled sending\r\n- new assignment-client type \"asset-server\" (type 3) - disabled in all domains by default\r\n- AssetClient/AssetResourceRequest to download/upload ATP files from Interface\r\n- reworking of resource request system to seamlessly handle HTTP/file/ATP requests\r\n\r\n### Asset Transfer Protocol (ATP)\r\n\r\nATP is a new protocol High Fidelity clients and servers can use to send assets (meshes, sounds, images, scripts) to each other over their existing hole-punched UDP connections. It is meant to eventually replace the serving of existing HTTP/TCP assets because of the following advantages :\r\n\r\n- no requirement for content creator to own a separate HTTP webserver or S3 bucket to serve assets\r\n- fairer than TCP to other concurrent connections\r\n- less aggresive than TCP at backing off when loss occurs (and quicker to recover from a one-off loss event)\r\n- easy direct LAN serving of files to locally connected clients\r\n- client downstream saturation by concurrent requesting of file blocks from multiple asset-servers (future improvement)\r\n\r\nATP URLS are of the form `atp:$HASH.$EXT`. Here's an example:\r\n\r\n`atp:89fcfdc5a74f3c78fa277ec4edf8fef367224bdc102dbe9794eb4788f537eac7.fbx`\r\n\r\nCurrently, when Interface is given an ATP URL (ex: for scripts, entities, or avatars) it confirms with the `asset-server` in its current domain that a file with the given hash and extension exists, and then it sends a request for the `asset-server` to send it the entire file. The `asset-server` dispatches a message that contains the data of the file via a UDT connection.\r\n\r\nFor clients, much of the ATP request/response is hidden in the `AssetResourceRequest` and `AssetClient` classes and networking layer. Callers that currently use HTTP downloads should expect an almost identical interface for success and failure for ATP downloads.\r\n\r\nThe `asset-server` will initially not be a default assigned type in domains. This is to allow for further testing of the new system in High Fidelity domains with many remote clients before suggesting widespread adoption in place of HTTP assets.\r\n\r\nOne major shortcoming of ATP in its current state is that it cannot handle files that contain links to other files via relative paths (meshes are the biggest offender here). This is due to the fact that there is currently no ability to reference a file in ATP by name. We have some potential solutions to this that we will explore in the coming weeks.\r\n\r\nPreliminary support for asset upload is enabled in interface via a Menu option at Developer->Assets. If the upload finishes successfully, Interface presents a dialog with a copiable ATP URL. If it fails, it shows an error dialog that explains why the upload failed. Ideally this would have been done via QML but a QML-friendly file dialog is not readily available. We will likely need to add one for global use in Interface, at which point the asset upload flow should be moved over as well.  \r\n\r\n### UDT\r\n\r\nThe reliable ordered sending required by the Asset Transfer Protocol is acheived by the addition of the [UDP-based data transfer (UDT) protocol](http://udt.sourceforge.net). We have only very slightly modified the behaviour of the fourth official version of the UDT protocol, created by Dr. Yunhong Gu and Dr. Robert L. Grossman.\r\n\r\nNodelist/LimitedNodeList UDP datagrams now flow through `udt::Socket` instead of directly through `QUdpSocket`. This allows the `udt::Socket` to determine if it needs simply to send the packet off, or hand it off to a matching `udt::Connection`. \r\n\r\nThe entry point for our implemenation of the UDT protocol is `udt::Connection`. At any time that a node is receiving or sending data to a specific socket (address and port), they will have a single connection open to that socket. While sending, the `udt::Connection` will spawn a `udt::SendQueue` on a separate thread (this is required so the thread can sleep for the packet send period and maintain the correct send rate). *It is likely in the future that it will make more sense to create one `udt::Connection` per request-response, as this will allow concurrent data flows between the same client/server that share the same available bandwidth.*\r\n\r\nThe reciever in a UDT connection sends NAK packets to ask the sender to re-send anything that was lost. In order to reduce the amount of packet loss and therefore re-sent packets, UDT uses a number of techniques to estimate the available bandwidth and current congestion for each connection. It attempts to use as much of the link as possible while being very fair to other protocols also using the same network connection. \r\n\r\nThe bulk of the UDT magic can be found in the `udt::DefaultCC` class. `udt::DefaultCC` is a subclass of `udt::CongestionControl`, a base class that UDT connections can leverage (via its subclasses) to adopt using any number of congestion control styles. The default implementation `udt::DefaultCC` is our slightly modified version of the congestion control technique presented in Dr. Gu's and Dr. Grossman's UDT papers.\r\n\r\nCurrently UDT can handle the following types of packets:\r\n- unreliable, unordered\r\n    - this goes direct from `udt::Socket` to the wire\r\n- reliable, unordered\r\n    - sent via the `udt::SendQueue` of a `udt::Connection`\r\n- reliable, ordered\r\n    - sent via the `udt::SendQueue` of a `udt::Connection`, re-constructed by the `udt::Connection` on receiver\r\n\r\nThe obvious missing combination is unreliable, but ordered. Support for this will be added shortly - the sender will send a block of data that the receiver knows it should drop as lost as soon as it loses any of the packets in the message.\r\n\r\n### WWCD\r\n\r\nWith @Atlante45 in France we truly couldn't have completed this work without the help of Clerb. \r\n\r\n![clerb](https://cloud.githubusercontent.com/assets/724069/9615673/f3313f4e-50b6-11e5-88b4-7009ba5e74ca.jpg)\r\n\r\nMuch of our design is driven by the simple question \"What would Clerb do?\" - the answer is usually just to move it.","created_at":"2015-09-01T20:41:18Z","updated_at":"2015-09-05T03:29:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2a8a6ac9f320c7f38b60f8c6a33ab8f26de0ca5c","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/highfidelity/hifi/pulls/5694/commits","review_comments_url":"https://api.github.com/repos/highfidelity/hifi/pulls/5694/comments","review_comment_url":"https://api.github.com/repos/highfidelity/hifi/pulls/comments{/number}","comments_url":"https://api.github.com/repos/highfidelity/hifi/issues/5694/comments","statuses_url":"https://api.github.com/repos/highfidelity/hifi/statuses/875d10575f50575bf0f5eccd64b130afcb78e591","head":{"label":"birarda:protocol","ref":"protocol","sha":"875d10575f50575bf0f5eccd64b130afcb78e591","user":{"login":"birarda","id":724069,"avatar_url":"https://avatars.githubusercontent.com/u/724069?v=3","gravatar_id":"","url":"https://api.github.com/users/birarda","html_url":"https://github.com/birarda","followers_url":"https://api.github.com/users/birarda/followers","following_url":"https://api.github.com/users/birarda/following{/other_user}","gists_url":"https://api.github.com/users/birarda/gists{/gist_id}","starred_url":"https://api.github.com/users/birarda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/birarda/subscriptions","organizations_url":"https://api.github.com/users/birarda/orgs","repos_url":"https://api.github.com/users/birarda/repos","events_url":"https://api.github.com/users/birarda/events{/privacy}","received_events_url":"https://api.github.com/users/birarda/received_events","type":"User","site_admin":false},"repo":{"id":9376753,"name":"hifi","full_name":"birarda/hifi","owner":{"login":"birarda","id":724069,"avatar_url":"https://avatars.githubusercontent.com/u/724069?v=3","gravatar_id":"","url":"https://api.github.com/users/birarda","html_url":"https://github.com/birarda","followers_url":"https://api.github.com/users/birarda/followers","following_url":"https://api.github.com/users/birarda/following{/other_user}","gists_url":"https://api.github.com/users/birarda/gists{/gist_id}","starred_url":"https://api.github.com/users/birarda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/birarda/subscriptions","organizations_url":"https://api.github.com/users/birarda/orgs","repos_url":"https://api.github.com/users/birarda/repos","events_url":"https://api.github.com/users/birarda/events{/privacy}","received_events_url":"https://api.github.com/users/birarda/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/birarda/hifi","description":"Test platform for various render and interface tests for next-gen VR system","fork":true,"url":"https://api.github.com/repos/birarda/hifi","forks_url":"https://api.github.com/repos/birarda/hifi/forks","keys_url":"https://api.github.com/repos/birarda/hifi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/birarda/hifi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/birarda/hifi/teams","hooks_url":"https://api.github.com/repos/birarda/hifi/hooks","issue_events_url":"https://api.github.com/repos/birarda/hifi/issues/events{/number}","events_url":"https://api.github.com/repos/birarda/hifi/events","assignees_url":"https://api.github.com/repos/birarda/hifi/assignees{/user}","branches_url":"https://api.github.com/repos/birarda/hifi/branches{/branch}","tags_url":"https://api.github.com/repos/birarda/hifi/tags","blobs_url":"https://api.github.com/repos/birarda/hifi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/birarda/hifi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/birarda/hifi/git/refs{/sha}","trees_url":"https://api.github.com/repos/birarda/hifi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/birarda/hifi/statuses/{sha}","languages_url":"https://api.github.com/repos/birarda/hifi/languages","stargazers_url":"https://api.github.com/repos/birarda/hifi/stargazers","contributors_url":"https://api.github.com/repos/birarda/hifi/contributors","subscribers_url":"https://api.github.com/repos/birarda/hifi/subscribers","subscription_url":"https://api.github.com/repos/birarda/hifi/subscription","commits_url":"https://api.github.com/repos/birarda/hifi/commits{/sha}","git_commits_url":"https://api.github.com/repos/birarda/hifi/git/commits{/sha}","comments_url":"https://api.github.com/repos/birarda/hifi/comments{/number}","issue_comment_url":"https://api.github.com/repos/birarda/hifi/issues/comments{/number}","contents_url":"https://api.github.com/repos/birarda/hifi/contents/{+path}","compare_url":"https://api.github.com/repos/birarda/hifi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/birarda/hifi/merges","archive_url":"https://api.github.com/repos/birarda/hifi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/birarda/hifi/downloads","issues_url":"https://api.github.com/repos/birarda/hifi/issues{/number}","pulls_url":"https://api.github.com/repos/birarda/hifi/pulls{/number}","milestones_url":"https://api.github.com/repos/birarda/hifi/milestones{/number}","notifications_url":"https://api.github.com/repos/birarda/hifi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/birarda/hifi/labels{/name}","releases_url":"https://api.github.com/repos/birarda/hifi/releases{/id}","created_at":"2013-04-11T17:58:46Z","updated_at":"2015-05-08T19:10:20Z","pushed_at":"2015-09-04T18:43:45Z","git_url":"git://github.com/birarda/hifi.git","ssh_url":"git@github.com:birarda/hifi.git","clone_url":"https://github.com/birarda/hifi.git","svn_url":"https://github.com/birarda/hifi","homepage":null,"size":183256,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"highfidelity:master","ref":"master","sha":"d623ba3ef26f08d55bce550896c51df6f4d9b785","user":{"login":"highfidelity","id":1565370,"avatar_url":"https://avatars.githubusercontent.com/u/1565370?v=3","gravatar_id":"","url":"https://api.github.com/users/highfidelity","html_url":"https://github.com/highfidelity","followers_url":"https://api.github.com/users/highfidelity/followers","following_url":"https://api.github.com/users/highfidelity/following{/other_user}","gists_url":"https://api.github.com/users/highfidelity/gists{/gist_id}","starred_url":"https://api.github.com/users/highfidelity/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/highfidelity/subscriptions","organizations_url":"https://api.github.com/users/highfidelity/orgs","repos_url":"https://api.github.com/users/highfidelity/repos","events_url":"https://api.github.com/users/highfidelity/events{/privacy}","received_events_url":"https://api.github.com/users/highfidelity/received_events","type":"Organization","site_admin":false},"repo":{"id":5372872,"name":"hifi","full_name":"highfidelity/hifi","owner":{"login":"highfidelity","id":1565370,"avatar_url":"https://avatars.githubusercontent.com/u/1565370?v=3","gravatar_id":"","url":"https://api.github.com/users/highfidelity","html_url":"https://github.com/highfidelity","followers_url":"https://api.github.com/users/highfidelity/followers","following_url":"https://api.github.com/users/highfidelity/following{/other_user}","gists_url":"https://api.github.com/users/highfidelity/gists{/gist_id}","starred_url":"https://api.github.com/users/highfidelity/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/highfidelity/subscriptions","organizations_url":"https://api.github.com/users/highfidelity/orgs","repos_url":"https://api.github.com/users/highfidelity/repos","events_url":"https://api.github.com/users/highfidelity/events{/privacy}","received_events_url":"https://api.github.com/users/highfidelity/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/highfidelity/hifi","description":"Open source software for shared virtual worlds using HMDs and dynamically assigned devices as servers.  San Francisco based startup, we are hiring: http://highfidelity.com/jobs  Documentation at http://docs.highfidelity.com  Contribute by reporting bugs & doing jobs on http://worklist.net","fork":false,"url":"https://api.github.com/repos/highfidelity/hifi","forks_url":"https://api.github.com/repos/highfidelity/hifi/forks","keys_url":"https://api.github.com/repos/highfidelity/hifi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/highfidelity/hifi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/highfidelity/hifi/teams","hooks_url":"https://api.github.com/repos/highfidelity/hifi/hooks","issue_events_url":"https://api.github.com/repos/highfidelity/hifi/issues/events{/number}","events_url":"https://api.github.com/repos/highfidelity/hifi/events","assignees_url":"https://api.github.com/repos/highfidelity/hifi/assignees{/user}","branches_url":"https://api.github.com/repos/highfidelity/hifi/branches{/branch}","tags_url":"https://api.github.com/repos/highfidelity/hifi/tags","blobs_url":"https://api.github.com/repos/highfidelity/hifi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/highfidelity/hifi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/highfidelity/hifi/git/refs{/sha}","trees_url":"https://api.github.com/repos/highfidelity/hifi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/highfidelity/hifi/statuses/{sha}","languages_url":"https://api.github.com/repos/highfidelity/hifi/languages","stargazers_url":"https://api.github.com/repos/highfidelity/hifi/stargazers","contributors_url":"https://api.github.com/repos/highfidelity/hifi/contributors","subscribers_url":"https://api.github.com/repos/highfidelity/hifi/subscribers","subscription_url":"https://api.github.com/repos/highfidelity/hifi/subscription","commits_url":"https://api.github.com/repos/highfidelity/hifi/commits{/sha}","git_commits_url":"https://api.github.com/repos/highfidelity/hifi/git/commits{/sha}","comments_url":"https://api.github.com/repos/highfidelity/hifi/comments{/number}","issue_comment_url":"https://api.github.com/repos/highfidelity/hifi/issues/comments{/number}","contents_url":"https://api.github.com/repos/highfidelity/hifi/contents/{+path}","compare_url":"https://api.github.com/repos/highfidelity/hifi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/highfidelity/hifi/merges","archive_url":"https://api.github.com/repos/highfidelity/hifi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/highfidelity/hifi/downloads","issues_url":"https://api.github.com/repos/highfidelity/hifi/issues{/number}","pulls_url":"https://api.github.com/repos/highfidelity/hifi/pulls{/number}","milestones_url":"https://api.github.com/repos/highfidelity/hifi/milestones{/number}","notifications_url":"https://api.github.com/repos/highfidelity/hifi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/highfidelity/hifi/labels{/name}","releases_url":"https://api.github.com/repos/highfidelity/hifi/releases{/id}","created_at":"2012-08-10T18:26:22Z","updated_at":"2015-09-04T18:53:37Z","pushed_at":"2015-09-05T03:07:22Z","git_url":"git://github.com/highfidelity/hifi.git","ssh_url":"git@github.com:highfidelity/hifi.git","clone_url":"https://github.com/highfidelity/hifi.git","svn_url":"https://github.com/highfidelity/hifi","homepage":"","size":233300,"stargazers_count":302,"watchers_count":302,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":172,"mirror_url":null,"open_issues_count":56,"forks":172,"open_issues":56,"watchers":302,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/5694"},"html":{"href":"https://github.com/highfidelity/hifi/pull/5694"},"issue":{"href":"https://api.github.com/repos/highfidelity/hifi/issues/5694"},"comments":{"href":"https://api.github.com/repos/highfidelity/hifi/issues/5694/comments"},"review_comments":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/5694/comments"},"review_comment":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/5694/commits"},"statuses":{"href":"https://api.github.com/repos/highfidelity/hifi/statuses/875d10575f50575bf0f5eccd64b130afcb78e591"}}}}