[
  {
    "path": ".gitignore",
    "content": ".idea/\n.env/\n*.egg-info\nreports/\nbuild/\nnohup.out\n.DS_Store\nxcuserdata/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\n*.xcworkspace\n!default.xcworkspace\n*xcuserdata\n*.xccheckout\nprofile\n*.moved-aside\nDerivedData\nextern/\n\n*.pyc\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"Vendor/xctoolchain\"]\n\tpath = Vendor/xctoolchain\n\turl = https://github.com/nlutsenko/xctoolchain.git\n"
  },
  {
    "path": ".ruby-version",
    "content": "2.3.1\n"
  },
  {
    "path": ".travis.yml",
    "content": "branches:\n  only:\n    - master\nlanguage: objective-c\nos: osx\nosx_image: xcode7.3\nenv:\n  matrix:\n    - TEST_TYPE=iOS\n    - TEST_TYPE=OSX\n    - TEST_TYPE=tvOS\n    - TEST_TYPE=CocoaPods\n    - TEST_TYPE=Carthage\nbefore_install:\n- |\n  if [ \"$TEST_TYPE\" = iOS ] || [ \"$TEST_TYPE\" = OSX ] || [ \"$TEST_TYPE\" = tvOS ]; then\n    bundle install\n  elif [ \"$TEST_TYPE\" = Carthage ]; then    \n    brew update\n    brew install carthage || brew upgrade carthage\n  fi\ninstall:\n- |\n  if [ \"$TEST_TYPE\" = iOS ]; then\n    ./TestSupport/setup_env.sh .env\n  fi\nscript:\n- |\n  if [ \"$TEST_TYPE\" = iOS ]; then\n    set -o pipefail\n    xcodebuild -project SocketRocket.xcodeproj -scheme \"SocketRocket-iOS\" -sdk iphonesimulator build test\n  elif [ \"$TEST_TYPE\" = OSX ]; then\n    set -o pipefail\n    xcodebuild -project SocketRocket.xcodeproj -scheme \"SocketRocket-macOS\" -sdk macosx build | xcpretty -c\n  elif [ \"$TEST_TYPE\" = tvOS ]; then\n    set -o pipefail\n    xcodebuild -project SocketRocket.xcodeproj -scheme \"SocketRocket-tvOS\" -sdk appletvsimulator build | xcpretty -c\n  elif [ \"$TEST_TYPE\" = CocoaPods ]; then\n    pod lib lint SocketRocket.podspec\n    pod lib lint --use-libraries SocketRocket.podspec\n  elif [ \"$TEST_TYPE\" = Carthage ]; then\n    carthage build --no-skip-current\n  fi\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\nFacebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.fb.com/codeofconduct) so that you can understand what actions will and will not be tolerated."
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to SocketRocket\nWe want to make contributing to this project as easy and transparent as possible.\n\n## Pull Requests\nWe actively welcome your pull requests.\n\n1. Fork the repo and create your branch from `master`.\n2. If you've added code that should be tested, add tests.\n3. If you've changed APIs, update the documentation.\n4. Ensure the test suite passes.\n5. Make sure your code lints.\n6. If you haven't already, complete the Contributor License Agreement (\"CLA\").\n\n## Contributor License Agreement (\"CLA\")\nIn order to accept your pull request, we need you to submit a CLA. \nYou only need to do this once to work on any of Facebook's open source projects.\n\nComplete your CLA here: <https://code.facebook.com/cla>\n\n## Issues\nWe use GitHub issues to track public bugs. Please ensure your description is\nclear and has sufficient instructions to be able to reproduce the issue.\n\nFacebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe\ndisclosure of security bugs. In those cases, please go through the process\noutlined on that page and do not file a public issue.\n\n## Coding Style  \n* Most importantly, match the existing code style as much as possible.\n* Try to keep lines under 140 characters, if possible.\n\n## License\nBy contributing to SocketRocket, you agree that your contributions will be licensed under its BSD license."
  },
  {
    "path": "Configurations/SocketRocket-iOS-Dynamic.xcconfig",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#include \"Shared/Platform/iOS.xcconfig\"\n#include \"Shared/Product/DynamicFramework.xcconfig\"\n\nPRODUCT_NAME = SocketRocket\nPRODUCT_BUNDLE_IDENTIFIER = com.facebook.socketrocket.ios\nIPHONEOS_DEPLOYMENT_TARGET = 11.0\n\nINFOPLIST_FILE = $(SRCROOT)/SocketRocket/Resources/Info.plist\n"
  },
  {
    "path": "Configurations/SocketRocket-iOS.xcconfig",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#include \"Shared/Platform/iOS.xcconfig\"\n#include \"Shared/Product/StaticFramework.xcconfig\"\n\nPRODUCT_NAME = SocketRocket\nPRODUCT_BUNDLE_IDENTIFIER = com.facebook.socketrocket.ios\nIPHONEOS_DEPLOYMENT_TARGET = 11.0\n\nINFOPLIST_FILE = $(SRCROOT)/SocketRocket/Resources/Info.plist\n\nOTHER_CFLAGS[sdk=iphoneos9.*] = $(inherited) -fembed-bitcode\nOTHER_LDFLAGS = $(inherited) -Licucore\n"
  },
  {
    "path": "Configurations/SocketRocket-macOS.xcconfig",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#include \"Shared/Platform/macOS.xcconfig\"\n#include \"Shared/Product/DynamicFramework.xcconfig\"\n\nPRODUCT_NAME = SocketRocket\nPRODUCT_BUNDLE_IDENTIFIER = com.facebook.socketrocket.macos\nMACOSX_DEPLOYMENT_TARGET = 10.13\n\nINFOPLIST_FILE = $(SRCROOT)/SocketRocket/Resources/Info.plist\n"
  },
  {
    "path": "Configurations/SocketRocket-tvOS.xcconfig",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#include \"Shared/Platform/tvOS.xcconfig\"\n#include \"Shared/Product/DynamicFramework.xcconfig\"\n\nPRODUCT_NAME = SocketRocket\nPRODUCT_BUNDLE_IDENTIFIER = com.facebook.socketrocket.tvos\nTVOS_DEPLOYMENT_TARGET = 11.0\n\nINFOPLIST_FILE = $(SRCROOT)/SocketRocket/Resources/Info.plist\n"
  },
  {
    "path": "Configurations/SocketRocketTests-iOS.xcconfig",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#include \"Shared/Platform/iOS.xcconfig\"\n#include \"Shared/Product/LogicTests.xcconfig\"\n\nPRODUCT_NAME = SocketRocketTests-iOS\nPRODUCT_MODULE_NAME = SocketRocketTests\nPRODUCT_BUNDLE_IDENTIFIER = com.facebook.socketrocket.tests.ios\n\nIPHONEOS_DEPLOYMENT_TARGET = 11.0\n\nINFOPLIST_FILE = $(SRCROOT)/Tests/Resources/Info.plist\n"
  },
  {
    "path": "Configurations/TestChat-iOS.xcconfig",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#include \"Shared/Platform/iOS.xcconfig\"\n#include \"Shared/Product/Application.xcconfig\"\n\nPRODUCT_NAME = TestChat\nPRODUCT_MODULE_NAME = TestChat\nPRODUCT_BUNDLE_IDENTIFIER = com.facebook.socketrocket.testchat\n\nIPHONEOS_DEPLOYMENT_TARGET = 11.0\n\nINFOPLIST_FILE = $(SRCROOT)/TestChat/TestChat-Info.plist\n"
  },
  {
    "path": "Gemfile",
    "content": "source 'https://rubygems.org'\n\ngem 'cocoapods'\ngem 'xcpretty'\n"
  },
  {
    "path": "LICENSE",
    "content": "BSD License\n\nFor SocketRocket software\n\nCopyright (c) 2016-present, Facebook, Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n * Neither the name Facebook nor the names of its contributors may be used to\n   endorse or promote products derived from this software without specific\n   prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  },
  {
    "path": "LICENSE-examples",
    "content": "Copyright (c) 2016-present, Facebook, Inc. All rights reserved.\n\nThe examples provided by Facebook are for non-commercial testing and evaluation\npurposes only. Facebook reserves all rights not expressly granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\nFACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\nACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "TEST_SCENARIOS=\"[1-8]*\"\nTEST_URL='ws://localhost:9001/'\n\nall:\n\t$(MAKE) -C SocketRocket\n\nclean:\n\t$(MAKE) -C SocketRocket clean\n\n.env:\n\n\t./TestSupport/setup_env.sh .env\n\ntest: .env\n\n\tmkdir -p pages/results\n\tbash ./TestSupport/run_test_server.sh $(TEST_SCENARIOS) $(TEST_URL) Debug || open pages/results/index.html && false\n\topen pages/results/index.html\n\ntest_all: .env\n\n\tmkdir -p pages/results\n\tbash ./TestSupport/run_test_server.sh '*' $(TEST_URL) Debug || open pages/results/index.html && false\n\topen pages/results/index.html\n\ntest_perf: .env\n\n\tmkdir -p pages/results\n\tbash ./TestSupport/run_test_server.sh '9.*' $(TEST_URL) Release || open pages/results/index.html && false\n\topen pages/results/index.html\n"
  },
  {
    "path": "PATENTS",
    "content": "Additional Grant of Patent Rights Version 2\n\n\"Software\" means the SocketRocket software distributed by Facebook, Inc.\n\nFacebook, Inc. (\"Facebook\") hereby grants to each recipient of the Software\n(\"you\") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable\n(subject to the termination provision below) license under any Necessary\nClaims, to make, have made, use, sell, offer to sell, import, and otherwise\ntransfer the Software. For avoidance of doubt, no license is granted under\nFacebook’s rights in any patent claims that are infringed by (i) modifications\nto the Software made by you or any third party or (ii) the Software in\ncombination with any software or other technology.\n\nThe license granted hereunder will terminate, automatically and without notice,\nif you (or any of your subsidiaries, corporate affiliates or agents) initiate\ndirectly or indirectly, or take a direct financial interest in, any Patent\nAssertion: (i) against Facebook or any of its subsidiaries or corporate\naffiliates, (ii) against any party if such Patent Assertion arises in whole or\nin part from any software, technology, product or service of Facebook or any of\nits subsidiaries or corporate affiliates, or (iii) against any party relating\nto the Software. Notwithstanding the foregoing, if Facebook or any of its\nsubsidiaries or corporate affiliates files a lawsuit alleging patent\ninfringement against you in the first instance, and you respond by filing a\npatent infringement counterclaim in that lawsuit against that party that is\nunrelated to the Software, the license granted hereunder will not terminate\nunder section (i) of this paragraph due to such counterclaim.\n\nA \"Necessary Claim\" is a claim of a patent owned by Facebook that is\nnecessarily infringed by the Software standing alone.\n\nA \"Patent Assertion\" is any lawsuit or other action alleging direct, indirect,\nor contributory infringement or inducement to infringe any patent, including a\ncross-claim or counterclaim.\n"
  },
  {
    "path": "README.md",
    "content": "# SocketRocket\n\n![Platforms][platforms-svg]\n[![License][license-svg]][license-link]\n\n[![Podspec][podspec-svg]][podspec-link]\n[![Carthage Compatible][carthage-svg]](carthage-link)\n\n[![Build Status][build-status-svg]][build-status-link]\n\nA conforming WebSocket ([RFC 6455](https://tools.ietf.org/html/rfc6455>)) client library for iOS, macOS, tvOS and visionOS.\n\nTest results for SocketRocket [here](http://facebook.github.io/SocketRocket/results/).\nYou can compare to what modern browsers look like [here](http://autobahn.ws/testsuite/reports/clients/index.html).\n\nSocketRocket currently conforms to all core ~300 of [Autobahn](http://autobahn.ws/testsuite/>)'s fuzzing tests \n(aside from two UTF-8 ones where it is merely *non-strict* tests 6.4.2 and 6.4.4).\n\n## Features/Design\n\n- TLS (wss) support, including self-signed certificates.\n- Seems to perform quite well.\n- Supports HTTP Proxies.\n- Supports IPv4/IPv6.\n- Supports SSL certificate pinning.\n- Sends `ping` and can process `pong` events.\n- Asynchronous and non-blocking. Most of the work is done on a background thread.\n- Supports iOS, macOS, tvOS.\n\n## Installing\n\nThere are a few options. Choose one, or just figure it out:\n\n- **[CocoaPods](https://cocoapods.org)**\n\n Add the following line to your Podfile:\n ```ruby\n pod 'SocketRocket'\n ```\n Run `pod install`, and you are all set.\n  \n- **[Carthage](https://github.com/carthage/carthage)**\n\n Add the following line to your Cartfile:\n ```\n github \"facebook/SocketRocket\"\n ```\n Run `carthage update`, and you should now have the latest version of `SocketRocket` in your `Carthage` folder.\n\n- **Using SocketRocket as a sub-project**\n\n  You can also include `SocketRocket` as a subproject inside of your application if you'd prefer, although we do not recommend this, as it will increase your indexing time significantly. To do so, just drag and drop the `SocketRocket.xcodeproj` file into your workspace.\n\n## API\n\n### `SRWebSocket`\n\nThe Web Socket.\n\n#### Note:\n\n`SRWebSocket` will retain itself between `-(void)open` and when it closes, errors, or fails.\nThis is similar to how `NSURLConnection` behaves (unlike `NSURLConnection`, `SRWebSocket` won't retain the delegate).\n\n#### Interface\n\n```objective-c\n@interface SRWebSocket : NSObject\n\n// Make it with this\n- (instancetype)initWithURLRequest:(NSURLRequest *)request;\n\n// Set this before opening\n@property (nonatomic, weak) id <SRWebSocketDelegate> delegate;\n\n// Open with this\n- (void)open;\n\n// Close it with this\n- (void)close;\n\n// Send a Data\n- (void)sendData:(nullable NSData *)data error:(NSError **)error;\n\n// Send a UTF8 String\n- (void)sendString:(NSString *)string error:(NSError **)error;\n\n@end\n```\n\n### `SRWebSocketDelegate`\n\nYou implement this\n\n```objective-c\n@protocol SRWebSocketDelegate <NSObject>\n\n@optional\n\n- (void)webSocketDidOpen:(SRWebSocket *)webSocket;\n\n- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(NSString *)string;\n- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithData:(NSData *)data;\n\n- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;\n- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(nullable NSString *)reason wasClean:(BOOL)wasClean;\n\n@end\n```\n\n## Testing\n\nIncluded are setup scripts for the python testing environment.\nIt comes packaged with vitualenv so all the dependencies are installed in userland.\n\nTo run the short test from the command line, run:\n```bash\n  make test\n```\n\nTo run all the tests, run:\n```bash\n  make test_all\n```\n\nThe short tests don't include the performance tests\n(the test harness is actually the bottleneck, not SocketRocket).\n\nThe first time this is run, it may take a while to install the dependencies. It will be smooth sailing after that. \n\nYou can also run tests inside Xcode, which runs the same thing, but makes it easier to debug.\n\n- Choose the `SocketRocketTests` target\n- Make sure your running destination is either your Mac or any Simulator\n- Run the test action (`⌘+U`)\n\n### TestChat Demo Application\n\nSocketRocket includes a demo app, TestChat.\nIt will \"chat\" with a listening websocket on port 9900.\n\n#### TestChat Server\n\nThe sever takes a message and broadcasts it to all other connected clients.\n\nIt requires some dependencies though to run. \nWe also want to reuse the virtualenv we made when we ran the tests. \nIf you haven't run the tests yet, go into the SocketRocket root directory and type:\n\n```bash\nmake test\n```\n\nThis will set up your [virtualenv](https://pypi.python.org/pypi/virtualenv).\n\nNow, in your terminal:\n\n```bash\nsource .env/bin/activate\npip install git+https://github.com/tornadoweb/tornado.git\n```\n\nIn the same terminal session, start the chatroom server:\n\n```bash\npython TestChatServer/py/chatroom.py\n```\n\nThere's also a Go implementation (with the latest weekly) where you can:\n\n```bash\ncd TestChatServer/go\ngo run chatroom.go\n```\n\n#### Chatting\n\nNow, start TestChat.app (just run the target in the Xcode project).\nIf you had it started already you can hit the refresh button to reconnect.\nIt should say \"Connected!\" on top.\n\nTo talk with the app, open up your browser to [http://localhost:9000](http://localhost:9000) and start chatting.\n\n\n## WebSocket Server Implementation Recommendations\n\nSocketRocket has been used with the following libraries:\n\n- [Tornado](https://github.com/tornadoweb/tornado)\n- Go's [WebSocket package](https://godoc.org/golang.org/x/net/websocket) or Gorilla's [version](http://www.gorillatoolkit.org/pkg/websocket).\n- [Autobahn](http://autobahn.ws/testsuite/) (using its fuzzing client).\n\nThe Tornado one is dirt simple and works like a charm. \n([IPython notebook](http://ipython.org/ipython-doc/dev/interactive/htmlnotebook.html) uses it too).\nIt's much easier to configure handlers and routes than in Autobahn/twisted.\n\n## Contributing\n\nWe’re glad you’re interested in SocketRocket, and we’d love to see where you take it. \nPlease read our [contributing guidelines](https://github.com/facebook/SocketRocket/blob/master/CONTRIBUTING.md) prior to submitting a Pull Request.\n\n [build-status-svg]: https://img.shields.io/travis/facebook/SocketRocket/master.svg\n [build-status-link]: https://travis-ci.org/facebook/SocketRocket/branches\n\n [license-svg]: https://img.shields.io/badge/license-BSD-lightgrey.svg\n [license-link]: https://github.com/facebook/SocketRocket/blob/master/LICENSE\n\n [podspec-svg]: https://img.shields.io/cocoapods/v/SocketRocket.svg\n [podspec-link]: https://cocoapods.org/pods/SocketRocket\n \n [carthage-svg]: https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\n [carthage-link]: https://github.com/carthage/carthage\n\n [platforms-svg]: http://img.shields.io/cocoapods/p/SocketRocket.svg?style=flat\n"
  },
  {
    "path": "SocketRocket/Internal/Delegate/SRDelegateController.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\n#import <SocketRocket/SRWebSocket.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n#if OBJC_BOOL_IS_BOOL\n\nstruct SRDelegateAvailableMethods {\n    BOOL didReceiveMessage : 1;\n    BOOL didReceiveMessageWithString : 1;\n    BOOL didReceiveMessageWithData : 1;\n    BOOL didOpen : 1;\n    BOOL didFailWithError : 1;\n    BOOL didCloseWithCode : 1;\n    BOOL didReceivePing : 1;\n    BOOL didReceivePong : 1;\n    BOOL shouldConvertTextFrameToString : 1;\n};\n\n#else\n\nstruct SRDelegateAvailableMethods {\n    BOOL didReceiveMessage;\n    BOOL didReceiveMessageWithString;\n    BOOL didReceiveMessageWithData;\n    BOOL didOpen;\n    BOOL didFailWithError;\n    BOOL didCloseWithCode;\n    BOOL didReceivePing;\n    BOOL didReceivePong;\n    BOOL shouldConvertTextFrameToString;\n};\n\n#endif\n\ntypedef struct SRDelegateAvailableMethods SRDelegateAvailableMethods;\n\ntypedef void(^SRDelegateBlock)(id<SRWebSocketDelegate> _Nullable delegate, SRDelegateAvailableMethods availableMethods);\n\n@interface SRDelegateController : NSObject\n\n@property (nonatomic, weak) id<SRWebSocketDelegate> delegate;\n@property (atomic, readonly) SRDelegateAvailableMethods availableDelegateMethods;\n\n@property (nullable, nonatomic, strong) dispatch_queue_t dispatchQueue;\n@property (nullable, nonatomic, strong) NSOperationQueue *operationQueue;\n\n///--------------------------------------\n#pragma mark - Perform\n///--------------------------------------\n\n- (void)performDelegateBlock:(SRDelegateBlock)block;\n- (void)performDelegateQueueBlock:(dispatch_block_t)block;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Delegate/SRDelegateController.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRDelegateController.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface SRDelegateController ()\n\n@property (nonatomic, strong, readonly) dispatch_queue_t accessQueue;\n\n@property (atomic, assign, readwrite) SRDelegateAvailableMethods availableDelegateMethods;\n\n@end\n\n@implementation SRDelegateController\n\n@synthesize delegate = _delegate;\n@synthesize dispatchQueue = _dispatchQueue;\n@synthesize operationQueue = _operationQueue;\n\n///--------------------------------------\n#pragma mark - Init\n///--------------------------------------\n\n- (instancetype)init\n{\n    self = [super init];\n    if (!self) return self;\n\n    _accessQueue = dispatch_queue_create(\"com.facebook.socketrocket.delegate.access\", DISPATCH_QUEUE_CONCURRENT);\n    _dispatchQueue = dispatch_get_main_queue();\n\n    return self;\n}\n\n///--------------------------------------\n#pragma mark - Accessors\n///--------------------------------------\n\n- (void)setDelegate:(id<SRWebSocketDelegate> _Nullable)delegate\n{\n    dispatch_barrier_async(self.accessQueue, ^{\n        self->_delegate = delegate;\n\n        self.availableDelegateMethods = (SRDelegateAvailableMethods){\n            .didReceiveMessage = [delegate respondsToSelector:@selector(webSocket:didReceiveMessage:)],\n            .didReceiveMessageWithString = [delegate respondsToSelector:@selector(webSocket:didReceiveMessageWithString:)],\n            .didReceiveMessageWithData = [delegate respondsToSelector:@selector(webSocket:didReceiveMessageWithData:)],\n            .didOpen = [delegate respondsToSelector:@selector(webSocketDidOpen:)],\n            .didFailWithError = [delegate respondsToSelector:@selector(webSocket:didFailWithError:)],\n            .didCloseWithCode = [delegate respondsToSelector:@selector(webSocket:didCloseWithCode:reason:wasClean:)],\n            .didReceivePing = [delegate respondsToSelector:@selector(webSocket:didReceivePingWithData:)],\n            .didReceivePong = [delegate respondsToSelector:@selector(webSocket:didReceivePong:)],\n            .shouldConvertTextFrameToString = [delegate respondsToSelector:@selector(webSocketShouldConvertTextFrameToString:)]\n        };\n    });\n}\n\n- (id<SRWebSocketDelegate> _Nullable)delegate\n{\n    __block id<SRWebSocketDelegate> delegate = nil;\n    dispatch_sync(self.accessQueue, ^{\n        delegate = self->_delegate;\n    });\n    return delegate;\n}\n\n- (void)setDispatchQueue:(dispatch_queue_t _Nullable)queue\n{\n    dispatch_barrier_async(self.accessQueue, ^{\n        self->_dispatchQueue = queue ?: dispatch_get_main_queue();\n        self->_operationQueue = nil;\n    });\n}\n\n- (dispatch_queue_t _Nullable)dispatchQueue\n{\n    __block dispatch_queue_t queue = nil;\n    dispatch_sync(self.accessQueue, ^{\n        queue = self->_dispatchQueue;\n    });\n    return queue;\n}\n\n- (void)setOperationQueue:(NSOperationQueue *_Nullable)queue\n{\n    dispatch_barrier_async(self.accessQueue, ^{\n        self->_dispatchQueue = queue ? nil : dispatch_get_main_queue();\n        self->_operationQueue = queue;\n    });\n}\n\n- (NSOperationQueue *_Nullable)operationQueue\n{\n    __block NSOperationQueue *queue = nil;\n    dispatch_sync(self.accessQueue, ^{\n        queue = self->_operationQueue;\n    });\n    return queue;\n}\n\n///--------------------------------------\n#pragma mark - Perform\n///--------------------------------------\n\n- (void)performDelegateBlock:(SRDelegateBlock)block\n{\n    __block __strong id<SRWebSocketDelegate> delegate = nil;\n    __block SRDelegateAvailableMethods availableMethods;\n    dispatch_sync(self.accessQueue, ^{\n        delegate = self->_delegate; // Not `OK` to go through `self`, since queue sync.\n        availableMethods = self.availableDelegateMethods; // `OK` to call through `self`, since no queue sync.\n    });\n    [self performDelegateQueueBlock:^{\n        block(delegate, availableMethods);\n    }];\n}\n\n- (void)performDelegateQueueBlock:(dispatch_block_t)block\n{\n    dispatch_queue_t dispatchQueue = self.dispatchQueue;\n    if (dispatchQueue) {\n        dispatch_async(dispatchQueue, block);\n    } else {\n        [self.operationQueue addOperationWithBlock:block];\n    }\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/IOConsumer/SRIOConsumer.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\n@class SRWebSocket; // TODO: (nlutsenko) Remove dependency on SRWebSocket here.\n\n// Returns number of bytes consumed. Returning 0 means you didn't match.\n// Sends bytes to callback handler;\ntypedef size_t (^stream_scanner)(NSData *collected_data);\ntypedef void (^data_callback)(SRWebSocket *webSocket,  NSData *data);\n\n@interface SRIOConsumer : NSObject {\n    stream_scanner _scanner;\n    data_callback _handler;\n    size_t _bytesNeeded;\n    BOOL _readToCurrentFrame;\n    BOOL _unmaskBytes;\n}\n@property (nonatomic, copy, readonly) stream_scanner consumer;\n@property (nonatomic, copy, readonly) data_callback handler;\n@property (nonatomic, assign) size_t bytesNeeded;\n@property (nonatomic, assign, readonly) BOOL readToCurrentFrame;\n@property (nonatomic, assign, readonly) BOOL unmaskBytes;\n\n- (void)resetWithScanner:(stream_scanner)scanner\n                 handler:(data_callback)handler\n             bytesNeeded:(size_t)bytesNeeded\n      readToCurrentFrame:(BOOL)readToCurrentFrame\n             unmaskBytes:(BOOL)unmaskBytes;\n\n@end\n"
  },
  {
    "path": "SocketRocket/Internal/IOConsumer/SRIOConsumer.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRIOConsumer.h\"\n\n@implementation SRIOConsumer\n\n@synthesize bytesNeeded = _bytesNeeded;\n@synthesize consumer = _scanner;\n@synthesize handler = _handler;\n@synthesize readToCurrentFrame = _readToCurrentFrame;\n@synthesize unmaskBytes = _unmaskBytes;\n\n- (void)resetWithScanner:(stream_scanner)scanner\n                 handler:(data_callback)handler\n             bytesNeeded:(size_t)bytesNeeded\n      readToCurrentFrame:(BOOL)readToCurrentFrame\n             unmaskBytes:(BOOL)unmaskBytes\n{\n    _scanner = [scanner copy];\n    _handler = [handler copy];\n    _bytesNeeded = bytesNeeded;\n    _readToCurrentFrame = readToCurrentFrame;\n    _unmaskBytes = unmaskBytes;\n    assert(_scanner || _bytesNeeded);\n}\n\n@end\n"
  },
  {
    "path": "SocketRocket/Internal/IOConsumer/SRIOConsumerPool.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"SRIOConsumer.h\" // TODO: (nlutsenko) Convert to @class and constants file for block types\n\n// This class is not thread-safe, and is expected to always be run on the same queue.\n@interface SRIOConsumerPool : NSObject\n\n- (instancetype)initWithBufferCapacity:(NSUInteger)poolSize;\n\n- (SRIOConsumer *)consumerWithScanner:(stream_scanner)scanner\n                              handler:(data_callback)handler\n                          bytesNeeded:(size_t)bytesNeeded\n                   readToCurrentFrame:(BOOL)readToCurrentFrame\n                          unmaskBytes:(BOOL)unmaskBytes;\n- (void)returnConsumer:(SRIOConsumer *)consumer;\n\n@end\n"
  },
  {
    "path": "SocketRocket/Internal/IOConsumer/SRIOConsumerPool.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRIOConsumerPool.h\"\n\n@implementation SRIOConsumerPool {\n    NSUInteger _poolSize;\n    NSMutableArray<SRIOConsumer *> *_bufferedConsumers;\n}\n\n- (instancetype)initWithBufferCapacity:(NSUInteger)poolSize\n{\n    self = [super init];\n    if (self) {\n        _poolSize = poolSize;\n        _bufferedConsumers = [NSMutableArray arrayWithCapacity:poolSize];\n    }\n    return self;\n}\n\n- (instancetype)init\n{\n    return [self initWithBufferCapacity:8];\n}\n\n- (SRIOConsumer *)consumerWithScanner:(stream_scanner)scanner\n                              handler:(data_callback)handler\n                          bytesNeeded:(size_t)bytesNeeded\n                   readToCurrentFrame:(BOOL)readToCurrentFrame\n                          unmaskBytes:(BOOL)unmaskBytes\n{\n    SRIOConsumer *consumer = nil;\n    if (_bufferedConsumers.count) {\n        consumer = [_bufferedConsumers lastObject];\n        [_bufferedConsumers removeLastObject];\n    } else {\n        consumer = [[SRIOConsumer alloc] init];\n    }\n\n    [consumer resetWithScanner:scanner\n                       handler:handler\n                   bytesNeeded:bytesNeeded\n            readToCurrentFrame:readToCurrentFrame\n                   unmaskBytes:unmaskBytes];\n\n    return consumer;\n}\n\n- (void)returnConsumer:(SRIOConsumer *)consumer\n{\n    if (_bufferedConsumers.count < _poolSize) {\n        [_bufferedConsumers addObject:consumer];\n    }\n}\n\n@end\n"
  },
  {
    "path": "SocketRocket/Internal/NSRunLoop+SRWebSocketPrivate.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <SocketRocket/NSRunLoop+SRWebSocket.h>\n\n// Empty function that force links the object file for the category.\nextern void import_NSRunLoop_SRWebSocket(void);\n"
  },
  {
    "path": "SocketRocket/Internal/NSURLRequest+SRWebSocketPrivate.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <SocketRocket/NSURLRequest+SRWebSocket.h>\n\n// Empty function that force links the object file for the category.\nextern void import_NSURLRequest_SRWebSocket(void);\n"
  },
  {
    "path": "SocketRocket/Internal/Proxy/SRProxyConnect.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef void(^SRProxyConnectCompletion)(NSError *_Nullable error,\n                                        NSInputStream *_Nullable readStream,\n                                        NSOutputStream *_Nullable writeStream);\n\n@interface SRProxyConnect : NSObject\n\n- (instancetype)initWithURL:(NSURL *)url;\n\n- (void)openNetworkStreamWithCompletion:(SRProxyConnectCompletion)completion;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Proxy/SRProxyConnect.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRProxyConnect.h\"\n\n#import \"NSRunLoop+SRWebSocket.h\"\n#import \"SRConstants.h\"\n#import \"SRError.h\"\n#import \"SRLog.h\"\n#import \"SRURLUtilities.h\"\n\n@interface SRProxyConnect() <NSStreamDelegate>\n\n@property (nonatomic, strong) NSURL *url;\n@property (nonatomic, strong) NSInputStream *inputStream;\n@property (nonatomic, strong) NSOutputStream *outputStream;\n\n@end\n\n@implementation SRProxyConnect\n{\n    SRProxyConnectCompletion _completion;\n\n    NSString *_httpProxyHost;\n    uint32_t _httpProxyPort;\n\n    CFHTTPMessageRef _receivedHTTPHeaders;\n\n    NSString *_socksProxyHost;\n    uint32_t _socksProxyPort;\n    NSString *_socksProxyUsername;\n    NSString *_socksProxyPassword;\n\n    BOOL _connectionRequiresSSL;\n\n    NSMutableArray<NSData *> *_inputQueue;\n    dispatch_queue_t _writeQueue;\n}\n\n///--------------------------------------\n#pragma mark - Init\n///--------------------------------------\n\n-(instancetype)initWithURL:(NSURL *)url\n{\n    self = [super init];\n    if (!self) return self;\n\n    _url = url;\n    _connectionRequiresSSL = SRURLRequiresSSL(url);\n\n    _writeQueue = dispatch_queue_create(\"com.facebook.socketrocket.proxyconnect.write\", DISPATCH_QUEUE_SERIAL);\n    _inputQueue = [NSMutableArray arrayWithCapacity:2];\n\n    return self;\n}\n\n- (void)dealloc\n{\n    // If we get deallocated before the socket open finishes - we need to cleanup everything.\n\n    [self.inputStream removeFromRunLoop:[NSRunLoop SR_networkRunLoop] forMode:NSDefaultRunLoopMode];\n    self.inputStream.delegate = nil;\n    [self.inputStream close];\n    self.inputStream = nil;\n\n    self.outputStream.delegate = nil;\n    [self.outputStream close];\n    self.outputStream = nil;\n}\n\n///--------------------------------------\n#pragma mark - Open\n///--------------------------------------\n\n- (void)openNetworkStreamWithCompletion:(SRProxyConnectCompletion)completion\n{\n    _completion = completion;\n    [self _configureProxy];\n}\n\n///--------------------------------------\n#pragma mark - Flow\n///--------------------------------------\n\n- (void)_didConnect\n{\n    SRDebugLog(@\"_didConnect, return streams\");\n    if (_connectionRequiresSSL) {\n        if (_httpProxyHost) {\n            // Must set the real peer name before turning on SSL\n            SRDebugLog(@\"proxy set peer name to real host %@\", self.url.host);\n            [self.outputStream setProperty:self.url.host forKey:@\"_kCFStreamPropertySocketPeerName\"];\n        }\n    }\n    if (_receivedHTTPHeaders) {\n        CFRelease(_receivedHTTPHeaders);\n        _receivedHTTPHeaders = NULL;\n    }\n\n    NSInputStream *inputStream = self.inputStream;\n    NSOutputStream *outputStream = self.outputStream;\n\n    self.inputStream = nil;\n    self.outputStream = nil;\n\n    [inputStream removeFromRunLoop:[NSRunLoop SR_networkRunLoop] forMode:NSDefaultRunLoopMode];\n    inputStream.delegate = nil;\n    outputStream.delegate = nil;\n\n    _completion(nil, inputStream, outputStream);\n}\n\n- (void)_failWithError:(NSError *)error\n{\n    SRDebugLog(@\"_failWithError, return error\");\n    if (!error) {\n        error = SRHTTPErrorWithCodeDescription(500, 2132,@\"Proxy Error\");\n    }\n\n    if (_receivedHTTPHeaders) {\n        CFRelease(_receivedHTTPHeaders);\n        _receivedHTTPHeaders = NULL;\n    }\n\n    self.inputStream.delegate = nil;\n    self.outputStream.delegate = nil;\n\n    [self.inputStream removeFromRunLoop:[NSRunLoop SR_networkRunLoop]\n                                forMode:NSDefaultRunLoopMode];\n    [self.inputStream close];\n    [self.outputStream close];\n    self.inputStream = nil;\n    self.outputStream = nil;\n    _completion(error, nil, nil);\n}\n\n// get proxy setting from device setting\n- (void)_configureProxy\n{\n    SRDebugLog(@\"configureProxy\");\n    NSDictionary *proxySettings = CFBridgingRelease(CFNetworkCopySystemProxySettings());\n\n    // CFNetworkCopyProxiesForURL doesn't understand ws:// or wss://\n    NSURL *httpURL;\n    if (_connectionRequiresSSL) {\n        httpURL = [NSURL URLWithString:[NSString stringWithFormat:@\"https://%@\", _url.host]];\n    } else {\n        httpURL = [NSURL URLWithString:[NSString stringWithFormat:@\"http://%@\", _url.host]];\n    }\n\n    NSArray *proxies = CFBridgingRelease(CFNetworkCopyProxiesForURL((__bridge CFURLRef)httpURL, (__bridge CFDictionaryRef)proxySettings));\n    if (proxies.count == 0) {\n        SRDebugLog(@\"configureProxy no proxies\");\n        [self _openConnection];\n        return;                 // no proxy\n    }\n    NSDictionary *settings = [proxies objectAtIndex:0];\n    NSString *proxyType = settings[(NSString *)kCFProxyTypeKey];\n    if ([proxyType isEqualToString:(NSString *)kCFProxyTypeAutoConfigurationURL]) {\n        NSURL *pacURL = settings[(NSString *)kCFProxyAutoConfigurationURLKey];\n        if (pacURL) {\n            [self _fetchPAC:pacURL withProxySettings:proxySettings];\n            return;\n        }\n    }\n    if ([proxyType isEqualToString:(__bridge NSString *)kCFProxyTypeAutoConfigurationJavaScript]) {\n        NSString *script = settings[(__bridge NSString *)kCFProxyAutoConfigurationJavaScriptKey];\n        if (script) {\n            [self _runPACScript:script withProxySettings:proxySettings];\n            return;\n        }\n    }\n    [self _readProxySettingWithType:proxyType settings:settings];\n\n    [self _openConnection];\n}\n\n- (void)_readProxySettingWithType:(NSString *)proxyType settings:(NSDictionary *)settings\n{\n    if ([proxyType isEqualToString:(NSString *)kCFProxyTypeHTTP] ||\n        [proxyType isEqualToString:(NSString *)kCFProxyTypeHTTPS]) {\n        _httpProxyHost = settings[(NSString *)kCFProxyHostNameKey];\n        NSNumber *portValue = settings[(NSString *)kCFProxyPortNumberKey];\n        if (portValue) {\n            _httpProxyPort = [portValue intValue];\n        }\n    }\n    if ([proxyType isEqualToString:(NSString *)kCFProxyTypeSOCKS]) {\n        _socksProxyHost = settings[(NSString *)kCFProxyHostNameKey];\n        NSNumber *portValue = settings[(NSString *)kCFProxyPortNumberKey];\n        if (portValue)\n            _socksProxyPort = [portValue intValue];\n        _socksProxyUsername = settings[(NSString *)kCFProxyUsernameKey];\n        _socksProxyPassword = settings[(NSString *)kCFProxyPasswordKey];\n    }\n    if (_httpProxyHost) {\n        SRDebugLog(@\"Using http proxy %@:%u\", _httpProxyHost, _httpProxyPort);\n    } else if (_socksProxyHost) {\n        SRDebugLog(@\"Using socks proxy %@:%u\", _socksProxyHost, _socksProxyPort);\n    } else {\n        SRDebugLog(@\"configureProxy no proxies\");\n    }\n}\n\n- (void)_fetchPAC:(NSURL *)PACurl withProxySettings:(NSDictionary *)proxySettings\n{\n    SRDebugLog(@\"SRWebSocket fetchPAC:%@\", PACurl);\n\n    if ([PACurl isFileURL]) {\n        NSError *error = nil;\n        NSString *script = [NSString stringWithContentsOfURL:PACurl\n                                                usedEncoding:NULL\n                                                       error:&error];\n\n        if (error) {\n            [self _openConnection];\n        } else {\n            [self _runPACScript:script withProxySettings:proxySettings];\n        }\n        return;\n    }\n\n    NSString *scheme = [PACurl.scheme lowercaseString];\n    if (![scheme isEqualToString:@\"http\"] && ![scheme isEqualToString:@\"https\"]) {\n        // Don't know how to read data from this URL, we'll have to give up\n        // We'll simply assume no proxies, and start the request as normal\n        [self _openConnection];\n        return;\n    }\n    __weak typeof(self) wself = self;\n    NSURLRequest *request = [NSURLRequest requestWithURL:PACurl];\n    NSURLSession *session = [NSURLSession sharedSession];\n    [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {\n        __strong typeof(wself) sself = wself;\n        if (!error) {\n            NSString *script = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];\n            [sself _runPACScript:script withProxySettings:proxySettings];\n        } else {\n            [sself _openConnection];\n        }\n    }] resume];\n}\n\n- (void)_runPACScript:(NSString *)script withProxySettings:(NSDictionary *)proxySettings\n{\n    if (!script) {\n        [self _openConnection];\n        return;\n    }\n    SRDebugLog(@\"runPACScript\");\n    // From: http://developer.apple.com/samplecode/CFProxySupportTool/listing1.html\n    // Work around <rdar://problem/5530166>.  This dummy call to\n    // CFNetworkCopyProxiesForURL initialise some state within CFNetwork\n    // that is required by CFNetworkCopyProxiesForAutoConfigurationScript.\n    CFBridgingRelease(CFNetworkCopyProxiesForURL((__bridge CFURLRef)_url, (__bridge CFDictionaryRef)proxySettings));\n\n    // Obtain the list of proxies by running the autoconfiguration script\n    CFErrorRef err = NULL;\n\n    // CFNetworkCopyProxiesForAutoConfigurationScript doesn't understand ws:// or wss://\n    NSURL *httpURL;\n    if (_connectionRequiresSSL)\n        httpURL = [NSURL URLWithString:[NSString stringWithFormat:@\"https://%@\", _url.host]];\n    else\n        httpURL = [NSURL URLWithString:[NSString stringWithFormat:@\"http://%@\", _url.host]];\n\n    NSArray *proxies = CFBridgingRelease(CFNetworkCopyProxiesForAutoConfigurationScript((__bridge CFStringRef)script,(__bridge CFURLRef)httpURL, &err));\n    if (!err && [proxies count] > 0) {\n        NSDictionary *settings = [proxies objectAtIndex:0];\n        NSString *proxyType = settings[(NSString *)kCFProxyTypeKey];\n        [self _readProxySettingWithType:proxyType settings:settings];\n    }\n    [self _openConnection];\n}\n\n- (void)_openConnection\n{\n    [self _initializeStreams];\n\n    [self.inputStream scheduleInRunLoop:[NSRunLoop SR_networkRunLoop]\n                                forMode:NSDefaultRunLoopMode];\n    //[self.outputStream scheduleInRunLoop:[NSRunLoop SR_networkRunLoop]\n    //                           forMode:NSDefaultRunLoopMode];\n    [self.outputStream open];\n    [self.inputStream open];\n}\n\n- (void)_initializeStreams\n{\n    assert(_url.port.unsignedIntValue <= UINT32_MAX);\n    uint32_t port = _url.port.unsignedIntValue;\n    if (port == 0) {\n        port = (_connectionRequiresSSL ? 443 : 80);\n    }\n    NSString *host = _url.host;\n\n    if (_httpProxyHost) {\n        host = _httpProxyHost;\n        port = (_httpProxyPort ?: 80);\n    }\n\n    CFReadStreamRef readStream = NULL;\n    CFWriteStreamRef writeStream = NULL;\n\n    SRDebugLog(@\"ProxyConnect connect stream to %@:%u\", host, port);\n    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);\n\n    self.outputStream = CFBridgingRelease(writeStream);\n    self.inputStream = CFBridgingRelease(readStream);\n\n    if (_socksProxyHost) {\n        SRDebugLog(@\"ProxyConnect set sock property stream to %@:%u user %@ password %@\", _socksProxyHost, _socksProxyPort, _socksProxyUsername, _socksProxyPassword);\n        NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:4];\n        settings[NSStreamSOCKSProxyHostKey] = _socksProxyHost;\n        if (_socksProxyPort) {\n            settings[NSStreamSOCKSProxyPortKey] = @(_socksProxyPort);\n        }\n        if (_socksProxyUsername) {\n            settings[NSStreamSOCKSProxyUserKey] = _socksProxyUsername;\n        }\n        if (_socksProxyPassword) {\n            settings[NSStreamSOCKSProxyPasswordKey] = _socksProxyPassword;\n        }\n        [self.inputStream setProperty:settings forKey:NSStreamSOCKSProxyConfigurationKey];\n        [self.outputStream setProperty:settings forKey:NSStreamSOCKSProxyConfigurationKey];\n    }\n    self.inputStream.delegate = self;\n    self.outputStream.delegate = self;\n}\n\n- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode\n{\n    SRDebugLog(@\"stream handleEvent %u\", eventCode);\n    switch (eventCode) {\n        case NSStreamEventOpenCompleted: {\n            if (aStream == self.inputStream) {\n                if (_httpProxyHost) {\n                    [self _proxyDidConnect];\n                } else {\n                    [self _didConnect];\n                }\n            }\n            break;\n        }\n        case NSStreamEventErrorOccurred: {\n            [self _failWithError:aStream.streamError];\n            break;\n        }\n        case NSStreamEventEndEncountered: {\n            [self _failWithError:aStream.streamError];\n            break;\n        }\n        case NSStreamEventHasBytesAvailable: {\n            if (aStream == _inputStream) {\n                [self _processInputStream];\n            }\n            break;\n        }\n        case NSStreamEventHasSpaceAvailable:\n        case NSStreamEventNone:\n            SRDebugLog(@\"(default)  %@\", aStream);\n            break;\n    }\n}\n\n- (void)_proxyDidConnect\n{\n    SRDebugLog(@\"Proxy Connected\");\n    uint32_t port = _url.port.unsignedIntValue;\n    if (port == 0) {\n        port = (_connectionRequiresSSL ? 443 : 80);\n    }\n    // Send HTTP CONNECT Request\n    NSString *connectRequestStr = [NSString stringWithFormat:@\"CONNECT %@:%u HTTP/1.1\\r\\nHost: %@\\r\\nConnection: keep-alive\\r\\nProxy-Connection: keep-alive\\r\\n\\r\\n\", _url.host, port, _url.host];\n\n    NSData *message = [connectRequestStr dataUsingEncoding:NSUTF8StringEncoding];\n    SRDebugLog(@\"Proxy sending %@\", connectRequestStr);\n\n    [self _writeData:message];\n}\n\n///handles the incoming bytes and sending them to the proper processing method\n- (void)_processInputStream\n{\n    NSMutableData *buf = [NSMutableData dataWithCapacity:SRDefaultBufferSize()];\n    uint8_t *buffer = buf.mutableBytes;\n    NSInteger length = [_inputStream read:buffer maxLength:SRDefaultBufferSize()];\n\n    if (length <= 0) {\n        return;\n    }\n\n    BOOL process = (_inputQueue.count == 0);\n    [_inputQueue addObject:[NSData dataWithBytes:buffer length:length]];\n\n    if (process) {\n        [self _dequeueInput];\n    }\n}\n\n// dequeue the incoming input so it is processed in order\n\n- (void)_dequeueInput\n{\n    while (_inputQueue.count > 0) {\n        NSData *data = _inputQueue.firstObject;\n        [_inputQueue removeObjectAtIndex:0];\n\n        // No need to process any data further, we got the full header data.\n        if ([self _proxyProcessHTTPResponseWithData:data]) {\n            break;\n        }\n    }\n}\n//handle checking the proxy  connection status\n- (BOOL)_proxyProcessHTTPResponseWithData:(NSData *)data\n{\n    if (_receivedHTTPHeaders == NULL) {\n        _receivedHTTPHeaders = CFHTTPMessageCreateEmpty(NULL, NO);\n    }\n\n    CFHTTPMessageAppendBytes(_receivedHTTPHeaders, (const UInt8 *)data.bytes, data.length);\n    if (CFHTTPMessageIsHeaderComplete(_receivedHTTPHeaders)) {\n        SRDebugLog(@\"Finished reading headers %@\", CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(_receivedHTTPHeaders)));\n        [self _proxyHTTPHeadersDidFinish];\n        return YES;\n    }\n\n    return NO;\n}\n\n- (void)_proxyHTTPHeadersDidFinish\n{\n    NSInteger responseCode = CFHTTPMessageGetResponseStatusCode(_receivedHTTPHeaders);\n\n    if (responseCode >= 299) {\n        SRDebugLog(@\"Connect to Proxy Request failed with response code %d\", responseCode);\n        NSError *error = SRHTTPErrorWithCodeDescription(responseCode, 2132,\n                                                        [NSString stringWithFormat:@\"Received bad response code from proxy server: %d.\",\n                                                         (int)responseCode]);\n        [self _failWithError:error];\n        return;\n    }\n    SRDebugLog(@\"proxy connect return %d, call socket connect\", responseCode);\n    [self _didConnect];\n}\n\nstatic NSTimeInterval const SRProxyConnectWriteTimeout = 5.0;\n\n- (void)_writeData:(NSData *)data\n{\n    const uint8_t * bytes = data.bytes;\n    __block NSInteger timeout = (NSInteger)(SRProxyConnectWriteTimeout * 1000000); // wait timeout before giving up\n    __weak typeof(self) wself = self;\n    dispatch_async(_writeQueue, ^{\n        __strong typeof(wself) sself = self;\n        if (!sself) {\n            return;\n        }\n        NSOutputStream *outStream = sself.outputStream;\n        if (!outStream) {\n            return;\n        }\n        while (![outStream hasSpaceAvailable]) {\n            usleep(100); //wait until the socket is ready\n            timeout -= 100;\n            if (timeout < 0) {\n                NSError *error = SRHTTPErrorWithCodeDescription(408, 2132, @\"Proxy timeout\");\n                [sself _failWithError:error];\n            } else if (outStream.streamError != nil) {\n                [sself _failWithError:outStream.streamError];\n            }\n        }\n        [outStream write:bytes maxLength:data.length];\n    });\n}\n\n@end\n"
  },
  {
    "path": "SocketRocket/Internal/RunLoop/SRRunLoopThread.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface SRRunLoopThread : NSThread\n\n@property (nonatomic, strong, readonly) NSRunLoop *runLoop;\n\n+ (instancetype)sharedThread;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/RunLoop/SRRunLoopThread.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRRunLoopThread.h\"\n\n@interface SRRunLoopThread ()\n{\n    dispatch_group_t _waitGroup;\n}\n\n@property (nonatomic, strong, readwrite) NSRunLoop *runLoop;\n\n@end\n\n@implementation SRRunLoopThread\n\n+ (instancetype)sharedThread\n{\n    static SRRunLoopThread *thread;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        thread = [[SRRunLoopThread alloc] init];\n        thread.name = @\"com.facebook.SocketRocket.NetworkThread\";\n        thread.qualityOfService = NSQualityOfServiceUserInitiated;\n        [thread start];\n    });\n    return thread;\n}\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        _waitGroup = dispatch_group_create();\n        dispatch_group_enter(_waitGroup);\n    }\n    return self;\n}\n\n- (void)main\n{\n    @autoreleasepool {\n        _runLoop = [NSRunLoop currentRunLoop];\n        dispatch_group_leave(_waitGroup);\n\n        // Add an empty run loop source to prevent runloop from spinning.\n        CFRunLoopSourceContext sourceCtx = {\n            .version = 0,\n            .info = NULL,\n            .retain = NULL,\n            .release = NULL,\n            .copyDescription = NULL,\n            .equal = NULL,\n            .hash = NULL,\n            .schedule = NULL,\n            .cancel = NULL,\n            .perform = NULL\n        };\n        CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0, &sourceCtx);\n        CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);\n        CFRelease(source);\n\n        while ([_runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {\n\n        }\n        assert(NO);\n    }\n}\n\n- (NSRunLoop *)runLoop\n{\n    dispatch_group_wait(_waitGroup, DISPATCH_TIME_FOREVER);\n    return _runLoop;\n}\n\n@end\n"
  },
  {
    "path": "SocketRocket/Internal/SRConstants.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\ntypedef NS_ENUM(uint8_t, SROpCode)\n{\n    SROpCodeTextFrame = 0x1,\n    SROpCodeBinaryFrame = 0x2,\n    // 3-7 reserved.\n    SROpCodeConnectionClose = 0x8,\n    SROpCodePing = 0x9,\n    SROpCodePong = 0xA,\n    // B-F reserved.\n};\n\n/**\n Default buffer size that is used for reading/writing to streams.\n */\nextern size_t SRDefaultBufferSize(void);\n"
  },
  {
    "path": "SocketRocket/Internal/SRConstants.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRConstants.h\"\n\nsize_t SRDefaultBufferSize(void) {\n    static size_t size;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        size = getpagesize();\n    });\n    return size;\n}\n"
  },
  {
    "path": "SocketRocket/Internal/Security/SRPinningSecurityPolicy.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\n#import <SocketRocket/SRSecurityPolicy.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n * NOTE: While publicly, SocketRocket does not support configuring the security policy with pinned certificates,\n * it is still possible to manually construct a security policy of this class. If you do this, note that you may\n * be open to MitM attacks, and we will not support any issues you may have. Dive at your own risk.\n */\n@interface SRPinningSecurityPolicy : SRSecurityPolicy\n\n- (instancetype)initWithCertificates:(NSArray *)pinnedCertificates;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Security/SRPinningSecurityPolicy.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRPinningSecurityPolicy.h\"\n\n#import <Foundation/Foundation.h>\n\n#import \"SRLog.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface SRPinningSecurityPolicy ()\n\n@property (nonatomic, copy, readonly) NSArray *pinnedCertificates;\n\n@end\n\n@implementation SRPinningSecurityPolicy\n\n- (instancetype)initWithCertificates:(NSArray *)pinnedCertificates\n{\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated\"\n    // Do not validate certificate chain since we're pinning to specific certificates.\n    self = [super initWithCertificateChainValidationEnabled:NO];\n#pragma clang diagnostic pop\n\n    if (!self) { return self; }\n\n    if (pinnedCertificates.count == 0) {\n        @throw [NSException exceptionWithName:@\"Creating security policy failed.\"\n                                       reason:@\"Must specify at least one certificate when creating a pinning policy.\"\n                                     userInfo:nil];\n    }\n    _pinnedCertificates = [pinnedCertificates copy];\n\n    return self;\n}\n\n- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain\n{\n    SRDebugLog(@\"Pinned cert count: %d\", self.pinnedCertificates.count);\n    NSUInteger requiredCertCount = self.pinnedCertificates.count;\n\n    NSUInteger validatedCertCount = 0;\n    CFIndex serverCertCount = SecTrustGetCertificateCount(serverTrust);\n    for (CFIndex i = 0; i < serverCertCount; i++) {\n        SecCertificateRef cert = SecTrustGetCertificateAtIndex(serverTrust, i);\n        NSData *data = CFBridgingRelease(SecCertificateCopyData(cert));\n        for (id ref in self.pinnedCertificates) {\n            SecCertificateRef trustedCert = (__bridge SecCertificateRef)ref;\n            // TODO: (nlutsenko) Add caching, so we don't copy the data for every pinned cert all the time.\n            NSData *trustedCertData = CFBridgingRelease(SecCertificateCopyData(trustedCert));\n            if ([trustedCertData isEqualToData:data]) {\n                validatedCertCount++;\n                break;\n            }\n        }\n    }\n    return (requiredCertCount == validatedCertCount);\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRError.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nextern NSError *SRErrorWithDomainCodeDescription(NSString *domain, NSInteger code, NSString *description);\nextern NSError *SRErrorWithCodeDescription(NSInteger code, NSString *description);\nextern NSError *SRErrorWithCodeDescriptionUnderlyingError(NSInteger code, NSString *description, NSError *underlyingError);\n\nextern NSError *SRHTTPErrorWithCodeDescription(NSInteger httpCode, NSInteger errorCode, NSString *description);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRError.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRError.h\"\n\n#import \"SRWebSocket.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\nNSError *SRErrorWithDomainCodeDescription(NSString *domain, NSInteger code, NSString *description)\n{\n    return [NSError errorWithDomain:domain code:code userInfo:@{ NSLocalizedDescriptionKey: description }];\n}\n\nNSError *SRErrorWithCodeDescription(NSInteger code, NSString *description)\n{\n    return SRErrorWithDomainCodeDescription(SRWebSocketErrorDomain, code, description);\n}\n\nNSError *SRErrorWithCodeDescriptionUnderlyingError(NSInteger code, NSString *description, NSError *underlyingError)\n{\n    return [NSError errorWithDomain:SRWebSocketErrorDomain\n                               code:code\n                           userInfo:@{ NSLocalizedDescriptionKey: description,\n                                       NSUnderlyingErrorKey: underlyingError }];\n}\n\nNSError *SRHTTPErrorWithCodeDescription(NSInteger httpCode, NSInteger errorCode, NSString *description)\n{\n    return [NSError errorWithDomain:SRWebSocketErrorDomain\n                               code:errorCode\n                           userInfo:@{ NSLocalizedDescriptionKey: description,\n                                       SRHTTPResponseErrorKey: @(httpCode) }];\n}\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRHTTPConnectMessage.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n#import <CFNetwork/CFNetwork.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nextern CFHTTPMessageRef SRHTTPConnectMessageCreate(NSURLRequest *request,\n                                                   NSString *securityKey,\n                                                   uint8_t webSocketProtocolVersion,\n                                                   NSArray<NSHTTPCookie *> *_Nullable cookies,\n                                                   NSArray<NSString *> *_Nullable requestedProtocols);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRHTTPConnectMessage.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRHTTPConnectMessage.h\"\n\n#import \"SRURLUtilities.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\nstatic NSString *_SRHTTPConnectMessageHost(NSURL *url)\n{\n    NSString *host = url.host;\n    if (url.port) {\n        host = [host stringByAppendingFormat:@\":%@\", url.port];\n    }\n    return host;\n}\n\nCFHTTPMessageRef SRHTTPConnectMessageCreate(NSURLRequest *request,\n                                            NSString *securityKey,\n                                            uint8_t webSocketProtocolVersion,\n                                            NSArray<NSHTTPCookie *> *_Nullable cookies,\n                                            NSArray<NSString *> *_Nullable requestedProtocols)\n{\n    NSURL *url = request.URL;\n\n    CFHTTPMessageRef message = CFHTTPMessageCreateRequest(NULL, (__bridge CFStringRef)request.HTTPMethod, (__bridge CFURLRef)url, kCFHTTPVersion1_1);\n\n    // Set host first so it defaults\n    CFHTTPMessageSetHeaderFieldValue(message, CFSTR(\"Host\"), (__bridge CFStringRef)_SRHTTPConnectMessageHost(url));\n\n    // Apply cookies if any have been provided\n    if (cookies) {\n        NSDictionary<NSString *, NSString *> *messageCookies = [NSHTTPCookie requestHeaderFieldsWithCookies:(NSArray<NSHTTPCookie*> *_Nonnull)cookies];\n        [messageCookies enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {\n            if (key.length && obj.length) {\n                CFHTTPMessageSetHeaderFieldValue(message, (__bridge CFStringRef)key, (__bridge CFStringRef)obj);\n            }\n        }];\n    }\n\n    // set header for http basic auth\n    NSString *basicAuthorizationString = SRBasicAuthorizationHeaderFromURL(url);\n    if (basicAuthorizationString) {\n        CFHTTPMessageSetHeaderFieldValue(message, CFSTR(\"Authorization\"), (__bridge CFStringRef)basicAuthorizationString);\n    }\n\n    CFHTTPMessageSetHeaderFieldValue(message, CFSTR(\"Upgrade\"), CFSTR(\"websocket\"));\n    CFHTTPMessageSetHeaderFieldValue(message, CFSTR(\"Connection\"), CFSTR(\"Upgrade\"));\n    CFHTTPMessageSetHeaderFieldValue(message, CFSTR(\"Sec-WebSocket-Key\"), (__bridge CFStringRef)securityKey);\n    CFHTTPMessageSetHeaderFieldValue(message, CFSTR(\"Sec-WebSocket-Version\"), (__bridge CFStringRef)@(webSocketProtocolVersion).stringValue);\n\n    CFHTTPMessageSetHeaderFieldValue(message, CFSTR(\"Origin\"), (__bridge CFStringRef)SRURLOrigin(url));\n\n    if (requestedProtocols.count) {\n        CFHTTPMessageSetHeaderFieldValue(message, CFSTR(\"Sec-WebSocket-Protocol\"),\n                                         (__bridge CFStringRef)[requestedProtocols componentsJoinedByString:@\", \"]);\n    }\n\n    [request.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {\n        CFHTTPMessageSetHeaderFieldValue(message, (__bridge CFStringRef)key, (__bridge CFStringRef)obj);\n    }];\n\n    return message;\n}\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRHash.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nextern NSData *SRSHA1HashFromString(NSString *string);\nextern NSData *SRSHA1HashFromBytes(const char *bytes, size_t length);\n\nextern NSString *SRBase64EncodedStringFromData(NSData *data);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRHash.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRHash.h\"\n\n#import <CommonCrypto/CommonDigest.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nNSData *SRSHA1HashFromString(NSString *string)\n{\n    const char *utf8String = string.UTF8String;\n    if (!utf8String) {\n        return [NSData data];\n    }\n    size_t length = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];\n    return SRSHA1HashFromBytes(utf8String, length);\n}\n\nNSData *SRSHA1HashFromBytes(const char *bytes, size_t length)\n{\n    uint8_t outputLength = CC_SHA1_DIGEST_LENGTH;\n    unsigned char output[outputLength];\n    CC_SHA1(bytes, (CC_LONG)length, output);\n\n    return [NSData dataWithBytes:output length:outputLength];\n}\n\nNSString *SRBase64EncodedStringFromData(NSData *data)\n{\n    if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {\n        return [data base64EncodedStringWithOptions:0];\n    }\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n    return [data base64Encoding];\n#pragma clang diagnostic pop\n}\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRLog.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n// Uncomment this line to enable debug logging\n//#define SR_DEBUG_LOG_ENABLED\n\nextern void SRErrorLog(NSString *format, ...);\nextern void SRDebugLog(NSString *format, ...);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRLog.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRLog.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\nextern void SRErrorLog(NSString *format, ...)\n{\n    __block va_list arg_list;\n    va_start (arg_list, format);\n\n    NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list];\n\n    va_end(arg_list);\n\n    NSLog(@\"[SocketRocket] %@\", formattedString);\n}\n\nextern void SRDebugLog(NSString *format, ...)\n{\n#ifdef SR_DEBUG_LOG_ENABLED\n    SRErrorLog(tag, format);\n#endif\n}\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRMutex.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef __attribute__((capability(\"mutex\"))) pthread_mutex_t *SRMutex;\n\nextern SRMutex SRMutexInitRecursive(void);\nextern void SRMutexDestroy(SRMutex mutex);\n\nextern void SRMutexLock(SRMutex mutex) __attribute__((acquire_capability(mutex)));\nextern void SRMutexUnlock(SRMutex mutex) __attribute__((release_capability(mutex)));\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRMutex.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRMutex.h\"\n\n#import <pthread/pthread.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nSRMutex SRMutexInitRecursive(void)\n{\n    pthread_mutex_t *mutex = malloc(sizeof(pthread_mutex_t));\n    pthread_mutexattr_t attributes;\n\n    pthread_mutexattr_init(&attributes);\n    pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE);\n    pthread_mutex_init(mutex, &attributes);\n    pthread_mutexattr_destroy(&attributes);\n\n    return mutex;\n}\n\nvoid SRMutexDestroy(SRMutex mutex)\n{\n    pthread_mutex_destroy(mutex);\n    free(mutex);\n}\n\n__attribute__((no_thread_safety_analysis))\nvoid SRMutexLock(SRMutex mutex)\n{\n    pthread_mutex_lock(mutex);\n}\n\n__attribute__((no_thread_safety_analysis))\nvoid SRMutexUnlock(SRMutex mutex)\n{\n    pthread_mutex_unlock(mutex);\n}\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRRandom.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nextern NSData *SRRandomData(NSUInteger length);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRRandom.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRRandom.h\"\n\n#import <Security/SecRandom.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nNSData *SRRandomData(NSUInteger length)\n{\n    NSMutableData *_Nullable data = [NSMutableData dataWithLength:length];\n    if (data == nil) {\n        [NSException raise:NSInternalInconsistencyException format:@\"Failed to allocate random data\"];\n    }\n    int result = SecRandomCopyBytes(kSecRandomDefault, data.length, ((NSMutableData *_Nonnull)data).mutableBytes);\n    if (result != errSecSuccess) {\n        [NSException raise:NSInternalInconsistencyException format:@\"Failed to generate random bytes with OSStatus: %d\", result];\n    }\n    return (NSMutableData *_Nonnull)data;\n}\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRSIMDHelpers.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\n/**\n Unmask bytes using XOR via SIMD.\n\n @param bytes    The bytes to unmask.\n @param length   The number of bytes to unmask.\n @param maskKey The mask to XOR with MUST be of length sizeof(uint32_t).\n */\nvoid SRMaskBytesSIMD(uint8_t *bytes, size_t length, uint8_t *maskKey);\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRSIMDHelpers.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRSIMDHelpers.h\"\n\ntypedef uint8_t uint8x32_t __attribute__((vector_size(32)));\n\nstatic void SRMaskBytesManual(uint8_t *bytes, size_t length, uint8_t *maskKey) {\n    for (size_t i = 0; i < length; i++) {\n        bytes[i] = bytes[i] ^ maskKey[i % sizeof(uint32_t)];\n    }\n}\n\n/**\n Right-shift the elements of a vector, circularly.\n\n @param vector The vector to circular shift.\n @param by     The number of elements to shift by.\n\n @return A shifted vector.\n */\nstatic uint8x32_t SRShiftVector(uint8x32_t vector, size_t by) {\n    uint8x32_t vectorCopy = vector;\n    by = by % _Alignof(uint8x32_t);\n\n    uint8_t *vectorPointer = (uint8_t *)&vector;\n    uint8_t *vectorCopyPointer = (uint8_t *)&vectorCopy;\n\n    memmove(vectorPointer + by, vectorPointer, sizeof(vector) - by);\n    memcpy(vectorPointer, vectorCopyPointer + (sizeof(vector) - by), by);\n\n    return vector;\n}\n\nvoid SRMaskBytesSIMD(uint8_t *bytes, size_t length, uint8_t *maskKey) {\n    size_t alignmentBytes = _Alignof(uint8x32_t) - ((uintptr_t)bytes % _Alignof(uint8x32_t));\n    if (alignmentBytes == _Alignof(uint8x32_t)) {\n        alignmentBytes = 0;\n    }\n\n    // If the number of bytes that can be processed after aligning is\n    // less than the number of bytes we can put into a vector,\n    // then there's no work to do with SIMD, just call the manual version.\n    if (alignmentBytes > length || (length - alignmentBytes) < sizeof(uint8x32_t)) {\n        SRMaskBytesManual(bytes, length, maskKey);\n        return;\n    }\n\n    size_t vectorLength = (length - alignmentBytes) / sizeof(uint8x32_t);\n    size_t manualStartOffset = alignmentBytes + (vectorLength * sizeof(uint8x32_t));\n    size_t manualLength = length - manualStartOffset;\n\n    uint8x32_t *vector = (uint8x32_t *)(bytes + alignmentBytes);\n    uint8x32_t maskVector;\n\n    memset_pattern4(&maskVector, maskKey, sizeof(uint8x32_t));\n    maskVector = SRShiftVector(maskVector, alignmentBytes);\n\n    SRMaskBytesManual(bytes, alignmentBytes, maskKey);\n\n    for (size_t vectorIndex = 0; vectorIndex < vectorLength; vectorIndex++) {\n        vector[vectorIndex] = vector[vectorIndex] ^ maskVector;\n    }\n\n    // Use the shifted mask for the final manual part.\n    SRMaskBytesManual(bytes + manualStartOffset, manualLength, (uint8_t *) &maskVector);\n}\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRURLUtilities.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n// The origin isn't really applicable for a native application.\n// So instead, just map ws -> http and wss -> https.\nextern NSString *SRURLOrigin(NSURL *url);\n\nextern BOOL SRURLRequiresSSL(NSURL *_Nullable url);\n\n// Extracts `user` and `password` from url (if available) into `Basic base64(user:password)`.\nextern NSString *_Nullable SRBasicAuthorizationHeaderFromURL(NSURL *url);\n\n// Returns a valid value for `NSStreamNetworkServiceType` or `nil`.\nextern NSString *_Nullable SRStreamNetworkServiceTypeFromURLRequest(NSURLRequest *request);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Internal/Utilities/SRURLUtilities.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRURLUtilities.h\"\n\n#import \"SRHash.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\nNSString *SRURLOrigin(NSURL *url)\n{\n    NSMutableString *origin = [NSMutableString string];\n\n    NSString *scheme = url.scheme.lowercaseString;\n    if ([scheme isEqualToString:@\"wss\"]) {\n        scheme = @\"https\";\n    } else if ([scheme isEqualToString:@\"ws\"]) {\n        scheme = @\"http\";\n    }\n    [origin appendFormat:@\"%@://%@\", scheme, url.host];\n\n    NSNumber *port = url.port;\n    BOOL portIsDefault = (!port ||\n                          ([scheme isEqualToString:@\"http\"] && port.integerValue == 80) ||\n                          ([scheme isEqualToString:@\"https\"] && port.integerValue == 443));\n    if (!portIsDefault) {\n        [origin appendFormat:@\":%@\", port.stringValue];\n    }\n    return origin;\n}\n\nextern BOOL SRURLRequiresSSL(NSURL *_Nullable url)\n{\n    NSString *scheme = url.scheme.lowercaseString;\n    return ([scheme isEqualToString:@\"wss\"] || [scheme isEqualToString:@\"https\"]);\n}\n\nextern NSString *_Nullable SRBasicAuthorizationHeaderFromURL(NSURL *url)\n{\n    if (!url.user || !url.password) {\n        return nil;\n    }\n\n    NSData *data = [[NSString stringWithFormat:@\"%@:%@\", url.user, url.password] dataUsingEncoding:NSUTF8StringEncoding];\n    return [NSString stringWithFormat:@\"Basic %@\", SRBase64EncodedStringFromData(data)];\n}\n\nextern NSString *_Nullable SRStreamNetworkServiceTypeFromURLRequest(NSURLRequest *request)\n{\n    NSString *networkServiceType = nil;\n    switch (request.networkServiceType) {\n        case NSURLNetworkServiceTypeDefault:\n        case NSURLNetworkServiceTypeResponsiveData:\n        case NSURLNetworkServiceTypeAVStreaming:\n        case NSURLNetworkServiceTypeResponsiveAV:\n            break;\n        case NSURLNetworkServiceTypeVoIP:\n            networkServiceType = NSStreamNetworkServiceTypeVoIP;\n            break;\n        case NSURLNetworkServiceTypeVideo:\n            networkServiceType = NSStreamNetworkServiceTypeVideo;\n            break;\n        case NSURLNetworkServiceTypeBackground:\n            networkServiceType = NSStreamNetworkServiceTypeBackground;\n            break;\n        case NSURLNetworkServiceTypeVoice:\n            networkServiceType = NSStreamNetworkServiceTypeVoice;\n            break;\n#if (__MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 || __TV_OS_VERSION_MAX_ALLOWED >= 100000 || __WATCH_OS_VERSION_MAX_ALLOWED >= 30000)\n        case NSURLNetworkServiceTypeCallSignaling: {\n            if (@available(iOS 10.0, tvOS 10.0, macOS 10.12, *)) {\n                networkServiceType = NSStreamNetworkServiceTypeCallSignaling;\n            }\n            break;\n        }\n#endif\n    }\n    return networkServiceType;\n}\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/NSRunLoop+SRWebSocket.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface NSRunLoop (SRWebSocket)\n\n/**\n Default run loop that will be used to schedule all instances of `SRWebSocket`.\n\n @return An instance of `NSRunLoop`.\n */\n+ (NSRunLoop *)SR_networkRunLoop;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/NSRunLoop+SRWebSocket.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"NSRunLoop+SRWebSocket.h\"\n#import \"NSRunLoop+SRWebSocketPrivate.h\"\n\n#import \"SRRunLoopThread.h\"\n\n// Required for object file to always be linked.\nvoid import_NSRunLoop_SRWebSocket(void) { }\n\n@implementation NSRunLoop (SRWebSocket)\n\n+ (NSRunLoop *)SR_networkRunLoop\n{\n    return [SRRunLoopThread sharedThread].runLoop;\n}\n\n@end\n"
  },
  {
    "path": "SocketRocket/NSURLRequest+SRWebSocket.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface NSURLRequest (SRWebSocket)\n\n/**\n An array of pinned `SecCertificateRef` SSL certificates that `SRWebSocket` will use for validation.\n */\n@property (nullable, nonatomic, copy, readonly) NSArray *SR_SSLPinnedCertificates\n    DEPRECATED_MSG_ATTRIBUTE(\"Using pinned certificates is neither secure nor supported in SocketRocket, \"\n                             \"and leads to security issues. Please use a proper, trust chain validated certificate.\");\n\n@end\n\n@interface NSMutableURLRequest (SRWebSocket)\n\n/**\n An array of pinned `SecCertificateRef` SSL certificates that `SRWebSocket` will use for validation.\n */\n@property (nullable, nonatomic, copy) NSArray *SR_SSLPinnedCertificates\n    DEPRECATED_MSG_ATTRIBUTE(\"Using pinned certificates is neither secure nor supported in SocketRocket, \"\n                             \"and leads to security issues. Please use a proper, trust chain validated certificate.\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/NSURLRequest+SRWebSocket.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"NSURLRequest+SRWebSocket.h\"\n#import \"NSURLRequest+SRWebSocketPrivate.h\"\n\n// Required for object file to always be linked.\nvoid import_NSURLRequest_SRWebSocket(void) { }\n\nNS_ASSUME_NONNULL_BEGIN\n\n@implementation NSURLRequest (SRWebSocket)\n\n- (nullable NSArray *)SR_SSLPinnedCertificates\n{\n    return nil;\n}\n\n@end\n\n@implementation NSMutableURLRequest (SRWebSocket)\n\n- (void)setSR_SSLPinnedCertificates:(nullable NSArray *)SR_SSLPinnedCertificates\n{\n    [NSException raise:NSInvalidArgumentException\n                format:@\"Using pinned certificates is neither secure nor supported in SocketRocket, \"\n                        \"and leads to security issues. Please use a proper, trust chain validated certificate.\"];\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/Resources/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(CURRENT_PROJECT_VERSION)</string>\n\t<key>NSPrincipalClass</key>\n\t<string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "SocketRocket/SRSecurityPolicy.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n#import <Security/Security.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface SRSecurityPolicy : NSObject\n\n/**\n A default `SRSecurityPolicy` implementation specifies socket security and\n validates the certificate chain.\n\n Use a subclass of `SRSecurityPolicy` for more fine grained customization.\n */\n+ (instancetype)defaultPolicy;\n\n/**\n Specifies socket security and provider certificate pinning, disregarding certificate\n chain validation.\n\n @param pinnedCertificates Array of `SecCertificateRef` SSL certificates to use for validation.\n */\n+ (instancetype)pinnningPolicyWithCertificates:(NSArray *)pinnedCertificates\n    DEPRECATED_MSG_ATTRIBUTE(\"Using pinned certificates is neither secure nor supported in SocketRocket, \"\n                             \"and leads to security issues. Please use a proper, trust chain validated certificate.\");\n\n/**\n Specifies socket security and optional certificate chain validation.\n\n @param enabled Whether or not to validate the SSL certificate chain. If you\n are considering using this method because your certificate was not issued by a\n recognized certificate authority, consider using `pinningPolicyWithCertificates` instead.\n */\n- (instancetype)initWithCertificateChainValidationEnabled:(BOOL)enabled\n    DEPRECATED_MSG_ATTRIBUTE(\"Disabling certificate chain validation is unsafe. \"\n                             \"Please use a proper Certificate Authority to issue your TLS certificates.\")\n    NS_DESIGNATED_INITIALIZER;\n\n/**\n Updates all the security options for input and output streams, for example you\n can set your socket security level here.\n\n @param stream Stream to update the options in.\n */\n- (void)updateSecurityOptionsInStream:(NSStream *)stream;\n\n/**\n Whether or not the specified server trust should be accepted, based on the security policy.\n\n This method should be used when responding to an authentication challenge from\n a server. In the default implemenation, no further validation is done here, but\n you're free to override it in a subclass. See `SRPinningSecurityPolicy.h` for\n an example.\n\n @param serverTrust The X.509 certificate trust of the server.\n @param domain The domain of serverTrust.\n\n @return Whether or not to trust the server.\n */\n- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/SRSecurityPolicy.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRSecurityPolicy.h\"\n#import \"SRPinningSecurityPolicy.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface SRSecurityPolicy ()\n\n@property (nonatomic, assign, readonly) BOOL certificateChainValidationEnabled;\n\n@end\n\n@implementation SRSecurityPolicy\n\n+ (instancetype)defaultPolicy\n{\n    return [self new];\n}\n\n+ (instancetype)pinnningPolicyWithCertificates:(NSArray *)pinnedCertificates\n{\n    [NSException raise:NSInvalidArgumentException\n                format:@\"Using pinned certificates is neither secure nor supported in SocketRocket, \"\n                        \"and leads to security issues. Please use a proper, trust chain validated certificate.\"];\n\n    return nil;\n}\n\n- (instancetype)initWithCertificateChainValidationEnabled:(BOOL)enabled\n{\n    self = [super init];\n    if (!self) { return self; }\n\n    _certificateChainValidationEnabled = enabled;\n\n    return self;\n}\n\n- (instancetype)init\n{\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated\"\n\n    return [self initWithCertificateChainValidationEnabled:YES];\n\n#pragma clang diagnostic pop\n}\n\n- (void)updateSecurityOptionsInStream:(NSStream *)stream\n{\n    // Enforce TLS 1.2\n    [stream setProperty:(__bridge id)CFSTR(\"kCFStreamSocketSecurityLevelTLSv1_2\") forKey:(__bridge id)kCFStreamPropertySocketSecurityLevel];\n\n    // Validate certificate chain for this stream if enabled.\n    NSDictionary<NSString *, id> *sslOptions = @{ (__bridge NSString *)kCFStreamSSLValidatesCertificateChain : @(self.certificateChainValidationEnabled) };\n    [stream setProperty:sslOptions forKey:(__bridge NSString *)kCFStreamPropertySSLSettings];\n}\n\n- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain\n{\n    // No further evaluation happens in the default policy.\n    return YES;\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/SRWebSocket.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef NS_ENUM(NSInteger, SRReadyState) {\n    SR_CONNECTING   = 0,\n    SR_OPEN         = 1,\n    SR_CLOSING      = 2,\n    SR_CLOSED       = 3,\n};\n\ntypedef NS_ENUM(NSInteger, SRStatusCode) {\n    // 0-999: Reserved and not used.\n    SRStatusCodeNormal = 1000,\n    SRStatusCodeGoingAway = 1001,\n    SRStatusCodeProtocolError = 1002,\n    SRStatusCodeUnhandledType = 1003,\n    // 1004 reserved.\n    SRStatusCodeNoStatusReceived = 1005,\n    SRStatusNoStatusReceived __deprecated_enum_msg(\"Use SRStatusCodeNoStatusReceived\") = SRStatusCodeNoStatusReceived,\n    SRStatusCodeAbnormal = 1006,\n    SRStatusCodeInvalidUTF8 = 1007,\n    SRStatusCodePolicyViolated = 1008,\n    SRStatusCodeMessageTooBig = 1009,\n    SRStatusCodeMissingExtension = 1010,\n    SRStatusCodeInternalError = 1011,\n    SRStatusCodeServiceRestart = 1012,\n    SRStatusCodeTryAgainLater = 1013,\n    // 1014: Reserved for future use by the WebSocket standard.\n    SRStatusCodeTLSHandshake = 1015,\n    // 1016-1999: Reserved for future use by the WebSocket standard.\n    // 2000-2999: Reserved for use by WebSocket extensions.\n    // 3000-3999: Available for use by libraries and frameworks. May not be used by applications. Available for registration at the IANA via first-come, first-serve.\n    // 4000-4999: Available for use by applications.\n};\n\n@class SRWebSocket;\n@class SRSecurityPolicy;\n\n/**\n Error domain used for errors reported by SRWebSocket.\n */\nextern NSString *const SRWebSocketErrorDomain;\n\n/**\n Key used for HTTP status code if bad response was received from the server.\n */\nextern NSString *const SRHTTPResponseErrorKey;\n\n@protocol SRWebSocketDelegate;\n\n///--------------------------------------\n#pragma mark - SRWebSocket\n///--------------------------------------\n\n/**\n A `SRWebSocket` object lets you connect, send and receive data to a remote Web Socket.\n */\n@interface SRWebSocket : NSObject <NSStreamDelegate>\n\n/**\n The delegate of the web socket.\n\n The web socket delegate is notified on all state changes that happen to the web socket.\n */\n@property (nonatomic, weak) id <SRWebSocketDelegate> delegate;\n\n/**\n A dispatch queue for scheduling the delegate calls. The queue doesn't need be a serial queue.\n\n If `nil` and `delegateOperationQueue` is `nil`, the socket uses main queue for performing all delegate method calls.\n */\n@property (nullable, nonatomic, strong) dispatch_queue_t delegateDispatchQueue;\n\n/**\n An operation queue for scheduling the delegate calls.\n\n If `nil` and `delegateOperationQueue` is `nil`, the socket uses main queue for performing all delegate method calls.\n */\n@property (nullable, nonatomic, strong) NSOperationQueue *delegateOperationQueue;\n\n/**\n Current ready state of the socket. Default: `SR_CONNECTING`.\n\n This property is Key-Value Observable and fully thread-safe.\n */\n@property (atomic, assign, readonly) SRReadyState readyState;\n\n/**\n An instance of `NSURL` that this socket connects to.\n */\n@property (nullable, nonatomic, strong, readonly) NSURL *url;\n\n/**\n All HTTP headers that were received by socket or `nil` if none were received so far.\n */\n@property (nullable, nonatomic, assign, readonly) CFHTTPMessageRef receivedHTTPHeaders;\n\n/**\n Array of `NSHTTPCookie` cookies to apply to the connection.\n */\n@property (nullable, nonatomic, copy) NSArray<NSHTTPCookie *> *requestCookies;\n\n/**\n The negotiated web socket protocol or `nil` if handshake did not yet complete.\n */\n@property (nullable, nonatomic, copy, readonly) NSString *protocol;\n\n/**\n A boolean value indicating whether this socket will allow connection without SSL trust chain evaluation.\n For DEBUG builds this flag is ignored, and SSL connections are allowed regardless of the certificate trust configuration\n */\n@property (nonatomic, assign, readonly) BOOL allowsUntrustedSSLCertificates;\n\n///--------------------------------------\n#pragma mark - Constructors\n///--------------------------------------\n\n/**\n Initializes a web socket with a given `NSURLRequest`.\n\n @param request Request to initialize with.\n */\n- (instancetype)initWithURLRequest:(NSURLRequest *)request;\n\n/**\n Initializes a web socket with a given `NSURLRequest`, specifying a transport security policy (e.g. SSL configuration).\n\n @param request        Request to initialize with.\n @param securityPolicy Policy object describing transport security behavior.\n */\n- (instancetype)initWithURLRequest:(NSURLRequest *)request securityPolicy:(SRSecurityPolicy *)securityPolicy;\n\n/**\n Initializes a web socket with a given `NSURLRequest` and list of sub-protocols.\n\n @param request   Request to initialize with.\n @param protocols An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.\n */\n- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(nullable NSArray<NSString *> *)protocols;\n\n/**\n Initializes a web socket with a given `NSURLRequest`, list of sub-protocols and whether untrusted SSL certificates are allowed.\n\n @param request                        Request to initialize with.\n @param protocols                      An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.\n @param allowsUntrustedSSLCertificates Boolean value indicating whether untrusted SSL certificates are allowed. Default: `false`.\n */\n- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(nullable NSArray<NSString *> *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates\n    DEPRECATED_MSG_ATTRIBUTE(\"Disabling certificate chain validation is unsafe. \"\n                             \"Please use a proper Certificate Authority to issue your TLS certificates.\");\n\n/**\n Initializes a web socket with a given `NSURLRequest`, list of sub-protocols and whether untrusted SSL certificates are allowed.\n\n @param request        Request to initialize with.\n @param protocols      An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.\n @param securityPolicy Policy object describing transport security behavior.\n */\n- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(nullable NSArray<NSString *> *)protocols securityPolicy:(SRSecurityPolicy *)securityPolicy NS_DESIGNATED_INITIALIZER;\n\n/**\n Initializes a web socket with a given `NSURL`.\n\n @param url URL to initialize with.\n */\n- (instancetype)initWithURL:(NSURL *)url;\n\n/**\n Initializes a web socket with a given `NSURL` and list of sub-protocols.\n\n @param url       URL to initialize with.\n @param protocols An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.\n */\n- (instancetype)initWithURL:(NSURL *)url protocols:(nullable NSArray<NSString *> *)protocols;\n\n/**\n Initializes a web socket with a given `NSURL`, specifying a transport security policy (e.g. SSL configuration).\n\n @param url            URL to initialize with.\n @param securityPolicy Policy object describing transport security behavior.\n */\n- (instancetype)initWithURL:(NSURL *)url securityPolicy:(SRSecurityPolicy *)securityPolicy;\n\n/**\n Initializes a web socket with a given `NSURL`, list of sub-protocols and whether untrusted SSL certificates are allowed.\n\n @param url                            URL to initialize with.\n @param protocols                      An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.\n @param allowsUntrustedSSLCertificates Boolean value indicating whether untrusted SSL certificates are allowed. Default: `false`.\n */\n- (instancetype)initWithURL:(NSURL *)url protocols:(nullable NSArray<NSString *> *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates\n    DEPRECATED_MSG_ATTRIBUTE(\"Disabling certificate chain validation is unsafe. \"\n                             \"Please use a proper Certificate Authority to issue your TLS certificates.\");\n\n/**\n Unavailable initializer. Please use any other initializer.\n */\n- (instancetype)init NS_UNAVAILABLE;\n\n/**\n Unavailable constructor. Please use any other initializer.\n */\n+ (instancetype)new NS_UNAVAILABLE;\n\n///--------------------------------------\n#pragma mark - Schedule\n///--------------------------------------\n\n/**\n Schedules a received on a given run loop in a given mode.\n By default, a web socket will schedule itself on `+[NSRunLoop SR_networkRunLoop]` using `NSDefaultRunLoopMode`.\n\n @param runLoop The run loop on which to schedule the receiver.\n @param mode     The mode for the run loop.\n */\n- (void)scheduleInRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode NS_SWIFT_NAME(schedule(in:forMode:));\n\n/**\n Removes the receiver from a given run loop running in a given mode.\n\n @param runLoop The run loop on which the receiver was scheduled.\n @param mode    The mode for the run loop.\n */\n- (void)unscheduleFromRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode NS_SWIFT_NAME(unschedule(from:forMode:));\n\n///--------------------------------------\n#pragma mark - Open / Close\n///--------------------------------------\n\n/**\n Opens web socket, which will trigger connection, authentication and start receiving/sending events.\n An instance of `SRWebSocket` is intended for one-time-use only. This method should be called once and only once.\n */\n- (void)open;\n\n/**\n Closes a web socket using `SRStatusCodeNormal` code and no reason.\n */\n- (void)close;\n\n/**\n Closes a web socket using a given code and reason.\n\n @param code   Code to close the socket with.\n @param reason Reason to send to the server or `nil`.\n */\n- (void)closeWithCode:(NSInteger)code reason:(nullable NSString *)reason;\n\n///--------------------------------------\n#pragma mark Send\n///--------------------------------------\n\n/**\n Send a UTF-8 string or binary data to the server.\n\n @param message UTF-8 String or Data to send.\n\n @deprecated Please use `sendString:` or `sendData` instead.\n */\n- (void)send:(nullable id)message __attribute__((deprecated(\"Please use `sendString:error:` or `sendData:error:` instead.\")));\n\n/**\n Send a UTF-8 String to the server.\n\n @param string String to send.\n @param error  On input, a pointer to variable for an `NSError` object.\n If an error occurs, this pointer is set to an `NSError` object containing information about the error.\n You may specify `nil` to ignore the error information.\n\n @return `YES` if the string was scheduled to send, otherwise - `NO`.\n */\n- (BOOL)sendString:(NSString *)string error:(NSError **)error NS_SWIFT_NAME(send(string:));\n\n/**\n Send binary data to the server.\n\n @param data  Data to send.\n @param error On input, a pointer to variable for an `NSError` object.\n If an error occurs, this pointer is set to an `NSError` object containing information about the error.\n You may specify `nil` to ignore the error information.\n\n @return `YES` if the string was scheduled to send, otherwise - `NO`.\n */\n- (BOOL)sendData:(nullable NSData *)data error:(NSError **)error NS_SWIFT_NAME(send(data:));\n\n/**\n Send binary data to the server, without making a defensive copy of it first.\n\n @param data  Data to send.\n @param error On input, a pointer to variable for an `NSError` object.\n If an error occurs, this pointer is set to an `NSError` object containing information about the error.\n You may specify `nil` to ignore the error information.\n\n @return `YES` if the string was scheduled to send, otherwise - `NO`.\n */\n- (BOOL)sendDataNoCopy:(nullable NSData *)data error:(NSError **)error NS_SWIFT_NAME(send(dataNoCopy:));\n\n/**\n Send Ping message to the server with optional data.\n\n @param data  Instance of `NSData` or `nil`.\n @param error On input, a pointer to variable for an `NSError` object.\n If an error occurs, this pointer is set to an `NSError` object containing information about the error.\n You may specify `nil` to ignore the error information.\n\n @return `YES` if the string was scheduled to send, otherwise - `NO`.\n */\n- (BOOL)sendPing:(nullable NSData *)data error:(NSError **)error NS_SWIFT_NAME(sendPing(_:));\n\n@end\n\n///--------------------------------------\n#pragma mark - SRWebSocketDelegate\n///--------------------------------------\n\n/**\n The `SRWebSocketDelegate` protocol describes the methods that `SRWebSocket` objects\n call on their delegates to handle status and messsage events.\n */\n@protocol SRWebSocketDelegate <NSObject>\n\n@optional\n\n#pragma mark Receive Messages\n\n/**\n Called when any message was received from a web socket.\n This method is suboptimal and might be deprecated in a future release.\n\n @param webSocket An instance of `SRWebSocket` that received a message.\n @param message   Received message. Either a `String` or `NSData`.\n */\n- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;\n\n/**\n Called when a frame was received from a web socket.\n\n @param webSocket An instance of `SRWebSocket` that received a message.\n @param string    Received text in a form of UTF-8 `String`.\n */\n- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(NSString *)string;\n\n/**\n Called when a frame was received from a web socket.\n\n @param webSocket An instance of `SRWebSocket` that received a message.\n @param data      Received data in a form of `NSData`.\n */\n- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithData:(NSData *)data;\n\n#pragma mark Status & Connection\n\n/**\n Called when a given web socket was open and authenticated.\n\n @param webSocket An instance of `SRWebSocket` that was open.\n */\n- (void)webSocketDidOpen:(SRWebSocket *)webSocket;\n\n/**\n Called when a given web socket encountered an error.\n\n @param webSocket An instance of `SRWebSocket` that failed with an error.\n @param error     An instance of `NSError`.\n */\n- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;\n\n/**\n Called when a given web socket was closed.\n\n @param webSocket An instance of `SRWebSocket` that was closed.\n @param code      Code reported by the server.\n @param reason    Reason in a form of a String that was reported by the server or `nil`.\n @param wasClean  Boolean value indicating whether a socket was closed in a clean state.\n */\n- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(nullable NSString *)reason wasClean:(BOOL)wasClean;\n\n/**\n Called on receive of a ping message from the server.\n\n @param webSocket An instance of `SRWebSocket` that received a ping frame.\n @param data      Payload that was received or `nil` if there was no payload.\n */\n- (void)webSocket:(SRWebSocket *)webSocket didReceivePingWithData:(nullable NSData *)data;\n\n/**\n Called when a pong data was received in response to ping.\n\n @param webSocket An instance of `SRWebSocket` that received a pong frame.\n @param pongData  Payload that was received or `nil` if there was no payload.\n */\n- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(nullable NSData *)pongData;\n\n/**\n Sent before reporting a text frame to be able to configure if it shuold be convert to a UTF-8 String or passed as `NSData`.\n If the method is not implemented - it will always convert text frames to String.\n\n @param webSocket An instance of `SRWebSocket` that received a text frame.\n\n @return `YES` if text frame should be converted to UTF-8 String, otherwise - `NO`. Default: `YES`.\n */\n- (BOOL)webSocketShouldConvertTextFrameToString:(SRWebSocket *)webSocket NS_SWIFT_NAME(webSocketShouldConvertTextFrameToString(_:));\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "SocketRocket/SRWebSocket.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRWebSocket.h\"\n\n#if __has_include(<unicode/utf8.h>)\n#define HAS_ICU\n#endif\n\n#ifdef HAS_ICU\n#import <unicode/utf8.h>\n#endif\n\n#import <os/lock.h>\n\n#import \"SRDelegateController.h\"\n#import \"SRIOConsumer.h\"\n#import \"SRIOConsumerPool.h\"\n#import \"SRHash.h\"\n#import \"SRURLUtilities.h\"\n#import \"SRError.h\"\n#import \"NSURLRequest+SRWebSocket.h\"\n#import \"NSRunLoop+SRWebSocket.h\"\n#import \"SRProxyConnect.h\"\n#import \"SRSecurityPolicy.h\"\n#import \"SRHTTPConnectMessage.h\"\n#import \"SRRandom.h\"\n#import \"SRLog.h\"\n#import \"SRMutex.h\"\n#import \"SRSIMDHelpers.h\"\n#import \"NSURLRequest+SRWebSocketPrivate.h\"\n#import \"NSRunLoop+SRWebSocketPrivate.h\"\n#import \"SRConstants.h\"\n\n#if !__has_feature(objc_arc)\n#error SocketRocket must be compiled with ARC enabled\n#endif\n\n__attribute__((used)) static void importCategories(void)\n{\n    import_NSURLRequest_SRWebSocket();\n    import_NSRunLoop_SRWebSocket();\n}\n\ntypedef struct {\n    BOOL fin;\n    //  BOOL rsv1;\n    //  BOOL rsv2;\n    //  BOOL rsv3;\n    uint8_t opcode;\n    BOOL masked;\n    uint64_t payload_length;\n} frame_header;\n\nstatic NSString *const SRWebSocketAppendToSecKeyString = @\"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\";\n\nstatic inline int32_t validate_dispatch_data_partial_string(NSData *data);\n\nstatic uint8_t const SRWebSocketProtocolVersion = 13;\n\n// Max frame payload length for all frames is 256MB, which is reasonable max.\nstatic const uint32_t SRWebSocketMaxFramePayloadLength = 256 * 1024 * 1024;\n\nNSString *const SRWebSocketErrorDomain = @\"SRWebSocketErrorDomain\";\nNSString *const SRHTTPResponseErrorKey = @\"HTTPResponseStatusCode\";\n\n@interface SRWebSocket ()  <NSStreamDelegate>\n\n@property (atomic, assign, readwrite) SRReadyState readyState;\n\n// Specifies whether SSL trust chain should NOT be evaluated.\n// By default this flag is set to NO, meaning only secure SSL connections are allowed.\n// For DEBUG builds this flag is ignored, and SSL connections are allowed regardless\n// of the certificate trust configuration\n@property (nonatomic, assign, readwrite) BOOL allowsUntrustedSSLCertificates;\n\n@property (nonatomic, strong, readonly) SRDelegateController *delegateController;\n\n@end\n\n@implementation SRWebSocket {\n    SRMutex _kvoLock;\n    os_unfair_lock _propertyLock;\n\n    dispatch_queue_t _workQueue;\n    NSMutableArray<SRIOConsumer *> *_consumers;\n\n    NSInputStream *_inputStream;\n    NSOutputStream *_outputStream;\n\n    dispatch_data_t _readBuffer;\n    NSUInteger _readBufferOffset;\n\n    dispatch_data_t _outputBuffer;\n    NSUInteger _outputBufferOffset;\n\n    uint8_t _currentFrameOpcode;\n    size_t _currentFrameCount;\n    size_t _readOpCount;\n    uint32_t _currentStringScanPosition;\n    NSMutableData *_currentFrameData;\n\n    NSString *_closeReason;\n\n    NSString *_secKey;\n\n    SRSecurityPolicy *_securityPolicy;\n    BOOL _requestRequiresSSL;\n    BOOL _streamSecurityValidated;\n\n    uint8_t _currentReadMaskKey[4];\n    size_t _currentReadMaskOffset;\n\n    BOOL _closeWhenFinishedWriting;\n    BOOL _failed;\n\n    NSURLRequest *_urlRequest;\n\n    BOOL _sentClose;\n    BOOL _didFail;\n    BOOL _cleanupScheduled;\n    int _closeCode;\n\n    BOOL _isPumping;\n\n    NSMutableSet<NSArray *> *_scheduledRunloops; // Set<[RunLoop, Mode]>. TODO: (nlutsenko) Fix clowntown\n\n    // We use this to retain ourselves.\n    __strong SRWebSocket *_selfRetain;\n\n    NSArray<NSString *> *_requestedProtocols;\n    SRIOConsumerPool *_consumerPool;\n\n    // proxy support\n    SRProxyConnect *_proxyConnect;\n}\n\n@synthesize readyState = _readyState;\n\n///--------------------------------------\n#pragma mark - Init\n///--------------------------------------\n\n- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols securityPolicy:(SRSecurityPolicy *)securityPolicy\n{\n    self = [super init];\n    if (!self) return self;\n\n    assert(request.URL);\n    _url = request.URL;\n    _urlRequest = request;\n    _requestedProtocols = [protocols copy];\n    _securityPolicy = securityPolicy;\n    _requestRequiresSSL = SRURLRequiresSSL(_url);\n\n    _readyState = SR_CONNECTING;\n\n    _propertyLock = OS_UNFAIR_LOCK_INIT;\n    _kvoLock = SRMutexInitRecursive();\n    _workQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);\n\n    // Going to set a specific on the queue so we can validate we're on the work queue\n    dispatch_queue_set_specific(_workQueue, (__bridge void *)self, (__bridge void *)(_workQueue), NULL);\n\n    _delegateController = [[SRDelegateController alloc] init];\n\n    _readBuffer = dispatch_data_empty;\n    _outputBuffer = dispatch_data_empty;\n\n    _currentFrameData = [[NSMutableData alloc] init];\n\n    _consumers = [[NSMutableArray alloc] init];\n\n    _consumerPool = [[SRIOConsumerPool alloc] init];\n\n    _scheduledRunloops = [[NSMutableSet alloc] init];\n\n    return self;\n}\n\n- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates\n{\n    SRSecurityPolicy *securityPolicy;\n    NSArray *pinnedCertificates = request.SR_SSLPinnedCertificates;\n    if (pinnedCertificates) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated\"\n        securityPolicy = [SRSecurityPolicy pinnningPolicyWithCertificates:pinnedCertificates];\n#pragma clang diagnostic pop\n    } else {\n        BOOL certificateChainValidationEnabled = !allowsUntrustedSSLCertificates;\n    securityPolicy = [[SRSecurityPolicy alloc] initWithCertificateChainValidationEnabled:certificateChainValidationEnabled];\n    }\n\n    return [self initWithURLRequest:request protocols:protocols securityPolicy:securityPolicy];\n}\n\n- (instancetype)initWithURLRequest:(NSURLRequest *)request securityPolicy:(SRSecurityPolicy *)securityPolicy\n{\n    return [self initWithURLRequest:request protocols:nil securityPolicy:securityPolicy];\n}\n\n- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols\n{\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated\"\n    return [self initWithURLRequest:request protocols:protocols allowsUntrustedSSLCertificates:NO];\n#pragma clang diagnostic pop\n}\n\n- (instancetype)initWithURLRequest:(NSURLRequest *)request\n{\n    return [self initWithURLRequest:request protocols:nil];\n}\n\n- (instancetype)initWithURL:(NSURL *)url\n{\n    return [self initWithURL:url protocols:nil];\n}\n\n- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray<NSString *> *)protocols\n{\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated\"\n    return [self initWithURL:url protocols:protocols allowsUntrustedSSLCertificates:NO];\n#pragma clang diagnostic pop\n}\n\n- (instancetype)initWithURL:(NSURL *)url securityPolicy:(SRSecurityPolicy *)securityPolicy\n{\n    NSURLRequest *request = [NSURLRequest requestWithURL:url];\n    return [self initWithURLRequest:request protocols:nil securityPolicy:securityPolicy];\n}\n\n- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray<NSString *> *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates\n{\n    NSURLRequest *request = [NSURLRequest requestWithURL:url];\n    return [self initWithURLRequest:request protocols:protocols allowsUntrustedSSLCertificates:allowsUntrustedSSLCertificates];\n}\n\n- (void)assertOnWorkQueue\n{\n    assert(dispatch_get_specific((__bridge void *)self) == (__bridge void *)_workQueue);\n}\n\n///--------------------------------------\n#pragma mark - Dealloc\n///--------------------------------------\n\n- (void)dealloc\n{\n    _inputStream.delegate = nil;\n    _outputStream.delegate = nil;\n\n    [_inputStream close];\n    [_outputStream close];\n\n    if (_receivedHTTPHeaders) {\n        CFRelease(_receivedHTTPHeaders);\n        _receivedHTTPHeaders = NULL;\n    }\n\n    SRMutexDestroy(_kvoLock);\n}\n\n///--------------------------------------\n#pragma mark - Accessors\n///--------------------------------------\n\n#pragma mark readyState\n\n- (void)setReadyState:(SRReadyState)readyState\n{\n    @try {\n        SRMutexLock(_kvoLock);\n        if (_readyState != readyState) {\n            [self willChangeValueForKey:@\"readyState\"];\n            os_unfair_lock_lock(&_propertyLock);\n            _readyState = readyState;\n            os_unfair_lock_unlock(&_propertyLock);\n            [self didChangeValueForKey:@\"readyState\"];\n        }\n    }\n    @finally {\n        SRMutexUnlock(_kvoLock);\n    }\n}\n\n- (SRReadyState)readyState\n{\n    SRReadyState state = 0;\n    os_unfair_lock_lock(&_propertyLock);\n    state = _readyState;\n    os_unfair_lock_unlock(&_propertyLock);\n    return state;\n}\n\n+ (BOOL)automaticallyNotifiesObserversOfReadyState {\n    return NO;\n}\n\n///--------------------------------------\n#pragma mark - Open / Close\n///--------------------------------------\n\n- (void)open\n{\n    NSURL* const url = _url;\n    if (!url) {\n        NSError *error = SRErrorWithDomainCodeDescription(NSURLErrorDomain, NSURLErrorBadURL, @\"Unable to open socket with emtpy URL.\");\n        [self _failWithError:error];\n        return;\n    }\n    NSAssert(self.readyState == SR_CONNECTING, @\"Cannot call -(void)open on SRWebSocket more than once.\");\n\n    _selfRetain = self;\n\n    if (_urlRequest.timeoutInterval > 0) {\n        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_urlRequest.timeoutInterval * NSEC_PER_SEC));\n        __weak typeof(self) wself = self;\n        dispatch_after(popTime, dispatch_get_main_queue(), ^{\n            __strong SRWebSocket *sself = wself;\n            if (!sself) {\n                return;\n            }\n            if (sself.readyState == SR_CONNECTING) {\n                NSError *error = SRErrorWithDomainCodeDescription(NSURLErrorDomain, NSURLErrorTimedOut, @\"Timed out connecting to server.\");\n                [sself _failWithError:error];\n            }\n        });\n    }\n\n    _proxyConnect = [[SRProxyConnect alloc] initWithURL:url];\n\n    __weak typeof(self) wself = self;\n    [_proxyConnect openNetworkStreamWithCompletion:^(NSError *error, NSInputStream *readStream, NSOutputStream *writeStream) {\n        [wself _connectionDoneWithError:error readStream:readStream writeStream:writeStream];\n    }];\n}\n\n- (void)_connectionDoneWithError:(NSError *)error readStream:(NSInputStream *)readStream writeStream:(NSOutputStream *)writeStream\n{\n    if (error != nil) {\n        [self _failWithError:error];\n    } else {\n        _outputStream = writeStream;\n        _inputStream = readStream;\n\n        _inputStream.delegate = self;\n        _outputStream.delegate = self;\n        [self _updateSecureStreamOptions];\n\n        if (!_scheduledRunloops.count) {\n            [self scheduleInRunLoop:[NSRunLoop SR_networkRunLoop] forMode:NSDefaultRunLoopMode];\n        }\n\n        // If we don't require SSL validation - consider that we connected.\n        // Otherwise `didConnect` is called when SSL validation finishes.\n        if (!_requestRequiresSSL) {\n            dispatch_async(_workQueue, ^{\n                [self didConnect];\n            });\n        }\n    }\n    // Schedule to run on a work queue, to make sure we don't run this inline and deallocate `self` inside `SRProxyConnect`.\n    // TODO: (nlutsenko) Find a better structure for this, maybe Bolts Tasks?\n    dispatch_async(_workQueue, ^{\n        self->_proxyConnect = nil;\n    });\n}\n\n- (BOOL)_checkHandshake:(CFHTTPMessageRef)httpMessage\n{\n    NSString *acceptHeader = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(httpMessage, CFSTR(\"Sec-WebSocket-Accept\")));\n\n    if (acceptHeader == nil) {\n        return NO;\n    }\n\n    NSString *concattedString = [_secKey stringByAppendingString:SRWebSocketAppendToSecKeyString];\n    NSData *hashedString = SRSHA1HashFromString(concattedString);\n    NSString *expectedAccept = SRBase64EncodedStringFromData(hashedString);\n    return [acceptHeader isEqualToString:expectedAccept];\n}\n\n- (void)_HTTPHeadersDidFinish:(CFHTTPMessageRef)httpMessage\n{\n    NSInteger responseCode = CFHTTPMessageGetResponseStatusCode(httpMessage);\n    if (responseCode >= 400) {\n        SRDebugLog(@\"Request failed with response code %d\", responseCode);\n        NSError *error = SRHTTPErrorWithCodeDescription(responseCode, 2132,\n                                                        [NSString stringWithFormat:@\"Received bad response code from server: %d.\",\n                                                         (int)responseCode]);\n        [self _failWithError:error];\n        return;\n    }\n\n    if(![self _checkHandshake:httpMessage]) {\n        NSError *error = SRErrorWithCodeDescription(2133, @\"Invalid Sec-WebSocket-Accept response.\");\n        [self _failWithError:error];\n        return;\n    }\n\n    NSString *negotiatedProtocol = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(httpMessage, CFSTR(\"Sec-WebSocket-Protocol\")));\n    if (negotiatedProtocol) {\n        // Make sure we requested the protocol\n        if ([_requestedProtocols indexOfObject:negotiatedProtocol] == NSNotFound) {\n            NSError *error = SRErrorWithCodeDescription(2133, @\"Server specified Sec-WebSocket-Protocol that wasn't requested.\");\n            [self _failWithError:error];\n            return;\n        }\n\n        _protocol = negotiatedProtocol;\n    }\n\n    self.readyState = SR_OPEN;\n\n    if (!_didFail) {\n        [self _readFrameNew];\n    }\n\n    [self.delegateController performDelegateBlock:^(id<SRWebSocketDelegate>  _Nullable delegate, SRDelegateAvailableMethods availableMethods) {\n        if (availableMethods.didOpen) {\n            [delegate webSocketDidOpen:self];\n        }\n    }];\n}\n\n\n- (void)_readHTTPHeader\n{\n    if (_receivedHTTPHeaders == NULL) {\n        _receivedHTTPHeaders = CFHTTPMessageCreateEmpty(NULL, NO);\n    }\n\n    [self _readUntilHeaderCompleteWithCallback:^(SRWebSocket *socket,  NSData *data) {\n        if (!socket) {\n            return;\n        }\n        CFHTTPMessageRef receivedHTTPHeaders = socket->_receivedHTTPHeaders;\n\n        CFHTTPMessageAppendBytes(receivedHTTPHeaders, (const UInt8 *)data.bytes, data.length);\n\n        if (CFHTTPMessageIsHeaderComplete(receivedHTTPHeaders)) {\n            SRDebugLog(@\"Finished reading headers %@\", CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(receivedHTTPHeaders)));\n            [socket _HTTPHeadersDidFinish:receivedHTTPHeaders];\n        } else {\n            [socket _readHTTPHeader];\n        }\n    }];\n}\n\n- (void)didConnect\n{\n    SRDebugLog(@\"Connected\");\n\n    _secKey = SRBase64EncodedStringFromData(SRRandomData(16));\n    assert([_secKey length] == 24);\n\n    CFHTTPMessageRef message = SRHTTPConnectMessageCreate(_urlRequest,\n                                                          _secKey,\n                                                          SRWebSocketProtocolVersion,\n                                                          self.requestCookies,\n                                                          _requestedProtocols);\n\n    NSData *messageData = CFBridgingRelease(CFHTTPMessageCopySerializedMessage(message));\n\n    CFRelease(message);\n\n    [self _writeData:messageData];\n    [self _readHTTPHeader];\n}\n\n- (void)_updateSecureStreamOptions\n{\n    if (_requestRequiresSSL) {\n        SRDebugLog(@\"Setting up security for streams.\");\n        [_securityPolicy updateSecurityOptionsInStream:_inputStream];\n        [_securityPolicy updateSecurityOptionsInStream:_outputStream];\n    }\n\n    NSString *networkServiceType = SRStreamNetworkServiceTypeFromURLRequest(_urlRequest);\n    if (networkServiceType != nil) {\n        [_inputStream setProperty:networkServiceType forKey:NSStreamNetworkServiceType];\n        [_outputStream setProperty:networkServiceType forKey:NSStreamNetworkServiceType];\n    }\n}\n\n- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode\n{\n    [_outputStream scheduleInRunLoop:aRunLoop forMode:mode];\n    [_inputStream scheduleInRunLoop:aRunLoop forMode:mode];\n\n    [_scheduledRunloops addObject:@[aRunLoop, mode]];\n}\n\n- (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode\n{\n    [_outputStream removeFromRunLoop:aRunLoop forMode:mode];\n    [_inputStream removeFromRunLoop:aRunLoop forMode:mode];\n\n    [_scheduledRunloops removeObject:@[aRunLoop, mode]];\n}\n\n- (void)close\n{\n    [self closeWithCode:SRStatusCodeNormal reason:nil];\n}\n\n- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason\n{\n    assert(code);\n    __weak typeof(self) wself = self;\n    dispatch_async(_workQueue, ^{\n        __strong SRWebSocket *sself = wself;\n        if (!sself) {\n          return;\n        }\n        if (sself.readyState == SR_CLOSING || sself.readyState == SR_CLOSED) {\n            return;\n        }\n\n        BOOL wasConnecting = sself.readyState == SR_CONNECTING;\n\n        sself.readyState = SR_CLOSING;\n\n        SRDebugLog(@\"Closing with code %d reason %@\", code, reason);\n\n        if (wasConnecting) {\n            [sself closeConnection];\n            return;\n        }\n\n        size_t maxMsgSize = [reason maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding];\n        NSMutableData *mutablePayload = [[NSMutableData alloc] initWithLength:sizeof(uint16_t) + maxMsgSize];\n        NSData *payload = mutablePayload;\n\n        ((uint16_t *)mutablePayload.mutableBytes)[0] = CFSwapInt16BigToHost((uint16_t)code);\n\n        if (reason) {\n            NSRange remainingRange = {0};\n\n            NSUInteger usedLength = 0;\n\n            BOOL success = [reason getBytes:(char *)mutablePayload.mutableBytes + sizeof(uint16_t) maxLength:payload.length - sizeof(uint16_t) usedLength:&usedLength encoding:NSUTF8StringEncoding options:NSStringEncodingConversionExternalRepresentation range:NSMakeRange(0, reason.length) remainingRange:&remainingRange];\n#pragma unused (success)\n\n            assert(success);\n            assert(remainingRange.length == 0);\n\n            if (usedLength != maxMsgSize) {\n                payload = [payload subdataWithRange:NSMakeRange(0, usedLength + sizeof(uint16_t))];\n            }\n        }\n\n\n        [sself _sendFrameWithOpcode:SROpCodeConnectionClose data:payload];\n    });\n}\n\n- (void)_closeWithProtocolError:(NSString *)message\n{\n    // Need to shunt this on the _callbackQueue first to see if they received any messages\n    [self.delegateController performDelegateQueueBlock:^{\n        [self closeWithCode:SRStatusCodeProtocolError reason:message];\n        dispatch_async(self->_workQueue, ^{\n            [self closeConnection];\n        });\n    }];\n}\n\n- (void)_failWithError:(NSError *)error\n{\n    dispatch_async(_workQueue, ^{\n        if (self.readyState != SR_CLOSED) {\n            self->_failed = YES;\n            [self.delegateController performDelegateBlock:^(id<SRWebSocketDelegate>  _Nullable delegate, SRDelegateAvailableMethods availableMethods) {\n                if (availableMethods.didFailWithError) {\n                    [delegate webSocket:self didFailWithError:error];\n                }\n            }];\n\n            self.readyState = SR_CLOSED;\n\n            SRDebugLog(@\"Failing with error %@\", error.localizedDescription);\n\n            [self closeConnection];\n            [self _scheduleCleanup];\n        }\n    });\n}\n\n- (void)_writeData:(NSData *)data\n{\n    [self assertOnWorkQueue];\n\n    if (_closeWhenFinishedWriting) {\n        return;\n    }\n\n    __block NSData *strongData = data;\n    dispatch_data_t newData = dispatch_data_create(data.bytes, data.length, nil, ^{\n        strongData = nil;\n    });\n    (void)strongData;\n    _outputBuffer = dispatch_data_create_concat(_outputBuffer, newData);\n    [self _pumpWriting];\n}\n\n- (void)send:(nullable id)message\n{\n    if (!message) {\n        [self sendData:nil error:nil]; // Send Data, but it doesn't matter since we are going to send the same text frame with 0 length.\n    } else if ([message isKindOfClass:[NSString class]]) {\n        [self sendString:(NSString *_Nonnull)message error:nil];\n    } else if ([message isKindOfClass:[NSData class]]) {\n        [self sendData:message error:nil];\n    } else {\n        NSAssert(NO, @\"Unrecognized message. Not able to send anything other than a String or NSData.\");\n    }\n}\n\n- (BOOL)sendString:(NSString *)string error:(NSError **)error\n{\n    if (self.readyState != SR_OPEN) {\n        NSString *message = @\"Invalid State: Cannot call `sendString:error:` until connection is open.\";\n        if (error) {\n            *error = SRErrorWithCodeDescription(2134, message);\n        }\n        SRDebugLog(message);\n        return NO;\n    }\n\n    string = [string copy];\n    dispatch_async(_workQueue, ^{\n        [self _sendFrameWithOpcode:SROpCodeTextFrame data:[string dataUsingEncoding:NSUTF8StringEncoding]];\n    });\n    return YES;\n}\n\n- (BOOL)sendData:(nullable NSData *)data error:(NSError **)error\n{\n    data = [data copy];\n    return [self sendDataNoCopy:data error:error];\n}\n\n- (BOOL)sendDataNoCopy:(nullable NSData *)data error:(NSError **)error\n{\n    if (self.readyState != SR_OPEN) {\n        NSString *message = @\"Invalid State: Cannot call `sendDataNoCopy:error:` until connection is open.\";\n        if (error) {\n            *error = SRErrorWithCodeDescription(2134, message);\n        }\n        SRDebugLog(message);\n        return NO;\n    }\n\n    dispatch_async(_workQueue, ^{\n        if (data) {\n            [self _sendFrameWithOpcode:SROpCodeBinaryFrame data:data];\n        } else {\n            [self _sendFrameWithOpcode:SROpCodeTextFrame data:nil];\n        }\n    });\n    return YES;\n}\n\n- (BOOL)sendPing:(nullable NSData *)data error:(NSError **)error\n{\n    if (self.readyState != SR_OPEN) {\n        NSString *message = @\"Invalid State: Cannot call `sendPing:error:` until connection is open.\";\n        if (error) {\n            *error = SRErrorWithCodeDescription(2134, message);\n        }\n        SRDebugLog(message);\n        return NO;\n    }\n\n    data = [data copy] ?: [NSData data]; // It's okay for a ping to be empty\n    dispatch_async(_workQueue, ^{\n        [self _sendFrameWithOpcode:SROpCodePing data:data];\n    });\n    return YES;\n}\n\n- (void)_handlePingWithData:(nullable NSData *)data\n{\n    // Need to pingpong this off _callbackQueue first to make sure messages happen in order\n    [self.delegateController performDelegateBlock:^(id<SRWebSocketDelegate> _Nullable delegate, SRDelegateAvailableMethods availableMethods) {\n        if (availableMethods.didReceivePing) {\n            [delegate webSocket:self didReceivePingWithData:data];\n        }\n        dispatch_async(self->_workQueue, ^{\n            [self _sendFrameWithOpcode:SROpCodePong data:data];\n        });\n    }];\n}\n\n- (void)handlePong:(NSData *)pongData\n{\n    SRDebugLog(@\"Received pong\");\n    [self.delegateController performDelegateBlock:^(id<SRWebSocketDelegate>  _Nullable delegate, SRDelegateAvailableMethods availableMethods) {\n        if (availableMethods.didReceivePong) {\n            [delegate webSocket:self didReceivePong:pongData];\n        }\n    }];\n}\n\n\nstatic inline BOOL closeCodeIsValid(int closeCode) {\n    if (closeCode < 1000) {\n        return NO;\n    }\n\n    if (closeCode >= 1000 && closeCode <= 1011) {\n        if (closeCode == 1004 ||\n            closeCode == 1005 ||\n            closeCode == 1006) {\n            return NO;\n        }\n        return YES;\n    }\n\n    if (closeCode >= 3000 && closeCode <= 3999) {\n        return YES;\n    }\n\n    if (closeCode >= 4000 && closeCode <= 4999) {\n        return YES;\n    }\n\n    return NO;\n}\n\n//  Note from RFC:\n//\n//  If there is a body, the first two\n//  bytes of the body MUST be a 2-byte unsigned integer (in network byte\n//  order) representing a status code with value /code/ defined in\n//  Section 7.4.  Following the 2-byte integer the body MAY contain UTF-8\n//  encoded data with value /reason/, the interpretation of which is not\n//  defined by this specification.\n\n- (void)handleCloseWithData:(NSData *)data\n{\n    size_t dataSize = data.length;\n    __block uint16_t closeCode = 0;\n\n    SRDebugLog(@\"Received close frame\");\n\n    if (dataSize == 1) {\n        // TODO handle error\n        [self _closeWithProtocolError:@\"Payload for close must be larger than 2 bytes\"];\n        return;\n    } else if (dataSize >= 2) {\n        [data getBytes:&closeCode length:sizeof(closeCode)];\n        _closeCode = CFSwapInt16BigToHost(closeCode);\n        if (!closeCodeIsValid(_closeCode)) {\n            [self _closeWithProtocolError:[NSString stringWithFormat:@\"Cannot have close code of %d\", _closeCode]];\n            return;\n        }\n        if (dataSize > 2) {\n            _closeReason = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(2, dataSize - 2)] encoding:NSUTF8StringEncoding];\n            if (!_closeReason) {\n                [self _closeWithProtocolError:@\"Close reason MUST be valid UTF-8\"];\n                return;\n            }\n        }\n    } else {\n        _closeCode = SRStatusCodeNoStatusReceived;\n    }\n\n    [self assertOnWorkQueue];\n\n    if (self.readyState == SR_OPEN) {\n        [self closeWithCode:1000 reason:nil];\n    }\n    dispatch_async(_workQueue, ^{\n        [self closeConnection];\n    });\n}\n\n- (void)closeConnection\n{\n    [self assertOnWorkQueue];\n    SRDebugLog(@\"Trying to disconnect\");\n    _closeWhenFinishedWriting = YES;\n    [self _pumpWriting];\n}\n\n- (void)_handleFrameWithData:(NSData *)frameData opCode:(SROpCode)opcode\n{\n    // Check that the current data is valid UTF8\n\n    BOOL isControlFrame = (opcode == SROpCodePing || opcode == SROpCodePong || opcode == SROpCodeConnectionClose);\n    if (isControlFrame) {\n        //frameData will be copied before passing to handlers\n        //otherwise there can be misbehaviours when value at the pointer is changed\n        frameData = [frameData copy];\n\n        dispatch_async(_workQueue, ^{\n            [self _readFrameContinue];\n        });\n    } else {\n        [self _readFrameNew];\n    }\n\n    switch (opcode) {\n        case SROpCodeTextFrame: {\n            NSString *string = [[NSString alloc] initWithData:frameData encoding:NSUTF8StringEncoding];\n            if (!string && frameData) {\n                [self closeWithCode:SRStatusCodeInvalidUTF8 reason:@\"Text frames must be valid UTF-8.\"];\n                dispatch_async(_workQueue, ^{\n                    [self closeConnection];\n                });\n                return;\n            }\n            SRDebugLog(@\"Received text message.\");\n            [self.delegateController performDelegateBlock:^(id<SRWebSocketDelegate>  _Nullable delegate, SRDelegateAvailableMethods availableMethods) {\n                // Don't convert into string - iff `delegate` tells us not to. Otherwise - create UTF8 string and handle that.\n                if (availableMethods.shouldConvertTextFrameToString && ![delegate webSocketShouldConvertTextFrameToString:self]) {\n                    if (availableMethods.didReceiveMessage) {\n                        [delegate webSocket:self didReceiveMessage:frameData];\n                    }\n                    if (availableMethods.didReceiveMessageWithData) {\n                        [delegate webSocket:self didReceiveMessageWithData:frameData];\n                    }\n                } else {\n                    if (availableMethods.didReceiveMessage) {\n                        [delegate webSocket:self didReceiveMessage:string];\n                    }\n                    if (availableMethods.didReceiveMessageWithString) {\n                        [delegate webSocket:self didReceiveMessageWithString:string];\n                    }\n                }\n            }];\n            break;\n        }\n        case SROpCodeBinaryFrame: {\n            SRDebugLog(@\"Received data message.\");\n            [self.delegateController performDelegateBlock:^(id<SRWebSocketDelegate>  _Nullable delegate, SRDelegateAvailableMethods availableMethods) {\n                if (availableMethods.didReceiveMessage) {\n                    [delegate webSocket:self didReceiveMessage:frameData];\n                }\n                if (availableMethods.didReceiveMessageWithData) {\n                    [delegate webSocket:self didReceiveMessageWithData:frameData];\n                }\n            }];\n        }\n            break;\n        case SROpCodeConnectionClose:\n            [self handleCloseWithData:frameData];\n            break;\n        case SROpCodePing:\n            [self _handlePingWithData:frameData];\n            break;\n        case SROpCodePong:\n            [self handlePong:frameData];\n            break;\n        default:\n            [self _closeWithProtocolError:[NSString stringWithFormat:@\"Unknown opcode %ld\", (long)opcode]];\n            // TODO: Handle invalid opcode\n            break;\n    }\n}\n\n- (void)_handleFrameHeader:(frame_header)frame_header curData:(NSData *)curData\n{\n    assert(frame_header.opcode != 0);\n\n    if (self.readyState == SR_CLOSED) {\n        return;\n    }\n\n\n    BOOL isControlFrame = (frame_header.opcode == SROpCodePing || frame_header.opcode == SROpCodePong || frame_header.opcode == SROpCodeConnectionClose);\n\n    if (isControlFrame && !frame_header.fin) {\n        [self _closeWithProtocolError:@\"Fragmented control frames not allowed\"];\n        return;\n    }\n\n    if (isControlFrame && frame_header.payload_length >= 126) {\n        [self _closeWithProtocolError:@\"Control frames cannot have payloads larger than 126 bytes\"];\n        return;\n    }\n\n    if (!isControlFrame) {\n        _currentFrameOpcode = frame_header.opcode;\n        _currentFrameCount += 1;\n    }\n\n    if (frame_header.payload_length == 0) {\n        if (isControlFrame) {\n            [self _handleFrameWithData:curData opCode:frame_header.opcode];\n        } else {\n            if (frame_header.fin) {\n                [self _handleFrameWithData:_currentFrameData opCode:frame_header.opcode];\n            } else {\n                // TODO add assert that opcode is not a control;\n                [self _readFrameContinue];\n            }\n        }\n    } else {\n        if (frame_header.payload_length > SRWebSocketMaxFramePayloadLength) {\n            [self _closeWithProtocolError:@\"Payload length too large.\"];\n            return;\n        }\n        [self _addConsumerWithDataLength:(size_t)frame_header.payload_length callback:^(SRWebSocket *sself, NSData *newData) {\n            if (isControlFrame) {\n                [sself _handleFrameWithData:newData opCode:frame_header.opcode];\n            } else {\n                if (frame_header.fin) {\n                    [sself _handleFrameWithData:sself->_currentFrameData opCode:frame_header.opcode];\n                } else {\n                    // TODO add assert that opcode is not a control;\n                    [sself _readFrameContinue];\n                }\n            }\n        } readToCurrentFrame:!isControlFrame unmaskBytes:frame_header.masked];\n    }\n}\n\n/* From RFC:\n\n 0                   1                   2                   3\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n +-+-+-+-+-------+-+-------------+-------------------------------+\n |F|R|R|R| opcode|M| Payload len |    Extended payload length    |\n |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |\n |N|V|V|V|       |S|             |   (if payload len==126/127)   |\n | |1|2|3|       |K|             |                               |\n +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +\n |     Extended payload length continued, if payload len == 127  |\n + - - - - - - - - - - - - - - - +-------------------------------+\n |                               |Masking-key, if MASK set to 1  |\n +-------------------------------+-------------------------------+\n | Masking-key (continued)       |          Payload Data         |\n +-------------------------------- - - - - - - - - - - - - - - - +\n :                     Payload Data continued ...                :\n + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +\n |                     Payload Data continued ...                |\n +---------------------------------------------------------------+\n */\n\nstatic const uint8_t SRFinMask          = 0x80;\nstatic const uint8_t SROpCodeMask       = 0x0F;\nstatic const uint8_t SRRsvMask          = 0x70;\nstatic const uint8_t SRMaskMask         = 0x80;\nstatic const uint8_t SRPayloadLenMask   = 0x7F;\n\n\n- (void)_readFrameContinue\n{\n    assert((_currentFrameCount == 0 && _currentFrameOpcode == 0) || (_currentFrameCount > 0 && _currentFrameOpcode > 0));\n\n    [self _addConsumerWithDataLength:2 callback:^(SRWebSocket *sself, NSData *data) {\n        __block frame_header header = {0};\n\n        const uint8_t *headerBuffer = data.bytes;\n        assert(data.length >= 2);\n\n        if (headerBuffer[0] & SRRsvMask) {\n            [sself _closeWithProtocolError:@\"Server used RSV bits\"];\n            return;\n        }\n\n        uint8_t receivedOpcode = (SROpCodeMask & headerBuffer[0]);\n\n        BOOL isControlFrame = (receivedOpcode == SROpCodePing || receivedOpcode == SROpCodePong || receivedOpcode == SROpCodeConnectionClose);\n\n        if (!isControlFrame && receivedOpcode != 0 && sself->_currentFrameCount > 0) {\n            [sself _closeWithProtocolError:@\"all data frames after the initial data frame must have opcode 0\"];\n            return;\n        }\n\n        if (receivedOpcode == 0 && sself->_currentFrameCount == 0) {\n            [sself _closeWithProtocolError:@\"cannot continue a message\"];\n            return;\n        }\n\n        header.opcode = receivedOpcode == 0 ? sself->_currentFrameOpcode : receivedOpcode;\n\n        header.fin = !!(SRFinMask & headerBuffer[0]);\n\n\n        header.masked = !!(SRMaskMask & headerBuffer[1]);\n        header.payload_length = SRPayloadLenMask & headerBuffer[1];\n\n        headerBuffer = NULL;\n\n        if (header.masked) {\n            [sself _closeWithProtocolError:@\"Client must receive unmasked data\"];\n            return;\n        }\n\n        size_t extra_bytes_needed = header.masked ? sizeof(sself->_currentReadMaskKey) : 0;\n\n        if (header.payload_length == 126) {\n            extra_bytes_needed += sizeof(uint16_t);\n        } else if (header.payload_length == 127) {\n            extra_bytes_needed += sizeof(uint64_t);\n        }\n\n        if (extra_bytes_needed == 0) {\n            [sself _handleFrameHeader:header curData:sself->_currentFrameData];\n        } else {\n            [sself _addConsumerWithDataLength:extra_bytes_needed callback:^(SRWebSocket *eself, NSData *edata) {\n                size_t mapped_size = edata.length;\n#pragma unused (mapped_size)\n                const void *mapped_buffer = edata.bytes;\n                size_t offset = 0;\n\n                if (header.payload_length == 126) {\n                    assert(mapped_size >= sizeof(uint16_t));\n                    uint16_t payloadLength = 0;\n                    memcpy(&payloadLength, mapped_buffer, sizeof(uint16_t));\n                    payloadLength = CFSwapInt16BigToHost(payloadLength);\n\n                    header.payload_length = payloadLength;\n                    offset += sizeof(uint16_t);\n                } else if (header.payload_length == 127) {\n                    assert(mapped_size >= sizeof(uint64_t));\n                    uint64_t payloadLength = 0;\n                    memcpy(&payloadLength, mapped_buffer, sizeof(uint64_t));\n                    payloadLength = CFSwapInt64BigToHost(payloadLength);\n\n                    header.payload_length = payloadLength;\n                    offset += sizeof(uint64_t);\n                } else {\n                    assert(header.payload_length < 126 && header.payload_length >= 0);\n                }\n\n                if (header.masked) {\n                    assert(mapped_size >= sizeof(eself->_currentReadMaskOffset) + offset);\n                    memcpy(eself->_currentReadMaskKey, ((uint8_t *)mapped_buffer) + offset, sizeof(eself->_currentReadMaskKey));\n                }\n\n                [eself _handleFrameHeader:header curData:eself->_currentFrameData];\n            } readToCurrentFrame:NO unmaskBytes:NO];\n        }\n    } readToCurrentFrame:NO unmaskBytes:NO];\n}\n\n- (void)_readFrameNew\n{\n    dispatch_async(_workQueue, ^{\n        // Don't reset the length, since Apple doesn't guarantee that this will free the memory (and in tests on\n        // some platforms, it doesn't seem to, effectively causing a leak the size of the biggest frame so far).\n        self->_currentFrameData = [[NSMutableData alloc] init];\n\n        self->_currentFrameOpcode = 0;\n        self->_currentFrameCount = 0;\n        self->_readOpCount = 0;\n        self->_currentStringScanPosition = 0;\n\n        [self _readFrameContinue];\n    });\n}\n\n- (void)_pumpWriting\n{\n    [self assertOnWorkQueue];\n\n    NSUInteger dataLength = dispatch_data_get_size(_outputBuffer);\n    if (dataLength - _outputBufferOffset > 0 && _outputStream.hasSpaceAvailable) {\n        __block NSInteger bytesWritten = 0;\n        __block BOOL streamFailed = NO;\n\n        dispatch_data_t dataToSend = dispatch_data_create_subrange(_outputBuffer, _outputBufferOffset, dataLength - _outputBufferOffset);\n        dispatch_data_apply(dataToSend, ^bool(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {\n            NSInteger sentLength = [_outputStream write:buffer maxLength:size];\n            if (sentLength == -1) {\n                streamFailed = YES;\n                return false;\n            }\n            bytesWritten += sentLength;\n            return (sentLength >= (NSInteger)size); // If we can't write all the data into the stream - bail-out early.\n        });\n        if (streamFailed) {\n            NSInteger code = 2145;\n            NSString *description = @\"Error writing to stream.\";\n            NSError *streamError = _outputStream.streamError;\n            NSError *error = streamError ? SRErrorWithCodeDescriptionUnderlyingError(code, description, streamError) : SRErrorWithCodeDescription(code, description);\n            [self _failWithError:error];\n            return;\n        }\n\n        _outputBufferOffset += bytesWritten;\n\n        if (_outputBufferOffset > SRDefaultBufferSize() && _outputBufferOffset > dataLength / 2) {\n            _outputBuffer = dispatch_data_create_subrange(_outputBuffer, _outputBufferOffset, dataLength - _outputBufferOffset);\n            _outputBufferOffset = 0;\n        }\n    }\n\n    if (_closeWhenFinishedWriting &&\n        (dispatch_data_get_size(_outputBuffer) - _outputBufferOffset) == 0 &&\n        (_inputStream.streamStatus != NSStreamStatusNotOpen &&\n         _inputStream.streamStatus != NSStreamStatusClosed) &&\n        !_sentClose) {\n        _sentClose = YES;\n\n        @synchronized(self) {\n            [_outputStream close];\n            [_inputStream close];\n\n\n            for (NSArray *runLoop in [_scheduledRunloops copy]) {\n                [self unscheduleFromRunLoop:[runLoop objectAtIndex:0] forMode:[runLoop objectAtIndex:1]];\n            }\n        }\n\n        if (!_failed) {\n            self.readyState = SR_CLOSED;\n            [self.delegateController performDelegateBlock:^(id<SRWebSocketDelegate>  _Nullable delegate, SRDelegateAvailableMethods availableMethods) {\n                if (availableMethods.didCloseWithCode) {\n                    [delegate webSocket:self didCloseWithCode:self->_closeCode reason:self->_closeReason wasClean:YES];\n                }\n            }];\n        }\n\n        [self _scheduleCleanup];\n    }\n}\n\n- (void)_addConsumerWithScanner:(stream_scanner)consumer callback:(data_callback)callback\n{\n    [self assertOnWorkQueue];\n    [self _addConsumerWithScanner:consumer callback:callback dataLength:0];\n}\n\n- (void)_addConsumerWithDataLength:(size_t)dataLength callback:(data_callback)callback readToCurrentFrame:(BOOL)readToCurrentFrame unmaskBytes:(BOOL)unmaskBytes\n{\n    [self assertOnWorkQueue];\n    assert(dataLength);\n\n    [_consumers addObject:[_consumerPool consumerWithScanner:nil handler:callback bytesNeeded:dataLength readToCurrentFrame:readToCurrentFrame unmaskBytes:unmaskBytes]];\n    [self _pumpScanner];\n}\n\n- (void)_addConsumerWithScanner:(stream_scanner)consumer callback:(data_callback)callback dataLength:(size_t)dataLength\n{\n    [self assertOnWorkQueue];\n    [_consumers addObject:[_consumerPool consumerWithScanner:consumer handler:callback bytesNeeded:dataLength readToCurrentFrame:NO unmaskBytes:NO]];\n    [self _pumpScanner];\n}\n\n\n- (void)_scheduleCleanup\n{\n    @synchronized(self) {\n        if (_cleanupScheduled) {\n            return;\n        }\n\n        _cleanupScheduled = YES;\n\n        // Cleanup NSStream delegate's in the same RunLoop used by the streams themselves:\n        // This way we'll prevent race conditions between handleEvent and SRWebsocket's dealloc\n        NSTimer *timer = [NSTimer timerWithTimeInterval:(0.0f) target:self selector:@selector(_cleanupSelfReference:) userInfo:nil repeats:NO];\n        [[NSRunLoop SR_networkRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];\n    }\n}\n\n- (void)_cleanupSelfReference:(NSTimer *)timer\n{\n    @synchronized(self) {\n        // Nuke NSStream delegate's\n        _inputStream.delegate = nil;\n        _outputStream.delegate = nil;\n\n        // Remove the streams, right now, from the networkRunLoop\n        [_inputStream close];\n        [_outputStream close];\n    }\n\n    // Cleanup selfRetain in the same GCD queue as usual\n    dispatch_async(_workQueue, ^{\n        self->_selfRetain = nil;\n    });\n}\n\n\nstatic const char CRLFCRLFBytes[] = {'\\r', '\\n', '\\r', '\\n'};\n\n- (void)_readUntilHeaderCompleteWithCallback:(data_callback)dataHandler\n{\n    [self _readUntilBytes:CRLFCRLFBytes length:sizeof(CRLFCRLFBytes) callback:dataHandler];\n}\n\n- (void)_readUntilBytes:(const void *)bytes length:(size_t)length callback:(data_callback)dataHandler\n{\n    // TODO optimize so this can continue from where we last searched\n    stream_scanner consumer = ^size_t(NSData *data) {\n        __block size_t found_size = 0;\n        __block size_t match_count = 0;\n\n        size_t size = data.length;\n        const unsigned char *buffer = data.bytes;\n        for (size_t i = 0; i < size; i++ ) {\n            if (((const unsigned char *)buffer)[i] == ((const unsigned char *)bytes)[match_count]) {\n                match_count += 1;\n                if (match_count == length) {\n                    found_size = i + 1;\n                    break;\n                }\n            } else {\n                match_count = 0;\n            }\n        }\n        return found_size;\n    };\n    [self _addConsumerWithScanner:consumer callback:dataHandler];\n}\n\n\n// Returns true if did work\n- (BOOL)_innerPumpScanner {\n\n    BOOL didWork = NO;\n\n    if (self.readyState >= SR_CLOSED) {\n        return didWork;\n    }\n\n    size_t readBufferSize = dispatch_data_get_size(_readBuffer);\n\n    if (!_consumers.count) {\n        return didWork;\n    }\n\n    size_t curSize = readBufferSize - _readBufferOffset;\n    if (!curSize) {\n        return didWork;\n    }\n\n    SRIOConsumer *consumer = [_consumers objectAtIndex:0];\n\n    size_t bytesNeeded = consumer.bytesNeeded;\n\n    size_t foundSize = 0;\n    if (consumer.consumer) {\n        NSData *subdata = (NSData *)dispatch_data_create_subrange(_readBuffer, _readBufferOffset, readBufferSize - _readBufferOffset);\n        foundSize = consumer.consumer(subdata);\n    } else {\n        assert(consumer.bytesNeeded);\n        if (curSize >= bytesNeeded) {\n            foundSize = bytesNeeded;\n        } else if (consumer.readToCurrentFrame) {\n            foundSize = curSize;\n        }\n    }\n\n    if (consumer.readToCurrentFrame || foundSize) {\n        dispatch_data_t slice = dispatch_data_create_subrange(_readBuffer, _readBufferOffset, foundSize);\n\n        _readBufferOffset += foundSize;\n\n        if (_readBufferOffset > SRDefaultBufferSize() && _readBufferOffset > readBufferSize / 2) {\n            _readBuffer = dispatch_data_create_subrange(_readBuffer, _readBufferOffset, readBufferSize - _readBufferOffset);\n            _readBufferOffset = 0;\n        }\n\n        if (consumer.unmaskBytes) {\n            __block NSMutableData *mutableSlice = [slice mutableCopy];\n\n            NSUInteger len = mutableSlice.length;\n            uint8_t *bytes = mutableSlice.mutableBytes;\n\n            for (NSUInteger i = 0; i < len; i++) {\n                bytes[i] = bytes[i] ^ _currentReadMaskKey[_currentReadMaskOffset % sizeof(_currentReadMaskKey)];\n                _currentReadMaskOffset += 1;\n            }\n\n            slice = dispatch_data_create(bytes, len, nil, ^{\n                mutableSlice = nil;\n            });\n        }\n\n        if (consumer.readToCurrentFrame) {\n            dispatch_data_apply(slice, ^bool(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {\n                [_currentFrameData appendBytes:buffer length:size];\n                return true;\n            });\n\n            _readOpCount += 1;\n\n            if (_currentFrameOpcode == SROpCodeTextFrame) {\n                // Validate UTF8 stuff.\n                size_t currentDataSize = _currentFrameData.length;\n                if (_currentFrameOpcode == SROpCodeTextFrame && currentDataSize > 0) {\n                    // TODO: Optimize the crap out of this.  Don't really have to copy all the data each time\n\n                    size_t scanSize = currentDataSize - _currentStringScanPosition;\n\n                    NSData *scan_data = [_currentFrameData subdataWithRange:NSMakeRange(_currentStringScanPosition, scanSize)];\n                    int32_t valid_utf8_size = validate_dispatch_data_partial_string(scan_data);\n\n                    if (valid_utf8_size == -1) {\n                        [self closeWithCode:SRStatusCodeInvalidUTF8 reason:@\"Text frames must be valid UTF-8\"];\n                        dispatch_async(_workQueue, ^{\n                            [self closeConnection];\n                        });\n                        return didWork;\n                    } else {\n                        _currentStringScanPosition += valid_utf8_size;\n                    }\n                }\n\n            }\n\n            consumer.bytesNeeded -= foundSize;\n\n            if (consumer.bytesNeeded == 0) {\n                [_consumers removeObjectAtIndex:0];\n                consumer.handler(self, nil);\n                [_consumerPool returnConsumer:consumer];\n                didWork = YES;\n            }\n        } else if (foundSize) {\n            [_consumers removeObjectAtIndex:0];\n            consumer.handler(self, (NSData *)slice);\n            [_consumerPool returnConsumer:consumer];\n            didWork = YES;\n        }\n    }\n    return didWork;\n}\n\n-(void)_pumpScanner\n{\n    [self assertOnWorkQueue];\n\n    if (!_isPumping) {\n        _isPumping = YES;\n    } else {\n        return;\n    }\n\n    while ([self _innerPumpScanner]) {\n\n    }\n\n    _isPumping = NO;\n}\n\n//#define NOMASK\n\nstatic const size_t SRFrameHeaderOverhead = 32;\n\n- (void)_sendFrameWithOpcode:(SROpCode)opCode data:(NSData *)data\n{\n    [self assertOnWorkQueue];\n\n    if (!data) {\n        return;\n    }\n\n    size_t payloadLength = data.length;\n\n    NSMutableData *frameData = [[NSMutableData alloc] initWithLength:payloadLength + SRFrameHeaderOverhead];\n    if (!frameData) {\n        [self closeWithCode:SRStatusCodeMessageTooBig reason:@\"Message too big\"];\n        return;\n    }\n    uint8_t *frameBuffer = (uint8_t *)frameData.mutableBytes;\n\n    // set fin\n    frameBuffer[0] = SRFinMask | opCode;\n\n    // set the mask and header\n    frameBuffer[1] |= SRMaskMask;\n\n    size_t frameBufferSize = 2;\n\n    if (payloadLength < 126) {\n        frameBuffer[1] |= payloadLength;\n    } else {\n        uint64_t declaredPayloadLength = 0;\n        size_t declaredPayloadLengthSize = 0;\n\n        if (payloadLength <= UINT16_MAX) {\n            frameBuffer[1] |= 126;\n\n            declaredPayloadLength = CFSwapInt16BigToHost((uint16_t)payloadLength);\n            declaredPayloadLengthSize = sizeof(uint16_t);\n        } else {\n            frameBuffer[1] |= 127;\n\n            declaredPayloadLength = CFSwapInt64BigToHost((uint64_t)payloadLength);\n            declaredPayloadLengthSize = sizeof(uint64_t);\n        }\n\n        memcpy((frameBuffer + frameBufferSize), &declaredPayloadLength, declaredPayloadLengthSize);\n        frameBufferSize += declaredPayloadLengthSize;\n    }\n\n    const uint8_t *unmaskedPayloadBuffer = (uint8_t *)data.bytes;\n    uint8_t *maskKey = frameBuffer + frameBufferSize;\n\n    size_t randomBytesSize = sizeof(uint32_t);\n    NSData *randomData = SRRandomData(randomBytesSize);\n    [randomData getBytes:maskKey range:NSMakeRange(0, randomBytesSize)];\n    frameBufferSize += randomBytesSize;\n\n    // Copy and unmask the buffer\n    uint8_t *frameBufferPayloadPointer = frameBuffer + frameBufferSize;\n\n    memcpy(frameBufferPayloadPointer, unmaskedPayloadBuffer, payloadLength);\n    SRMaskBytesSIMD(frameBufferPayloadPointer, payloadLength, maskKey);\n    frameBufferSize += payloadLength;\n\n    assert(frameBufferSize <= frameData.length);\n    frameData.length = frameBufferSize;\n\n    [self _writeData:frameData];\n}\n\n- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode\n{\n    __weak typeof(self) wself = self;\n\n    if (_requestRequiresSSL && !_streamSecurityValidated &&\n        (eventCode == NSStreamEventHasBytesAvailable || eventCode == NSStreamEventHasSpaceAvailable)) {\n        SecTrustRef trust = (__bridge SecTrustRef)[aStream propertyForKey:(__bridge id)kCFStreamPropertySSLPeerTrust];\n        if (trust) {\n            NSString *const host = _urlRequest.URL.host;\n            if (!host || host.length == 0) {\n                dispatch_async(_workQueue, ^{\n                    NSError *error = SRErrorWithDomainCodeDescription(NSURLErrorDomain,\n                                                                      NSURLErrorBadURL,\n                                                                      @\"Unable to validate certificate for empty host.\");\n                    [wself _failWithError:error];\n                });\n                return;\n            }\n            _streamSecurityValidated = [_securityPolicy evaluateServerTrust:trust forDomain:host];\n        }\n        if (!_streamSecurityValidated) {\n            dispatch_async(_workQueue, ^{\n                NSError *error = SRErrorWithDomainCodeDescription(NSURLErrorDomain,\n                                                                  NSURLErrorClientCertificateRejected,\n                                                                  @\"Invalid server certificate.\");\n                [wself _failWithError:error];\n            });\n            return;\n        }\n        dispatch_async(_workQueue, ^{\n            [self didConnect];\n        });\n    }\n    dispatch_async(_workQueue, ^{\n        [wself safeHandleEvent:eventCode stream:aStream];\n    });\n}\n\n- (void)safeHandleEvent:(NSStreamEvent)eventCode stream:(NSStream *)aStream\n{\n    switch (eventCode) {\n        case NSStreamEventOpenCompleted: {\n            SRDebugLog(@\"NSStreamEventOpenCompleted %@\", aStream);\n            if (self.readyState >= SR_CLOSING) {\n                return;\n            }\n            assert(_readBuffer);\n\n            if (!_requestRequiresSSL && self.readyState == SR_CONNECTING && aStream == _inputStream) {\n                [self didConnect];\n            }\n\n            [self _pumpWriting];\n            [self _pumpScanner];\n\n            break;\n        }\n\n        case NSStreamEventErrorOccurred: {\n            SRDebugLog(@\"NSStreamEventErrorOccurred %@ %@\", aStream, [[aStream streamError] copy]);\n            /// TODO specify error better!\n            [self _failWithError:aStream.streamError];\n            _readBufferOffset = 0;\n            _readBuffer = dispatch_data_empty;\n            break;\n\n        }\n\n        case NSStreamEventEndEncountered: {\n            [self _pumpScanner];\n            SRDebugLog(@\"NSStreamEventEndEncountered %@\", aStream);\n            if (aStream.streamError) {\n                [self _failWithError:aStream.streamError];\n            } else {\n                dispatch_async(_workQueue, ^{\n                    if (self.readyState != SR_CLOSED) {\n                        self.readyState = SR_CLOSED;\n                        [self _scheduleCleanup];\n                    }\n\n                    if (!self->_sentClose && !self->_failed) {\n                        self->_sentClose = YES;\n                        // If we get closed in this state it's probably not clean because we should be sending this when we send messages\n                        [self.delegateController performDelegateBlock:^(id<SRWebSocketDelegate>  _Nullable delegate, SRDelegateAvailableMethods availableMethods) {\n                            if (availableMethods.didCloseWithCode) {\n                                [delegate webSocket:self\n                                   didCloseWithCode:SRStatusCodeGoingAway\n                                             reason:@\"Stream end encountered\"\n                                           wasClean:NO];\n                            }\n                        }];\n                    }\n                });\n            }\n\n            break;\n        }\n\n        case NSStreamEventHasBytesAvailable: {\n            SRDebugLog(@\"NSStreamEventHasBytesAvailable %@\", aStream);\n            uint8_t buffer[SRDefaultBufferSize()];\n\n            while (_inputStream.hasBytesAvailable) {\n                NSInteger bytesRead = [_inputStream read:buffer maxLength:SRDefaultBufferSize()];\n                if (bytesRead > 0) {\n                    dispatch_data_t data = dispatch_data_create(buffer, bytesRead, nil, DISPATCH_DATA_DESTRUCTOR_DEFAULT);\n                    if (!data) {\n                        NSError *error = SRErrorWithCodeDescription(SRStatusCodeMessageTooBig,\n                                                                    @\"Unable to allocate memory to read from socket.\");\n                        [self _failWithError:error];\n                        return;\n                    }\n                    _readBuffer = dispatch_data_create_concat(_readBuffer, data);\n                } else if (bytesRead == -1) {\n                    [self _failWithError:_inputStream.streamError];\n                }\n            }\n            [self _pumpScanner];\n            break;\n        }\n\n        case NSStreamEventHasSpaceAvailable: {\n            SRDebugLog(@\"NSStreamEventHasSpaceAvailable %@\", aStream);\n            [self _pumpWriting];\n            break;\n        }\n\n        case NSStreamEventNone:\n            SRDebugLog(@\"(default)  %@\", aStream);\n            break;\n    }\n}\n\n///--------------------------------------\n#pragma mark - Delegate\n///--------------------------------------\n\n- (id<SRWebSocketDelegate> _Nullable)delegate\n{\n    return self.delegateController.delegate;\n}\n\n- (void)setDelegate:(id<SRWebSocketDelegate> _Nullable)delegate\n{\n    self.delegateController.delegate = delegate;\n}\n\n- (void)setDelegateDispatchQueue:(dispatch_queue_t _Nullable)queue\n{\n    self.delegateController.dispatchQueue = queue;\n}\n\n- (dispatch_queue_t _Nullable)delegateDispatchQueue\n{\n    return self.delegateController.dispatchQueue;\n}\n\n- (void)setDelegateOperationQueue:(NSOperationQueue *_Nullable)queue\n{\n    self.delegateController.operationQueue = queue;\n}\n\n- (NSOperationQueue *_Nullable)delegateOperationQueue\n{\n    return self.delegateController.operationQueue;\n}\n\n@end\n\n#ifdef HAS_ICU\n\nstatic inline int32_t validate_dispatch_data_partial_string(NSData *data) {\n    if ([data length] > INT32_MAX) {\n        // INT32_MAX is the limit so long as this Framework is using 32 bit ints everywhere.\n        return -1;\n    }\n\n    int32_t size = (int32_t)[data length];\n\n    const void * contents = [data bytes];\n    const uint8_t *str = (const uint8_t *)contents;\n\n    UChar32 codepoint = 1;\n    int32_t offset = 0;\n    int32_t lastOffset = 0;\n    while(offset < size && codepoint > 0)  {\n        lastOffset = offset;\n        U8_NEXT(str, offset, size, codepoint);\n    }\n\n    if (codepoint == -1) {\n        // Check to see if the last byte is valid or whether it was just continuing\n        if (!U8_IS_LEAD(str[lastOffset]) || U8_COUNT_TRAIL_BYTES(str[lastOffset]) + lastOffset < (int32_t)size) {\n\n            size = -1;\n        } else {\n            uint8_t leadByte = str[lastOffset];\n            U8_MASK_LEAD_BYTE(leadByte, U8_COUNT_TRAIL_BYTES(leadByte));\n\n            for (int i = lastOffset + 1; i < offset; i++) {\n                if (U8_IS_SINGLE(str[i]) || U8_IS_LEAD(str[i]) || !U8_IS_TRAIL(str[i])) {\n                    size = -1;\n                }\n            }\n\n            if (size != -1) {\n                size = lastOffset;\n            }\n        }\n    }\n\n    if (size != -1 && ![[NSString alloc] initWithBytesNoCopy:(char *)[data bytes] length:size encoding:NSUTF8StringEncoding freeWhenDone:NO]) {\n        size = -1;\n    }\n\n    return size;\n}\n\n#else\n\n// This is a hack, and probably not optimal\nstatic inline int32_t validate_dispatch_data_partial_string(NSData *data) {\n    static const int maxCodepointSize = 3;\n\n    for (int i = 0; i < maxCodepointSize; i++) {\n        NSString *str = [[NSString alloc] initWithBytesNoCopy:(char *)data.bytes length:data.length - i encoding:NSUTF8StringEncoding freeWhenDone:NO];\n        if (str) {\n            return (int32_t)data.length - i;\n        }\n    }\n\n    return -1;\n}\n\n#endif\n"
  },
  {
    "path": "SocketRocket/SocketRocket.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <SocketRocket/NSRunLoop+SRWebSocket.h>\n#import <SocketRocket/NSURLRequest+SRWebSocket.h>\n#import <SocketRocket/SRSecurityPolicy.h>\n#import <SocketRocket/SRWebSocket.h>\n"
  },
  {
    "path": "SocketRocket.podspec",
    "content": "Pod::Spec.new do |s|\n  s.name               = 'SocketRocket'\n  s.version            = '0.7.1'\n  s.summary            = 'A conforming WebSocket (RFC 6455) client library for iOS, macOS and tvOS.'\n  s.homepage           = 'https://github.com/facebook/SocketRocket'\n  s.authors            = { 'Nikita Lutsenko' => 'nlutsenko@me.com', 'Dan Federman' => 'federman@squareup.com', 'Mike Lewis' => 'mikelikespie@gmail.com' }\n  s.license            = 'BSD'\n  s.source             = { :git => 'https://github.com/facebook/SocketRocket.git', :tag => s.version.to_s }\n  s.requires_arc       = true\n\n  s.source_files       = 'SocketRocket/**/*.{h,m}'\n  s.public_header_files = 'SocketRocket/*.h'\n\n  s.ios.deployment_target  = '11.0'\n  s.osx.deployment_target  = '10.13'\n  s.tvos.deployment_target = '11.0'\n  s.visionos.deployment_target = '1.0'\n\n  s.ios.frameworks     = 'CFNetwork', 'Security'\n  s.osx.frameworks     = 'CoreServices', 'Security'\n  s.tvos.frameworks    = 'CFNetwork', 'Security'\n  s.libraries          = 'icucore'\nend\n"
  },
  {
    "path": "SocketRocket.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t2D42277F1BB4365C000C1A6C /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t2D4227801BB43693000C1A6C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };\n\t\t2D4227831BB436B1000C1A6C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };\n\t\t2D4227851BB43734000C1A6C /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.m */; };\n\t\t3345DC841C52ACD70083CCB8 /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.m */; };\n\t\t3345DC871C52ACD70083CCB8 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };\n\t\t3345DC881C52ACD70083CCB8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };\n\t\t3345DC8A1C52ACD70083CCB8 /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t454A02D61D0FAD010060DFB2 /* SRSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 454A02D41D0FAD010060DFB2 /* SRSecurityPolicy.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t454A02D71D0FAD010060DFB2 /* SRSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 454A02D41D0FAD010060DFB2 /* SRSecurityPolicy.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t454A02D81D0FAD010060DFB2 /* SRSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 454A02D41D0FAD010060DFB2 /* SRSecurityPolicy.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t454FEA7D1D2570F600073768 /* SRPinningSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 454FEA791D2570D400073768 /* SRPinningSecurityPolicy.h */; };\n\t\t454FEA7E1D2570F600073768 /* SRPinningSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 454FEA7A1D2570D400073768 /* SRPinningSecurityPolicy.m */; };\n\t\t454FEA7F1D2570F800073768 /* SRPinningSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 454FEA791D2570D400073768 /* SRPinningSecurityPolicy.h */; };\n\t\t454FEA801D2570F800073768 /* SRPinningSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 454FEA7A1D2570D400073768 /* SRPinningSecurityPolicy.m */; };\n\t\t454FEA811D2570F900073768 /* SRPinningSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 454FEA791D2570D400073768 /* SRPinningSecurityPolicy.h */; };\n\t\t454FEA821D2570F900073768 /* SRPinningSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 454FEA7A1D2570D400073768 /* SRPinningSecurityPolicy.m */; };\n\t\t454FEA851D25719900073768 /* SRSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 454FEA831D25717C00073768 /* SRSecurityPolicy.m */; };\n\t\t454FEA861D25719A00073768 /* SRSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 454FEA831D25717C00073768 /* SRSecurityPolicy.m */; };\n\t\t454FEA871D25719A00073768 /* SRSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 454FEA831D25717C00073768 /* SRSecurityPolicy.m */; };\n\t\t8105E4801CDD67B400AA12DB /* SRAutobahnTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8105E47A1CDD679A00AA12DB /* SRAutobahnTests.m */; };\n\t\t8105E4821CDD67BD00AA12DB /* SRTWebSocketOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8105E4771CDD679A00AA12DB /* SRTWebSocketOperation.m */; };\n\t\t8105E4AE1CDD6E6200AA12DB /* SRAutobahnOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 8105E4AD1CDD6E6200AA12DB /* SRAutobahnOperation.m */; };\n\t\t8105E5281CDD98E100AA12DB /* autobahn_configuration.json in Resources */ = {isa = PBXBuildFile; fileRef = 8105E5271CDD98E100AA12DB /* autobahn_configuration.json */; };\n\t\t8117C4241D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8117C4221D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h */; };\n\t\t8117C4251D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8117C4221D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h */; };\n\t\t8117C4261D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8117C4221D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h */; };\n\t\t8117C4311D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8117C42F1D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h */; };\n\t\t8117C4321D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8117C42F1D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h */; };\n\t\t8117C4331D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8117C42F1D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h */; };\n\t\t811934BC1CDAF725003AB243 /* SocketRocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 555E0EB11C51E56D00E6BB92 /* SocketRocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t811934BE1CDAF725003AB243 /* SocketRocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 555E0EB11C51E56D00E6BB92 /* SocketRocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t811934C01CDAF726003AB243 /* SocketRocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 555E0EB11C51E56D00E6BB92 /* SocketRocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t813364001D091E170062E28D /* SRProxyConnect.h in Headers */ = {isa = PBXBuildFile; fileRef = 4861E7731D022211002FAB1D /* SRProxyConnect.h */; };\n\t\t813364041D091E170062E28D /* SRProxyConnect.h in Headers */ = {isa = PBXBuildFile; fileRef = 4861E7731D022211002FAB1D /* SRProxyConnect.h */; };\n\t\t813364081D091E180062E28D /* SRProxyConnect.h in Headers */ = {isa = PBXBuildFile; fileRef = 4861E7731D022211002FAB1D /* SRProxyConnect.h */; };\n\t\t8133640C1D091E1B0062E28D /* SRProxyConnect.m in Sources */ = {isa = PBXBuildFile; fileRef = 4861E7741D022211002FAB1D /* SRProxyConnect.m */; };\n\t\t8133640E1D091E1B0062E28D /* SRProxyConnect.m in Sources */ = {isa = PBXBuildFile; fileRef = 4861E7741D022211002FAB1D /* SRProxyConnect.m */; };\n\t\t8133640F1D091E1C0062E28D /* SRProxyConnect.m in Sources */ = {isa = PBXBuildFile; fileRef = 4861E7741D022211002FAB1D /* SRProxyConnect.m */; };\n\t\t815FE7271D497D720085FDA5 /* SRConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 815FE7241D497D720085FDA5 /* SRConstants.h */; };\n\t\t815FE7281D497D720085FDA5 /* SRConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 815FE7241D497D720085FDA5 /* SRConstants.h */; };\n\t\t815FE7291D497D720085FDA5 /* SRConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 815FE7241D497D720085FDA5 /* SRConstants.h */; };\n\t\t815FE72B1D497D720085FDA5 /* SRConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 815FE7251D497D720085FDA5 /* SRConstants.m */; };\n\t\t815FE72C1D497D720085FDA5 /* SRConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 815FE7251D497D720085FDA5 /* SRConstants.m */; };\n\t\t815FE72D1D497D720085FDA5 /* SRConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 815FE7251D497D720085FDA5 /* SRConstants.m */; };\n\t\t817491A91D1C8C33006E09DF /* SRMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 817491A61D1C8C33006E09DF /* SRMutex.h */; };\n\t\t817491AA1D1C8C33006E09DF /* SRMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 817491A61D1C8C33006E09DF /* SRMutex.h */; };\n\t\t817491AB1D1C8C33006E09DF /* SRMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 817491A61D1C8C33006E09DF /* SRMutex.h */; };\n\t\t817491AD1D1C8C33006E09DF /* SRMutex.m in Sources */ = {isa = PBXBuildFile; fileRef = 817491A71D1C8C33006E09DF /* SRMutex.m */; };\n\t\t817491AE1D1C8C33006E09DF /* SRMutex.m in Sources */ = {isa = PBXBuildFile; fileRef = 817491A71D1C8C33006E09DF /* SRMutex.m */; };\n\t\t817491AF1D1C8C33006E09DF /* SRMutex.m in Sources */ = {isa = PBXBuildFile; fileRef = 817491A71D1C8C33006E09DF /* SRMutex.m */; };\n\t\t817995871CE139700084DA37 /* SRDelegateController.h in Headers */ = {isa = PBXBuildFile; fileRef = 817995841CE139700084DA37 /* SRDelegateController.h */; };\n\t\t817995881CE139700084DA37 /* SRDelegateController.h in Headers */ = {isa = PBXBuildFile; fileRef = 817995841CE139700084DA37 /* SRDelegateController.h */; };\n\t\t817995891CE139700084DA37 /* SRDelegateController.h in Headers */ = {isa = PBXBuildFile; fileRef = 817995841CE139700084DA37 /* SRDelegateController.h */; };\n\t\t8179958B1CE139700084DA37 /* SRDelegateController.m in Sources */ = {isa = PBXBuildFile; fileRef = 817995851CE139700084DA37 /* SRDelegateController.m */; };\n\t\t8179958C1CE139700084DA37 /* SRDelegateController.m in Sources */ = {isa = PBXBuildFile; fileRef = 817995851CE139700084DA37 /* SRDelegateController.m */; };\n\t\t8179958D1CE139700084DA37 /* SRDelegateController.m in Sources */ = {isa = PBXBuildFile; fileRef = 817995851CE139700084DA37 /* SRDelegateController.m */; };\n\t\t817996801CE184F40084DA37 /* SRAutobahnUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 8179967F1CE184F40084DA37 /* SRAutobahnUtilities.m */; };\n\t\t81900A4D1D18C9CC0015A290 /* SRLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 81900A4A1D18C9CC0015A290 /* SRLog.h */; };\n\t\t81900A4E1D18C9CC0015A290 /* SRLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 81900A4A1D18C9CC0015A290 /* SRLog.h */; };\n\t\t81900A4F1D18C9CC0015A290 /* SRLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 81900A4A1D18C9CC0015A290 /* SRLog.h */; };\n\t\t81900A511D18C9CC0015A290 /* SRLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 81900A4B1D18C9CC0015A290 /* SRLog.m */; };\n\t\t81900A521D18C9CC0015A290 /* SRLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 81900A4B1D18C9CC0015A290 /* SRLog.m */; };\n\t\t81900A531D18C9CC0015A290 /* SRLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 81900A4B1D18C9CC0015A290 /* SRLog.m */; };\n\t\t81AFCD661D4C431C00B3AFC9 /* libicucore.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 81AFCD651D4C431C00B3AFC9 /* libicucore.tbd */; };\n\t\t81B22EC61CE42D7E0073C636 /* SRError.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B22EC31CE42D7E0073C636 /* SRError.h */; };\n\t\t81B22EC71CE42D7E0073C636 /* SRError.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B22EC31CE42D7E0073C636 /* SRError.h */; };\n\t\t81B22EC81CE42D7E0073C636 /* SRError.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B22EC31CE42D7E0073C636 /* SRError.h */; };\n\t\t81B22ECA1CE42D7E0073C636 /* SRError.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B22EC41CE42D7E0073C636 /* SRError.m */; };\n\t\t81B22ECB1CE42D7E0073C636 /* SRError.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B22EC41CE42D7E0073C636 /* SRError.m */; };\n\t\t81B22ECC1CE42D7E0073C636 /* SRError.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B22EC41CE42D7E0073C636 /* SRError.m */; };\n\t\t81B22EE51CE43ECC0073C636 /* SRURLUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B22EE21CE43ECC0073C636 /* SRURLUtilities.h */; };\n\t\t81B22EE61CE43ECC0073C636 /* SRURLUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B22EE21CE43ECC0073C636 /* SRURLUtilities.h */; };\n\t\t81B22EE71CE43ECC0073C636 /* SRURLUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B22EE21CE43ECC0073C636 /* SRURLUtilities.h */; };\n\t\t81B22EE91CE43ECC0073C636 /* SRURLUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B22EE31CE43ECC0073C636 /* SRURLUtilities.m */; };\n\t\t81B22EEA1CE43ECC0073C636 /* SRURLUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B22EE31CE43ECC0073C636 /* SRURLUtilities.m */; };\n\t\t81B22EEB1CE43ECC0073C636 /* SRURLUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B22EE31CE43ECC0073C636 /* SRURLUtilities.m */; };\n\t\t81B31C151CDC404100D86D43 /* SRIOConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */; };\n\t\t81B31C161CDC404100D86D43 /* SRIOConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */; };\n\t\t81B31C171CDC404100D86D43 /* SRIOConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */; };\n\t\t81B31C191CDC404100D86D43 /* SRIOConsumer.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C101CDC404100D86D43 /* SRIOConsumer.m */; };\n\t\t81B31C1A1CDC404100D86D43 /* SRIOConsumer.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C101CDC404100D86D43 /* SRIOConsumer.m */; };\n\t\t81B31C1B1CDC404100D86D43 /* SRIOConsumer.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C101CDC404100D86D43 /* SRIOConsumer.m */; };\n\t\t81B31C1D1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */; };\n\t\t81B31C1E1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */; };\n\t\t81B31C1F1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */; };\n\t\t81B31C211CDC404100D86D43 /* SRIOConsumerPool.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */; };\n\t\t81B31C221CDC404100D86D43 /* SRIOConsumerPool.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */; };\n\t\t81B31C231CDC404100D86D43 /* SRIOConsumerPool.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */; };\n\t\t81B31C2E1CDC406B00D86D43 /* SRHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C2B1CDC406B00D86D43 /* SRHash.h */; };\n\t\t81B31C2F1CDC406B00D86D43 /* SRHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C2B1CDC406B00D86D43 /* SRHash.h */; };\n\t\t81B31C301CDC406B00D86D43 /* SRHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C2B1CDC406B00D86D43 /* SRHash.h */; };\n\t\t81B31C321CDC406B00D86D43 /* SRHash.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C2C1CDC406B00D86D43 /* SRHash.m */; };\n\t\t81B31C331CDC406B00D86D43 /* SRHash.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C2C1CDC406B00D86D43 /* SRHash.m */; };\n\t\t81B31C341CDC406B00D86D43 /* SRHash.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C2C1CDC406B00D86D43 /* SRHash.m */; };\n\t\t81B31C601CDC444900D86D43 /* SRRunLoopThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */; };\n\t\t81B31C611CDC444900D86D43 /* SRRunLoopThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */; };\n\t\t81B31C621CDC444900D86D43 /* SRRunLoopThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */; };\n\t\t81B31C641CDC444900D86D43 /* SRRunLoopThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */; };\n\t\t81B31C651CDC444900D86D43 /* SRRunLoopThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */; };\n\t\t81B31C661CDC444900D86D43 /* SRRunLoopThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */; };\n\t\t81C22BC31D124168007BFDDF /* SRHTTPConnectMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C22BC01D124168007BFDDF /* SRHTTPConnectMessage.h */; };\n\t\t81C22BC41D124168007BFDDF /* SRHTTPConnectMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C22BC01D124168007BFDDF /* SRHTTPConnectMessage.h */; };\n\t\t81C22BC51D124168007BFDDF /* SRHTTPConnectMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C22BC01D124168007BFDDF /* SRHTTPConnectMessage.h */; };\n\t\t81C22BC71D124168007BFDDF /* SRHTTPConnectMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 81C22BC11D124168007BFDDF /* SRHTTPConnectMessage.m */; };\n\t\t81C22BC81D124168007BFDDF /* SRHTTPConnectMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 81C22BC11D124168007BFDDF /* SRHTTPConnectMessage.m */; };\n\t\t81C22BC91D124168007BFDDF /* SRHTTPConnectMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 81C22BC11D124168007BFDDF /* SRHTTPConnectMessage.m */; };\n\t\t81C22BF91D1256E1007BFDDF /* SRRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C22BF61D1256E1007BFDDF /* SRRandom.h */; };\n\t\t81C22BFA1D1256E1007BFDDF /* SRRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C22BF61D1256E1007BFDDF /* SRRandom.h */; };\n\t\t81C22BFB1D1256E1007BFDDF /* SRRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C22BF61D1256E1007BFDDF /* SRRandom.h */; };\n\t\t81C22BFD1D1256E1007BFDDF /* SRRandom.m in Sources */ = {isa = PBXBuildFile; fileRef = 81C22BF71D1256E1007BFDDF /* SRRandom.m */; };\n\t\t81C22BFE1D1256E1007BFDDF /* SRRandom.m in Sources */ = {isa = PBXBuildFile; fileRef = 81C22BF71D1256E1007BFDDF /* SRRandom.m */; };\n\t\t81C22BFF1D1256E1007BFDDF /* SRRandom.m in Sources */ = {isa = PBXBuildFile; fileRef = 81C22BF71D1256E1007BFDDF /* SRRandom.m */; };\n\t\t81C68CD41D2CBE0A00A1D005 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C68CD31D2CBE0A00A1D005 /* CFNetwork.framework */; };\n\t\t81C68CDF1D2CBE1900A1D005 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C68CDE1D2CBE1900A1D005 /* CFNetwork.framework */; };\n\t\t81C68CEE1D2CBE9400A1D005 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };\n\t\t81C68CF11D2CBE9F00A1D005 /* libicucore.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C68CF01D2CBE9F00A1D005 /* libicucore.tbd */; };\n\t\t81C68CF61D2CBED100A1D005 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };\n\t\t81C68D071D2CBF6A00A1D005 /* libicucore.A.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C68D061D2CBF6A00A1D005 /* libicucore.A.tbd */; };\n\t\t81C68D0E1D2CBFA800A1D005 /* libicucore.A.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C68D0D1D2CBFA800A1D005 /* libicucore.A.tbd */; };\n\t\t81CD05D81CEEC47300497F47 /* NSURLRequest+SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 81CD05D51CEEC47300497F47 /* NSURLRequest+SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t81CD05D91CEEC47300497F47 /* NSURLRequest+SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 81CD05D51CEEC47300497F47 /* NSURLRequest+SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t81CD05DA1CEEC47300497F47 /* NSURLRequest+SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 81CD05D51CEEC47300497F47 /* NSURLRequest+SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t81CD05DC1CEEC47300497F47 /* NSURLRequest+SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 81CD05D61CEEC47300497F47 /* NSURLRequest+SRWebSocket.m */; };\n\t\t81CD05DD1CEEC47300497F47 /* NSURLRequest+SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 81CD05D61CEEC47300497F47 /* NSURLRequest+SRWebSocket.m */; };\n\t\t81CD05DE1CEEC47300497F47 /* NSURLRequest+SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 81CD05D61CEEC47300497F47 /* NSURLRequest+SRWebSocket.m */; };\n\t\t81CD05FE1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 81CD05FB1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t81CD05FF1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 81CD05FB1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t81CD06001CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 81CD05FB1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t81CD06021CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 81CD05FC1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m */; };\n\t\t81CD06031CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 81CD05FC1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m */; };\n\t\t81CD06041CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 81CD05FC1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m */; };\n\t\t81DCD1241D2D9235002501A2 /* libicucore.A.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 81C68D0D1D2CBFA800A1D005 /* libicucore.A.tbd */; };\n\t\tF5391CBF1D2F4B4700606A81 /* SRSIMDHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = F5391CBC1D2F4B4700606A81 /* SRSIMDHelpers.h */; };\n\t\tF5391CC01D2F4B4700606A81 /* SRSIMDHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = F5391CBC1D2F4B4700606A81 /* SRSIMDHelpers.h */; };\n\t\tF5391CC11D2F4B4700606A81 /* SRSIMDHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = F5391CBC1D2F4B4700606A81 /* SRSIMDHelpers.h */; };\n\t\tF5391CC31D2F4B4700606A81 /* SRSIMDHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = F5391CBD1D2F4B4700606A81 /* SRSIMDHelpers.m */; };\n\t\tF5391CC41D2F4B4700606A81 /* SRSIMDHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = F5391CBD1D2F4B4700606A81 /* SRSIMDHelpers.m */; };\n\t\tF5391CC51D2F4B4700606A81 /* SRSIMDHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = F5391CBD1D2F4B4700606A81 /* SRSIMDHelpers.m */; };\n\t\tF6016C8814620EC70037BB3D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };\n\t\tF61A0DC81625F44D00365EBD /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F61A0DC71625F44D00365EBD /* Default-568h@2x.png */; };\n\t\tF62417E614D52F3C003CE997 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F62417E514D52F3C003CE997 /* UIKit.framework */; };\n\t\tF62417E714D52F3C003CE997 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };\n\t\tF62417EF14D52F3C003CE997 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F62417ED14D52F3C003CE997 /* InfoPlist.strings */; };\n\t\tF62417F114D52F3C003CE997 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F62417F014D52F3C003CE997 /* main.m */; };\n\t\tF62417F514D52F3C003CE997 /* TCAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F62417F414D52F3C003CE997 /* TCAppDelegate.m */; };\n\t\tF62417F814D52F3C003CE997 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F62417F614D52F3C003CE997 /* MainStoryboard.storyboard */; };\n\t\tF62417FB14D52F3C003CE997 /* TCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F62417FA14D52F3C003CE997 /* TCViewController.m */; };\n\t\tF624180114D5300C003CE997 /* TCChatCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F624180014D5300C003CE997 /* TCChatCell.m */; };\n\t\tF624180314D53449003CE997 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };\n\t\tF624180414D53449003CE997 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };\n\t\tF6396B86153E67EC00345B5E /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.m */; };\n\t\tF668C8AA153E92F90044DBAC /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tF6AE45241459071C0022AF3C /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };\n\t\tF6BDA806145900D200FE3253 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B208301450F597009315AF /* Foundation.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t81E8A6A01D4C41DA00916C7E /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F6B208241450F597009315AF /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 2D4227611BB4358C000C1A6C;\n\t\t\tremoteInfo = \"SocketRocket-iOS-Dynamic\";\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t81E8A6A61D4C41E000916C7E /* Embed Frameworks */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tname = \"Embed Frameworks\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t2D4227621BB4358C000C1A6C /* SocketRocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SocketRocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t3345DC901C52ACD70083CCB8 /* SocketRocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SocketRocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t454A02D41D0FAD010060DFB2 /* SRSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRSecurityPolicy.h; path = SocketRocket/SRSecurityPolicy.h; sourceTree = SOURCE_ROOT; };\n\t\t454FEA791D2570D400073768 /* SRPinningSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRPinningSecurityPolicy.h; sourceTree = \"<group>\"; };\n\t\t454FEA7A1D2570D400073768 /* SRPinningSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRPinningSecurityPolicy.m; sourceTree = \"<group>\"; };\n\t\t454FEA831D25717C00073768 /* SRSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRSecurityPolicy.m; sourceTree = \"<group>\"; };\n\t\t4861E7731D022211002FAB1D /* SRProxyConnect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRProxyConnect.h; sourceTree = \"<group>\"; };\n\t\t4861E7741D022211002FAB1D /* SRProxyConnect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRProxyConnect.m; sourceTree = \"<group>\"; };\n\t\t555E0EB11C51E56D00E6BB92 /* SocketRocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketRocket.h; sourceTree = \"<group>\"; };\n\t\t8105E4761CDD679A00AA12DB /* SRTWebSocketOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SRTWebSocketOperation.h; sourceTree = \"<group>\"; };\n\t\t8105E4771CDD679A00AA12DB /* SRTWebSocketOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SRTWebSocketOperation.m; sourceTree = \"<group>\"; };\n\t\t8105E4791CDD679A00AA12DB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t8105E47A1CDD679A00AA12DB /* SRAutobahnTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SRAutobahnTests.m; sourceTree = \"<group>\"; };\n\t\t8105E4AC1CDD6E6200AA12DB /* SRAutobahnOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRAutobahnOperation.h; sourceTree = \"<group>\"; };\n\t\t8105E4AD1CDD6E6200AA12DB /* SRAutobahnOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRAutobahnOperation.m; sourceTree = \"<group>\"; };\n\t\t8105E5271CDD98E100AA12DB /* autobahn_configuration.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = autobahn_configuration.json; sourceTree = \"<group>\"; };\n\t\t8117C4221D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NSURLRequest+SRWebSocketPrivate.h\"; path = \"Internal/NSURLRequest+SRWebSocketPrivate.h\"; sourceTree = \"<group>\"; };\n\t\t8117C42F1D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NSRunLoop+SRWebSocketPrivate.h\"; path = \"Internal/NSRunLoop+SRWebSocketPrivate.h\"; sourceTree = \"<group>\"; };\n\t\t811934B11CDAF711003AB243 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t815FE7241D497D720085FDA5 /* SRConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRConstants.h; path = SocketRocket/Internal/SRConstants.h; sourceTree = SOURCE_ROOT; };\n\t\t815FE7251D497D720085FDA5 /* SRConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRConstants.m; path = SocketRocket/Internal/SRConstants.m; sourceTree = SOURCE_ROOT; };\n\t\t817491A61D1C8C33006E09DF /* SRMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRMutex.h; sourceTree = \"<group>\"; };\n\t\t817491A71D1C8C33006E09DF /* SRMutex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRMutex.m; sourceTree = \"<group>\"; };\n\t\t817995841CE139700084DA37 /* SRDelegateController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRDelegateController.h; sourceTree = \"<group>\"; };\n\t\t817995851CE139700084DA37 /* SRDelegateController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRDelegateController.m; sourceTree = \"<group>\"; };\n\t\t8179967E1CE184F40084DA37 /* SRAutobahnUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRAutobahnUtilities.h; sourceTree = \"<group>\"; };\n\t\t8179967F1CE184F40084DA37 /* SRAutobahnUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRAutobahnUtilities.m; sourceTree = \"<group>\"; };\n\t\t81900A4A1D18C9CC0015A290 /* SRLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRLog.h; sourceTree = \"<group>\"; };\n\t\t81900A4B1D18C9CC0015A290 /* SRLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRLog.m; sourceTree = \"<group>\"; };\n\t\t81AFCD651D4C431C00B3AFC9 /* libicucore.tbd */ = {isa = PBXFileReference; lastKnownFileType = \"sourcecode.text-based-dylib-definition\"; name = libicucore.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/usr/lib/libicucore.tbd; sourceTree = DEVELOPER_DIR; };\n\t\t81B22EC31CE42D7E0073C636 /* SRError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRError.h; sourceTree = \"<group>\"; };\n\t\t81B22EC41CE42D7E0073C636 /* SRError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRError.m; sourceTree = \"<group>\"; };\n\t\t81B22EE21CE43ECC0073C636 /* SRURLUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRURLUtilities.h; sourceTree = \"<group>\"; };\n\t\t81B22EE31CE43ECC0073C636 /* SRURLUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRURLUtilities.m; sourceTree = \"<group>\"; };\n\t\t81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRIOConsumer.h; sourceTree = \"<group>\"; };\n\t\t81B31C101CDC404100D86D43 /* SRIOConsumer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRIOConsumer.m; sourceTree = \"<group>\"; };\n\t\t81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRIOConsumerPool.h; sourceTree = \"<group>\"; };\n\t\t81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRIOConsumerPool.m; sourceTree = \"<group>\"; };\n\t\t81B31C2B1CDC406B00D86D43 /* SRHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRHash.h; sourceTree = \"<group>\"; };\n\t\t81B31C2C1CDC406B00D86D43 /* SRHash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRHash.m; sourceTree = \"<group>\"; };\n\t\t81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRRunLoopThread.h; sourceTree = \"<group>\"; };\n\t\t81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRRunLoopThread.m; sourceTree = \"<group>\"; };\n\t\t81C22BC01D124168007BFDDF /* SRHTTPConnectMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRHTTPConnectMessage.h; sourceTree = \"<group>\"; };\n\t\t81C22BC11D124168007BFDDF /* SRHTTPConnectMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRHTTPConnectMessage.m; sourceTree = \"<group>\"; };\n\t\t81C22BF61D1256E1007BFDDF /* SRRandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRRandom.h; sourceTree = \"<group>\"; };\n\t\t81C22BF71D1256E1007BFDDF /* SRRandom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRRandom.m; sourceTree = \"<group>\"; };\n\t\t81C68CD31D2CBE0A00A1D005 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; };\n\t\t81C68CDE1D2CBE1900A1D005 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; };\n\t\t81C68CF01D2CBE9F00A1D005 /* libicucore.tbd */ = {isa = PBXFileReference; lastKnownFileType = \"sourcecode.text-based-dylib-definition\"; name = libicucore.tbd; path = usr/lib/libicucore.tbd; sourceTree = SDKROOT; };\n\t\t81C68D061D2CBF6A00A1D005 /* libicucore.A.tbd */ = {isa = PBXFileReference; lastKnownFileType = \"sourcecode.text-based-dylib-definition\"; name = libicucore.A.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/usr/lib/libicucore.A.tbd; sourceTree = DEVELOPER_DIR; };\n\t\t81C68D0D1D2CBFA800A1D005 /* libicucore.A.tbd */ = {isa = PBXFileReference; lastKnownFileType = \"sourcecode.text-based-dylib-definition\"; name = libicucore.A.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/libicucore.A.tbd; sourceTree = DEVELOPER_DIR; };\n\t\t81CD05D51CEEC47300497F47 /* NSURLRequest+SRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSURLRequest+SRWebSocket.h\"; sourceTree = \"<group>\"; };\n\t\t81CD05D61CEEC47300497F47 /* NSURLRequest+SRWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSURLRequest+SRWebSocket.m\"; sourceTree = \"<group>\"; };\n\t\t81CD05FB1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSRunLoop+SRWebSocket.h\"; sourceTree = \"<group>\"; };\n\t\t81CD05FC1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSRunLoop+SRWebSocket.m\"; sourceTree = \"<group>\"; };\n\t\t81D6474A1D2CA6A100690609 /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D6474C1D2CA6A100690609 /* iOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = iOS.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D6474D1D2CA6A100690609 /* macOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = macOS.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D6474E1D2CA6A100690609 /* tvOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = tvOS.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D6474F1D2CA6A100690609 /* watchOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = watchOS.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D647511D2CA6A100690609 /* Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Application.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D647521D2CA6A100690609 /* DynamicFramework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DynamicFramework.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D647531D2CA6A100690609 /* LogicTests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = LogicTests.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D647541D2CA6A100690609 /* StaticFramework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = StaticFramework.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D647561D2CA6A100690609 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D647571D2CA6A100690609 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D647581D2CA6A100690609 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = \"<group>\"; };\n\t\t81D647591D2CA6A100690609 /* SocketRocket-iOS-Dynamic.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = \"SocketRocket-iOS-Dynamic.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t81D6475A1D2CA6A100690609 /* SocketRocket-iOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = \"SocketRocket-iOS.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t81D6475B1D2CA6A100690609 /* SocketRocket-macOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = \"SocketRocket-macOS.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t81D6475C1D2CA6A100690609 /* SocketRocket-tvOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = \"SocketRocket-tvOS.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t81D6475D1D2CA6A100690609 /* SocketRocketTests-iOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = \"SocketRocketTests-iOS.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t81E8A69A1D4C417A00916C7E /* TestChat-iOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = \"TestChat-iOS.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tF5391CBC1D2F4B4700606A81 /* SRSIMDHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRSIMDHelpers.h; sourceTree = \"<group>\"; };\n\t\tF5391CBD1D2F4B4700606A81 /* SRSIMDHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRSIMDHelpers.m; sourceTree = \"<group>\"; };\n\t\tF61A0DC71625F44D00365EBD /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = \"Default-568h@2x.png\"; path = \"en.lproj/Default-568h@2x.png\"; sourceTree = \"<group>\"; };\n\t\tF62417E314D52F3C003CE997 /* TestChat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestChat.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tF62417E514D52F3C003CE997 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };\n\t\tF62417EC14D52F3C003CE997 /* TestChat-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = \"TestChat-Info.plist\"; sourceTree = \"<group>\"; };\n\t\tF62417EE14D52F3C003CE997 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\tF62417F014D52F3C003CE997 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = \"<group>\"; };\n\t\tF62417F314D52F3C003CE997 /* TCAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TCAppDelegate.h; sourceTree = \"<group>\"; };\n\t\tF62417F414D52F3C003CE997 /* TCAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TCAppDelegate.m; sourceTree = \"<group>\"; };\n\t\tF62417F714D52F3C003CE997 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = \"<group>\"; };\n\t\tF62417F914D52F3C003CE997 /* TCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TCViewController.h; sourceTree = \"<group>\"; };\n\t\tF62417FA14D52F3C003CE997 /* TCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TCViewController.m; sourceTree = \"<group>\"; };\n\t\tF62417FF14D5300C003CE997 /* TCChatCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCChatCell.h; sourceTree = \"<group>\"; };\n\t\tF624180014D5300C003CE997 /* TCChatCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCChatCell.m; sourceTree = \"<group>\"; };\n\t\tF668C880153E91210044DBAC /* SocketRocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SocketRocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tF6A12CCF145119B700C1D980 /* SRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRWebSocket.h; sourceTree = \"<group>\"; };\n\t\tF6A12CD0145119B700C1D980 /* SRWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRWebSocket.m; sourceTree = \"<group>\"; };\n\t\tF6A12CD3145122FC00C1D980 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };\n\t\tF6A12CD51451231B00C1D980 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };\n\t\tF6B208301450F597009315AF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };\n\t\tF6BDA802145900D200FE3253 /* SocketRocketTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = \"SocketRocketTests-iOS.xctest\"; sourceTree = BUILT_PRODUCTS_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t2D42275E1BB4358C000C1A6C /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81C68D0E1D2CBFA800A1D005 /* libicucore.A.tbd in Frameworks */,\n\t\t\t\t81C68CD41D2CBE0A00A1D005 /* CFNetwork.framework in Frameworks */,\n\t\t\t\t2D4227831BB436B1000C1A6C /* Security.framework in Frameworks */,\n\t\t\t\t2D4227801BB43693000C1A6C /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t3345DC851C52ACD70083CCB8 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81C68D071D2CBF6A00A1D005 /* libicucore.A.tbd in Frameworks */,\n\t\t\t\t81C68CDF1D2CBE1900A1D005 /* CFNetwork.framework in Frameworks */,\n\t\t\t\t3345DC871C52ACD70083CCB8 /* Security.framework in Frameworks */,\n\t\t\t\t3345DC881C52ACD70083CCB8 /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF62417E014D52F3C003CE997 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81AFCD661D4C431C00B3AFC9 /* libicucore.tbd in Frameworks */,\n\t\t\t\tF62417E614D52F3C003CE997 /* UIKit.framework in Frameworks */,\n\t\t\t\tF62417E714D52F3C003CE997 /* Foundation.framework in Frameworks */,\n\t\t\t\tF624180314D53449003CE997 /* CFNetwork.framework in Frameworks */,\n\t\t\t\tF624180414D53449003CE997 /* Security.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF668C87C153E91210044DBAC /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81C68CEE1D2CBE9400A1D005 /* CFNetwork.framework in Frameworks */,\n\t\t\t\t81C68CF61D2CBED100A1D005 /* Security.framework in Frameworks */,\n\t\t\t\t81C68CF11D2CBE9F00A1D005 /* libicucore.tbd in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF6BDA7FE145900D200FE3253 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF6BDA806145900D200FE3253 /* Foundation.framework in Frameworks */,\n\t\t\t\tF6AE45241459071C0022AF3C /* CFNetwork.framework in Frameworks */,\n\t\t\t\tF6016C8814620EC70037BB3D /* Security.framework in Frameworks */,\n\t\t\t\t81DCD1241D2D9235002501A2 /* libicucore.A.tbd in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t4861E7721D022211002FAB1D /* Proxy */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4861E7731D022211002FAB1D /* SRProxyConnect.h */,\n\t\t\t\t4861E7741D022211002FAB1D /* SRProxyConnect.m */,\n\t\t\t);\n\t\t\tpath = Proxy;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8105E4741CDD679A00AA12DB /* Tests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8105E47A1CDD679A00AA12DB /* SRAutobahnTests.m */,\n\t\t\t\t8105E4751CDD679A00AA12DB /* Operations */,\n\t\t\t\t8105E47C1CDD679A00AA12DB /* Utilities */,\n\t\t\t\t8105E4781CDD679A00AA12DB /* Resources */,\n\t\t\t);\n\t\t\tpath = Tests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8105E4751CDD679A00AA12DB /* Operations */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8105E4761CDD679A00AA12DB /* SRTWebSocketOperation.h */,\n\t\t\t\t8105E4771CDD679A00AA12DB /* SRTWebSocketOperation.m */,\n\t\t\t\t8105E4AC1CDD6E6200AA12DB /* SRAutobahnOperation.h */,\n\t\t\t\t8105E4AD1CDD6E6200AA12DB /* SRAutobahnOperation.m */,\n\t\t\t);\n\t\t\tpath = Operations;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8105E4781CDD679A00AA12DB /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8105E5271CDD98E100AA12DB /* autobahn_configuration.json */,\n\t\t\t\t8105E4791CDD679A00AA12DB /* Info.plist */,\n\t\t\t);\n\t\t\tpath = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8105E47C1CDD679A00AA12DB /* Utilities */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8179967E1CE184F40084DA37 /* SRAutobahnUtilities.h */,\n\t\t\t\t8179967F1CE184F40084DA37 /* SRAutobahnUtilities.m */,\n\t\t\t);\n\t\t\tpath = Utilities;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t811934B01CDAF711003AB243 /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t811934B11CDAF711003AB243 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t817995831CE139540084DA37 /* Delegate */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t817995841CE139700084DA37 /* SRDelegateController.h */,\n\t\t\t\t817995851CE139700084DA37 /* SRDelegateController.m */,\n\t\t\t);\n\t\t\tpath = Delegate;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8186892C1D08EF3C004F94C8 /* Security */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t454FEA791D2570D400073768 /* SRPinningSecurityPolicy.h */,\n\t\t\t\t454FEA7A1D2570D400073768 /* SRPinningSecurityPolicy.m */,\n\t\t\t);\n\t\t\tpath = Security;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81B31C0D1CDC404100D86D43 /* Internal */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8186892C1D08EF3C004F94C8 /* Security */,\n\t\t\t\t4861E7721D022211002FAB1D /* Proxy */,\n\t\t\t\t817995831CE139540084DA37 /* Delegate */,\n\t\t\t\t81B31C0E1CDC404100D86D43 /* IOConsumer */,\n\t\t\t\t81B31C5C1CDC443A00D86D43 /* RunLoop */,\n\t\t\t\t81B31C131CDC404100D86D43 /* Utilities */,\n\t\t\t);\n\t\t\tpath = Internal;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81B31C0E1CDC404100D86D43 /* IOConsumer */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81B31C0F1CDC404100D86D43 /* SRIOConsumer.h */,\n\t\t\t\t81B31C101CDC404100D86D43 /* SRIOConsumer.m */,\n\t\t\t\t81B31C111CDC404100D86D43 /* SRIOConsumerPool.h */,\n\t\t\t\t81B31C121CDC404100D86D43 /* SRIOConsumerPool.m */,\n\t\t\t);\n\t\t\tpath = IOConsumer;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81B31C131CDC404100D86D43 /* Utilities */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81B22EC31CE42D7E0073C636 /* SRError.h */,\n\t\t\t\t81B22EC41CE42D7E0073C636 /* SRError.m */,\n\t\t\t\t81B31C2B1CDC406B00D86D43 /* SRHash.h */,\n\t\t\t\t81B31C2C1CDC406B00D86D43 /* SRHash.m */,\n\t\t\t\t81C22BC01D124168007BFDDF /* SRHTTPConnectMessage.h */,\n\t\t\t\t81C22BC11D124168007BFDDF /* SRHTTPConnectMessage.m */,\n\t\t\t\t81900A4A1D18C9CC0015A290 /* SRLog.h */,\n\t\t\t\t81900A4B1D18C9CC0015A290 /* SRLog.m */,\n\t\t\t\t817491A61D1C8C33006E09DF /* SRMutex.h */,\n\t\t\t\t817491A71D1C8C33006E09DF /* SRMutex.m */,\n\t\t\t\t81C22BF61D1256E1007BFDDF /* SRRandom.h */,\n\t\t\t\t81C22BF71D1256E1007BFDDF /* SRRandom.m */,\n\t\t\t\t815FE7241D497D720085FDA5 /* SRConstants.h */,\n\t\t\t\t815FE7251D497D720085FDA5 /* SRConstants.m */,\n\t\t\t\t81B22EE21CE43ECC0073C636 /* SRURLUtilities.h */,\n\t\t\t\t81B22EE31CE43ECC0073C636 /* SRURLUtilities.m */,\n\t\t\t\tF5391CBC1D2F4B4700606A81 /* SRSIMDHelpers.h */,\n\t\t\t\tF5391CBD1D2F4B4700606A81 /* SRSIMDHelpers.m */,\n\t\t\t);\n\t\t\tpath = Utilities;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81B31C5C1CDC443A00D86D43 /* RunLoop */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81B31C5D1CDC444900D86D43 /* SRRunLoopThread.h */,\n\t\t\t\t81B31C5E1CDC444900D86D43 /* SRRunLoopThread.m */,\n\t\t\t);\n\t\t\tname = RunLoop;\n\t\t\tpath = SocketRocket/Internal/RunLoop;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t81C68CF41D2CBEBD00A1D005 /* macOS */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF6B208301450F597009315AF /* Foundation.framework */,\n\t\t\t\tF6A12CD3145122FC00C1D980 /* Security.framework */,\n\t\t\t\tF6A12CD51451231B00C1D980 /* CFNetwork.framework */,\n\t\t\t\t81C68CF01D2CBE9F00A1D005 /* libicucore.tbd */,\n\t\t\t);\n\t\t\tname = macOS;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81C68CFD1D2CBF1800A1D005 /* tvOS */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81C68CDE1D2CBE1900A1D005 /* CFNetwork.framework */,\n\t\t\t\t81C68D061D2CBF6A00A1D005 /* libicucore.A.tbd */,\n\t\t\t);\n\t\t\tname = tvOS;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81C68CFE1D2CBF2100A1D005 /* iOS */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF62417E514D52F3C003CE997 /* UIKit.framework */,\n\t\t\t\t81C68CD31D2CBE0A00A1D005 /* CFNetwork.framework */,\n\t\t\t\t81C68D0D1D2CBFA800A1D005 /* libicucore.A.tbd */,\n\t\t\t);\n\t\t\tname = iOS;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81D647481D2CA6A100690609 /* Configurations */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81D6475A1D2CA6A100690609 /* SocketRocket-iOS.xcconfig */,\n\t\t\t\t81D647591D2CA6A100690609 /* SocketRocket-iOS-Dynamic.xcconfig */,\n\t\t\t\t81D6475B1D2CA6A100690609 /* SocketRocket-macOS.xcconfig */,\n\t\t\t\t81D6475C1D2CA6A100690609 /* SocketRocket-tvOS.xcconfig */,\n\t\t\t\t81D6475D1D2CA6A100690609 /* SocketRocketTests-iOS.xcconfig */,\n\t\t\t\t81E8A69A1D4C417A00916C7E /* TestChat-iOS.xcconfig */,\n\t\t\t\t81D647491D2CA6A100690609 /* Shared */,\n\t\t\t);\n\t\t\tpath = Configurations;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81D647491D2CA6A100690609 /* Shared */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81D6474A1D2CA6A100690609 /* Common.xcconfig */,\n\t\t\t\t81D6474B1D2CA6A100690609 /* Platform */,\n\t\t\t\t81D647501D2CA6A100690609 /* Product */,\n\t\t\t\t81D647551D2CA6A100690609 /* Project */,\n\t\t\t\t81D647581D2CA6A100690609 /* Warnings.xcconfig */,\n\t\t\t);\n\t\t\tpath = Shared;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81D6474B1D2CA6A100690609 /* Platform */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81D6474C1D2CA6A100690609 /* iOS.xcconfig */,\n\t\t\t\t81D6474D1D2CA6A100690609 /* macOS.xcconfig */,\n\t\t\t\t81D6474E1D2CA6A100690609 /* tvOS.xcconfig */,\n\t\t\t\t81D6474F1D2CA6A100690609 /* watchOS.xcconfig */,\n\t\t\t);\n\t\t\tpath = Platform;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81D647501D2CA6A100690609 /* Product */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81D647511D2CA6A100690609 /* Application.xcconfig */,\n\t\t\t\t81D647521D2CA6A100690609 /* DynamicFramework.xcconfig */,\n\t\t\t\t81D647531D2CA6A100690609 /* LogicTests.xcconfig */,\n\t\t\t\t81D647541D2CA6A100690609 /* StaticFramework.xcconfig */,\n\t\t\t);\n\t\t\tpath = Product;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t81D647551D2CA6A100690609 /* Project */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81D647561D2CA6A100690609 /* Debug.xcconfig */,\n\t\t\t\t81D647571D2CA6A100690609 /* Release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Project;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF62417EA14D52F3C003CE997 /* TestChat */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF62417EB14D52F3C003CE997 /* Supporting Files */,\n\t\t\t\tF62417F314D52F3C003CE997 /* TCAppDelegate.h */,\n\t\t\t\tF62417F414D52F3C003CE997 /* TCAppDelegate.m */,\n\t\t\t\tF62417F614D52F3C003CE997 /* MainStoryboard.storyboard */,\n\t\t\t\tF62417F914D52F3C003CE997 /* TCViewController.h */,\n\t\t\t\tF62417FA14D52F3C003CE997 /* TCViewController.m */,\n\t\t\t\tF62417FF14D5300C003CE997 /* TCChatCell.h */,\n\t\t\t\tF624180014D5300C003CE997 /* TCChatCell.m */,\n\t\t\t);\n\t\t\tpath = TestChat;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF62417EB14D52F3C003CE997 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF61A0DC71625F44D00365EBD /* Default-568h@2x.png */,\n\t\t\t\tF62417EC14D52F3C003CE997 /* TestChat-Info.plist */,\n\t\t\t\tF62417ED14D52F3C003CE997 /* InfoPlist.strings */,\n\t\t\t\tF62417F014D52F3C003CE997 /* main.m */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF6B208221450F597009315AF = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81D647481D2CA6A100690609 /* Configurations */,\n\t\t\t\tF6B208321450F597009315AF /* SocketRocket */,\n\t\t\t\t8105E4741CDD679A00AA12DB /* Tests */,\n\t\t\t\tF62417EA14D52F3C003CE997 /* TestChat */,\n\t\t\t\tF6B2082F1450F597009315AF /* Frameworks */,\n\t\t\t\tF6B2082E1450F597009315AF /* Products */,\n\t\t\t);\n\t\t\tindentWidth = 4;\n\t\t\tsourceTree = \"<group>\";\n\t\t\ttabWidth = 4;\n\t\t};\n\t\tF6B2082E1450F597009315AF /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF6BDA802145900D200FE3253 /* SocketRocketTests-iOS.xctest */,\n\t\t\t\tF62417E314D52F3C003CE997 /* TestChat.app */,\n\t\t\t\tF668C880153E91210044DBAC /* SocketRocket.framework */,\n\t\t\t\t2D4227621BB4358C000C1A6C /* SocketRocket.framework */,\n\t\t\t\t3345DC901C52ACD70083CCB8 /* SocketRocket.framework */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF6B2082F1450F597009315AF /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81AFCD651D4C431C00B3AFC9 /* libicucore.tbd */,\n\t\t\t\t81C68CF41D2CBEBD00A1D005 /* macOS */,\n\t\t\t\t81C68CFD1D2CBF1800A1D005 /* tvOS */,\n\t\t\t\t81C68CFE1D2CBF2100A1D005 /* iOS */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF6B208321450F597009315AF /* SocketRocket */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t81B31C0D1CDC404100D86D43 /* Internal */,\n\t\t\t\t555E0EB11C51E56D00E6BB92 /* SocketRocket.h */,\n\t\t\t\t454A02D41D0FAD010060DFB2 /* SRSecurityPolicy.h */,\n\t\t\t\t454FEA831D25717C00073768 /* SRSecurityPolicy.m */,\n\t\t\t\tF6A12CCF145119B700C1D980 /* SRWebSocket.h */,\n\t\t\t\tF6A12CD0145119B700C1D980 /* SRWebSocket.m */,\n\t\t\t\t81CD05D51CEEC47300497F47 /* NSURLRequest+SRWebSocket.h */,\n\t\t\t\t8117C4221D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h */,\n\t\t\t\t81CD05D61CEEC47300497F47 /* NSURLRequest+SRWebSocket.m */,\n\t\t\t\t81CD05FB1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h */,\n\t\t\t\t8117C42F1D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h */,\n\t\t\t\t81CD05FC1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m */,\n\t\t\t\t811934B01CDAF711003AB243 /* Resources */,\n\t\t\t);\n\t\t\tpath = SocketRocket;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\t2D42275F1BB4358C000C1A6C /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81B22EE51CE43ECC0073C636 /* SRURLUtilities.h in Headers */,\n\t\t\t\t454FEA7F1D2570F800073768 /* SRPinningSecurityPolicy.h in Headers */,\n\t\t\t\t81B31C151CDC404100D86D43 /* SRIOConsumer.h in Headers */,\n\t\t\t\t8117C4241D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h in Headers */,\n\t\t\t\t81CD05FE1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h in Headers */,\n\t\t\t\t815FE7271D497D720085FDA5 /* SRConstants.h in Headers */,\n\t\t\t\t454A02D61D0FAD010060DFB2 /* SRSecurityPolicy.h in Headers */,\n\t\t\t\t81CD05D81CEEC47300497F47 /* NSURLRequest+SRWebSocket.h in Headers */,\n\t\t\t\t81900A4D1D18C9CC0015A290 /* SRLog.h in Headers */,\n\t\t\t\t81B31C1D1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */,\n\t\t\t\t813364001D091E170062E28D /* SRProxyConnect.h in Headers */,\n\t\t\t\t2D42277F1BB4365C000C1A6C /* SRWebSocket.h in Headers */,\n\t\t\t\t81B31C2E1CDC406B00D86D43 /* SRHash.h in Headers */,\n\t\t\t\t811934BE1CDAF725003AB243 /* SocketRocket.h in Headers */,\n\t\t\t\t81C22BF91D1256E1007BFDDF /* SRRandom.h in Headers */,\n\t\t\t\t8117C4311D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h in Headers */,\n\t\t\t\t81C22BC31D124168007BFDDF /* SRHTTPConnectMessage.h in Headers */,\n\t\t\t\t817995871CE139700084DA37 /* SRDelegateController.h in Headers */,\n\t\t\t\t817491A91D1C8C33006E09DF /* SRMutex.h in Headers */,\n\t\t\t\t81B22EC61CE42D7E0073C636 /* SRError.h in Headers */,\n\t\t\t\t81B31C601CDC444900D86D43 /* SRRunLoopThread.h in Headers */,\n\t\t\t\tF5391CBF1D2F4B4700606A81 /* SRSIMDHelpers.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t3345DC891C52ACD70083CCB8 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81B22EE71CE43ECC0073C636 /* SRURLUtilities.h in Headers */,\n\t\t\t\t454FEA811D2570F900073768 /* SRPinningSecurityPolicy.h in Headers */,\n\t\t\t\t81B31C171CDC404100D86D43 /* SRIOConsumer.h in Headers */,\n\t\t\t\t8117C4261D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h in Headers */,\n\t\t\t\t81CD06001CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h in Headers */,\n\t\t\t\t815FE7291D497D720085FDA5 /* SRConstants.h in Headers */,\n\t\t\t\t454A02D81D0FAD010060DFB2 /* SRSecurityPolicy.h in Headers */,\n\t\t\t\t81CD05DA1CEEC47300497F47 /* NSURLRequest+SRWebSocket.h in Headers */,\n\t\t\t\t81900A4F1D18C9CC0015A290 /* SRLog.h in Headers */,\n\t\t\t\t81B31C1F1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */,\n\t\t\t\t813364081D091E180062E28D /* SRProxyConnect.h in Headers */,\n\t\t\t\t3345DC8A1C52ACD70083CCB8 /* SRWebSocket.h in Headers */,\n\t\t\t\t81B31C301CDC406B00D86D43 /* SRHash.h in Headers */,\n\t\t\t\t811934C01CDAF726003AB243 /* SocketRocket.h in Headers */,\n\t\t\t\t81C22BFB1D1256E1007BFDDF /* SRRandom.h in Headers */,\n\t\t\t\t8117C4331D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h in Headers */,\n\t\t\t\t81C22BC51D124168007BFDDF /* SRHTTPConnectMessage.h in Headers */,\n\t\t\t\t817995891CE139700084DA37 /* SRDelegateController.h in Headers */,\n\t\t\t\t817491AB1D1C8C33006E09DF /* SRMutex.h in Headers */,\n\t\t\t\t81B22EC81CE42D7E0073C636 /* SRError.h in Headers */,\n\t\t\t\t81B31C621CDC444900D86D43 /* SRRunLoopThread.h in Headers */,\n\t\t\t\tF5391CC11D2F4B4700606A81 /* SRSIMDHelpers.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF668C87D153E91210044DBAC /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81B22EE61CE43ECC0073C636 /* SRURLUtilities.h in Headers */,\n\t\t\t\t454FEA7D1D2570F600073768 /* SRPinningSecurityPolicy.h in Headers */,\n\t\t\t\t81B31C161CDC404100D86D43 /* SRIOConsumer.h in Headers */,\n\t\t\t\t8117C4251D3076DF00784D79 /* NSURLRequest+SRWebSocketPrivate.h in Headers */,\n\t\t\t\t81CD05FF1CEEC65D00497F47 /* NSRunLoop+SRWebSocket.h in Headers */,\n\t\t\t\t815FE7281D497D720085FDA5 /* SRConstants.h in Headers */,\n\t\t\t\t454A02D71D0FAD010060DFB2 /* SRSecurityPolicy.h in Headers */,\n\t\t\t\t81CD05D91CEEC47300497F47 /* NSURLRequest+SRWebSocket.h in Headers */,\n\t\t\t\t81900A4E1D18C9CC0015A290 /* SRLog.h in Headers */,\n\t\t\t\t81B31C1E1CDC404100D86D43 /* SRIOConsumerPool.h in Headers */,\n\t\t\t\t813364041D091E170062E28D /* SRProxyConnect.h in Headers */,\n\t\t\t\tF668C8AA153E92F90044DBAC /* SRWebSocket.h in Headers */,\n\t\t\t\t81B31C2F1CDC406B00D86D43 /* SRHash.h in Headers */,\n\t\t\t\t811934BC1CDAF725003AB243 /* SocketRocket.h in Headers */,\n\t\t\t\t81C22BFA1D1256E1007BFDDF /* SRRandom.h in Headers */,\n\t\t\t\t8117C4321D30779900784D79 /* NSRunLoop+SRWebSocketPrivate.h in Headers */,\n\t\t\t\t81C22BC41D124168007BFDDF /* SRHTTPConnectMessage.h in Headers */,\n\t\t\t\t817995881CE139700084DA37 /* SRDelegateController.h in Headers */,\n\t\t\t\t817491AA1D1C8C33006E09DF /* SRMutex.h in Headers */,\n\t\t\t\t81B22EC71CE42D7E0073C636 /* SRError.h in Headers */,\n\t\t\t\t81B31C611CDC444900D86D43 /* SRRunLoopThread.h in Headers */,\n\t\t\t\tF5391CC01D2F4B4700606A81 /* SRSIMDHelpers.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\t2D4227611BB4358C000C1A6C /* SocketRocket-iOS-Dynamic */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2D4227671BB4358C000C1A6C /* Build configuration list for PBXNativeTarget \"SocketRocket-iOS-Dynamic\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t2D42275D1BB4358C000C1A6C /* Sources */,\n\t\t\t\t2D42275E1BB4358C000C1A6C /* Frameworks */,\n\t\t\t\t2D42275F1BB4358C000C1A6C /* Headers */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"SocketRocket-iOS-Dynamic\";\n\t\t\tproductName = \"SocketRocket-iOS\";\n\t\t\tproductReference = 2D4227621BB4358C000C1A6C /* SocketRocket.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t3345DC821C52ACD70083CCB8 /* SocketRocket-tvOS */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 3345DC8D1C52ACD70083CCB8 /* Build configuration list for PBXNativeTarget \"SocketRocket-tvOS\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t3345DC831C52ACD70083CCB8 /* Sources */,\n\t\t\t\t3345DC851C52ACD70083CCB8 /* Frameworks */,\n\t\t\t\t3345DC891C52ACD70083CCB8 /* Headers */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"SocketRocket-tvOS\";\n\t\t\tproductName = \"SocketRocket-iOS\";\n\t\t\tproductReference = 3345DC901C52ACD70083CCB8 /* SocketRocket.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\tF62417E214D52F3C003CE997 /* TestChat */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = F62417FC14D52F3C003CE997 /* Build configuration list for PBXNativeTarget \"TestChat\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tF62417DF14D52F3C003CE997 /* Sources */,\n\t\t\t\tF62417E014D52F3C003CE997 /* Frameworks */,\n\t\t\t\tF62417E114D52F3C003CE997 /* Resources */,\n\t\t\t\t81E8A6A61D4C41E000916C7E /* Embed Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t81E8A6A11D4C41DA00916C7E /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = TestChat;\n\t\t\tproductName = TestChat;\n\t\t\tproductReference = F62417E314D52F3C003CE997 /* TestChat.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\tF668C87F153E91210044DBAC /* SocketRocket-macOS */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = F668C891153E91210044DBAC /* Build configuration list for PBXNativeTarget \"SocketRocket-macOS\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tF6396B85153E67EC00345B5E /* Sources */,\n\t\t\t\tF668C87C153E91210044DBAC /* Frameworks */,\n\t\t\t\tF668C87D153E91210044DBAC /* Headers */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"SocketRocket-macOS\";\n\t\t\tproductName = SocketRocketOSX;\n\t\t\tproductReference = F668C880153E91210044DBAC /* SocketRocket.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\tF6BDA801145900D200FE3253 /* SocketRocketTests-iOS */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = F6BDA813145900D200FE3253 /* Build configuration list for PBXNativeTarget \"SocketRocketTests-iOS\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tF6BDA7FD145900D200FE3253 /* Sources */,\n\t\t\t\tF6BDA7FE145900D200FE3253 /* Frameworks */,\n\t\t\t\tF6BDA7FF145900D200FE3253 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"SocketRocketTests-iOS\";\n\t\t\tproductName = SRWebSocketTests;\n\t\t\tproductReference = F6BDA802145900D200FE3253 /* SocketRocketTests-iOS.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tF6B208241450F597009315AF /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastTestingUpgradeCheck = 0640;\n\t\t\t\tLastUpgradeCheck = 0800;\n\t\t\t};\n\t\t\tbuildConfigurationList = F6B208271450F597009315AF /* Build configuration list for PBXProject \"SocketRocket\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\tEnglish,\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = F6B208221450F597009315AF;\n\t\t\tproductRefGroup = F6B2082E1450F597009315AF /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t2D4227611BB4358C000C1A6C /* SocketRocket-iOS-Dynamic */,\n\t\t\t\tF668C87F153E91210044DBAC /* SocketRocket-macOS */,\n\t\t\t\t3345DC821C52ACD70083CCB8 /* SocketRocket-tvOS */,\n\t\t\t\tF6BDA801145900D200FE3253 /* SocketRocketTests-iOS */,\n\t\t\t\tF62417E214D52F3C003CE997 /* TestChat */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tF62417E114D52F3C003CE997 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF62417EF14D52F3C003CE997 /* InfoPlist.strings in Resources */,\n\t\t\t\tF62417F814D52F3C003CE997 /* MainStoryboard.storyboard in Resources */,\n\t\t\t\tF61A0DC81625F44D00365EBD /* Default-568h@2x.png in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF6BDA7FF145900D200FE3253 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8105E5281CDD98E100AA12DB /* autobahn_configuration.json in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t2D42275D1BB4358C000C1A6C /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81CD05DC1CEEC47300497F47 /* NSURLRequest+SRWebSocket.m in Sources */,\n\t\t\t\tF5391CC31D2F4B4700606A81 /* SRSIMDHelpers.m in Sources */,\n\t\t\t\t81B22ECA1CE42D7E0073C636 /* SRError.m in Sources */,\n\t\t\t\t81B31C191CDC404100D86D43 /* SRIOConsumer.m in Sources */,\n\t\t\t\t81C22BC71D124168007BFDDF /* SRHTTPConnectMessage.m in Sources */,\n\t\t\t\t454FEA801D2570F800073768 /* SRPinningSecurityPolicy.m in Sources */,\n\t\t\t\t454FEA851D25719900073768 /* SRSecurityPolicy.m in Sources */,\n\t\t\t\t815FE72B1D497D720085FDA5 /* SRConstants.m in Sources */,\n\t\t\t\t81CD06021CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m in Sources */,\n\t\t\t\t2D4227851BB43734000C1A6C /* SRWebSocket.m in Sources */,\n\t\t\t\t81C22BFD1D1256E1007BFDDF /* SRRandom.m in Sources */,\n\t\t\t\t81B31C211CDC404100D86D43 /* SRIOConsumerPool.m in Sources */,\n\t\t\t\t81B22EE91CE43ECC0073C636 /* SRURLUtilities.m in Sources */,\n\t\t\t\t8133640C1D091E1B0062E28D /* SRProxyConnect.m in Sources */,\n\t\t\t\t817491AD1D1C8C33006E09DF /* SRMutex.m in Sources */,\n\t\t\t\t81B31C641CDC444900D86D43 /* SRRunLoopThread.m in Sources */,\n\t\t\t\t81900A511D18C9CC0015A290 /* SRLog.m in Sources */,\n\t\t\t\t81B31C321CDC406B00D86D43 /* SRHash.m in Sources */,\n\t\t\t\t8179958B1CE139700084DA37 /* SRDelegateController.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t3345DC831C52ACD70083CCB8 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81CD05DE1CEEC47300497F47 /* NSURLRequest+SRWebSocket.m in Sources */,\n\t\t\t\tF5391CC51D2F4B4700606A81 /* SRSIMDHelpers.m in Sources */,\n\t\t\t\t81B22ECC1CE42D7E0073C636 /* SRError.m in Sources */,\n\t\t\t\t81B31C1B1CDC404100D86D43 /* SRIOConsumer.m in Sources */,\n\t\t\t\t81C22BC91D124168007BFDDF /* SRHTTPConnectMessage.m in Sources */,\n\t\t\t\t454FEA821D2570F900073768 /* SRPinningSecurityPolicy.m in Sources */,\n\t\t\t\t454FEA871D25719A00073768 /* SRSecurityPolicy.m in Sources */,\n\t\t\t\t815FE72D1D497D720085FDA5 /* SRConstants.m in Sources */,\n\t\t\t\t81CD06041CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m in Sources */,\n\t\t\t\t3345DC841C52ACD70083CCB8 /* SRWebSocket.m in Sources */,\n\t\t\t\t81C22BFF1D1256E1007BFDDF /* SRRandom.m in Sources */,\n\t\t\t\t81B31C231CDC404100D86D43 /* SRIOConsumerPool.m in Sources */,\n\t\t\t\t81B22EEB1CE43ECC0073C636 /* SRURLUtilities.m in Sources */,\n\t\t\t\t8133640F1D091E1C0062E28D /* SRProxyConnect.m in Sources */,\n\t\t\t\t817491AF1D1C8C33006E09DF /* SRMutex.m in Sources */,\n\t\t\t\t81B31C661CDC444900D86D43 /* SRRunLoopThread.m in Sources */,\n\t\t\t\t81900A531D18C9CC0015A290 /* SRLog.m in Sources */,\n\t\t\t\t81B31C341CDC406B00D86D43 /* SRHash.m in Sources */,\n\t\t\t\t8179958D1CE139700084DA37 /* SRDelegateController.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF62417DF14D52F3C003CE997 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF62417F114D52F3C003CE997 /* main.m in Sources */,\n\t\t\t\tF62417F514D52F3C003CE997 /* TCAppDelegate.m in Sources */,\n\t\t\t\tF62417FB14D52F3C003CE997 /* TCViewController.m in Sources */,\n\t\t\t\tF624180114D5300C003CE997 /* TCChatCell.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF6396B85153E67EC00345B5E /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t81CD05DD1CEEC47300497F47 /* NSURLRequest+SRWebSocket.m in Sources */,\n\t\t\t\tF5391CC41D2F4B4700606A81 /* SRSIMDHelpers.m in Sources */,\n\t\t\t\t81B22ECB1CE42D7E0073C636 /* SRError.m in Sources */,\n\t\t\t\t81B31C1A1CDC404100D86D43 /* SRIOConsumer.m in Sources */,\n\t\t\t\t81C22BC81D124168007BFDDF /* SRHTTPConnectMessage.m in Sources */,\n\t\t\t\t454FEA7E1D2570F600073768 /* SRPinningSecurityPolicy.m in Sources */,\n\t\t\t\t454FEA861D25719A00073768 /* SRSecurityPolicy.m in Sources */,\n\t\t\t\t815FE72C1D497D720085FDA5 /* SRConstants.m in Sources */,\n\t\t\t\t81CD06031CEEC65D00497F47 /* NSRunLoop+SRWebSocket.m in Sources */,\n\t\t\t\tF6396B86153E67EC00345B5E /* SRWebSocket.m in Sources */,\n\t\t\t\t81C22BFE1D1256E1007BFDDF /* SRRandom.m in Sources */,\n\t\t\t\t81B31C221CDC404100D86D43 /* SRIOConsumerPool.m in Sources */,\n\t\t\t\t81B22EEA1CE43ECC0073C636 /* SRURLUtilities.m in Sources */,\n\t\t\t\t8133640E1D091E1B0062E28D /* SRProxyConnect.m in Sources */,\n\t\t\t\t817491AE1D1C8C33006E09DF /* SRMutex.m in Sources */,\n\t\t\t\t81B31C651CDC444900D86D43 /* SRRunLoopThread.m in Sources */,\n\t\t\t\t81900A521D18C9CC0015A290 /* SRLog.m in Sources */,\n\t\t\t\t81B31C331CDC406B00D86D43 /* SRHash.m in Sources */,\n\t\t\t\t8179958C1CE139700084DA37 /* SRDelegateController.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF6BDA7FD145900D200FE3253 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8105E4AE1CDD6E6200AA12DB /* SRAutobahnOperation.m in Sources */,\n\t\t\t\t817996801CE184F40084DA37 /* SRAutobahnUtilities.m in Sources */,\n\t\t\t\t8105E4801CDD67B400AA12DB /* SRAutobahnTests.m in Sources */,\n\t\t\t\t8105E4821CDD67BD00AA12DB /* SRTWebSocketOperation.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t81E8A6A11D4C41DA00916C7E /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 2D4227611BB4358C000C1A6C /* SocketRocket-iOS-Dynamic */;\n\t\t\ttargetProxy = 81E8A6A01D4C41DA00916C7E /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\tF62417ED14D52F3C003CE997 /* InfoPlist.strings */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tF62417EE14D52F3C003CE997 /* en */,\n\t\t\t);\n\t\t\tname = InfoPlist.strings;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF62417F614D52F3C003CE997 /* MainStoryboard.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tF62417F714D52F3C003CE997 /* en */,\n\t\t\t);\n\t\t\tname = MainStoryboard.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t2D4227681BB4358C000C1A6C /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D647591D2CA6A100690609 /* SocketRocket-iOS-Dynamic.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2D4227691BB4358C000C1A6C /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D647591D2CA6A100690609 /* SocketRocket-iOS-Dynamic.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t3345DC8E1C52ACD70083CCB8 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D6475C1D2CA6A100690609 /* SocketRocket-tvOS.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t3345DC8F1C52ACD70083CCB8 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D6475C1D2CA6A100690609 /* SocketRocket-tvOS.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tF62417FD14D52F3C003CE997 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81E8A69A1D4C417A00916C7E /* TestChat-iOS.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF62417FE14D52F3C003CE997 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81E8A69A1D4C417A00916C7E /* TestChat-iOS.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tF668C892153E91210044DBAC /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D6475B1D2CA6A100690609 /* SocketRocket-macOS.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF668C893153E91210044DBAC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D6475B1D2CA6A100690609 /* SocketRocket-macOS.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tF6B208381450F597009315AF /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D647561D2CA6A100690609 /* Debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF6B208391450F597009315AF /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D647571D2CA6A100690609 /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tF6BDA811145900D200FE3253 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D6475D1D2CA6A100690609 /* SocketRocketTests-iOS.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF6BDA812145900D200FE3253 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81D6475D1D2CA6A100690609 /* SocketRocketTests-iOS.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t2D4227671BB4358C000C1A6C /* Build configuration list for PBXNativeTarget \"SocketRocket-iOS-Dynamic\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2D4227681BB4358C000C1A6C /* Debug */,\n\t\t\t\t2D4227691BB4358C000C1A6C /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t3345DC8D1C52ACD70083CCB8 /* Build configuration list for PBXNativeTarget \"SocketRocket-tvOS\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t3345DC8E1C52ACD70083CCB8 /* Debug */,\n\t\t\t\t3345DC8F1C52ACD70083CCB8 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tF62417FC14D52F3C003CE997 /* Build configuration list for PBXNativeTarget \"TestChat\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF62417FD14D52F3C003CE997 /* Debug */,\n\t\t\t\tF62417FE14D52F3C003CE997 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tF668C891153E91210044DBAC /* Build configuration list for PBXNativeTarget \"SocketRocket-macOS\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF668C892153E91210044DBAC /* Debug */,\n\t\t\t\tF668C893153E91210044DBAC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tF6B208271450F597009315AF /* Build configuration list for PBXProject \"SocketRocket\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF6B208381450F597009315AF /* Debug */,\n\t\t\t\tF6B208391450F597009315AF /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tF6BDA813145900D200FE3253 /* Build configuration list for PBXNativeTarget \"SocketRocketTests-iOS\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF6BDA811145900D200FE3253 /* Debug */,\n\t\t\t\tF6BDA812145900D200FE3253 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = F6B208241450F597009315AF /* Project object */;\n}\n"
  },
  {
    "path": "SocketRocket.xcodeproj/xcshareddata/xcschemes/SocketRocket-iOS-Dynamic.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1250\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2D4227611BB4358C000C1A6C\"\n               BuildableName = \"SocketRocket.framework\"\n               BlueprintName = \"SocketRocket-iOS-Dynamic\"\n               ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"2D4227611BB4358C000C1A6C\"\n            BuildableName = \"SocketRocket.framework\"\n            BlueprintName = \"SocketRocket-iOS-Dynamic\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"2D4227611BB4358C000C1A6C\"\n            BuildableName = \"SocketRocket.framework\"\n            BlueprintName = \"SocketRocket-iOS-Dynamic\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "SocketRocket.xcodeproj/xcshareddata/xcschemes/SocketRocket-iOS.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1250\"\n   version = \"1.7\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"81D6475F1D2CA78800690609\"\n               BuildableName = \"SocketRocket.framework\"\n               BlueprintName = \"SocketRocket-iOS\"\n               ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"NO\"\n            buildForProfiling = \"NO\"\n            buildForArchiving = \"NO\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"F6BDA801145900D200FE3253\"\n               BuildableName = \"SocketRocketTests-iOS.xctest\"\n               BlueprintName = \"SocketRocketTests-iOS\"\n               ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <PreActions>\n         <ExecutionAction\n            ActionType = \"Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction\">\n            <ActionContent\n               title = \"Run Script\"\n               scriptText = \"PIDFILE=$TMPDIR/sr_test_server.pid&#10;&#10;if [ -r $PIDFILE ]; then&#10;EXISTING_PID=`cat $PIDFILE`&#10;echo &quot;Killing Dangling Autobahn Server PID:&quot; $EXISTING_PID&#10;kill $EXISTING_PID || true&#10;rm $PIDFILE&#10;fi&#10;&#10;pushd $PROJECT_DIR&#10;&#10;source .env/bin/activate&#10;nohup ./TestSupport/run_test_server.sh &amp;&#10;&#10;echo $! &gt; $PIDFILE&#10;&#10;popd&#10;\">\n               <EnvironmentBuildable>\n                  <BuildableReference\n                     BuildableIdentifier = \"primary\"\n                     BlueprintIdentifier = \"F6BDA801145900D200FE3253\"\n                     BuildableName = \"SocketRocketTests-iOS.xctest\"\n                     BlueprintName = \"SocketRocketTests-iOS\"\n                     ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n                  </BuildableReference>\n               </EnvironmentBuildable>\n            </ActionContent>\n         </ExecutionAction>\n      </PreActions>\n      <PostActions>\n         <ExecutionAction\n            ActionType = \"Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction\">\n            <ActionContent\n               title = \"Run Script\"\n               scriptText = \"PIDFILE=$TMPDIR/sr_test_server.pid&#10;&#10;if [ -r $PIDFILE ]; then&#10;EXISTING_PID=`cat $PIDFILE`&#10;echo &quot;Killing SR TestServer PID:&quot; $EXISTING_PID&#10;kill $EXISTING_PID&#10;rm $PIDFILE&#10;fi&#10;\">\n               <EnvironmentBuildable>\n                  <BuildableReference\n                     BuildableIdentifier = \"primary\"\n                     BlueprintIdentifier = \"F6BDA801145900D200FE3253\"\n                     BuildableName = \"SocketRocketTests-iOS.xctest\"\n                     BlueprintName = \"SocketRocketTests-iOS\"\n                     ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n                  </BuildableReference>\n               </EnvironmentBuildable>\n            </ActionContent>\n         </ExecutionAction>\n      </PostActions>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"81D6475F1D2CA78800690609\"\n            BuildableName = \"SocketRocket.framework\"\n            BlueprintName = \"SocketRocket-iOS\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"F6BDA801145900D200FE3253\"\n               BuildableName = \"SocketRocketTests-iOS.xctest\"\n               BlueprintName = \"SocketRocketTests-iOS\"\n               ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"81D6475F1D2CA78800690609\"\n            BuildableName = \"SocketRocket.framework\"\n            BlueprintName = \"SocketRocket-iOS\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"81D6475F1D2CA78800690609\"\n            BuildableName = \"SocketRocket.framework\"\n            BlueprintName = \"SocketRocket-iOS\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "SocketRocket.xcodeproj/xcshareddata/xcschemes/SocketRocket-macOS.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1250\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"F668C87F153E91210044DBAC\"\n               BuildableName = \"SocketRocket.framework\"\n               BlueprintName = \"SocketRocket-macOS\"\n               ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"F668C87F153E91210044DBAC\"\n            BuildableName = \"SocketRocket.framework\"\n            BlueprintName = \"SocketRocket-macOS\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"F668C87F153E91210044DBAC\"\n            BuildableName = \"SocketRocket.framework\"\n            BlueprintName = \"SocketRocket-macOS\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "SocketRocket.xcodeproj/xcshareddata/xcschemes/SocketRocket-tvOS.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1250\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"3345DC821C52ACD70083CCB8\"\n               BuildableName = \"SocketRocket.framework\"\n               BlueprintName = \"SocketRocket-tvOS\"\n               ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"3345DC821C52ACD70083CCB8\"\n            BuildableName = \"SocketRocket.framework\"\n            BlueprintName = \"SocketRocket-tvOS\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "SocketRocket.xcodeproj/xcshareddata/xcschemes/SocketRocketTests.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0730\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"NO\"\n            buildForArchiving = \"NO\"\n            buildForAnalyzing = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"F6BDA801145900D200FE3253\"\n               BuildableName = \"SocketRocketTests-iOS.xctest\"\n               BlueprintName = \"SocketRocketTests-iOS\"\n               ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"NO\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"F6BDA801145900D200FE3253\"\n               BuildableName = \"SocketRocketTests-iOS.xctest\"\n               BlueprintName = \"SocketRocketTests-iOS\"\n               ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"F6BDA801145900D200FE3253\"\n            BuildableName = \"SocketRocketTests-iOS.xctest\"\n            BlueprintName = \"SocketRocketTests-iOS\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n         <AdditionalOption\n            key = \"NSZombieEnabled\"\n            value = \"YES\"\n            isEnabled = \"YES\">\n         </AdditionalOption>\n         <AdditionalOption\n            key = \"OBJC_PRINT_EXCEPTIONS\"\n            value = \"YES\"\n            isEnabled = \"YES\">\n         </AdditionalOption>\n         <AdditionalOption\n            key = \"MallocGuardEdges\"\n            value = \"\"\n            isEnabled = \"YES\">\n         </AdditionalOption>\n         <AdditionalOption\n            key = \"MallocScribble\"\n            value = \"\"\n            isEnabled = \"YES\">\n         </AdditionalOption>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "SocketRocket.xcodeproj/xcshareddata/xcschemes/TestChat.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0730\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"F62417E214D52F3C003CE997\"\n               BuildableName = \"TestChat.app\"\n               BlueprintName = \"TestChat\"\n               ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.GDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"F62417E214D52F3C003CE997\"\n            BuildableName = \"TestChat.app\"\n            BlueprintName = \"TestChat\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"F62417E214D52F3C003CE997\"\n            BuildableName = \"TestChat.app\"\n            BlueprintName = \"TestChat\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n         <AdditionalOption\n            key = \"NSZombieEnabled\"\n            value = \"YES\"\n            isEnabled = \"YES\">\n         </AdditionalOption>\n         <AdditionalOption\n            key = \"OBJC_PRINT_EXCEPTIONS\"\n            value = \"YES\"\n            isEnabled = \"YES\">\n         </AdditionalOption>\n         <AdditionalOption\n            key = \"MallocGuardEdges\"\n            value = \"\"\n            isEnabled = \"YES\">\n         </AdditionalOption>\n         <AdditionalOption\n            key = \"MallocScribble\"\n            value = \"\"\n            isEnabled = \"YES\">\n         </AdditionalOption>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"F62417E214D52F3C003CE997\"\n            BuildableName = \"TestChat.app\"\n            BlueprintName = \"TestChat\"\n            ReferencedContainer = \"container:SocketRocket.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "TestChat/TCAppDelegate.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the license found in the\n// LICENSE-examples file in the root directory of this source tree.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface TCAppDelegate : UIResponder <UIApplicationDelegate>\n\n@property (nonatomic, strong) UIWindow *window;\n\n@end\n"
  },
  {
    "path": "TestChat/TCAppDelegate.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the license found in the\n// LICENSE-examples file in the root directory of this source tree.\n//\n\n#import \"TCAppDelegate.h\"\n\n@implementation TCAppDelegate\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\n{\n    return YES;\n}\n\n@end\n"
  },
  {
    "path": "TestChat/TCChatCell.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the license found in the\n// LICENSE-examples file in the root directory of this source tree.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface TCChatCell : UITableViewCell\n\n@property (nonatomic, retain) IBOutlet UITextView *textView;\n@property (nonatomic, retain) IBOutlet UILabel *nameLabel;\n\n@end\n"
  },
  {
    "path": "TestChat/TCChatCell.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the license found in the\n// LICENSE-examples file in the root directory of this source tree.\n//\n\n#import \"TCChatCell.h\"\n\n@implementation TCChatCell\n\n@synthesize nameLabel = _nameLabel;\n@synthesize textView = _textView;\n\n- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier\n{\n    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];\n    if (self) {\n        // Initialization code\n    }\n    return self;\n}\n\n- (CGSize)sizeThatFits:(CGSize)size;\n{\n    CGSize textViewSize = _textView.bounds.size;\n    CGSize fitTextViewSize = CGSizeMake(textViewSize.width, size.height);\n    CGSize sizeThatFitsSize = [self.textView sizeThatFits:fitTextViewSize];\n    \n    CGSize superSize = [super sizeThatFits:size];\n    \n    sizeThatFitsSize.height = MAX(superSize.height, sizeThatFitsSize.height);\n    sizeThatFitsSize.width = superSize.width;\n    \n    return sizeThatFitsSize;\n}\n\n@end\n"
  },
  {
    "path": "TestChat/TCViewController.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the license found in the\n// LICENSE-examples file in the root directory of this source tree.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface TCViewController : UITableViewController\n\n@property (nonatomic, strong) IBOutlet UITextView *inputView;\n\n- (IBAction)reconnect:(id)sender;\n- (IBAction)sendPing:(id)sender;\n\n@end\n"
  },
  {
    "path": "TestChat/TCViewController.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the license found in the\n// LICENSE-examples file in the root directory of this source tree.\n//\n\n#import \"TCViewController.h\"\n\n#import <SocketRocket/SocketRocket.h>\n\n#import \"TCChatCell.h\"\n\n@interface TCMessage : NSObject\n\n- (instancetype)initWithMessage:(NSString *)message incoming:(BOOL)incoming;\n\n@property (nonatomic, copy, readonly) NSString *message;\n@property (nonatomic, assign, readonly, getter=isIncoming) BOOL incoming;\n\n@end\n\n@implementation TCMessage\n\n- (instancetype)initWithMessage:(NSString *)message incoming:(BOOL)incoming\n{\n    self = [super init];\n    if (!self) return self;\n\n    _incoming = incoming;\n    _message = message;\n\n    return self;\n}\n\n@end\n\n\n@interface TCViewController () <SRWebSocketDelegate, UITextViewDelegate>\n{\n    SRWebSocket *_webSocket;\n    NSMutableArray<TCMessage *> *_messages;\n}\n\n@end\n\n@implementation TCViewController\n\n///--------------------------------------\n#pragma mark - View\n///--------------------------------------\n\n- (void)viewDidLoad;\n{\n    [super viewDidLoad];\n\n    _messages = [[NSMutableArray alloc] init];\n}\n\n- (void)viewWillAppear:(BOOL)animated\n{\n    [super viewWillAppear:animated];\n\n    [self reconnect:nil];\n}\n\n- (void)viewDidAppear:(BOOL)animated\n{\n    [super viewDidAppear:animated];\n\n    [_inputView becomeFirstResponder];\n}\n\n- (void)viewDidDisappear:(BOOL)animated\n{\n    [super viewDidDisappear:animated];\n\n    [_webSocket close];\n    _webSocket = nil;\n}\n\n///--------------------------------------\n#pragma mark - Actions\n///--------------------------------------\n\n- (IBAction)reconnect:(id)sender\n{\n    _webSocket.delegate = nil;\n    [_webSocket close];\n\n    _webSocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:@\"wss://echo.websocket.org\"]];\n    _webSocket.delegate = self;\n\n    self.title = @\"Opening Connection...\";\n    [_webSocket open];\n}\n\n- (void)sendPing:(id)sender;\n{\n    [_webSocket sendPing:nil error:NULL];\n}\n\n///--------------------------------------\n#pragma mark - Messages\n///--------------------------------------\n\n- (void)_addMessage:(TCMessage *)message\n{\n    [_messages addObject:message];\n    [self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:_messages.count - 1 inSection:0] ]\n                          withRowAnimation:UITableViewRowAnimationNone];\n    [self.tableView scrollRectToVisible:self.tableView.tableFooterView.frame animated:YES];\n}\n\n///--------------------------------------\n#pragma mark - UITableViewController\n///--------------------------------------\n\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section\n{\n    return _messages.count;\n}\n\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath\n{\n    TCMessage *message = _messages[indexPath.row];\n\n    TCChatCell *cell = [self.tableView dequeueReusableCellWithIdentifier:message.incoming ? @\"ReceivedCell\" : @\"SentCell\"\n                                                            forIndexPath:indexPath];\n\n    cell.textView.text = message.message;\n    cell.nameLabel.text = message.incoming ? @\"Other\" : @\"Me\";\n\n    return cell;\n}\n\n///--------------------------------------\n#pragma mark - SRWebSocketDelegate\n///--------------------------------------\n\n- (void)webSocketDidOpen:(SRWebSocket *)webSocket;\n{\n    NSLog(@\"Websocket Connected\");\n    self.title = @\"Connected!\";\n}\n\n- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;\n{\n    NSLog(@\":( Websocket Failed With Error %@\", error);\n\n    self.title = @\"Connection Failed! (see logs)\";\n    _webSocket = nil;\n}\n\n- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(nonnull NSString *)string\n{\n    NSLog(@\"Received \\\"%@\\\"\", string);\n    [self _addMessage:[[TCMessage alloc] initWithMessage:string incoming:YES]];\n}\n\n- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;\n{\n    NSLog(@\"WebSocket closed\");\n    self.title = @\"Connection Closed! (see logs)\";\n    _webSocket = nil;\n}\n\n- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload;\n{\n    NSLog(@\"WebSocket received pong\");\n}\n\n///--------------------------------------\n#pragma mark - UITextViewDelegate\n///--------------------------------------\n\n- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text\n{\n    if ([text rangeOfString:@\"\\n\"].location != NSNotFound) {\n        NSString *message = [textView.text stringByReplacingCharactersInRange:range withString:text];\n        message = [message stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];\n\n        [_webSocket sendString:message error:NULL];\n\n        [self _addMessage:[[TCMessage alloc] initWithMessage:message incoming:NO]];\n\n        textView.text = nil;\n        return NO;\n    }\n    return YES;\n}\n\n@end\n"
  },
  {
    "path": "TestChat/TestChat-Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>${PRODUCT_NAME}</string>\n\t<key>CFBundleExecutable</key>\n\t<string>${EXECUTABLE_NAME}</string>\n\t<key>CFBundleIconFiles</key>\n\t<array/>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>${PRODUCT_NAME}</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UIMainStoryboardFile</key>\n\t<string>MainStoryboard</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "TestChat/en.lproj/InfoPlist.strings",
    "content": "/* Localized versions of Info.plist keys */\n\n"
  },
  {
    "path": "TestChat/en.lproj/MainStoryboard.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"10117\" systemVersion=\"15F34\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" initialViewController=\"J5d-9g-n8O\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"10085\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"6me-oX-IDw\">\n            <objects>\n                <tableViewController id=\"X5f-jW-I9m\" customClass=\"TCViewController\" sceneMemberID=\"viewController\">\n                    <tableView key=\"view\" opaque=\"NO\" clipsSubviews=\"YES\" clearsContextBeforeDrawing=\"NO\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" dataMode=\"prototypes\" style=\"plain\" separatorStyle=\"default\" allowsSelection=\"NO\" rowHeight=\"44\" sectionHeaderHeight=\"22\" sectionFooterHeight=\"22\" id=\"RXu-lL-Fvu\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"480\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n                        <textView key=\"tableFooterView\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" scrollEnabled=\"NO\" id=\"rfU-78-BK7\">\n                            <rect key=\"frame\" x=\"0.0\" y=\"174\" width=\"320\" height=\"48\"/>\n                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\"/>\n                            <color key=\"backgroundColor\" red=\"0.90196079015731812\" green=\"0.90196079015731812\" blue=\"0.90196079015731812\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                            <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                            <fontDescription key=\"fontDescription\" type=\"boldSystem\" pointSize=\"14\"/>\n                            <textInputTraits key=\"textInputTraits\" autocapitalizationType=\"sentences\"/>\n                            <connections>\n                                <outlet property=\"delegate\" destination=\"X5f-jW-I9m\" id=\"wFD-6X-WBc\"/>\n                            </connections>\n                        </textView>\n                        <prototypes>\n                            <tableViewCell contentMode=\"scaleToFill\" selectionStyle=\"blue\" hidesAccessoryWhenEditing=\"NO\" indentationLevel=\"1\" indentationWidth=\"0.0\" reuseIdentifier=\"SentCell\" id=\"bz8-oG-fQA\" customClass=\"TCChatCell\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"86\" width=\"320\" height=\"44\"/>\n                                <autoresizingMask key=\"autoresizingMask\"/>\n                                <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" tableViewCell=\"bz8-oG-fQA\" id=\"ZUj-kZ-dtZ\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"43\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                    <subviews>\n                                        <textView clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" scrollEnabled=\"NO\" editable=\"NO\" text=\"blah\" id=\"5Mf-2x-lct\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"340\" height=\"43\"/>\n                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                            <color key=\"backgroundColor\" red=\"1\" green=\"0.80000001192092896\" blue=\"0.40000000596046448\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                                            <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"14\"/>\n                                            <textInputTraits key=\"textInputTraits\" autocapitalizationType=\"sentences\"/>\n                                            <dataDetectorType key=\"dataDetectorTypes\" phoneNumber=\"YES\" link=\"YES\" address=\"YES\"/>\n                                            <connections>\n                                                <outlet property=\"delegate\" destination=\"RXu-lL-Fvu\" id=\"gq9-g4-aL4\"/>\n                                            </connections>\n                                        </textView>\n                                    </subviews>\n                                </tableViewCellContentView>\n                                <color key=\"backgroundColor\" red=\"0.40000000596046448\" green=\"0.80000001192092896\" blue=\"1\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                                <connections>\n                                    <outlet property=\"textView\" destination=\"5Mf-2x-lct\" id=\"9XD-07-EiF\"/>\n                                </connections>\n                            </tableViewCell>\n                            <tableViewCell contentMode=\"scaleToFill\" selectionStyle=\"blue\" hidesAccessoryWhenEditing=\"NO\" indentationLevel=\"1\" indentationWidth=\"0.0\" reuseIdentifier=\"ReceivedCell\" id=\"RDH-ix-a2K\" customClass=\"TCChatCell\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"130\" width=\"320\" height=\"44\"/>\n                                <autoresizingMask key=\"autoresizingMask\"/>\n                                <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" tableViewCell=\"RDH-ix-a2K\" id=\"HND-fP-cKl\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"43\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                    <subviews>\n                                        <textView clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" scrollEnabled=\"NO\" editable=\"NO\" text=\"blah\" id=\"D4G-dV-Fxa\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"340\" height=\"43\"/>\n                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                            <color key=\"backgroundColor\" red=\"0.80000001192092896\" green=\"1\" blue=\"0.40000000596046448\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                                            <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"14\"/>\n                                            <textInputTraits key=\"textInputTraits\" autocapitalizationType=\"sentences\"/>\n                                            <dataDetectorType key=\"dataDetectorTypes\" phoneNumber=\"YES\" link=\"YES\" address=\"YES\"/>\n                                            <connections>\n                                                <outlet property=\"delegate\" destination=\"RXu-lL-Fvu\" id=\"R8T-eM-Gx7\"/>\n                                            </connections>\n                                        </textView>\n                                    </subviews>\n                                </tableViewCellContentView>\n                                <color key=\"backgroundColor\" red=\"0.40000000600000002\" green=\"0.80000001190000003\" blue=\"1\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                                <connections>\n                                    <outlet property=\"textView\" destination=\"D4G-dV-Fxa\" id=\"uY3-zG-DIh\"/>\n                                </connections>\n                            </tableViewCell>\n                        </prototypes>\n                        <connections>\n                            <outlet property=\"dataSource\" destination=\"X5f-jW-I9m\" id=\"L9s-pB-HYL\"/>\n                            <outlet property=\"delegate\" destination=\"X5f-jW-I9m\" id=\"ikq-4l-mw5\"/>\n                        </connections>\n                    </tableView>\n                    <navigationItem key=\"navigationItem\" id=\"hu8-ml-uHB\">\n                        <barButtonItem key=\"leftBarButtonItem\" title=\"Ping\" id=\"zLH-d1-wAa\">\n                            <connections>\n                                <action selector=\"sendPing:\" destination=\"X5f-jW-I9m\" id=\"y6C-K5-50Q\"/>\n                            </connections>\n                        </barButtonItem>\n                        <barButtonItem key=\"rightBarButtonItem\" systemItem=\"refresh\" id=\"cNK-1A-b66\">\n                            <connections>\n                                <action selector=\"reconnect:\" destination=\"X5f-jW-I9m\" id=\"yjV-1U-Tjn\"/>\n                            </connections>\n                        </barButtonItem>\n                    </navigationItem>\n                    <connections>\n                        <outlet property=\"inputView\" destination=\"rfU-78-BK7\" id=\"emF-S6-iR0\"/>\n                    </connections>\n                </tableViewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"KsG-hH-48N\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"676\" y=\"93\"/>\n        </scene>\n        <!--Navigation Controller-->\n        <scene sceneID=\"nGX-KT-vxI\">\n            <objects>\n                <navigationController id=\"J5d-9g-n8O\" sceneMemberID=\"viewController\">\n                    <toolbarItems/>\n                    <navigationBar key=\"navigationBar\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" id=\"8yP-KL-gkV\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"44\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </navigationBar>\n                    <nil name=\"viewControllers\"/>\n                    <connections>\n                        <segue destination=\"X5f-jW-I9m\" kind=\"relationship\" relationship=\"rootViewController\" id=\"3EC-DA-AY5\"/>\n                    </connections>\n                </navigationController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"DyG-Ww-kME\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"227\" y=\"65\"/>\n        </scene>\n    </scenes>\n    <simulatedMetricsContainer key=\"defaultSimulatedMetrics\">\n        <simulatedStatusBarMetrics key=\"statusBar\"/>\n        <simulatedOrientationMetrics key=\"orientation\"/>\n        <simulatedScreenMetrics key=\"destination\"/>\n    </simulatedMetricsContainer>\n</document>\n"
  },
  {
    "path": "TestChat/main.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the license found in the\n// LICENSE-examples file in the root directory of this source tree.\n//\n\n#import <UIKit/UIKit.h>\n\n#import \"TCAppDelegate.h\"\n\nint main(int argc, char *argv[])\n{\n    @autoreleasepool {\n        return UIApplicationMain(argc, argv, nil, NSStringFromClass([TCAppDelegate class]));\n    }\n}\n"
  },
  {
    "path": "TestChatServer/go/README",
    "content": "With the latest weekly go:\n\n\tgo run chatroom.go\n"
  },
  {
    "path": "TestChatServer/go/chatroom.go",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n// \n// This source code is licensed under the license found in the\n// LICENSE-examples file in the root directory of this source tree.\n//\n\npackage main\n\nimport (\n\t\"code.google.com/p/go.net/websocket\"\n\t\"net/http\"\n)\n\n// Msg stores both the message and the connection\ntype Msg struct {\n\tsender *websocket.Conn\n\tmsg    string\n}\n\nfunc run(reg chan *websocket.Conn, unreg chan *websocket.Conn, msg chan Msg) {\n\tconns := make(map[*websocket.Conn]int)\n\tfor {\n\t\tselect {\n\t\tcase c := <-reg:\n\t\t\tconns[c] = 1\n\t\tcase c := <-unreg:\n\t\t\tdelete(conns, c)\n\t\tcase msg := <-msg:\n\t\t\tfor c := range conns {\n\t\t\t\tif c != msg.sender {\n\t\t\t\t\twebsocket.Message.Send(c, msg.msg)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc newChatServer(reg chan *websocket.Conn, unreg chan *websocket.Conn, msg chan Msg) websocket.Handler {\n\treturn func(ws *websocket.Conn) {\n\t\treg <- ws\n\t\tfor {\n\t\t\tvar message string\n\t\t\terr := websocket.Message.Receive(ws, &message)\n\t\t\tif err != nil {\n\t\t\t\tunreg <- ws\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tmsg <- Msg{ws, message}\n\t\t}\n\t}\n}\n\nfunc main() {\n\treg := make(chan *websocket.Conn)\n\tunreg := make(chan *websocket.Conn)\n\tmsg := make(chan Msg)\n\n\thttp.Handle(\"/chat\", websocket.Handler(newChatServer(reg, unreg, msg)))\n\thttp.Handle(\"/\", http.FileServer(http.Dir(\"../static\")))\n\n\tgo run(reg, unreg, msg)\n\n\terr := http.ListenAndServe(\":9000\", nil)\n\tif err != nil {\n\t\tpanic(\"ListenAndServe: \" + err.Error())\n\t}\n}\n"
  },
  {
    "path": "TestChatServer/py/chatroom.py",
    "content": "#!/usr/bin/env python\n#\n# Copyright 2012 Square Inc.\n# Portions Copyright (c) 2016-present, Facebook, Inc.\n# All rights reserved.\n#\n# This source code is licensed under the license found in the\n# LICENSE-examples file in the root directory of this source tree.\n#\n\nimport tornado\nimport tornado.web\nimport tornado.websocket\nimport tornado.options\n\nimport os\n\nimport json\nimport uuid\n\nimport argparse\n\nimport logging\n\nlogger = logging.getLogger('gateway')\n\nargs = None\n\ndef parse_args():\n    global args\n    static_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'static'))\n    parser = argparse.ArgumentParser(description='Gateway server')\n\n    parser.add_argument('-v', '--verbose', help='verbose logging', action='store_true')\n\n    parser.add_argument('-s', '--static-path', help='path for static files [default: %(default)s]', default=static_path)\n\n    parser.add_argument('-p', '--listen-port', help='port to listen on [default: %(default)s]', default=9000, type=int, metavar='PORT')\n    parser.add_argument('-i', '--listen-interface', help='interface to listen on. [default: %(default)s]', default='0.0.0.0', metavar='IFACE')\n\n    args = parser.parse_args()\n    \n    \nconnections = set()\n \nclass ChatHandler(tornado.websocket.WebSocketHandler):\n    def open(self):\n        connections.add(self)\n        return None\n\n    def on_message(self, msg):\n        for c in connections:\n            if c is self:\n                continue\n            c.write_message(msg)\n\n    def on_close(self):\n        connections.remove(self)\n\n\ndef main():\n    global logger\n    #tornado.options.parse_command_line()\n\n    parse_args()\n\n    if args.verbose:\n        tornado.options.enable_pretty_logging()\n        logger = logging.getLogger()\n        logger.setLevel(logging.INFO)\n\n\n    application = tornado.web.Application([\n        (r\"/chat\", ChatHandler),\n        (r\"/(.*)\", tornado.web.StaticFileHandler, {\"path\": args.static_path, \"default_filename\":'index.html'}),\n    ],\n    )\n\n\n    print \"Listening on %s:%s\" % (args.listen_interface, args.listen_port)\n    application.listen(args.listen_port, args.listen_interface)\n    tornado.ioloop.IOLoop.instance().start()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "TestChatServer/static/.gitignore",
    "content": "devtools/\n"
  },
  {
    "path": "TestChatServer/static/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n  <head>\n    <script src='proxy.js'>\n    </script>\n    <style type='text/css'>\n      html {\n        background-color: rgb(48,48, 48);\n        color: rgb(221, 190, 120);\n        font-family: \"HelveticaNeue\", Helvetica, Arial;\n      }\n\n      a {\n        color: rgb(193, 127, 128);\n      }\n      #info_div {\n        font-size:small;\n        color: rgb(108, 144, 100);\n      }\n\n      .device_details {\n        font-size:small;\n      }\n    </style>\n  </head>\n  <body>\n    <h3>Chat History</h3>\n    <ul id='history'>\n    </ul>\n    <form id=\"msg_form\">\n      <input type='text' name='message' id='msg_field'/>\n      <input type='submit'/>\n    </form>\n\n    <ul id='client_list'></ul>\n    <div id='info_div'></div>\n  </body>\n</html>\n"
  },
  {
    "path": "TestChatServer/static/proxy.js",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n// \n// This source code is licensed under the license found in the\n// LICENSE-examples file in the root directory of this source tree.\n// \n\nfunction SocketClient () {\n  this.list_elem = document.getElementById('client_list');\n  this.info_div = document.getElementById('info_div');\n  var self = this;\n}\n\nSocketClient.prototype.connect = function () {\n  var self = this;\n\n  this.list_elem.innerHTML = '';\n  this.info_div.innerHTML = 'status: connecting...'; \n  this.socket = new WebSocket(\"ws://\" + document.location.host + \"/chat\");  \n  \n  this.socket.onopen = function () {self.onopen.apply(self, arguments);};\n  this.socket.onmessage = function () {self.onmessage.apply(self, arguments);};\n  this.socket.onclose = function () {self.onclose.apply(self, arguments);};\n};\n\nSocketClient.prototype.deviceAdded = function (params) {\n  var el = document.createElement('li');\n  el.innerHTML = '<a href=\"devtools/devtools.html?host=' + document.location.host + '&page=' + params.page + '\">' + params.device_name + '</a>' + ' <span class=\"device_details\">(' + params.app_id + ', ' + params.device_model + ', ' + params.device_id + ')</span>';\n  this.list_elem.appendChild(el);\n  this.visibleElems[params.connection_id] = el;\n};\n\nSocketClient.prototype.deviceRemoved = function (params) {\n  var li = this.visibleElems[params.connection_id];\n  li.parentNode.removeChild(li);\n};\n\nSocketClient.prototype.onopen = function () {\n  this.info_div.innerHTML = 'status: connected to gateway';\n  this.list_elem.innerHTML = '';\n  this.visibleElems = {};\n  console.log('connection to gateway opened');\n};\n\nSocketClient.prototype.onmessage = function (message) {\n  var el = document.createElement('li');\n  el.innerHTML = message.data;\n  window.document.getElementById('history').appendChild(el);\n};\n\nSocketClient.prototype.onclose = function () {\n  var retryInterval = 1000.0;\n  console.log('connection closed, retrying in ' + (retryInterval/1000.0) + ' seconds');\n  var self = this;\n  window.setTimeout(function () {self.connect();}, retryInterval);\n};\n\n\nwindow.addEventListener('load', function () {\n    var form = window.document.getElementById('msg_form');\n    var msg_field = window.document.getElementById('msg_field');\n\n    var socketClient = new SocketClient();\n    socketClient.connect()\n\n    form.onsubmit = function () {\n      msg = msg_field.value;\n      msg_field.value = '';\n\n      socketClient.socket.send(msg);\n\n      var el = document.createElement('li');\n      el.innerHTML = msg;\n      window.document.getElementById('history').appendChild(el);\n\n      return false;\n    };\n  }\n);\n"
  },
  {
    "path": "TestSupport/autobahn_fuzzingserver.json",
    "content": "{\n   \"url\": \"ws://127.0.0.1:9001\",\n   \"outdir\": \"./pages/results\",\n   \"cases\": [\"*\"],\n   \"exclude-cases\": [],\n   \"exclude-agent-cases\": {}\n}\n"
  },
  {
    "path": "TestSupport/run_test_server.sh",
    "content": "#\n# Copyright (c) 2016-present, Facebook, Inc.\n# All rights reserved.\n#\n# This source code is licensed under the license found in the\n# LICENSE-examples file in the root directory of this source tree.\n#\n\nPYENV_PATH=$(pwd)/.env\n\necho $PYENV_PATH\nif [ -d \"$PYENV_PATH\" ]; then \n  source $PYENV_PATH/bin/activate\n  $PYENV_PATH/bin/wstest -m fuzzingserver -s TestSupport/autobahn_fuzzingserver.json\nelse\n  echo \"Python Virtualenv not set up. Please run './TestSupport/setup_env.sh .env' first.\"\nfi\n\n"
  },
  {
    "path": "TestSupport/setup_env.sh",
    "content": "#\n# Copyright (c) 2016-present, Facebook, Inc.\n# All rights reserved.\n#\n# This source code is licensed under the license found in the\n# LICENSE-examples file in the root directory of this source tree.\n#\n\nVIRTUALENV_PATH=$1\n\nif [ -d \"$VIRTUALENV_PATH\" ]; then \n\techo \"Virtual Env already installed\"\nelif [ -z \"$VIRTUALENV_PATH\" ]; then\n  echo \"Usage: ./setup_env.sh <folder path>\"\nelse\n  mkdir $VIRTUALENV_PATH\n\n  pushd $VIRTUALENV_PATH  \n  \n  curl -L -o virtualenv.pyz https://bootstrap.pypa.io/virtualenv.pyz\n  \n  popd\n\n  python $VIRTUALENV_PATH/virtualenv.pyz $VIRTUALENV_PATH\n\n  source $VIRTUALENV_PATH/bin/activate\n\tpip install autobahntestsuite\n  \n  echo \"Environment succesfully set up in $VIRTUALENV_PATH.\"\nfi\n"
  },
  {
    "path": "Tests/Operations/SRAutobahnOperation.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRTWebSocketOperation.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef void(^SRAutobahnSocketTextMessageHandler)(SRWebSocket *socket, NSString  * _Nullable message);\ntypedef void(^SRAutobahnSocketDataMessageHandler)(SRWebSocket *socket, NSData  * _Nullable message);\n\n@interface SRAutobahnOperation : SRTWebSocketOperation\n\n- (instancetype)initWithServerURL:(NSURL *)url\n                  testCommandPath:(NSString *)path\n                       caseNumber:(nullable NSNumber *)caseNumber\n                            agent:(nullable NSString *)agent\n               textMessageHandler:(nullable SRAutobahnSocketTextMessageHandler)textMessageHandler\n               dataMessageHandler:(nullable SRAutobahnSocketDataMessageHandler)dataMessageHandler;\n\n@end\n\nextern SRAutobahnOperation *SRAutobahnTestOperation(NSURL *serverURL, NSInteger caseNumber, NSString *agent);\n\ntypedef void(^SRAutobahnTestResultHandler)(NSDictionary *_Nullable result);\nextern SRAutobahnOperation *SRAutobahnTestResultOperation(NSURL *serverURL, NSInteger caseNumber, NSString *agent, SRAutobahnTestResultHandler handler);\n\ntypedef void(^SRAutobahnTestCaseInfoHandler)(NSDictionary *_Nullable caseInfo);\nextern SRAutobahnOperation *SRAutobahnTestCaseInfoOperation(NSURL *serverURL, NSInteger caseNumber, SRAutobahnTestCaseInfoHandler handler);\n\ntypedef void(^SRAutobahnTestCaseCountHandler)(NSInteger caseCount);\nextern SRAutobahnOperation *SRAutobahnTestCaseCountOperation(NSURL *serverURL, NSString *agent, SRAutobahnTestCaseCountHandler handler);\n\nextern SRAutobahnOperation *SRAutobahnTestUpdateReportsOperation(NSURL *serverURL, NSString *agent);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tests/Operations/SRAutobahnOperation.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRAutobahnOperation.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface SRAutobahnOperation ()\n\n@property (nullable, nonatomic, copy, readonly) SRAutobahnSocketTextMessageHandler textMessageHandler;\n@property (nullable, nonatomic, copy, readonly) SRAutobahnSocketDataMessageHandler dataMessageHandler;\n\n@end\n\n@implementation SRAutobahnOperation\n\n- (instancetype)initWithServerURL:(NSURL *)url\n                  testCommandPath:(NSString *)path\n                       caseNumber:(nullable NSNumber *)caseNumber\n                            agent:(nullable NSString *)agent\n               textMessageHandler:(nullable SRAutobahnSocketTextMessageHandler)textMessageHandler\n               dataMessageHandler:(nullable SRAutobahnSocketDataMessageHandler)dataMessageHandler\n{\n    NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];\n    components.path = (components.path ? [components.path stringByAppendingPathComponent:path] : path);\n\n    NSMutableArray<NSURLQueryItem *> *queryItems = [NSMutableArray arrayWithCapacity:2];\n    if (caseNumber) {\n        [queryItems addObject:[NSURLQueryItem queryItemWithName:@\"case\" value:caseNumber.stringValue]];\n    }\n    if (agent) {\n        [queryItems addObject:[NSURLQueryItem queryItemWithName:@\"agent\" value:agent]];\n    }\n    components.queryItems = queryItems;\n    self = [self initWithURL:components.URL];\n    if (!self) return self;\n\n    _textMessageHandler = [textMessageHandler copy];\n    _dataMessageHandler = [dataMessageHandler copy];\n\n    return self;\n}\n\n- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(NSString *)string\n{\n    if (self.textMessageHandler) {\n        self.textMessageHandler(webSocket, string);\n    }\n}\n\n- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithData:(NSData *)data\n{\n    if (self.dataMessageHandler) {\n        self.dataMessageHandler(webSocket, data);\n    }\n}\n\n@end\n\nSRAutobahnOperation *SRAutobahnTestOperation(NSURL *serverURL, NSInteger caseNumber, NSString *agent)\n{\n    return [[SRAutobahnOperation alloc] initWithServerURL:serverURL\n                                          testCommandPath:@\"/runCase\"\n                                               caseNumber:@(caseNumber)\n                                                    agent:agent\n                                       textMessageHandler:^(SRWebSocket * _Nonnull socket, NSString  * _Nullable message) {\n                                           [socket sendString:message error:nil];\n                                       }\n                                       dataMessageHandler:^(SRWebSocket * _Nonnull socket, NSData * _Nullable message) {\n                                           [socket sendData:message error:nil];\n                                       }];\n}\n\nextern SRAutobahnOperation *SRAutobahnTestResultOperation(NSURL *serverURL, NSInteger caseNumber, NSString *agent, SRAutobahnTestResultHandler handler)\n{\n    return [[SRAutobahnOperation alloc] initWithServerURL:serverURL\n                                          testCommandPath:@\"/getCaseStatus\"\n                                               caseNumber:@(caseNumber)\n                                                    agent:agent\n                                       textMessageHandler:^(SRWebSocket * _Nonnull socket, NSString * _Nullable message) {\n                                           NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding];\n                                           NSDictionary *result = [NSJSONSerialization JSONObjectWithData:messageData options:0 error:NULL];\n                                           handler(result);\n                                       }\n                                       dataMessageHandler:nil];\n}\n\nextern SRAutobahnOperation *SRAutobahnTestCaseInfoOperation(NSURL *serverURL, NSInteger caseNumber, SRAutobahnTestCaseInfoHandler handler)\n{\n    return [[SRAutobahnOperation alloc] initWithServerURL:serverURL\n                                          testCommandPath:@\"/getCaseInfo\"\n                                               caseNumber:@(caseNumber)\n                                                    agent:nil\n                                       textMessageHandler:^(SRWebSocket * _Nonnull socket, NSString * _Nullable message) {\n                                           NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding];\n                                           NSDictionary *result = [NSJSONSerialization JSONObjectWithData:messageData options:0 error:NULL];\n                                           handler(result);\n                                       }\n                                       dataMessageHandler:nil];\n}\n\nextern SRAutobahnOperation *SRAutobahnTestCaseCountOperation(NSURL *serverURL, NSString *agent, SRAutobahnTestCaseCountHandler handler)\n{\n    return [[SRAutobahnOperation alloc] initWithServerURL:serverURL\n                                          testCommandPath:@\"/getCaseCount\"\n                                               caseNumber:nil\n                                                    agent:agent\n                                       textMessageHandler:^(SRWebSocket * _Nonnull socket, NSString * _Nullable message) {\n                                           NSInteger count = [message integerValue];\n                                           handler(count);\n                                       }\n                                       dataMessageHandler:nil];\n}\n\nextern SRAutobahnOperation *SRAutobahnTestUpdateReportsOperation(NSURL *serverURL, NSString *agent)\n{\n    return [[SRAutobahnOperation alloc] initWithServerURL:serverURL\n                                          testCommandPath:@\"/updateReports\"\n                                               caseNumber:nil\n                                                    agent:agent\n                                       textMessageHandler:nil\n                                       dataMessageHandler:nil];\n}\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tests/Operations/SRTWebSocketOperation.h",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import <SocketRocket/SRWebSocket.h>\n\n@interface SRTWebSocketOperation : NSOperation <SRWebSocketDelegate>\n\n@property (nonatomic) BOOL isFinished;\n@property (nonatomic) BOOL isExecuting;\n\n@property (nonatomic, strong, readonly) NSError *error;\n\n- (instancetype)initWithURL:(NSURL *)URL;\n\n// We override these methods.  Please call super\n- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean NS_REQUIRES_SUPER;\n- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error NS_REQUIRES_SUPER;\n\n- (BOOL)waitUntilFinishedWithTimeout:(NSTimeInterval)timeout;\n\n@end\n"
  },
  {
    "path": "Tests/Operations/SRTWebSocketOperation.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRTWebSocketOperation.h\"\n\n#import \"SRAutobahnUtilities.h\"\n\n@interface SRTWebSocketOperation ()\n\n@end\n\n@implementation SRTWebSocketOperation {\n    NSInteger _testNumber;\n    SRWebSocket *_webSocket;\n    NSURL *_url;\n}\n\n@synthesize isFinished = _isFinished;\n@synthesize isExecuting = _isExecuting;\n@synthesize error = _error;\n\n- (instancetype)initWithURL:(NSURL *)URL;\n{\n    self = [super init];\n    if (self) {\n        _url = URL;\n        _isExecuting = NO;\n        _isFinished = NO;\n    }\n    return self;\n}\n\n- (BOOL)isConcurrent;\n{\n    return YES;\n}\n\n- (void)start;\n{\n    dispatch_async(dispatch_get_main_queue(), ^{\n        SRWebSocket *socket  = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:self->_url]];\n        socket.delegate = self;\n        self->_webSocket = socket;\n        [socket open];\n    });\n    self.isExecuting = YES;\n}\n\n- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;\n{\n    [self willChangeValueForKey:@\"isExecuting\"];\n    [self willChangeValueForKey:@\"isFinished\"];\n    _isFinished = YES;\n    _isExecuting = NO;\n    [self didChangeValueForKey:@\"isExecuting\"];\n    [self didChangeValueForKey:@\"isFinished\"];\n    _webSocket.delegate = nil;\n    _webSocket = nil;\n}\n\n- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;\n{\n    _error = error;\n    [self willChangeValueForKey:@\"isExecuting\"];\n    [self willChangeValueForKey:@\"isFinished\"];\n    _isFinished = YES;\n    _isExecuting = NO;\n    [self didChangeValueForKey:@\"isExecuting\"];\n    [self didChangeValueForKey:@\"isFinished\"];\n    _webSocket.delegate = nil;\n    _webSocket = nil;\n}\n\n- (BOOL)waitUntilFinishedWithTimeout:(NSTimeInterval)timeout\n{\n    if (self.isFinished) {\n        return YES;\n    }\n    return SRRunLoopRunUntil(^BOOL{\n        return self.isFinished;\n    }, timeout);\n}\n\n@end\n"
  },
  {
    "path": "Tests/Resources/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>${EXECUTABLE_NAME}</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Tests/Resources/autobahn_configuration.json",
    "content": "{\n    \"UNIMPLEMENTED\": [\n                      \"12\",\n                      \"13\"\n                      ],\n    \"NON-STRICT\": [\n                   \"6.4.2\",\n                   \"6.4.4\",\n                   ],\n    \"INFORMATIONAL\": [\n                      \"7.1.6\",\n                      \"7.13.1\",\n                      \"7.13.2\"\n                      ]\n}"
  },
  {
    "path": "Tests/SRAutobahnTests.m",
    "content": "//\n// Copyright 2012 Square Inc.\n// Portions Copyright (c) 2016-present, Facebook, Inc.\n//\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n@import XCTest;\n@import ObjectiveC;\n\n#import <SocketRocket/SRWebSocket.h>\n\n#import \"SRTWebSocketOperation.h\"\n#import \"SRAutobahnOperation.h\"\n#import \"SRAutobahnUtilities.h\"\n\n@interface SRAutobahnTests : XCTestCase\n@end\n\n@implementation SRAutobahnTests\n\n///--------------------------------------\n#pragma mark - Init\n///--------------------------------------\n\n/**\n This method is called if Xcode is targeting a specific test or a set of them.\n If you change this method - please make sure you test this behavior in Xcode by running all tests, then running 1+ test.\n */\n+ (instancetype)testCaseWithSelector:(SEL)selector\n{\n    NSArray<NSInvocation *> *invocations = [self testInvocations];\n    for (NSInvocation *invocation in invocations) {\n        if (invocation.selector == selector) {\n            return [super testCaseWithSelector:selector];\n        }\n    }\n    return nil;\n}\n\n///--------------------------------------\n#pragma mark - Setup\n///--------------------------------------\n\n/**\n This method is called by xctest to figure out all the tests that are available.\n All the selector names are also reported back to Xcode and displayed in Test Navigator/Console.\n */\n+ (NSArray<NSInvocation *> *)testInvocations\n{\n    __block NSArray<NSInvocation *> *array = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        NSMutableArray<NSInvocation *> *invocations = [NSMutableArray array];\n        for (NSUInteger i = 1; i <= SRAutobahnTestCaseCount(); i++) {\n            NSDictionary *caseInfo = SRAutobahnTestCaseInfo(i);\n            NSString *identifier = caseInfo[@\"id\"];\n\n            NSInvocation *invocation = [self invocationWithCaseNumber:i identifier:identifier];\n            [invocations addObject:invocation];\n        }\n\n        array = [invocations sortedArrayUsingComparator:^NSComparisonResult(NSInvocation *_Nonnull obj1, NSInvocation *_Nonnull obj2) {\n            return [NSStringFromSelector(obj1.selector) compare:NSStringFromSelector(obj2.selector) options:NSNumericSearch];\n        }];\n    });\n    return array;\n}\n\n+ (NSInvocation *)invocationWithCaseNumber:(NSUInteger)caseNumber identifier:(NSString *)identifier\n{\n    SEL selector = [self addInstanceMethodForTestCaseNumber:caseNumber identifier:identifier];\n    NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector];\n    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];\n    invocation.selector = selector;\n    return invocation;\n}\n\n+ (SEL)addInstanceMethodForTestCaseNumber:(NSInteger)caseNumber identifier:(NSString *)identifier\n{\n    NSString *selectorName = [NSString stringWithFormat:@\"Case #%@\", identifier];\n    SEL selector = NSSelectorFromString(selectorName);\n\n    IMP implementation = imp_implementationWithBlock(^(SRAutobahnTests *sself) {\n        [sself performTestWithCaseNumber:caseNumber identifier:identifier];\n    });\n    NSString *typeString = [NSString stringWithFormat:@\"%s%s%s\",  @encode(id), @encode(id), @encode(SEL)];\n    class_addMethod(self, selector, implementation, typeString.UTF8String);\n\n    return selector;\n}\n\n///--------------------------------------\n#pragma mark - Teardown\n///--------------------------------------\n\n+ (void)tearDown\n{\n    [self updateReports];\n    [super tearDown];\n}\n\n+ (void)updateReports\n{\n    SRAutobahnOperation *operation = SRAutobahnTestUpdateReportsOperation(SRAutobahnTestServerURL(), SRAutobahnTestAgentName());\n    [operation start];\n\n    NSAssert([operation waitUntilFinishedWithTimeout:60], @\"Timed out on updating reports.\");\n    NSAssert(!operation.error, @\"Updating the report should not have errored %@\", operation.error);\n}\n\n///--------------------------------------\n#pragma mark - Test\n///--------------------------------------\n\n- (void)performTestWithCaseNumber:(NSInteger)caseNumber identifier:(NSString *)identifier\n{\n    NSURL *serverURL = SRAutobahnTestServerURL();\n    NSString *agent = SRAutobahnTestAgentName();\n\n    NSOperationQueue *testQueue = [[NSOperationQueue alloc] init];\n    testQueue.maxConcurrentOperationCount = 1;\n\n    SRAutobahnOperation *testOp = SRAutobahnTestOperation(serverURL, caseNumber, agent);\n    [testQueue addOperation:testOp];\n\n    __block NSDictionary *resultInfo = nil;\n    SRAutobahnOperation *resultOp = SRAutobahnTestResultOperation(serverURL, caseNumber, agent, ^(NSDictionary * _Nullable result) {\n        resultInfo = result;\n    });\n    [resultOp addDependency:testOp];\n    [testQueue addOperation:resultOp];\n\n\n    XCTAssertTrue([resultOp waitUntilFinishedWithTimeout:60 * 5], @\"Test operation timed out.\");\n    XCTAssertTrue(!testOp.error, @\"Test operation should not have failed\");\n    if (!SRAutobahnIsValidResultBehavior(identifier, resultInfo[@\"behavior\"])) {\n        XCTFail(@\"Invalid test behavior %@ for %@.\", resultInfo[@\"behavior\"], identifier);\n    }\n}\n\n@end\n"
  },
  {
    "path": "Tests/Utilities/SRAutobahnUtilities.h",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n@import Foundation;\n\nNS_ASSUME_NONNULL_BEGIN\n\n///--------------------------------------\n#pragma mark - Test Configuration\n///--------------------------------------\n\nextern NSString *SRAutobahnTestAgentName(void);\nextern NSURL *SRAutobahnTestServerURL(void);\n\n///--------------------------------------\n#pragma mark - Validation\n///--------------------------------------\n\nextern NSDictionary<NSString *, id> *SRAutobahnTestConfiguration(void);\nextern BOOL SRAutobahnIsValidResultBehavior(NSString *caseIdentifier, NSString *behavior);\n\n///--------------------------------------\n#pragma mark - Utilities\n///--------------------------------------\n\nextern BOOL SRRunLoopRunUntil(BOOL (^predicate)(), NSTimeInterval timeout);\n\n///--------------------------------------\n#pragma mark - Setup\n///--------------------------------------\n\nextern NSUInteger SRAutobahnTestCaseCount(void);\nextern NSDictionary<NSString *, id> *SRAutobahnTestCaseInfo(NSInteger caseNumber);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tests/Utilities/SRAutobahnUtilities.m",
    "content": "//\n// Copyright (c) 2016-present, Facebook, Inc.\n// All rights reserved.\n//\n// This source code is licensed under the BSD-style license found in the\n// LICENSE file in the root directory of this source tree. An additional grant\n// of patent rights can be found in the PATENTS file in the same directory.\n//\n\n#import \"SRAutobahnUtilities.h\"\n\n#import \"SRAutobahnOperation.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface SRAutobahnUtilities : NSObject @end\n@implementation SRAutobahnUtilities @end\n\n///--------------------------------------\n#pragma mark - Test Configuration\n///--------------------------------------\n\nNSString *SRAutobahnTestAgentName(void)\n{\n    return [NSBundle bundleForClass:[SRAutobahnUtilities class]].bundleIdentifier;\n}\n\nNSURL *SRAutobahnTestServerURL(void)\n{\n    return [NSURL URLWithString:@\"ws://localhost:9001\"];\n}\n\n///--------------------------------------\n#pragma mark - Validation\n///--------------------------------------\n\nNSDictionary<NSString *, id> *SRAutobahnTestConfiguration(void)\n{\n    static NSDictionary *configuration;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        NSURL *configurationURL = [[NSBundle bundleForClass:[SRAutobahnUtilities class]] URLForResource:@\"autobahn_configuration\"\n                                                                                          withExtension:@\"json\"];\n        NSInputStream *readStream = [NSInputStream inputStreamWithURL:configurationURL];\n        [readStream open];\n        configuration = [NSJSONSerialization JSONObjectWithStream:readStream options:0 error:nil];\n        [readStream close];\n    });\n    return configuration;\n}\n\nBOOL SRAutobahnIsValidResultBehavior(NSString *caseIdentifier, NSString *behavior)\n{\n    if ([behavior isEqualToString:@\"OK\"]) {\n        return YES;\n    }\n\n    NSArray *cases = SRAutobahnTestConfiguration()[behavior];\n    for (NSString *caseId in cases) {\n        if ([caseIdentifier hasPrefix:caseId]) {\n            return YES;\n        }\n    }\n    return NO;\n}\n\n///--------------------------------------\n#pragma mark - Utilities\n///--------------------------------------\n\nBOOL SRRunLoopRunUntil(BOOL (^predicate)(), NSTimeInterval timeout)\n{\n    NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeout];\n\n    NSTimeInterval timeoutTime = [timeoutDate timeIntervalSinceReferenceDate];\n    NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate];\n\n    while (!predicate() && currentTime < timeoutTime) {\n        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];\n        currentTime = [NSDate timeIntervalSinceReferenceDate];\n    }\n    return (currentTime <= timeoutTime);\n}\n\n///--------------------------------------\n#pragma mark - Setup\n///--------------------------------------\n\nNSUInteger SRAutobahnTestCaseCount(void)\n{\n    static NSUInteger count;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        SRAutobahnOperation *operation = SRAutobahnTestCaseCountOperation(SRAutobahnTestServerURL(),\n                                                                           SRAutobahnTestAgentName(),\n                                                                           ^(NSInteger caseCount) {\n                                                                               count = caseCount;\n                                                                           });\n        [operation start];\n\n        NSCAssert([operation waitUntilFinishedWithTimeout:10], @\"Timed out fetching test case count.\");\n        NSCAssert(!operation.error, @\"CaseGetter should have successfully returned the number of testCases. Instead got error %@\", operation.error);\n    });\n    return count;\n}\n\nNSDictionary<NSString *, id> *SRAutobahnTestCaseInfo(NSInteger caseNumber)\n{\n    __block NSDictionary *caseInfo = nil;\n    SRAutobahnOperation *operation = SRAutobahnTestCaseInfoOperation(SRAutobahnTestServerURL(), caseNumber, ^(NSDictionary * _Nullable info) {\n        caseInfo = info;\n    });\n    [operation start];\n\n    NSCAssert([operation waitUntilFinishedWithTimeout:10], @\"Timed out fetching test case info %ld.\", (long)caseNumber);\n    NSCAssert(!operation.error, @\"Updating the report should not have errored\");\n    return caseInfo;\n}\n\nNS_ASSUME_NONNULL_END\n"
  }
]