[
  {
    "path": ".gitignore",
    "content": ".DS_Store\n*.pyc\nbuild/\ndocs/output/\ndocs/output-docset/\nxcuserdata\n*.xcworkspace\nnode_modules\ncoverage/\n\nNimbusAttributedLabel+Namespace.h\nNimbusCore+Namespace.h\nNimbusCss+Namespace.h\nNimbusInterapp+Namespace.h\nNimbusLauncher+Namespace.h\nNimbusModels+Namespace.h\nNimbusNetworkControllers+Namespace.h\nNimbusNetworkImage+Namespace.h\nNimbusOverview+Namespace.h\nNimbusPagingScrollView+Namespace.h\nNimbusPhotos+Namespace.h\nNimbusWebController+Namespace.h\nNimbusTextField+Namespace.h\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"thirdparty/AFNetworking\"]\n\tpath = thirdparty/AFNetworking\n\turl = https://github.com/AFNetworking/AFNetworking.git\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: objective-c\nosx_image: xcode8.3\nsudo: false\nenv:\n  global:\n  - LC_CTYPE=en_US.UTF-8\n  - LANG=en_US.UTF-8\n  matrix:\n    - DESTINATION=\"OS=10.3.1,name=iPhone 6s\" SDK=iphonesimulator10.3\n    - DESTINATION=\"OS=9.1,name=iPhone 6s\" SDK=iphonesimulator10.3\n    - DESTINATION=\"OS=9.0,name=iPhone 6 Plus\" SDK=iphonesimulator10.3\nbefore_install:\n  - gem install cocoapods --no-rdoc --no-ri --no-document --quiet\n  - gem install xcpretty --no-rdoc --no-ri --no-document --quiet\n  - git submodule update\nscript:\n  - set -o pipefail\n  - xcodebuild -version\n  - xcodebuild -showsdks\n  - xcodebuild -project src/Nimbus.xcodeproj -scheme NimbusAttributedLabel -sdk \"$SDK\" -destination \"$DESTINATION\" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; \n  - xcodebuild -project src/Nimbus.xcodeproj -scheme NimbusCore -sdk \"$SDK\" -destination \"$DESTINATION\" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; \n  - xcodebuild -project src/Nimbus.xcodeproj -scheme NimbusCss -sdk \"$SDK\" -destination \"$DESTINATION\" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; \n  - xcodebuild -project src/Nimbus.xcodeproj -scheme NimbusInterapp -sdk \"$SDK\" -destination \"$DESTINATION\" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; \n  - xcodebuild -project src/Nimbus.xcodeproj -scheme NimbusModels -sdk \"$SDK\" -destination \"$DESTINATION\" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; \n  - xcodebuild -project src/Nimbus.xcodeproj -scheme NimbusOverview -sdk \"$SDK\" -destination \"$DESTINATION\" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; \n  - xcodebuild -project src/Nimbus.xcodeproj -scheme NimbusPagingScrollView -sdk \"$SDK\" -destination \"$DESTINATION\" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; \n  - xcodebuild -project src/Nimbus.xcodeproj -scheme NimbusPhotos -sdk \"$SDK\" -destination \"$DESTINATION\" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; \n  - xcodebuild -project src/Nimbus.xcodeproj -scheme NimbusWebController -sdk \"$SDK\" -destination \"$DESTINATION\" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c; \n  \n"
  },
  {
    "path": "AUTHORS",
    "content": "Nimbus Authors\r\n\r\nThe following people have contributed their time and effort to the Nimbus framework:\r\n\r\nbubnov gh:bubnov\r\nRoger Chapman gh:rogchap\r\nManu Cornet gh:lmanul\r\nGlenn Grant gh:alias1\r\nAviel Lazar gh:aviell\r\nDave MacLachlan gh:dmaclach\r\nBenedikt Meurer gh:bmeurer\r\nAnderson Miller gh:candersonmiller\r\nStephane Moore gh:stephanemoore\r\nBasil Shkara gh:baz\r\nPeter Steinberger gh:steipete\r\nJeff Verkoeyen gh:jverkoey @featherless (project founder)\r\nHwee-Boon Yar gh:hboon\r\nSteven Nie gh:ynie\r\n\r\nThanks to everyone who has given feedback and reported bugs as well:\r\n\r\nLaurin Brandner @Larcus94\r\nAvi Itskovich gh:aitskovi\r\nJohn Wang gh:jwang\r\n\r\n"
  },
  {
    "path": "CONTRIBUTING.mdown",
    "content": "So you wanna hack on Nimbus?\n============================\n\nNimbus follows one principle above all others:\n\n            Nimbus may only grow if its documentation grows at the same rate, or faster.\n\nBy this principle, any new feature added to Nimbus must be documented. Where possible, examples\nshould be provided. When necessary, architectural explanations must be referred to.\n\n\nTaking on Tasks\n===============\n\nIf you would like to help out with the development of Nimbus, the easiest way to start is to\ncheck out the Grab Bag tasks on Github:\n\nhttps://github.com/jverkoey/nimbus/issues?milestone=5&sort=created&direction=desc&state=open\n\n\nAdding New Features to Nimbus\n=============================\n\nIf you would like to add a new feature to Nimbus take a moment to consider the following questions:\n\n- Has the feature already been built and open-sourced by someone else?\n  - Does it have all of the features you'd like to see?\n  - Is it well documented?\n  - If the answers to the above are YES, then it's probably not a good feature to build for\n    Nimbus. Consider either writing a guide for integrating it with Nimbus or seeing whether it\n    makes sense to add the feature as a third-party feature.\n- Are you ok with open sourcing your code?\n  - If you work for a company, consult with your manager and/or legal team to ensure that it's ok\n    for you to contribute code to an open source project. Nimbus uses the Apache 2.0 license.\n\n\n### Creating the Feature\n\nAll Nimbus features are contained within the src directory in separate directories with the\nfollowing structure:\n\n    src       - all of the feature's source code\n    unittests - all unit test code\n    resources - any resources the feature might require (in bundles for simplicity, usually)\n\nOnce you've set up the directory structure for your feature, add a new static library\ntarget to the Nimbus root project and add the necessary files to the target.\n\n\nDocumentation\n=============\n\nNimbus documentation is generated using a tool called Doxygen. It's a powerful piece of software\nthat allows Nimbus to generate Xcode docsets and documentation that is accessible from the web.\n\nOut of the box, Doxygen does not provide as much support for generating Apple-esque documentation\nas would be desired, so Jeff has been hacking on Doxygen to get it to generate documentation\nthat resembles Apple's docs.\n\nYou can download the custom build here:\nhttps://github.com/downloads/jverkoey/nimbus/Nimbus%20Doxygen.dmg.zip\n\nAnd the source is accessible here:\nhttps://github.com/nimbusios/Doxygen\n\n\nGenerating the Documentation\n----------------------------\n\nAfter you've installed Doxygen on your system, open Doxygen.\n\nOpen the Doxyfile found in Nimbus' `docs` directory. Run Doxygen and the\ndocumentation will be output in `docs/output/html`.\n"
  },
  {
    "path": "DONORS",
    "content": "Nimbus donors\r\n\r\nMany thanks to those who have made generous contributions to the Nimbus framework:\r\n\r\nSumeru Chatterjee\r\nMatt Coneybeare\r\nCraig Gilchrist\r\nAtsushi Nagase\r\nPeter Nelson\r\nThanh Nguyen\r\nJindrich Sarson\r\nSindre Sørhus\r\nMatthew Wilkinson\r\nLucian Burja\r\n\r\nYou can add yourself to this list by sending money to jverkoey@gmail.com.\r\n\r\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "NOTICE_LICENSE",
    "content": "Copyright 2011-2012 Jeff Verkoeyen\nhttp://NimbusKit.info\nFor a list of contributors see https://github.com/jverkoey/nimbus/graphs/contributors\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nSee the AUTHORS and DONORS files for more information about Nimbus\ncontributors."
  },
  {
    "path": "Nimbus.podspec",
    "content": "Pod::Spec.new do |s|\n  s.name         = \"Nimbus\"\n  s.version      = \"1.3.0\"\n  s.summary      = \"The iOS framework that grows only as fast as its documentation\"\n  s.description  = <<-DESC\n  Nimbus is an iOS framework whose feature set grows only as fast as its documentation. By focusing\n  on documentation first and features second, Nimbus hopes to be a framework that accelerates the\n  development process of any application by being easy to use and simple to understand.\n                   DESC\n  s.homepage     = \"http://nimbuskit.info\"\n  s.license      = \"Apache License, Version 2.0\"\n  s.authors            = {\n    \"Jeff Verkoeyen\" => \"jverkoey@gmail.com\",\n    \"Bubnov Slavik\" => \"bubnovslavik@gmail.com\",\n    \"Roger Chapman\" => \"rogchap@gmail.com\",\n    \"Manu Cornet\" => \"manu.cornet@gmail.com\",\n    \"Glenn Grant\" => \"glenn@ensquared.net\",\n    \"Aviel Lazar\" => \"aviellazar@gmail.com\",\n    \"Benedikt Meurer\" => \"benedikt.meurer@googlemail.com\",\n    \"Anderson Miller\" => \"anderson@submarinerich.com\",\n    \"Basil Shkara\" => \"basil@neat.io\",\n    \"Peter Steinberger\" => \"me@petersteinberger.com\",\n    \"Hwee-Boon Yar\" => \"hboon@motionobj.com\",\n    \"Stephane Moore\" => \"stephane.moore@gmail.com\"\n  }\n  s.social_media_url   = \"http://twitter.com/NimbusKit\"\n  s.platform     = :ios, \"11.0\"\n  s.source       = { :git => \"https://github.com/jverkoey/nimbus.git\", :tag => s.version }\n  s.requires_arc = true\n\n  s.subspec 'AttributedLabel' do |ss|\n    ss.source_files = 'src/attributedlabel/src'\n    ss.dependency 'Nimbus/Core'\n  end\n\n  s.subspec 'Core' do |ss|\n    ss.source_files = 'src/core/src'\n  end\n\n  s.subspec 'Badge' do |ss|\n    ss.source_files = 'src/badge/src'\n    ss.dependency 'Nimbus/Core'\n  end\n\n  s.subspec 'Collections' do |ss|\n    ss.source_files = 'src/collections/src'\n    ss.dependency 'Nimbus/Core'\n  end\n\n  s.subspec 'CSS' do |ss|\n    ss.source_files = 'src/css/src'\n    ss.dependency 'Nimbus/Core'\n    ss.dependency 'Nimbus/Textfield'\n    ss.dependency 'AFNetworking', '~> 3.0'\n  end\n\n  s.subspec 'Interapp' do |ss|\n    ss.source_files = 'src/interapp/src'\n    ss.dependency 'Nimbus/Core'\n    ss.framework = 'CoreLocation'\n  end\n\n  s.subspec 'Launcher' do |ss|\n    ss.source_files = 'src/launcher/src'\n    ss.dependency 'Nimbus/Core'\n    ss.dependency 'Nimbus/PagingScrollView'\n  end\n\n  s.subspec 'Models' do |ss|\n    ss.source_files = 'src/models/src'\n    ss.dependency 'Nimbus/Core'\n  end\n\n  s.subspec 'NetworkControllers' do |ss|\n    ss.source_files = 'src/networkcontrollers/src'\n    ss.dependency 'Nimbus/Core'\n  end\n\n  s.subspec 'NetworkImage' do |ss|\n    ss.source_files = 'src/networkimage/src'\n    ss.dependency 'Nimbus/Core'\n    ss.dependency 'AFNetworking', '~> 3.0'\n  end\n\n  s.subspec 'Overview' do |ss|\n    ss.source_files = 'src/overview/src'\n    ss.dependency 'Nimbus/Core'\n    ss.dependency 'Nimbus/Models'\n    s.resource_bundles = {\n      'Overview' => ['src/overview/resources/NimbusOverviewer.bundle/*']\n    }\n  end\n\n  s.subspec 'PagingScrollView' do |ss|\n    ss.source_files = 'src/pagingscrollview/src'\n    ss.dependency 'Nimbus/Core'\n  end\n\n  s.subspec 'Photos' do |ss|\n    ss.source_files = 'src/photos/src'\n    ss.dependency 'Nimbus/Core'\n    ss.dependency 'Nimbus/PagingScrollView'\n  end\n\n  s.subspec 'Textfield' do |ss|\n    ss.source_files = 'src/textfield/src'\n    ss.dependency 'Nimbus/Core'\n  end\n\n  s.subspec 'WebController' do |ss|\n    ss.source_files = 'src/webcontroller/src'\n    ss.dependency 'Nimbus/Core'\n    s.resource_bundles = {\n      'WebController' => ['src/webcontroller/resources/NimbusWebController.bundle/*']\n    }\n  end\nend\n"
  },
  {
    "path": "README.mdown",
    "content": "Nimbus is an iOS framework whose feature set grows only as fast as its documentation.\n\n[![Build Status](https://travis-ci.org/jverkoey/nimbus.svg)](https://travis-ci.org/jverkoey/nimbus)\n\nSupport status\n--------------\n\nNimbus is in a **supported maintenance mode**, meaning its feature set and public APIs will not change\nsubstantially over time but high priority bugs will be addressed.\n\nNimbus is maintained and supported on a best-effort basis. Pull requests are welcome with the above in\nmind.\n\nGetting Started\n---------------\n\n- Visit the Nimbus website at [nimbuskit.info](http://nimbuskit.info).\n- [Add Nimbus to your project](http://wiki.nimbuskit.info/Add-Nimbus-to-your-project).\n- Follow Nimbus' development through its [version history](http://docs.nimbuskit.info/group___version-_history.html).\n- See the [latest API diffs](http://docs.nimbuskit.info/group___version-9-3.html).\n- Read the [Three20 Migration Guide](http://docs.nimbuskit.info/group___three20-_migration-_guide.html).\n- Ask questions and get updates via the [Nimbus mailing list](http://groups.google.com/group/nimbusios).\n"
  },
  {
    "path": "docs/Doxyfile",
    "content": "# Doxyfile 1.8.6\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project.\n#\n# All text after a double hash (##) is considered a comment and is placed in\n# front of the TAG it is preceding.\n#\n# All text after a single hash (#) is considered a comment and will be ignored.\n# The format is:\n# TAG = value [value, ...]\n# For lists, items can also be appended using:\n# TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\\\" \\\").\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the config file\n# that follow. The default is UTF-8 which is also the encoding used for all text\n# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv\n# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv\n# for the list of possible encodings.\n# The default value is: UTF-8.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by\n# double-quotes, unless you are using Doxywizard) that should identify the\n# project for which the documentation is generated. This name is used in the\n# title of most generated pages and in a few other places.\n# The default value is: My Project.\n\nPROJECT_NAME           = NimbusKit\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. This\n# could be handy for archiving the generated documentation or if some version\n# control system is used.\n\nPROJECT_NUMBER         = 1.2.1\n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description\n# for a project that appears at the top of each page and should give viewer a\n# quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          = \"The iOS framework that grows only as fast as its documentation\"\n\n# With the PROJECT_LOGO tag one can specify an logo or icon that is included in\n# the documentation. The maximum height of the logo should not exceed 55 pixels\n# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo\n# to the output directory.\n\nPROJECT_LOGO           =\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path\n# into which the generated documentation will be written. If a relative path is\n# entered, it will be relative to the location where doxygen was started. If\n# left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = docs/output\n\n# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-\n# directories (in 2 levels) under the output directory of each output format and\n# will distribute the generated files over these directories. Enabling this\n# option can be useful when feeding doxygen a huge amount of source files, where\n# putting all generated files in the same directory would otherwise causes\n# performance problems for the file system.\n# The default value is: NO.\n\nCREATE_SUBDIRS         = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all constant output in the proper language.\n# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,\n# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),\n# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,\n# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),\n# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,\n# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,\n# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,\n# Ukrainian and Vietnamese.\n# The default value is: English.\n\nOUTPUT_LANGUAGE        = English\n\n# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member\n# descriptions after the members that are listed in the file and class\n# documentation (similar to Javadoc). Set to NO to disable this.\n# The default value is: YES.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief\n# description of a member or function before the detailed description\n#\n# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\n# brief descriptions will be completely suppressed.\n# The default value is: YES.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator that is\n# used to form the text in various listings. Each string in this list, if found\n# as the leading text of the brief description, will be stripped from the text\n# and the result, after processing the whole list, is used as the annotated\n# text. Otherwise, the brief description is used as-is. If left blank, the\n# following values are used ($name is automatically replaced with the name of\n# the entity):The $name class, The $name widget, The $name file, is, provides,\n# specifies, contains, represents, a, an and the.\n\nABBREVIATE_BRIEF       = \"The $name class\" \\\n                         \"The $name widget\" \\\n                         \"The $name file\" \\\n                         is \\\n                         provides \\\n                         specifies \\\n                         contains \\\n                         represents \\\n                         a \\\n                         an \\\n                         the\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\n# doxygen will generate a detailed section even if there is only a brief\n# description.\n# The default value is: NO.\n\nALWAYS_DETAILED_SEC    = YES\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\n# inherited members of a class in the documentation of that class as if those\n# members were ordinary class members. Constructors, destructors and assignment\n# operators of the base classes will not be shown.\n# The default value is: NO.\n\nINLINE_INHERITED_MEMB  = YES\n\n# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path\n# before files name in the file list and in the header files. If set to NO the\n# shortest path that makes the file name unique will be used\n# The default value is: YES.\n\nFULL_PATH_NAMES        = YES\n\n# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.\n# Stripping is only done if one of the specified strings matches the left-hand\n# part of the path. The tag can be used to show relative paths in the file list.\n# If left blank the directory from which doxygen is run is used as the path to\n# strip.\n#\n# Note that you can specify absolute paths here, but also relative paths, which\n# will be relative from the directory where doxygen is started.\n# This tag requires that the tag FULL_PATH_NAMES is set to YES.\n\nSTRIP_FROM_PATH        =\n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the\n# path mentioned in the documentation of a class, which tells the reader which\n# header file to include in order to use a class. If left blank only the name of\n# the header file containing the class definition is used. Otherwise one should\n# specify the list of include paths that are normally passed to the compiler\n# using the -I flag.\n\nSTRIP_FROM_INC_PATH    =\n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but\n# less readable) file names. This can be useful is your file systems doesn't\n# support long names like on DOS, Mac, or CD-ROM.\n# The default value is: NO.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the\n# first line (until the first dot) of a Javadoc-style comment as the brief\n# description. If set to NO, the Javadoc-style will behave just like regular Qt-\n# style comments (thus requiring an explicit @brief command for a brief\n# description.)\n# The default value is: NO.\n\nJAVADOC_AUTOBRIEF      = YES\n\n# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first\n# line (until the first dot) of a Qt-style comment as the brief description. If\n# set to NO, the Qt-style will behave just like regular Qt-style comments (thus\n# requiring an explicit \\brief command for a brief description.)\n# The default value is: NO.\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a\n# multi-line C++ special comment block (i.e. a block of //! or /// comments) as\n# a brief description. This used to be the default behavior. The new default is\n# to treat a multi-line C++ comment block as a detailed description. Set this\n# tag to YES if you prefer the old behavior instead.\n#\n# Note that setting this tag to YES also means that rational rose comments are\n# not recognized any more.\n# The default value is: NO.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the\n# documentation from any documented member that it re-implements.\n# The default value is: YES.\n\nINHERIT_DOCS           = NO\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a\n# new page for each member. If set to NO, the documentation of a member will be\n# part of the file/class/namespace that contains it.\n# The default value is: NO.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen\n# uses this value to replace tabs by spaces in code fragments.\n# Minimum value: 1, maximum value: 16, default value: 4.\n\nTAB_SIZE               = 2\n\n# This tag can be used to specify a number of aliases that act as commands in\n# the documentation. An alias has the form:\n# name=value\n# For example adding\n# \"sideeffect=@par Side Effects:\\n\"\n# will allow you to put the command \\sideeffect (or @sideeffect) in the\n# documentation, which will result in a user-defined paragraph with heading\n# \"Side Effects:\". You can put \\n's in the value part of an alias to insert\n# newlines.\n\nALIASES                =\n\n# This tag can be used to specify a number of word-keyword mappings (TCL only).\n# A mapping has the form \"name=value\". For example adding \"class=itcl::class\"\n# will allow you to use the command class in the itcl::class meaning.\n\nTCL_SUBST              =\n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources\n# only. Doxygen will then generate output that is more tailored for C. For\n# instance, some of the names that are used will be different. The list of all\n# members will be omitted, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_FOR_C  = NO\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or\n# Python sources only. Doxygen will then generate output that is more tailored\n# for that language. For instance, namespaces will be presented as packages,\n# qualified scopes will look different, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\n# sources. Doxygen will then generate output that is tailored for Fortran.\n# The default value is: NO.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\n# sources. Doxygen will then generate output that is tailored for VHDL.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it\n# parses. With this tag you can assign which parser to use for a given\n# extension. Doxygen has a built-in mapping, but you can override or extend it\n# using this tag. The format is ext=language, where ext is a file extension, and\n# language is one of the parsers supported by doxygen: IDL, Java, Javascript,\n# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make\n# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C\n# (default is Fortran), use: inc=Fortran f=C.\n#\n# Note For files without extension you can use no_extension as a placeholder.\n#\n# Note that for custom extensions you also need to set FILE_PATTERNS otherwise\n# the files are not read by doxygen.\n\nEXTENSION_MAPPING      =\n\n# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments\n# according to the Markdown format, which allows for more readable\n# documentation. See http://daringfireball.net/projects/markdown/ for details.\n# The output of markdown processing is further processed by doxygen, so you can\n# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in\n# case of backward compatibilities issues.\n# The default value is: YES.\n\nMARKDOWN_SUPPORT       = YES\n\n# When enabled doxygen tries to link words that correspond to documented\n# classes, or namespaces to their corresponding documentation. Such a link can\n# be prevented in individual cases by by putting a % sign in front of the word\n# or globally by setting AUTOLINK_SUPPORT to NO.\n# The default value is: YES.\n\nAUTOLINK_SUPPORT       = YES\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\n# to include (a tag file for) the STL sources as input, then you should set this\n# tag to YES in order to let doxygen match functions declarations and\n# definitions whose arguments contain STL classes (e.g. func(std::string);\n# versus func(std::string) {}). This also make the inheritance and collaboration\n# diagrams that involve STL classes more complete and accurate.\n# The default value is: NO.\n\nBUILTIN_STL_SUPPORT    = NO\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to\n# enable parsing support.\n# The default value is: NO.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:\n# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen\n# will parse them like normal C++ but will assume all classes use public instead\n# of private inheritance when no explicit protection keyword is present.\n# The default value is: NO.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate\n# getter and setter methods for a property. Setting this option to YES will make\n# doxygen to replace the get and set methods by a property in the documentation.\n# This will only work if the methods are indeed getting or setting a simple\n# type. If this is not the case, or you want to show the methods anyway, you\n# should set this option to NO.\n# The default value is: YES.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\n# tag is set to YES, then doxygen will reuse the documentation of the first\n# member in the group (if any) for the other members of the group. By default\n# all members of a group must be documented explicitly.\n# The default value is: NO.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# Set the SUBGROUPING tag to YES to allow class member groups of the same type\n# (for instance a group of public functions) to be put as a subgroup of that\n# type (e.g. under the Public Functions section). Set it to NO to prevent\n# subgrouping. Alternatively, this can be done per class using the\n# \\nosubgrouping command.\n# The default value is: YES.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions\n# are shown inside the group in which they are included (e.g. using \\ingroup)\n# instead of on a separate page (for HTML and Man pages) or section (for LaTeX\n# and RTF).\n#\n# Note that this feature does not work in combination with\n# SEPARATE_MEMBER_PAGES.\n# The default value is: NO.\n\nINLINE_GROUPED_CLASSES = NO\n\n# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions\n# with only public data fields or simple typedef fields will be shown inline in\n# the documentation of the scope in which they are defined (i.e. file,\n# namespace, or group documentation), provided this scope is documented. If set\n# to NO, structs, classes, and unions are shown on a separate page (for HTML and\n# Man pages) or section (for LaTeX and RTF).\n# The default value is: NO.\n\nINLINE_SIMPLE_STRUCTS  = NO\n\n# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or\n# enum is documented as struct, union, or enum with the name of the typedef. So\n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\n# with name TypeT. When disabled the typedef will appear as a member of a file,\n# namespace, or class. And the struct will be named TypeS. This can typically be\n# useful for C code in case the coding convention dictates that all compound\n# types are typedef'ed and only the typedef is referenced, never the tag name.\n# The default value is: NO.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This\n# cache is used to resolve symbols given their name and scope. Since this can be\n# an expensive process and often the same symbol appears multiple times in the\n# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small\n# doxygen will become slower. If the cache is too large, memory is wasted. The\n# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range\n# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536\n# symbols. At the end of a run doxygen will report the cache usage and suggest\n# the optimal cache size from a speed point of view.\n# Minimum value: 0, maximum value: 9, default value: 0.\n\nLOOKUP_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in\n# documentation are documented, even if no documentation was available. Private\n# class members and static file members will be hidden unless the\n# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.\n# Note: This will also disable the warnings about undocumented members that are\n# normally produced when WARNINGS is set to YES.\n# The default value is: NO.\n\nEXTRACT_ALL            = NO\n\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will\n# be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal\n# scope will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PACKAGE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES all static members of a file will be\n# included in the documentation.\n# The default value is: NO.\n\nEXTRACT_STATIC         = NO\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined\n# locally in source files will be included in the documentation. If set to NO\n# only classes defined in header files are included. Does not have any effect\n# for Java sources.\n# The default value is: YES.\n\nEXTRACT_LOCAL_CLASSES  = NO\n\n# This flag is only useful for Objective-C code. When set to YES local methods,\n# which are defined in the implementation section but not in the interface are\n# included in the documentation. If set to NO only methods in the interface are\n# included.\n# The default value is: NO.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be\n# extracted and appear in the documentation as a namespace called\n# 'anonymous_namespace{file}', where file will be replaced with the base name of\n# the file that contains the anonymous namespace. By default anonymous namespace\n# are hidden.\n# The default value is: NO.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all\n# undocumented members inside documented classes or files. If set to NO these\n# members will be included in the various overviews, but no documentation\n# section is generated. This option has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_MEMBERS     = YES\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all\n# undocumented classes that are normally visible in the class hierarchy. If set\n# to NO these classes will be included in the various overviews. This option has\n# no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_CLASSES     = YES\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend\n# (class|struct|union) declarations. If set to NO these declarations will be\n# included in the documentation.\n# The default value is: NO.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any\n# documentation blocks found inside the body of a function. If set to NO these\n# blocks will be appended to the function's detailed documentation block.\n# The default value is: NO.\n\nHIDE_IN_BODY_DOCS      = YES\n\n# The INTERNAL_DOCS tag determines if documentation that is typed after a\n# \\internal command is included. If the tag is set to NO then the documentation\n# will be excluded. Set it to YES to include the internal documentation.\n# The default value is: NO.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file\n# names in lower-case letters. If set to YES upper-case letters are also\n# allowed. This is useful if you have classes or files whose names only differ\n# in case and if your file system supports case sensitive file names. Windows\n# and Mac users are advised to set this option to NO.\n# The default value is: system dependent.\n\nCASE_SENSE_NAMES       = YES\n\n# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with\n# their full class and namespace scopes in the documentation. If set to YES the\n# scope will be hidden.\n# The default value is: NO.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of\n# the files that are included by a file in the documentation of that file.\n# The default value is: YES.\n\nSHOW_INCLUDE_FILES     = NO\n\n# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each\n# grouped member an include statement to the documentation, telling the reader\n# which file to include in order to use the member.\n# The default value is: NO.\n\nSHOW_GROUPED_MEMB_INC  = NO\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include\n# files with double quotes in the documentation rather than with sharp brackets.\n# The default value is: NO.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the\n# documentation for inline members.\n# The default value is: YES.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the\n# (detailed) documentation of file and class members alphabetically by member\n# name. If set to NO the members will appear in declaration order.\n# The default value is: YES.\n\nSORT_MEMBER_DOCS       = NO\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief\n# descriptions of file, namespace and class members alphabetically by member\n# name. If set to NO the members will appear in declaration order. Note that\n# this will also influence the order of the classes in the class list.\n# The default value is: NO.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the\n# (brief and detailed) documentation of class members so that constructors and\n# destructors are listed first. If set to NO the constructors will appear in the\n# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.\n# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief\n# member documentation.\n# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting\n# detailed member documentation.\n# The default value is: NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy\n# of group names into alphabetical order. If set to NO the group names will\n# appear in their defined order.\n# The default value is: NO.\n\nSORT_GROUP_NAMES       = YES\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by\n# fully-qualified names, including namespaces. If set to NO, the class list will\n# be sorted only by class name, not including the namespace part.\n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\n# Note: This option applies only to the class list, not to the alphabetical\n# list.\n# The default value is: NO.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper\n# type resolution of all parameters of a function it will reject a match between\n# the prototype and the implementation of a member function even if there is\n# only one candidate or it is obvious which candidate to choose by doing a\n# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still\n# accept a match between prototype and implementation in such cases.\n# The default value is: NO.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the\n# todo list. This list is created by putting \\todo commands in the\n# documentation.\n# The default value is: YES.\n\nGENERATE_TODOLIST      = NO\n\n# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the\n# test list. This list is created by putting \\test commands in the\n# documentation.\n# The default value is: YES.\n\nGENERATE_TESTLIST      = NO\n\n# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug\n# list. This list is created by putting \\bug commands in the documentation.\n# The default value is: YES.\n\nGENERATE_BUGLIST       = NO\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)\n# the deprecated list. This list is created by putting \\deprecated commands in\n# the documentation.\n# The default value is: YES.\n\nGENERATE_DEPRECATEDLIST= NO\n\n# The ENABLED_SECTIONS tag can be used to enable conditional documentation\n# sections, marked by \\if <section_label> ... \\endif and \\cond <section_label>\n# ... \\endcond blocks.\n\nENABLED_SECTIONS       =\n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the\n# initial value of a variable or macro / define can have for it to appear in the\n# documentation. If the initializer consists of more lines than specified here\n# it will be hidden. Use a value of 0 to hide initializers completely. The\n# appearance of the value of individual variables and macros / defines can be\n# controlled using \\showinitializer or \\hideinitializer command in the\n# documentation regardless of this setting.\n# Minimum value: 0, maximum value: 10000, default value: 30.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at\n# the bottom of the documentation of classes and structs. If set to YES the list\n# will mention the files that were used to generate the documentation.\n# The default value is: YES.\n\nSHOW_USED_FILES        = NO\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This\n# will remove the Files entry from the Quick Index and from the Folder Tree View\n# (if specified).\n# The default value is: YES.\n\nSHOW_FILES             = NO\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces\n# page. This will remove the Namespaces entry from the Quick Index and from the\n# Folder Tree View (if specified).\n# The default value is: YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that\n# doxygen should invoke to get the current version for each file (typically from\n# the version control system). Doxygen will invoke the program by executing (via\n# popen()) the command command input-file, where command is the value of the\n# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided\n# by doxygen. Whatever the program writes to standard output is used as the file\n# version. For an example see the documentation.\n\nFILE_VERSION_FILTER    =\n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\n# by doxygen. The layout file controls the global structure of the generated\n# output files in an output format independent way. To create the layout file\n# that represents doxygen's defaults, run doxygen with the -l option. You can\n# optionally specify a file name after the option, if omitted DoxygenLayout.xml\n# will be used as the name of the layout file.\n#\n# Note that if you run doxygen from a directory containing a file called\n# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE\n# tag is left empty.\n\nLAYOUT_FILE            = docs/layout/DoxygenLayout.xml\n\n# The CITE_BIB_FILES tag can be used to specify one or more bib files containing\n# the reference definitions. This must be a list of .bib files. The .bib\n# extension is automatically appended if omitted. This requires the bibtex tool\n# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.\n# For LaTeX the style of the bibliography can be controlled using\n# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the\n# search path. Do not use file names with spaces, bibtex cannot handle them. See\n# also \\cite for info how to create references.\n\nCITE_BIB_FILES         =\n\n#---------------------------------------------------------------------------\n# Configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated to\n# standard output by doxygen. If QUIET is set to YES this implies that the\n# messages are off.\n# The default value is: NO.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are\n# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES\n# this implies that the warnings are on.\n#\n# Tip: Turn warnings on while writing the documentation.\n# The default value is: YES.\n\nWARNINGS               = YES\n\n# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate\n# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag\n# will automatically be disabled.\n# The default value is: YES.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for\n# potential errors in the documentation, such as not documenting some parameters\n# in a documented function, or documenting parameters that don't exist or using\n# markup commands wrongly.\n# The default value is: YES.\n\nWARN_IF_DOC_ERROR      = YES\n\n# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that\n# are documented, but have no documentation for their parameters or return\n# value. If set to NO doxygen will only warn about wrong or incomplete parameter\n# documentation, but not about the absence of documentation.\n# The default value is: NO.\n\nWARN_NO_PARAMDOC       = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that doxygen\n# can produce. The string should contain the $file, $line, and $text tags, which\n# will be replaced by the file and line number from which the warning originated\n# and the warning text. Optionally the format may contain $version, which will\n# be replaced by the version of the file (if it could be obtained via\n# FILE_VERSION_FILTER)\n# The default value is: $file:$line: $text.\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning and error\n# messages should be written. If left blank the output is written to standard\n# error (stderr).\n\nWARN_LOGFILE           =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag is used to specify the files and/or directories that contain\n# documented source files. You may enter file names like myfile.cpp or\n# directories like /usr/src/myproject. Separate the files or directories with\n# spaces.\n# Note: If this tag is empty the current directory is searched.\n\nINPUT                  = src\n\n# This tag can be used to specify the character encoding of the source files\n# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses\n# libiconv (or the iconv built into libc) for the transcoding. See the libiconv\n# documentation (see: http://www.gnu.org/software/libiconv) for the list of\n# possible encodings.\n# The default value is: UTF-8.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the\n# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank the\n# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,\n# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,\n# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,\n# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,\n# *.qsf, *.as and *.js.\n\nFILE_PATTERNS          = *.h \\\n                         *.m \\\n                         *.mm\n\n# The RECURSIVE tag can be used to specify whether or not subdirectories should\n# be searched for input files as well.\n# The default value is: NO.\n\nRECURSIVE              = YES\n\n# The EXCLUDE tag can be used to specify files and/or directories that should be\n# excluded from the INPUT source files. This way you can easily exclude a\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n#\n# Note that relative paths are relative to the directory from which doxygen is\n# run.\n\nEXCLUDE                =\n\n# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or\n# directories that are symbolic links (a Unix file system feature) are excluded\n# from the input.\n# The default value is: NO.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n# certain files from those directories.\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       =\n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\n# (namespaces, classes, functions, etc.) that should be excluded from the\n# output. The symbol name can be a fully qualified name, a word, or if the\n# wildcard * is used, a substring. Examples: ANamespace, AClass,\n# AClass::ANamespace, ANamespace::*Test\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories use the pattern */test/*\n\nEXCLUDE_SYMBOLS        =\n\n# The EXAMPLE_PATH tag can be used to specify one or more files or directories\n# that contain example code fragments that are included (see the \\include\n# command).\n\nEXAMPLE_PATH           = src/core/examples/ \\\n                         src/models/examples/\n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank all\n# files are included.\n\nEXAMPLE_PATTERNS       = *\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\n# searched for input files to be used with the \\include or \\dontinclude commands\n# irrespective of the value of the RECURSIVE tag.\n# The default value is: NO.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or directories\n# that contain images that are to be included in the documentation (see the\n# \\image command).\n\nIMAGE_PATH             = docs/gfx/\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should\n# invoke to filter for each input file. Doxygen will invoke the filter program\n# by executing (via popen()) the command:\n#\n# <filter> <input-file>\n#\n# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the\n# name of an input file. Doxygen will then use the output that the filter\n# program writes to standard output. If FILTER_PATTERNS is specified, this tag\n# will be ignored.\n#\n# Note that the filter must not add or remove lines; it is applied before the\n# code is scanned, but not when the output code is generated. If lines are added\n# or removed, the anchors will not be placed correctly.\n\nINPUT_FILTER           =\n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\n# basis. Doxygen will compare the file name with each pattern and apply the\n# filter if there is a match. The filters are a list of the form: pattern=filter\n# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how\n# filters are used. If the FILTER_PATTERNS tag is empty or if none of the\n# patterns match the file name, INPUT_FILTER is applied.\n\nFILTER_PATTERNS        =\n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\n# INPUT_FILTER ) will also be used to filter the input files that are used for\n# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).\n# The default value is: NO.\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\n# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and\n# it is also possible to disable source filtering for a specific pattern using\n# *.ext= (so without naming a filter).\n# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.\n\nFILTER_SOURCE_PATTERNS =\n\n# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that\n# is part of the input, its contents will be placed on the main page\n# (index.html). This can be useful if you have a project on for instance GitHub\n# and want to reuse the introduction page also for the doxygen output.\n\nUSE_MDFILE_AS_MAINPAGE =\n\n#---------------------------------------------------------------------------\n# Configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will be\n# generated. Documented entities will be cross-referenced with these sources.\n#\n# Note: To get rid of all source code in the generated output, make sure that\n# also VERBATIM_HEADERS is set to NO.\n# The default value is: NO.\n\nSOURCE_BROWSER         = YES\n\n# Setting the INLINE_SOURCES tag to YES will include the body of functions,\n# classes and enums directly into the documentation.\n# The default value is: NO.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any\n# special comment blocks from generated source code fragments. Normal C, C++ and\n# Fortran comments will always remain visible.\n# The default value is: YES.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES then for each documented\n# function all documented functions referencing it will be listed.\n# The default value is: NO.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES then for each documented function\n# all documented entities called/used by that function will be listed.\n# The default value is: NO.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set\n# to YES, then the hyperlinks from functions in REFERENCES_RELATION and\n# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will\n# link to the documentation.\n# The default value is: YES.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the\n# source code will show a tooltip with additional information such as prototype,\n# brief description and links to the definition and documentation. Since this\n# will make the HTML file larger and loading of large files a bit slower, you\n# can opt to disable this feature.\n# The default value is: YES.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nSOURCE_TOOLTIPS        = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code will\n# point to the HTML generated by the htags(1) tool instead of doxygen built-in\n# source browser. The htags tool is part of GNU's global source tagging system\n# (see http://www.gnu.org/software/global/global.html). You will need version\n# 4.8.6 or higher.\n#\n# To use it do the following:\n# - Install the latest version of global\n# - Enable SOURCE_BROWSER and USE_HTAGS in the config file\n# - Make sure the INPUT points to the root of the source tree\n# - Run doxygen as normal\n#\n# Doxygen will invoke htags (and that will in turn invoke gtags), so these\n# tools must be available from the command line (i.e. in the search path).\n#\n# The result: instead of the source browser generated by doxygen, the links to\n# source code will now point to the output of htags.\n# The default value is: NO.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a\n# verbatim copy of the header file for each class for which an include is\n# specified. Set to NO to disable this.\n# See also: Section \\class.\n# The default value is: YES.\n\nVERBATIM_HEADERS       = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all\n# compounds will be generated. Enable this if the project contains a lot of\n# classes, structs, unions or interfaces.\n# The default value is: YES.\n\nALPHABETICAL_INDEX     = YES\n\n# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in\n# which the alphabetical index list will be split.\n# Minimum value: 1, maximum value: 20, default value: 5.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nCOLS_IN_ALPHA_INDEX    = 5\n\n# In case all classes in a project start with a common prefix, all classes will\n# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag\n# can be used to specify a prefix (or a list of prefixes) that should be ignored\n# while generating the index headers.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nIGNORE_PREFIX          = NI\n\n#---------------------------------------------------------------------------\n# Configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output\n# The default value is: YES.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each\n# generated HTML page (for example: .htm, .php, .asp).\n# The default value is: .html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a user-defined HTML header file for\n# each generated HTML page. If the tag is left blank doxygen will generate a\n# standard header.\n#\n# To get valid HTML the header file that includes any scripts and style sheets\n# that doxygen needs, which is dependent on the configuration options used (e.g.\n# the setting GENERATE_TREEVIEW). It is highly recommended to start with a\n# default header using\n# doxygen -w html new_header.html new_footer.html new_stylesheet.css\n# YourConfigFile\n# and then modify the file new_header.html. See also section \"Doxygen usage\"\n# for information on how to generate the default header that doxygen normally\n# uses.\n# Note: The header is subject to change so you typically have to regenerate the\n# default header when upgrading to a newer version of doxygen. For a description\n# of the possible markers and block names see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_HEADER            = docs/layout/header.html\n\n# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each\n# generated HTML page. If the tag is left blank doxygen will generate a standard\n# footer. See HTML_HEADER for more information on how to generate a default\n# footer and what special commands can be used inside the footer. See also\n# section \"Doxygen usage\" for information on how to generate the default footer\n# that doxygen normally uses.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FOOTER            = docs/layout/footer.html\n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style\n# sheet that is used by each HTML page. It can be used to fine-tune the look of\n# the HTML output. If left blank doxygen will generate a default style sheet.\n# See also section \"Doxygen usage\" for information on how to generate the style\n# sheet that doxygen normally uses.\n# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as\n# it is more robust and this tag (HTML_STYLESHEET) will in the future become\n# obsolete.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_STYLESHEET        = \n\n# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-\n# defined cascading style sheet that is included after the standard style sheets\n# created by doxygen. Using this option one can overrule certain style aspects.\n# This is preferred over using HTML_STYLESHEET since it does not replace the\n# standard style sheet and is therefor more robust against future updates.\n# Doxygen will copy the style sheet file to the output directory. For an example\n# see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_STYLESHEET  = docs/css/appledocs.css\n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the HTML output directory. Note\n# that these files will be copied to the base HTML output directory. Use the\n# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\n# files. In the HTML_STYLESHEET file, use the file name only. Also note that the\n# files will be copied as-is; there are no commands or markers available.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_FILES       = docs/js/widget.js \\\n                         docs/gfx/nimbus128.png \\\n                         docs/css/nimbuskit.css\n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen\n# will adjust the colors in the stylesheet and background images according to\n# this color. Hue is specified as an angle on a colorwheel, see\n# http://en.wikipedia.org/wiki/Hue for more information. For instance the value\n# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300\n# purple, and 360 is red again.\n# Minimum value: 0, maximum value: 359, default value: 220.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors\n# in the HTML output. For a value of 0 the output will use grayscales only. A\n# value of 255 will produce the most vivid colors.\n# Minimum value: 0, maximum value: 255, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_SAT    = 100\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the\n# luminance component of the colors in the HTML output. Values below 100\n# gradually make the output lighter, whereas values above 100 make the output\n# darker. The value divided by 100 is the actual gamma applied, so 80 represents\n# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not\n# change the gamma.\n# Minimum value: 40, maximum value: 240, default value: 80.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_GAMMA  = 130\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\n# page will contain the date and time when the page was generated. Setting this\n# to NO can help when comparing the output of multiple runs.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_TIMESTAMP         = NO\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\n# documentation will contain sections that can be hidden and shown after the\n# page has loaded.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries\n# shown in the various tree structured indices initially; the user can expand\n# and collapse entries dynamically later on. Doxygen will expand the tree to\n# such a level that at most the specified number of entries are visible (unless\n# a fully collapsed tree already exceeds this amount). So setting the number of\n# entries 1 will produce a full collapsed tree by default. 0 is a special value\n# representing an infinite number of entries and will result in a full expanded\n# tree by default.\n# Minimum value: 0, maximum value: 9999, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_INDEX_NUM_ENTRIES = 100\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files will be\n# generated that can be used as input for Apple's Xcode 3 integrated development\n# environment (see: http://developer.apple.com/tools/xcode/), introduced with\n# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a\n# Makefile in the HTML output directory. Running make will produce the docset in\n# that directory and running make install will install the docset in\n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at\n# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html\n# for more information.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_DOCSET        = YES\n\n# This tag determines the name of the docset feed. A documentation feed provides\n# an umbrella under which multiple documentation sets from a single provider\n# (such as a company or product suite) can be grouped.\n# The default value is: Doxygen generated docs.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_FEEDNAME        = \"NimbusKit Docs\"\n\n# This tag specifies a string that should uniquely identify the documentation\n# set bundle. This should be a reverse domain-name style string, e.g.\n# com.mycompany.MyDocSet. Doxygen will append .docset to the name.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_BUNDLE_ID       = org.nimbuskit\n\n# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify\n# the documentation publisher. This should be a reverse domain-name style\n# string, e.g. com.mycompany.MyDocSet.documentation.\n# The default value is: org.doxygen.Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_ID    = org.nimbuskit\n\n# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.\n# The default value is: Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_NAME  = NimbusKit\n\n# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three\n# additional HTML index files: index.hhp, index.hhc, and index.hhk. The\n# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop\n# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on\n# Windows.\n#\n# The HTML Help Workshop contains a compiler that can convert all HTML output\n# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML\n# files are now used as the Windows 98 help format, and will replace the old\n# Windows help format (.hlp) on all Windows platforms in the future. Compressed\n# HTML files also contain an index, a table of contents, and you can search for\n# words in the documentation. The HTML workshop also contains a viewer for\n# compressed HTML files.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_HTMLHELP      = NO\n\n# The CHM_FILE tag can be used to specify the file name of the resulting .chm\n# file. You can add a path in front of the file if the result should not be\n# written to the html output directory.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_FILE               =\n\n# The HHC_LOCATION tag can be used to specify the location (absolute path\n# including file name) of the HTML help compiler ( hhc.exe). If non-empty\n# doxygen will try to run the HTML help compiler on the generated index.hhp.\n# The file has to be specified with full path.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nHHC_LOCATION           =\n\n# The GENERATE_CHI flag controls if a separate .chi index file is generated (\n# YES) or that it should be included in the master .chm file ( NO).\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nGENERATE_CHI           = NO\n\n# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)\n# and project file content.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_INDEX_ENCODING     =\n\n# The BINARY_TOC flag controls whether a binary table of contents is generated (\n# YES) or a normal table of contents ( NO) in the .chm file.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members to\n# the table of contents of the HTML help documentation and to the tree view.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that\n# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help\n# (.qch) of the generated HTML documentation.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify\n# the file name of the resulting .qch file. The path specified is relative to\n# the HTML output folder.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQCH_FILE               =\n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help\n# Project output. For more information please see Qt Help Project / Namespace\n# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_NAMESPACE          = org.doxygen.Project\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt\n# Help Project output. For more information please see Qt Help Project / Virtual\n# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-\n# folders).\n# The default value is: doc.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom\n# filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_NAME   =\n\n# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the\n# custom filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_ATTRS  =\n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\n# project's filter section matches. Qt Help Project / Filter Attributes (see:\n# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_SECT_FILTER_ATTRS  =\n\n# The QHG_LOCATION tag can be used to specify the location of Qt's\n# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the\n# generated .qhp file.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHG_LOCATION           =\n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be\n# generated, together with the HTML files, they form an Eclipse help plugin. To\n# install this plugin and make it available under the help contents menu in\n# Eclipse, the contents of the directory containing the HTML and XML files needs\n# to be copied into the plugins directory of eclipse. The name of the directory\n# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.\n# After copying Eclipse needs to be restarted before the help appears.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the Eclipse help plugin. When installing the plugin\n# the directory name containing the HTML and XML files should also have this\n# name. Each documentation set should have its own identifier.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.\n\nECLIPSE_DOC_ID         = org.doxygen.Project\n\n# If you want full control over the layout of the generated HTML pages it might\n# be necessary to disable the index and replace it with your own. The\n# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top\n# of each HTML page. A value of NO enables the index and the value YES disables\n# it. Since the tabs in the index contain the same information as the navigation\n# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nDISABLE_INDEX          = YES\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\n# structure should be generated to display hierarchical information. If the tag\n# value is set to YES, a side panel will be generated containing a tree-like\n# index structure (just like the one that is generated for HTML Help). For this\n# to work a browser that supports JavaScript, DHTML, CSS and frames is required\n# (i.e. any modern browser). Windows users are probably better off using the\n# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can\n# further fine-tune the look of the index. As an example, the default style\n# sheet generated by doxygen has an example that shows how to put an image at\n# the root of the tree instead of the PROJECT_NAME. Since the tree basically has\n# the same information as the tab index, you could consider setting\n# DISABLE_INDEX to YES when enabling this option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_TREEVIEW      = YES\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that\n# doxygen will group on one line in the generated HTML documentation.\n#\n# Note that a value of 0 will completely suppress the enum values from appearing\n# in the overview section.\n# Minimum value: 0, maximum value: 20, default value: 4.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used\n# to set the initial width (in pixels) of the frame in which the tree is shown.\n# Minimum value: 0, maximum value: 1500, default value: 250.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nTREEVIEW_WIDTH         = 200\n\n# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to\n# external symbols imported via tag files in a separate window.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# Use this tag to change the font size of LaTeX formulas included as images in\n# the HTML documentation. When you change the font size after a successful\n# doxygen run you need to manually remove any form_*.png images from the HTML\n# output directory to force them to be regenerated.\n# Minimum value: 8, maximum value: 50, default value: 10.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_FONTSIZE       = 10\n\n# Use the FORMULA_TRANPARENT tag to determine whether or not the images\n# generated for formulas are transparent PNGs. Transparent PNGs are not\n# supported properly for IE 6.0, but are supported on all modern browsers.\n#\n# Note that when changing this option you need to delete any form_*.png files in\n# the HTML output directory before the changes have effect.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_TRANSPARENT    = YES\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see\n# http://www.mathjax.org) which uses client side Javascript for the rendering\n# instead of using prerendered bitmaps. Use this if you do not have LaTeX\n# installed or if you want to formulas look prettier in the HTML output. When\n# enabled you may also need to install MathJax separately and configure the path\n# to it using the MATHJAX_RELPATH option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nUSE_MATHJAX            = NO\n\n# When MathJax is enabled you can set the default output format to be used for\n# the MathJax output. See the MathJax site (see:\n# http://docs.mathjax.org/en/latest/output.html) for more details.\n# Possible values are: HTML-CSS (which is slower, but has the best\n# compatibility), NativeMML (i.e. MathML) and SVG.\n# The default value is: HTML-CSS.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_FORMAT         = HTML-CSS\n\n# When MathJax is enabled you need to specify the location relative to the HTML\n# output directory using the MATHJAX_RELPATH option. The destination directory\n# should contain the MathJax.js script. For instance, if the mathjax directory\n# is located at the same level as the HTML output directory, then\n# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax\n# Content Delivery Network so you can quickly see the result without installing\n# MathJax. However, it is strongly recommended to install a local copy of\n# MathJax from http://www.mathjax.org before deployment.\n# The default value is: http://cdn.mathjax.org/mathjax/latest.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest\n\n# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax\n# extension names that should be enabled during MathJax rendering. For example\n# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_EXTENSIONS     =\n\n# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces\n# of code that will be used on startup of the MathJax code. See the MathJax site\n# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an\n# example see the documentation.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_CODEFILE       =\n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box for\n# the HTML output. The underlying search engine uses javascript and DHTML and\n# should work on any modern browser. Note that when using HTML help\n# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)\n# there is already a search function so this one should typically be disabled.\n# For large projects the javascript based search engine can be slow, then\n# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to\n# search using the keyboard; to jump to the search box use <access key> + S\n# (what the <access key> is depends on the OS and browser, but it is typically\n# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down\n# key> to jump into the search results window, the results can be navigated\n# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel\n# the search. The filter options can be selected when the cursor is inside the\n# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>\n# to select a filter and <Enter> or <escape> to activate or cancel the filter\n# option.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nSEARCHENGINE           = NO\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n# implemented using a web server instead of a web client using Javascript. There\n# are two flavors of web server based searching depending on the EXTERNAL_SEARCH\n# setting. When disabled, doxygen will generate a PHP script for searching and\n# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing\n# and searching needs to be provided by external tools. See the section\n# \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSERVER_BASED_SEARCH    = NO\n\n# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP\n# script for searching. Instead the search results are written to an XML file\n# which needs to be processed by an external indexer. Doxygen will invoke an\n# external search engine pointed to by the SEARCHENGINE_URL option to obtain the\n# search results.\n#\n# Doxygen ships with an example indexer ( doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/).\n#\n# See the section \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH        = NO\n\n# The SEARCHENGINE_URL should point to a search engine hosted by a web server\n# which will return the search results when EXTERNAL_SEARCH is enabled.\n#\n# Doxygen ships with an example indexer ( doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/). See the section \"External Indexing and\n# Searching\" for details.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHENGINE_URL       =\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed\n# search data is written to a file for indexing by an external tool. With the\n# SEARCHDATA_FILE tag the name of this file can be specified.\n# The default file is: searchdata.xml.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHDATA_FILE        = searchdata.xml\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the\n# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is\n# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple\n# projects and redirect the results back to the right project.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH_ID     =\n\n# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen\n# projects other than the one defined by this configuration file, but that are\n# all added to the same external search index. Each project needs to have a\n# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of\n# to a relative location where the documentation can be found. The format is:\n# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTRA_SEARCH_MAPPINGS  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.\n# The default value is: YES.\n\nGENERATE_LATEX         = NO\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\n# invoked.\n#\n# Note that when enabling USE_PDFLATEX this option is only used for generating\n# bitmaps for formulas in the HTML output, but not in the Makefile that is\n# written to the output directory.\n# The default file is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_CMD_NAME         = latex\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate\n# index for LaTeX.\n# The default file is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used by the\n# printer.\n# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x\n# 14 inches) and executive (7.25 x 10.5 inches).\n# The default value is: a4.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPAPER_TYPE             = a4\n\n# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names\n# that should be included in the LaTeX output. To get the times font for\n# instance you can specify\n# EXTRA_PACKAGES=times\n# If left blank no extra packages will be included.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nEXTRA_PACKAGES         =\n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the\n# generated LaTeX document. The header should contain everything until the first\n# chapter. If it is left blank doxygen will generate a standard header. See\n# section \"Doxygen usage\" for information on how to let doxygen write the\n# default header to a separate file.\n#\n# Note: Only use a user-defined header if you know what you are doing! The\n# following commands have a special meaning inside the header: $title,\n# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will\n# replace them by respectively the title of the page, the current date and time,\n# only the current date, the version number of doxygen, the project name (see\n# PROJECT_NAME), or the project number (see PROJECT_NUMBER).\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HEADER           =\n\n# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the\n# generated LaTeX document. The footer should contain everything after the last\n# chapter. If it is left blank doxygen will generate a standard footer.\n#\n# Note: Only use a user-defined footer if you know what you are doing!\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_FOOTER           =\n\n# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the LATEX_OUTPUT output\n# directory. Note that the files will be copied as-is; there are no commands or\n# markers available.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_FILES      =\n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is\n# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will\n# contain links (just like the HTML output) instead of page references. This\n# makes the output suitable for online browsing using a PDF viewer.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPDF_HYPERLINKS         = YES\n\n# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate\n# the PDF file directly from the LaTeX files. Set this option to YES to get a\n# higher quality PDF documentation.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode\n# command to the generated LaTeX files. This will instruct LaTeX to keep running\n# if errors occur, instead of asking the user for help. This option is also used\n# when generating formulas in HTML.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BATCHMODE        = NO\n\n# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the\n# index chapters (such as File Index, Compound Index, etc.) in the output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HIDE_INDICES     = NO\n\n# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source\n# code with syntax highlighting in the LaTeX output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_SOURCE_CODE      = NO\n\n# The LATEX_BIB_STYLE tag can be used to specify the style to use for the\n# bibliography, e.g. plainnat, or ieeetr. See\n# http://en.wikipedia.org/wiki/BibTeX and \\cite for more info.\n# The default value is: plain.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BIB_STYLE        = plain\n\n#---------------------------------------------------------------------------\n# Configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The\n# RTF output is optimized for Word 97 and may not look too pretty with other RTF\n# readers/editors.\n# The default value is: NO.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: rtf.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will\n# contain hyperlink fields. The RTF file will contain links (just like the HTML\n# output) instead of page references. This makes the output suitable for online\n# browsing using Word or some other Word compatible readers that support those\n# fields.\n#\n# Note: WordPad (write) and others do not support links.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's config\n# file, i.e. a series of assignments. You only have to provide replacements,\n# missing definitions are set to their default value.\n#\n# See also section \"Doxygen usage\" for information on how to generate the\n# default style sheet that doxygen normally uses.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_STYLESHEET_FILE    =\n\n# Set optional variables used in the generation of an RTF document. Syntax is\n# similar to doxygen's config file. A template extensions file can be generated\n# using doxygen -e rtf extensionFile.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_EXTENSIONS_FILE    =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for\n# classes and files.\n# The default value is: NO.\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it. A directory man3 will be created inside the directory specified by\n# MAN_OUTPUT.\n# The default directory is: man.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to the generated\n# man pages. In case the manual section does not start with a number, the number\n# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is\n# optional.\n# The default value is: .3.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_EXTENSION          = .3\n\n# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it\n# will generate one additional man file for each entity documented in the real\n# man page(s). These additional files only source the real man page, but without\n# them the man command would be unable to find the correct page.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that\n# captures the structure of the code including all documentation.\n# The default value is: NO.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: xml.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_OUTPUT             = xml\n\n# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program\n# listings (including syntax highlighting and cross-referencing information) to\n# the XML output. Note that enabling this will significantly increase the size\n# of the XML output.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_PROGRAMLISTING     = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the DOCBOOK output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files\n# that can be used to generate PDF.\n# The default value is: NO.\n\nGENERATE_DOCBOOK       = NO\n\n# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in\n# front of it.\n# The default directory is: docbook.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_OUTPUT         = docbook\n\n#---------------------------------------------------------------------------\n# Configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen\n# Definitions (see http://autogen.sf.net) file that captures the structure of\n# the code including all documentation. Note that this feature is still\n# experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module\n# file that captures the structure of the code including all documentation.\n#\n# Note that this feature is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary\n# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI\n# output from the Perl module output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely\n# formatted so it can be parsed by a human reader. This is useful if you want to\n# understand what is going on. On the other hand, if this tag is set to NO the\n# size of the Perl module output will be much smaller and Perl will parse it\n# just the same.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file are\n# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful\n# so different doxyrules.make files included by the same Makefile don't\n# overwrite each other's variables.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_MAKEVAR_PREFIX =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all\n# C-preprocessor directives found in the sources and include files.\n# The default value is: YES.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names\n# in the source code. If set to NO only conditional compilation will be\n# performed. Macro expansion can be done in a controlled way by setting\n# EXPAND_ONLY_PREDEF to YES.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nMACRO_EXPANSION        = YES\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then\n# the macro expansion is limited to the macros specified with the PREDEFINED and\n# EXPAND_AS_DEFINED tags.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_ONLY_PREDEF     = YES\n\n# If the SEARCH_INCLUDES tag is set to YES the includes files in the\n# INCLUDE_PATH will be searched if a #include is found.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that\n# contain include files that are not input files but should be processed by the\n# preprocessor.\n# This tag requires that the tag SEARCH_INCLUDES is set to YES.\n\nINCLUDE_PATH           =\n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\n# patterns (like *.h and *.hpp) to filter out the header-files in the\n# directories. If left blank, the patterns specified with FILE_PATTERNS will be\n# used.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nINCLUDE_FILE_PATTERNS  =\n\n# The PREDEFINED tag can be used to specify one or more macro names that are\n# defined before the preprocessor is started (similar to the -D option of e.g.\n# gcc). The argument of the tag is a list of macros of the form: name or\n# name=definition (no spaces). If the definition and the \"=\" are omitted, \"=1\"\n# is assumed. To prevent a macro definition from being undefined via #undef or\n# recursively expanded use the := operator instead of the = operator.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nPREDEFINED             = DEBUG \\\n                         NS_BLOCKS_AVAILABLE \\\n                         \"__NI_DEPRECATED_METHOD=\"\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this\n# tag can be used to specify a list of macro names that should be expanded. The\n# macro definition that is found in the sources will be used. Use the PREDEFINED\n# tag if you want to use a different macro definition that overrules the\n# definition found in the source code.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_AS_DEFINED      =\n\n# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will\n# remove all references to function-like macros that are alone on a line, have\n# an all uppercase name, and do not end with a semicolon. Such function macros\n# are typically used for boiler-plate code, and will confuse the parser if not\n# removed.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES tag can be used to specify one or more tag files. For each tag\n# file the location of the external documentation should be added. The format of\n# a tag file without this location is as follows:\n# TAGFILES = file1 file2 ...\n# Adding location for the tag files is done as follows:\n# TAGFILES = file1=loc1 \"file2 = loc2\" ...\n# where loc1 and loc2 can be relative or absolute paths or URLs. See the\n# section \"Linking to external documentation\" for more information about the use\n# of tag files.\n# Note: Each tag file must have a unique name (where the name does NOT include\n# the path). If a tag file is not located in the directory in which doxygen is\n# run, you must also specify the path to the tagfile here.\n\nTAGFILES               =\n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create a\n# tag file that is based on the input files it reads. See section \"Linking to\n# external documentation\" for more information about the usage of tag files.\n\nGENERATE_TAGFILE       =\n\n# If the ALLEXTERNALS tag is set to YES all external class will be listed in the\n# class index. If set to NO only the inherited external classes will be listed.\n# The default value is: NO.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in\n# the modules index. If set to NO, only the current project's groups will be\n# listed.\n# The default value is: YES.\n\nEXTERNAL_GROUPS        = YES\n\n# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in\n# the related pages index. If set to NO, only the current project's pages will\n# be listed.\n# The default value is: YES.\n\nEXTERNAL_PAGES         = YES\n\n# The PERL_PATH should be the absolute path and name of the perl script\n# interpreter (i.e. the result of 'which perl').\n# The default file (with absolute path) is: /usr/bin/perl.\n\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram\n# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to\n# NO turns the diagrams off. Note that this option also works with HAVE_DOT\n# disabled, but it is recommended to install and use dot, since it yields more\n# powerful graphs.\n# The default value is: YES.\n\nCLASS_DIAGRAMS         = YES\n\n# You can define message sequence charts within doxygen comments using the \\msc\n# command. Doxygen will then run the mscgen tool (see:\n# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the\n# documentation. The MSCGEN_PATH tag allows you to specify the directory where\n# the mscgen tool resides. If left empty the tool is assumed to be found in the\n# default search path.\n\nMSCGEN_PATH            =\n\n# You can include diagrams made with dia in doxygen documentation. Doxygen will\n# then run dia to produce the diagram and insert it in the documentation. The\n# DIA_PATH tag allows you to specify the directory where the dia binary resides.\n# If left empty dia is assumed to be found in the default search path.\n\nDIA_PATH               =\n\n# If set to YES, the inheritance and collaboration graphs will hide inheritance\n# and usage relations if the target is undocumented or is not a class.\n# The default value is: YES.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\n# available from the path. This tool is part of Graphviz (see:\n# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent\n# Bell Labs. The other options in this section have no effect if this option is\n# set to NO\n# The default value is: NO.\n\nHAVE_DOT               = NO\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed\n# to run in parallel. When set to 0 doxygen will base this on the number of\n# processors available in the system. You can set it explicitly to a value\n# larger than 0 to get control over the balance between CPU load and processing\n# speed.\n# Minimum value: 0, maximum value: 32, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_NUM_THREADS        = 0\n\n# When you want a differently looking font n the dot files that doxygen\n# generates you can specify the font name using DOT_FONTNAME. You need to make\n# sure dot is able to find the font, which can be done by putting it in a\n# standard location or by setting the DOTFONTPATH environment variable or by\n# setting DOT_FONTPATH to the directory containing the font.\n# The default value is: Helvetica.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of\n# dot graphs.\n# Minimum value: 4, maximum value: 24, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the default font as specified with\n# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set\n# the path where dot can find it using this tag.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTPATH           =\n\n# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for\n# each documented class showing the direct and indirect inheritance relations.\n# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a\n# graph for each documented class showing the direct and indirect implementation\n# dependencies (inheritance, containment, and class references variables) of the\n# class with other documented classes.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for\n# groups, showing the direct groups dependencies.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES doxygen will generate inheritance and\n# collaboration diagrams in a style similar to the OMG's Unified Modeling\n# Language.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LOOK               = NO\n\n# If the UML_LOOK tag is enabled, the fields and methods are shown inside the\n# class node. If there are many fields or methods and many nodes the graph may\n# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the\n# number of items for each type to make the size more manageable. Set this to 0\n# for no limit. Note that the threshold may be exceeded by 50% before the limit\n# is enforced. So when you set the threshold to 10, up to 15 fields may appear,\n# but if the number exceeds 15, the total amount of fields shown is limited to\n# 10.\n# Minimum value: 0, maximum value: 100, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LIMIT_NUM_FIELDS   = 10\n\n# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and\n# collaboration graphs will show the relations between templates and their\n# instances.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to\n# YES then doxygen will generate a graph for each documented file showing the\n# direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDE_GRAPH          = YES\n\n# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are\n# set to YES then doxygen will generate a graph for each documented file showing\n# the direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH tag is set to YES then doxygen will generate a call\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable call graphs for selected\n# functions only using the \\callgraph command.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable caller graphs for selected\n# functions only using the \\callergraph command.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical\n# hierarchy of all classes instead of a textual one.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the\n# dependencies a directory has on other directories in a graphical way. The\n# dependency relations are determined by the #include relations between the\n# files in the directories.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\n# generated by dot.\n# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order\n# to make the SVG files visible in IE 9+ (other browsers do not have this\n# requirement).\n# Possible values are: png, jpg, gif and svg.\n# The default value is: png.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_IMAGE_FORMAT       = png\n\n# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to\n# enable generation of interactive SVG images that allow zooming and panning.\n#\n# Note that this requires a modern browser other than Internet Explorer. Tested\n# and working are Firefox, Chrome, Safari, and Opera.\n# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make\n# the SVG files visible. Older versions of IE do not have SVG support.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINTERACTIVE_SVG        = NO\n\n# The DOT_PATH tag can be used to specify the path where the dot tool can be\n# found. If left blank, it is assumed the dot tool can be found in the path.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_PATH               =\n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that\n# contain dot files that are included in the documentation (see the \\dotfile\n# command).\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOTFILE_DIRS           =\n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that\n# contain msc files that are included in the documentation (see the \\mscfile\n# command).\n\nMSCFILE_DIRS           =\n\n# The DIAFILE_DIRS tag can be used to specify one or more directories that\n# contain dia files that are included in the documentation (see the \\diafile\n# command).\n\nDIAFILE_DIRS           =\n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes\n# that will be shown in the graph. If the number of nodes in a graph becomes\n# larger than this value, doxygen will truncate the graph, which is visualized\n# by representing a node as a red box. Note that doxygen if the number of direct\n# children of the root node in a graph is already larger than\n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that\n# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n# Minimum value: 0, maximum value: 10000, default value: 50.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs\n# generated by dot. A depth value of 3 means that only nodes reachable from the\n# root by following a path via at most 3 edges will be shown. Nodes that lay\n# further from the root node will be omitted. Note that setting this option to 1\n# or 2 may greatly reduce the computation time needed for large code bases. Also\n# note that the size of a graph can be further restricted by\n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n# Minimum value: 0, maximum value: 1000, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\n# background. This is disabled by default, because dot on Windows does not seem\n# to support this out of the box.\n#\n# Warning: Depending on the platform used, enabling this option may lead to\n# badly anti-aliased labels on the edges of a graph (i.e. they become hard to\n# read).\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output\n# files in one run (i.e. multiple -o and -T options on the command line). This\n# makes dot run faster, but since only newer versions of dot (>1.8.10) support\n# this, this feature is disabled by default.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page\n# explaining the meaning of the various boxes and arrows in the dot generated\n# graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot\n# files that are used to generate the various graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_CLEANUP            = YES\n\n# If the NIMBUSKIT_HTML_ONLYSHOWMODULES tag is set to YES doxygen will only show\n# modules in the HTML tree view.\n\nNIMBUSKIT_HTML_ONLYSHOWMODULES            = YES\n\n# If the \\c NIMBUSKIT_HTML_FIXEDTREEVIEW tag is set to \\c YES the generated tree view\n# will have a fixed width as defined by the css #side-nav width property.\n\nNIMBUSKIT_HTML_FIXEDTREEVIEW  = YES\nNIMBUSKIT_HTML_DISABLENAVTREESYNC = YES\nNIMBUSKIT_HTML_NAVTREESTRIPPREFIX = \"Nimbus \"\nNIMBUSKIT_NOLINK_CLASS = \"Nimbus\"\nNIMBUSKIT_USE_METHOD_NAME_FOR_ANCHOR = YES\nNIMBUSKIT_HIDE_INHERITANCE_DESCRIPTION = YES\nNIMBUSKIT_PROPERTIES_ARE_PUBLIC_METHODS = YES\nNIMBUSKIT_PROPERTIES_SUFFIX = YES\nNIMBUSKIT_GROUP_STATIC_AND_INSTANCE_METHODS = YES\nNIMBUSKIT_ALWAYS_SHOW_DETAILED_DOCS = YES\nNIMBUSKIT_DOCSET_DEFAULT_OBJC = YES\nNIMBUSKIT_DOCSET_FEED_URL = http://jverkoey.github.com/nimbus/nimbusdocset.atom\nNIMBUSKIT_HTML_DONT_SHOW_DEFS = YES\nNIMBUSKIT_HTML_APPLE_METHOD_DECLS = YES\nNIMBUSKIT_DISCUSSION_AND_BRIEF = YES\nNIMBUSKIT_SANE_PREFIXES = YES\nNIMBUSKIT_ORIGINAL_DECLARATIONS = YES\nNIMBUSKIT_NO_MEMBER_BRIEF = YES\n"
  },
  {
    "path": "docs/Doxyfile-docset",
    "content": "# Doxyfile 1.8.6\n#\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project.\n#\n# All text after a double hash (##) is considered a comment and is placed in\n# front of the TAG it is preceding.\n#\n# All text after a single hash (#) is considered a comment and will be ignored.\n# The format is:\n# TAG = value [value, ...]\n# For lists, items can also be appended using:\n# TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\\\" \\\").\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the config file\n# that follow. The default is UTF-8 which is also the encoding used for all text\n# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv\n# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv\n# for the list of possible encodings.\n# The default value is: UTF-8.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by\n# double-quotes, unless you are using Doxywizard) that should identify the\n# project for which the documentation is generated. This name is used in the\n# title of most generated pages and in a few other places.\n# The default value is: My Project.\n\nPROJECT_NAME           = \"NimbusKit 1.2.1\"\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. This\n# could be handy for archiving the generated documentation or if some version\n# control system is used.\n\nPROJECT_NUMBER         = 1.2.1\n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description\n# for a project that appears at the top of each page and should give viewer a\n# quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          = \"The iOS framework that grows only as fast as its documentation\"\n\n# With the PROJECT_LOGO tag one can specify an logo or icon that is included in\n# the documentation. The maximum height of the logo should not exceed 55 pixels\n# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo\n# to the output directory.\n\nPROJECT_LOGO           =\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path\n# into which the generated documentation will be written. If a relative path is\n# entered, it will be relative to the location where doxygen was started. If\n# left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = docs/output-docset\n\n# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-\n# directories (in 2 levels) under the output directory of each output format and\n# will distribute the generated files over these directories. Enabling this\n# option can be useful when feeding doxygen a huge amount of source files, where\n# putting all generated files in the same directory would otherwise causes\n# performance problems for the file system.\n# The default value is: NO.\n\nCREATE_SUBDIRS         = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all constant output in the proper language.\n# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,\n# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),\n# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,\n# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),\n# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,\n# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,\n# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,\n# Ukrainian and Vietnamese.\n# The default value is: English.\n\nOUTPUT_LANGUAGE        = English\n\n# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member\n# descriptions after the members that are listed in the file and class\n# documentation (similar to Javadoc). Set to NO to disable this.\n# The default value is: YES.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief\n# description of a member or function before the detailed description\n#\n# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\n# brief descriptions will be completely suppressed.\n# The default value is: YES.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator that is\n# used to form the text in various listings. Each string in this list, if found\n# as the leading text of the brief description, will be stripped from the text\n# and the result, after processing the whole list, is used as the annotated\n# text. Otherwise, the brief description is used as-is. If left blank, the\n# following values are used ($name is automatically replaced with the name of\n# the entity):The $name class, The $name widget, The $name file, is, provides,\n# specifies, contains, represents, a, an and the.\n\nABBREVIATE_BRIEF       = \"The $name class\" \\\n                         \"The $name widget\" \\\n                         \"The $name file\" \\\n                         is \\\n                         provides \\\n                         specifies \\\n                         contains \\\n                         represents \\\n                         a \\\n                         an \\\n                         the\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\n# doxygen will generate a detailed section even if there is only a brief\n# description.\n# The default value is: NO.\n\nALWAYS_DETAILED_SEC    = YES\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\n# inherited members of a class in the documentation of that class as if those\n# members were ordinary class members. Constructors, destructors and assignment\n# operators of the base classes will not be shown.\n# The default value is: NO.\n\nINLINE_INHERITED_MEMB  = YES\n\n# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path\n# before files name in the file list and in the header files. If set to NO the\n# shortest path that makes the file name unique will be used\n# The default value is: YES.\n\nFULL_PATH_NAMES        = YES\n\n# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.\n# Stripping is only done if one of the specified strings matches the left-hand\n# part of the path. The tag can be used to show relative paths in the file list.\n# If left blank the directory from which doxygen is run is used as the path to\n# strip.\n#\n# Note that you can specify absolute paths here, but also relative paths, which\n# will be relative from the directory where doxygen is started.\n# This tag requires that the tag FULL_PATH_NAMES is set to YES.\n\nSTRIP_FROM_PATH        = /Users/featherless/workbench/ios/nimbus\n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the\n# path mentioned in the documentation of a class, which tells the reader which\n# header file to include in order to use a class. If left blank only the name of\n# the header file containing the class definition is used. Otherwise one should\n# specify the list of include paths that are normally passed to the compiler\n# using the -I flag.\n\nSTRIP_FROM_INC_PATH    =\n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but\n# less readable) file names. This can be useful is your file systems doesn't\n# support long names like on DOS, Mac, or CD-ROM.\n# The default value is: NO.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the\n# first line (until the first dot) of a Javadoc-style comment as the brief\n# description. If set to NO, the Javadoc-style will behave just like regular Qt-\n# style comments (thus requiring an explicit @brief command for a brief\n# description.)\n# The default value is: NO.\n\nJAVADOC_AUTOBRIEF      = YES\n\n# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first\n# line (until the first dot) of a Qt-style comment as the brief description. If\n# set to NO, the Qt-style will behave just like regular Qt-style comments (thus\n# requiring an explicit \\brief command for a brief description.)\n# The default value is: NO.\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a\n# multi-line C++ special comment block (i.e. a block of //! or /// comments) as\n# a brief description. This used to be the default behavior. The new default is\n# to treat a multi-line C++ comment block as a detailed description. Set this\n# tag to YES if you prefer the old behavior instead.\n#\n# Note that setting this tag to YES also means that rational rose comments are\n# not recognized any more.\n# The default value is: NO.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the\n# documentation from any documented member that it re-implements.\n# The default value is: YES.\n\nINHERIT_DOCS           = NO\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a\n# new page for each member. If set to NO, the documentation of a member will be\n# part of the file/class/namespace that contains it.\n# The default value is: NO.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen\n# uses this value to replace tabs by spaces in code fragments.\n# Minimum value: 1, maximum value: 16, default value: 4.\n\nTAB_SIZE               = 2\n\n# This tag can be used to specify a number of aliases that act as commands in\n# the documentation. An alias has the form:\n# name=value\n# For example adding\n# \"sideeffect=@par Side Effects:\\n\"\n# will allow you to put the command \\sideeffect (or @sideeffect) in the\n# documentation, which will result in a user-defined paragraph with heading\n# \"Side Effects:\". You can put \\n's in the value part of an alias to insert\n# newlines.\n\nALIASES                =\n\n# This tag can be used to specify a number of word-keyword mappings (TCL only).\n# A mapping has the form \"name=value\". For example adding \"class=itcl::class\"\n# will allow you to use the command class in the itcl::class meaning.\n\nTCL_SUBST              =\n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources\n# only. Doxygen will then generate output that is more tailored for C. For\n# instance, some of the names that are used will be different. The list of all\n# members will be omitted, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_FOR_C  = NO\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or\n# Python sources only. Doxygen will then generate output that is more tailored\n# for that language. For instance, namespaces will be presented as packages,\n# qualified scopes will look different, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\n# sources. Doxygen will then generate output that is tailored for Fortran.\n# The default value is: NO.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\n# sources. Doxygen will then generate output that is tailored for VHDL.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it\n# parses. With this tag you can assign which parser to use for a given\n# extension. Doxygen has a built-in mapping, but you can override or extend it\n# using this tag. The format is ext=language, where ext is a file extension, and\n# language is one of the parsers supported by doxygen: IDL, Java, Javascript,\n# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make\n# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C\n# (default is Fortran), use: inc=Fortran f=C.\n#\n# Note For files without extension you can use no_extension as a placeholder.\n#\n# Note that for custom extensions you also need to set FILE_PATTERNS otherwise\n# the files are not read by doxygen.\n\nEXTENSION_MAPPING      =\n\n# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments\n# according to the Markdown format, which allows for more readable\n# documentation. See http://daringfireball.net/projects/markdown/ for details.\n# The output of markdown processing is further processed by doxygen, so you can\n# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in\n# case of backward compatibilities issues.\n# The default value is: YES.\n\nMARKDOWN_SUPPORT       = YES\n\n# When enabled doxygen tries to link words that correspond to documented\n# classes, or namespaces to their corresponding documentation. Such a link can\n# be prevented in individual cases by by putting a % sign in front of the word\n# or globally by setting AUTOLINK_SUPPORT to NO.\n# The default value is: YES.\n\nAUTOLINK_SUPPORT       = YES\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\n# to include (a tag file for) the STL sources as input, then you should set this\n# tag to YES in order to let doxygen match functions declarations and\n# definitions whose arguments contain STL classes (e.g. func(std::string);\n# versus func(std::string) {}). This also make the inheritance and collaboration\n# diagrams that involve STL classes more complete and accurate.\n# The default value is: NO.\n\nBUILTIN_STL_SUPPORT    = NO\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to\n# enable parsing support.\n# The default value is: NO.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:\n# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen\n# will parse them like normal C++ but will assume all classes use public instead\n# of private inheritance when no explicit protection keyword is present.\n# The default value is: NO.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate\n# getter and setter methods for a property. Setting this option to YES will make\n# doxygen to replace the get and set methods by a property in the documentation.\n# This will only work if the methods are indeed getting or setting a simple\n# type. If this is not the case, or you want to show the methods anyway, you\n# should set this option to NO.\n# The default value is: YES.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\n# tag is set to YES, then doxygen will reuse the documentation of the first\n# member in the group (if any) for the other members of the group. By default\n# all members of a group must be documented explicitly.\n# The default value is: NO.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# Set the SUBGROUPING tag to YES to allow class member groups of the same type\n# (for instance a group of public functions) to be put as a subgroup of that\n# type (e.g. under the Public Functions section). Set it to NO to prevent\n# subgrouping. Alternatively, this can be done per class using the\n# \\nosubgrouping command.\n# The default value is: YES.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions\n# are shown inside the group in which they are included (e.g. using \\ingroup)\n# instead of on a separate page (for HTML and Man pages) or section (for LaTeX\n# and RTF).\n#\n# Note that this feature does not work in combination with\n# SEPARATE_MEMBER_PAGES.\n# The default value is: NO.\n\nINLINE_GROUPED_CLASSES = NO\n\n# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions\n# with only public data fields or simple typedef fields will be shown inline in\n# the documentation of the scope in which they are defined (i.e. file,\n# namespace, or group documentation), provided this scope is documented. If set\n# to NO, structs, classes, and unions are shown on a separate page (for HTML and\n# Man pages) or section (for LaTeX and RTF).\n# The default value is: NO.\n\nINLINE_SIMPLE_STRUCTS  = NO\n\n# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or\n# enum is documented as struct, union, or enum with the name of the typedef. So\n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\n# with name TypeT. When disabled the typedef will appear as a member of a file,\n# namespace, or class. And the struct will be named TypeS. This can typically be\n# useful for C code in case the coding convention dictates that all compound\n# types are typedef'ed and only the typedef is referenced, never the tag name.\n# The default value is: NO.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This\n# cache is used to resolve symbols given their name and scope. Since this can be\n# an expensive process and often the same symbol appears multiple times in the\n# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small\n# doxygen will become slower. If the cache is too large, memory is wasted. The\n# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range\n# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536\n# symbols. At the end of a run doxygen will report the cache usage and suggest\n# the optimal cache size from a speed point of view.\n# Minimum value: 0, maximum value: 9, default value: 0.\n\nLOOKUP_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in\n# documentation are documented, even if no documentation was available. Private\n# class members and static file members will be hidden unless the\n# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.\n# Note: This will also disable the warnings about undocumented members that are\n# normally produced when WARNINGS is set to YES.\n# The default value is: NO.\n\nEXTRACT_ALL            = NO\n\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will\n# be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal\n# scope will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PACKAGE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES all static members of a file will be\n# included in the documentation.\n# The default value is: NO.\n\nEXTRACT_STATIC         = NO\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined\n# locally in source files will be included in the documentation. If set to NO\n# only classes defined in header files are included. Does not have any effect\n# for Java sources.\n# The default value is: YES.\n\nEXTRACT_LOCAL_CLASSES  = NO\n\n# This flag is only useful for Objective-C code. When set to YES local methods,\n# which are defined in the implementation section but not in the interface are\n# included in the documentation. If set to NO only methods in the interface are\n# included.\n# The default value is: NO.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be\n# extracted and appear in the documentation as a namespace called\n# 'anonymous_namespace{file}', where file will be replaced with the base name of\n# the file that contains the anonymous namespace. By default anonymous namespace\n# are hidden.\n# The default value is: NO.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all\n# undocumented members inside documented classes or files. If set to NO these\n# members will be included in the various overviews, but no documentation\n# section is generated. This option has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_MEMBERS     = YES\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all\n# undocumented classes that are normally visible in the class hierarchy. If set\n# to NO these classes will be included in the various overviews. This option has\n# no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_CLASSES     = YES\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend\n# (class|struct|union) declarations. If set to NO these declarations will be\n# included in the documentation.\n# The default value is: NO.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any\n# documentation blocks found inside the body of a function. If set to NO these\n# blocks will be appended to the function's detailed documentation block.\n# The default value is: NO.\n\nHIDE_IN_BODY_DOCS      = YES\n\n# The INTERNAL_DOCS tag determines if documentation that is typed after a\n# \\internal command is included. If the tag is set to NO then the documentation\n# will be excluded. Set it to YES to include the internal documentation.\n# The default value is: NO.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file\n# names in lower-case letters. If set to YES upper-case letters are also\n# allowed. This is useful if you have classes or files whose names only differ\n# in case and if your file system supports case sensitive file names. Windows\n# and Mac users are advised to set this option to NO.\n# The default value is: system dependent.\n\nCASE_SENSE_NAMES       = YES\n\n# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with\n# their full class and namespace scopes in the documentation. If set to YES the\n# scope will be hidden.\n# The default value is: NO.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of\n# the files that are included by a file in the documentation of that file.\n# The default value is: YES.\n\nSHOW_INCLUDE_FILES     = NO\n\n# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each\n# grouped member an include statement to the documentation, telling the reader\n# which file to include in order to use the member.\n# The default value is: NO.\n\nSHOW_GROUPED_MEMB_INC  = NO\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include\n# files with double quotes in the documentation rather than with sharp brackets.\n# The default value is: NO.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the\n# documentation for inline members.\n# The default value is: YES.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the\n# (detailed) documentation of file and class members alphabetically by member\n# name. If set to NO the members will appear in declaration order.\n# The default value is: YES.\n\nSORT_MEMBER_DOCS       = NO\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief\n# descriptions of file, namespace and class members alphabetically by member\n# name. If set to NO the members will appear in declaration order. Note that\n# this will also influence the order of the classes in the class list.\n# The default value is: NO.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the\n# (brief and detailed) documentation of class members so that constructors and\n# destructors are listed first. If set to NO the constructors will appear in the\n# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.\n# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief\n# member documentation.\n# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting\n# detailed member documentation.\n# The default value is: NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy\n# of group names into alphabetical order. If set to NO the group names will\n# appear in their defined order.\n# The default value is: NO.\n\nSORT_GROUP_NAMES       = YES\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by\n# fully-qualified names, including namespaces. If set to NO, the class list will\n# be sorted only by class name, not including the namespace part.\n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\n# Note: This option applies only to the class list, not to the alphabetical\n# list.\n# The default value is: NO.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper\n# type resolution of all parameters of a function it will reject a match between\n# the prototype and the implementation of a member function even if there is\n# only one candidate or it is obvious which candidate to choose by doing a\n# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still\n# accept a match between prototype and implementation in such cases.\n# The default value is: NO.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the\n# todo list. This list is created by putting \\todo commands in the\n# documentation.\n# The default value is: YES.\n\nGENERATE_TODOLIST      = NO\n\n# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the\n# test list. This list is created by putting \\test commands in the\n# documentation.\n# The default value is: YES.\n\nGENERATE_TESTLIST      = NO\n\n# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug\n# list. This list is created by putting \\bug commands in the documentation.\n# The default value is: YES.\n\nGENERATE_BUGLIST       = NO\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)\n# the deprecated list. This list is created by putting \\deprecated commands in\n# the documentation.\n# The default value is: YES.\n\nGENERATE_DEPRECATEDLIST= NO\n\n# The ENABLED_SECTIONS tag can be used to enable conditional documentation\n# sections, marked by \\if <section_label> ... \\endif and \\cond <section_label>\n# ... \\endcond blocks.\n\nENABLED_SECTIONS       =\n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the\n# initial value of a variable or macro / define can have for it to appear in the\n# documentation. If the initializer consists of more lines than specified here\n# it will be hidden. Use a value of 0 to hide initializers completely. The\n# appearance of the value of individual variables and macros / defines can be\n# controlled using \\showinitializer or \\hideinitializer command in the\n# documentation regardless of this setting.\n# Minimum value: 0, maximum value: 10000, default value: 30.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at\n# the bottom of the documentation of classes and structs. If set to YES the list\n# will mention the files that were used to generate the documentation.\n# The default value is: YES.\n\nSHOW_USED_FILES        = NO\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This\n# will remove the Files entry from the Quick Index and from the Folder Tree View\n# (if specified).\n# The default value is: YES.\n\nSHOW_FILES             = NO\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces\n# page. This will remove the Namespaces entry from the Quick Index and from the\n# Folder Tree View (if specified).\n# The default value is: YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that\n# doxygen should invoke to get the current version for each file (typically from\n# the version control system). Doxygen will invoke the program by executing (via\n# popen()) the command command input-file, where command is the value of the\n# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided\n# by doxygen. Whatever the program writes to standard output is used as the file\n# version. For an example see the documentation.\n\nFILE_VERSION_FILTER    =\n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\n# by doxygen. The layout file controls the global structure of the generated\n# output files in an output format independent way. To create the layout file\n# that represents doxygen's defaults, run doxygen with the -l option. You can\n# optionally specify a file name after the option, if omitted DoxygenLayout.xml\n# will be used as the name of the layout file.\n#\n# Note that if you run doxygen from a directory containing a file called\n# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE\n# tag is left empty.\n\nLAYOUT_FILE            = docs/layout/DoxygenLayout.xml\n\n# The CITE_BIB_FILES tag can be used to specify one or more bib files containing\n# the reference definitions. This must be a list of .bib files. The .bib\n# extension is automatically appended if omitted. This requires the bibtex tool\n# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.\n# For LaTeX the style of the bibliography can be controlled using\n# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the\n# search path. Do not use file names with spaces, bibtex cannot handle them. See\n# also \\cite for info how to create references.\n\nCITE_BIB_FILES         =\n\n#---------------------------------------------------------------------------\n# Configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated to\n# standard output by doxygen. If QUIET is set to YES this implies that the\n# messages are off.\n# The default value is: NO.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are\n# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES\n# this implies that the warnings are on.\n#\n# Tip: Turn warnings on while writing the documentation.\n# The default value is: YES.\n\nWARNINGS               = YES\n\n# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate\n# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag\n# will automatically be disabled.\n# The default value is: YES.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for\n# potential errors in the documentation, such as not documenting some parameters\n# in a documented function, or documenting parameters that don't exist or using\n# markup commands wrongly.\n# The default value is: YES.\n\nWARN_IF_DOC_ERROR      = YES\n\n# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that\n# are documented, but have no documentation for their parameters or return\n# value. If set to NO doxygen will only warn about wrong or incomplete parameter\n# documentation, but not about the absence of documentation.\n# The default value is: NO.\n\nWARN_NO_PARAMDOC       = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that doxygen\n# can produce. The string should contain the $file, $line, and $text tags, which\n# will be replaced by the file and line number from which the warning originated\n# and the warning text. Optionally the format may contain $version, which will\n# be replaced by the version of the file (if it could be obtained via\n# FILE_VERSION_FILTER)\n# The default value is: $file:$line: $text.\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning and error\n# messages should be written. If left blank the output is written to standard\n# error (stderr).\n\nWARN_LOGFILE           =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag is used to specify the files and/or directories that contain\n# documented source files. You may enter file names like myfile.cpp or\n# directories like /usr/src/myproject. Separate the files or directories with\n# spaces.\n# Note: If this tag is empty the current directory is searched.\n\nINPUT                  = src\n\n# This tag can be used to specify the character encoding of the source files\n# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses\n# libiconv (or the iconv built into libc) for the transcoding. See the libiconv\n# documentation (see: http://www.gnu.org/software/libiconv) for the list of\n# possible encodings.\n# The default value is: UTF-8.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the\n# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank the\n# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,\n# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,\n# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,\n# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,\n# *.qsf, *.as and *.js.\n\nFILE_PATTERNS          = *.h \\\n                         *.m \\\n                         *.mm\n\n# The RECURSIVE tag can be used to specify whether or not subdirectories should\n# be searched for input files as well.\n# The default value is: NO.\n\nRECURSIVE              = YES\n\n# The EXCLUDE tag can be used to specify files and/or directories that should be\n# excluded from the INPUT source files. This way you can easily exclude a\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n#\n# Note that relative paths are relative to the directory from which doxygen is\n# run.\n\nEXCLUDE                =\n\n# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or\n# directories that are symbolic links (a Unix file system feature) are excluded\n# from the input.\n# The default value is: NO.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n# certain files from those directories.\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       =\n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\n# (namespaces, classes, functions, etc.) that should be excluded from the\n# output. The symbol name can be a fully qualified name, a word, or if the\n# wildcard * is used, a substring. Examples: ANamespace, AClass,\n# AClass::ANamespace, ANamespace::*Test\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories use the pattern */test/*\n\nEXCLUDE_SYMBOLS        =\n\n# The EXAMPLE_PATH tag can be used to specify one or more files or directories\n# that contain example code fragments that are included (see the \\include\n# command).\n\nEXAMPLE_PATH           = src/core/examples/ \\\n                         src/models/examples/\n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank all\n# files are included.\n\nEXAMPLE_PATTERNS       = *\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\n# searched for input files to be used with the \\include or \\dontinclude commands\n# irrespective of the value of the RECURSIVE tag.\n# The default value is: NO.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or directories\n# that contain images that are to be included in the documentation (see the\n# \\image command).\n\nIMAGE_PATH             = docs/gfx/\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should\n# invoke to filter for each input file. Doxygen will invoke the filter program\n# by executing (via popen()) the command:\n#\n# <filter> <input-file>\n#\n# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the\n# name of an input file. Doxygen will then use the output that the filter\n# program writes to standard output. If FILTER_PATTERNS is specified, this tag\n# will be ignored.\n#\n# Note that the filter must not add or remove lines; it is applied before the\n# code is scanned, but not when the output code is generated. If lines are added\n# or removed, the anchors will not be placed correctly.\n\nINPUT_FILTER           =\n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\n# basis. Doxygen will compare the file name with each pattern and apply the\n# filter if there is a match. The filters are a list of the form: pattern=filter\n# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how\n# filters are used. If the FILTER_PATTERNS tag is empty or if none of the\n# patterns match the file name, INPUT_FILTER is applied.\n\nFILTER_PATTERNS        =\n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\n# INPUT_FILTER ) will also be used to filter the input files that are used for\n# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).\n# The default value is: NO.\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\n# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and\n# it is also possible to disable source filtering for a specific pattern using\n# *.ext= (so without naming a filter).\n# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.\n\nFILTER_SOURCE_PATTERNS =\n\n# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that\n# is part of the input, its contents will be placed on the main page\n# (index.html). This can be useful if you have a project on for instance GitHub\n# and want to reuse the introduction page also for the doxygen output.\n\nUSE_MDFILE_AS_MAINPAGE =\n\n#---------------------------------------------------------------------------\n# Configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will be\n# generated. Documented entities will be cross-referenced with these sources.\n#\n# Note: To get rid of all source code in the generated output, make sure that\n# also VERBATIM_HEADERS is set to NO.\n# The default value is: NO.\n\nSOURCE_BROWSER         = YES\n\n# Setting the INLINE_SOURCES tag to YES will include the body of functions,\n# classes and enums directly into the documentation.\n# The default value is: NO.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any\n# special comment blocks from generated source code fragments. Normal C, C++ and\n# Fortran comments will always remain visible.\n# The default value is: YES.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES then for each documented\n# function all documented functions referencing it will be listed.\n# The default value is: NO.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES then for each documented function\n# all documented entities called/used by that function will be listed.\n# The default value is: NO.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set\n# to YES, then the hyperlinks from functions in REFERENCES_RELATION and\n# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will\n# link to the documentation.\n# The default value is: YES.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the\n# source code will show a tooltip with additional information such as prototype,\n# brief description and links to the definition and documentation. Since this\n# will make the HTML file larger and loading of large files a bit slower, you\n# can opt to disable this feature.\n# The default value is: YES.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nSOURCE_TOOLTIPS        = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code will\n# point to the HTML generated by the htags(1) tool instead of doxygen built-in\n# source browser. The htags tool is part of GNU's global source tagging system\n# (see http://www.gnu.org/software/global/global.html). You will need version\n# 4.8.6 or higher.\n#\n# To use it do the following:\n# - Install the latest version of global\n# - Enable SOURCE_BROWSER and USE_HTAGS in the config file\n# - Make sure the INPUT points to the root of the source tree\n# - Run doxygen as normal\n#\n# Doxygen will invoke htags (and that will in turn invoke gtags), so these\n# tools must be available from the command line (i.e. in the search path).\n#\n# The result: instead of the source browser generated by doxygen, the links to\n# source code will now point to the output of htags.\n# The default value is: NO.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a\n# verbatim copy of the header file for each class for which an include is\n# specified. Set to NO to disable this.\n# See also: Section \\class.\n# The default value is: YES.\n\nVERBATIM_HEADERS       = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all\n# compounds will be generated. Enable this if the project contains a lot of\n# classes, structs, unions or interfaces.\n# The default value is: YES.\n\nALPHABETICAL_INDEX     = YES\n\n# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in\n# which the alphabetical index list will be split.\n# Minimum value: 1, maximum value: 20, default value: 5.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nCOLS_IN_ALPHA_INDEX    = 5\n\n# In case all classes in a project start with a common prefix, all classes will\n# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag\n# can be used to specify a prefix (or a list of prefixes) that should be ignored\n# while generating the index headers.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nIGNORE_PREFIX          = NI\n\n#---------------------------------------------------------------------------\n# Configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output\n# The default value is: YES.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each\n# generated HTML page (for example: .htm, .php, .asp).\n# The default value is: .html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a user-defined HTML header file for\n# each generated HTML page. If the tag is left blank doxygen will generate a\n# standard header.\n#\n# To get valid HTML the header file that includes any scripts and style sheets\n# that doxygen needs, which is dependent on the configuration options used (e.g.\n# the setting GENERATE_TREEVIEW). It is highly recommended to start with a\n# default header using\n# doxygen -w html new_header.html new_footer.html new_stylesheet.css\n# YourConfigFile\n# and then modify the file new_header.html. See also section \"Doxygen usage\"\n# for information on how to generate the default header that doxygen normally\n# uses.\n# Note: The header is subject to change so you typically have to regenerate the\n# default header when upgrading to a newer version of doxygen. For a description\n# of the possible markers and block names see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_HEADER            = docs/layout/header-docset.html\n\n# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each\n# generated HTML page. If the tag is left blank doxygen will generate a standard\n# footer. See HTML_HEADER for more information on how to generate a default\n# footer and what special commands can be used inside the footer. See also\n# section \"Doxygen usage\" for information on how to generate the default footer\n# that doxygen normally uses.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FOOTER            = docs/layout/footer-docset.html\n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style\n# sheet that is used by each HTML page. It can be used to fine-tune the look of\n# the HTML output. If left blank doxygen will generate a default style sheet.\n# See also section \"Doxygen usage\" for information on how to generate the style\n# sheet that doxygen normally uses.\n# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as\n# it is more robust and this tag (HTML_STYLESHEET) will in the future become\n# obsolete.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_STYLESHEET        = \n\n# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-\n# defined cascading style sheet that is included after the standard style sheets\n# created by doxygen. Using this option one can overrule certain style aspects.\n# This is preferred over using HTML_STYLESHEET since it does not replace the\n# standard style sheet and is therefor more robust against future updates.\n# Doxygen will copy the style sheet file to the output directory. For an example\n# see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_STYLESHEET  = docs/css/appledocs.css\n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the HTML output directory. Note\n# that these files will be copied to the base HTML output directory. Use the\n# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\n# files. In the HTML_STYLESHEET file, use the file name only. Also note that the\n# files will be copied as-is; there are no commands or markers available.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_FILES       = docs/js/widget.js \\\n                         docs/gfx/nimbus128.png \\\n                         docs/css/nimbuskit.css\n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen\n# will adjust the colors in the stylesheet and background images according to\n# this color. Hue is specified as an angle on a colorwheel, see\n# http://en.wikipedia.org/wiki/Hue for more information. For instance the value\n# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300\n# purple, and 360 is red again.\n# Minimum value: 0, maximum value: 359, default value: 220.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors\n# in the HTML output. For a value of 0 the output will use grayscales only. A\n# value of 255 will produce the most vivid colors.\n# Minimum value: 0, maximum value: 255, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_SAT    = 100\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the\n# luminance component of the colors in the HTML output. Values below 100\n# gradually make the output lighter, whereas values above 100 make the output\n# darker. The value divided by 100 is the actual gamma applied, so 80 represents\n# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not\n# change the gamma.\n# Minimum value: 40, maximum value: 240, default value: 80.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_GAMMA  = 130\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\n# page will contain the date and time when the page was generated. Setting this\n# to NO can help when comparing the output of multiple runs.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_TIMESTAMP         = NO\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\n# documentation will contain sections that can be hidden and shown after the\n# page has loaded.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries\n# shown in the various tree structured indices initially; the user can expand\n# and collapse entries dynamically later on. Doxygen will expand the tree to\n# such a level that at most the specified number of entries are visible (unless\n# a fully collapsed tree already exceeds this amount). So setting the number of\n# entries 1 will produce a full collapsed tree by default. 0 is a special value\n# representing an infinite number of entries and will result in a full expanded\n# tree by default.\n# Minimum value: 0, maximum value: 9999, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_INDEX_NUM_ENTRIES = 100\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files will be\n# generated that can be used as input for Apple's Xcode 3 integrated development\n# environment (see: http://developer.apple.com/tools/xcode/), introduced with\n# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a\n# Makefile in the HTML output directory. Running make will produce the docset in\n# that directory and running make install will install the docset in\n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at\n# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html\n# for more information.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_DOCSET        = YES\n\n# This tag determines the name of the docset feed. A documentation feed provides\n# an umbrella under which multiple documentation sets from a single provider\n# (such as a company or product suite) can be grouped.\n# The default value is: Doxygen generated docs.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_FEEDNAME        = \"NimbusKit Docs\"\n\n# This tag specifies a string that should uniquely identify the documentation\n# set bundle. This should be a reverse domain-name style string, e.g.\n# com.mycompany.MyDocSet. Doxygen will append .docset to the name.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_BUNDLE_ID       = org.nimbuskit\n\n# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify\n# the documentation publisher. This should be a reverse domain-name style\n# string, e.g. com.mycompany.MyDocSet.documentation.\n# The default value is: org.doxygen.Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_ID    = org.nimbuskit\n\n# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.\n# The default value is: Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_NAME  = NimbusKit\n\n# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three\n# additional HTML index files: index.hhp, index.hhc, and index.hhk. The\n# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop\n# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on\n# Windows.\n#\n# The HTML Help Workshop contains a compiler that can convert all HTML output\n# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML\n# files are now used as the Windows 98 help format, and will replace the old\n# Windows help format (.hlp) on all Windows platforms in the future. Compressed\n# HTML files also contain an index, a table of contents, and you can search for\n# words in the documentation. The HTML workshop also contains a viewer for\n# compressed HTML files.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_HTMLHELP      = NO\n\n# The CHM_FILE tag can be used to specify the file name of the resulting .chm\n# file. You can add a path in front of the file if the result should not be\n# written to the html output directory.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_FILE               =\n\n# The HHC_LOCATION tag can be used to specify the location (absolute path\n# including file name) of the HTML help compiler ( hhc.exe). If non-empty\n# doxygen will try to run the HTML help compiler on the generated index.hhp.\n# The file has to be specified with full path.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nHHC_LOCATION           =\n\n# The GENERATE_CHI flag controls if a separate .chi index file is generated (\n# YES) or that it should be included in the master .chm file ( NO).\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nGENERATE_CHI           = NO\n\n# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)\n# and project file content.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_INDEX_ENCODING     =\n\n# The BINARY_TOC flag controls whether a binary table of contents is generated (\n# YES) or a normal table of contents ( NO) in the .chm file.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members to\n# the table of contents of the HTML help documentation and to the tree view.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that\n# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help\n# (.qch) of the generated HTML documentation.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify\n# the file name of the resulting .qch file. The path specified is relative to\n# the HTML output folder.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQCH_FILE               =\n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help\n# Project output. For more information please see Qt Help Project / Namespace\n# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_NAMESPACE          = org.doxygen.Project\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt\n# Help Project output. For more information please see Qt Help Project / Virtual\n# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-\n# folders).\n# The default value is: doc.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom\n# filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_NAME   =\n\n# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the\n# custom filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_ATTRS  =\n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\n# project's filter section matches. Qt Help Project / Filter Attributes (see:\n# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_SECT_FILTER_ATTRS  =\n\n# The QHG_LOCATION tag can be used to specify the location of Qt's\n# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the\n# generated .qhp file.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHG_LOCATION           =\n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be\n# generated, together with the HTML files, they form an Eclipse help plugin. To\n# install this plugin and make it available under the help contents menu in\n# Eclipse, the contents of the directory containing the HTML and XML files needs\n# to be copied into the plugins directory of eclipse. The name of the directory\n# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.\n# After copying Eclipse needs to be restarted before the help appears.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the Eclipse help plugin. When installing the plugin\n# the directory name containing the HTML and XML files should also have this\n# name. Each documentation set should have its own identifier.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.\n\nECLIPSE_DOC_ID         = org.doxygen.Project\n\n# If you want full control over the layout of the generated HTML pages it might\n# be necessary to disable the index and replace it with your own. The\n# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top\n# of each HTML page. A value of NO enables the index and the value YES disables\n# it. Since the tabs in the index contain the same information as the navigation\n# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nDISABLE_INDEX          = YES\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\n# structure should be generated to display hierarchical information. If the tag\n# value is set to YES, a side panel will be generated containing a tree-like\n# index structure (just like the one that is generated for HTML Help). For this\n# to work a browser that supports JavaScript, DHTML, CSS and frames is required\n# (i.e. any modern browser). Windows users are probably better off using the\n# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can\n# further fine-tune the look of the index. As an example, the default style\n# sheet generated by doxygen has an example that shows how to put an image at\n# the root of the tree instead of the PROJECT_NAME. Since the tree basically has\n# the same information as the tab index, you could consider setting\n# DISABLE_INDEX to YES when enabling this option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_TREEVIEW      = NO\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that\n# doxygen will group on one line in the generated HTML documentation.\n#\n# Note that a value of 0 will completely suppress the enum values from appearing\n# in the overview section.\n# Minimum value: 0, maximum value: 20, default value: 4.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used\n# to set the initial width (in pixels) of the frame in which the tree is shown.\n# Minimum value: 0, maximum value: 1500, default value: 250.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nTREEVIEW_WIDTH         = 200\n\n# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to\n# external symbols imported via tag files in a separate window.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# Use this tag to change the font size of LaTeX formulas included as images in\n# the HTML documentation. When you change the font size after a successful\n# doxygen run you need to manually remove any form_*.png images from the HTML\n# output directory to force them to be regenerated.\n# Minimum value: 8, maximum value: 50, default value: 10.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_FONTSIZE       = 10\n\n# Use the FORMULA_TRANPARENT tag to determine whether or not the images\n# generated for formulas are transparent PNGs. Transparent PNGs are not\n# supported properly for IE 6.0, but are supported on all modern browsers.\n#\n# Note that when changing this option you need to delete any form_*.png files in\n# the HTML output directory before the changes have effect.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_TRANSPARENT    = YES\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see\n# http://www.mathjax.org) which uses client side Javascript for the rendering\n# instead of using prerendered bitmaps. Use this if you do not have LaTeX\n# installed or if you want to formulas look prettier in the HTML output. When\n# enabled you may also need to install MathJax separately and configure the path\n# to it using the MATHJAX_RELPATH option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nUSE_MATHJAX            = NO\n\n# When MathJax is enabled you can set the default output format to be used for\n# the MathJax output. See the MathJax site (see:\n# http://docs.mathjax.org/en/latest/output.html) for more details.\n# Possible values are: HTML-CSS (which is slower, but has the best\n# compatibility), NativeMML (i.e. MathML) and SVG.\n# The default value is: HTML-CSS.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_FORMAT         = HTML-CSS\n\n# When MathJax is enabled you need to specify the location relative to the HTML\n# output directory using the MATHJAX_RELPATH option. The destination directory\n# should contain the MathJax.js script. For instance, if the mathjax directory\n# is located at the same level as the HTML output directory, then\n# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax\n# Content Delivery Network so you can quickly see the result without installing\n# MathJax. However, it is strongly recommended to install a local copy of\n# MathJax from http://www.mathjax.org before deployment.\n# The default value is: http://cdn.mathjax.org/mathjax/latest.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest\n\n# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax\n# extension names that should be enabled during MathJax rendering. For example\n# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_EXTENSIONS     =\n\n# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces\n# of code that will be used on startup of the MathJax code. See the MathJax site\n# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an\n# example see the documentation.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_CODEFILE       =\n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box for\n# the HTML output. The underlying search engine uses javascript and DHTML and\n# should work on any modern browser. Note that when using HTML help\n# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)\n# there is already a search function so this one should typically be disabled.\n# For large projects the javascript based search engine can be slow, then\n# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to\n# search using the keyboard; to jump to the search box use <access key> + S\n# (what the <access key> is depends on the OS and browser, but it is typically\n# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down\n# key> to jump into the search results window, the results can be navigated\n# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel\n# the search. The filter options can be selected when the cursor is inside the\n# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>\n# to select a filter and <Enter> or <escape> to activate or cancel the filter\n# option.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nSEARCHENGINE           = NO\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n# implemented using a web server instead of a web client using Javascript. There\n# are two flavors of web server based searching depending on the EXTERNAL_SEARCH\n# setting. When disabled, doxygen will generate a PHP script for searching and\n# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing\n# and searching needs to be provided by external tools. See the section\n# \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSERVER_BASED_SEARCH    = NO\n\n# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP\n# script for searching. Instead the search results are written to an XML file\n# which needs to be processed by an external indexer. Doxygen will invoke an\n# external search engine pointed to by the SEARCHENGINE_URL option to obtain the\n# search results.\n#\n# Doxygen ships with an example indexer ( doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/).\n#\n# See the section \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH        = NO\n\n# The SEARCHENGINE_URL should point to a search engine hosted by a web server\n# which will return the search results when EXTERNAL_SEARCH is enabled.\n#\n# Doxygen ships with an example indexer ( doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/). See the section \"External Indexing and\n# Searching\" for details.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHENGINE_URL       =\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed\n# search data is written to a file for indexing by an external tool. With the\n# SEARCHDATA_FILE tag the name of this file can be specified.\n# The default file is: searchdata.xml.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHDATA_FILE        = searchdata.xml\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the\n# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is\n# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple\n# projects and redirect the results back to the right project.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH_ID     =\n\n# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen\n# projects other than the one defined by this configuration file, but that are\n# all added to the same external search index. Each project needs to have a\n# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of\n# to a relative location where the documentation can be found. The format is:\n# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTRA_SEARCH_MAPPINGS  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.\n# The default value is: YES.\n\nGENERATE_LATEX         = NO\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\n# invoked.\n#\n# Note that when enabling USE_PDFLATEX this option is only used for generating\n# bitmaps for formulas in the HTML output, but not in the Makefile that is\n# written to the output directory.\n# The default file is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_CMD_NAME         = latex\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate\n# index for LaTeX.\n# The default file is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used by the\n# printer.\n# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x\n# 14 inches) and executive (7.25 x 10.5 inches).\n# The default value is: a4.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPAPER_TYPE             = a4\n\n# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names\n# that should be included in the LaTeX output. To get the times font for\n# instance you can specify\n# EXTRA_PACKAGES=times\n# If left blank no extra packages will be included.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nEXTRA_PACKAGES         =\n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the\n# generated LaTeX document. The header should contain everything until the first\n# chapter. If it is left blank doxygen will generate a standard header. See\n# section \"Doxygen usage\" for information on how to let doxygen write the\n# default header to a separate file.\n#\n# Note: Only use a user-defined header if you know what you are doing! The\n# following commands have a special meaning inside the header: $title,\n# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will\n# replace them by respectively the title of the page, the current date and time,\n# only the current date, the version number of doxygen, the project name (see\n# PROJECT_NAME), or the project number (see PROJECT_NUMBER).\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HEADER           =\n\n# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the\n# generated LaTeX document. The footer should contain everything after the last\n# chapter. If it is left blank doxygen will generate a standard footer.\n#\n# Note: Only use a user-defined footer if you know what you are doing!\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_FOOTER           =\n\n# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the LATEX_OUTPUT output\n# directory. Note that the files will be copied as-is; there are no commands or\n# markers available.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_FILES      =\n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is\n# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will\n# contain links (just like the HTML output) instead of page references. This\n# makes the output suitable for online browsing using a PDF viewer.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPDF_HYPERLINKS         = YES\n\n# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate\n# the PDF file directly from the LaTeX files. Set this option to YES to get a\n# higher quality PDF documentation.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode\n# command to the generated LaTeX files. This will instruct LaTeX to keep running\n# if errors occur, instead of asking the user for help. This option is also used\n# when generating formulas in HTML.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BATCHMODE        = NO\n\n# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the\n# index chapters (such as File Index, Compound Index, etc.) in the output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HIDE_INDICES     = NO\n\n# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source\n# code with syntax highlighting in the LaTeX output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_SOURCE_CODE      = NO\n\n# The LATEX_BIB_STYLE tag can be used to specify the style to use for the\n# bibliography, e.g. plainnat, or ieeetr. See\n# http://en.wikipedia.org/wiki/BibTeX and \\cite for more info.\n# The default value is: plain.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BIB_STYLE        = plain\n\n#---------------------------------------------------------------------------\n# Configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The\n# RTF output is optimized for Word 97 and may not look too pretty with other RTF\n# readers/editors.\n# The default value is: NO.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: rtf.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will\n# contain hyperlink fields. The RTF file will contain links (just like the HTML\n# output) instead of page references. This makes the output suitable for online\n# browsing using Word or some other Word compatible readers that support those\n# fields.\n#\n# Note: WordPad (write) and others do not support links.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's config\n# file, i.e. a series of assignments. You only have to provide replacements,\n# missing definitions are set to their default value.\n#\n# See also section \"Doxygen usage\" for information on how to generate the\n# default style sheet that doxygen normally uses.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_STYLESHEET_FILE    =\n\n# Set optional variables used in the generation of an RTF document. Syntax is\n# similar to doxygen's config file. A template extensions file can be generated\n# using doxygen -e rtf extensionFile.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_EXTENSIONS_FILE    =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for\n# classes and files.\n# The default value is: NO.\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it. A directory man3 will be created inside the directory specified by\n# MAN_OUTPUT.\n# The default directory is: man.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to the generated\n# man pages. In case the manual section does not start with a number, the number\n# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is\n# optional.\n# The default value is: .3.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_EXTENSION          = .3\n\n# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it\n# will generate one additional man file for each entity documented in the real\n# man page(s). These additional files only source the real man page, but without\n# them the man command would be unable to find the correct page.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that\n# captures the structure of the code including all documentation.\n# The default value is: NO.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: xml.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_OUTPUT             = xml\n\n# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program\n# listings (including syntax highlighting and cross-referencing information) to\n# the XML output. Note that enabling this will significantly increase the size\n# of the XML output.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_PROGRAMLISTING     = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the DOCBOOK output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files\n# that can be used to generate PDF.\n# The default value is: NO.\n\nGENERATE_DOCBOOK       = NO\n\n# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in\n# front of it.\n# The default directory is: docbook.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_OUTPUT         = docbook\n\n#---------------------------------------------------------------------------\n# Configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen\n# Definitions (see http://autogen.sf.net) file that captures the structure of\n# the code including all documentation. Note that this feature is still\n# experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module\n# file that captures the structure of the code including all documentation.\n#\n# Note that this feature is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary\n# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI\n# output from the Perl module output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely\n# formatted so it can be parsed by a human reader. This is useful if you want to\n# understand what is going on. On the other hand, if this tag is set to NO the\n# size of the Perl module output will be much smaller and Perl will parse it\n# just the same.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file are\n# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful\n# so different doxyrules.make files included by the same Makefile don't\n# overwrite each other's variables.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_MAKEVAR_PREFIX =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all\n# C-preprocessor directives found in the sources and include files.\n# The default value is: YES.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names\n# in the source code. If set to NO only conditional compilation will be\n# performed. Macro expansion can be done in a controlled way by setting\n# EXPAND_ONLY_PREDEF to YES.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nMACRO_EXPANSION        = YES\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then\n# the macro expansion is limited to the macros specified with the PREDEFINED and\n# EXPAND_AS_DEFINED tags.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_ONLY_PREDEF     = YES\n\n# If the SEARCH_INCLUDES tag is set to YES the includes files in the\n# INCLUDE_PATH will be searched if a #include is found.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that\n# contain include files that are not input files but should be processed by the\n# preprocessor.\n# This tag requires that the tag SEARCH_INCLUDES is set to YES.\n\nINCLUDE_PATH           =\n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\n# patterns (like *.h and *.hpp) to filter out the header-files in the\n# directories. If left blank, the patterns specified with FILE_PATTERNS will be\n# used.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nINCLUDE_FILE_PATTERNS  =\n\n# The PREDEFINED tag can be used to specify one or more macro names that are\n# defined before the preprocessor is started (similar to the -D option of e.g.\n# gcc). The argument of the tag is a list of macros of the form: name or\n# name=definition (no spaces). If the definition and the \"=\" are omitted, \"=1\"\n# is assumed. To prevent a macro definition from being undefined via #undef or\n# recursively expanded use the := operator instead of the = operator.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nPREDEFINED             = DEBUG \\\n                         NS_BLOCKS_AVAILABLE \\\n                         \"__NI_DEPRECATED_METHOD=\"\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this\n# tag can be used to specify a list of macro names that should be expanded. The\n# macro definition that is found in the sources will be used. Use the PREDEFINED\n# tag if you want to use a different macro definition that overrules the\n# definition found in the source code.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_AS_DEFINED      =\n\n# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will\n# remove all references to function-like macros that are alone on a line, have\n# an all uppercase name, and do not end with a semicolon. Such function macros\n# are typically used for boiler-plate code, and will confuse the parser if not\n# removed.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES tag can be used to specify one or more tag files. For each tag\n# file the location of the external documentation should be added. The format of\n# a tag file without this location is as follows:\n# TAGFILES = file1 file2 ...\n# Adding location for the tag files is done as follows:\n# TAGFILES = file1=loc1 \"file2 = loc2\" ...\n# where loc1 and loc2 can be relative or absolute paths or URLs. See the\n# section \"Linking to external documentation\" for more information about the use\n# of tag files.\n# Note: Each tag file must have a unique name (where the name does NOT include\n# the path). If a tag file is not located in the directory in which doxygen is\n# run, you must also specify the path to the tagfile here.\n\nTAGFILES               =\n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create a\n# tag file that is based on the input files it reads. See section \"Linking to\n# external documentation\" for more information about the usage of tag files.\n\nGENERATE_TAGFILE       =\n\n# If the ALLEXTERNALS tag is set to YES all external class will be listed in the\n# class index. If set to NO only the inherited external classes will be listed.\n# The default value is: NO.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in\n# the modules index. If set to NO, only the current project's groups will be\n# listed.\n# The default value is: YES.\n\nEXTERNAL_GROUPS        = YES\n\n# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in\n# the related pages index. If set to NO, only the current project's pages will\n# be listed.\n# The default value is: YES.\n\nEXTERNAL_PAGES         = YES\n\n# The PERL_PATH should be the absolute path and name of the perl script\n# interpreter (i.e. the result of 'which perl').\n# The default file (with absolute path) is: /usr/bin/perl.\n\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram\n# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to\n# NO turns the diagrams off. Note that this option also works with HAVE_DOT\n# disabled, but it is recommended to install and use dot, since it yields more\n# powerful graphs.\n# The default value is: YES.\n\nCLASS_DIAGRAMS         = YES\n\n# You can define message sequence charts within doxygen comments using the \\msc\n# command. Doxygen will then run the mscgen tool (see:\n# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the\n# documentation. The MSCGEN_PATH tag allows you to specify the directory where\n# the mscgen tool resides. If left empty the tool is assumed to be found in the\n# default search path.\n\nMSCGEN_PATH            =\n\n# You can include diagrams made with dia in doxygen documentation. Doxygen will\n# then run dia to produce the diagram and insert it in the documentation. The\n# DIA_PATH tag allows you to specify the directory where the dia binary resides.\n# If left empty dia is assumed to be found in the default search path.\n\nDIA_PATH               =\n\n# If set to YES, the inheritance and collaboration graphs will hide inheritance\n# and usage relations if the target is undocumented or is not a class.\n# The default value is: YES.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\n# available from the path. This tool is part of Graphviz (see:\n# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent\n# Bell Labs. The other options in this section have no effect if this option is\n# set to NO\n# The default value is: NO.\n\nHAVE_DOT               = NO\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed\n# to run in parallel. When set to 0 doxygen will base this on the number of\n# processors available in the system. You can set it explicitly to a value\n# larger than 0 to get control over the balance between CPU load and processing\n# speed.\n# Minimum value: 0, maximum value: 32, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_NUM_THREADS        = 0\n\n# When you want a differently looking font n the dot files that doxygen\n# generates you can specify the font name using DOT_FONTNAME. You need to make\n# sure dot is able to find the font, which can be done by putting it in a\n# standard location or by setting the DOTFONTPATH environment variable or by\n# setting DOT_FONTPATH to the directory containing the font.\n# The default value is: Helvetica.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of\n# dot graphs.\n# Minimum value: 4, maximum value: 24, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the default font as specified with\n# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set\n# the path where dot can find it using this tag.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTPATH           =\n\n# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for\n# each documented class showing the direct and indirect inheritance relations.\n# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a\n# graph for each documented class showing the direct and indirect implementation\n# dependencies (inheritance, containment, and class references variables) of the\n# class with other documented classes.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for\n# groups, showing the direct groups dependencies.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES doxygen will generate inheritance and\n# collaboration diagrams in a style similar to the OMG's Unified Modeling\n# Language.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LOOK               = NO\n\n# If the UML_LOOK tag is enabled, the fields and methods are shown inside the\n# class node. If there are many fields or methods and many nodes the graph may\n# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the\n# number of items for each type to make the size more manageable. Set this to 0\n# for no limit. Note that the threshold may be exceeded by 50% before the limit\n# is enforced. So when you set the threshold to 10, up to 15 fields may appear,\n# but if the number exceeds 15, the total amount of fields shown is limited to\n# 10.\n# Minimum value: 0, maximum value: 100, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LIMIT_NUM_FIELDS   = 10\n\n# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and\n# collaboration graphs will show the relations between templates and their\n# instances.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to\n# YES then doxygen will generate a graph for each documented file showing the\n# direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDE_GRAPH          = YES\n\n# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are\n# set to YES then doxygen will generate a graph for each documented file showing\n# the direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH tag is set to YES then doxygen will generate a call\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable call graphs for selected\n# functions only using the \\callgraph command.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable caller graphs for selected\n# functions only using the \\callergraph command.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical\n# hierarchy of all classes instead of a textual one.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the\n# dependencies a directory has on other directories in a graphical way. The\n# dependency relations are determined by the #include relations between the\n# files in the directories.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\n# generated by dot.\n# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order\n# to make the SVG files visible in IE 9+ (other browsers do not have this\n# requirement).\n# Possible values are: png, jpg, gif and svg.\n# The default value is: png.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_IMAGE_FORMAT       = png\n\n# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to\n# enable generation of interactive SVG images that allow zooming and panning.\n#\n# Note that this requires a modern browser other than Internet Explorer. Tested\n# and working are Firefox, Chrome, Safari, and Opera.\n# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make\n# the SVG files visible. Older versions of IE do not have SVG support.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINTERACTIVE_SVG        = NO\n\n# The DOT_PATH tag can be used to specify the path where the dot tool can be\n# found. If left blank, it is assumed the dot tool can be found in the path.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_PATH               =\n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that\n# contain dot files that are included in the documentation (see the \\dotfile\n# command).\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOTFILE_DIRS           =\n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that\n# contain msc files that are included in the documentation (see the \\mscfile\n# command).\n\nMSCFILE_DIRS           =\n\n# The DIAFILE_DIRS tag can be used to specify one or more directories that\n# contain dia files that are included in the documentation (see the \\diafile\n# command).\n\nDIAFILE_DIRS           =\n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes\n# that will be shown in the graph. If the number of nodes in a graph becomes\n# larger than this value, doxygen will truncate the graph, which is visualized\n# by representing a node as a red box. Note that doxygen if the number of direct\n# children of the root node in a graph is already larger than\n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that\n# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n# Minimum value: 0, maximum value: 10000, default value: 50.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs\n# generated by dot. A depth value of 3 means that only nodes reachable from the\n# root by following a path via at most 3 edges will be shown. Nodes that lay\n# further from the root node will be omitted. Note that setting this option to 1\n# or 2 may greatly reduce the computation time needed for large code bases. Also\n# note that the size of a graph can be further restricted by\n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n# Minimum value: 0, maximum value: 1000, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\n# background. This is disabled by default, because dot on Windows does not seem\n# to support this out of the box.\n#\n# Warning: Depending on the platform used, enabling this option may lead to\n# badly anti-aliased labels on the edges of a graph (i.e. they become hard to\n# read).\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output\n# files in one run (i.e. multiple -o and -T options on the command line). This\n# makes dot run faster, but since only newer versions of dot (>1.8.10) support\n# this, this feature is disabled by default.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page\n# explaining the meaning of the various boxes and arrows in the dot generated\n# graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot\n# files that are used to generate the various graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_CLEANUP            = YES\n\n# If the NIMBUSKIT_HTML_ONLYSHOWMODULES tag is set to YES doxygen will only show\n# modules in the HTML tree view.\n\nNIMBUSKIT_HTML_ONLYSHOWMODULES            = YES\n\n# If the \\c NIMBUSKIT_HTML_FIXEDTREEVIEW tag is set to \\c YES the generated tree view\n# will have a fixed width as defined by the css #side-nav width property.\n\nNIMBUSKIT_HTML_FIXEDTREEVIEW  = YES\nNIMBUSKIT_HTML_DISABLENAVTREESYNC = YES\nNIMBUSKIT_HTML_NAVTREESTRIPPREFIX = \"Nimbus \"\nNIMBUSKIT_NOLINK_CLASS = \"Nimbus\"\nNIMBUSKIT_USE_METHOD_NAME_FOR_ANCHOR = YES\nNIMBUSKIT_HIDE_INHERITANCE_DESCRIPTION = YES\nNIMBUSKIT_PROPERTIES_ARE_PUBLIC_METHODS = YES\nNIMBUSKIT_PROPERTIES_SUFFIX = YES\nNIMBUSKIT_GROUP_STATIC_AND_INSTANCE_METHODS = YES\nNIMBUSKIT_ALWAYS_SHOW_DETAILED_DOCS = YES\nNIMBUSKIT_DOCSET_DEFAULT_OBJC = YES\nNIMBUSKIT_DOCSET_FEED_URL = http://jverkoey.github.com/nimbus/nimbusdocset.atom\nNIMBUSKIT_HTML_DONT_SHOW_DEFS = YES\nNIMBUSKIT_HTML_APPLE_METHOD_DECLS = YES\nNIMBUSKIT_DISCUSSION_AND_BRIEF = YES\nNIMBUSKIT_SANE_PREFIXES = YES\nNIMBUSKIT_ORIGINAL_DECLARATIONS = YES\nNIMBUSKIT_NO_MEMBER_BRIEF = YES\n"
  },
  {
    "path": "docs/css/appledocs.css",
    "content": "/** Doxygen-Specific Overrides for Apple Docs Style */\n\nbody, table, div, p, dl {\n  font: normal normal normal 100%/normal 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;\n  font-size: 13px;\n}\n\na {\n  color: #36C;\n  font-weight: normal;\n}\n\na.el {\n  font-weight: normal;\n}\n\nh2,\nh2.groupheader {\n  font-size: 187%;\n  color: #3C4C6C;\n  font-weight: normal;\n  border-bottom: 1px solid #8391A8;\n}\n\np {\n  margin-top: 0;\n}\n\n#titlearea {\n  border-bottom: 1px solid #ACACAC;\n}\n\n/** Nav-Tree */\n\n#nav-tree {\n  background: none;\n  background-color: ghostwhite;\n  border-right: 1px solid #ACACAC;\n}\n\n#nav-tree-contents a {\n  color: #000;\n  font-weight: bold;\n  font-size: 11px;\n}\n\n#nav-tree .label {\n  font: normal normal normal 100%/normal 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;\n  font-size: 13px;\n}\n\n#nav-tree .label a,\n#nav-tree .selected a {\n  padding: 0;\n}\n\n#nav-tree .selected {\n  background: none;\n  text-shadow: none;\n}\n\n#nav-tree .selected a {\n  color: gray;\n}\n\n/** Individual Pages */\n\ndiv.header {\n  padding-left: 2em;\n  padding-right: 2em;\n  background: none;\n  border: none;\n}\n\ndiv.summary {\n  display: none;\n}\n\ndiv.headertitle {\n  padding: 0;\n  padding-top: 5px;\n}\n\n.headertitle .title {\n  font: 215% HelveticaNeue,Helvetica,Arial,sans-serif;\n}\n\n.title {\n  margin-left: 0;\n}\n\ntable.memberdecls {\n  width: 100%;\n}\n\ndiv.contents {\n  margin-left: 2em;\n  margin-right: 2em;\n}\n\ntr.heading h2 {\n  margin: 0.83em 0;\n  padding: 0;\n}\n\n.mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams {\n  background: none\n}\n\n.memSeparator {\n  border-bottom: none;\n  line-height: 0px;\n}\n\n.contents a:visited {\n  color: #4665A2;\n}\n\nh2.groupheader {\n  margin: 0.83em 0;\n  padding: 0;\n}\n\ndiv.groupHeader {\n  margin: 0;\n  font-size: 145%;\n  font-weight: normal;\n  margin-bottom: .25em;\n  margin-top: 0.6em;\n}\n\n.suffix {\n  font-style: italic;\n  color: #996;\n  font-size: 91.67%;\n}\n\n.memitem {\n  display: block !important;\n}\n\n.memdoc, dl.reflist dd {\n  border: none;\n  background: none;\n  padding: 0;\n  box-shadow: none;\n}\n\n.memname {\n  margin-top: 1.5em;\n  margin-bottom: .25em;\n  margin-left: 0;\n  margin-right: 0;\n  font-size: 145%;\n  font-weight: normal;\n  color: black;\n}\n\np.abstract {\n  margin-top: 1.083em;\n  margin-bottom: .833em;\n}\n\nh3 {\n  font-size: 100%;\n}\n\nh5 {\n  margin: .692em 0 .154em 0;\n  padding: 0;\n  font-size: 100%;\n  color: black;\n}\n\n.memItemLeft, .mdescLeft {\n  display: none;\n}\n\n.memItemRight {\n  padding-left: 20px;\n}\n\n.mdescRight {\n  padding-left: 40px;\n}\n\n.declaration {\n  font: 104% Courier,Consolas,monospace;\n  margin: 1em 0;\n}\n\ndiv.fragment {\n  background-color: ghostwhite;\n  padding: 1em;\n  overflow: auto;\n  word-wrap: break-word;\n  font-size: 9pt;\n  line-height: 125%;\n  margin: 2em;\n  border: none;\n}"
  },
  {
    "path": "docs/css/nimbuskit.css",
    "content": "/** NimbusKit */\n\n#projectname,\n#projectbrief {\n  font-family: HelveticaNeue,Helvetica,Arial,sans-serif;\n}\n\n#projectname {\n  font-size: 300%;\n  margin: 0px;\n  padding: 2px 0px;\n}\n\n#projectbrief {\n  font-size: 120%;\n  padding-bottom: 10px;\n}\n\n#doc-content {\n  margin-left: 250px;\n}\n\n#side-nav {\n  width: 250px;\n}\n\n.clearfix {\n  clear: both;\n}\n\ntable.modificationtable {\n  border: 1px #888 solid;\n  padding: 2px;\n  border-spacing: 0px;\n  border-collapse: collapse;\n  margin-left: 40px;\n  margin-top: 7px;\n}\n\ntable.modificationtable th {\n  font-size: 10px;\n  text-align: center;\n  background-color: #EEE;\n  border: 1px #888 solid;\n  padding: 3px 6px;\n  font-weight: bold;\n}\n\ntable.modificationtable td {\n  font-size: 90%;\n  border: 1px #888 solid;\n  padding: 3px 6px;\n  text-align: left;\n  font-family: courier, monospace;\n}\n\n.apiDiffAdded {\n  font-style: italic;\n  font-size: 80%;\n  color: blue;\n}\n\n.apiDiffModified {\n  font-style: italic;\n  font-size: 80%;\n  color: #080;\n}\n\n.apiDiffRemoved {\n  font-style: italic;\n  font-size: 80%;\n  color: red;\n}\n\n.apiDiffFeature {\n  font-style: italic;\n  font-size: 80%;\n  color: orange;\n}\n\n.apiDiffBugfix {\n  font-style: italic;\n  font-size: 80%;\n  color: black;\n}\n\n.contributor_profile {\n  padding: 5px;\n  margin: 0 5px;\n  margin-bottom: 20px;\n  border: 1px solid #DDD;\n  background-color: #FFF;\n  float: left;\n}\n\n.contributor_profile .retired {\n  opacity: 0.5;\n}\n\n.contributor_profile .name {\n  margin-top: 0.2em;\n  text-align: center;\n  width: 135px;\n}\n\n.contributor_profile .role {\n  text-align: center;\n  color: #888;\n  margin-bottom: 0.3em;\n}\n\n.contributor_profile .twitter,\n.contributor_profile .github {\n  text-align: center;\n}\n\n#github {\n  float: right;\n  margin-top: 20px;\n}\n\n#github .issues {\n  color: #AAA;\n  padding: 5px;\n  margin-top: 10px;\n  margin-left: 10px;\n  border: 1px solid #EEE;\n  font-size: 2em;\n}\n\n#github .issues.no-issues {\n  background-color: #C9FFD4;\n}\n\n#github .issues.few-issues {\n  background-color: #FFFFC9;\n}\n\n#github .issues.many-issues {\n  background-color: #FFC9C9;\n}\n"
  },
  {
    "path": "docs/js/widget.js",
    "content": "/**\n * Welcome to janky-town. This code is messy as shit.\n */\n\nvar GitHubAPI = {};\n\nGitHubAPI.Repo = function(username, reponame, callback) {\n  requestURL = \"https://api.github.com/repos/\"+username+\"/\"+reponame+'?callback=?';\n  $.getJSON(requestURL, function(json, status){\n    callback(json.data, status);\n  });\n};\nGitHubAPI.RepoEvents = function(username, reponame, callback) {\n  requestURL = \"https://api.github.com/repos/\"+username+\"/\"+reponame+\"/events?callback=?\";\n  $.getJSON(requestURL, function(json, status){\n    callback(json.data, status);\n  });\n};\nGitHubAPI.RepoIssues = function(username, reponame, labels, callback) {\n  requestURL = \"https://api.github.com/repos/\"+username+\"/\"+reponame+'/issues?labels='+labels+'&callback=?';\n  $.getJSON(requestURL, function(json, status){\n    callback(json.data, status);\n  });\n};\nfunction normalizeDate(date) {\n  var relative_to = new Date();\n  var delta = parseInt((relative_to.getTime() - date.getTime()) / 1000);\n\n  var out = '';\n  if (delta < 60) {\n    out = 'a minute ago';\n  } else if(delta < 120) {\n    out = 'couple of minutes ago';\n  } else if(delta < (45*60)) {\n    out = (parseInt(delta / 60)).toString() + ' minutes ago';\n  } else if(delta < (90*60)) {\n    out = 'an hour ago';\n  } else if(delta < (24*60*60)) {\n    out = '' + (parseInt(delta / 3600 + 0.5)).toString() + ' hours ago';\n  } else if(delta < (48*60*60)) {\n    out = '1 day ago';\n  } else {\n    out = (parseInt(delta / 86400)).toString() + ' days ago';\n  }\n\n  return out;\n}\n\nfunction fetchIssues(feature, element, type, typename) {\n  var labels = type+',['+feature+']';\n  element.attr('href', 'http://github.com/jverkoey/nimbus/issues?labels='+labels);\n  GitHubAPI.RepoIssues('jverkoey', 'nimbus', labels, function(json, status) {\n    if (json) {\n      var text = json.length;\n      if (json.length == 0) {\n        text = 'No '+typename+'s'\n      } else if (json.length == 1) {\n        text = text + ' ' + typename;\n      } else {\n        text = text + ' ' + typename + 's';\n      }\n      element.html(text);\n      if (type == 'bug') {\n        if (json.length == 0) {\n          element.addClass('no-issues');\n        } else if (json.length < 3) {\n          element.addClass('few-issues');\n        } else {\n          element.addClass('many-issues');\n        }\n      }\n    }\n  });\n}\n\n$(document).ready(function(){\n  var element = $('#github');\n  if (element && element.length > 0) {\n    // Move the node higher in the page.\n    element.remove();\n    $('#doc-content .header').prepend(element);\n    var bugs = $('<a class=\"issues\">');\n    var features = $('<a class=\"issues\">');\n    var updatingText = 'Updating...';\n    bugs.html(updatingText);\n    features.html(updatingText);\n\n    element.append(bugs).append(features);\n\n    fetchIssues(element.attr('feature'), bugs, 'bug', 'bug');\n    fetchIssues(element.attr('feature'), features, 'feature', 'feature request');\n  }\n});"
  },
  {
    "path": "docs/layout/DoxygenLayout.xml",
    "content": "<doxygenlayout version=\"1.0\">\n  <!-- Generated by doxygen 1.8.6 -->\n  <!-- Navigation index tabs for HTML output -->\n  <navindex>\n    <tab type=\"mainpage\" visible=\"yes\" title=\"\"/>\n    <tab type=\"pages\" visible=\"yes\" title=\"\" intro=\"\"/>\n    <tab type=\"modules\" visible=\"yes\" title=\"\" intro=\"\"/>\n    <tab type=\"namespaces\" visible=\"yes\" title=\"\">\n      <tab type=\"namespacelist\" visible=\"yes\" title=\"\" intro=\"\"/>\n      <tab type=\"namespacemembers\" visible=\"yes\" title=\"\" intro=\"\"/>\n    </tab>\n    <tab type=\"classes\" visible=\"yes\" title=\"\">\n      <tab type=\"classlist\" visible=\"yes\" title=\"\" intro=\"\"/>\n      <tab type=\"classindex\" visible=\"$ALPHABETICAL_INDEX\" title=\"\"/> \n      <tab type=\"hierarchy\" visible=\"yes\" title=\"\" intro=\"\"/>\n      <tab type=\"classmembers\" visible=\"yes\" title=\"\" intro=\"\"/>\n    </tab>\n    <tab type=\"files\" visible=\"yes\" title=\"\">\n      <tab type=\"filelist\" visible=\"yes\" title=\"\" intro=\"\"/>\n      <tab type=\"globals\" visible=\"yes\" title=\"\" intro=\"\"/>\n    </tab>\n    <tab type=\"examples\" visible=\"yes\" title=\"\" intro=\"\"/>  \n  </navindex>\n\n  <!-- Layout definition for a class page -->\n  <class>\n    <detaileddescription title=\"Overview\"/>\n    <includes visible=\"$SHOW_INCLUDE_FILES\"/>\n    <inheritancegraph visible=\"$CLASS_GRAPH\"/>\n    <collaborationgraph visible=\"$COLLABORATION_GRAPH\"/>\n    <memberdecl>\n      <nestedclasses visible=\"yes\" title=\"\"/>\n      <publictypes title=\"\"/>\n      <services title=\"\"/>\n      <interfaces title=\"\"/>\n      <publicslots title=\"\"/>\n      <signals title=\"\"/>\n      <publicmethods title=\"Tasks\"/>\n      <publicstaticmethods title=\"\"/>\n      <publicattributes title=\"\"/>\n      <publicstaticattributes title=\"\"/>\n      <protectedtypes title=\"\"/>\n      <protectedslots title=\"\"/>\n      <protectedmethods title=\"\"/>\n      <protectedstaticmethods title=\"\"/>\n      <protectedattributes title=\"\"/>\n      <protectedstaticattributes title=\"\"/>\n      <packagetypes title=\"\"/>\n      <packagemethods title=\"\"/>\n      <packagestaticmethods title=\"\"/>\n      <packageattributes title=\"\"/>\n      <packagestaticattributes title=\"\"/>\n      <properties title=\"\"/>\n      <events title=\"\"/>\n      <privatetypes title=\"\"/>\n      <privateslots title=\"\"/>\n      <privatemethods title=\"\"/>\n      <privatestaticmethods title=\"\"/>\n      <privateattributes title=\"\"/>\n      <privatestaticattributes title=\"\"/>\n      <friends title=\"\"/>\n      <related title=\"\" subtitle=\"\"/>\n      <membergroups visible=\"yes\"/>\n    </memberdecl>\n    <memberdef>\n      <inlineclasses title=\"\"/>\n      <typedefs title=\"\"/>\n      <enums title=\"\"/>\n      <services title=\"\"/>\n      <interfaces title=\"\"/>\n      <constructors title=\"\"/>\n      <functions title=\"\"/>\n      <related title=\"\"/>\n      <variables title=\"\"/>\n      <properties title=\"\"/>\n      <events title=\"\"/>\n    </memberdef>\n    <allmemberslink visible=\"yes\"/>\n    <usedfiles visible=\"$SHOW_USED_FILES\"/>\n    <authorsection visible=\"yes\"/>\n  </class>\n\n  <!-- Layout definition for a namespace page -->\n  <namespace>\n    <briefdescription visible=\"yes\"/>\n    <memberdecl>\n      <nestednamespaces visible=\"yes\" title=\"\"/>\n      <constantgroups visible=\"yes\" title=\"\"/>\n      <classes visible=\"yes\" title=\"\"/>\n      <typedefs title=\"\"/>\n      <enums title=\"\"/>\n      <functions title=\"\"/>\n      <variables title=\"\"/>\n      <membergroups visible=\"yes\"/>\n    </memberdecl>\n    <detaileddescription title=\"\"/>\n    <memberdef>\n      <inlineclasses title=\"\"/>\n      <typedefs title=\"\"/>\n      <enums title=\"\"/>\n      <functions title=\"\"/>\n      <variables title=\"\"/>\n    </memberdef>\n    <authorsection visible=\"yes\"/>\n  </namespace>\n\n  <!-- Layout definition for a file page -->\n  <file>\n    <briefdescription visible=\"yes\"/>\n    <includes visible=\"$SHOW_INCLUDE_FILES\"/>\n    <includegraph visible=\"$INCLUDE_GRAPH\"/>\n    <includedbygraph visible=\"$INCLUDED_BY_GRAPH\"/>\n    <sourcelink visible=\"yes\"/>\n    <memberdecl>\n      <classes visible=\"yes\" title=\"\"/>\n      <namespaces visible=\"yes\" title=\"\"/>\n      <constantgroups visible=\"yes\" title=\"\"/>\n      <defines title=\"\"/>\n      <typedefs title=\"\"/>\n      <enums title=\"\"/>\n      <functions title=\"\"/>\n      <variables title=\"\"/>\n      <membergroups visible=\"yes\"/>\n    </memberdecl>\n    <detaileddescription title=\"\"/>\n    <memberdef>\n      <inlineclasses title=\"\"/>\n      <defines title=\"\"/>\n      <typedefs title=\"\"/>\n      <enums title=\"\"/>\n      <functions title=\"\"/>\n      <variables title=\"\"/>\n    </memberdef>\n    <authorsection/>\n  </file>\n\n  <!-- Layout definition for a group page -->\n  <group>\n    <groupgraph visible=\"$GROUP_GRAPHS\"/>\n    <memberdecl>\n      <nestedgroups visible=\"yes\" title=\"\"/>\n      <dirs visible=\"yes\" title=\"\"/>\n      <files visible=\"yes\" title=\"\"/>\n      <namespaces visible=\"yes\" title=\"\"/>\n      <classes visible=\"yes\" title=\"\"/>\n      <defines title=\"\"/>\n      <typedefs title=\"\"/>\n      <enums title=\"\"/>\n      <enumvalues title=\"\"/>\n      <functions title=\"\"/>\n      <variables title=\"\"/>\n      <signals title=\"\"/>\n      <publicslots title=\"\"/>\n      <protectedslots title=\"\"/>\n      <privateslots title=\"\"/>\n      <events title=\"\"/>\n      <properties title=\"\"/>\n      <friends title=\"\"/>\n      <membergroups visible=\"yes\"/>\n    </memberdecl>\n    <detaileddescription title=\"Overview\"/>\n    <memberdef>\n      <pagedocs/>\n      <inlineclasses title=\"\"/>\n      <defines title=\"\"/>\n      <typedefs title=\"\"/>\n      <enums title=\"\"/>\n      <enumvalues title=\"\"/>\n      <functions title=\"\"/>\n      <variables title=\"\"/>\n      <signals title=\"\"/>\n      <publicslots title=\"\"/>\n      <protectedslots title=\"\"/>\n      <privateslots title=\"\"/>\n      <events title=\"\"/>\n      <properties title=\"\"/>\n      <friends title=\"\"/>\n    </memberdef>\n    <authorsection visible=\"yes\"/>\n  </group>\n\n  <!-- Layout definition for a directory page -->\n  <directory>\n    <briefdescription visible=\"yes\"/>\n    <directorygraph visible=\"yes\"/>\n    <memberdecl>\n      <dirs visible=\"yes\"/>\n      <files visible=\"yes\"/>\n    </memberdecl>\n    <detaileddescription title=\"\"/>\n  </directory>\n</doxygenlayout>\n"
  },
  {
    "path": "docs/layout/footer-docset.html",
    "content": "<!-- HTML footer for doxygen 1.8.6-->\n<!-- start footer part -->\n</body>\n</html>\n"
  },
  {
    "path": "docs/layout/footer.html",
    "content": "<!-- HTML footer for doxygen 1.8.6-->\n<!-- start footer part -->\n<script type=\"text/javascript\" src=\"widget.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "docs/layout/header-docset.html",
    "content": "<!-- HTML header for doxygen 1.8.6-->\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=9\"/>\n<meta name=\"generator\" content=\"Doxygen $doxygenversion\"/>\n<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->\n<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->\n<link href=\"$relpath^tabs.css\" rel=\"stylesheet\" type=\"text/css\"/>\n<script type=\"text/javascript\" src=\"$relpath^jquery.js\"></script>\n<script type=\"text/javascript\" src=\"$relpath^dynsections.js\"></script>\n$treeview\n$search\n$mathjax\n<link href=\"$relpath^$stylesheet\" rel=\"stylesheet\" type=\"text/css\" />\n$extrastylesheet\n<link href=\"$relpath^nimbuskit.css\" rel=\"stylesheet\" type=\"text/css\" />\n</head>\n<body>\n<div id=\"top\"><!-- do not remove this div, it is closed by doxygen! -->\n<!--END TITLEAREA-->\n<!-- end header part -->\n"
  },
  {
    "path": "docs/layout/header.html",
    "content": "<!-- HTML header for doxygen 1.8.6-->\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=9\"/>\n<meta name=\"generator\" content=\"Doxygen $doxygenversion\"/>\n<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->\n<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->\n<link href=\"$relpath^tabs.css\" rel=\"stylesheet\" type=\"text/css\"/>\n<script type=\"text/javascript\" src=\"$relpath^jquery.js\"></script>\n<script type=\"text/javascript\" src=\"$relpath^dynsections.js\"></script>\n$treeview\n$search\n$mathjax\n<link href=\"$relpath^$stylesheet\" rel=\"stylesheet\" type=\"text/css\" />\n$extrastylesheet\n<link href=\"$relpath^nimbuskit.css\" rel=\"stylesheet\" type=\"text/css\" />\n\n<script type=\"text/javascript\">\n\n  var _gaq = _gaq || [];\n  _gaq.push(['_setAccount', 'UA-24278774-1']);\n  _gaq.push(['_setDomainName', 'nimbuskit.info']);\n  _gaq.push(['_trackPageview']);\n\n  (function() {\n    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n  })();\n\n</script>\n</head>\n<body>\n<div id=\"top\"><!-- do not remove this div, it is closed by doxygen! -->\n\n<!--BEGIN TITLEAREA-->\n<div id=\"titlearea\">\n<a href=\"index.html\"><img style=\"float:left\" src=\"nimbus128.png\" width=\"80\" height=\"80\" /></a>\n<table cellspacing=\"0\" cellpadding=\"0\">\n <tbody>\n <tr style=\"height: 56px;\">\n  <!--BEGIN PROJECT_LOGO-->\n  <td id=\"projectlogo\"><img alt=\"Logo\" src=\"$relpath^$projectlogo\"/></td>\n  <!--END PROJECT_LOGO-->\n  <!--BEGIN PROJECT_NAME-->\n  <td style=\"padding-left: 0.5em;\">\n   <div id=\"projectname\">$projectname\n   <!--BEGIN PROJECT_NUMBER-->&#160;<span id=\"projectnumber\">$projectnumber - <a href=\"http://github.com/jverkoey/nimbus\">Fork Nimbus on Github</a> - <a href=\"http://wiki.nimbuskit.info/\">Visit the Nimbus Wiki</a></span><!--END PROJECT_NUMBER-->\n   </div>\n   <!--BEGIN PROJECT_BRIEF--><div id=\"projectbrief\">$projectbrief</div><!--END PROJECT_BRIEF-->\n  </td>\n  <!--END PROJECT_NAME-->\n  <!--BEGIN !PROJECT_NAME-->\n   <!--BEGIN PROJECT_BRIEF-->\n    <td style=\"padding-left: 0.5em;\">\n    <div id=\"projectbrief\">$projectbrief</div>\n    </td>\n   <!--END PROJECT_BRIEF-->\n  <!--END !PROJECT_NAME-->\n  <!--BEGIN DISABLE_INDEX-->\n   <!--BEGIN SEARCHENGINE-->\n   <td>$searchbox</td>\n   <!--END SEARCHENGINE-->\n  <!--END DISABLE_INDEX-->\n </tr>\n </tbody>\n</table>\n</div>\n<!--END TITLEAREA-->\n<!-- end header part -->\n"
  },
  {
    "path": "docs/nimbusdocset.atom",
    "content": "<feed xmlns=\"http://www.w3.org/2005/Atom\"\n  xmlns:docset=\"http://developer.apple.com/rss/docset_extensions\"\n  xml:lang=\"en\">\n  <id>http://jverkoey.github.com/nimbus</id>\n  <title type=\"text\">Nimbus Documentation</title>\n  <updated>2012-12-10T12:00:01Z</updated>\n  <author>\n    <name>Jeff Verkoeyen</name>\n    <uri>http://nimbuskit.info/</uri>\n  </author>\n  <rights>Copyright (c) 2012, Jeff Verkoeyen</rights>\n  <link rel=\"self\" href=\"nimbusdocset.atom\" />\n  <entry>\n    <id>http://jverkoey.github.com/nimbus/docsets/org.jeffverkoeyen.nimbus.1.0.0</id>\n    <title type=\"text\">Nimbus Documentation</title>\n    <summary type=\"text\">Includes reference for Nimbus</summary>\n    <updated>2012-12-10T12:00:00Z</updated>\n    <link rel=\"enclosure\" type=\"application/octet-stream\" href=\"/nimbus/docsets/org.jeffverkoeyen.nimbus.1.0.0.xar\" />\n    <docset:identifier>org.jeffverkoeyen.nimbus</docset:identifier>\n    <docset:version>1.0.0</docset:version>\n    <docset:minimumXcodeVersion>4.0</docset:minimumXcodeVersion>\n  </entry>\n  <entry>\n    <id>http://jverkoey.github.com/nimbus/docsets/org.jeffverkoeyen.nimbus.0.9.3</id>\n    <title type=\"text\">Nimbus Documentation</title>\n    <summary type=\"text\">Includes reference for Nimbus</summary>\n    <updated>2012-06-10T12:00:00Z</updated>\n    <link rel=\"enclosure\" type=\"application/octet-stream\" href=\"/nimbus/docsets/org.jeffverkoeyen.nimbus.0.9.3.xar\" />\n    <docset:identifier>org.jeffverkoeyen.nimbus</docset:identifier>\n    <docset:version>0.9.3</docset:version>\n    <docset:minimumXcodeVersion>4.0</docset:minimumXcodeVersion>\n  </entry>\n  <entry>\n    <id>http://jverkoey.github.com/nimbus/docsets/org.jeffverkoeyen.nimbus.0.9.2</id>\n    <title type=\"text\">Nimbus Documentation</title>\n    <summary type=\"text\">Includes reference for Nimbus</summary>\n    <updated>2012-02-19T12:00:00Z</updated>\n    <link rel=\"enclosure\" type=\"application/octet-stream\" href=\"/nimbus/docsets/org.jeffverkoeyen.nimbus.0.9.2.xar\" />\n    <docset:identifier>org.jeffverkoeyen.nimbus</docset:identifier>\n    <docset:version>0.9.2</docset:version>\n    <docset:minimumXcodeVersion>3.0</docset:minimumXcodeVersion>\n  </entry>\n  <entry>\n    <id>http://jverkoey.github.com/nimbus/docsets/org.jeffverkoeyen.nimbus.0.9.1</id>\n    <title type=\"text\">Nimbus Documentation</title>\n    <summary type=\"text\">Includes reference for Nimbus</summary>\n    <updated>2011-12-05T12:00:00Z</updated>\n    <link rel=\"enclosure\" type=\"application/octet-stream\" href=\"/nimbus/docsets/org.jeffverkoeyen.nimbus.0.9.1.xar\" />\n    <docset:identifier>org.jeffverkoeyen.nimbus</docset:identifier>\n    <docset:version>0.9.1</docset:version>\n    <docset:minimumXcodeVersion>3.0</docset:minimumXcodeVersion>\n  </entry>\n  <entry>\n    <id>http://jverkoey.github.com/nimbus/docsets/org.jeffverkoeyen.nimbus.0.9.0</id>\n    <title type=\"text\">Nimbus Documentation</title>\n    <summary type=\"text\">Includes reference for Nimbus</summary>\n    <updated>2011-10-24T12:00:00Z</updated>\n    <link rel=\"enclosure\" type=\"application/octet-stream\" href=\"/nimbus/docsets/org.jeffverkoeyen.nimbus.0.9.0.xar\" />\n    <docset:identifier>org.jeffverkoeyen.nimbus</docset:identifier>\n    <docset:version>0.9.0</docset:version>\n    <docset:minimumXcodeVersion>3.0</docset:minimumXcodeVersion>\n  </entry>\n</feed>\n"
  },
  {
    "path": "examples/catalog/Catalog/ActionsTableModelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface ActionsTableModelViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ActionsTableModelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"ActionsTableModelViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of handling actions in a UITableView.\n//\n// The NITableViewActions object attaches blocks to objects in three contexts: tapping, navigating,\n// and detail actions. Any combination of these three blocks may be attached to a given object.\n// The actions object will automatically update the accessory type of the cell when it is displayed\n// so that it shows the correct accessory type for the available actions.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NITableViewModel\n// NITableViewActions\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface ActionsTableModelViewController ()\n@property (nonatomic, retain) NITableViewModel* model;\n\n// The actions are stored in a separate object from the model.\n@property (nonatomic, retain) NITableViewActions* actions;\n@end\n\n@implementation ActionsTableModelViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"Actions\";\n\n    // We provide a weak reference to the controller object so that the actions object can pass\n    // the controller to the block when the action is executed.\n    _actions = [[NITableViewActions alloc] initWithTarget:self];\n\n    // This is what an action block looks like. The block is given the object that was tapped and\n    // the containing controller. In the following two blocks we simply show an alert view.\n    NIActionBlock tapAction = ^BOOL(id object, UIViewController *controller, NSIndexPath* indexPath) {\n      UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"Notice\"\n                                                      message:@\"You tapped a cell!\"\n                                                     delegate:nil\n                                            cancelButtonTitle:@\"OK\"\n                                            otherButtonTitles:nil];\n      [alert show];\n\n      // For tap actions specifically, returning YES means that we want the cell to deselect itself\n      // after the action has performed. All other types of actions ignore the return value.\n      return YES;\n    };\n    \n    NIActionBlock tapAction2 = ^BOOL(id object, UIViewController *controller, NSIndexPath* indexPath) {\n      UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"Notice\"\n                                                      message:@\"Alternative tap action\"\n                                                     delegate:nil\n                                            cancelButtonTitle:@\"OK\"\n                                            otherButtonTitles:nil];\n      [alert show];\n      return YES;\n    };\n\n    NSArray* tableContents =\n    [NSArray arrayWithObjects:\n\n     // As seen in previous examples, this will show a cell that is not actionable. Tapping it will\n     // not highlight it, nor are any cell accessories shown.\n     [NITitleCellObject objectWithTitle:@\"No action attached\"],\n\n     @\"\",\n     // This attaches one of the tap action blocks defined above to this cell. Notice how we are\n     // using the return value of attachTapAction:toObject: here. The attach:toObject: methods all\n     // return the object that was passed in, allowing you to simultaneously add an object to a\n     // table model and attach an action to it.\n     [_actions attachToObject:[NITitleCellObject objectWithTitle:@\"Tap me\"]\n                     tapBlock:tapAction],\n\n     @\"\",\n     // This attaches a navigation action to the object. We use a standard method,\n     // NIPushControllerAction, here which simply instantiates the given class and then pushes it\n     // to the current navigation controller. This method does not work in all situations, in which\n     // cases you should implement your own block. When this cell appears it will automatically be\n     // assigned a navigation accessory type.\n     [_actions attachToObject:[NITitleCellObject objectWithTitle:@\"Navigate elsewhere\"]\n              navigationBlock:NIPushControllerAction([ActionsTableModelViewController class])],\n\n     // This attaches a detail action to the object, displaying a detail accessory on the cell that\n     // can be tapped. When the detail accessory is tapped, this action is executed.\n     [_actions attachToObject:[NITitleCellObject objectWithTitle:@\"Detail action\"]\n                  detailBlock:NIPushControllerAction([ActionsTableModelViewController class])],\n\n     // It is possible to attach multiple types of actions to a single object. In the next three\n     // examples we show attaching different types of actions to objects.\n     [_actions attachToObject:\n      [_actions attachToObject:[NITitleCellObject objectWithTitle:@\"Navigate and detail\"]\n               navigationBlock:NIPushControllerAction([ActionsTableModelViewController class])]\n                   detailBlock:NIPushControllerAction([ActionsTableModelViewController class])],\n\n     [_actions attachToObject:\n      [_actions attachToObject:[NITitleCellObject objectWithTitle:@\"Tap and detail\"]\n                      tapBlock:tapAction]\n                   detailBlock:NIPushControllerAction([ActionsTableModelViewController class])],\n\n     // When you have a tap and navigation action attached to an object, both will be executed when\n     // you tap the cell. Try tapping this cell and you will see that it navigates and shows an\n     // alert view simultaneously.\n     [_actions attachToObject:\n      [_actions attachToObject:\n       [_actions attachToObject:[NITitleCellObject objectWithTitle:@\"All actions\"]\n                navigationBlock:NIPushControllerAction([ActionsTableModelViewController class])]\n                       tapBlock:tapAction]\n                    detailBlock:NIPushControllerAction([ActionsTableModelViewController class])],\n\n     @\"Implicit Actions\",\n     // It is possible to set up implicit actions by attaching an action to a class. When such an\n     // attachment is made, all instances of that class (including subclasses of that class) will\n     // implicitly have the given action. For example, we attach below a tap action to the\n     // NISubtitleCellObject class. Now when we include any NISubtitleCellObject or subclass of\n     // NISubtitleCellObject in the model they will automatically respond to taps.\n     [NISubtitleCellObject objectWithTitle:@\"Tap me\" subtitle:@\"Implicit action\"],\n\n     // You can also explicitly override the implicit action by attaching an action directly to\n     // the object.\n     [_actions attachToObject:[NISubtitleCellObject objectWithTitle:@\"Override\" subtitle:@\"Explicit tap action\"]\n                     tapBlock:tapAction2],\n\n     @\"Selector Actions\",\n     // Consider attaching a selector to an object instead of a block when an action requires\n     // complex logic. The selector will be performed on the NITableViewActions target and the\n     // attached object will be provided as the first argument.\n     [_actions attachToObject:[NITitleCellObject objectWithTitle:@\"Tap me\"]\n                  tapSelector:@selector(didTapObject:)],\n\n     nil];\n\n    // This attaches a tap action to all instances of NISubtitleCellObject and is a great way to\n    // handle common cells.\n    [_actions attachToClass:[NISubtitleCellObject class] tapBlock:tapAction];\n\n    _model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                     delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.tableView.dataSource = self.model;\n\n  // What we're doing here is known as \"delegate chaining\". It uses the message forwarding\n  // functionality of Objective-C to insert the actions object between the table view\n  // and this controller. The actions object forwards UITableViewDelegate methods along and\n  // selectively intercepts methods required to make user interactions work.\n  //\n  // Experiment: try commenting out this line. You'll notice that you can no longer tap any of\n  // the cells in the table view and that they no longer show the disclosure accessory types.\n  // Cool, eh? That this functionality is all provided to you in one line should make you\n  // heel-click.\n  self.tableView.delegate = [self.actions forwardingTo:self];\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n#pragma mark - Actions\n\n- (BOOL)didTapObject:(id)object {\n  NSLog(@\"Did tap object %@\", object);\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/AlignmentAttributedLabelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Contributed by Jeroen Trappers\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface AlignmentAttributedLabelViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/AlignmentAttributedLabelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Contributed by Jeroen Trappers\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"AlignmentAttributedLabelViewController.h\"\n#import \"NIAttributedLabel.h\"\n\n@interface AlignmentAttributedLabelViewController ()\n\n@property (weak, nonatomic) IBOutlet NIAttributedLabel *topLeft;\n@property (weak, nonatomic) IBOutlet NIAttributedLabel *top;\n@property (weak, nonatomic) IBOutlet NIAttributedLabel *topRight;\n@property (weak, nonatomic) IBOutlet NIAttributedLabel *left;\n@property (weak, nonatomic) IBOutlet NIAttributedLabel *center;\n@property (weak, nonatomic) IBOutlet NIAttributedLabel *right;\n@property (weak, nonatomic) IBOutlet NIAttributedLabel *bottom;\n@property (weak, nonatomic) IBOutlet NIAttributedLabel *bottomRight;\n@property (weak, nonatomic) IBOutlet NIAttributedLabel *bottomLeft;\n\n@end\n\n@implementation AlignmentAttributedLabelViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Alignment\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n  // Do any additional setup after loading the view from its nib.\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n\n  self.topLeft.verticalTextAlignment = NIVerticalTextAlignmentTop;\n  self.top.verticalTextAlignment = NIVerticalTextAlignmentTop;\n  self.topRight.verticalTextAlignment = NIVerticalTextAlignmentTop;\n\n  self.left.verticalTextAlignment = NIVerticalTextAlignmentMiddle;\n  self.center.verticalTextAlignment = NIVerticalTextAlignmentMiddle;\n  self.right.verticalTextAlignment = NIVerticalTextAlignmentMiddle;\n\n  self.bottomLeft.verticalTextAlignment = NIVerticalTextAlignmentBottom;\n  self.bottom.verticalTextAlignment = NIVerticalTextAlignmentBottom;\n  self.bottomRight.verticalTextAlignment = NIVerticalTextAlignmentBottom;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/AlignmentAttributedLabelViewController.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" colorMatched=\"YES\">\n    <dependencies>\n        <deployment version=\"1792\" identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14460.20\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"AlignmentAttributedLabelViewController\">\n            <connections>\n                <outlet property=\"bottom\" destination=\"18\" id=\"27\"/>\n                <outlet property=\"bottomLeft\" destination=\"17\" id=\"29\"/>\n                <outlet property=\"bottomRight\" destination=\"19\" id=\"28\"/>\n                <outlet property=\"center\" destination=\"15\" id=\"25\"/>\n                <outlet property=\"left\" destination=\"14\" id=\"24\"/>\n                <outlet property=\"right\" destination=\"16\" id=\"26\"/>\n                <outlet property=\"top\" destination=\"12\" id=\"22\"/>\n                <outlet property=\"topLeft\" destination=\"4\" id=\"21\"/>\n                <outlet property=\"topRight\" destination=\"13\" id=\"23\"/>\n                <outlet property=\"view\" destination=\"1\" id=\"3\"/>\n            </connections>\n        </placeholder>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view contentMode=\"scaleToFill\" id=\"1\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <subviews>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Label\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"4\" customClass=\"NIAttributedLabel\">\n                    <rect key=\"frame\" x=\"20\" y=\"20\" width=\"82\" height=\"74\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.66666668653488159\" green=\"0.66666668653488159\" blue=\"0.66666668653488159\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"12\" customClass=\"NIAttributedLabel\">\n                    <rect key=\"frame\" x=\"119\" y=\"20\" width=\"82\" height=\"74\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.66666668653488159\" green=\"0.66666668653488159\" blue=\"0.66666668653488159\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Label\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"13\" customClass=\"NIAttributedLabel\">\n                    <rect key=\"frame\" x=\"218\" y=\"20\" width=\"82\" height=\"74\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.66666668653488159\" green=\"0.66666668653488159\" blue=\"0.66666668653488159\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Label\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"14\" customClass=\"NIAttributedLabel\">\n                    <rect key=\"frame\" x=\"20\" y=\"102\" width=\"82\" height=\"74\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.66666668653488159\" green=\"0.66666668653488159\" blue=\"0.66666668653488159\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"15\" customClass=\"NIAttributedLabel\">\n                    <rect key=\"frame\" x=\"119\" y=\"102\" width=\"82\" height=\"74\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.66666668653488159\" green=\"0.66666668653488159\" blue=\"0.66666668653488159\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Label\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"16\" customClass=\"NIAttributedLabel\">\n                    <rect key=\"frame\" x=\"218\" y=\"102\" width=\"82\" height=\"74\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.66666668653488159\" green=\"0.66666668653488159\" blue=\"0.66666668653488159\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Label\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"17\" customClass=\"NIAttributedLabel\">\n                    <rect key=\"frame\" x=\"20\" y=\"184\" width=\"82\" height=\"74\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.66666668653488159\" green=\"0.66666668653488159\" blue=\"0.66666668653488159\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"18\" customClass=\"NIAttributedLabel\">\n                    <rect key=\"frame\" x=\"119\" y=\"184\" width=\"82\" height=\"74\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.66666668653488159\" green=\"0.66666668653488159\" blue=\"0.66666668653488159\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Label\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"19\" customClass=\"NIAttributedLabel\">\n                    <rect key=\"frame\" x=\"218\" y=\"184\" width=\"82\" height=\"74\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.66666668653488159\" green=\"0.66666668653488159\" blue=\"0.66666668653488159\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n            </subviews>\n            <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n        </view>\n    </objects>\n</document>\n"
  },
  {
    "path": "examples/catalog/Catalog/AppDelegate.h",
    "content": "//\n// Copyright 2011-2012 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate>\n@property (strong, nonatomic) UIWindow *window;\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/AppDelegate.m",
    "content": "//\n// Copyright 2011-2012 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"AppDelegate.h\"\n\n#import \"CatalogViewController.h\"\n\n@implementation AppDelegate\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];\n  self.window.backgroundColor = [UIColor whiteColor];\n  CatalogViewController* catalogController = [[CatalogViewController alloc] init];\n  self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:catalogController];\n  [self.window makeKeyAndVisible];\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ApplicationBadges.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" colorMatched=\"YES\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <deployment version=\"1792\" identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14460.20\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"InterfaceBuilderBadgeViewController\">\n            <connections>\n                <outlet property=\"badgeView\" destination=\"10\" id=\"11\"/>\n                <outlet property=\"badgeView2\" destination=\"18\" id=\"19\"/>\n                <outlet property=\"view\" destination=\"1\" id=\"3\"/>\n            </connections>\n        </placeholder>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view contentMode=\"scaleToFill\" id=\"1\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"480\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <subviews>\n                <button opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" lineBreakMode=\"middleTruncation\" id=\"12\">\n                    <rect key=\"frame\" x=\"20\" y=\"34\" width=\"56\" height=\"59\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <fontDescription key=\"fontDescription\" type=\"boldSystem\" size=\"button\"/>\n                    <state key=\"normal\" title=\"Hello!\" image=\"Icon.png\">\n                        <color key=\"titleColor\" red=\"0.1960784314\" green=\"0.30980392159999998\" blue=\"0.52156862749999999\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <color key=\"titleShadowColor\" red=\"0.5\" green=\"0.5\" blue=\"0.5\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    </state>\n                    <state key=\"highlighted\">\n                        <color key=\"titleColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    </state>\n                </button>\n                <view contentMode=\"scaleToFill\" id=\"10\" customClass=\"NIBadgeView\">\n                    <rect key=\"frame\" x=\"58\" y=\"20\" width=\"45\" height=\"37\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                </view>\n                <button opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" lineBreakMode=\"middleTruncation\" id=\"17\">\n                    <rect key=\"frame\" x=\"106\" y=\"34\" width=\"56\" height=\"59\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <fontDescription key=\"fontDescription\" type=\"boldSystem\" size=\"button\"/>\n                    <state key=\"normal\" title=\"Hello!\" image=\"Icon.png\">\n                        <color key=\"titleColor\" red=\"0.1960784314\" green=\"0.30980392159999998\" blue=\"0.52156862749999999\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <color key=\"titleShadowColor\" red=\"0.5\" green=\"0.5\" blue=\"0.5\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    </state>\n                    <state key=\"highlighted\">\n                        <color key=\"titleColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    </state>\n                </button>\n                <view contentMode=\"scaleToFill\" id=\"18\" customClass=\"NIBadgeView\">\n                    <rect key=\"frame\" x=\"144\" y=\"20\" width=\"45\" height=\"37\"/>\n                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                    <color key=\"backgroundColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                </view>\n            </subviews>\n            <color key=\"backgroundColor\" cocoaTouchSystemColor=\"scrollViewTexturedBackgroundColor\"/>\n            <freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>\n        </view>\n    </objects>\n    <resources>\n        <image name=\"Icon.png\" width=\"57\" height=\"57\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "examples/catalog/Catalog/AttributedLabelMashup.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" colorMatched=\"YES\">\n    <dependencies>\n        <deployment version=\"1792\" identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14460.20\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"InterfaceBuilderAttributedLabelViewController\">\n            <connections>\n                <outlet property=\"label1\" destination=\"8\" id=\"81\"/>\n                <outlet property=\"label2\" destination=\"7\" id=\"79\"/>\n                <outlet property=\"label3\" destination=\"6\" id=\"80\"/>\n                <outlet property=\"label4\" destination=\"5\" id=\"82\"/>\n                <outlet property=\"nimbusTitle\" destination=\"9\" id=\"77\"/>\n                <outlet property=\"scrollView\" destination=\"4\" id=\"76\"/>\n                <outlet property=\"view\" destination=\"1\" id=\"3\"/>\n            </connections>\n        </placeholder>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view contentMode=\"scaleToFill\" id=\"1\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"416\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <subviews>\n                <scrollView clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" id=\"4\">\n                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"416\"/>\n                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                    <subviews>\n                        <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Nimbus\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" adjustsFontSizeToFit=\"NO\" id=\"9\" customClass=\"NIAttributedLabel\">\n                            <rect key=\"frame\" x=\"20\" y=\"20\" width=\"280\" height=\"47\"/>\n                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMaxY=\"YES\"/>\n                            <fontDescription key=\"fontDescription\" name=\"STHeitiTC-Medium\" family=\"Heiti TC\" pointSize=\"36\"/>\n                            <color key=\"textColor\" red=\"0.0\" green=\"0.59999999999999998\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                            <nil key=\"highlightedColor\"/>\n                            <connections>\n                                <outlet property=\"delegate\" destination=\"-1\" id=\"83\"/>\n                            </connections>\n                        </label>\n                        <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"Documentation &gt;= code\" lineBreakMode=\"tailTruncation\" adjustsFontSizeToFit=\"NO\" id=\"7\" customClass=\"NIAttributedLabel\">\n                            <rect key=\"frame\" x=\"20\" y=\"133\" width=\"280\" height=\"34\"/>\n                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMaxY=\"YES\"/>\n                            <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                            <color key=\"textColor\" red=\"0.36954829096794128\" green=\"0.54501217603683472\" blue=\"0.20968678593635559\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                            <nil key=\"highlightedColor\"/>\n                            <connections>\n                                <outlet property=\"delegate\" destination=\"-1\" id=\"84\"/>\n                            </connections>\n                        </label>\n                        <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"http://docs.nimbuskit.info\" lineBreakMode=\"tailTruncation\" adjustsFontSizeToFit=\"NO\" id=\"6\" customClass=\"NIAttributedLabel\">\n                            <rect key=\"frame\" x=\"20\" y=\"171\" width=\"295\" height=\"32\"/>\n                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMaxY=\"YES\"/>\n                            <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                            <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                            <nil key=\"highlightedColor\"/>\n                            <connections>\n                                <outlet property=\"delegate\" destination=\"-1\" id=\"85\"/>\n                            </connections>\n                        </label>\n                        <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" text=\"The iOS framework whose growth is bounded by its documentation.\" lineBreakMode=\"wordWrap\" numberOfLines=\"0\" adjustsFontSizeToFit=\"NO\" id=\"8\" customClass=\"NIAttributedLabel\">\n                            <rect key=\"frame\" x=\"20\" y=\"77\" width=\"280\" height=\"65\"/>\n                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMaxY=\"YES\"/>\n                            <fontDescription key=\"fontDescription\" name=\"SnellRoundhand-Bold\" family=\"Snell Roundhand\" pointSize=\"16\"/>\n                            <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                            <nil key=\"highlightedColor\"/>\n                            <connections>\n                                <outlet property=\"delegate\" destination=\"-1\" id=\"86\"/>\n                            </connections>\n                        </label>\n                        <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" lineBreakMode=\"wordWrap\" numberOfLines=\"0\" adjustsFontSizeToFit=\"NO\" id=\"5\" customClass=\"NIAttributedLabel\">\n                            <rect key=\"frame\" x=\"20\" y=\"207\" width=\"280\" height=\"128\"/>\n                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMaxY=\"YES\"/>\n                            <string key=\"text\">By focusing on documentation first and features second, Nimbus accelerates the development process of any application by being easy to use and simple to understand.</string>\n                            <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                            <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                            <nil key=\"highlightedColor\"/>\n                            <connections>\n                                <outlet property=\"delegate\" destination=\"-1\" id=\"87\"/>\n                            </connections>\n                        </label>\n                    </subviews>\n                </scrollView>\n            </subviews>\n            <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n            <simulatedNavigationBarMetrics key=\"simulatedTopBarMetrics\" prompted=\"NO\"/>\n            <freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>\n        </view>\n    </objects>\n</document>\n"
  },
  {
    "path": "examples/catalog/Catalog/BadgedLauncherButtonView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusLauncher.h\"\n\n@class NIBadgeView;\n\n/**\n * A subclass of NILauncherViewObject that provides badging support.\n *\n * Adding this type of object to a NILauncherViewModel will create a BadgedLauncherButtonView view.\n */\n@interface BadgedLauncherViewObject : NILauncherViewObject\n@property (nonatomic, assign) NSInteger badgeNumber;\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image badgeNumber:(NSInteger)badgeNumber;\n+ (id)objectWithTitle:(NSString *)title image:(UIImage *)image badgeNumber:(NSInteger)badgeNumber;\n@end\n\n/**\n * A launcher button view that displays a badge number.\n *\n * The badge is hidden if the number is 0.\n * The badge displays 99+ if the number is greater than 99.\n */\n@interface BadgedLauncherButtonView : NILauncherButtonView\n@property (nonatomic, retain) NIBadgeView* badgeView;\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BadgedLauncherButtonView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"BadgedLauncherButtonView.h\"\n\n#import \"NimbusBadge.h\"\n\n@implementation BadgedLauncherViewObject\n\n\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image badgeNumber:(NSInteger)badgeNumber {\n  if ((self = [super initWithTitle:title image:image])) {\n    _badgeNumber = badgeNumber;\n  }\n  return self;\n}\n\n+ (id)objectWithTitle:(NSString *)title image:(UIImage *)image badgeNumber:(NSInteger)badgeNumber {\n  return [[self alloc] initWithTitle:title image:image badgeNumber:badgeNumber];\n}\n\n- (Class)buttonViewClass {\n  return [BadgedLauncherButtonView class];\n}\n\n@end\n\n@implementation BadgedLauncherButtonView\n\n\n- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithReuseIdentifier:reuseIdentifier])) {\n    _badgeView = [[NIBadgeView alloc] initWithFrame:CGRectZero];\n    _badgeView.backgroundColor = [UIColor clearColor];\n    _badgeView.hidden = YES;\n\n    // This ensures that the badge will not eat taps.\n    _badgeView.userInteractionEnabled = NO;\n\n    [self addSubview:_badgeView];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  [self.badgeView sizeToFit];\n  // Find the image's top right corner.\n  CGPoint imageTopRight = CGPointMake(floorf((self.button.frame.size.width\n                                              + [self.button imageForState:UIControlStateNormal].size.width)\n                                             / 2.f),\n                                      floorf((self.button.frame.size.height\n                                              - [self.button imageForState:UIControlStateNormal].size.height)\n                                             / 2.f));\n\n  // Center the badge on the image's top right corner.\n  self.badgeView.frame = CGRectMake(floorf(imageTopRight.x - self.badgeView.frame.size.width / 2.f),\n                                    floorf(imageTopRight.y - self.badgeView.frame.size.height / 3.f),\n                                    self.badgeView.frame.size.width, self.badgeView.frame.size.height);\n}\n\n- (void)shouldUpdateViewWithObject:(BadgedLauncherViewObject *)object {\n  [super shouldUpdateViewWithObject:object];\n\n  NSInteger badgeNumber = NIBoundi(object.badgeNumber, 0, 100);\n  if (object.badgeNumber > 0) {\n    if (badgeNumber < 100) {\n      self.badgeView.text = [NSString stringWithFormat:@\"%zd\", badgeNumber];\n    } else {\n      self.badgeView.text = @\"99+\";\n    }\n    self.badgeView.hidden = NO;\n\n  } else {\n    self.badgeView.hidden = YES;\n  }\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BadgedLauncherViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusLauncher.h\"\n\n// All docs are in the .m.\n@interface BadgedLauncherViewController : NILauncherViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BadgedLauncherViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"BadgedLauncherViewController.h\"\n\n#import \"BadgedLauncherButtonView.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n//\n// What's going on in this file:\n//\n// This controller shows the use of two separate Nimbus features: [launcher] and [badge]. We've\n// created a subclass of NILauncherViewObject and NILauncherButtonView called\n// BadgedLauncherViewObject and BadgedLauncherButtonView, respectively. You can find these classes\n// in BadgedLauncherButtonView.h/m. These subclasses allow us to provide a badge number for the\n// launcher button and then display this badge in the launcher button's top right corner.\n//\n// A badged launcher button is not part of Nimbus itself because it depends on two independent\n// Nimbus features. This sort of composite functionality generally does not get added directly to\n// Nimbus.\n//\n// You will find the following Nimbus features used:\n//\n// [badge]\n// NIBadgeView\n//\n// [launcher]\n// NILauncherViewController\n// NILauncherViewModel\n// NILauncherViewModelDelegate\n// NILauncherDataSource\n// NILauncherDelegate\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// QuartzCore.framework\n//\n\n@interface BadgedLauncherViewController () <NILauncherViewModelDelegate>\n@property (nonatomic, retain) NILauncherViewModel* model;\n@end\n\n@implementation BadgedLauncherViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    self.title = @\"Badges\";\n\n    // Load the Nimbus app icon.\n    NSString* imagePath = NIPathForBundleResource(nil, @\"Icon.png\");\n    UIImage* image = [[Nimbus imageMemoryCache] objectWithName:imagePath];\n    if (nil == image) {\n      image = [UIImage imageWithContentsOfFile:imagePath];\n      [[Nimbus imageMemoryCache] storeObject:image withName:imagePath];\n    }\n\n    // We can provide different launcher objects in the model to show different types of launcher\n    // buttons. In this example we'll mix the default NILauncherViewObject with\n    // BadgedLauncherViewObject, which displays a launcher button with a badge number.\n    NSArray* contents =\n    [NSArray arrayWithObjects:\n     [NSArray arrayWithObjects:\n      // Shows a button with a badge showing the number 12.\n      [BadgedLauncherViewObject objectWithTitle:@\"Nimbus\" image:image badgeNumber:12],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 2\" image:image],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 3\" image:image],\n\n      // Will not display a badge because the number is 0.\n      [BadgedLauncherViewObject objectWithTitle:@\"Nimbus 4\" image:image badgeNumber:0],\n\n      // The badge number will become @\"99+\".\n      [BadgedLauncherViewObject objectWithTitle:@\"Nimbus 6\" image:image badgeNumber:103],\n      nil],\n     nil];\n\n    _model = [[NILauncherViewModel alloc] initWithArrayOfPages:contents delegate:self];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n\n  self.view.backgroundColor = [UIColor underPageBackgroundColor];\n\n  self.launcherView.dataSource = self.model;\n}\n\n#pragma mark - NILauncherViewModelDelegate\n\n- (void)launcherViewModel:(NILauncherViewModel *)launcherViewModel\n      configureButtonView:(UIView<NILauncherButtonView> *)buttonView\n          forLauncherView:(NILauncherView *)launcherView\n                pageIndex:(NSInteger)pageIndex\n              buttonIndex:(NSInteger)buttonIndex\n                   object:(id<NILauncherViewObject>)object {\n  // BadgedLauncherViewObject is a subclass of NILauncherButtonView so we can still safely cast\n  // without worrying about crashes.\n  NILauncherButtonView* launcherButtonView = (NILauncherButtonView *)buttonView;\n\n  launcherButtonView.label.layer.shadowColor = [UIColor blackColor].CGColor;\n  launcherButtonView.label.layer.shadowOffset = CGSizeMake(0, 1);\n  launcherButtonView.label.layer.shadowOpacity = 1;\n  launcherButtonView.label.layer.shadowRadius = 1;\n}\n\n#pragma mark - NILauncherDelegate\n\n- (void)launcherView:(NILauncherView *)launcher didSelectItemOnPage:(NSInteger)page atIndex:(NSInteger)index {\n  id<NILauncherViewObject> object = [self.model objectAtIndex:index pageIndex:page];\n\n  UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"Notice\"\n                                                  message:[@\"Did tap button with title: \" stringByAppendingString:object.title]\n                                                 delegate:nil\n                                        cancelButtonTitle:@\"OK\"\n                                        otherButtonTitles:nil];\n  [alert show];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationAttributedLabelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface BasicInstantiationAttributedLabelViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationAttributedLabelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"BasicInstantiationAttributedLabelViewController.h\"\n\n#import \"NimbusAttributedLabel.h\"\n\n//\n// What's going on in this file:\n//\n// This is a simple hello world example of the NIAttributedLabel object from the [attributedlabel]\n// feature of Nimbus. It is a simple view controller that instantiates and styles a single\n// NIAttributedLabel that says \"Hello World!\" with an orange stroke.\n//\n// You will find the following Nimbus features used:\n//\n// [core]\n// RGBCOLOR\n// RGBACOLOR\n//\n// [attributedlabel]\n// NIAttributedLabel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// CoreText.framework\n// QuartzCore.framework\n//\n\n@implementation BasicInstantiationAttributedLabelViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Basic Instantiation\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  // We create an NIAttributedLabel the same way we would a UILabel.\n  NIAttributedLabel* label = [[NIAttributedLabel alloc] initWithFrame:CGRectZero];\n\n  // In practice we set the text before applying any CoreText style. Modifying the text after\n  // setting the styles will clear any existing CoreText-specific styles.\n  //\n  // Peeking under the hood: NIAttributedLabel creates an NSMutableAttributedString object when we\n  // set this text. The NSMutableAttributedString object is initially styled with whatever values\n  // were set on the UILabel. For example, if we set the textColor to blue and then set the text to\n  // @\"Nimbus\", the label would correctly display the text as blue. This allows you to treat\n  // NIAttributedLabel as a UILabel but still easily be able to style its attributed string with\n  // additional CoreText properties.\n  label.text = @\"An explorer's tale\";\n\n  label.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n\n  // These are standard UILabel styles. We can set these whenever we like and the attributed label\n  // will apply them to entire string even if we change the text again.\n  label.font = [UIFont fontWithName:@\"Zapfino\" size:25];\n\n  // Set the text color to the bright Nimbus orange. This will be the \"fill\" color when we specify\n  // a negative stroke width below.\n  label.textColor = RGBCOLOR(0xFF, 0x9F, 0x00);\n\n  // Set a CoreText stroke color to a dark orange with 40% opacity.\n  label.strokeColor = RGBACOLOR(0x93, 0x36, 0x00, 0.4);\n\n  // A negative stroke width means that we also want to fill the stroke with the textColor.\n  // A postiive stroke would leave the fill as the background color.\n  label.strokeWidth = -3;\n\n  // Fill the view with the label, but give the label a 20 pixel margins on all sides.\n  label.frame = CGRectInset(self.view.bounds, 20, 20);\n\n  [self.view addSubview:label];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationBadgeViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface BasicInstantiationBadgeViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationBadgeViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"BasicInstantiationBadgeViewController.h\"\n#import \"NimbusBadge.h\"\n\n//\n// What's going on in this file:\n//\n// This controller shows how to instantiate a simple NIBadgeView and add it to a view hierarchy.\n// Within this example we also show that you should call sizeToFit to properly size the NIBadgeView\n// after it has been instantiated.\n//\n// You will find the following Nimbus features used:\n//\n// [badge]\n// NIBadgeView\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@implementation BasicInstantiationBadgeViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Basic Instantiation\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n\n  // The default view background color is transparent, so let's make sure the badge view has a\n  // non-transparent background color when we assign it further down.\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  // We don't know what the initial frame will be, so pass the empty rect.\n  NIBadgeView* badgeView = [[NIBadgeView alloc] initWithFrame:CGRectZero];\n\n  // Avoid using transparency whenever possible. The badgeView backgroundColor is black by default.\n  badgeView.backgroundColor = self.view.backgroundColor;\n\n  // We can set any arbitrary text to the badge view.\n  badgeView.text = @\"7\";\n\n  // Once we've set the text we allow the badge view to size itself to fit the contents of the\n  // text. If we wanted to we could explicitly set the frame of the badge view to something larger,\n  // but in nearly all cases the sizeToFit rect will be the one you want to use.\n  [badgeView sizeToFit];\n\n  [self.view addSubview:badgeView];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationCollectionModelViewController.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface BasicInstantiationCollectionModelViewController : UICollectionViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationCollectionModelViewController.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"BasicInstantiationCollectionModelViewController.h\"\n\n#import \"ColorCell.h\"\n\n#import \"NimbusCollections.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of creating a NICollectionViewModel and filling it with a list of objects that\n// will be displayed in a collection view.\n//\n// You will find the following Nimbus features used:\n//\n// [collections]\n// NICollectionViewModel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface BasicInstantiationCollectionModelViewController ()\n\n// A model exists through the lifetime of the controller.\n@property (nonatomic, strong) NICollectionViewModel* model;\n\n@end\n\n@implementation BasicInstantiationCollectionModelViewController\n\n- (id)initWithCollectionViewLayout:(UICollectionViewLayout *)layout {\n  if ((self = [super initWithCollectionViewLayout:layout])) {\n    self.title = @\"Basic Instantiation\";\n\n    // This controller uses the Nimbus collection view model. In loose terms, Nimbus models\n    // implement data source protocols. In this particular case we're using NICollectionViewModel\n    // with a list of objects.\n    //\n    // Each of these objects must implement the NICollectionViewCellObject protocol which requires\n    // the object to implement the method `-collectionViewCellClass`. This method can be called by\n    // the delegate provided to NICollectionViewModel to determine which cell implementation should\n    // be used to display this object.\n    //\n    // In this case we will use the NICollectionViewCellFactory helper class which provides a\n    // typical implementation of the NICollectionViewModelDelegate protocol.\n    NSArray* collectionContents =\n    @[\n      // You can find the implementation for the cells used in this catalog in the \"Collection\n      // Cells\" folder, or by command-clicking the cell object class name.\n      [Color colorWithColor:[UIColor redColor]],\n      [Color colorWithColor:[UIColor blueColor]],\n    ];\n\n    // NICollectionViewModel may be initialized with two types of arrays: list and sectioned.\n    // A list array is a list of objects, where each object in the array will map to a cell in\n    // the collection view.\n    // A sectioned array is a list of NSStrings and objects, where each NSString starts a new\n    // section and any other type of object is a cell.\n    //\n    // As discussed above, we provide the model with the NICollectionViewCellFactory class as its\n    // delegate.\n    //\n    // Further exploration:\n    // Check out the NICollectionViewCellFactory implementation and notice how the\n    // NICollectionViewModelDelegate methods are implemented twice. First as class methods (+ as a\n    // prefix), second as instance methods (- as a prefix). This allows you to use\n    // NICollectionViewCellFactory's class as the delegate or to instantiate the\n    // NICollectionViewCellFactory as an object and provide explicit mappings.\n    _model = [[NICollectionViewModel alloc] initWithListArray:collectionContents\n                                                     delegate:(id)[NICollectionViewCellFactory class]];\n  }\n  return self;\n}\n\n- (id)init {\n  // UICollectionViewController doesn't implement its initializer chain as would be expected, so we\n  // must forward init methods to -initWithCollectionViewLayout ourselves.\n  UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc] init];\n  return [self initWithCollectionViewLayout:flowLayout];\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // Only assign the collection view's data source after the view has loaded.\n  // You must be careful when you call self.collectionView in general because it will call loadView\n  // if the view has not been loaded yet.\n  self.collectionView.dataSource = _model;\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationLauncherViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusLauncher.h\"\n\n// All docs are in the .m.\n@interface BasicInstantiationLauncherViewController : NILauncherViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationLauncherViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"BasicInstantiationLauncherViewController.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n//\n// What's going on in this file:\n//\n// This controller shows a simple subclass implementation of NILauncherViewController and the\n// NILauncherDataSource and NILauncherDelegate protocol methods. This controller shows a single\n// page of four launcher icons and handles selection notifications by showing an alert view.\n//\n// You will find the following Nimbus features used:\n//\n// [launcher]\n// NILauncherViewController\n// NILauncherDataSource\n// NILauncherDelegate\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// QuartzCore.framework\n//\n\n// The reuse identifier for buttons in the launcher view.\nstatic NSString* const kButtonReuseIdentifier = @\"button\";\n\n@implementation BasicInstantiationLauncherViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    self.title = @\"Basic Instantiation\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n\n  self.view.backgroundColor = [UIColor underPageBackgroundColor];\n}\n\n// Similar to UITableViewController, NILauncherViewController automatically sets the dataSource and\n// delegate properties of self.launcherView to self. We simply have to implement the methods and\n// the launcher view will do the rest.\n#pragma mark - NILauncherDataSource\n\n- (NSInteger)launcherView:(NILauncherView *)launcherView numberOfButtonsInPage:(NSInteger)page {\n  // For the purposes of this simple example we are going to return a constant number of identical\n  // buttons.\n  return 4;\n}\n\n// This method works exactly like UITableViewDataSource's tableView:cellForRowAtIndexPath:. The\n// basic principal is to try to fetch a reusable view from the launcher view's recyclable view\n// queue. If no reusable view is available, we create one. We then configure the view for being\n// displayed and return the view object.\n- (UIView<NILauncherButtonView> *)launcherView:(NILauncherView *)launcherView buttonViewForPage:(NSInteger)page atIndex:(NSInteger)index {\n\n  // Start by attempting to dequeue a reusable view from the launcher view. Note that since we're\n  // only going to create and return NILauncherButtonView views, so we can safely cast to\n  // NILauncherButtonView without type checking first.\n  NILauncherButtonView* buttonView = (NILauncherButtonView *)[launcherView dequeueReusableViewWithIdentifier:kButtonReuseIdentifier];\n\n  // If the launcher view didn't have a reusable view then we will need to create one.\n  if (nil == buttonView) {\n    // We must create a UIView that conforms to the NILauncherButtonView protocol. Thankfully the\n    // launcher features comes with a stock launcher view that we can use!\n    buttonView = [[NILauncherButtonView alloc] initWithReuseIdentifier:kButtonReuseIdentifier];\n\n    // We're going to load the Nimbus application icon and store it in the Nimbus image cache.\n    NSString* imagePath = NIPathForBundleResource(nil, @\"Icon.png\");\n\n    // Try to load it from memory first.\n    UIImage* image = [[Nimbus imageMemoryCache] objectWithName:imagePath];\n\n    if (nil == image) {\n      // The image wasn't in memory, so let's load it from disk.\n      image = [UIImage imageWithContentsOfFile:imagePath];\n\n      // And then store it in memory.\n      [[Nimbus imageMemoryCache] storeObject:image withName:imagePath];\n\n      // The above logic of checking whether an image is in memory, loading it from disk when it's\n      // not in memory, and then storing the image in memory is a common pattern that you should\n      // consider using whenever loading static images throughout your application. Because the\n      // Nimbus image memory cache implements an efficient least-recently-used cache it can expire\n      // images that haven't been used recently when memory warnings are received.\n    }\n\n    // Add the image to the button view.\n    [buttonView.button setImage:image forState:UIControlStateNormal];\n\n    buttonView.label.text = @\"Nimbus\";\n\n    // Configure our label to show a nice blurred text shadow.\n    buttonView.label.layer.shadowColor = [UIColor blackColor].CGColor;\n    buttonView.label.layer.shadowOffset = CGSizeMake(0, 1);\n    buttonView.label.layer.shadowOpacity = 1;\n    buttonView.label.layer.shadowRadius = 1;\n  }\n\n  return buttonView;\n}\n\n#pragma mark - NILauncherDelegate\n\n- (void)launcherView:(NILauncherView *)launcher didSelectItemOnPage:(NSInteger)page atIndex:(NSInteger)index {\n  UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"Notice\"\n                                                  message:\n                        [NSString stringWithFormat:@\"Did tap button index %zd on page %zd\",\n                         index, page]\n                                          delegate:nil\n                                        cancelButtonTitle:@\"OK\"\n                                        otherButtonTitles:nil];\n  [alert show];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationNetworkImageViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface BasicInstantiationNetworkImageViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationNetworkImageViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"BasicInstantiationNetworkImageViewController.h\"\n#import \"NimbusNetworkImage.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n//\n// What's going on in this file:\n//\n// This is a simple example of instantiating a NINetworkImageView and loading an image from the\n// network. This controller shows how to modify the content mode and frame to adjust the way the\n// network image is displayed.\n//\n// You will find the following Nimbus features used:\n//\n// [networkimage]\n// NINetworkImageView\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// QuartzCore.framework\n// AFNetworking https://github.com/AFNetworking/AFNetworking\n//\n\n@implementation BasicInstantiationNetworkImageViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    self.title = @\"Basic Instantiation\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  // A NINetworkImageView is a subclass of UIImageView. We can provide an image to the initializer\n  // and it will be displayed until the network image is loaded. In this example we won't set an\n  // initial image.\n  NINetworkImageView* imageView = [[NINetworkImageView alloc] initWithFrame:CGRectZero];\n  imageView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;\n\n  // We don't set an initial image so let's create a nice-looking \"frame\" effect on the view.\n  // This will show a translucent background with a highlighted border.\n  imageView.backgroundColor = [UIColor colorWithWhite:1 alpha:0.2];\n  imageView.layer.borderColor = [UIColor colorWithWhite:1 alpha:0.1].CGColor;\n  imageView.layer.borderWidth = 1;\n\n  // The content mode of the image view is an important thing to consider. For normal UIImageViews\n  // the content mode is used to position the image in the bounds. This is how NINetworkImageView\n  // works as well, but with one additional feature: images downloaded from the network will be\n  // cropped and/or resized to fit the content mode. This ensures that the image being displayed\n  // in your NINetworkImageView is only taking up as much memory as is needed to display it.\n  // This also significantly improves performance because the image dimensions match your view\n  // dimensions, allowing a straight copy onto the screen.\n  //\n  // Experiment: Try changing the content mode to different values and seeing the effect it has on\n  // the downloaded image.\n  imageView.contentMode = UIViewContentModeScaleAspectFill;\n\n  // When we ask the network image view to download an image it will use the current image view's\n  // dimensions to create the final cropped and/or resized image. It's important, as a result, to\n  // set the frame before we load the image.\n  imageView.frame = CGRectMake(20, 20, 200, 200);\n\n  // We can set the path to this image view's image on the network now that the various presentation\n  // options have been set. As discussed above, the network image view will use the contentMode and\n  // bounds to crop and/or resize the downloaded image to fit the dimensions perfectly.\n  [imageView setPathToNetworkImage:@\"http://farm5.staticflickr.com/4016/4441744445_97cfbf4519_b_d.jpg\"];\n\n  [self.view addSubview:imageView];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationPagingScrollViewController.h",
    "content": "//\n// Copyright 2012 Manu Cornet\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface BasicInstantiationPagingScrollViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationPagingScrollViewController.m",
    "content": "//\n// Copyright 2012 Manu Cornet\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"BasicInstantiationPagingScrollViewController.h\"\n\n#import \"SamplePageView.h\"\n#import \"NimbusPagingScrollView.h\"\n\n//\n// What's going on in this file:\n//\n// This is a simple example of instantiating a NIPagingScrollView and implementing the\n// NIPagingScrollViewDataSource protocol. This controller implements the bare minimum of\n// functionality required to start using a paging scroll view in your own application. The data\n// source returns a fixed number of pages and each page is configured to display its page number.\n//\n// The key understanding you should gain of the paging scroll view is that it only ever has three\n// page views in memory. When the user moves from one page to another it adds the now invisible page\n// to a recyclable cell queue and then dequeues this view to be displayed at the new page index.\n// This is the same way UITableView works with its cell reuse.\n//\n// You will find the following Nimbus features used:\n//\n// [pagingscrollview]\n// NIPagingScrollView\n// NIPagingScrollViewDataSource\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n// The reuse identifier for a single page.\n// Having the const after NSString* means that we can't assign a new value to kPageReuseIdentifier.\nstatic NSString* const kPageReuseIdentifier = @\"SamplePageIdentifier\";\n\n@interface BasicInstantiationPagingScrollViewController() <NIPagingScrollViewDataSource>\n// We must retain the paging scroll view in order to autorotate it correctly.\n@property (nonatomic, retain) NIPagingScrollView* pagingScrollView;\n@end\n\n@implementation BasicInstantiationPagingScrollViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    self.title = @\"Basic Instantiation\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor blackColor];\n\n  // Create a paging scroll view the same way we would any other type of view.\n  self.pagingScrollView = [[NIPagingScrollView alloc] initWithFrame:self.view.bounds];\n  self.pagingScrollView.autoresizingMask =\n      (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n\n  // A paging scroll view has a data source much like a UITableView.\n  self.pagingScrollView.dataSource = self;\n\n  [self.view addSubview:self.pagingScrollView];\n\n  // Tells the paging scroll view to ask the dataSource for information about how to present itself.\n  [self.pagingScrollView reloadData];\n}\n\n- (void)didReceiveMemoryWarning {\n  self.pagingScrollView = nil;\n\n  [super didReceiveMemoryWarning];\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation\n                                duration:(NSTimeInterval)duration {\n  [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n\n  // The paging scroll view implements autorotation internally so that the current visible page\n  // index is maintained correctly. It also provides an opportunity for each visible page view to\n  // maintain zoom information correctly.\n  [self.pagingScrollView willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n}\n\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation\n                                         duration:(NSTimeInterval)duration {\n  [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n\n  // The second part of the paging scroll view's autorotation functionality. Both of these methods\n  // must be called in order for the paging scroll view to rotate itself correctly.\n  [self.pagingScrollView willAnimateRotationToInterfaceOrientation:toInterfaceOrientation\n                                                      duration:duration];\n}\n\n// The paging scroll view data source works similarly to UITableViewDataSource. We will return\n// the total number of pages in the scroll view as well as each page as it is about to be displayed.\n#pragma mark - NIPagingScrollViewDataSource\n\n- (NSInteger)numberOfPagesInPagingScrollView:(NIPagingScrollView *)pagingScrollView {\n  // For the sake of this example we'll show a fixed number of pages.\n  return 10;\n}\n\n// Similar to UITableViewDataSource, we create each page view on demand as the user is scrolling\n// through the page view.\n// Unlike UITableViewDataSource, this method requests a UIView that conforms to a protocol, rather\n// than requiring a specific subclass of a type of view. This allows you to use any UIView as long\n// as it conforms to NIPagingScrollView.\n- (UIView<NIPagingScrollViewPage> *)pagingScrollView:(NIPagingScrollView *)pagingScrollView\n                                    pageViewForIndex:(NSInteger)pageIndex {\n  // Check the reusable page queue.\n  SamplePageView *page = (SamplePageView *)[pagingScrollView dequeueReusablePageWithIdentifier:kPageReuseIdentifier];\n  // If no page was in the reusable queue, we need to create one.\n  if (nil == page) {\n    page = [[SamplePageView alloc] initWithReuseIdentifier:kPageReuseIdentifier];\n  }\n  return page;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationTableModelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface BasicInstantiationTableModelViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BasicInstantiationTableModelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"BasicInstantiationTableModelViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of creating a NITableViewModel and filling it with a list of objects that will\n// be displayed in a table view.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NITableViewModel\n// NICellFactory\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface BasicInstantiationTableModelViewController ()\n@property (nonatomic, retain) NITableViewModel* model;\n@end\n\n@implementation BasicInstantiationTableModelViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"Basic Instantiation\";\n    \n    // This controller uses the Nimbus table view model. In loose terms, Nimbus models implement\n    // data source protocols. They encapsulate standard delegate functionality and will make your\n    // life a lot easier. In this particular case we're using NITableViewModel with a list of\n    // objects.\n    //\n    // Each of these objects implements the NICellObject protocol which requires the object to\n    // implement the method \"cellClass\". This method is called by the NICellFactory to determine\n    // which UITableViewCell implementation should be used to display this object.\n    //\n    // When a cell is about to be created, the model asks its delegate to create a cell with the\n    // given object. In most cases the delegate is [NICellFactory class]. NICellFactory implements\n    // the NITableViewModelDelegate protocol as static methods, allowing us to use it as a delegate\n    // without instantiating it.\n    //\n    // Once the cell is created, shouldUpdateCellWithObject: is called on the cell, giving it the\n    // opportunity to update itself accordingly.\n    NSArray* tableContents =\n    [NSArray arrayWithObjects:\n\n     // Shows a cell with a title.\n     [NITitleCellObject objectWithTitle:@\"Row 1\"],\n     [NITitleCellObject objectWithTitle:@\"Row 2\"],\n\n     // Shows a cell with a title and subtitle.\n     [NISubtitleCellObject objectWithTitle:@\"Row 3\" subtitle:@\"Subtitle\"],\n     nil];\n    \n    // NITableViewModel may be initialized with two types of arrays: list and sectioned.\n    // A list array is a list of objects, where each object in the array will map to a cell in\n    // the table view.\n    // A sectioned array is a list of NSStrings and objects, where each NSString starts a new\n    // section and any other type of object is a cell.\n    //\n    // As discussed above, we provide the model with the NICellFactory class as its delegate.\n    // In a future example we will show how you can create a NICellFactory object to override the\n    // default mappings that the cell objects return from their cellClass implementation.\n    //\n    // Further exploration:\n    // Check out the NICellFactory implementation and notice how the NITableViewModelDelegate\n    // methods are implemented twice. First as class methods (+ as a prefix), second as\n    // instance methods (- as a prefix). This allows you to use NICellFactory's class object as\n    // the delegate or to instantiate the NICellFactory as an object and provide explicit mappings.\n    _model = [[NITableViewModel alloc] initWithListArray:tableContents\n                                                delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n  \n  // Only assign the table view's data source after the view has loaded.\n  // You must be careful when you call self.tableView in general because it will call loadView\n  // if the view has not been loaded yet. You do not need to clear the data source when the\n  // view is unloaded (more importantly: you shouldn't, due to the reason just outlined\n  // regarding loadView).\n  self.tableView.dataSource = _model;\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BlockCellsViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface BlockCellsViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/BlockCellsViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"BlockCellsViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of rendering table view cells with blocks.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NITableViewModel\n// NIDrawRectBlockCellObject\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface BlockCellsViewController ()\n@property (nonatomic, retain) NITableViewModel* model;\n@end\n\n@implementation BlockCellsViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStylePlain])) {\n    self.title = @\"Block Cells\";\n\n    // We load the image outside of the block so that we spend as little time in the block as\n    // possible.\n    UIImage* image = [UIImage imageNamed:@\"Icon\"];\n\n    // We create a single block that can render a table view cell given an object.\n    NICellDrawRectBlock drawTextBlock = ^CGFloat(CGRect rect, id object, UITableViewCell *cell) {\n      // If the cell is tapped or selected we want to draw the text on top of the selection\n      // background. This requires that the content's background be clear.\n      if (cell.isHighlighted || cell.isSelected) {\n        [[UIColor clearColor] set];\n      } else {\n        [[UIColor whiteColor] set];\n      }\n\n      // Fill in the content rect.\n      UIRectFill(rect);\n\n      // Draw the object that was given to this block. In this case it will always be an NSString.\n      NSString* text = object;\n      [[UIColor blackColor] set];\n      UIFont* titleFont = [UIFont boldSystemFontOfSize:16];\n      [text drawAtPoint:CGPointMake(10, 5) withAttributes:@{NSFontAttributeName: titleFont}];\n\n      // Draw a static subtitle below the title.\n      [[UIColor grayColor] set];\n      [@\"Subtitle\" drawAtPoint:CGPointMake(10, 5 + titleFont.lineHeight)\n                withAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:12]}];\n\n      // Draw the Nimbus application icon on the right edge of the cell.\n      [image drawAtPoint:CGPointMake(CGRectGetMaxX(rect) - image.size.width - 10, 5)];\n\n      // We can optionally return the height of the cell if we want to support variable-height\n      // custom-drawn cells.\n      return 0;\n    };\n\n    // Create 1000 cells that are individually named so that we can show how quickly we can scroll\n    // through the cells.\n    NSMutableArray* tableContents = [NSMutableArray array];\n    for (NSInteger ix = 0; ix < 1000; ++ix) {\n      [tableContents addObject:\n       [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:\n        [NSString stringWithFormat:@\"This is cell #%zd\", ix]]];\n    }\n\n    _model = [[NITableViewModel alloc] initWithListArray:tableContents\n                                                delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // Experiment:\n  // Try playing around with the row height.\n  self.tableView.rowHeight = 70;\n\n  self.tableView.dataSource = _model;\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CatalogViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface CatalogViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CatalogViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"CatalogViewController.h\"\n\n// Attributed Label\n#import \"BasicInstantiationAttributedLabelViewController.h\"\n#import \"CustomTextAttributedLabelViewController.h\"\n#import \"LinksAttributedLabelViewController.h\"\n#import \"DataTypesAttributedLabelViewController.h\"\n#import \"ImagesAttributedLabelViewController.h\"\n#import \"PerformanceAttributedLabelViewController.h\"\n#import \"LongTapAttributedLabelViewController.h\"\n#import \"InterfaceBuilderAttributedLabelViewController.h\"\n#import \"AlignmentAttributedLabelViewController.h\"\n\n// Badge\n#import \"BasicInstantiationBadgeViewController.h\"\n#import \"CustomizingBadgesViewController.h\"\n#import \"InterfaceBuilderBadgeViewController.h\"\n\n// Collections\n#import \"BasicInstantiationCollectionModelViewController.h\"\n#import \"NibCollectionModelViewController.h\"\n#import \"CustomNibCollectionModelViewController.h\"\n\n// Interapp\n#import \"InterappViewController.h\"\n\n// Launcher\n#import \"BasicInstantiationLauncherViewController.h\"\n#import \"ModelLauncherViewController.h\"\n#import \"ModifyingLauncherViewController.h\"\n#import \"RestoringLauncherViewController.h\"\n#import \"BadgedLauncherViewController.h\"\n\n// Network Image\n#import \"BasicInstantiationNetworkImageViewController.h\"\n#import \"ContentModesNetworkImageViewController.h\"\n\n// Paging Scroll View\n#import \"BasicInstantiationPagingScrollViewController.h\"\n#import \"VerticalPagingScrollViewController.h\"\n\n// Tables\n#import \"BasicInstantiationTableModelViewController.h\"\n#import \"SectionedTableModelViewController.h\"\n#import \"IndexedTableModelViewController.h\"\n#import \"ActionsTableModelViewController.h\"\n#import \"RadioGroupTableModelViewController.h\"\n#import \"NestedRadioGroupTableModelViewController.h\"\n#import \"ModalRadioGroupTableModelViewController.h\"\n#import \"FormCellCatalogViewController.h\"\n#import \"NetworkBlockCellsViewController.h\"\n#import \"BlockCellsViewController.h\"\n#import \"SnapshotRotationTableViewController.h\"\n#import \"MutableTableModelViewController.h\"\n\n// Web Controller\n#import \"ExtraActionsWebViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NimbusWebController.h\"\n\n//\n// What's going on in this file:\n//\n// This is the root view controller of the Nimbus iPhone Catalog application. It is a table view\n// controller that uses Nimbus' table view models features to populate the data source and handle\n// user actions. From this controller the user can navigate to any of the Nimbus samples.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NITableViewModel\n// NITableViewActions\n// NISubtitleCellObject\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@implementation CatalogViewController {\n  // The UITableView refers to the model and actions objects throughout its lifetime but does not\n  // retain them. We must store the instances in this class.\n  NITableViewModel* _model;\n  NITableViewActions* _actions;\n}\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  // We explicitly set the table view style in this controller's implementation because we want this\n  // controller to control how the table view is displayed.\n  self = [super initWithStyle:UITableViewStyleGrouped];\n\n  if (self) {\n    // We set the title in the init method because it will never change.\n    self.title = @\"Nimbus Catalog\";\n\n    // When we instantiate the actions object we must provide it with a reference to the target to\n    // whom actions will be sent.\n    //\n    // For block actions:\n    // This value is passed to the block as an argument so that we can navigate to new\n    // controllers without introducing retain cycles by otherwise having to access\n    // self.navigationController in the block.\n    //\n    // For selector actions:\n    // The selector will be executed on the target. For a demo of selector actions, see\n    // ActionsTableModelViewController.m.\n    _actions = [[NITableViewActions alloc] initWithTarget:self];\n\n    // This controller uses the Nimbus table view model. In loose terms, Nimbus models implement\n    // data source protocols. They avoid code duplication and abstract the storage of the backing\n    // data for views. There is a model for UITableView, NITableViewModel, and a model for\n    // UICollectionView, NICollectionViewModel.\n    //\n    // We're going to use NITableViewModel with a sectioned array of objects. A sectioned array of\n    // objects is an NSArray where any instance of an NSString delimits the beginning of a new\n    // section.\n    NSArray* sectionedObjects =\n    @[\n     // An NSString in a sectioned array denotes the start of a new section. It's also the label of\n     // the section header.\n     @\"Attributed Label\",\n\n     // Any objects following an NSString will be part of the same group until another NSString\n     // is encountered.\n\n     // We attach actions to objects using the chaining pattern. The \"attach\" methods of\n     // NITableViewActions will return the object we pass to them, allowing us to create an object,\n     // attach an action to it, and then add the object to the sectioned array in one statement.\n     [_actions attachToObject:\n\n      // A subtitle cell object will eventually display a NITextCell in the table view. A NITextCell\n      // is a simple UITableViewCell built to work with Nimbus' cell architecture.\n      [NISubtitleCellObject objectWithTitle:@\"Basic Instantiation\"\n                                   subtitle:@\"How to create a simple NIAttributedLabel\"]\n\n      // NIPushControllerAction is a helper method that instantiates the controller class and then\n      // pushes it onto the current view controller's navigation stack. It initializes the\n      // controller via the init method, so if you need custom initialization then you'll need to\n      // implement the block yourself.\n              navigationBlock:NIPushControllerAction([BasicInstantiationAttributedLabelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Customizing Text\"\n                                   subtitle:@\"How to use NSAttributedString\"]\n              navigationBlock:NIPushControllerAction([CustomTextAttributedLabelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Links\"\n                                   subtitle:@\"Automatic and explicit links\"]\n              navigationBlock:NIPushControllerAction([LinksAttributedLabelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Data Types\"\n                                   subtitle:@\"Detecting different data types\"]\n              navigationBlock:NIPushControllerAction([DataTypesAttributedLabelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Images\"\n                                   subtitle:@\"Adding inline images\"]\n              navigationBlock:NIPushControllerAction([ImagesAttributedLabelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Performance\"\n                                   subtitle:@\"Speeding up attributed labels\"]\n              navigationBlock:NIPushControllerAction([PerformanceAttributedLabelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Long Taps\"\n                                   subtitle:@\"Configuring long tap action sheets\"]\n              navigationBlock:NIPushControllerAction([LongTapAttributedLabelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Interface Builder\"\n                                   subtitle:@\"Using attributed labels in IB\"]\n              navigationBlock:NIPushControllerAction([InterfaceBuilderAttributedLabelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Alignment\"\n                                   subtitle:@\"Verical alignment in attributed labels\"]\n              navigationBlock:NIPushControllerAction([AlignmentAttributedLabelViewController class])],\n\n     @\"Badge\",\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Basic Instantiation\"\n                                   subtitle:@\"How to create a simple NIBadgeView\"]\n              navigationBlock:NIPushControllerAction([BasicInstantiationBadgeViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Customizing Badges\"\n                                   subtitle:@\"How to customize badges\"]\n              navigationBlock:NIPushControllerAction([CustomizingBadgesViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Interface Builder\"\n                                   subtitle:@\"Using badges in IB\"]\n              navigationBlock:NIPushControllerAction([InterfaceBuilderBadgeViewController class])],\n\n     @\"Collections\",\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Basic Instantiation\"\n                                   subtitle:@\"How to create a collection view model\"]\n              navigationBlock:NIPushControllerAction([BasicInstantiationCollectionModelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Nibs\"\n                                   subtitle:@\"How to use nibs with collection view models\"]\n              navigationBlock:NIPushControllerAction([NibCollectionModelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Custom Nibs\"\n                                   subtitle:@\"How to customize nibs\"]\n              navigationBlock:NIPushControllerAction([CustomNibCollectionModelViewController class])],\n\n     @\"Interapp\",\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"All Actions\"\n                                   subtitle:@\"A list of all available actions\"]\n              navigationBlock:NIPushControllerAction([InterappViewController class])],\n\n     @\"Launcher\",\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Basic Instantiation\"\n                                   subtitle:@\"How to subclass a launcher controller\"]\n              navigationBlock:NIPushControllerAction([BasicInstantiationLauncherViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Model\"\n                                   subtitle:@\"Using a model to manage data\"]\n              navigationBlock:NIPushControllerAction([ModelLauncherViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Modifying\"\n                                   subtitle:@\"How to add new launcher buttons\"]\n              navigationBlock:NIPushControllerAction([ModifyingLauncherViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Restoring\"\n                                   subtitle:@\"Saving and loading launcher data\"]\n              navigationBlock:NIPushControllerAction([RestoringLauncherViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Badges\"\n                                   subtitle:@\"Adding badges to launcher items\"]\n              navigationBlock:NIPushControllerAction([BadgedLauncherViewController class])],\n\n     @\"Network Image\",\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Basic Instantiation\"\n                                   subtitle:@\"How to create a NINetworkImageView\"]\n              navigationBlock:NIPushControllerAction([BasicInstantiationNetworkImageViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Content Modes\"\n                                   subtitle:@\"Effects of each content mode\"]\n              navigationBlock:NIPushControllerAction([ContentModesNetworkImageViewController class])],\n\n     @\"Paging Scroll Views\",\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Basic Instantiation\"\n                                   subtitle:@\"How to create a paging scroll view\"]\n              navigationBlock:NIPushControllerAction([BasicInstantiationPagingScrollViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Vertical Paging\"\n                                   subtitle:@\"Using a vertical layout\"]\n              navigationBlock:NIPushControllerAction([VerticalPagingScrollViewController class])],\n\n     @\"Table Models\",\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Basic Instantiation\"\n                                   subtitle:@\"How to create a table view model\"]\n              navigationBlock:NIPushControllerAction([BasicInstantiationTableModelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Sectioned Model\"\n                                   subtitle:@\"Sectioned table view models\"]\n              navigationBlock:NIPushControllerAction([SectionedTableModelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Indexed Model\"\n                                   subtitle:@\"Indexed table view models\"]\n              navigationBlock:NIPushControllerAction([IndexedTableModelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Actions\"\n                                   subtitle:@\"Handling actions in table views\"]\n              navigationBlock:NIPushControllerAction([ActionsTableModelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Radio Group\"\n                                   subtitle:@\"How to use radio groups\"]\n              navigationBlock:NIPushControllerAction([RadioGroupTableModelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Nested Radio Group\"\n                                   subtitle:@\"How to nest radio groups\"]\n              navigationBlock:NIPushControllerAction([NestedRadioGroupTableModelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Modal Radio Group\"\n                                   subtitle:@\"Customizing presentation\"]\n              navigationBlock:NIPushControllerAction([ModalRadioGroupTableModelViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Form Cell Catalog\"\n                                   subtitle:@\"Table view cells for forms\"]\n              navigationBlock:NIPushControllerAction([FormCellCatalogViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Block Cells\"\n                                   subtitle:@\"Rendering cells with blocks\"]\n              navigationBlock:NIPushControllerAction([BlockCellsViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Network Block Cells\"\n                                   subtitle:@\"Rendering network images with blocks\"]\n              navigationBlock:NIPushControllerAction([NetworkBlockCellsViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Snapshot Rotation\"\n                                   subtitle:@\"Rotating table views with snapshots\"]\n              navigationBlock:NIPushControllerAction([SnapshotRotationTableViewController class])],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Mutable Models\"\n                                   subtitle:@\"Mutating table view models\"]\n              navigationBlock:NIPushControllerAction([MutableTableModelViewController class])],\n\n     @\"Web Controller\",\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Basic Instantiation\"\n                                   subtitle:@\"How to create a simple NIWebController\"]\n              navigationBlock:\n      ^(id object, UIViewController* controller, NSIndexPath* indexPath) {\n        NIWebController* webController = [[NIWebController alloc] initWithURL:[NSURL URLWithString:@\"http://nimbuskit.info\"]];\n        [controller.navigationController pushViewController:webController\n                                                   animated:YES];\n\n        // NimbusKit uses the return value from this block to determine whether to deselect the cell\n        // after it has been selected. This, however, only applies to tap actions. For navigation\n        // actions we never want to deselect the cell immediately after tapping it because we're\n        // supposed to keep it selected until the controller we pushed gets popped, at which point\n        // the selected cell will be deselected during the pop animation.\n        return NO;\n      }],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Hiding the Toolbar\"\n                                   subtitle:@\"Showing a web controller without actions\"]\n              navigationBlock:\n      ^(id object, UIViewController* controller, NSIndexPath* indexPath) {\n        NIWebController* webController = [[NIWebController alloc] initWithURL:[NSURL URLWithString:@\"http://nimbuskit.info\"]];\n        webController.toolbarHidden = YES;\n        [controller.navigationController pushViewController:webController\n                                                   animated:YES];\n\n        return NO;\n      }],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Tinting the Toolbar\"\n                                   subtitle:@\"Tinting a web controller's toolbar\"]\n              navigationBlock:\n      ^(id object, UIViewController* controller, NSIndexPath* indexPath) {\n        NIWebController* webController = [[NIWebController alloc] initWithURL:[NSURL URLWithString:@\"http://nimbuskit.info\"]];\n        webController.toolbarTintColor = [UIColor orangeColor];\n        [controller.navigationController pushViewController:webController\n                                                   animated:YES];\n\n        return NO;\n      }],\n\n     [_actions attachToObject:\n      [NISubtitleCellObject objectWithTitle:@\"Extra Actions\"\n                                   subtitle:@\"Subclassing for more actions\"]\n              navigationBlock:\n      ^(id object, UIViewController* controller, NSIndexPath* indexPath) {\n        NIWebController* webController = [[ExtraActionsWebViewController alloc] initWithURL:[NSURL URLWithString:@\"http://nimbuskit.info\"]];\n        [controller.navigationController pushViewController:webController\n                                                   animated:YES];\n\n        return NO;\n      }]\n     ];\n\n    // When we create the model we must provide it with a delegate that implements the\n    // NITableViewModelDelegate protocol. This protocol has a single method that is used to create\n    // cells given an object from the model. If we don't require any custom cell bindings then it's\n    // often easiest to use the NICellFactory as the delegate. The NICellFactory class provides a\n    // barebones implementation that is sufficient for nearly all applications.\n    _model = [[NITableViewModel alloc] initWithSectionedArray:sectionedObjects\n                                                     delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // Once the tableView has loaded we attach the model to the data source. As mentioned above,\n  // NITableViewModel implements UITableViewDataSource so that you don't have to implement any\n  // of the data source methods directly in your controller.\n  self.tableView.dataSource = _model;\n\n  // What we're doing here is known as \"delegate chaining\". It uses the message forwarding\n  // functionality of Objective-C to insert the actions object between the table view\n  // and this controller. The actions object forwards UITableViewDelegate methods along and\n  // selectively intercepts methods required to make user interactions work.\n  //\n  // Experiment: try commenting out this line. You'll notice that you can no longer tap any of\n  // the cells in the table view and that they no longer show the disclosure accessory types.\n  // Cool, eh? That this functionality is all provided to you in one line should make you\n  // heel-click.\n  self.tableView.delegate = [_actions forwardingTo:self];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ColorCell.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusCollections.h\"\n\n@interface Color : NSObject <NICollectionViewCellObject>\n+ (instancetype)colorWithColor:(UIColor *)color;\n@property (nonatomic, strong) UIColor* color;\n@end\n\n@interface ColorCell : UICollectionViewCell <NICollectionViewCell>\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ColorCell.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"ColorCell.h\"\n\n@implementation Color\n\n+ (instancetype)colorWithColor:(UIColor *)color {\n  Color* instance = [[Color alloc] init];\n  instance.color = color;\n  return instance;\n}\n\n#pragma mark - NICollectionViewCellObject\n\n- (Class)collectionViewCellClass {\n  return [ColorCell class];\n}\n\n@end\n\n@implementation ColorCell\n\n#pragma mark - NICollectionViewCell\n\n- (BOOL)shouldUpdateCellWithObject:(Color *)object {\n  self.contentView.backgroundColor = object.color;\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ContentModesNetworkImageViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface ContentModesNetworkImageViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ContentModesNetworkImageViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"ContentModesNetworkImageViewController.h\"\n#import \"NimbusNetworkImage.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n//\n// What's going on in this file:\n//\n// This controller demos the various UIViewContentMode types supported by the network image view.\n// It shows a grid of images, each with a different content mode for the same image.\n//\n// You will find the following Nimbus features used:\n//\n// [networkimage]\n// NINetworkImageView\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// QuartzCore.framework\n// AFNetworking https://github.com/AFNetworking/AFNetworking\n//\n\n// Various display metrics used through the view. We define them at the top of the file so that\n// they're easy to access and modify.\nstatic const CGFloat kImageDimensions = 78;\nstatic const CGFloat kFramePadding = 10;\nstatic const CGFloat kImageSpacing = 5;\n\n@interface ContentModesNetworkImageViewController()\n@property (nonatomic, copy) NSArray* networkImageViews;\n@end\n\n@implementation ContentModesNetworkImageViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    self.title = @\"Content Modes\";\n  }\n  return self;\n}\n\n// Lays out all of our network image views within the controller view.\n- (void)layoutImageViews {\n  CGRect frame = self.view.bounds;\n  \n  CGFloat maxRightEdge = 0;\n  \n  CGFloat currentX = kFramePadding;\n  CGFloat currentY = kFramePadding;\n\n  // Iterate through the image views and wrap them in rows/columns.\n  for (NINetworkImageView* imageView in self.networkImageViews) {\n    imageView.frame = CGRectMake(currentX, currentY, kImageDimensions, kImageDimensions);\n    \n    maxRightEdge = MAX(maxRightEdge, currentX + kImageDimensions);\n    \n    currentX += kImageDimensions + kImageSpacing;\n    \n    if (currentX + kImageDimensions >= frame.size.width - kFramePadding) {\n      // Wrap to the next row.\n      currentX = kFramePadding;\n      currentY += kImageDimensions + kImageSpacing;\n    }\n  }\n  \n  // Center the columns.\n  CGFloat contentWidth = (maxRightEdge + kFramePadding);\n  CGFloat contentPadding = floorf((frame.size.width - contentWidth) / 2);\n\n  // Offset all of the images as a unit so that they're all centered.\n  // If we wanted to simplify this we could add all of the image views to a container view\n  // that would then be offset to center everything.\n  for (NINetworkImageView* imageView in self.networkImageViews) {\n    CGRect imageFrame = imageView.frame;\n    imageFrame.origin.x += contentPadding;\n    imageView.frame = imageFrame;\n  }\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor underPageBackgroundColor];\n\n  // We only want one network request to be able to fire off at a time because we know all of the\n  // requests are going to be for the same image. This way each subsequent request will load the\n  // already downloaded image from the cache.\n  [[Nimbus networkOperationQueue] setMaxConcurrentOperationCount:1];\n\n  // We're going to create a network image view for each UIViewContentMode that the network image\n  // view supports.\n  NSMutableArray* networkImageViews = [NSMutableArray array];\n  for (NSInteger ix = UIViewContentModeScaleToFill; ix <= UIViewContentModeBottomRight; ++ix) {\n    if (UIViewContentModeRedraw == ix) {\n      // Unsupported mode.\n      continue;\n    }\n    NINetworkImageView* imageView = [[NINetworkImageView alloc] initWithFrame:CGRectZero];\n    imageView.backgroundColor = [UIColor colorWithWhite:1 alpha:0.2];\n    imageView.layer.borderColor = [UIColor colorWithWhite:1 alpha:0.1].CGColor;\n    imageView.layer.borderWidth = 1;\n    \n    // From: http://www.flickr.com/photos/htakashi/5653586269/\n    // We fetch the network image by explicitly setting the display size and content mode.\n    // This overrides the use of the frame to determine the display size. This allows you to fetch\n    // the image without laying out your views first, which can be useful if you know the dimensions\n    // of the images you'll be fetching.\n    //\n    // The network image view is smart enough to know that the display size you pass should be\n    // doubled when creating the image on retina displays.\n    //\n    // Note that setting the content mode this way is also a useful way of having a different\n    // content mode for the network image compared to the initial image.\n    [imageView setPathToNetworkImage:\n     @\"http://farm6.staticflickr.com/5030/5653586269_0737781c55_b.jpg\"\n                      forDisplaySize:CGSizeMake(kImageDimensions, kImageDimensions)\n                         contentMode:ix];\n\n    [self.view addSubview:imageView];\n    [networkImageViews addObject:imageView];\n  }\n  self.networkImageViews = networkImageViews;\n\n  [self layoutImageViews];\n}\n\n- (void)viewDidUnload {\n  [super viewDidUnload];\n\n  // The views are no longer needed.\n  self.networkImageViews = nil;\n\n  // Reset the maximum number of concurrent operations.\n  [[Nimbus networkOperationQueue] setMaxConcurrentOperationCount:NSOperationQueueDefaultMaxConcurrentOperationCount];\n}\n\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n\n  // When we rotate we will need to update the layout of all of the image views so that they fit.\n  [self layoutImageViews];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CustomNibCollectionModelViewController.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface CustomNibCollectionModelViewController : UICollectionViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CustomNibCollectionModelViewController.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"CustomNibCollectionModelViewController.h\"\n\n#import \"CustomTextCell.h\"\n#import \"NibCellObject.h\"\n\n#import \"NimbusCollections.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of creating a NICollectionViewModel and filling it with a list of objects that\n// will be displayed in a collection view.\n//\n// You will find the following Nimbus features used:\n//\n// [collections]\n// NICollectionViewModel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface CustomNibCollectionModelViewController ()\n@property (nonatomic, strong) NICollectionViewModel* model;\n@end\n\n@implementation CustomNibCollectionModelViewController\n\n- (id)initWithCollectionViewLayout:(UICollectionViewLayout *)layout {\n  if ((self = [super initWithCollectionViewLayout:layout])) {\n    self.title = @\"Nibs\";\n\n    NSArray* collectionContents =\n    @[\n      [CustomTextCellObject objectWithTitle:@\"Title 1\"],\n      [CustomTextCellObject objectWithTitle:@\"Title 2\"],\n      [[NibCellObject alloc] init],\n    ];\n\n    _model = [[NICollectionViewModel alloc] initWithListArray:collectionContents\n                                                     delegate:(id)[NICollectionViewCellFactory class]];\n  }\n  return self;\n}\n\n- (id)init {\n  UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc] init];\n  flowLayout.itemSize = CGSizeMake(200, 200);\n  return [self initWithCollectionViewLayout:flowLayout];\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.collectionView.dataSource = _model;\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CustomTextAttributedLabelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface CustomTextAttributedLabelViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CustomTextAttributedLabelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"CustomTextAttributedLabelViewController.h\"\n\n#import \"NimbusAttributedLabel.h\"\n\n// This import is not included by NimbusAttributedLabel.h because it is a category and we want to\n// make it explicit that you are augmenting a class.\n#import \"NSMutableAttributedString+NimbusAttributedLabel.h\"\n\n//\n// What's going on in this file:\n//\n// This controller shows how to create an NSAttributedString object, modify its style, and assign\n// it to an NIAttributedLabel for display.\n//\n// You will find the following Nimbus features used:\n//\n// [attributedlabel]\n// NIAttributedLabel\n// NSMutableAttributedString additions (via NSMutableAttributedString+NimbusAttributedLabel.h).\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// CoreText.framework\n// QuartzCore.framework\n//\n\n@implementation CustomTextAttributedLabelViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Customizing Text\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  NSString* string =\n  @\"For 20 years she has ventured into the dark horizon. \"\n  @\"At long last, a planet grows in the distance. \"\n  @\"\\\"Hello world!\\\" she exclaims.\";\n\n  // We're going to customize the words \"hello\" and \"world\" in the string above to make them stand\n  // out in our text.\n  NSRange rangeOfHello = [string rangeOfString:@\"Hello\"];\n  NSRange rangeOfWorld = [string rangeOfString:@\"world!\"];\n\n  // We must create a mutable attributed string in order to set the CoreText properties.\n  NSMutableAttributedString* text = [[NSMutableAttributedString alloc] initWithString:string];\n\n  // See http://iosfonts.com/ for a list of all fonts supported out of the box on iOS.\n  UIFont* font = [UIFont fontWithName:@\"Futura-MediumItalic\" size:30];\n\n  // The following set of methods are all category methods added by the [attributedlabel] feature.\n  // Each method has a final argument for specifying a range. If you don't specify a range then the\n  // modification will be applied to the entire string.\n  [text setFont:font range:rangeOfHello];\n  [text setFont:font range:rangeOfWorld];\n  [text setUnderlineStyle:kCTUnderlineStyleSingle\n                 modifier:kCTUnderlinePatternSolid\n                    range:rangeOfHello];\n  [text setTextColor:[UIColor redColor] range:rangeOfHello];\n\n  NIAttributedLabel* label = [[NIAttributedLabel alloc] initWithFrame:CGRectZero];\n\n  // We want this label to wrap over multiple lines. With CoreText we have to use either word or\n  // character wrapping in order to have a paragraph wrap over multiple lines. Truncation modes\n  // will only work for single lines of text and would require us to explicitly break the lines up\n  // with newline (\\n) characters.\n  label.numberOfLines = 0;\n  label.lineBreakMode = NSLineBreakByWordWrapping;\n\n  label.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  label.frame = CGRectInset(self.view.bounds, 20, 20);\n\n  // When we assign the attributed text to the label it copies the attributed text object into the\n  // label. If we want to make any further stylistic changes then we must either use the label's\n  // methods or assign a modified attributed string object again.\n  label.attributedText = text;\n\n  [self.view addSubview:label];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CustomTextCell.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusCollections.h\"\n\n@interface CustomTextCellObject : NSObject <NICollectionViewNibCellObject>\n\n+ (instancetype)objectWithTitle:(NSString *)title;\n\n@property (nonatomic, copy) NSString* title;\n\n@end\n\n@interface CustomTextCell : UICollectionViewCell <NICollectionViewCell>\n\n@property (nonatomic, strong) IBOutlet UILabel* label;\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CustomTextCell.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"CustomTextCell.h\"\n\n@implementation CustomTextCellObject\n\n+ (instancetype)objectWithTitle:(NSString *)title {\n  CustomTextCellObject* object = [[[self class] alloc] init];\n  object.title = title;\n  return object;\n}\n\n#pragma mark - NICollectionViewNibCellObject\n\n- (UINib *)collectionViewCellNib {\n  return [UINib nibWithNibName:NSStringFromClass([CustomTextCell class]) bundle:nil];\n}\n\n@end\n\n@implementation CustomTextCell\n\n#pragma mark - NICollectionViewCell\n\n- (BOOL)shouldUpdateCellWithObject:(CustomTextCellObject *)object {\n  self.label.text = object.title;\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CustomTextCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" colorMatched=\"YES\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <deployment version=\"1792\" identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14460.20\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"CustomTextCell\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <collectionViewCell opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" id=\"eig-34-YUy\" customClass=\"CustomTextCell\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"100\" height=\"100\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <view key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"100\" height=\"100\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"top\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" lineBreakMode=\"wordWrap\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" preferredMaxLayoutWidth=\"60\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Pnw-LM-Lnv\">\n                        <rect key=\"frame\" x=\"20\" y=\"20\" width=\"60\" height=\"60\"/>\n                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                        <nil key=\"highlightedColor\"/>\n                    </label>\n                </subviews>\n            </view>\n            <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n            <constraints>\n                <constraint firstAttribute=\"bottom\" secondItem=\"Pnw-LM-Lnv\" secondAttribute=\"bottom\" constant=\"20\" id=\"Cmt-4X-bpg\"/>\n                <constraint firstItem=\"Pnw-LM-Lnv\" firstAttribute=\"top\" secondItem=\"eig-34-YUy\" secondAttribute=\"top\" constant=\"20\" id=\"HW2-kf-H2M\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"Pnw-LM-Lnv\" secondAttribute=\"trailing\" constant=\"20\" id=\"f88-eS-cO8\"/>\n                <constraint firstItem=\"Pnw-LM-Lnv\" firstAttribute=\"leading\" secondItem=\"eig-34-YUy\" secondAttribute=\"leading\" constant=\"20\" id=\"kYH-lV-dqm\"/>\n            </constraints>\n            <size key=\"customSize\" width=\"138\" height=\"95\"/>\n            <connections>\n                <outlet property=\"label\" destination=\"Pnw-LM-Lnv\" id=\"YxA-qe-3Wr\"/>\n            </connections>\n        </collectionViewCell>\n    </objects>\n</document>\n"
  },
  {
    "path": "examples/catalog/Catalog/CustomizingBadgesViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface CustomizingBadgesViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/CustomizingBadgesViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"CustomizingBadgesViewController.h\"\n#import \"NimbusBadge.h\"\n\n//\n// What's going on in this file:\n//\n// This controller shows how to customize the various NIBadgeView attributes.\n//\n// You will find the following Nimbus features used:\n//\n// [badge]\n// NIBadgeView\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@implementation CustomizingBadgesViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Customizing Badges\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  NIBadgeView* badgeView = [[NIBadgeView alloc] initWithFrame:CGRectZero];\n  badgeView.backgroundColor = self.view.backgroundColor;\n  badgeView.text = @\"White on blue\";\n  badgeView.tintColor = [UIColor blueColor];\n  [badgeView sizeToFit];\n  [self.view addSubview:badgeView];\n  \n  NIBadgeView* badgeView2 = [[NIBadgeView alloc] initWithFrame:CGRectZero];\n  badgeView2.backgroundColor = self.view.backgroundColor;\n  badgeView2.text = @\"Black on orange\";\n  badgeView2.tintColor = [UIColor orangeColor];\n  badgeView2.textColor = [UIColor blackColor];\n  [badgeView2 sizeToFit];\n  badgeView2.frame = CGRectMake(CGRectGetMaxX(badgeView.frame), 0, badgeView2.frame.size.width, badgeView2.frame.size.height);\n  [self.view addSubview:badgeView2];\n  \n  NIBadgeView* badgeView3 = [[NIBadgeView alloc] initWithFrame:CGRectZero];\n  badgeView3.backgroundColor = self.view.backgroundColor;\n  badgeView3.text = @\"Tiny\";\n  badgeView3.font = [UIFont systemFontOfSize:12];\n  [badgeView3 sizeToFit];\n  badgeView3.frame = CGRectMake(0, CGRectGetMaxY(badgeView.frame), badgeView3.frame.size.width, badgeView3.frame.size.height);\n  [self.view addSubview:badgeView3];\n\n  NIBadgeView* badgeView4 = [[NIBadgeView alloc] initWithFrame:CGRectZero];\n  badgeView4.backgroundColor = self.view.backgroundColor;\n  badgeView4.text = @\"Zapfino Huge\";\n  badgeView4.font = [UIFont fontWithName:@\"Zapfino\" size:30];\n  [badgeView4 sizeToFit];\n  badgeView4.frame = CGRectMake(0, CGRectGetMaxY(badgeView3.frame), badgeView4.frame.size.width, badgeView4.frame.size.height);\n  [self.view addSubview:badgeView4];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/DataTypesAttributedLabelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface DataTypesAttributedLabelViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/DataTypesAttributedLabelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"DataTypesAttributedLabelViewController.h\"\n#import \"NimbusAttributedLabel.h\"\n\n//\n// What's going on in this file:\n//\n// This controller shows the various data types that an attributed label may display and handle.\n//\n// You will find the following Nimbus features used:\n//\n// [attributedlabel]\n// NIAttributedLabel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// CoreText.framework\n// QuartzCore.framework\n//\n\n@interface DataTypesAttributedLabelViewController() <NIAttributedLabelDelegate>\n@end\n\n@implementation DataTypesAttributedLabelViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Data Types\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  NIAttributedLabel* label = [[NIAttributedLabel alloc] initWithFrame:CGRectZero];\n  label.numberOfLines = 0;\n  label.lineBreakMode = NSLineBreakByWordWrapping;\n  label.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  label.frame = CGRectInset(self.view.bounds, 20, 20);\n  label.font = [UIFont fontWithName:@\"Optima-Regular\" size:20];\n  label.delegate = self;\n  label.autoDetectLinks = YES;\n\n  // Turn on all available data detectors. This includes phone numbers, email addresses, and\n  // addresses.\n  label.dataDetectorTypes = NSTextCheckingAllSystemTypes;\n\n  label.text = @\"She presses a button next to the display and it flickers once more.\"\n  @\"\\n\\nUpon the arrival at Gliese 581 g, initiate contact with the following:\"\n  @\"\\n\\nCall: 555-0131\"\n  @\"\\nEmail: hello@nimbuskit.info\"\n  @\"\\nMail: 123 Nimbus Ln.\";\n\n  [self.view addSubview:label];\n}\n\n#pragma mark - NIAttributedLabelDelegate\n\n- (void)attributedLabel:(NIAttributedLabel*)attributedLabel didSelectTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point {\n  NSURL* url = nil;\n\n  // We can receive many different types of data types now, so we have to handle each one a little\n  // differently.\n  if (NSTextCheckingTypePhoneNumber == result.resultType) {\n    // Opens the phone app if it exists.\n    url = [NSURL URLWithString:[@\"tel://\" stringByAppendingString:result.phoneNumber]];\n\n  } else if (NSTextCheckingTypeLink == result.resultType) {\n    // Simply open the URL that was tapped. emails count as URLs as well and are automatically\n    // prefixed with @\"mailto:\".\n    url = result.URL;\n\n  } else if (NSTextCheckingTypeAddress == result.resultType) {\n    // Open the Maps application or Safari if the maps application isn't installed.\n    url = [NSURL URLWithString:[@\"https://maps.google.com/maps?q=\" stringByAppendingString:[[result.addressComponents objectForKey:NSTextCheckingStreetKey] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];\n  }\n\n  if (nil != url) {\n    if (![[UIApplication sharedApplication] openURL:url]) {\n      UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"Error\"\n                                                      message:[@\"No application was found that could open this url: \" stringByAppendingString:url.absoluteString]\n                                                     delegate:nil\n                                            cancelButtonTitle:@\"OK\"\n                                            otherButtonTitles:nil];\n      [alert show];\n    }\n\n  } else {\n    NSLog(@\"Unsupported data type\");\n  }\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ExtraActionsWebViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusWebController.h\"\n\n@interface ExtraActionsWebViewController : NIWebController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ExtraActionsWebViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"ExtraActionsWebViewController.h\"\n\n@implementation ExtraActionsWebViewController\n\n- (BOOL)shouldPresentActionSheet:(UIActionSheet *)actionSheet {\n  // We call super here to populate the action sheet with the default actions.\n  [super shouldPresentActionSheet:actionSheet];\n\n  // Add our custom action.\n  [actionSheet addButtonWithTitle:@\"Latest Docs\"];\n\n  // Returning YES means that we want to allow this action sheet to appear.\n  // If we return NO then the action sheet would not appear and we'd be expected to have shown our\n  // own action sheet or dialog in some way.\n  return YES;\n}\n\n- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {\n  [super actionSheet:actionSheet clickedButtonAtIndex:buttonIndex];\n  if (buttonIndex == 2) {\n    [self openURL:[NSURL URLWithString:@\"http://latest.docs.nimbuskit.info/\"]];\n  }\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/FormCellCatalogViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface FormCellCatalogViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/FormCellCatalogViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"FormCellCatalogViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NIFormCellCatalog.h\"\n#import \"NIRadioGroup.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a catalog of all of Nimbus' form cells. This example does not go into details on the\n// individual cells. It is meant to provide a quick overview of the cells.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NITableViewModel\n// NICellFactory\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n// This enumeration is used in the radio group mapping.\ntypedef enum {\n  RadioOption1,\n  RadioOption2,\n  RadioOption3,\n} RadioOptions;\n\n// This enumeration is used in the sub radio group mapping.\ntypedef enum {\n  SubRadioOption1,\n  SubRadioOption2,\n  SubRadioOption3,\n} SubRadioOptions;\n\n@interface FormCellCatalogViewController () <UITextFieldDelegate, NIRadioGroupDelegate>\n@property (nonatomic, retain) NITableViewModel* model;\n\n// A radio group object allows us to easily maintain radio group-style interactions in a table view.\n@property (nonatomic, retain) NIRadioGroup* radioGroup;\n\n// Each radio group object maintains a specific set of table objects, so in order to have multiple\n// radio groups you need to instantiate multiple radio group objects.\n@property (nonatomic, retain) NIRadioGroup* subRadioGroup;\n@end\n\n@implementation FormCellCatalogViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"Form Cell Catalog\";\n    \n    _radioGroup = [[NIRadioGroup alloc] init];\n    _radioGroup.delegate = self;\n    \n    _subRadioGroup = [[NIRadioGroup alloc] initWithController:self];\n    _subRadioGroup.delegate = self;\n    _subRadioGroup.cellTitle = @\"Selection\";\n    _subRadioGroup.controllerTitle = @\"Make a Selection\";\n    \n    [_subRadioGroup mapObject:[NISubtitleCellObject objectWithTitle:@\"Sub Radio 1\"\n                                                           subtitle:@\"First option\"]\n                 toIdentifier:SubRadioOption1];\n    [_subRadioGroup mapObject:[NISubtitleCellObject objectWithTitle:@\"Sub Radio 2\"\n                                                           subtitle:@\"Second option\"]\n                 toIdentifier:SubRadioOption2];\n    [_subRadioGroup mapObject:[NISubtitleCellObject objectWithTitle:@\"Sub Radio 3\"\n                                                           subtitle:@\"Third option\"]\n                 toIdentifier:SubRadioOption3];\n    \n    NSArray* tableContents =\n    [NSArray arrayWithObjects:\n     @\"Radio Group\",\n     [_radioGroup mapObject:[NISubtitleCellObject objectWithTitle:@\"Radio 1\"\n                                                         subtitle:@\"First option\"]\n               toIdentifier:RadioOption1],\n     [_radioGroup mapObject:[NISubtitleCellObject objectWithTitle:@\"Radio 2\"\n                                                         subtitle:@\"Second option\"]\n               toIdentifier:RadioOption2],\n     [_radioGroup mapObject:[NISubtitleCellObject objectWithTitle:@\"Radio 3\"\n                                                         subtitle:@\"Third option\"]\n               toIdentifier:RadioOption3],\n     @\"Radio Group Controller\",\n     _subRadioGroup,\n     \n     @\"NITextInputFormElement\",\n     [NITextInputFormElement textInputElementWithID:0 placeholderText:@\"Placeholder\" value:nil],\n     [NITextInputFormElement textInputElementWithID:0 placeholderText:@\"Placeholder\" value:@\"Initial value\"],\n     [NITextInputFormElement textInputElementWithID:1 placeholderText:nil value:@\"Disabled input field\" delegate:self],\n     [NITextInputFormElement passwordInputElementWithID:0 placeholderText:@\"Password\" value:nil],\n     [NITextInputFormElement passwordInputElementWithID:0 placeholderText:@\"Password\" value:@\"Password\"],\n     \n     @\"NISwitchFormElement\",\n     [NISwitchFormElement switchElementWithID:0 labelText:@\"Switch\" value:NO],\n     [NISwitchFormElement switchElementWithID:0 labelText:@\"Switch with a really long label that will be cut off\" value:YES],\n     [NISwitchFormElement switchElementWithID:0 labelText:@\"Switch with target/selector\" value:NO didChangeTarget:self didChangeSelector:@selector(switchChanged:)],\n\n     @\"NISliderFormElement\",\n     [NISliderFormElement sliderElementWithID:0\n                                    labelText:@\"Slider\"\n                                        value:45\n                                 minimumValue:0\n                                 maximumValue:100],\n     \n     @\"NISegmentedControlFormElement\",\n     [NISegmentedControlFormElement segmentedControlElementWithID:0\n                                                        labelText:@\"Text segments\"\n                                                         segments:[NSArray arrayWithObjects:\n                                                                   @\"one\", @\"two\", nil]\n                                                    selectedIndex:0],\n     [NISegmentedControlFormElement segmentedControlElementWithID:0\n                                                        labelText:@\"Image segments\"\n                                                         segments:[NSArray arrayWithObjects:\n                                                                   [UIImage imageNamed:@\"star.png\"],\n                                                                   [UIImage imageNamed:@\"circle.png\"],\n                                                                   nil]\n                                                    selectedIndex:-1\n                                                  didChangeTarget:self\n                                                didChangeSelector:@selector(segmentedControlWithImagesDidChangeValue:)],\n     @\"NIDatePickerFormElement\",\n     [NIDatePickerFormElement datePickerElementWithID:0\n                                            labelText:@\"Date and time\"\n                                                 date:[NSDate date]\n                                       datePickerMode:UIDatePickerModeDateAndTime],\n     [NIDatePickerFormElement datePickerElementWithID:0\n                                            labelText:@\"Date only\"\n                                                 date:[NSDate date]\n                                       datePickerMode:UIDatePickerModeDate],\n     [NIDatePickerFormElement datePickerElementWithID:0\n                                            labelText:@\"Time only\"\n                                                 date:[NSDate date]\n                                       datePickerMode:UIDatePickerModeTime\n                                      didChangeTarget:self\n                                    didChangeSelector:@selector(datePickerDidChangeValue:)],\n     [NIDatePickerFormElement datePickerElementWithID:0\n                                            labelText:@\"Countdown\"\n                                                 date:[NSDate date]\n                                       datePickerMode:UIDatePickerModeCountDownTimer],\n     nil];\n    \n    self.radioGroup.selectedIdentifier = RadioOption1;\n    self.subRadioGroup.selectedIdentifier = SubRadioOption1;\n    \n    // We let the Nimbus cell factory create the cells.\n    _model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                     delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.tableView.dataSource = _model;\n  \n  self.tableView.delegate = [self.radioGroup forwardingTo:\n                             [self.subRadioGroup forwardingTo:self.tableView.delegate]];\n  \n  // When including text editing cells in table views you should provide a means for the user to\n  // stop editing the control. To do this we add a gesture recognizer to the table view.\n  UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapTableView)];\n\n  // We still want the table view to be able to process touch events when we tap.\n  tap.cancelsTouchesInView = NO;\n\n  [self.tableView addGestureRecognizer:tap];\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n- (void)segmentedControlWithImagesDidChangeValue:(UISegmentedControl *)segmentedControl {\n  NIDPRINT(@\"Segmented control changed value to index %@\", @(segmentedControl.selectedSegmentIndex));\n}\n\n- (void)datePickerDidChangeValue:(UIDatePicker *)picker {\n  NIDPRINT(@\"Time only date picker changed value to %@\",\n           [NSDateFormatter localizedStringFromDate:picker.date\n                                          dateStyle:NSDateFormatterNoStyle\n                                          timeStyle:NSDateFormatterShortStyle]);\n}\n\n#pragma mark - UITextFieldDelegate\n\n- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {\n  if (textField.tag == 1) {\n    return NO;\n  }\n  return YES;\n}\n\n#pragma mark - UITableViewDelegate\n\n- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {\n  // Customize the presentation of certain types of cells.\n  if ([cell isKindOfClass:[NITextInputFormElementCell class]]) {\n    NITextInputFormElementCell* textInputCell = (NITextInputFormElementCell *)cell;\n    if (1 == cell.tag) {\n      // Make the disabled input field look slightly different.\n      textInputCell.textField.textColor = [UIColor colorWithRed:1 green:0.5 blue:0.5 alpha:1];\n\n    } else {\n      // We must always handle the else case because cells can be reused.\n      textInputCell.textField.textColor = [UIColor blackColor];\n    }\n  }\n}\n\n#pragma mark - NIRadioGroupDelegate\n\n- (void)radioGroup:(NIRadioGroup *)radioGroup didSelectIdentifier:(NSInteger)identifier {\n  if (radioGroup == self.radioGroup) {\n    NSLog(@\"Radio group selection: %zd\", identifier);\n  } else if (radioGroup == self.subRadioGroup) {\n    NSLog(@\"Sub radio group selection: %zd\", identifier);\n  }\n}\n\n- (NSString *)radioGroup:(NIRadioGroup *)radioGroup textForIdentifier:(NSInteger)identifier {\n  switch (identifier) {\n    case SubRadioOption1:\n      return @\"Option 1\";\n    case SubRadioOption2:\n      return @\"Option 2\";\n    case SubRadioOption3:\n      return @\"Option 3\";\n  }\n  return nil;\n}\n\n- (void)switchChanged:(UISwitch *)uiSwitch {\n    NSLog(@\"Switch changed to %@\", uiSwitch.on ? @\"YES\" : @\"NO\");\n}\n\n#pragma mark - Gesture Recognizers\n\n- (void)didTapTableView {\n  [self.view endEditing:YES];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ImagesAttributedLabelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface ImagesAttributedLabelViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ImagesAttributedLabelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"ImagesAttributedLabelViewController.h\"\n\n#import \"NimbusAttributedLabel.h\"\n\n//\n// What's going on in this file:\n//\n// This controller shows how to add inline images to NIAttributedLabel.\n//\n// You will find the following Nimbus features used:\n//\n// [attributedlabel]\n// NIAttributedLabel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// CoreText.framework\n// QuartzCore.framework\n//\n\n@implementation ImagesAttributedLabelViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Images\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  NIAttributedLabel* label = [[NIAttributedLabel alloc] initWithFrame:CGRectZero];\n\n  // When we assign the text we do not include any markup for the images.\n  label.text = @\"This is Nimbus:He's a red panda.\\nThis is a star:\";\n\n  label.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  label.lineBreakMode = NSLineBreakByWordWrapping;\n  label.numberOfLines = 0;\n  label.font = [UIFont systemFontOfSize:20];\n  label.textColor = [UIColor blackColor];\n  label.frame = CGRectInset(self.view.bounds, 20, 20);\n\n  // We want to insert an image directly after the string \"Nimbus:\" in the above string, so find its\n  // range and then use NSMaxRange to get the last index.\n  NSRange range = [label.text rangeOfString:@\"Nimbus:\"];\n\n  // When we insert an image we have the option to provide margins and vertical text alignment.\n  //\n  // Experiment:\n  // Try changing the values of the margins and seeing the effects it has.\n  //\n  [label insertImage:[UIImage imageNamed:@\"Icon\"]\n             atIndex:NSMaxRange(range)\n             margins:UIEdgeInsetsMake(5, 5, 5, 5)];\n\n  // We're going to add an image to the end of the string, so we pass the length of the string.\n  // Why not length - 1? Because the image gets inserted at the given index, so if we passed\n  // length - 1 the image would be immediately before the last character.\n  //\n  // Experiment:\n  // Try changing the index to other arbitrary values and seeing how it affects the way the text is\n  // drawn.\n  //\n  [label insertImage:[UIImage imageNamed:@\"star\"]\n             atIndex:label.text.length\n             margins:UIEdgeInsetsMake(5, 5, 5, 5)];\n\n  [self.view addSubview:label];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/IndexedTableModelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface IndexedTableModelViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/IndexedTableModelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"IndexedTableModelViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of creating a NITableViewModel with an indexed group of objects.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NITableViewModel\n// NICellFactory\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface IndexedTableModelViewController ()\n@property (nonatomic, retain) NITableViewModel* model;\n@end\n\n@implementation IndexedTableModelViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"Indexed Model\";\n    \n    // When using sectioned indexes we create our model with sectioned objects. Each section header\n    // is generally the alphabetic letter that the contents of that section are grouped by. This\n    // may be alphabetic by last name or first name, or by some other arbitrary sorting algorithm.\n    // Whatever the algorithm may be, you should ensure that the groups are sorted in a way that\n    // matches the index sorting algorithm.\n    //\n    // In this example we use a static list of names that are sorted by last name and\n    // NITableViewModelSectionIndexAlphabetical as the index type.\n    NSArray* tableContents =\n    [NSArray arrayWithObjects:\n     @\"A\",\n     [NITitleCellObject objectWithTitle:@\"Jon Abrams\"],\n     [NITitleCellObject objectWithTitle:@\"Crystal Arbor\"],\n     [NITitleCellObject objectWithTitle:@\"Mike Axiom\"],\n     \n     @\"B\",\n     [NITitleCellObject objectWithTitle:@\"Joey Bannister\"],\n     [NITitleCellObject objectWithTitle:@\"Ray Bowl\"],\n     [NITitleCellObject objectWithTitle:@\"Jane Byte\"],\n     \n     @\"C\",\n     [NITitleCellObject objectWithTitle:@\"JJ Cranilly\"],\n     \n     @\"K\",\n     [NITitleCellObject objectWithTitle:@\"Jake Klark\"],\n     [NITitleCellObject objectWithTitle:@\"Viktor Krum\"],\n     [NITitleCellObject objectWithTitle:@\"Abraham Kyle\"],\n     \n     @\"L\",\n     [NITitleCellObject objectWithTitle:@\"Mr Larry\"],\n     [NITitleCellObject objectWithTitle:@\"Mo Lundlum\"],\n     \n     @\"N\",\n     [NITitleCellObject objectWithTitle:@\"Carl Nolly\"],\n     [NITitleCellObject objectWithTitle:@\"Jeremy Nym\"],\n     \n     @\"O\",\n     [NITitleCellObject objectWithTitle:@\"Number 1 Otter\"],\n     [NITitleCellObject objectWithTitle:@\"Number 2 Otter\"],\n     [NITitleCellObject objectWithTitle:@\"Number 3 Otter\"],\n     [NITitleCellObject objectWithTitle:@\"Number 4 Otter\"],\n     [NITitleCellObject objectWithTitle:@\"Number 5 Otter\"],\n     [NITitleCellObject objectWithTitle:@\"Number 6 Otter\"],\n     [NITitleCellObject objectWithTitle:@\"Number 7 Otter\"],\n     [NITitleCellObject objectWithTitle:@\"Number 8 Otter\"],\n     [NITitleCellObject objectWithTitle:@\"Number 9 Otter\"],\n     [NITitleCellObject objectWithTitle:@\"Number 10 Otter\"],\n     \n     @\"X\",\n     [NITitleCellObject objectWithTitle:@\"Charles Xavier\"],\n     nil];\n\n    _model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                     delegate:(id)[NICellFactory class]];\n\n    // NITableViewModelSectionIndexAlphabetical generates an index that shows the entire alphabetic\n    // range from A-Z. When the user taps any of these letters the model will jump to the closest\n    // section for the tapped letter.\n    //\n    // Experiment:\n    // Try changing the index type to NITableViewModelSectionIndexDynamic. You should notice that\n    // the index is now generated from the section headers. In nearly every case you will want to\n    // use the alphabetical index.\n    [_model setSectionIndexType:NITableViewModelSectionIndexAlphabetical\n                    showsSearch:NO\n                   showsSummary:NO];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n  \n  self.tableView.dataSource = _model;\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/InterappViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface InterappViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/InterappViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"InterappViewController.h\"\n#import \"NimbusModels.h\"\n#import \"NimbusInterapp.h\"\n\n//\n// What's going on in this file:\n//\n// This controller shows all of the available communication methods that NIInterapp provides.\n//\n// You will find the following Nimbus features used:\n//\n// [interapp]\n// All NIInterapp category methods\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// CoreLocation.framework\n//\n\n@interface InterappViewController () <UIDocumentInteractionControllerDelegate>\n@property (nonatomic, retain) NITableViewModel* model;\n@property (nonatomic, retain) NITableViewActions* actions;\n@property (nonatomic, copy) NSURL* fileUrl;\n@property (nonatomic, retain) UIDocumentInteractionController* docController;\n@end\n\n@implementation InterappViewController\n\n\n- (void)cleanupDocController {\n  [[NSFileManager defaultManager] removeItemAtURL:self.fileUrl error:nil];\n  self.fileUrl = nil;\n  self.docController = nil;\n}\n\n// This method is the short form of adding a cell object with an action.\n- (id)objectWithAction:(BOOL (^)())action title:(NSString *)title subtitle:(NSString *)subtitle {\n  return [self.actions attachToObject:[NISubtitleCellObject objectWithTitle:title subtitle:subtitle]\n                             tapBlock:\n          ^BOOL(id object, UIViewController *controller, NSIndexPath* indexPath) {\n            if (!action()) {\n              UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"We've givin' her all she's got, cap'n!\"\n                                                              message:@\"The app you tried to open does not appear to be installed on this device.\"\n                                                             delegate:nil\n                                                    cancelButtonTitle:@\"Oh well\"\n                                                    otherButtonTitles:nil];\n              [alert show];\n            }\n            return YES;\n          }];\n}\n\n// Prepares an Instagram image for sharing and then uses the UIDocumentInteractionController\n// to show a sharing controller.\n- (BOOL)openInstagramImage {\n  [self cleanupDocController];\n  \n  NSError* error = nil;\n  self.fileUrl = [NIInterapp urlForInstagramImageAtFilePath:NIPathForBundleResource(nil, @\"dilly.jpg\")\n                                                      error:&error];\n  if (nil != self.fileUrl) {\n    self.docController = [UIDocumentInteractionController interactionControllerWithURL:_fileUrl];\n    self.docController.delegate = self;\n\n    [self.docController presentOpenInMenuFromRect:CGRectZero\n                                           inView:self.view\n                                         animated:YES];\n    return YES;\n  }\n\n  return NO;\n}\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"All Actions\";\n    \n    _actions = [[NITableViewActions alloc] initWithTarget:self];\n\n    NSArray* sectionedObjects =\n    [NSArray arrayWithObjects:\n\n     @\"Safari\",\n     [self objectWithAction:^{return [NIInterapp safariWithURL:[NSURL URLWithString:@\"http://latest.docs.nimbuskit.info\"]];}\n                      title:@\"Open a URL in Safari\" subtitle:@\"http://latest.docs.nimbuskit.info\"],\n\n     @\"Maps\",\n     [self objectWithAction:^{return [NIInterapp googleMapAtLocation:CLLocationCoordinate2DMake(37.37165, -121.97877)];}\n                      title:@\"Open a Lat/Long\" subtitle:@\"Trampoline dodgeball!\"],\n     [self objectWithAction:^{return [NIInterapp googleMapAtLocation:CLLocationCoordinate2DMake(37.37165, -121.97877)\n                                                               title:@\"Trampoline Dodgeball\"];}\n                      title:@\"Open a Lat/Long with a title\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp googleMapDirectionsFromLocation:CLLocationCoordinate2DMake(37.6139, -122.4871)\n                                                                      toLocation:CLLocationCoordinate2DMake(36.6039, -121.9116)];}\n                      title:@\"Directions\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp googleMapWithQuery:@\"Boudin Bakeries\"];}\n                      title:@\"Search for Boudin Bakeries\" subtitle:nil],\n\n     @\"Phone\",\n     [self objectWithAction:^{return [NIInterapp phone];} title:@\"Open the app\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp phoneWithNumber:@\"123-500-7890\"];} title:@\"Call 123-500-7890\" subtitle:nil],\n\n     @\"SMS\",\n     [self objectWithAction:^{return [NIInterapp sms];} title:@\"Open the app\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp smsWithNumber:@\"123-500-7890\"];} title:@\"SMS 123-500-7890\" subtitle:nil],\n     \n     @\"Mail\",\n     [self objectWithAction:^{NIMailAppInvocation* invocation = [NIMailAppInvocation invocation];\n      invocation.recipient = @\"jverkoey@gmail.com\";\n      return [NIInterapp mailWithInvocation:invocation];} title:@\"Mail to jverkoey@gmail.com\" subtitle:nil],\n     [self objectWithAction:^{NIMailAppInvocation* invocation = [NIMailAppInvocation invocation];\n      invocation.recipient = @\"jverkoey@gmail.com\";\n      invocation.subject = @\"Nimbus made me do it!\";\n      return [NIInterapp mailWithInvocation:invocation];} title:@\"Mail with a subject\" subtitle:nil],\n     [self objectWithAction:^{NIMailAppInvocation* invocation = [NIMailAppInvocation invocation];\n      invocation.recipient = @\"jverkoey@gmail.com\";\n      invocation.subject = @\"Nimbus made me do it!\";\n      invocation.bcc = @\"jverkoey+bcc@gmail.com\";\n      invocation.cc = @\"jverkoey+cc@gmail.com\";\n      invocation.body = @\"This will be an awesome email.\";\n      return [NIInterapp mailWithInvocation:invocation];} title:@\"Mail with all details\" subtitle:nil],\n     \n     @\"YouTube\",\n     [self objectWithAction:^{return [NIInterapp youTubeWithVideoId:@\"fzzjgBAaWZw\"];} title:@\"Ninja cat video\" subtitle:nil],\n     \n     @\"iBooks\",\n     [self objectWithAction:^{return [NIInterapp iBooks];} title:@\"Open the app\" subtitle:nil],\n     \n     @\"App Store\",\n     [self objectWithAction:^{return [NIInterapp appStoreWithAppId:@\"364709193\"];} title:@\"Buy the iBooks app\" subtitle:nil],\n     \n     @\"Facebook\",\n     [self objectWithAction:^{return [NIInterapp facebook];} title:@\"Open the app\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp facebookProfileWithId:@\"122605446\"];} title:@\"Jeff's profile page\" subtitle:nil],\n     \n     @\"Twitter\",\n     [self objectWithAction:^{return [NIInterapp twitter];} title:@\"Open the app\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp twitterWithMessage:@\"I'm playing with the Nimbus sample apps! http://nimbuskit.info\"];} title:@\"Post a tweet\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp twitterProfileForUsername:@\"featherless\"];} title:@\"Open featherless' profile\" subtitle:nil],\n     \n     @\"Instagram\",\n     [self objectWithAction:^{return [NIInterapp instagram];} title:@\"Open the app\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp instagramCamera];} title:@\"Camera\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp instagramProfileForUsername:@\"featherless\"];} title:@\"Open featherless' profile\" subtitle:nil],\n     [self objectWithAction:^{return [self openInstagramImage];} title:@\"Open local image in Instagram\" subtitle:nil],\n     \n     @\"Custom Application\",\n     [self objectWithAction:^{return [NIInterapp applicationWithScheme:@\"RAWR:\"];} title:@\"Open custom app (RAWR:)\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp applicationWithScheme:@\"RAWR:\"\n                                                         andAppStoreId:@\"000000000\"];} title:@\"Custom app or AppStore\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp applicationWithScheme:@\"RAWR:\"\n                                                               andPath:@\"//friends/blah\"];} title:@\"Custom app with url\" subtitle:nil],\n     [self objectWithAction:^{return [NIInterapp applicationWithScheme:@\"RAWR:\"\n                                                            appStoreId:@\"000000000\" \n                                                               andPath:@\"//friends/blah\"];} title:@\"Custom app with url or AppStore\" subtitle:nil],\n     \n     nil];\n\n    _model = [[NITableViewModel alloc] initWithSectionedArray:sectionedObjects\n                                                     delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.tableView.dataSource = self.model;\n  self.tableView.delegate = [self.actions forwardingTo:self];\n}\n\n#pragma mark - UIDocumentInteractionControllerDelegate\n\n- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller {\n  [self cleanupDocController];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/InterfaceBuilderAttributedLabelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface InterfaceBuilderAttributedLabelViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/InterfaceBuilderAttributedLabelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"InterfaceBuilderAttributedLabelViewController.h\"\n#import \"NimbusAttributedLabel.h\"\n\n//\n// What's going on in this file:\n//\n// This controller creates its view from the AttributedLabelMashup xib file found adjacent to this\n// controller in the Xcode project. UILabel views are added to the interface and NIAttributedLabel\n// is set as the custom class. We then configure the attributed labels further in viewDidLoad.\n//\n// You will find the following Nimbus features used:\n//\n// [attributedlabel]\n// NIAttributedLabel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// CoreText.framework\n// QuartzCore.framework\n//\n\n@interface InterfaceBuilderAttributedLabelViewController() <NIAttributedLabelDelegate>\n@property (nonatomic, retain) IBOutlet UIScrollView* scrollView;\n@property (nonatomic, retain) IBOutlet NIAttributedLabel* nimbusTitle;\n@property (nonatomic, retain) IBOutlet NIAttributedLabel* label1;\n@property (nonatomic, retain) IBOutlet NIAttributedLabel* label2;\n@property (nonatomic, retain) IBOutlet NIAttributedLabel* label3;\n@property (nonatomic, retain) IBOutlet NIAttributedLabel* label4;\n@end\n\n@implementation InterfaceBuilderAttributedLabelViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:@\"AttributedLabelMashup\" bundle:nil])) {\n    self.title = @\"Interface Builder\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  _nimbusTitle.strokeWidth = -3.0;\n  _nimbusTitle.strokeColor = [UIColor blackColor];\n\n  // Kerning modifies the spacing between letters.\n  _nimbusTitle.textKern = 15.0;\n\n  _label1.textAlignment = NSTextAlignmentJustified;\n\n  _label2.underlineStyle = kCTUnderlineStyleDouble;\n  _label2.underlineStyleModifier = kCTUnderlinePatternDot;\n\n  _label3.autoDetectLinks = YES;\n  _label3.linkColor = [UIColor purpleColor];\n  _label3.highlightedLinkBackgroundColor = [UIColor orangeColor];\n  _label3.linksHaveUnderlines = YES;\n\n  _label4.textAlignment = NSTextAlignmentJustified;\n  [_label4 setTextColor:[UIColor orangeColor]  range:[_label4.text rangeOfString:@\"Nimbus\"]];\n  [_label4 setTextColor:[UIColor redColor]  range:[_label4.text rangeOfString:@\"accelerates\"]];\n  [_label4 setFont:[UIFont boldSystemFontOfSize:22] range:[_label4.text rangeOfString:@\"iOS\"]];\n  [_label4 setUnderlineStyle:kCTUnderlineStyleSingle modifier:kCTUnderlinePatternDash range:[_label4.text rangeOfString:@\"documentation\"]];\n  [_label4 setFont:[UIFont fontWithName:@\"MarkerFelt-Wide\" size:17] range:[_label4.text rangeOfString:@\"Nimbus\" options:NSBackwardsSearch]];\n  [_label4 addLink:[NSURL URLWithString:@\"nimbus://custom/url\"] range:[_label4.text rangeOfString:@\"easy\"]];\n\n  self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, CGRectGetMaxY(_label4.frame));\n}\n\n#pragma mark - NIAttributedLabelDelegate\n\n- (void)attributedLabel:(NIAttributedLabel *)attributedLabel didSelectTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point {\n  UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"Link Selected\" message:result.URL.relativeString delegate:nil cancelButtonTitle:@\"OK\" otherButtonTitles: nil];\n  [alert show];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/InterfaceBuilderBadgeViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface InterfaceBuilderBadgeViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/InterfaceBuilderBadgeViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"InterfaceBuilderBadgeViewController.h\"\n#import \"NimbusBadge.h\"\n\n//\n// What's going on in this file:\n//\n// This controller shows how to add NIBadgeViews to a xib file and configure them from within\n// Interface Builder (IB).\n//\n// To add a NIBadgeView to IB you will need to add a UIView object and specify NIBadgeView as the\n// subclass.\n//\n// You will find the following Nimbus features used:\n//\n// [badge]\n// NIBadgeView\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface InterfaceBuilderBadgeViewController ()\n@property (nonatomic, retain) IBOutlet NIBadgeView* badgeView;\n@property (nonatomic, retain) IBOutlet NIBadgeView* badgeView2;\n@end\n\n@implementation InterfaceBuilderBadgeViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:@\"ApplicationBadges\" bundle:nibBundleOrNil])) {\n    self.title = @\"Interface Builder\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n\n  self.badgeView.text = @\"2\";\n  self.badgeView2.text = @\"4\";\n  [self.badgeView sizeToFit];\n  [self.badgeView2 sizeToFit];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/LinksAttributedLabelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface LinksAttributedLabelViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/LinksAttributedLabelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"LinksAttributedLabelViewController.h\"\n#import \"NimbusAttributedLabel.h\"\n\n//\n// What's going on in this file:\n//\n// This controller demos the use of links in NIAttributedLabels. You'll see how to explicitly add\n// links and how to configure autodetection of links.\n//\n// You will find the following Nimbus features used:\n//\n// [attributedlabel]\n// NIAttributedLabel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// CoreText.framework\n// QuartzCore.framework\n//\n\n// We declare the protocol conformity here in the source file using a category extension.\n// This allows us to conform to protocols privately and to avoid polluting the public namespace.\n@interface LinksAttributedLabelViewController() <NIAttributedLabelDelegate>\n@end\n\n@implementation LinksAttributedLabelViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Links\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  NIAttributedLabel* label = [[NIAttributedLabel alloc] initWithFrame:CGRectZero];\n  label.numberOfLines = 0;\n  label.lineBreakMode = NSLineBreakByWordWrapping;\n  label.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  label.frame = CGRectInset(self.view.bounds, 20, 20);\n  label.font = [UIFont fontWithName:@\"AmericanTypewriter\" size:15];\n\n  // When the user taps a link we can change the way the link text looks.\n  label.attributesForHighlightedLink = @{NSForegroundColorAttributeName: RGBCOLOR(255, 0, 0)};\n\n  // In order to handle the events generated by the user tapping a link we must implement the\n  // delegate.\n  label.delegate = self;\n\n  // By default the label will not automatically detect links. Turning this on will cause the label\n  // to pass through the text with an NSDataDetector, highlighting any detected URLs.\n  label.autoDetectLinks = YES;\n\n  // By default links do not have underlines and this is generally accepted as the standard on iOS.\n  // If, however, you do wish to show underlines, you can enable them like so:\n  label.linksHaveUnderlines = YES;\n\n  label.text =\n  @\"A screen on the dash flickers and displays an artist's rendition of the planet.\"\n  // We can use \\n characters to separate lines of text.\n  @\"\\nSigned beneath the image: tenach.deviantart.com\";\n\n  NSRange linkRange = [label.text rangeOfString:@\"an artist's rendition of the planet\"];\n\n  // Explicitly adds a link at a given range.\n  [label addLink:[NSURL URLWithString:@\"http://th04.deviantart.net/fs71/300W/f/2010/145/c/9/Planet_Concept_1_by_Tenach.jpg\"]\n           range:linkRange];\n\n  [self.view addSubview:label];\n}\n\n#pragma mark - NIAttributedLabelDelegate\n\n- (void)attributedLabel:(NIAttributedLabel*)attributedLabel didSelectTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point {\n  // In a later example we will show how to push a Nimbus web controller onto the navigation stack\n  // rather than punt the user out of the application to Safari.\n  [[UIApplication sharedApplication] openURL:result.URL];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/LongTapAttributedLabelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface LongTapAttributedLabelViewController : UIViewController\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/LongTapAttributedLabelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"LongTapAttributedLabelViewController.h\"\n\n#import \"NimbusAttributedLabel.h\"\n\n//\n// What's going on in this file:\n//\n// This controller shows how to disable long taps in attributed labels.\n//\n// You will find the following Nimbus features used:\n//\n// [attributedlabel]\n// NIAttributedLabel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// CoreText.framework\n// QuartzCore.framework\n//\n\n@interface LongTapAttributedLabelViewController () <NIAttributedLabelDelegate>\n@end\n\n@implementation LongTapAttributedLabelViewController\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Long Tap\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  NIAttributedLabel* label = [[NIAttributedLabel alloc] initWithFrame:CGRectZero];\n  label.numberOfLines = 0;\n  label.lineBreakMode = NSLineBreakByWordWrapping;\n  label.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  label.frame = CGRectInset(self.view.bounds, 20, 20);\n  label.font = [UIFont fontWithName:@\"AmericanTypewriter\" size:15];\n  label.delegate = self;\n  label.autoDetectLinks = YES;\n\n  label.text = @\"Nimbus' latest documentation is always available at http://latest.docs.nimbuskit.info/\";\n\n  [self.view addSubview:label];\n}\n\n#pragma mark - NIAttributedLabelDelegate\n\n- (void)attributedLabel:(NIAttributedLabel*)attributedLabel didSelectTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point {\n  [[UIApplication sharedApplication] openURL:result.URL];\n}\n\n- (BOOL)attributedLabel:(NIAttributedLabel *)attributedLabel shouldPresentActionSheet:(UIActionSheet *)actionSheet withTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point {\n  // Returning NO here will disable the long-tap action sheet from appearing.\n  return NO;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ModalRadioGroupTableModelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface ModalRadioGroupTableModelViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ModalRadioGroupTableModelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"ModalRadioGroupTableModelViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NIRadioGroup.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of customizing the appearance of a radio group controller so that it appears\n// modally and making a selection dismisses the controller.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NIRadioGroup\n// NIRadioGroupDelegate\n// NITableViewModel\n// NICellFactory\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\ntypedef enum {\n  RadioGroupOption1,\n  RadioGroupOption2,\n  RadioGroupOption3,\n} RadioGroup;\n\n@interface ModalRadioGroupTableModelViewController () <NIRadioGroupDelegate>\n@property (nonatomic, retain) NITableViewModel* model;\n@property (nonatomic, retain) NIRadioGroup* radioGroup;\n@end\n\n@implementation ModalRadioGroupTableModelViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"Modal Radio Group\";\n\n    _radioGroup = [[NIRadioGroup alloc] initWithController:self];\n    _radioGroup.delegate = self;\n\n    _radioGroup.cellTitle = @\"Selection\";\n    _radioGroup.controllerTitle = @\"Make a selection\";\n\n    [_radioGroup mapObject:[NITitleCellObject objectWithTitle:@\"Option 1\"] toIdentifier:RadioGroupOption1];\n    [_radioGroup mapObject:[NITitleCellObject objectWithTitle:@\"Option 2\"] toIdentifier:RadioGroupOption2];\n    [_radioGroup mapObject:[NITitleCellObject objectWithTitle:@\"Option 3\"] toIdentifier:RadioGroupOption3];\n    _radioGroup.selectedIdentifier = RadioGroupOption2;\n\n    NSArray* tableContents = [NSArray arrayWithObject:_radioGroup];\n    _model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                     delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.tableView.dataSource = self.model;\n  self.tableView.delegate = [self.radioGroup forwardingTo:self];\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n#pragma mark - NIRadioGroupDelegate\n\n- (void)radioGroup:(NIRadioGroup *)radioGroup didSelectIdentifier:(NSInteger)identifier {\n  NSLog(@\"Did select radio group option %zd\", identifier);\n\n  // Dismiss the modal view controller that's showing the radio group options.\n  [self dismissViewControllerAnimated:YES completion:nil];\n}\n\n- (NSString *)radioGroup:(NIRadioGroup *)radioGroup textForIdentifier:(NSInteger)identifier {\n  switch (identifier) {\n    case RadioGroupOption1:\n      return @\"Option 1\";\n    case RadioGroupOption2:\n      return @\"Option 2\";\n    case RadioGroupOption3:\n      return @\"Option 3\";\n  }\n  return nil;\n}\n\n// This method will be called immediately before the radio group controller is presented and gives\n// us the opportunity to present the controller ourselves, rather than simply pushing the radio\n// group controller onto the current navigation controller stack.\n- (BOOL)radioGroup:(NIRadioGroup *)radioGroup radioGroupController:(NIRadioGroupController *)radioGroupController willAppear:(BOOL)animated {\n  // We wrap the radio controller in a navigation controller so that it has a navbar when\n  // presented.\n  UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:radioGroupController];\n\n  // Present the radio controller modally.\n  [self presentViewController:nc animated:YES completion:nil];\n\n  return NO; // Don't let the radio group display the controller; we're displaying it ourselves.\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ModelLauncherViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusLauncher.h\"\n\n// All docs are in the .m.\n@interface ModelLauncherViewController : NILauncherViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ModelLauncherViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"ModelLauncherViewController.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n//\n// What's going on in this file:\n//\n// This controller shows how to use NILauncherViewModel to store the launcher object information.\n// This model object greatly simplifies your interactions with the launcher view data source\n// compared to the BasicIntantiation launcher example.\n//\n// This example shows how to create a model that lasts the lifetime of this controller and never\n// changes. In the Modifying example you will learn how to modify the model by adding more pages to\n// it.\n//\n// You will find the following Nimbus features used:\n//\n// [launcher]\n// NILauncherViewController\n// NILauncherViewModel\n// NILauncherViewModelDelegate\n// NILauncherDataSource\n// NILauncherDelegate\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface ModelLauncherViewController () <NILauncherViewModelDelegate>\n@property (nonatomic, retain) NILauncherViewModel* model;\n@end\n\n@implementation ModelLauncherViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    self.title = @\"Model\";\n\n    // Load the Nimbus app icon.\n    NSString* imagePath = NIPathForBundleResource(nil, @\"Icon.png\");\n    UIImage* image = [[Nimbus imageMemoryCache] objectWithName:imagePath];\n    if (nil == image) {\n      image = [UIImage imageWithContentsOfFile:imagePath];\n      [[Nimbus imageMemoryCache] storeObject:image withName:imagePath];\n    }\n\n    // We populate the launcher model with an array of arrays of NILauncherViewObject objects.\n    // Each sub array is a single page of the launcher view. The default NILauncherViewObject object\n    // allows you to provide a title and image.\n    NSArray* contents =\n    [NSArray arrayWithObjects:\n     [NSArray arrayWithObjects:\n      [NILauncherViewObject objectWithTitle:@\"Nimbus\" image:image],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 2\" image:image],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 3\" image:image],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 5\" image:image],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 6\" image:image],\n      nil],\n\n     // A new page.\n     [NSArray arrayWithObjects:\n      [NILauncherViewObject objectWithTitle:@\"Page 2\" image:image],\n      nil],\n\n     // A third page.\n     [NSArray arrayWithObjects:\n      [NILauncherViewObject objectWithTitle:@\"Page 3\" image:image],\n      nil],\n     nil];\n\n    // Create the model object with the contents array. We provide self as the delegate so that\n    // we can customize what the buttons look like.\n    _model = [[NILauncherViewModel alloc] initWithArrayOfPages:contents delegate:self];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n\n  self.view.backgroundColor = [UIColor underPageBackgroundColor];\n\n  // Because the model implements the NILauncherViewDataSource protocol we can simply assign the\n  // model to the dataSource property and everything will magically work. Wicked!\n  self.launcherView.dataSource = self.model;\n}\n\n#pragma mark - NILauncherViewModelDelegate\n\n- (void)launcherViewModel:(NILauncherViewModel *)launcherViewModel\n      configureButtonView:(UIView<NILauncherButtonView> *)buttonView\n          forLauncherView:(NILauncherView *)launcherView\n                pageIndex:(NSInteger)pageIndex\n              buttonIndex:(NSInteger)buttonIndex\n                   object:(id<NILauncherViewObject>)object {\n\n  // The NILauncherViewObject object always creates a NILauncherButtonView so we can safely cast\n  // here and update the label's style to add the nice blurred shadow we saw in the\n  // BasicInstantiation example.\n  NILauncherButtonView* launcherButtonView = (NILauncherButtonView *)buttonView;\n\n  launcherButtonView.label.layer.shadowColor = [UIColor blackColor].CGColor;\n  launcherButtonView.label.layer.shadowOffset = CGSizeMake(0, 1);\n  launcherButtonView.label.layer.shadowOpacity = 1;\n  launcherButtonView.label.layer.shadowRadius = 1;\n}\n\n#pragma mark - NILauncherDelegate\n\n- (void)launcherView:(NILauncherView *)launcher didSelectItemOnPage:(NSInteger)page atIndex:(NSInteger)index {\n  // Now that we're using a model we can easily refer back to which object was selected when we\n  // receive a selection notification.\n  id<NILauncherViewObject> object = [self.model objectAtIndex:index pageIndex:page];\n\n  UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"Notice\"\n                                                  message:[@\"Did tap button with title: \" stringByAppendingString:object.title]\n                                                 delegate:nil\n                                        cancelButtonTitle:@\"OK\"\n                                        otherButtonTitles:nil];\n  [alert show];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ModifyingLauncherViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusLauncher.h\"\n\n// All docs are in the .m.\n@interface ModifyingLauncherViewController : NILauncherViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/ModifyingLauncherViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"ModifyingLauncherViewController.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n//\n// What's going on in this file:\n//\n// This controller shows how to modify a NILauncherViewModel by adding new pages every time the +\n// button is tapped.\n//\n// You will find the following Nimbus features used:\n//\n// [launcher]\n// NILauncherViewController\n// NILauncherViewModel\n// NILauncherViewModelDelegate\n// NILauncherDataSource\n// NILauncherDelegate\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// QuartzCore.framework\n//\n\n@interface ModifyingLauncherViewController () <NILauncherViewModelDelegate>\n@property (nonatomic, retain) NILauncherViewModel* model;\n@end\n\n@implementation ModifyingLauncherViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    self.title = @\"Modifying\";\n\n    // We'll start off with a completely empty model.\n    _model = [[NILauncherViewModel alloc] initWithArrayOfPages:nil delegate:self];\n\n    // We want to add a button to the navigation bar that, when tapped, adds a new page of launcher\n    // buttons to the launcher view.\n    self.navigationItem.rightBarButtonItem =\n    [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd\n                                                  target:self\n                                                  action:@selector(didTapAddButton:)];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n\n  self.view.backgroundColor = [UIColor underPageBackgroundColor];\n  \n  self.launcherView.dataSource = self.model;\n}\n\n#pragma mark - NILauncherViewModelDelegate\n\n- (void)launcherViewModel:(NILauncherViewModel *)launcherViewModel\n      configureButtonView:(UIView<NILauncherButtonView> *)buttonView\n          forLauncherView:(NILauncherView *)launcherView\n                pageIndex:(NSInteger)pageIndex\n              buttonIndex:(NSInteger)buttonIndex\n                   object:(id<NILauncherViewObject>)object {\n  NILauncherButtonView* launcherButtonView = (NILauncherButtonView *)buttonView;\n  \n  launcherButtonView.label.layer.shadowColor = [UIColor blackColor].CGColor;\n  launcherButtonView.label.layer.shadowOffset = CGSizeMake(0, 1);\n  launcherButtonView.label.layer.shadowOpacity = 1;\n  launcherButtonView.label.layer.shadowRadius = 1;\n}\n\n#pragma mark - NILauncherDelegate\n\n- (void)launcherView:(NILauncherView *)launcher didSelectItemOnPage:(NSInteger)page atIndex:(NSInteger)index {\n  id<NILauncherViewObject> object = [self.model objectAtIndex:index pageIndex:page];\n  UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"Notice\"\n                                                  message:[@\"Did tap button with title: \" stringByAppendingString:object.title]\n                                                 delegate:nil\n                                        cancelButtonTitle:@\"OK\"\n                                        otherButtonTitles:nil];\n  [alert show];\n}\n\n#pragma mark - User Actions\n\n- (void)didTapAddButton:(UIBarButtonItem *)barButtonItem {\n  // When the user taps the + button we are going to create a new page filled with a random number\n  // of buttons with random titles.\n\n  // Start by loading the Nimbus app icon.\n  NSString* imagePath = NIPathForBundleResource(nil, @\"Icon.png\");\n  UIImage* image = [[Nimbus imageMemoryCache] objectWithName:imagePath];\n  if (nil == image) {\n    image = [UIImage imageWithContentsOfFile:imagePath];\n    [[Nimbus imageMemoryCache] storeObject:image withName:imagePath];\n  }\n\n  // Now we create a page with 1-9 randomly titled objects.\n  NSInteger randomNumberOfItems = arc4random_uniform(8) + 1;\n  NSMutableArray* objects = [NSMutableArray array];\n  for (NSInteger ix = 0; ix < randomNumberOfItems; ++ix) {\n    [objects addObject:[NILauncherViewObject objectWithTitle:[NSString stringWithFormat:@\"Nimbus %d\", arc4random_uniform(1000)] image:image]];\n  }\n\n  // appendPage should be pretty self-explanatory.\n  [self.model appendPage:objects];\n\n  // Now that we've modified the model we need to reload the data for our changes to become visible.\n  // The cool thing about Nimbus' launcher view is that it only reloads the visible data, so\n  // reloadData is a relatively lightweight operation, just like UITableView.\n  [self.launcherView reloadData];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/MutableTableModelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface MutableTableModelViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/MutableTableModelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"MutableTableModelViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of using a NIMutableTableViewModel to modify the contents of a table model. This\n// demo shows how to add a section of objects to the model, inform the table view that the section\n// has been added, and then recompile the section index.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NIMutableTableViewModel\n// NICellFactory\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface MutableTableModelViewController () <NIMutableTableViewModelDelegate>\n@property (nonatomic, strong) NIMutableTableViewModel* model;\n@property (nonatomic, strong) NIMutableTableViewModel* actions;\n@property (nonatomic, strong) NSIndexPath* indexPathForDeletion;\n@end\n\n@implementation MutableTableModelViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"Mutable Models\";\n\n    // In order to be able to modify a model we must create an instance of NIMutableTableViewModel.\n    // This object differs from NITableViewModel in that it exposes methods for modifying the\n    // contents of the model, similarly to the differences between NSArray and NSMutableArray.\n    _model = [[NIMutableTableViewModel alloc] initWithDelegate:self];\n\n    // We are going to show how to recompile the section index so we provide the settings here.\n    [_model setSectionIndexType:NITableViewModelSectionIndexDynamic\n                    showsSearch:NO\n                   showsSummary:NO];\n\n    // By tapping this button we'll add a new section to the model.\n    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(didTapAddButton:)];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.tableView.dataSource = _model;\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n- (NSString *)randomName {\n  NSMutableString *name = [[NSMutableString alloc] init];\n  for (NSInteger ix = 0; ix < arc4random_uniform(10) + 5; ++ix) {\n    [name appendFormat:@\"%c\", arc4random_uniform('z'-'a')+'a'];\n  }\n  return [name capitalizedString];\n}\n\n- (void)didTapAddButton:(UIBarButtonItem *)buttonItem {\n  // We first create a new section in the model.\n  NSIndexSet* indexSet = [self.model addSectionWithTitle:[self randomName]];\n\n  // Then we create an array of objects that we want to add to this section.\n  NSMutableArray *objects = [NSMutableArray array];\n  for (NSInteger ix = 0; ix < arc4random_uniform(10) + 1; ++ix) {\n    [objects addObject:[NITitleCellObject objectWithTitle:[self randomName]]];\n  }\n\n  // The result of adding these objects is an array of index paths that can be used to ensure the\n  // visibility of the new objects.\n  NSArray* indexPaths = [self.model addObjectsFromArray:objects];\n\n  // Now that we've modified the model, we want to recompile the section index before notifying the\n  // table view of changes to the model.\n  [self.model updateSectionIndex];\n\n  // Tell the table view that we've added a new section and that it should use the default\n  // animation.\n  [self.tableView insertSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];\n\n  // Scroll the table view such that the last object is in view.\n  [self.tableView scrollToRowAtIndexPath:indexPaths.lastObject atScrollPosition:UITableViewScrollPositionBottom animated:YES];\n}\n\n#pragma mark - UITableViewDelegate\n\n- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {\n  return UITableViewCellEditingStyleDelete;\n}\n\n#pragma mark - NIMutableTableViewModelDelegate\n\n- (BOOL)tableViewModel:(NIMutableTableViewModel *)tableViewModel\n         canEditObject:(id)object\n           atIndexPath:(NSIndexPath *)indexPath\n           inTableView:(UITableView *)tableView {\n  // We want every cell to be editable.\n  return YES;\n}\n\n- (BOOL)tableViewModel:(NIMutableTableViewModel *)tableViewModel\n    shouldDeleteObject:(id)object\n           atIndexPath:(NSIndexPath *)indexPath\n           inTableView:(UITableView *)tableView {\n  // We're going to store the index path that wants to be deleted so that we can delete the correct\n  // cell after the alert view has been dismissed.\n  self.indexPathForDeletion = indexPath;\n\n  // Rather than allow the model to simply delete the object, we're going to present a prompt that\n  // confirms with the user that they want to delete this object.\n  UIAlertView *confirmationAlertView = [[UIAlertView alloc] initWithTitle:@\"Confirm\" message:@\"Are you that sure you want to delete this cell?\" delegate:self cancelButtonTitle:@\"No\" otherButtonTitles:@\"Yes\", nil];\n  [confirmationAlertView show];\n  return NO;\n}\n\n- (UITableViewCell *)tableViewModel:(NITableViewModel *)tableViewModel\n                   cellForTableView:(UITableView *)tableView\n                        atIndexPath:(NSIndexPath *)indexPath\n                         withObject:(id)object {\n  return [NICellFactory tableViewModel:tableViewModel cellForTableView:tableView atIndexPath:indexPath withObject:object];\n}\n\n#pragma mark - UIAlertViewDelegate\n\n- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {\n  if (alertView.cancelButtonIndex != buttonIndex) {\n    // If the user hits \"OK\" then let's delete the object from the model.\n    NSArray *indexPaths = [self.model removeObjectAtIndexPath:self.indexPathForDeletion];\n\n    // And then notify the table view of the deletion.\n    [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];\n\n    // Now that we've deleted the object we no longer need this index path.\n    self.indexPathForDeletion = nil;\n  }\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/NestedRadioGroupTableModelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface NestedRadioGroupTableModelViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/NestedRadioGroupTableModelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NestedRadioGroupTableModelViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NIRadioGroup.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of using a nested radio group with a table view.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NIRadioGroup\n// NITableViewModel\n// NICellFactory\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\ntypedef enum {\n  RadioGroupOption1,\n  RadioGroupOption2,\n  RadioGroupOption3,\n} RadioGroup;\n\n@interface NestedRadioGroupTableModelViewController () <NIRadioGroupDelegate>\n@property (nonatomic, retain) NITableViewModel* model;\n@property (nonatomic, retain) NIRadioGroup* radioGroup;\n@end\n\n@implementation NestedRadioGroupTableModelViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"Nested Radio Group\";\n\n    _radioGroup = [[NIRadioGroup alloc] initWithController:self];\n    _radioGroup.delegate = self;\n\n    // The title that will be displayed in the radio group cell.\n    _radioGroup.cellTitle = @\"Selection\";\n\n    // The title that will be displayed in the nested radio group controller.\n    _radioGroup.controllerTitle = @\"Make a selection\";\n    \n    [_radioGroup mapObject:[NITitleCellObject objectWithTitle:@\"Option 1\"] toIdentifier:RadioGroupOption1];\n    [_radioGroup mapObject:[NITitleCellObject objectWithTitle:@\"Option 2\"] toIdentifier:RadioGroupOption2];\n    [_radioGroup mapObject:[NITitleCellObject objectWithTitle:@\"Option 3\"] toIdentifier:RadioGroupOption3];\n\n    NSArray* tableContents =\n    [NSArray arrayWithObjects:\n     // To create a nested radio group we simply add the radio group as an object in the model.\n     // NIRadioGroup implements the NICellObject protocol which allows us to do this.\n     _radioGroup,\n     nil];\n\n    _radioGroup.selectedIdentifier = RadioGroupOption2;\n\n    _model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                     delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n  \n  self.tableView.dataSource = self.model;\n  self.tableView.delegate = [self.radioGroup forwardingTo:self];\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n#pragma mark - NIRadioGroupDelegate\n\n- (void)radioGroup:(NIRadioGroup *)radioGroup didSelectIdentifier:(NSInteger)identifier {\n  // When the radio group selection changes, this method will be called with the new identifier.\n  NSLog(@\"Did select radio group option %zd\", identifier);\n}\n\n- (NSString *)radioGroup:(NIRadioGroup *)radioGroup textForIdentifier:(NSInteger)identifier {\n  switch (identifier) {\n    case RadioGroupOption1:\n      return @\"Option 1\";\n    case RadioGroupOption2:\n      return @\"Option 2\";\n    case RadioGroupOption3:\n      return @\"Option 3\";\n  }\n  return nil;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/NetworkBlockCellsViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface NetworkBlockCellsViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/NetworkBlockCellsViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NetworkBlockCellsViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NimbusNetworkImage.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of rendering table view cells with network images using blocks. This demo creates\n// a subclass of the NIDrawRectBlockCell and uses NINetworkImageView to download the image.\n//\n// You will find the following Nimbus features used:\n//\n// [networkimage]\n// NINetworkImageView\n//\n// [models]\n// NITableViewModel\n// NICellFactory\n// NIDrawRectBlockCell\n// NIDrawRectBlockCellObject\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n// This subclass of NIDrawRectBlockCell simply handles the fetching of an image from the network.\n// We use a network image view to do this, but we never add the network image view to the view\n// hierarchy because we are going to render the image in the cell block.\n@interface NetworkDrawRectBlockCell : NIDrawRectBlockCell <NINetworkImageViewDelegate>\n@property (nonatomic, retain) NINetworkImageView* networkImageView;\n@end\n\n@implementation NetworkDrawRectBlockCell\n\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {\n    _networkImageView = [[NINetworkImageView alloc] init];\n\n    // We implement the delegate so that we know when the image has finished downloading.\n    _networkImageView.delegate = self;\n  }\n  return self;\n}\n\n- (void)prepareForReuse {\n  [super prepareForReuse];\n\n  // This resets the networkImageView's .image to the initial image (in this case nil). Oftentimes\n  // the initial image will be a local \"empty\" avatar image that you've provided with your\n  // application.\n  [self.networkImageView prepareForReuse];\n}\n\n- (BOOL)shouldUpdateCellWithObject:(NIDrawRectBlockCellObject *)object {\n  [super shouldUpdateCellWithObject:object];\n\n  // Fetch the avatar from the network.\n  NSString* gravatarUrl = [NSString stringWithFormat:@\"http://www.gravatar.com/avatar/%@?s=140\", object.object];\n  // NINetworkImageView is smart enough to know that if we want to display an image at size 70x70\n  // on a retina display then it will crop the image to 140x140 and set the image scale to 2.\n  CGFloat imageSize = 70;\n  \n  // We explicitly set the display size of the network image so that when it is downloaded it gets\n  // cropped and resized accordingly. In this case we're fetching a 140x140 image from gravatar\n  // so there will be little work to do on retina displays, but older devices will need to resize\n  // the image to 70x70.\n  [self.networkImageView setPathToNetworkImage:gravatarUrl forDisplaySize:CGSizeMake(imageSize, imageSize)];\n\n  return YES;\n}\n\n#pragma mark - NINetworkImageViewDelegate\n\n- (void)networkImageView:(NINetworkImageView *)imageView didLoadImage:(UIImage *)image {\n  // Once the image has been downloaded we need to redraw the block.\n  [self.blockView setNeedsDisplay];\n}\n\n@end\n\n@interface NetworkBlockCellsViewController ()\n@property (nonatomic, retain) NITableViewModel* model;\n\n// We're going to override the default mapping of NIDrawRectBlockCellObject -> NIDrawRectBlockCell\n// so that we can display our subclassed version of NIDrawRectBlockCell with network images.\n// To do this we must create an instance of NICellFactory which we will be able to customize by\n// adding explicit mappings which will be used in preference of the implicit ones denoted by the\n// cell objects.\n@property (nonatomic, retain) NICellFactory* cellFactory;\n@end\n\n@implementation NetworkBlockCellsViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStylePlain])) {\n    self.title = @\"Network Block Cells\";\n\n    NICellDrawRectBlock drawTextBlock = ^CGFloat(CGRect rect, id object, UITableViewCell *cell) {\n      if (cell.isHighlighted || cell.isSelected) {\n        [[UIColor clearColor] set];\n      } else {\n        [[UIColor whiteColor] set];\n      }\n      UIRectFill(rect);\n\n      NSString* text = object;\n      [[UIColor blackColor] set];\n      UIFont* titleFont = [UIFont boldSystemFontOfSize:16];\n      [text drawAtPoint:CGPointMake(10, 5) withFont:titleFont];\n\n      // We know that we're using a network cell here, so we can safely cast without checking.\n      NetworkDrawRectBlockCell* networkCell = (NetworkDrawRectBlockCell *)cell;\n\n      // Grab the image and then draw it on the cell. If there is no image yet then the draw method\n      // will do nothing.\n      UIImage* image = networkCell.networkImageView.image;\n      [image drawAtPoint:CGPointMake(CGRectGetMaxX(rect) - image.size.width - 10, 5)];\n\n      return 0;\n    };\n\n    NSMutableArray* tableContents =\n    [NSMutableArray arrayWithObjects:\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"f3c8603c353afa79b9f1c77f35efd566\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"c28f6b282ad61bff6aa9aba06c62ad66\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"22f25c7b3f0f15a6854fae62bbd3482f\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"ec5d7ba9c004f79817c76146247e787e\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"832ece085bfe2c7c5b0ed6be62d7e675\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"2ea33a461b2c20894f62958bcd9a4fb2\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"430e340a391ff510825c61fb0f6ffeca\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"875412d23685f3a6f49fff1b927512cb\"],\n     nil];\n\n    // Set up our explicit mapping of NIDrawRectBlockCellObject -> NetworkDrawRectBlockCell.\n    _cellFactory = [[NICellFactory alloc] init];\n    [_cellFactory mapObjectClass:[NIDrawRectBlockCellObject class]\n                     toCellClass:[NetworkDrawRectBlockCell class]];\n\n    // Notice that we're passing the _cellFactory instance rather than (id)[NICellFactory class]\n    // now.\n    _model = [[NITableViewModel alloc] initWithListArray:tableContents\n                                                delegate:_cellFactory];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.tableView.rowHeight = 80;\n  self.tableView.dataSource = _model;\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/NibCellObject.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusCollections.h\"\n\n@interface NibCellObject : NSObject <NICollectionViewNibCellObject>\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/NibCellObject.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NibCellObject.h\"\n\n@implementation NibCellObject\n\n#pragma mark - NICollectionViewNibCellObject\n\n- (UINib *)collectionViewCellNib {\n  return [UINib nibWithNibName:@\"NimbusKitCell\" bundle:nil];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/NibCollectionModelViewController.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface NibCollectionModelViewController : UICollectionViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/NibCollectionModelViewController.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NibCollectionModelViewController.h\"\n\n#import \"NibCellObject.h\"\n\n#import \"NimbusCollections.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of creating a NICollectionViewModel and filling it with a list of objects that\n// will be displayed in a collection view.\n//\n// You will find the following Nimbus features used:\n//\n// [collections]\n// NICollectionViewModel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface NibCollectionModelViewController ()\n@property (nonatomic, strong) NICollectionViewModel* model;\n@end\n\n@implementation NibCollectionModelViewController\n\n- (id)initWithCollectionViewLayout:(UICollectionViewLayout *)layout {\n  if ((self = [super initWithCollectionViewLayout:layout])) {\n    self.title = @\"Nibs\";\n\n    NSArray* collectionContents =\n    @[\n      [[NibCellObject alloc] init],\n      [[NibCellObject alloc] init],\n    ];\n\n    _model = [[NICollectionViewModel alloc] initWithListArray:collectionContents\n                                                     delegate:(id)[NICollectionViewCellFactory class]];\n  }\n  return self;\n}\n\n- (id)init {\n  UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc] init];\n  flowLayout.itemSize = CGSizeMake(200, 200);\n  return [self initWithCollectionViewLayout:flowLayout];\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.collectionView.dataSource = _model;\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/NimbusCatalog-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>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>NSAppTransportSecurity</key>\n\t<dict>\n\t\t<key>NSExceptionDomains</key>\n\t\t<dict>\n\t\t\t<key>nimbuskit.info</key>\n\t\t\t<dict>\n\t\t\t\t<key>NSTemporaryExceptionMinimumTLSVersion</key>\n\t\t\t\t<string>TLSv1.1</string>\n\t\t\t\t<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>\n\t\t\t\t<true/>\n\t\t\t\t<key>NSIncludesSubdomains</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>staticflickr.com</key>\n\t\t\t<dict>\n\t\t\t\t<key>NSIncludesSubdomains</key>\n\t\t\t\t<true/>\n\t\t\t\t<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>\n\t\t\t\t<true/>\n\t\t\t\t<key>NSTemporaryExceptionMinimumTLSVersion</key>\n\t\t\t\t<string>TLSv1.1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</dict>\n\t<key>UILaunchStoryboardName</key>\n\t<string>Launch Screen</string>\n\t<key>UIPrerenderedIcon</key>\n\t<true/>\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\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "examples/catalog/Catalog/NimbusCatalog-Prefix.pch",
    "content": "//\n// Prefix header for all source files of the 'Catalog' target in the 'Catalog' project\n//\n\n#import <Availability.h>\n\n#ifndef __IPHONE_3_0\n#warning \"This project uses features only available in iOS SDK 3.0 and later.\"\n#endif\n\n#ifdef __OBJC__\n  #import <UIKit/UIKit.h>\n  #import <Foundation/Foundation.h>\n#endif\n"
  },
  {
    "path": "examples/catalog/Catalog/NimbusKitCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" colorMatched=\"YES\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <deployment version=\"1792\" identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14460.20\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <collectionViewCell opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" id=\"eig-34-YUy\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"100\" height=\"100\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <view key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"100\" height=\"100\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" fixedFrame=\"YES\" text=\"NimbusKit\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Pnw-LM-Lnv\">\n                        <rect key=\"frame\" x=\"10\" y=\"20\" width=\"80\" height=\"21\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                        <nil key=\"highlightedColor\"/>\n                    </label>\n                </subviews>\n            </view>\n            <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n            <size key=\"customSize\" width=\"138\" height=\"95\"/>\n        </collectionViewCell>\n    </objects>\n</document>\n"
  },
  {
    "path": "examples/catalog/Catalog/PerformanceAttributedLabelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface PerformanceAttributedLabelViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/PerformanceAttributedLabelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"PerformanceAttributedLabelViewController.h\"\n#import \"NimbusAttributedLabel.h\"\n\n//\n// What's going on in this file:\n//\n// This controller displays a remarkably large label with defered link autodetection. The goal\n// of this controller is to demonstrate the performance improvements of offloading automatic link\n// detection.\n//\n// You will find the following Nimbus features used:\n//\n// [attributedlabel]\n// NIAttributedLabel\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// CoreText.framework\n// QuartzCore.framework\n//\n\n@interface PerformanceAttributedLabelViewController()\n@property (nonatomic, retain) NIAttributedLabel* label;\n@property (nonatomic, retain) UIScrollView* scrollView;\n@end\n\n@implementation PerformanceAttributedLabelViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];\n  if (self) {\n    self.title = @\"Performance\";\n  }\n  return self;\n}\n\n- (void)_layoutLabel {\n  CGSize size = [self.label sizeThatFits:CGSizeMake(self.view.bounds.size.width - 40, CGFLOAT_MAX)];\n  self.label.frame = CGRectMake(20, 0, size.width, size.height);\n  self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.label.frame.size.height);\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  self.label = [[NIAttributedLabel alloc] initWithFrame:CGRectZero];\n  self.label.numberOfLines = 0;\n  self.label.lineBreakMode = NSLineBreakByWordWrapping;\n  self.label.font = [UIFont fontWithName:@\"Optima-Regular\" size:20];\n  self.label.autoDetectLinks = YES;\n  self.label.dataDetectorTypes = NSTextCheckingAllSystemTypes;\n\n  // When we enable defering the link detection is offloaded to a separate thread. This allows\n  // the label to display its text immediately and redraw itself once the links have been\n  // detected. For the block of text below this ends up displaying the text ~300ms faster on an\n  // iPhone 4S than it otherwise would have.\n  self.label.deferLinkDetection = YES;\n\n  // Add a ridiculous amount of text to the attributed label.\n  // http://hipsteripsum.me/\n  self.label.text = @\"Echo.com park farm-to-table irony, brooklyn raw denim elit mumblecore sapiente cliche nisi proident. Ennui fingerstache next level portland craft beer carles, leggings nostrud. 3 wolf moon kale chips twee elit, pork belly bicycle rights ut stumptown aesthetic. Culpa cred id beard. Sustainable fugiat aliqua, bespoke ullamco banh mi forage thundercats helvetica non farm-to-table chillwave esse sed organic. Pork belly cray irony, forage eiusmod ethnic hoodie brooklyn PBR cupidatat duis quinoa banh mi gentrify. Craft beer sustainable mlkshk, labore marfa deserunt yr put a bird on it ea aesthetic aute placeat.\"\n  @\"Tempor truffaut mumblecore pinterest cred locavore single-origin coffee, authentic pitchfork sapiente lo-fi. Nulla viral next level, consectetur nostrud voluptate ex skateboard butcher. Vice wolf anim etsy mustache. Single-origin coffee artisan 8-bit, minim delectus pariatur esse thundercats keffiyeh. Laboris fugiat swag carles terry richardson cillum, sustainable aute semiotics et. Whatever in irure, qui butcher ethical lo-fi. Trust fund PBR quinoa dolore salvia cosby sweater messenger bag tempor +1, magna lomo.\"\n  @\"Culpa flexitarian@gmail.com pour-over, high life PBR quis dreamcatcher tumblr next level. Id gentrify kale chips consectetur minim labore ennui, fixie thundercats mustache banh mi DIY laboris. Small batch carles aute, deserunt pariatur odio raw denim retro do nostrud street art chambray you probably haven't heard of them sed. Photo booth gentrify nihil, delectus retro bespoke ethical pork belly. 8-bit post-ironic mustache odd future umami et. Squid retro mumblecore, keytar sint swag brooklyn skateboard. Mcsweeney's esse fugiat, quinoa sriracha wayfarers tempor ethnic placeat jean shorts narwhal.\"\n  @\"Irure leggings nostrud adipisicing enim excepteur. Vinyl marfa labore cray, wes anderson echo park chambray carles retro veniam godard duis sint laborum. Minim ex exercitation pariatur leggings, occaecat aliqua dolore locavore. Est squid deserunt, godard ethical veniam gluten-free wolf aliqua VHS. Dreamcatcher nostrud dolore fap quinoa put a bird on it wayfarers, vinyl nulla. Photo booth farm-to-table enim fixie. Fanny pack beard salvia minim ethical aute, cred officia tofu vegan whatever helvetica mustache messenger bag.\"\n  @\"Nisi vegan portland.net assumenda narwhal 8-bit. Adipisicing keytar master cleanse proident, qui marfa wes anderson id gluten-free. Quis put a bird on it american apparel flexitarian bicycle rights cred. Truffaut veniam aliquip deserunt blog dolore. Vice pickled consectetur ad, velit selvage chillwave gluten-free keytar qui forage scenester. Delectus vero eiusmod pour-over occaecat, fanny pack excepteur mixtape. Forage post-ironic qui, assumenda magna gentrify in mcsweeney's banksy mollit eiusmod.\"\n  @\"Lomo hella mumblecore nostrud bicycle rights. Ethical hella aesthetic pickled dolore, officia leggings next level delectus. Sunt jean shorts officia shoreditch, biodiesel quinoa Austin keytar helvetica vegan forage bicycle rights cray esse small batch. Incididunt salvia echo park, ea esse synth laborum chillwave hella tempor enim. Vegan cliche incididunt kale chips nostrud terry richardson, mixtape VHS excepteur. Pop-up cosby sweater helvetica do. Viral gentrify brunch kale chips stumptown, tofu truffaut pariatur.\"\n  @\"Dolor kale chips ad semiotics, synth dolore labore scenester street art brunch occaecat jean shorts before they sold out echo park. Marfa pop-up quinoa, enim sriracha thundercats mcsweeney's wes anderson bespoke nihil occaecat adipisicing sapiente. Wolf freegan messenger bag lo-fi sartorial deserunt, ex sustainable minim american apparel master cleanse single-origin coffee. Fap sriracha pariatur, id fingerstache commodo culpa flexitarian irony shoreditch aute street art. Officia leggings elit, sapiente mlkshk umami placeat truffaut minim fanny pack. Artisan non sriracha, thundercats reprehenderit stumptown dolor messenger bag quis polaroid scenester officia williamsburg pour-over trust fund. Swag vegan craft beer etsy, seitan pickled commodo banksy wolf vinyl wayfarers marfa nihil brooklyn.\"\n  @\"Voluptate trust fund non beard.edu, cardigan pariatur before they sold out id craft beer post-ironic +1 helvetica laborum bespoke. Odd future helvetica keffiyeh, bicycle rights anim american apparel VHS hella magna nostrud tempor williamsburg godard. Et aute aliquip fap. Mixtape anim ennui, cardigan cupidatat velit terry richardson labore cliche food truck keffiyeh enim. Commodo flexitarian ullamco est cillum, 8-bit narwhal butcher four loko art party thundercats jean shorts salvia. In Austin small batch locavore. Farm-to-table DIY assumenda elit sed mlkshk, cray fugiat mcsweeney's minim duis.\"\n  @\"Kale chips wolf dreamcatcher scenester ex hella anim ad polaroid artisan. Incididunt vice polaroid cliche ut, viral jean shorts chillwave direct trade gastropub helvetica cupidatat. Art party cupidatat bicycle rights exercitation et elit. Reprehenderit polaroid vero, pariatur wolf semiotics forage ethical pitchfork velit. Jean shorts high life locavore, aliqua excepteur aliquip est ethical. Whatever irony pitchfork, do four loko lomo odio et american apparel. Terry richardson id viral, 3 wolf moon mlkshk nisi sartorial master cleanse officia irure readymade cardigan chambray street art.\"\n  @\"Excepteur minim pop-up, craft beer mixtape brooklyn raw denim gentrify brunch sed you probably haven't heard of them cliche voluptate photo booth. Forage marfa laboris portland mustache, reprehenderit wes anderson eu. Master cleanse godard organic post-ironic. Elit +1 est wes anderson qui cliche cardigan, non deserunt godard consectetur photo booth organic forage. Pickled fugiat sint consectetur williamsburg. Butcher sustainable readymade fap chambray, labore letterpress gluten-free 3 wolf moon gentrify vero qui mcsweeney's whatever. Dreamcatcher farm-to-table lo-fi nesciunt magna, hella reprehenderit messenger bag ullamco VHS tofu est.\";\n\n  self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];\n  self.scrollView.autoresizingMask =\n      (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  self.scrollView.contentInset = UIEdgeInsetsMake(20, 0, 20, 0);\n  [self.scrollView addSubview:self.label];\n  [self.view addSubview:self.scrollView];\n\n  [self _layoutLabel];\n}\n\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n\n  // When we rotate the device we need to recalculate how tall the scroll view should be.\n  [self _layoutLabel];\n}\n\n- (void)viewWillAppear:(BOOL)animated {\n  [super viewWillAppear:animated];\n\n  // If the controller is presented in landscape mode we need to ensure that we update the layout.\n  [self _layoutLabel];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/RadioGroupTableModelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface RadioGroupTableModelViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/RadioGroupTableModelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"RadioGroupTableModelViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NIRadioGroup.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of using a radio group with a table view simultaneously with table actions.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NIRadioGroup\n// NITableViewModel\n// NITableViewActions\n// NICellFactory\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\ntypedef enum {\n  RadioGroupOption1,\n  RadioGroupOption2,\n  RadioGroupOption3,\n} RadioGroup;\n\n@interface RadioGroupTableModelViewController () <NIRadioGroupDelegate>\n@end\n\n@implementation RadioGroupTableModelViewController {\n  NITableViewModel* _model;\n\n  // In order to implement the radio group we must create a radio group object. This object will\n  // maintain the state of the currently selected object. It will also handle all user interactions\n  // and updating the visual state of the cell when the selection changes.\n  NIRadioGroup* _radioGroup;\n\n  NITableViewActions* _actions;\n}\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"Radio Group\";\n\n    // When we create the radio group we must provide it with a reference to the parent controller.\n    // This allows the radio group to push new controllers onto the navigation controller when the\n    // radio group is added as an object in the table view model.\n    _radioGroup = [[NIRadioGroup alloc] initWithController:self];\n\n    // We want to be notified of changes to the radio group selection.\n    _radioGroup.delegate = self;\n\n    // We'll demonstrate how to use a radio group and actions simultaneously.\n    _actions = [[NITableViewActions alloc] initWithTarget:self];\n\n    // When we create the table contents we use the chaining pattern to create the table cell\n    // object, map it in the radio group to an identifier, and then add the object to the array.\n    // The radio group's mapObject:toIdentifier: method returns the given object which is what\n    // allows us to use this pattern.\n    NSArray* tableContents =\n    [NSArray arrayWithObjects:\n     [_actions attachToObject:[NITitleCellObject objectWithTitle:@\"Tap me\"] tapSelector:@selector(didTapObject:)],\n     [_radioGroup mapObject:[NITitleCellObject objectWithTitle:@\"Option 1\"] toIdentifier:RadioGroupOption1],\n     [_radioGroup mapObject:[NITitleCellObject objectWithTitle:@\"Option 2\"] toIdentifier:RadioGroupOption2],\n     [_radioGroup mapObject:[NITitleCellObject objectWithTitle:@\"Option 3\"] toIdentifier:RadioGroupOption3],\n     nil];\n\n    // The alternative method to initializing the radio group would look like this for each\n    // object:\n    //\n    //   NITitleCellObject* object1 = [NITitleCellObject objectWithTitle:@\"Option 1\"];\n    //   [_radioGroup mapObject:object1 toIdentifier:RadioGroupOption1];\n    //   [tableContents addObject:object1];\n    //\n\n    // We can only set the selected identifier once we've mapped an object in the radio group to\n    // the given identifier. Attempting to assign an identifier that hasn't been mapped will fire\n    // a debug assertion and then clear the selection.\n    _radioGroup.selectedIdentifier = RadioGroupOption2;\n\n    _model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                     delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n  \n  self.tableView.dataSource = _model;\n\n  // The radio group object implements a subset of the UITableViewDelegate methods and forwards all\n  // delegate methods along. This allows us to insert the radio group into the delegate chain and\n  // not have to implement any additional delegate methods in our controller.\n  //\n  // Experiment:\n  // Try removing this line. You will notice that the radio group no longer shows the current\n  // selection or allows you to select objects in the group.\n  //\n  // Note:\n  // In order to support actions and radio groups on the same delegate you must chain them in the\n  // following order: actions -> radio group -> self.\n  //\n  // The actions objects enforces the concept that only cells with attached actions should be\n  // actionable. The radio group implements its own actions and assigns them afterward. Finally self\n  // can override any of this functionality in its implementation of the table view delegate.\n  //\n  // Implementing the chain in the opposite order would cause the actions object to \"disable\" the\n  // radio group. You can try this for yourself to see the effect.\n  self.tableView.delegate = [_actions forwardingTo:[_radioGroup forwardingTo:self]];\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n#pragma mark - User Actions\n\n- (BOOL)didTapObject:(id)object {\n  NSLog(@\"Did tap object %@\", object);\n  return YES;\n}\n\n#pragma mark - NIRadioGroupDelegate\n\n- (void)radioGroup:(NIRadioGroup *)radioGroup didSelectIdentifier:(NSInteger)identifier {\n  // When the radio group selection changes, this method will be called with the new identifier.\n  NSLog(@\"Did select radio group option %zd\", identifier);\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/RestoringLauncherViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NimbusLauncher.h\"\n\n// All docs are in the .m.\n@interface RestoringLauncherViewController : NILauncherViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/RestoringLauncherViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"RestoringLauncherViewController.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n//\n// What's going on in this file:\n//\n// This controller shows how to save and restore a NILauncherViewModel to disk so that its state is\n// persisted across runs of the application and instances of the controller.\n//\n// You will find the following Nimbus features used:\n//\n// [core]\n// NIPathForDocumentsResource\n//\n// [launcher]\n// NILauncherViewController\n// NILauncherViewModel\n// NILauncherViewModelDelegate\n// NILauncherDataSource\n// NILauncherDelegate\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n// QuartzCore.framework\n//\n\n@interface RestoringLauncherViewController () <NILauncherViewModelDelegate>\n@property (nonatomic, retain) NILauncherViewModel* model;\n@end\n\n@implementation RestoringLauncherViewController\n\n\n// We provide a consistent way to fetch the path to the launcher data.\n- (NSString *)pathForLauncherData {\n  // NIPathForDocumentsResource is a handy method for getting a subpath within the user's documents\n  // directory.\n  return NIPathForDocumentsResource(@\"launcher\");\n}\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    self.title = @\"Restoring\";\n\n    // Get the path to the launcher data.\n    NSString* path = [self pathForLauncherData];\n\n    // And then try to load it. Keyed unarchiver makes this super easy because the\n    // NILauncherViewModel implements NSCoding.\n    _model = [NSKeyedUnarchiver unarchiveObjectWithFile:path];\n    if (nil == _model) {\n      // If model is nil that means we haven't saved any data to disk yet, so let's just create\n      // an empty model.\n      _model = [[NILauncherViewModel alloc] initWithArrayOfPages:nil delegate:nil];\n    }\n\n    // Assign the delegate regardless of how we create the model. The delegate isn't stored to disk\n    // because the delegate is simply a pointer to this controller and it is incredibly unlikely\n    // that the pointer would be identical between sessions.\n    _model.delegate = self;\n\n    self.navigationItem.rightBarButtonItem =\n    [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd\n                                                  target:self\n                                                  action:@selector(didTapAddButton:)];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n\n  self.view.backgroundColor = [UIColor whiteColor];\n\n  self.launcherView.dataSource = self.model;\n}\n\n#pragma mark - NILauncherViewModelDelegate\n\n- (void)launcherViewModel:(NILauncherViewModel *)launcherViewModel\n      configureButtonView:(UIView<NILauncherButtonView> *)buttonView\n          forLauncherView:(NILauncherView *)launcherView\n                pageIndex:(NSInteger)pageIndex\n              buttonIndex:(NSInteger)buttonIndex\n                   object:(id<NILauncherViewObject>)object {\n  NILauncherButtonView* launcherButtonView = (NILauncherButtonView *)buttonView;\n  \n  launcherButtonView.label.layer.shadowColor = [UIColor blackColor].CGColor;\n  launcherButtonView.label.layer.shadowOffset = CGSizeMake(0, 1);\n  launcherButtonView.label.layer.shadowOpacity = 1;\n  launcherButtonView.label.layer.shadowRadius = 1;\n}\n\n#pragma mark - NILauncherDelegate\n\n- (void)launcherView:(NILauncherView *)launcher didSelectItemOnPage:(NSInteger)page atIndex:(NSInteger)index {\n  id<NILauncherViewObject> object = [self.model objectAtIndex:index pageIndex:page];\n  UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@\"Notice\"\n                                                  message:[@\"Did tap button with title: \" stringByAppendingString:object.title]\n                                                 delegate:nil\n                                        cancelButtonTitle:@\"OK\"\n                                        otherButtonTitles:nil];\n  [alert show];\n}\n\n#pragma mark - User Actions\n\n- (void)didTapAddButton:(UIBarButtonItem *)barButtonItem {\n  NSString* imagePath = NIPathForBundleResource(nil, @\"Icon.png\");\n  UIImage* image = [[Nimbus imageMemoryCache] objectWithName:imagePath];\n  if (nil == image) {\n    image = [UIImage imageWithContentsOfFile:imagePath];\n    [[Nimbus imageMemoryCache] storeObject:image withName:imagePath];\n  }\n\n  NSInteger randomNumberOfItems = arc4random_uniform(8) + 1;\n  NSMutableArray* objects = [NSMutableArray array];\n  for (NSInteger ix = 0; ix < randomNumberOfItems; ++ix) {\n    [objects addObject:[NILauncherViewObject objectWithTitle:[NSString stringWithFormat:@\"Nimbus %d\", arc4random_uniform(1000)] image:image]];\n  }\n\n  [self.model appendPage:objects];\n  [self.launcherView reloadData];\n\n  // One-line save to disk! So sexy. If we were worried about performance in any way we might do\n  // this only when the app is about to shut down or periodically on a background thread. For the\n  // purposes of this example that would be overkill.\n  [NSKeyedArchiver archiveRootObject:self.model toFile:[self pathForLauncherData]];\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/SamplePageView.h",
    "content": "//\n// Copyright 2012 Manu Cornet\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <UIKit/UIKit.h>\n\n#import \"NimbusPagingScrollView.h\"\n\n// This is the page view object that will be displayed for each page of the paging scroll view.\n// Pages that will be displayed in a NIPagingScrollView must implement the NIPagingScrollViewPage\n// protocol.\n@interface SamplePageView : UIView <NIPagingScrollViewPage>\n@property (nonatomic, retain) UILabel* label;\n- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier;\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/SamplePageView.m",
    "content": "//\n// Copyright 2012 Manu Cornet\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"SamplePageView.h\"\n\n@implementation SamplePageView\n\n@synthesize pageIndex = _pageIndex;\n@synthesize reuseIdentifier = _reuseIdentifier;\n\n- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithFrame:CGRectZero])) {\n    _label = [[UILabel alloc] initWithFrame:self.bounds];\n    _label.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n    _label.font = [UIFont systemFontOfSize:26];\n    _label.textAlignment = NSTextAlignmentCenter;\n    _label.backgroundColor = [UIColor clearColor];\n    \n    [self addSubview:_label];\n      \n    self.reuseIdentifier = reuseIdentifier;\n  }\n  return self;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  return [self initWithReuseIdentifier:nil];\n}\n\n- (void)setPageIndex:(NSInteger)pageIndex {\n  _pageIndex = pageIndex;\n  \n  self.label.text = [NSString stringWithFormat:@\"This is page %zd\", pageIndex];\n  \n  UIColor* bgColor;\n  UIColor* textColor;\n  // Change the background and text color depending on the index.\n  switch (pageIndex % 4) {\n    case 0:\n      bgColor = [UIColor redColor];\n      textColor = [UIColor whiteColor];\n      break;\n    case 1:\n      bgColor = [UIColor blueColor];\n      textColor = [UIColor whiteColor];\n      break;\n    case 2:\n      bgColor = [UIColor yellowColor];\n      textColor = [UIColor blackColor];\n      break;\n    case 3:\n      bgColor = [UIColor greenColor];\n      textColor = [UIColor blackColor];\n      break;\n  }\n  \n  self.backgroundColor = bgColor;\n  self.label.textColor = textColor;\n  \n  [self setNeedsLayout];\n}\n\n- (void)prepareForReuse {\n  self.label.text = nil;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/SectionedTableModelViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface SectionedTableModelViewController : UITableViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/SectionedTableModelViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"SectionedTableModelViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This is a demo of creating a NITableViewModel with a sectioned group of objects.\n//\n// You will find the following Nimbus features used:\n//\n// [models]\n// NITableViewModel\n// NICellFactory\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n@interface SectionedTableModelViewController ()\n@property (nonatomic, retain) NITableViewModel* model;\n@end\n\n@implementation SectionedTableModelViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    self.title = @\"Sectioned Model\";\n\n    NSArray* tableContents =\n    [NSArray arrayWithObjects:\n     // If the table contents starts with an object instead of a string then the first section\n     // will not have a section header.\n     //\n     // Experiment:\n     // Try uncommenting the following line to add a section header to the first section.\n     //\n     // @\"Section Header\",\n     [NITitleCellObject objectWithTitle:@\"First section\"],\n\n     // Each time an NSString is encountered in the table contents a new section will begin. All\n     // proceeding objects will be part of this section until another NSString is encountered.\n     @\"Section with rows\",\n     [NITitleCellObject objectWithTitle:@\"Row\"],\n     [NITitleCellObject objectWithTitle:@\"Row\"],\n     [NITitleCellObject objectWithTitle:@\"Row\"],\n\n     // It is also possible to create sections without any rows by following one NSString with\n     // another NSString.\n     @\"Section without any rows\",\n\n     // This NSString will close off the previous section.\n     @\"Another section\",\n     [NITitleCellObject objectWithTitle:@\"Row\"],\n\n     // To start a new group without providing a section header you use an empty string.\n     @\"\",\n     [NITitleCellObject objectWithTitle:@\"This section has no header\"],\n     [NITitleCellObject objectWithTitle:@\"Row\"],\n     nil];\n\n    // We want to treat the table contents as a sectioned array, so we use\n    // initWithSectionedArray:delegate: here.\n    _model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                     delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.tableView.dataSource = _model;\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/SnapshotRotationTableViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface SnapshotRotationTableViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/SnapshotRotationTableViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"SnapshotRotationTableViewController.h\"\n\n#import \"NimbusModels.h\"\n#import \"NimbusNetworkImage.h\"\n#import \"NimbusCore.h\"\n\n//\n// What's going on in this file:\n//\n// This controller demos how to use the snapshot rotation feature of Nimbus' core. This feature only\n// works on iOS 6 and higher. This controller is a UIViewController but it adds a UITableView in\n// order to demo snapshot rotation for table views.\n//\n// Snapshot rotation is the act of taking two snapshots of a view controller's initial and final\n// states, respectively, and then cross-fading between them during the rotation. This is\n// specifically useful for block rendered cells because otherwise the cells get stretched awkwardly\n// during the rotation.\n//\n// Note: to see snapshot rotations you should enable Slow Animations via the \"Debug\" menu of the\n// simulator.\n//\n// You will find the following Nimbus features used:\n//\n// [core]\n// NISnapshotRotation\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\n// NISnapshotRotation requires that we implement the NISnapshotRotationDelegate protocol for its\n// delegate.\n@interface SnapshotRotationTableViewController () <UITableViewDelegate, NISnapshotRotationDelegate>\n\n// UITableViewController's self.view == self.tableView, but for snapshot rotation to work we must\n// ensure that the container view is not equivalent to the rotating view. To solve this we simply\n// don't subclass UITableViewController and instead implement the basic UITableViewController\n// functionality ourselves.\n@property (nonatomic, retain) UITableView* tableView;\n\n// In order to implement snapshot rotations we must create a snapshot rotation object and keep it\n// around at least for the duration of the rotation. In this example we create the snapshot rotation\n// object during initialization and just keep it around forever. If you wanted to save memory you\n// could create the rotation object when a rotation is about to begin and then release it when the\n// rotation completes.\n@property (nonatomic, retain) NISnapshotRotation* snapshotRotation;\n\n@property (nonatomic, retain) NITableViewModel* model;\n@property (nonatomic, retain) NITableViewActions* actions;\n@end\n\n@implementation SnapshotRotationTableViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nil bundle:nil])) {\n    self.title = @\"Snapshot Rotation\";\n\n    // We must provide the snapshot rotation object a delegate so that it knows which view to\n    // snapshot rotate.\n    // Note here that we're creating a NITableViewSnapshotRotation version of NISnapshotRotation.\n    // This subclass of NISnapshotRotation handles UITableViews specifically by creating a resizing\n    // snapshot that cuts off along a vertical line between the contentView and the accessoryView.\n    // The standard NISnapshotRotation object, on the other hand, will simply snapshot the entire\n    // rotating view without a vertical divider.\n    _snapshotRotation = [[NITableViewSnapshotRotation alloc] initWithDelegate:self];\n\n    NICellDrawRectBlock drawTextBlock = ^CGFloat(CGRect rect, id object, UITableViewCell *cell) {\n      if (cell.isHighlighted || cell.isSelected) {\n        [[UIColor clearColor] set];\n      } else {\n        [[UIColor whiteColor] set];\n      }\n      UIRectFill(rect);\n      \n      NSString* text = object;\n      [[UIColor blackColor] set];\n      UIFont* titleFont = [UIFont boldSystemFontOfSize:16];\n      CGFloat titleWidth = rect.size.width - 20;\n\n      // We're drawing variable height cells in this example to show how the table view smoothly\n      // animates between the two very different states of the table view.\n      CGSize size = [text sizeWithFont:titleFont constrainedToSize:CGSizeMake(titleWidth, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];\n      if (nil != cell) {\n        [text drawInRect:CGRectMake(10, 5, size.width, size.height) withFont:titleFont lineBreakMode:NSLineBreakByWordWrapping];\n      }\n\n      return size.height + 10;\n    };\n\n    NSMutableArray* tableContents =\n    [NSMutableArray arrayWithObjects:\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a cell with a large amount of text that is going to wrap over multiple lines.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a short label.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a cell with a large amount of text that is going to wrap over multiple lines.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a cell with a large amount of text that is going to wrap over multiple lines.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a short label.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a cell with a large amount of text that is going to wrap over multiple lines.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a cell with a large amount of text that is going to wrap over multiple lines.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a short label.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a cell with a large amount of text that is going to wrap over multiple lines.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a cell with a large amount of text that is going to wrap over multiple lines.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a short label.\"],\n     [NIDrawRectBlockCellObject objectWithBlock:drawTextBlock object:@\"This is a cell with a large amount of text that is going to wrap over multiple lines.\"],\n     nil];\n\n    _model = [[NITableViewModel alloc] initWithListArray:tableContents\n                                                delegate:(id)[NICellFactory class]];\n\n    // We give every cell an action that pushes to the same controller purely so that we can show\n    // how the accessory indicators react to snapshot rotations.\n    //\n    // Experiment: try changing the action type to attachDetailAction to see what snapshot rotation\n    // looks like with larger accessory types.\n    _actions = [[NITableViewActions alloc] initWithTarget:self];\n    [_actions attachToClass:[NIDrawRectBlockCellObject class]\n            navigationBlock:NIPushControllerAction([self class])];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // This is standard UITableView instantiation. It's effectively what UITableViewController does\n  // in loadView, except we're adding the table view to self.view rather than assigning it to\n  // self.view.\n  self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];\n  self.tableView.autoresizingMask =\n      (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  [self.view addSubview:self.tableView];\n\n  self.tableView.delegate = [self.actions forwardingTo:self];\n  self.tableView.dataSource = _model;\n}\n\n- (void)viewWillAppear:(BOOL)animated {\n  [super viewWillAppear:animated];\n\n  // When the controller first appears we want to ensure that the table view shows its data.\n  // The self.view here ensures that we load the table view first.\n  if (self.view && self.tableView.numberOfSections == 0) {\n    [self.tableView reloadData];\n  }\n\n  // When this controller appears we want to deselect whatever cell was previously selected. This\n  // logic also comes for free with UITableViewController, so we make sure to include it here as\n  // well.\n  NSIndexPath* selectedRow = self.tableView.indexPathForSelectedRow;\n  if (nil != selectedRow) {\n    [self.tableView deselectRowAtIndexPath:selectedRow animated:animated];\n  }\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n// The following three methods MUST all be forwarded to the snapshot rotation object in order for\n// it to function correctly.\n- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n  [self.snapshotRotation willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n}\n\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n  [self.snapshotRotation willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n}\n\n- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {\n  [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];\n  [self.snapshotRotation didRotateFromInterfaceOrientation:fromInterfaceOrientation];\n}\n\n#pragma mark - UITableViewDelegate\n\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {\n  // We ask each block to calculate its size in order to create variable-height block cells.\n  NIDrawRectBlockCellObject *object = [self.model objectAtIndexPath:indexPath];\n  return object.block(self.tableView.bounds, object.object, nil);\n}\n\n// The following implementation of NISnapshotRotationDelegate is why we need to ensure that\n// self.view != self.tableView. Essentially what's going on in the background is NISnapshotRotation\n// takes a snapshot of the rotating view in its initial and final rotation state, removes the\n// rotating view from the hierarchy and crossfades between the two images. Once the animation\n// completes we add the rotating view back to the container.\n#pragma mark - NISnapshotRotationDelegate\n\n- (UIView *)containerViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation {\n  return self.view;\n}\n\n- (UIView *)rotatingViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation {\n  return self.tableView;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/VerticalPagingScrollViewController.h",
    "content": "//\n// Copyright 2012 Manu Cornet\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import <UIKit/UIKit.h>\n\n// All docs are in the .m.\n@interface VerticalPagingScrollViewController : UIViewController\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/VerticalPagingScrollViewController.m",
    "content": "//\n// Copyright 2012 Manu Cornet\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#import \"VerticalPagingScrollViewController.h\"\n\n#import \"SamplePageView.h\"\n#import \"NimbusPagingScrollView.h\"\n\n//\n// What's going on in this file:\n//\n// This controller demonstrates how to create a vertical paging scroll view by simply changing the\n// type of the paging scroll view instance to NIPagingScrollViewVertical.\n//\n// You will find the following Nimbus features used:\n//\n// [pagingscrollview]\n// NIPagingScrollView\n// NIPagingScrollViewDataSource\n//\n// This controller requires the following frameworks:\n//\n// Foundation.framework\n// UIKit.framework\n//\n\nstatic NSString* const kPageReuseIdentifier = @\"SamplePageIdentifier\";\n\n@interface VerticalPagingScrollViewController () <NIPagingScrollViewDataSource>\n@property (nonatomic, retain) NIPagingScrollView* pagingScrollView;\n@end\n\n@implementation VerticalPagingScrollViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    self.title = @\"Vertical Scroll View\";\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  // iOS 7-only.\n  if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {\n    self.edgesForExtendedLayout = UIRectEdgeNone;\n  }\n  self.view.backgroundColor = [UIColor blackColor];\n\n  self.pagingScrollView = [[NIPagingScrollView alloc] initWithFrame:self.view.bounds];\n\n  // This is the only change from the BasicInstantiation example.\n  self.pagingScrollView.type = NIPagingScrollViewVertical;\n\n  self.pagingScrollView.autoresizingMask =\n      (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  self.pagingScrollView.dataSource = self;\n  [self.view addSubview:self.pagingScrollView];\n  [self.pagingScrollView reloadData];\n}\n\n- (void)didReceiveMemoryWarning {\n  self.pagingScrollView = nil;\n  \n  [super didReceiveMemoryWarning];\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation\n                                duration:(NSTimeInterval)duration {\n  [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n\n  [self.pagingScrollView willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n}\n\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation\n                                         duration:(NSTimeInterval)duration {\n  [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n\n  [self.pagingScrollView willAnimateRotationToInterfaceOrientation:toInterfaceOrientation\n                                                          duration:duration];\n}\n\n#pragma mark - NIPagingScrollViewDataSource\n\n- (NSInteger)numberOfPagesInPagingScrollView:(NIPagingScrollView *)pagingScrollView {\n  return 10;\n}\n\n- (UIView<NIPagingScrollViewPage> *)pagingScrollView:(NIPagingScrollView *)pagingScrollView\n                                    pageViewForIndex:(NSInteger)pageIndex {\n  SamplePageView *page = (SamplePageView *)[pagingScrollView dequeueReusablePageWithIdentifier:kPageReuseIdentifier];\n  if (nil == page) {\n    page = [[SamplePageView alloc] initWithReuseIdentifier:kPageReuseIdentifier];\n  }\n  return page;\n}\n\n@end\n"
  },
  {
    "path": "examples/catalog/Catalog/en.lproj/InfoPlist.strings",
    "content": "/* Localized versions of Info.plist keys */\n\n"
  },
  {
    "path": "examples/catalog/Catalog/main.m",
    "content": "//\n// Copyright 2011-2012 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n#import \"AppDelegate.h\"\n\nint main(int argc, char *argv[]) {\n  @autoreleasepool {\n    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n  }\n}\n"
  },
  {
    "path": "examples/catalog/Launch Screen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13142\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"12042\"/>\n        <capability name=\"Constraints with non-1.0 multipliers\" minToolsVersion=\"5.1\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Copyright © 2019 Nimbus. All rights reserved.\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"9\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"obG-Y5-kRd\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"626.5\" width=\"375\" height=\"20.5\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                            <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Nimbus\" textAlignment=\"center\" lineBreakMode=\"middleTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"18\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"GJd-Yh-RWb\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"202\" width=\"375\" height=\"43\"/>\n                                <fontDescription key=\"fontDescription\" type=\"boldSystem\" pointSize=\"36\"/>\n                                <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstItem=\"Bcu-3y-fUS\" firstAttribute=\"centerX\" secondItem=\"obG-Y5-kRd\" secondAttribute=\"centerX\" id=\"5cz-MP-9tL\"/>\n                            <constraint firstItem=\"Bcu-3y-fUS\" firstAttribute=\"centerX\" secondItem=\"GJd-Yh-RWb\" secondAttribute=\"centerX\" id=\"Q3B-4B-g5h\"/>\n                            <constraint firstItem=\"obG-Y5-kRd\" firstAttribute=\"leading\" secondItem=\"Bcu-3y-fUS\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"SfN-ll-jLj\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"obG-Y5-kRd\" secondAttribute=\"bottom\" constant=\"20\" id=\"Y44-ml-fuU\"/>\n                            <constraint firstItem=\"GJd-Yh-RWb\" firstAttribute=\"centerY\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"bottom\" multiplier=\"1/3\" constant=\"1\" id=\"moa-c2-u7t\"/>\n                            <constraint firstItem=\"GJd-Yh-RWb\" firstAttribute=\"leading\" secondItem=\"Bcu-3y-fUS\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"x7j-FC-K8j\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"Bcu-3y-fUS\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "examples/catalog/NimbusCatalog.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\t2B960E8415AE41FC005714CA /* navigationbar.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B960E8315AE41FC005714CA /* navigationbar.png */; };\n\t\t3616212C16812222002A9078 /* AlignmentAttributedLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3616212A16812222002A9078 /* AlignmentAttributedLabelViewController.m */; };\n\t\t3616212D16812222002A9078 /* AlignmentAttributedLabelViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3616212B16812222002A9078 /* AlignmentAttributedLabelViewController.xib */; };\n\t\t44707C77159B06A700B83149 /* BasicInstantiationPagingScrollViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 44707C76159B06A000B83149 /* BasicInstantiationPagingScrollViewController.m */; };\n\t\t5CAE32622222514F0055EC24 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CAE32612222514F0055EC24 /* MobileCoreServices.framework */; };\n\t\t660C6F2915992B2500209EB3 /* BadgedLauncherButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 660C6F2815992B2500209EB3 /* BadgedLauncherButtonView.m */; };\n\t\t6613335E15D3A66B00369333 /* SnapshotRotationTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6613335D15D3A66B00369333 /* SnapshotRotationTableViewController.m */; };\n\t\t6617AF2018A8138500037E75 /* NibCollectionModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AF1F18A8138500037E75 /* NibCollectionModelViewController.m */; };\n\t\t6617AF2318A813FC00037E75 /* NibCellObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AF2218A813FC00037E75 /* NibCellObject.m */; };\n\t\t6617AF2518A817D600037E75 /* CustomTextCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6617AF2418A817D600037E75 /* CustomTextCell.xib */; };\n\t\t6617AF2818A8188000037E75 /* CustomNibCollectionModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AF2718A8188000037E75 /* CustomNibCollectionModelViewController.m */; };\n\t\t6617AF2B18A8189D00037E75 /* CustomTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AF2A18A8189D00037E75 /* CustomTextCell.m */; };\n\t\t6617B06418A9102A00037E75 /* NIImageResponseSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617B06118A9100500037E75 /* NIImageResponseSerializer.m */; };\n\t\t661B9AB615AFF9DC00B743F1 /* NetworkBlockCellsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 661B9AB515AFF9DC00B743F1 /* NetworkBlockCellsViewController.m */; };\n\t\t661F28EE159292B800D11FC3 /* BasicInstantiationBadgeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 661F28ED159292B800D11FC3 /* BasicInstantiationBadgeViewController.m */; };\n\t\t661F28F3159292E800D11FC3 /* NIBadgeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 661F28F1159292E800D11FC3 /* NIBadgeView.m */; };\n\t\t661F28F6159299C900D11FC3 /* CustomizingBadgesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 661F28F5159299C900D11FC3 /* CustomizingBadgesViewController.m */; };\n\t\t661F293215929E2300D11FC3 /* InterfaceBuilderBadgeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 661F293015929E2300D11FC3 /* InterfaceBuilderBadgeViewController.m */; };\n\t\t661F293315929E2300D11FC3 /* ApplicationBadges.xib in Resources */ = {isa = PBXBuildFile; fileRef = 661F293115929E2300D11FC3 /* ApplicationBadges.xib */; };\n\t\t6633C7EF158F08A40054D240 /* InterfaceBuilderAttributedLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6633C7EE158F08A40054D240 /* InterfaceBuilderAttributedLabelViewController.m */; };\n\t\t6633C7F2158F08EA0054D240 /* AttributedLabelMashup.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6633C7F1158F08EA0054D240 /* AttributedLabelMashup.xib */; };\n\t\t6633D21F15DDBD4100A4B07E /* ImagesAttributedLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6633D21E15DDBD4100A4B07E /* ImagesAttributedLabelViewController.m */; };\n\t\t664D94AF22731A1C00A2F6A5 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 664D94AE22731A1C00A2F6A5 /* Launch Screen.storyboard */; };\n\t\t66559AFA15C8BE6800ED9047 /* ActionsTableModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66559AF915C8BE6800ED9047 /* ActionsTableModelViewController.m */; };\n\t\t66559AFE15CC3F9B00ED9047 /* ModalRadioGroupTableModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66559AFD15CC3F9B00ED9047 /* ModalRadioGroupTableModelViewController.m */; };\n\t\t6658C38B18A910820080B319 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6658C38A18A910820080B319 /* SystemConfiguration.framework */; };\n\t\t6658C38D18A910860080B319 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6658C38C18A910860080B319 /* Security.framework */; };\n\t\t6677FEBD15AB8A0300517ABC /* BasicInstantiationTableModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6677FEBC15AB8A0300517ABC /* BasicInstantiationTableModelViewController.m */; };\n\t\t6677FEDC15AB96BF00517ABC /* SectionedTableModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6677FEDB15AB96BF00517ABC /* SectionedTableModelViewController.m */; };\n\t\t6677FEE015ABA9A300517ABC /* IndexedTableModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6677FEDF15ABA9A300517ABC /* IndexedTableModelViewController.m */; };\n\t\t6677FEE315ABACC500517ABC /* FormCellCatalogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6677FEE215ABACC500517ABC /* FormCellCatalogViewController.m */; };\n\t\t6677FEE515AC8D1600517ABC /* circle.png in Resources */ = {isa = PBXBuildFile; fileRef = 6677FEE415AC8D1600517ABC /* circle.png */; };\n\t\t6677FEE715AC8D1C00517ABC /* star.png in Resources */ = {isa = PBXBuildFile; fileRef = 6677FEE615AC8D1C00517ABC /* star.png */; };\n\t\t6677FEEA15AC92C800517ABC /* RadioGroupTableModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6677FEE915AC92C800517ABC /* RadioGroupTableModelViewController.m */; };\n\t\t6677FEED15ACA60400517ABC /* NestedRadioGroupTableModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6677FEEC15ACA60400517ABC /* NestedRadioGroupTableModelViewController.m */; };\n\t\t668B766F15938C8400EA86F6 /* ExtraActionsWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B766E15938C8400EA86F6 /* ExtraActionsWebViewController.m */; };\n\t\t668B7673159394A200EA86F6 /* BasicInstantiationNetworkImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B7672159394A200EA86F6 /* BasicInstantiationNetworkImageViewController.m */; };\n\t\t668B767B159394EF00EA86F6 /* NIImageProcessing.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B7678159394EF00EA86F6 /* NIImageProcessing.m */; };\n\t\t668B767C159394EF00EA86F6 /* NINetworkImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B767A159394EF00EA86F6 /* NINetworkImageView.m */; };\n\t\t668EA9C417206F640056C8C3 /* NIActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 668EA9C217206F640056C8C3 /* NIActions.m */; };\n\t\t6692F58F159920E200FA074E /* BadgedLauncherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6692F58E159920E200FA074E /* BadgedLauncherViewController.m */; };\n\t\t6693C0F0158A63E600950D42 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6693C0EF158A63E600950D42 /* UIKit.framework */; };\n\t\t6693C0F2158A63E600950D42 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6693C0F1158A63E600950D42 /* Foundation.framework */; };\n\t\t6693C0F4158A63E600950D42 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6693C0F3158A63E600950D42 /* CoreGraphics.framework */; };\n\t\t6693C0FA158A63E600950D42 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6693C0F8158A63E600950D42 /* InfoPlist.strings */; };\n\t\t6693C0FC158A63E600950D42 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C0FB158A63E600950D42 /* main.m */; };\n\t\t6693C100158A63E600950D42 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C0FF158A63E600950D42 /* AppDelegate.m */; };\n\t\t6693C1D3158A80A000950D42 /* CatalogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1D2158A80A000950D42 /* CatalogViewController.m */; };\n\t\t6693C202158A81D300950D42 /* NICommonMetrics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1D6158A81D300950D42 /* NICommonMetrics.m */; };\n\t\t6693C204158A81D300950D42 /* NIDebuggingTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1DA158A81D300950D42 /* NIDebuggingTools.m */; };\n\t\t6693C205158A81D300950D42 /* NIDeviceOrientation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1DC158A81D300950D42 /* NIDeviceOrientation.m */; };\n\t\t6693C206158A81D300950D42 /* NIError.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1DE158A81D300950D42 /* NIError.m */; };\n\t\t6693C207158A81D300950D42 /* NIFoundationMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1E0158A81D300950D42 /* NIFoundationMethods.m */; };\n\t\t6693C208158A81D300950D42 /* NIInMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1E2158A81D300950D42 /* NIInMemoryCache.m */; };\n\t\t6693C20A158A81D300950D42 /* NINetworkActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1E9158A81D300950D42 /* NINetworkActivity.m */; };\n\t\t6693C20B158A81D300950D42 /* NINonEmptyCollectionTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1EB158A81D300950D42 /* NINonEmptyCollectionTesting.m */; };\n\t\t6693C20C158A81D300950D42 /* NINonRetainingCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1ED158A81D300950D42 /* NINonRetainingCollections.m */; };\n\t\t6693C20D158A81D400950D42 /* NIOperations.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1EF158A81D300950D42 /* NIOperations.m */; };\n\t\t6693C20E158A81D400950D42 /* NIPaths.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1F2158A81D300950D42 /* NIPaths.m */; };\n\t\t6693C20F158A81D400950D42 /* NIRuntimeClassModifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1F5158A81D300950D42 /* NIRuntimeClassModifications.m */; };\n\t\t6693C210158A81D400950D42 /* NISDKAvailability.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1F7158A81D300950D42 /* NISDKAvailability.m */; };\n\t\t6693C211158A81D400950D42 /* NIState.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1F9158A81D300950D42 /* NIState.m */; };\n\t\t6693C212158A81D400950D42 /* NIViewRecycler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C1FB158A81D300950D42 /* NIViewRecycler.m */; };\n\t\t6693C227158A81DD00950D42 /* NICellCatalog.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C217158A81DD00950D42 /* NICellCatalog.m */; };\n\t\t6693C228158A81DD00950D42 /* NICellFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C219158A81DD00950D42 /* NICellFactory.m */; };\n\t\t6693C229158A81DD00950D42 /* NIFormCellCatalog.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C21B158A81DD00950D42 /* NIFormCellCatalog.m */; };\n\t\t6693C22A158A81DD00950D42 /* NIRadioGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C21F158A81DD00950D42 /* NIRadioGroup.m */; };\n\t\t6693C22B158A81DD00950D42 /* NIRadioGroupController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C221158A81DD00950D42 /* NIRadioGroupController.m */; };\n\t\t6693C22C158A81DD00950D42 /* NITableViewActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C223158A81DD00950D42 /* NITableViewActions.m */; };\n\t\t6693C22D158A81DD00950D42 /* NITableViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C225158A81DD00950D42 /* NITableViewModel.m */; };\n\t\t6693C299158A8E4000950D42 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 6693C290158A8E4000950D42 /* Default.png */; };\n\t\t6693C29A158A8E4000950D42 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6693C291158A8E4000950D42 /* Default@2x.png */; };\n\t\t6693C29B158A8E4000950D42 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 6693C292158A8E4000950D42 /* Icon-72.png */; };\n\t\t6693C29C158A8E4000950D42 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 6693C293158A8E4000950D42 /* Icon-Small-50.png */; };\n\t\t6693C29D158A8E4000950D42 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 6693C294158A8E4000950D42 /* Icon-Small.png */; };\n\t\t6693C29E158A8E4000950D42 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6693C295158A8E4000950D42 /* Icon-Small@2x.png */; };\n\t\t6693C29F158A8E4000950D42 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 6693C296158A8E4000950D42 /* Icon.png */; };\n\t\t6693C2A0158A8E4000950D42 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6693C297158A8E4000950D42 /* Icon@2x.png */; };\n\t\t6693C2E8158AA21E00950D42 /* NIAttributedLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C2E3158AA21E00950D42 /* NIAttributedLabel.m */; };\n\t\t6693C2E9158AA21E00950D42 /* NSMutableAttributedString+NimbusAttributedLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C2E7158AA21E00950D42 /* NSMutableAttributedString+NimbusAttributedLabel.m */; };\n\t\t6693C2EB158AA2BF00950D42 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6693C2EA158AA2BE00950D42 /* CoreText.framework */; };\n\t\t6693C2EE158AB5B600950D42 /* CustomTextAttributedLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C2ED158AB5B600950D42 /* CustomTextAttributedLabelViewController.m */; };\n\t\t6693EFED18A7293700A600A0 /* BasicInstantiationCollectionModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693EFEC18A7293700A600A0 /* BasicInstantiationCollectionModelViewController.m */; };\n\t\t6693EFFA18A7A34A00A600A0 /* NICollectionViewActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693EFF018A7A34A00A600A0 /* NICollectionViewActions.m */; };\n\t\t6693EFFB18A7A34A00A600A0 /* NICollectionViewCellFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693EFF218A7A34A00A600A0 /* NICollectionViewCellFactory.m */; };\n\t\t6693EFFC18A7A34A00A600A0 /* NICollectionViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693EFF418A7A34A00A600A0 /* NICollectionViewModel.m */; };\n\t\t6693EFFD18A7A34A00A600A0 /* NIMutableCollectionViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693EFF818A7A34A00A600A0 /* NIMutableCollectionViewModel.m */; };\n\t\t6693F00118A7A40A00A600A0 /* ColorCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693F00018A7A40A00A600A0 /* ColorCell.m */; };\n\t\t6693F00618A7B0B900A600A0 /* NimbusKitCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6693F00518A7B0B900A600A0 /* NimbusKitCell.xib */; };\n\t\t669819DF159B953A00C2D3EF /* NISnapshotRotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 669819DE159B953A00C2D3EF /* NISnapshotRotation.m */; };\n\t\t669A15CD158D318B00A0990A /* LinksAttributedLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 669A15CC158D318B00A0990A /* LinksAttributedLabelViewController.m */; };\n\t\t669A15D0158D38E700A0990A /* BasicInstantiationAttributedLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 669A15CF158D38E700A0990A /* BasicInstantiationAttributedLabelViewController.m */; };\n\t\t669A15D3158E6C7C00A0990A /* DataTypesAttributedLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 669A15D2158E6C7C00A0990A /* DataTypesAttributedLabelViewController.m */; };\n\t\t669A15D6158E81D200A0990A /* PerformanceAttributedLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 669A15D5158E81D200A0990A /* PerformanceAttributedLabelViewController.m */; };\n\t\t66A29F8B1595080E00F6EA64 /* NILauncherButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A29F831595080E00F6EA64 /* NILauncherButtonView.m */; };\n\t\t66A29F8D1595080E00F6EA64 /* NILauncherView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A29F861595080E00F6EA64 /* NILauncherView.m */; };\n\t\t66A29F8E1595080E00F6EA64 /* NILauncherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A29F881595080E00F6EA64 /* NILauncherViewController.m */; };\n\t\t66A29F911595082C00F6EA64 /* BasicInstantiationLauncherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A29F901595082C00F6EA64 /* BasicInstantiationLauncherViewController.m */; };\n\t\t66B6692F159BD22500FE4AE8 /* LongTapAttributedLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B6692E159BD22500FE4AE8 /* LongTapAttributedLabelViewController.m */; };\n\t\t66B67087159CC32D00FE4AE8 /* VerticalPagingScrollViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B67086159CC32D00FE4AE8 /* VerticalPagingScrollViewController.m */; };\n\t\t66B6708B159CC39E00FE4AE8 /* SamplePageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B6708A159CC39D00FE4AE8 /* SamplePageView.m */; };\n\t\t66B6714315AB751E00FE4AE8 /* NICellBackgrounds.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B6714215AB751E00FE4AE8 /* NICellBackgrounds.m */; };\n\t\t66B9414B1592E30100AEA1D2 /* NIInterapp.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B941481592E30100AEA1D2 /* NIInterapp.m */; };\n\t\t66B941521592E36900AEA1D2 /* InterappViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B941511592E36900AEA1D2 /* InterappViewController.m */; };\n\t\t66B941541592E5EF00AEA1D2 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66B941531592E5EF00AEA1D2 /* CoreLocation.framework */; };\n\t\t66B941561592EB4500AEA1D2 /* dilly.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 66B941551592EB4500AEA1D2 /* dilly.jpg */; };\n\t\t66B9415D1593866900AEA1D2 /* NIWebController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B9415C1593866900AEA1D2 /* NIWebController.m */; };\n\t\t66B9415F159386D300AEA1D2 /* NimbusWebController.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 66B9415E159386D300AEA1D2 /* NimbusWebController.bundle */; };\n\t\t66B9C3D5189B750100CCC971 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 66B9C3D4189B750100CCC971 /* Default-568h@2x.png */; };\n\t\t66BB4F52159527E200020EE8 /* NILauncherPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4F51159527E200020EE8 /* NILauncherPageView.m */; };\n\t\t66BB4F6A15957E4300020EE8 /* NILauncherViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4F6915957E4300020EE8 /* NILauncherViewModel.m */; };\n\t\t66BB4F6D1595801900020EE8 /* NILauncherViewObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4F6C1595801900020EE8 /* NILauncherViewObject.m */; };\n\t\t66BB4FA815958A6F00020EE8 /* ModelLauncherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4FA715958A6F00020EE8 /* ModelLauncherViewController.m */; };\n\t\t66BB4FAF159594E300020EE8 /* ModifyingLauncherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4FAE159594E300020EE8 /* ModifyingLauncherViewController.m */; };\n\t\t66BB4FCE15959B5000020EE8 /* RestoringLauncherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4FCD15959B5000020EE8 /* RestoringLauncherViewController.m */; };\n\t\t66CB01A415ACA85E0048E189 /* BlockCellsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66CB01A315ACA85E0048E189 /* BlockCellsViewController.m */; };\n\t\t66D2E54B15D9613800281511 /* NIMutableTableViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 66D2E54915D9613800281511 /* NIMutableTableViewModel.m */; };\n\t\t66D2E54F15D9616500281511 /* MutableTableModelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66D2E54E15D9616500281511 /* MutableTableModelViewController.m */; };\n\t\t66D2FDB81593D5D000B2BEFD /* ContentModesNetworkImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66D2FDB71593D5D000B2BEFD /* ContentModesNetworkImageViewController.m */; };\n\t\t66EBCC5118AAC7AE00A98C3C /* NIPagingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66EBCC4D18AAC7AE00A98C3C /* NIPagingScrollView.m */; };\n\t\t66EBCC5218AAC7AE00A98C3C /* NIPagingScrollViewPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 66EBCC5018AAC7AE00A98C3C /* NIPagingScrollViewPage.m */; };\n\t\t66F01FAE22F33004007656B4 /* UIActivityIndicatorView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01F9A22F33003007656B4 /* UIActivityIndicatorView+AFNetworking.m */; };\n\t\t66F01FAF22F33004007656B4 /* UIImageView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01F9C22F33003007656B4 /* UIImageView+AFNetworking.m */; };\n\t\t66F01FB022F33004007656B4 /* AFAutoPurgingImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01F9D22F33003007656B4 /* AFAutoPurgingImageCache.m */; };\n\t\t66F01FB122F33004007656B4 /* UIButton+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01F9E22F33003007656B4 /* UIButton+AFNetworking.m */; };\n\t\t66F01FB222F33004007656B4 /* UIProgressView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FA222F33003007656B4 /* UIProgressView+AFNetworking.m */; };\n\t\t66F01FB322F33004007656B4 /* AFNetworkActivityIndicatorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FA322F33003007656B4 /* AFNetworkActivityIndicatorManager.m */; };\n\t\t66F01FB422F33004007656B4 /* UIRefreshControl+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FA522F33003007656B4 /* UIRefreshControl+AFNetworking.m */; };\n\t\t66F01FB522F33004007656B4 /* AFImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FA822F33003007656B4 /* AFImageDownloader.m */; };\n\t\t66F01FB622F33004007656B4 /* UIWebView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FAC22F33003007656B4 /* UIWebView+AFNetworking.m */; };\n\t\t66F01FC522F3300D007656B4 /* AFNetworkReachabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FB822F3300C007656B4 /* AFNetworkReachabilityManager.m */; };\n\t\t66F01FC622F3300D007656B4 /* AFHTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FBA22F3300C007656B4 /* AFHTTPSessionManager.m */; };\n\t\t66F01FC722F3300D007656B4 /* AFURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FBC22F3300C007656B4 /* AFURLSessionManager.m */; };\n\t\t66F01FC822F3300D007656B4 /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FBE22F3300C007656B4 /* AFSecurityPolicy.m */; };\n\t\t66F01FC922F3300D007656B4 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FC222F3300C007656B4 /* AFURLResponseSerialization.m */; };\n\t\t66F01FCA22F3300D007656B4 /* AFURLRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FC422F3300C007656B4 /* AFURLRequestSerialization.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t2B960E8315AE41FC005714CA /* navigationbar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = navigationbar.png; path = Catalog/navigationbar.png; sourceTree = \"<group>\"; };\n\t\t3616212916812222002A9078 /* AlignmentAttributedLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlignmentAttributedLabelViewController.h; sourceTree = \"<group>\"; };\n\t\t3616212A16812222002A9078 /* AlignmentAttributedLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlignmentAttributedLabelViewController.m; sourceTree = \"<group>\"; };\n\t\t3616212B16812222002A9078 /* AlignmentAttributedLabelViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AlignmentAttributedLabelViewController.xib; sourceTree = \"<group>\"; };\n\t\t44707C75159B06A000B83149 /* BasicInstantiationPagingScrollViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BasicInstantiationPagingScrollViewController.h; sourceTree = \"<group>\"; };\n\t\t44707C76159B06A000B83149 /* BasicInstantiationPagingScrollViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BasicInstantiationPagingScrollViewController.m; sourceTree = \"<group>\"; };\n\t\t5CAE32612222514F0055EC24 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };\n\t\t660C6F2715992B2500209EB3 /* BadgedLauncherButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BadgedLauncherButtonView.h; sourceTree = \"<group>\"; };\n\t\t660C6F2815992B2500209EB3 /* BadgedLauncherButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BadgedLauncherButtonView.m; sourceTree = \"<group>\"; };\n\t\t6613335C15D3A66B00369333 /* SnapshotRotationTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnapshotRotationTableViewController.h; sourceTree = \"<group>\"; };\n\t\t6613335D15D3A66B00369333 /* SnapshotRotationTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SnapshotRotationTableViewController.m; sourceTree = \"<group>\"; };\n\t\t6617AF1E18A8138500037E75 /* NibCollectionModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NibCollectionModelViewController.h; sourceTree = \"<group>\"; };\n\t\t6617AF1F18A8138500037E75 /* NibCollectionModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NibCollectionModelViewController.m; sourceTree = \"<group>\"; };\n\t\t6617AF2118A813FC00037E75 /* NibCellObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NibCellObject.h; sourceTree = \"<group>\"; };\n\t\t6617AF2218A813FC00037E75 /* NibCellObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NibCellObject.m; sourceTree = \"<group>\"; };\n\t\t6617AF2418A817D600037E75 /* CustomTextCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CustomTextCell.xib; sourceTree = \"<group>\"; };\n\t\t6617AF2618A8188000037E75 /* CustomNibCollectionModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomNibCollectionModelViewController.h; sourceTree = \"<group>\"; };\n\t\t6617AF2718A8188000037E75 /* CustomNibCollectionModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomNibCollectionModelViewController.m; sourceTree = \"<group>\"; };\n\t\t6617AF2918A8189D00037E75 /* CustomTextCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomTextCell.h; sourceTree = \"<group>\"; };\n\t\t6617AF2A18A8189D00037E75 /* CustomTextCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomTextCell.m; sourceTree = \"<group>\"; };\n\t\t6617B06018A9100500037E75 /* NIImageResponseSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIImageResponseSerializer.h; path = ../../src/networkimage/src/NIImageResponseSerializer.h; sourceTree = \"<group>\"; };\n\t\t6617B06118A9100500037E75 /* NIImageResponseSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIImageResponseSerializer.m; path = ../../src/networkimage/src/NIImageResponseSerializer.m; sourceTree = \"<group>\"; };\n\t\t661B9AB415AFF9DC00B743F1 /* NetworkBlockCellsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkBlockCellsViewController.h; sourceTree = \"<group>\"; };\n\t\t661B9AB515AFF9DC00B743F1 /* NetworkBlockCellsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NetworkBlockCellsViewController.m; sourceTree = \"<group>\"; };\n\t\t661F28EC159292B800D11FC3 /* BasicInstantiationBadgeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicInstantiationBadgeViewController.h; sourceTree = \"<group>\"; };\n\t\t661F28ED159292B800D11FC3 /* BasicInstantiationBadgeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BasicInstantiationBadgeViewController.m; sourceTree = \"<group>\"; };\n\t\t661F28F0159292E800D11FC3 /* NIBadgeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIBadgeView.h; path = ../../src/badge/src/NIBadgeView.h; sourceTree = \"<group>\"; };\n\t\t661F28F1159292E800D11FC3 /* NIBadgeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIBadgeView.m; path = ../../src/badge/src/NIBadgeView.m; sourceTree = \"<group>\"; };\n\t\t661F28F2159292E800D11FC3 /* NimbusBadge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusBadge.h; path = ../../src/badge/src/NimbusBadge.h; sourceTree = \"<group>\"; };\n\t\t661F28F4159299C900D11FC3 /* CustomizingBadgesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomizingBadgesViewController.h; sourceTree = \"<group>\"; };\n\t\t661F28F5159299C900D11FC3 /* CustomizingBadgesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomizingBadgesViewController.m; sourceTree = \"<group>\"; };\n\t\t661F292F15929E2300D11FC3 /* InterfaceBuilderBadgeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterfaceBuilderBadgeViewController.h; sourceTree = \"<group>\"; };\n\t\t661F293015929E2300D11FC3 /* InterfaceBuilderBadgeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InterfaceBuilderBadgeViewController.m; sourceTree = \"<group>\"; };\n\t\t661F293115929E2300D11FC3 /* ApplicationBadges.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ApplicationBadges.xib; sourceTree = \"<group>\"; };\n\t\t6633C7ED158F08A40054D240 /* InterfaceBuilderAttributedLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterfaceBuilderAttributedLabelViewController.h; sourceTree = \"<group>\"; };\n\t\t6633C7EE158F08A40054D240 /* InterfaceBuilderAttributedLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InterfaceBuilderAttributedLabelViewController.m; sourceTree = \"<group>\"; };\n\t\t6633C7F1158F08EA0054D240 /* AttributedLabelMashup.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AttributedLabelMashup.xib; sourceTree = \"<group>\"; };\n\t\t6633D21D15DDBD4100A4B07E /* ImagesAttributedLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImagesAttributedLabelViewController.h; sourceTree = \"<group>\"; };\n\t\t6633D21E15DDBD4100A4B07E /* ImagesAttributedLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImagesAttributedLabelViewController.m; sourceTree = \"<group>\"; };\n\t\t664D94AE22731A1C00A2F6A5 /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = \"Launch Screen.storyboard\"; sourceTree = \"<group>\"; };\n\t\t66559AF815C8BE6800ED9047 /* ActionsTableModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActionsTableModelViewController.h; sourceTree = \"<group>\"; };\n\t\t66559AF915C8BE6800ED9047 /* ActionsTableModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ActionsTableModelViewController.m; sourceTree = \"<group>\"; };\n\t\t66559AFC15CC3F9B00ED9047 /* ModalRadioGroupTableModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModalRadioGroupTableModelViewController.h; sourceTree = \"<group>\"; };\n\t\t66559AFD15CC3F9B00ED9047 /* ModalRadioGroupTableModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ModalRadioGroupTableModelViewController.m; sourceTree = \"<group>\"; };\n\t\t6658C38A18A910820080B319 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };\n\t\t6658C38C18A910860080B319 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };\n\t\t6677FEBB15AB8A0300517ABC /* BasicInstantiationTableModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicInstantiationTableModelViewController.h; sourceTree = \"<group>\"; };\n\t\t6677FEBC15AB8A0300517ABC /* BasicInstantiationTableModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BasicInstantiationTableModelViewController.m; sourceTree = \"<group>\"; };\n\t\t6677FEDA15AB96BF00517ABC /* SectionedTableModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SectionedTableModelViewController.h; sourceTree = \"<group>\"; };\n\t\t6677FEDB15AB96BF00517ABC /* SectionedTableModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SectionedTableModelViewController.m; sourceTree = \"<group>\"; };\n\t\t6677FEDE15ABA9A200517ABC /* IndexedTableModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndexedTableModelViewController.h; sourceTree = \"<group>\"; };\n\t\t6677FEDF15ABA9A300517ABC /* IndexedTableModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IndexedTableModelViewController.m; sourceTree = \"<group>\"; };\n\t\t6677FEE115ABACC500517ABC /* FormCellCatalogViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormCellCatalogViewController.h; sourceTree = \"<group>\"; };\n\t\t6677FEE215ABACC500517ABC /* FormCellCatalogViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FormCellCatalogViewController.m; sourceTree = \"<group>\"; };\n\t\t6677FEE415AC8D1600517ABC /* circle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = circle.png; path = ../catalog/Catalog/circle.png; sourceTree = \"<group>\"; };\n\t\t6677FEE615AC8D1C00517ABC /* star.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = star.png; path = ../catalog/Catalog/star.png; sourceTree = \"<group>\"; };\n\t\t6677FEE815AC92C800517ABC /* RadioGroupTableModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RadioGroupTableModelViewController.h; sourceTree = \"<group>\"; };\n\t\t6677FEE915AC92C800517ABC /* RadioGroupTableModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RadioGroupTableModelViewController.m; sourceTree = \"<group>\"; };\n\t\t6677FEEB15ACA60300517ABC /* NestedRadioGroupTableModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NestedRadioGroupTableModelViewController.h; sourceTree = \"<group>\"; };\n\t\t6677FEEC15ACA60400517ABC /* NestedRadioGroupTableModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NestedRadioGroupTableModelViewController.m; sourceTree = \"<group>\"; };\n\t\t668B766D15938C8400EA86F6 /* ExtraActionsWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtraActionsWebViewController.h; sourceTree = \"<group>\"; };\n\t\t668B766E15938C8400EA86F6 /* ExtraActionsWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExtraActionsWebViewController.m; sourceTree = \"<group>\"; };\n\t\t668B7671159394A200EA86F6 /* BasicInstantiationNetworkImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicInstantiationNetworkImageViewController.h; sourceTree = \"<group>\"; };\n\t\t668B7672159394A200EA86F6 /* BasicInstantiationNetworkImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BasicInstantiationNetworkImageViewController.m; sourceTree = \"<group>\"; };\n\t\t668B7675159394EF00EA86F6 /* NimbusNetworkImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusNetworkImage.h; path = ../../src/networkimage/src/NimbusNetworkImage.h; sourceTree = \"<group>\"; };\n\t\t668B7677159394EF00EA86F6 /* NIImageProcessing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIImageProcessing.h; path = ../../src/networkimage/src/NIImageProcessing.h; sourceTree = \"<group>\"; };\n\t\t668B7678159394EF00EA86F6 /* NIImageProcessing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIImageProcessing.m; path = ../../src/networkimage/src/NIImageProcessing.m; sourceTree = \"<group>\"; };\n\t\t668B7679159394EF00EA86F6 /* NINetworkImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINetworkImageView.h; path = ../../src/networkimage/src/NINetworkImageView.h; sourceTree = \"<group>\"; };\n\t\t668B767A159394EF00EA86F6 /* NINetworkImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINetworkImageView.m; path = ../../src/networkimage/src/NINetworkImageView.m; sourceTree = \"<group>\"; };\n\t\t668EA9C117206F640056C8C3 /* NIActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIActions.h; path = ../../src/core/src/NIActions.h; sourceTree = \"<group>\"; };\n\t\t668EA9C217206F640056C8C3 /* NIActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIActions.m; path = ../../src/core/src/NIActions.m; sourceTree = \"<group>\"; };\n\t\t668EA9C317206F640056C8C3 /* NIActions+Subclassing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NIActions+Subclassing.h\"; path = \"../../src/core/src/NIActions+Subclassing.h\"; sourceTree = \"<group>\"; };\n\t\t6692F58D159920E200FA074E /* BadgedLauncherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BadgedLauncherViewController.h; sourceTree = \"<group>\"; };\n\t\t6692F58E159920E200FA074E /* BadgedLauncherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BadgedLauncherViewController.m; sourceTree = \"<group>\"; };\n\t\t6693C0EB158A63E600950D42 /* Nimbus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Nimbus.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6693C0EF158A63E600950D42 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };\n\t\t6693C0F1158A63E600950D42 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };\n\t\t6693C0F3158A63E600950D42 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };\n\t\t6693C0F7158A63E600950D42 /* NimbusCatalog-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = \"NimbusCatalog-Info.plist\"; path = \"Catalog/NimbusCatalog-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t6693C0F9158A63E600950D42 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\t6693C0FB158A63E600950D42 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Catalog/main.m; sourceTree = \"<group>\"; };\n\t\t6693C0FD158A63E600950D42 /* NimbusCatalog-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = \"NimbusCatalog-Prefix.pch\"; path = \"Catalog/NimbusCatalog-Prefix.pch\"; sourceTree = \"<group>\"; };\n\t\t6693C0FE158A63E600950D42 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Catalog/AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t6693C0FF158A63E600950D42 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Catalog/AppDelegate.m; sourceTree = \"<group>\"; };\n\t\t6693C1D1158A80A000950D42 /* CatalogViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CatalogViewController.h; sourceTree = \"<group>\"; };\n\t\t6693C1D2158A80A000950D42 /* CatalogViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CatalogViewController.m; sourceTree = \"<group>\"; };\n\t\t6693C1D5158A81D300950D42 /* NICommonMetrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICommonMetrics.h; path = ../../src/core/src/NICommonMetrics.h; sourceTree = \"<group>\"; };\n\t\t6693C1D6158A81D300950D42 /* NICommonMetrics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICommonMetrics.m; path = ../../src/core/src/NICommonMetrics.m; sourceTree = \"<group>\"; };\n\t\t6693C1D9158A81D300950D42 /* NIDebuggingTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIDebuggingTools.h; path = ../../src/core/src/NIDebuggingTools.h; sourceTree = \"<group>\"; };\n\t\t6693C1DA158A81D300950D42 /* NIDebuggingTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIDebuggingTools.m; path = ../../src/core/src/NIDebuggingTools.m; sourceTree = \"<group>\"; };\n\t\t6693C1DB158A81D300950D42 /* NIDeviceOrientation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIDeviceOrientation.h; path = ../../src/core/src/NIDeviceOrientation.h; sourceTree = \"<group>\"; };\n\t\t6693C1DC158A81D300950D42 /* NIDeviceOrientation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIDeviceOrientation.m; path = ../../src/core/src/NIDeviceOrientation.m; sourceTree = \"<group>\"; };\n\t\t6693C1DD158A81D300950D42 /* NIError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIError.h; path = ../../src/core/src/NIError.h; sourceTree = \"<group>\"; };\n\t\t6693C1DE158A81D300950D42 /* NIError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIError.m; path = ../../src/core/src/NIError.m; sourceTree = \"<group>\"; };\n\t\t6693C1DF158A81D300950D42 /* NIFoundationMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIFoundationMethods.h; path = ../../src/core/src/NIFoundationMethods.h; sourceTree = \"<group>\"; };\n\t\t6693C1E0158A81D300950D42 /* NIFoundationMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIFoundationMethods.m; path = ../../src/core/src/NIFoundationMethods.m; sourceTree = \"<group>\"; };\n\t\t6693C1E1158A81D300950D42 /* NIInMemoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIInMemoryCache.h; path = ../../src/core/src/NIInMemoryCache.h; sourceTree = \"<group>\"; };\n\t\t6693C1E2158A81D300950D42 /* NIInMemoryCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIInMemoryCache.m; path = ../../src/core/src/NIInMemoryCache.m; sourceTree = \"<group>\"; };\n\t\t6693C1E3158A81D300950D42 /* NimbusCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusCore.h; path = ../../src/core/src/NimbusCore.h; sourceTree = \"<group>\"; };\n\t\t6693C1E4158A81D300950D42 /* NimbusCore+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NimbusCore+Additions.h\"; path = \"../../src/core/src/NimbusCore+Additions.h\"; sourceTree = \"<group>\"; };\n\t\t6693C1E8158A81D300950D42 /* NINetworkActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINetworkActivity.h; path = ../../src/core/src/NINetworkActivity.h; sourceTree = \"<group>\"; };\n\t\t6693C1E9158A81D300950D42 /* NINetworkActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINetworkActivity.m; path = ../../src/core/src/NINetworkActivity.m; sourceTree = \"<group>\"; };\n\t\t6693C1EA158A81D300950D42 /* NINonEmptyCollectionTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINonEmptyCollectionTesting.h; path = ../../src/core/src/NINonEmptyCollectionTesting.h; sourceTree = \"<group>\"; };\n\t\t6693C1EB158A81D300950D42 /* NINonEmptyCollectionTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINonEmptyCollectionTesting.m; path = ../../src/core/src/NINonEmptyCollectionTesting.m; sourceTree = \"<group>\"; };\n\t\t6693C1EC158A81D300950D42 /* NINonRetainingCollections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINonRetainingCollections.h; path = ../../src/core/src/NINonRetainingCollections.h; sourceTree = \"<group>\"; };\n\t\t6693C1ED158A81D300950D42 /* NINonRetainingCollections.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINonRetainingCollections.m; path = ../../src/core/src/NINonRetainingCollections.m; sourceTree = \"<group>\"; };\n\t\t6693C1EE158A81D300950D42 /* NIOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOperations.h; path = ../../src/core/src/NIOperations.h; sourceTree = \"<group>\"; };\n\t\t6693C1EF158A81D300950D42 /* NIOperations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOperations.m; path = ../../src/core/src/NIOperations.m; sourceTree = \"<group>\"; };\n\t\t6693C1F0158A81D300950D42 /* NIOperations+Subclassing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NIOperations+Subclassing.h\"; path = \"../../src/core/src/NIOperations+Subclassing.h\"; sourceTree = \"<group>\"; };\n\t\t6693C1F1158A81D300950D42 /* NIPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPaths.h; path = ../../src/core/src/NIPaths.h; sourceTree = \"<group>\"; };\n\t\t6693C1F2158A81D300950D42 /* NIPaths.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIPaths.m; path = ../../src/core/src/NIPaths.m; sourceTree = \"<group>\"; };\n\t\t6693C1F3158A81D300950D42 /* NIPreprocessorMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPreprocessorMacros.h; path = ../../src/core/src/NIPreprocessorMacros.h; sourceTree = \"<group>\"; };\n\t\t6693C1F4158A81D300950D42 /* NIRuntimeClassModifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIRuntimeClassModifications.h; path = ../../src/core/src/NIRuntimeClassModifications.h; sourceTree = \"<group>\"; };\n\t\t6693C1F5158A81D300950D42 /* NIRuntimeClassModifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIRuntimeClassModifications.m; path = ../../src/core/src/NIRuntimeClassModifications.m; sourceTree = \"<group>\"; };\n\t\t6693C1F6158A81D300950D42 /* NISDKAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NISDKAvailability.h; path = ../../src/core/src/NISDKAvailability.h; sourceTree = \"<group>\"; };\n\t\t6693C1F7158A81D300950D42 /* NISDKAvailability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NISDKAvailability.m; path = ../../src/core/src/NISDKAvailability.m; sourceTree = \"<group>\"; };\n\t\t6693C1F8158A81D300950D42 /* NIState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIState.h; path = ../../src/core/src/NIState.h; sourceTree = \"<group>\"; };\n\t\t6693C1F9158A81D300950D42 /* NIState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIState.m; path = ../../src/core/src/NIState.m; sourceTree = \"<group>\"; };\n\t\t6693C1FA158A81D300950D42 /* NIViewRecycler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIViewRecycler.h; path = ../../src/core/src/NIViewRecycler.h; sourceTree = \"<group>\"; };\n\t\t6693C1FB158A81D300950D42 /* NIViewRecycler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIViewRecycler.m; path = ../../src/core/src/NIViewRecycler.m; sourceTree = \"<group>\"; };\n\t\t6693C216158A81DD00950D42 /* NICellCatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICellCatalog.h; path = ../../src/models/src/NICellCatalog.h; sourceTree = \"<group>\"; };\n\t\t6693C217158A81DD00950D42 /* NICellCatalog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICellCatalog.m; path = ../../src/models/src/NICellCatalog.m; sourceTree = \"<group>\"; };\n\t\t6693C218158A81DD00950D42 /* NICellFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICellFactory.h; path = ../../src/models/src/NICellFactory.h; sourceTree = \"<group>\"; };\n\t\t6693C219158A81DD00950D42 /* NICellFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICellFactory.m; path = ../../src/models/src/NICellFactory.m; sourceTree = \"<group>\"; };\n\t\t6693C21A158A81DD00950D42 /* NIFormCellCatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIFormCellCatalog.h; path = ../../src/models/src/NIFormCellCatalog.h; sourceTree = \"<group>\"; };\n\t\t6693C21B158A81DD00950D42 /* NIFormCellCatalog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIFormCellCatalog.m; path = ../../src/models/src/NIFormCellCatalog.m; sourceTree = \"<group>\"; };\n\t\t6693C21C158A81DD00950D42 /* NimbusModels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusModels.h; path = ../../src/models/src/NimbusModels.h; sourceTree = \"<group>\"; };\n\t\t6693C21E158A81DD00950D42 /* NIRadioGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIRadioGroup.h; path = ../../src/models/src/NIRadioGroup.h; sourceTree = \"<group>\"; };\n\t\t6693C21F158A81DD00950D42 /* NIRadioGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIRadioGroup.m; path = ../../src/models/src/NIRadioGroup.m; sourceTree = \"<group>\"; };\n\t\t6693C220158A81DD00950D42 /* NIRadioGroupController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIRadioGroupController.h; path = ../../src/models/src/NIRadioGroupController.h; sourceTree = \"<group>\"; };\n\t\t6693C221158A81DD00950D42 /* NIRadioGroupController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIRadioGroupController.m; path = ../../src/models/src/NIRadioGroupController.m; sourceTree = \"<group>\"; };\n\t\t6693C222158A81DD00950D42 /* NITableViewActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NITableViewActions.h; path = ../../src/models/src/NITableViewActions.h; sourceTree = \"<group>\"; };\n\t\t6693C223158A81DD00950D42 /* NITableViewActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NITableViewActions.m; path = ../../src/models/src/NITableViewActions.m; sourceTree = \"<group>\"; };\n\t\t6693C224158A81DD00950D42 /* NITableViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NITableViewModel.h; path = ../../src/models/src/NITableViewModel.h; sourceTree = \"<group>\"; };\n\t\t6693C225158A81DD00950D42 /* NITableViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NITableViewModel.m; path = ../../src/models/src/NITableViewModel.m; sourceTree = \"<group>\"; };\n\t\t6693C226158A81DD00950D42 /* NITableViewModel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NITableViewModel+Private.h\"; path = \"../../src/models/src/NITableViewModel+Private.h\"; sourceTree = \"<group>\"; };\n\t\t6693C290158A8E4000950D42 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = \"<group>\"; };\n\t\t6693C291158A8E4000950D42 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Default@2x.png\"; sourceTree = \"<group>\"; };\n\t\t6693C292158A8E4000950D42 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-72.png\"; sourceTree = \"<group>\"; };\n\t\t6693C293158A8E4000950D42 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-Small-50.png\"; sourceTree = \"<group>\"; };\n\t\t6693C294158A8E4000950D42 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-Small.png\"; sourceTree = \"<group>\"; };\n\t\t6693C295158A8E4000950D42 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-Small@2x.png\"; sourceTree = \"<group>\"; };\n\t\t6693C296158A8E4000950D42 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = \"<group>\"; };\n\t\t6693C297158A8E4000950D42 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon@2x.png\"; sourceTree = \"<group>\"; };\n\t\t6693C2DE158A9A3E00950D42 /* BasicInstantiationAttributedLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicInstantiationAttributedLabelViewController.h; sourceTree = \"<group>\"; };\n\t\t6693C2E2158AA21E00950D42 /* NIAttributedLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIAttributedLabel.h; path = ../../src/attributedlabel/src/NIAttributedLabel.h; sourceTree = \"<group>\"; };\n\t\t6693C2E3158AA21E00950D42 /* NIAttributedLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIAttributedLabel.m; path = ../../src/attributedlabel/src/NIAttributedLabel.m; sourceTree = \"<group>\"; };\n\t\t6693C2E4158AA21E00950D42 /* NimbusAttributedLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusAttributedLabel.h; path = ../../src/attributedlabel/src/NimbusAttributedLabel.h; sourceTree = \"<group>\"; };\n\t\t6693C2E6158AA21E00950D42 /* NSMutableAttributedString+NimbusAttributedLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NSMutableAttributedString+NimbusAttributedLabel.h\"; path = \"../../src/attributedlabel/src/NSMutableAttributedString+NimbusAttributedLabel.h\"; sourceTree = \"<group>\"; };\n\t\t6693C2E7158AA21E00950D42 /* NSMutableAttributedString+NimbusAttributedLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"NSMutableAttributedString+NimbusAttributedLabel.m\"; path = \"../../src/attributedlabel/src/NSMutableAttributedString+NimbusAttributedLabel.m\"; sourceTree = \"<group>\"; };\n\t\t6693C2EA158AA2BE00950D42 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };\n\t\t6693C2EC158AB5B600950D42 /* CustomTextAttributedLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomTextAttributedLabelViewController.h; sourceTree = \"<group>\"; };\n\t\t6693C2ED158AB5B600950D42 /* CustomTextAttributedLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomTextAttributedLabelViewController.m; sourceTree = \"<group>\"; };\n\t\t6693EFEB18A7293700A600A0 /* BasicInstantiationCollectionModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicInstantiationCollectionModelViewController.h; sourceTree = \"<group>\"; };\n\t\t6693EFEC18A7293700A600A0 /* BasicInstantiationCollectionModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BasicInstantiationCollectionModelViewController.m; sourceTree = \"<group>\"; };\n\t\t6693EFEF18A7A34A00A600A0 /* NICollectionViewActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICollectionViewActions.h; sourceTree = \"<group>\"; };\n\t\t6693EFF018A7A34A00A600A0 /* NICollectionViewActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICollectionViewActions.m; sourceTree = \"<group>\"; };\n\t\t6693EFF118A7A34A00A600A0 /* NICollectionViewCellFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICollectionViewCellFactory.h; sourceTree = \"<group>\"; };\n\t\t6693EFF218A7A34A00A600A0 /* NICollectionViewCellFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICollectionViewCellFactory.m; sourceTree = \"<group>\"; };\n\t\t6693EFF318A7A34A00A600A0 /* NICollectionViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICollectionViewModel.h; sourceTree = \"<group>\"; };\n\t\t6693EFF418A7A34A00A600A0 /* NICollectionViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICollectionViewModel.m; sourceTree = \"<group>\"; };\n\t\t6693EFF518A7A34A00A600A0 /* NICollectionViewModel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NICollectionViewModel+Private.h\"; sourceTree = \"<group>\"; };\n\t\t6693EFF618A7A34A00A600A0 /* NimbusCollections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusCollections.h; sourceTree = \"<group>\"; };\n\t\t6693EFF718A7A34A00A600A0 /* NIMutableCollectionViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIMutableCollectionViewModel.h; sourceTree = \"<group>\"; };\n\t\t6693EFF818A7A34A00A600A0 /* NIMutableCollectionViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIMutableCollectionViewModel.m; sourceTree = \"<group>\"; };\n\t\t6693EFF918A7A34A00A600A0 /* NIMutableCollectionViewModel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NIMutableCollectionViewModel+Private.h\"; sourceTree = \"<group>\"; };\n\t\t6693EFFF18A7A40A00A600A0 /* ColorCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorCell.h; sourceTree = \"<group>\"; };\n\t\t6693F00018A7A40A00A600A0 /* ColorCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ColorCell.m; sourceTree = \"<group>\"; };\n\t\t6693F00518A7B0B900A600A0 /* NimbusKitCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NimbusKitCell.xib; sourceTree = \"<group>\"; };\n\t\t669819DD159B953A00C2D3EF /* NISnapshotRotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NISnapshotRotation.h; path = ../../src/core/src/NISnapshotRotation.h; sourceTree = \"<group>\"; };\n\t\t669819DE159B953A00C2D3EF /* NISnapshotRotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NISnapshotRotation.m; path = ../../src/core/src/NISnapshotRotation.m; sourceTree = \"<group>\"; };\n\t\t669A15CB158D318B00A0990A /* LinksAttributedLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinksAttributedLabelViewController.h; sourceTree = \"<group>\"; };\n\t\t669A15CC158D318B00A0990A /* LinksAttributedLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinksAttributedLabelViewController.m; sourceTree = \"<group>\"; };\n\t\t669A15CF158D38E700A0990A /* BasicInstantiationAttributedLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BasicInstantiationAttributedLabelViewController.m; sourceTree = \"<group>\"; };\n\t\t669A15D1158E6C7C00A0990A /* DataTypesAttributedLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataTypesAttributedLabelViewController.h; sourceTree = \"<group>\"; };\n\t\t669A15D2158E6C7C00A0990A /* DataTypesAttributedLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataTypesAttributedLabelViewController.m; sourceTree = \"<group>\"; };\n\t\t669A15D4158E81D200A0990A /* PerformanceAttributedLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceAttributedLabelViewController.h; sourceTree = \"<group>\"; };\n\t\t669A15D5158E81D200A0990A /* PerformanceAttributedLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PerformanceAttributedLabelViewController.m; sourceTree = \"<group>\"; };\n\t\t66A29F831595080E00F6EA64 /* NILauncherButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NILauncherButtonView.m; path = ../../src/launcher/src/NILauncherButtonView.m; sourceTree = \"<group>\"; };\n\t\t66A29F851595080E00F6EA64 /* NILauncherView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NILauncherView.h; path = ../../src/launcher/src/NILauncherView.h; sourceTree = \"<group>\"; };\n\t\t66A29F861595080E00F6EA64 /* NILauncherView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NILauncherView.m; path = ../../src/launcher/src/NILauncherView.m; sourceTree = \"<group>\"; };\n\t\t66A29F871595080E00F6EA64 /* NILauncherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NILauncherViewController.h; path = ../../src/launcher/src/NILauncherViewController.h; sourceTree = \"<group>\"; };\n\t\t66A29F881595080E00F6EA64 /* NILauncherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NILauncherViewController.m; path = ../../src/launcher/src/NILauncherViewController.m; sourceTree = \"<group>\"; };\n\t\t66A29F891595080E00F6EA64 /* NimbusLauncher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusLauncher.h; path = ../../src/launcher/src/NimbusLauncher.h; sourceTree = \"<group>\"; };\n\t\t66A29F8F1595082C00F6EA64 /* BasicInstantiationLauncherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicInstantiationLauncherViewController.h; sourceTree = \"<group>\"; };\n\t\t66A29F901595082C00F6EA64 /* BasicInstantiationLauncherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BasicInstantiationLauncherViewController.m; sourceTree = \"<group>\"; };\n\t\t66A29F92159509EE00F6EA64 /* NILauncherButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NILauncherButtonView.h; path = ../../src/launcher/src/NILauncherButtonView.h; sourceTree = \"<group>\"; };\n\t\t66B6692D159BD22500FE4AE8 /* LongTapAttributedLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LongTapAttributedLabelViewController.h; sourceTree = \"<group>\"; };\n\t\t66B6692E159BD22500FE4AE8 /* LongTapAttributedLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LongTapAttributedLabelViewController.m; sourceTree = \"<group>\"; };\n\t\t66B67085159CC32D00FE4AE8 /* VerticalPagingScrollViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VerticalPagingScrollViewController.h; sourceTree = \"<group>\"; };\n\t\t66B67086159CC32D00FE4AE8 /* VerticalPagingScrollViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VerticalPagingScrollViewController.m; sourceTree = \"<group>\"; };\n\t\t66B67089159CC39D00FE4AE8 /* SamplePageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplePageView.h; sourceTree = \"<group>\"; };\n\t\t66B6708A159CC39D00FE4AE8 /* SamplePageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SamplePageView.m; sourceTree = \"<group>\"; };\n\t\t66B6714115AB751E00FE4AE8 /* NICellBackgrounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICellBackgrounds.h; path = ../../src/models/src/NICellBackgrounds.h; sourceTree = \"<group>\"; };\n\t\t66B6714215AB751E00FE4AE8 /* NICellBackgrounds.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICellBackgrounds.m; path = ../../src/models/src/NICellBackgrounds.m; sourceTree = \"<group>\"; };\n\t\t66B941471592E30100AEA1D2 /* NIInterapp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIInterapp.h; path = ../../src/interapp/src/NIInterapp.h; sourceTree = \"<group>\"; };\n\t\t66B941481592E30100AEA1D2 /* NIInterapp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIInterapp.m; path = ../../src/interapp/src/NIInterapp.m; sourceTree = \"<group>\"; };\n\t\t66B941491592E30100AEA1D2 /* NimbusInterapp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusInterapp.h; path = ../../src/interapp/src/NimbusInterapp.h; sourceTree = \"<group>\"; };\n\t\t66B941501592E36900AEA1D2 /* InterappViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterappViewController.h; sourceTree = \"<group>\"; };\n\t\t66B941511592E36900AEA1D2 /* InterappViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InterappViewController.m; sourceTree = \"<group>\"; };\n\t\t66B941531592E5EF00AEA1D2 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };\n\t\t66B941551592EB4500AEA1D2 /* dilly.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = dilly.jpg; path = ../catalog/Catalog/dilly.jpg; sourceTree = \"<group>\"; };\n\t\t66B941591593866900AEA1D2 /* NimbusWebController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusWebController.h; path = ../../src/webcontroller/src/NimbusWebController.h; sourceTree = \"<group>\"; };\n\t\t66B9415B1593866900AEA1D2 /* NIWebController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIWebController.h; path = ../../src/webcontroller/src/NIWebController.h; sourceTree = \"<group>\"; };\n\t\t66B9415C1593866900AEA1D2 /* NIWebController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIWebController.m; path = ../../src/webcontroller/src/NIWebController.m; sourceTree = \"<group>\"; };\n\t\t66B9415E159386D300AEA1D2 /* NimbusWebController.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; name = NimbusWebController.bundle; path = ../../src/webcontroller/resources/NimbusWebController.bundle; sourceTree = \"<group>\"; };\n\t\t66B9C3D4189B750100CCC971 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Default-568h@2x.png\"; sourceTree = \"<group>\"; };\n\t\t66BB4F50159527E200020EE8 /* NILauncherPageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NILauncherPageView.h; path = ../../src/launcher/src/NILauncherPageView.h; sourceTree = \"<group>\"; };\n\t\t66BB4F51159527E200020EE8 /* NILauncherPageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NILauncherPageView.m; path = ../../src/launcher/src/NILauncherPageView.m; sourceTree = \"<group>\"; };\n\t\t66BB4F6815957E4300020EE8 /* NILauncherViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NILauncherViewModel.h; path = ../../src/launcher/src/NILauncherViewModel.h; sourceTree = \"<group>\"; };\n\t\t66BB4F6915957E4300020EE8 /* NILauncherViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NILauncherViewModel.m; path = ../../src/launcher/src/NILauncherViewModel.m; sourceTree = \"<group>\"; };\n\t\t66BB4F6B1595801900020EE8 /* NILauncherViewObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NILauncherViewObject.h; path = ../../src/launcher/src/NILauncherViewObject.h; sourceTree = \"<group>\"; };\n\t\t66BB4F6C1595801900020EE8 /* NILauncherViewObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NILauncherViewObject.m; path = ../../src/launcher/src/NILauncherViewObject.m; sourceTree = \"<group>\"; };\n\t\t66BB4FA615958A6F00020EE8 /* ModelLauncherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModelLauncherViewController.h; sourceTree = \"<group>\"; };\n\t\t66BB4FA715958A6F00020EE8 /* ModelLauncherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ModelLauncherViewController.m; sourceTree = \"<group>\"; };\n\t\t66BB4FAD159594E300020EE8 /* ModifyingLauncherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModifyingLauncherViewController.h; sourceTree = \"<group>\"; };\n\t\t66BB4FAE159594E300020EE8 /* ModifyingLauncherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ModifyingLauncherViewController.m; sourceTree = \"<group>\"; };\n\t\t66BB4FCC15959B5000020EE8 /* RestoringLauncherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestoringLauncherViewController.h; sourceTree = \"<group>\"; };\n\t\t66BB4FCD15959B5000020EE8 /* RestoringLauncherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RestoringLauncherViewController.m; sourceTree = \"<group>\"; };\n\t\t66CB01A215ACA85E0048E189 /* BlockCellsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockCellsViewController.h; sourceTree = \"<group>\"; };\n\t\t66CB01A315ACA85E0048E189 /* BlockCellsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockCellsViewController.m; sourceTree = \"<group>\"; };\n\t\t66D2E54815D9613700281511 /* NIMutableTableViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIMutableTableViewModel.h; path = ../../src/models/src/NIMutableTableViewModel.h; sourceTree = \"<group>\"; };\n\t\t66D2E54915D9613800281511 /* NIMutableTableViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIMutableTableViewModel.m; path = ../../src/models/src/NIMutableTableViewModel.m; sourceTree = \"<group>\"; };\n\t\t66D2E54A15D9613800281511 /* NIMutableTableViewModel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NIMutableTableViewModel+Private.h\"; path = \"../../src/models/src/NIMutableTableViewModel+Private.h\"; sourceTree = \"<group>\"; };\n\t\t66D2E54D15D9616500281511 /* MutableTableModelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MutableTableModelViewController.h; sourceTree = \"<group>\"; };\n\t\t66D2E54E15D9616500281511 /* MutableTableModelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MutableTableModelViewController.m; sourceTree = \"<group>\"; };\n\t\t66D2FDB61593D5D000B2BEFD /* ContentModesNetworkImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentModesNetworkImageViewController.h; sourceTree = \"<group>\"; };\n\t\t66D2FDB71593D5D000B2BEFD /* ContentModesNetworkImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContentModesNetworkImageViewController.m; sourceTree = \"<group>\"; };\n\t\t66EBCC4A18AAC7AE00A98C3C /* NimbusPagingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusPagingScrollView.h; sourceTree = \"<group>\"; };\n\t\t66EBCC4B18AAC7AE00A98C3C /* NimbusPagingScrollView+Namespace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NimbusPagingScrollView+Namespace.h\"; sourceTree = \"<group>\"; };\n\t\t66EBCC4C18AAC7AE00A98C3C /* NIPagingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPagingScrollView.h; sourceTree = \"<group>\"; };\n\t\t66EBCC4D18AAC7AE00A98C3C /* NIPagingScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPagingScrollView.m; sourceTree = \"<group>\"; };\n\t\t66EBCC4E18AAC7AE00A98C3C /* NIPagingScrollView+Subclassing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NIPagingScrollView+Subclassing.h\"; sourceTree = \"<group>\"; };\n\t\t66EBCC4F18AAC7AE00A98C3C /* NIPagingScrollViewPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPagingScrollViewPage.h; sourceTree = \"<group>\"; };\n\t\t66EBCC5018AAC7AE00A98C3C /* NIPagingScrollViewPage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPagingScrollViewPage.m; sourceTree = \"<group>\"; };\n\t\t66F01F9A22F33003007656B4 /* UIActivityIndicatorView+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIActivityIndicatorView+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t66F01F9B22F33003007656B4 /* UIImage+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIImage+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t66F01F9C22F33003007656B4 /* UIImageView+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIImageView+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t66F01F9D22F33003007656B4 /* AFAutoPurgingImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFAutoPurgingImageCache.m; sourceTree = \"<group>\"; };\n\t\t66F01F9E22F33003007656B4 /* UIButton+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIButton+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t66F01F9F22F33003007656B4 /* UIImageView+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIImageView+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t66F01FA022F33003007656B4 /* AFNetworkActivityIndicatorManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworkActivityIndicatorManager.h; sourceTree = \"<group>\"; };\n\t\t66F01FA122F33003007656B4 /* UIKit+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIKit+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t66F01FA222F33003007656B4 /* UIProgressView+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIProgressView+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t66F01FA322F33003007656B4 /* AFNetworkActivityIndicatorManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFNetworkActivityIndicatorManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FA422F33003007656B4 /* UIProgressView+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIProgressView+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t66F01FA522F33003007656B4 /* UIRefreshControl+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIRefreshControl+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t66F01FA622F33003007656B4 /* AFImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFImageDownloader.h; sourceTree = \"<group>\"; };\n\t\t66F01FA722F33003007656B4 /* UIWebView+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIWebView+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t66F01FA822F33003007656B4 /* AFImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFImageDownloader.m; sourceTree = \"<group>\"; };\n\t\t66F01FA922F33003007656B4 /* UIActivityIndicatorView+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIActivityIndicatorView+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t66F01FAA22F33003007656B4 /* UIButton+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIButton+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t66F01FAB22F33003007656B4 /* AFAutoPurgingImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFAutoPurgingImageCache.h; sourceTree = \"<group>\"; };\n\t\t66F01FAC22F33003007656B4 /* UIWebView+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIWebView+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t66F01FAD22F33003007656B4 /* UIRefreshControl+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIRefreshControl+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t66F01FB722F3300C007656B4 /* AFCompatibilityMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFCompatibilityMacros.h; sourceTree = \"<group>\"; };\n\t\t66F01FB822F3300C007656B4 /* AFNetworkReachabilityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFNetworkReachabilityManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FB922F3300C007656B4 /* AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworking.h; sourceTree = \"<group>\"; };\n\t\t66F01FBA22F3300C007656B4 /* AFHTTPSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPSessionManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FBB22F3300C007656B4 /* AFURLSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLSessionManager.h; sourceTree = \"<group>\"; };\n\t\t66F01FBC22F3300C007656B4 /* AFURLSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLSessionManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FBD22F3300C007656B4 /* AFNetworkReachabilityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworkReachabilityManager.h; sourceTree = \"<group>\"; };\n\t\t66F01FBE22F3300C007656B4 /* AFSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSecurityPolicy.m; sourceTree = \"<group>\"; };\n\t\t66F01FBF22F3300C007656B4 /* AFHTTPSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPSessionManager.h; sourceTree = \"<group>\"; };\n\t\t66F01FC022F3300C007656B4 /* AFURLRequestSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLRequestSerialization.h; sourceTree = \"<group>\"; };\n\t\t66F01FC122F3300C007656B4 /* AFURLResponseSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLResponseSerialization.h; sourceTree = \"<group>\"; };\n\t\t66F01FC222F3300C007656B4 /* AFURLResponseSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLResponseSerialization.m; sourceTree = \"<group>\"; };\n\t\t66F01FC322F3300C007656B4 /* AFSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSecurityPolicy.h; sourceTree = \"<group>\"; };\n\t\t66F01FC422F3300C007656B4 /* AFURLRequestSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLRequestSerialization.m; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t6693C0E8158A63E600950D42 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t5CAE32622222514F0055EC24 /* MobileCoreServices.framework in Frameworks */,\n\t\t\t\t6658C38D18A910860080B319 /* Security.framework in Frameworks */,\n\t\t\t\t6658C38B18A910820080B319 /* SystemConfiguration.framework in Frameworks */,\n\t\t\t\t66B941541592E5EF00AEA1D2 /* CoreLocation.framework in Frameworks */,\n\t\t\t\t6693C2EB158AA2BF00950D42 /* CoreText.framework in Frameworks */,\n\t\t\t\t6693C0F0158A63E600950D42 /* UIKit.framework in Frameworks */,\n\t\t\t\t6693C0F2158A63E600950D42 /* Foundation.framework in Frameworks */,\n\t\t\t\t6693C0F4158A63E600950D42 /* CoreGraphics.framework 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\t44707C73159B068400B83149 /* Paging Scroll View */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t44707C75159B06A000B83149 /* BasicInstantiationPagingScrollViewController.h */,\n\t\t\t\t44707C76159B06A000B83149 /* BasicInstantiationPagingScrollViewController.m */,\n\t\t\t\t66B67085159CC32D00FE4AE8 /* VerticalPagingScrollViewController.h */,\n\t\t\t\t66B67086159CC32D00FE4AE8 /* VerticalPagingScrollViewController.m */,\n\t\t\t\t66B67089159CC39D00FE4AE8 /* SamplePageView.h */,\n\t\t\t\t66B6708A159CC39D00FE4AE8 /* SamplePageView.m */,\n\t\t\t);\n\t\t\tname = \"Paging Scroll View\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6617B02918A90FF000037E75 /* UIKit */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66F01FAB22F33003007656B4 /* AFAutoPurgingImageCache.h */,\n\t\t\t\t66F01F9D22F33003007656B4 /* AFAutoPurgingImageCache.m */,\n\t\t\t\t66F01FA622F33003007656B4 /* AFImageDownloader.h */,\n\t\t\t\t66F01FA822F33003007656B4 /* AFImageDownloader.m */,\n\t\t\t\t66F01FA022F33003007656B4 /* AFNetworkActivityIndicatorManager.h */,\n\t\t\t\t66F01FA322F33003007656B4 /* AFNetworkActivityIndicatorManager.m */,\n\t\t\t\t66F01FA922F33003007656B4 /* UIActivityIndicatorView+AFNetworking.h */,\n\t\t\t\t66F01F9A22F33003007656B4 /* UIActivityIndicatorView+AFNetworking.m */,\n\t\t\t\t66F01FAA22F33003007656B4 /* UIButton+AFNetworking.h */,\n\t\t\t\t66F01F9E22F33003007656B4 /* UIButton+AFNetworking.m */,\n\t\t\t\t66F01F9B22F33003007656B4 /* UIImage+AFNetworking.h */,\n\t\t\t\t66F01F9F22F33003007656B4 /* UIImageView+AFNetworking.h */,\n\t\t\t\t66F01F9C22F33003007656B4 /* UIImageView+AFNetworking.m */,\n\t\t\t\t66F01FA122F33003007656B4 /* UIKit+AFNetworking.h */,\n\t\t\t\t66F01FA422F33003007656B4 /* UIProgressView+AFNetworking.h */,\n\t\t\t\t66F01FA222F33003007656B4 /* UIProgressView+AFNetworking.m */,\n\t\t\t\t66F01FAD22F33003007656B4 /* UIRefreshControl+AFNetworking.h */,\n\t\t\t\t66F01FA522F33003007656B4 /* UIRefreshControl+AFNetworking.m */,\n\t\t\t\t66F01FA722F33003007656B4 /* UIWebView+AFNetworking.h */,\n\t\t\t\t66F01FAC22F33003007656B4 /* UIWebView+AFNetworking.m */,\n\t\t\t);\n\t\t\tname = UIKit;\n\t\t\tpath = \"../UIKit+AFNetworking\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6617B03D18A90FF000037E75 /* AFNetworking */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66F01FB722F3300C007656B4 /* AFCompatibilityMacros.h */,\n\t\t\t\t66F01FBF22F3300C007656B4 /* AFHTTPSessionManager.h */,\n\t\t\t\t66F01FBA22F3300C007656B4 /* AFHTTPSessionManager.m */,\n\t\t\t\t66F01FB922F3300C007656B4 /* AFNetworking.h */,\n\t\t\t\t66F01FBD22F3300C007656B4 /* AFNetworkReachabilityManager.h */,\n\t\t\t\t66F01FB822F3300C007656B4 /* AFNetworkReachabilityManager.m */,\n\t\t\t\t66F01FC322F3300C007656B4 /* AFSecurityPolicy.h */,\n\t\t\t\t66F01FBE22F3300C007656B4 /* AFSecurityPolicy.m */,\n\t\t\t\t66F01FC022F3300C007656B4 /* AFURLRequestSerialization.h */,\n\t\t\t\t66F01FC422F3300C007656B4 /* AFURLRequestSerialization.m */,\n\t\t\t\t66F01FC122F3300C007656B4 /* AFURLResponseSerialization.h */,\n\t\t\t\t66F01FC222F3300C007656B4 /* AFURLResponseSerialization.m */,\n\t\t\t\t66F01FBB22F3300C007656B4 /* AFURLSessionManager.h */,\n\t\t\t\t66F01FBC22F3300C007656B4 /* AFURLSessionManager.m */,\n\t\t\t\t6617B02918A90FF000037E75 /* UIKit */,\n\t\t\t);\n\t\t\tname = AFNetworking;\n\t\t\tpath = ../../thirdparty/AFNetworking/AFNetworking;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t661F28EA1592929E00D11FC3 /* Badge */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t661F28EC159292B800D11FC3 /* BasicInstantiationBadgeViewController.h */,\n\t\t\t\t661F28ED159292B800D11FC3 /* BasicInstantiationBadgeViewController.m */,\n\t\t\t\t661F28F4159299C900D11FC3 /* CustomizingBadgesViewController.h */,\n\t\t\t\t661F28F5159299C900D11FC3 /* CustomizingBadgesViewController.m */,\n\t\t\t\t661F292F15929E2300D11FC3 /* InterfaceBuilderBadgeViewController.h */,\n\t\t\t\t661F293015929E2300D11FC3 /* InterfaceBuilderBadgeViewController.m */,\n\t\t\t\t661F293115929E2300D11FC3 /* ApplicationBadges.xib */,\n\t\t\t);\n\t\t\tname = Badge;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t661F28EF159292D900D11FC3 /* Badge */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t661F28F0159292E800D11FC3 /* NIBadgeView.h */,\n\t\t\t\t661F28F1159292E800D11FC3 /* NIBadgeView.m */,\n\t\t\t\t661F28F2159292E800D11FC3 /* NimbusBadge.h */,\n\t\t\t);\n\t\t\tname = Badge;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6677FEB915AB886B00517ABC /* Table Models */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6677FEBB15AB8A0300517ABC /* BasicInstantiationTableModelViewController.h */,\n\t\t\t\t6677FEBC15AB8A0300517ABC /* BasicInstantiationTableModelViewController.m */,\n\t\t\t\t6677FEDA15AB96BF00517ABC /* SectionedTableModelViewController.h */,\n\t\t\t\t6677FEDB15AB96BF00517ABC /* SectionedTableModelViewController.m */,\n\t\t\t\t6677FEDE15ABA9A200517ABC /* IndexedTableModelViewController.h */,\n\t\t\t\t6677FEDF15ABA9A300517ABC /* IndexedTableModelViewController.m */,\n\t\t\t\t66559AF815C8BE6800ED9047 /* ActionsTableModelViewController.h */,\n\t\t\t\t66559AF915C8BE6800ED9047 /* ActionsTableModelViewController.m */,\n\t\t\t\t6677FEE815AC92C800517ABC /* RadioGroupTableModelViewController.h */,\n\t\t\t\t6677FEE915AC92C800517ABC /* RadioGroupTableModelViewController.m */,\n\t\t\t\t6677FEEB15ACA60300517ABC /* NestedRadioGroupTableModelViewController.h */,\n\t\t\t\t6677FEEC15ACA60400517ABC /* NestedRadioGroupTableModelViewController.m */,\n\t\t\t\t66559AFC15CC3F9B00ED9047 /* ModalRadioGroupTableModelViewController.h */,\n\t\t\t\t66559AFD15CC3F9B00ED9047 /* ModalRadioGroupTableModelViewController.m */,\n\t\t\t\t6677FEE115ABACC500517ABC /* FormCellCatalogViewController.h */,\n\t\t\t\t6677FEE215ABACC500517ABC /* FormCellCatalogViewController.m */,\n\t\t\t\t66CB01A215ACA85E0048E189 /* BlockCellsViewController.h */,\n\t\t\t\t66CB01A315ACA85E0048E189 /* BlockCellsViewController.m */,\n\t\t\t\t661B9AB415AFF9DC00B743F1 /* NetworkBlockCellsViewController.h */,\n\t\t\t\t661B9AB515AFF9DC00B743F1 /* NetworkBlockCellsViewController.m */,\n\t\t\t\t6613335C15D3A66B00369333 /* SnapshotRotationTableViewController.h */,\n\t\t\t\t6613335D15D3A66B00369333 /* SnapshotRotationTableViewController.m */,\n\t\t\t\t66D2E54D15D9616500281511 /* MutableTableModelViewController.h */,\n\t\t\t\t66D2E54E15D9616500281511 /* MutableTableModelViewController.m */,\n\t\t\t);\n\t\t\tname = \"Table Models\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t668B766B15938C6E00EA86F6 /* Web Controller */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t668B766D15938C8400EA86F6 /* ExtraActionsWebViewController.h */,\n\t\t\t\t668B766E15938C8400EA86F6 /* ExtraActionsWebViewController.m */,\n\t\t\t);\n\t\t\tname = \"Web Controller\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t668B7670159393B400EA86F6 /* Network Image */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t668B7671159394A200EA86F6 /* BasicInstantiationNetworkImageViewController.h */,\n\t\t\t\t668B7672159394A200EA86F6 /* BasicInstantiationNetworkImageViewController.m */,\n\t\t\t\t66D2FDB61593D5D000B2BEFD /* ContentModesNetworkImageViewController.h */,\n\t\t\t\t66D2FDB71593D5D000B2BEFD /* ContentModesNetworkImageViewController.m */,\n\t\t\t);\n\t\t\tname = \"Network Image\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t668B7674159394DE00EA86F6 /* Network Image */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t668B7675159394EF00EA86F6 /* NimbusNetworkImage.h */,\n\t\t\t\t668B7677159394EF00EA86F6 /* NIImageProcessing.h */,\n\t\t\t\t668B7678159394EF00EA86F6 /* NIImageProcessing.m */,\n\t\t\t\t668B7679159394EF00EA86F6 /* NINetworkImageView.h */,\n\t\t\t\t668B767A159394EF00EA86F6 /* NINetworkImageView.m */,\n\t\t\t\t6617B06018A9100500037E75 /* NIImageResponseSerializer.h */,\n\t\t\t\t6617B06118A9100500037E75 /* NIImageResponseSerializer.m */,\n\t\t\t);\n\t\t\tname = \"Network Image\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C0E0158A63E600950D42 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C0FD158A63E600950D42 /* NimbusCatalog-Prefix.pch */,\n\t\t\t\t6693C0FE158A63E600950D42 /* AppDelegate.h */,\n\t\t\t\t6693C0FF158A63E600950D42 /* AppDelegate.m */,\n\t\t\t\t6693C0FB158A63E600950D42 /* main.m */,\n\t\t\t\t6693C1D0158A808100950D42 /* Catalog */,\n\t\t\t\t6693C14E158A64BD00950D42 /* Nimbus */,\n\t\t\t\t6617B03D18A90FF000037E75 /* AFNetworking */,\n\t\t\t\t6693C10C158A63F700950D42 /* Resources */,\n\t\t\t\t6693C0EE158A63E600950D42 /* Frameworks */,\n\t\t\t\t6693C0EC158A63E600950D42 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C0EC158A63E600950D42 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C0EB158A63E600950D42 /* Nimbus.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C0EE158A63E600950D42 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t5CAE32612222514F0055EC24 /* MobileCoreServices.framework */,\n\t\t\t\t6658C38C18A910860080B319 /* Security.framework */,\n\t\t\t\t6658C38A18A910820080B319 /* SystemConfiguration.framework */,\n\t\t\t\t66B941531592E5EF00AEA1D2 /* CoreLocation.framework */,\n\t\t\t\t6693C2EA158AA2BE00950D42 /* CoreText.framework */,\n\t\t\t\t6693C0EF158A63E600950D42 /* UIKit.framework */,\n\t\t\t\t6693C0F1158A63E600950D42 /* Foundation.framework */,\n\t\t\t\t6693C0F3158A63E600950D42 /* CoreGraphics.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C10C158A63F700950D42 /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2B960E8315AE41FC005714CA /* navigationbar.png */,\n\t\t\t\t6677FEE415AC8D1600517ABC /* circle.png */,\n\t\t\t\t6677FEE615AC8D1C00517ABC /* star.png */,\n\t\t\t\t66B9415E159386D300AEA1D2 /* NimbusWebController.bundle */,\n\t\t\t\t66B941551592EB4500AEA1D2 /* dilly.jpg */,\n\t\t\t\t6693C0F7158A63E600950D42 /* NimbusCatalog-Info.plist */,\n\t\t\t\t6693C0F8158A63E600950D42 /* InfoPlist.strings */,\n\t\t\t\t664D94AE22731A1C00A2F6A5 /* Launch Screen.storyboard */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C14E158A64BD00950D42 /* Nimbus */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C298158A8E4000950D42 /* Resources */,\n\t\t\t\t6693C2E1158AA13900950D42 /* Attributed Label */,\n\t\t\t\t661F28EF159292D900D11FC3 /* Badge */,\n\t\t\t\t6693EFEE18A7A33400A600A0 /* Collections */,\n\t\t\t\t6693C150158A64C100950D42 /* Core */,\n\t\t\t\t66B941461592E2E200AEA1D2 /* Interapp */,\n\t\t\t\t66A29F82159507DF00F6EA64 /* Launcher */,\n\t\t\t\t6693C1AD158A64CE00950D42 /* Models */,\n\t\t\t\t668B7674159394DE00EA86F6 /* Network Image */,\n\t\t\t\t66A29F9415951BF700F6EA64 /* Paging Scroll View */,\n\t\t\t\t66B941581593865E00AEA1D2 /* Web Controller */,\n\t\t\t);\n\t\t\tname = Nimbus;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C150158A64C100950D42 /* Core */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t668EA9C117206F640056C8C3 /* NIActions.h */,\n\t\t\t\t668EA9C217206F640056C8C3 /* NIActions.m */,\n\t\t\t\t668EA9C317206F640056C8C3 /* NIActions+Subclassing.h */,\n\t\t\t\t6693C1D5158A81D300950D42 /* NICommonMetrics.h */,\n\t\t\t\t6693C1D6158A81D300950D42 /* NICommonMetrics.m */,\n\t\t\t\t6693C1D9158A81D300950D42 /* NIDebuggingTools.h */,\n\t\t\t\t6693C1DA158A81D300950D42 /* NIDebuggingTools.m */,\n\t\t\t\t6693C1DB158A81D300950D42 /* NIDeviceOrientation.h */,\n\t\t\t\t6693C1DC158A81D300950D42 /* NIDeviceOrientation.m */,\n\t\t\t\t6693C1DD158A81D300950D42 /* NIError.h */,\n\t\t\t\t6693C1DE158A81D300950D42 /* NIError.m */,\n\t\t\t\t6693C1DF158A81D300950D42 /* NIFoundationMethods.h */,\n\t\t\t\t6693C1E0158A81D300950D42 /* NIFoundationMethods.m */,\n\t\t\t\t6693C1E1158A81D300950D42 /* NIInMemoryCache.h */,\n\t\t\t\t6693C1E2158A81D300950D42 /* NIInMemoryCache.m */,\n\t\t\t\t6693C1E3158A81D300950D42 /* NimbusCore.h */,\n\t\t\t\t6693C1E4158A81D300950D42 /* NimbusCore+Additions.h */,\n\t\t\t\t6693C1E8158A81D300950D42 /* NINetworkActivity.h */,\n\t\t\t\t6693C1E9158A81D300950D42 /* NINetworkActivity.m */,\n\t\t\t\t6693C1EA158A81D300950D42 /* NINonEmptyCollectionTesting.h */,\n\t\t\t\t6693C1EB158A81D300950D42 /* NINonEmptyCollectionTesting.m */,\n\t\t\t\t6693C1EC158A81D300950D42 /* NINonRetainingCollections.h */,\n\t\t\t\t6693C1ED158A81D300950D42 /* NINonRetainingCollections.m */,\n\t\t\t\t6693C1EE158A81D300950D42 /* NIOperations.h */,\n\t\t\t\t6693C1EF158A81D300950D42 /* NIOperations.m */,\n\t\t\t\t6693C1F0158A81D300950D42 /* NIOperations+Subclassing.h */,\n\t\t\t\t6693C1F1158A81D300950D42 /* NIPaths.h */,\n\t\t\t\t6693C1F2158A81D300950D42 /* NIPaths.m */,\n\t\t\t\t6693C1F3158A81D300950D42 /* NIPreprocessorMacros.h */,\n\t\t\t\t6693C1F4158A81D300950D42 /* NIRuntimeClassModifications.h */,\n\t\t\t\t6693C1F5158A81D300950D42 /* NIRuntimeClassModifications.m */,\n\t\t\t\t6693C1F6158A81D300950D42 /* NISDKAvailability.h */,\n\t\t\t\t6693C1F7158A81D300950D42 /* NISDKAvailability.m */,\n\t\t\t\t669819DD159B953A00C2D3EF /* NISnapshotRotation.h */,\n\t\t\t\t669819DE159B953A00C2D3EF /* NISnapshotRotation.m */,\n\t\t\t\t6693C1F8158A81D300950D42 /* NIState.h */,\n\t\t\t\t6693C1F9158A81D300950D42 /* NIState.m */,\n\t\t\t\t6693C1FA158A81D300950D42 /* NIViewRecycler.h */,\n\t\t\t\t6693C1FB158A81D300950D42 /* NIViewRecycler.m */,\n\t\t\t);\n\t\t\tname = Core;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C1AD158A64CE00950D42 /* Models */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66B6714115AB751E00FE4AE8 /* NICellBackgrounds.h */,\n\t\t\t\t66B6714215AB751E00FE4AE8 /* NICellBackgrounds.m */,\n\t\t\t\t6693C216158A81DD00950D42 /* NICellCatalog.h */,\n\t\t\t\t6693C217158A81DD00950D42 /* NICellCatalog.m */,\n\t\t\t\t6693C218158A81DD00950D42 /* NICellFactory.h */,\n\t\t\t\t6693C219158A81DD00950D42 /* NICellFactory.m */,\n\t\t\t\t6693C21A158A81DD00950D42 /* NIFormCellCatalog.h */,\n\t\t\t\t6693C21B158A81DD00950D42 /* NIFormCellCatalog.m */,\n\t\t\t\t6693C21C158A81DD00950D42 /* NimbusModels.h */,\n\t\t\t\t6693C21E158A81DD00950D42 /* NIRadioGroup.h */,\n\t\t\t\t6693C21F158A81DD00950D42 /* NIRadioGroup.m */,\n\t\t\t\t6693C220158A81DD00950D42 /* NIRadioGroupController.h */,\n\t\t\t\t6693C221158A81DD00950D42 /* NIRadioGroupController.m */,\n\t\t\t\t6693C222158A81DD00950D42 /* NITableViewActions.h */,\n\t\t\t\t6693C223158A81DD00950D42 /* NITableViewActions.m */,\n\t\t\t\t6693C224158A81DD00950D42 /* NITableViewModel.h */,\n\t\t\t\t6693C225158A81DD00950D42 /* NITableViewModel.m */,\n\t\t\t\t6693C226158A81DD00950D42 /* NITableViewModel+Private.h */,\n\t\t\t\t66D2E54815D9613700281511 /* NIMutableTableViewModel.h */,\n\t\t\t\t66D2E54915D9613800281511 /* NIMutableTableViewModel.m */,\n\t\t\t\t66D2E54A15D9613800281511 /* NIMutableTableViewModel+Private.h */,\n\t\t\t);\n\t\t\tname = Models;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C1D0158A808100950D42 /* Catalog */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C1D1158A80A000950D42 /* CatalogViewController.h */,\n\t\t\t\t6693C1D2158A80A000950D42 /* CatalogViewController.m */,\n\t\t\t\t6693C2DC158A9A0E00950D42 /* Attributed Label */,\n\t\t\t\t661F28EA1592929E00D11FC3 /* Badge */,\n\t\t\t\t6693EFEA18A7290800A600A0 /* Collection Models */,\n\t\t\t\t66B9414C1592E33900AEA1D2 /* Interapp */,\n\t\t\t\t66A29F80159507D700F6EA64 /* Launcher */,\n\t\t\t\t668B7670159393B400EA86F6 /* Network Image */,\n\t\t\t\t44707C73159B068400B83149 /* Paging Scroll View */,\n\t\t\t\t6677FEB915AB886B00517ABC /* Table Models */,\n\t\t\t\t668B766B15938C6E00EA86F6 /* Web Controller */,\n\t\t\t);\n\t\t\tname = Catalog;\n\t\t\tpath = ../catalog/Catalog;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C298158A8E4000950D42 /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C290158A8E4000950D42 /* Default.png */,\n\t\t\t\t6693C291158A8E4000950D42 /* Default@2x.png */,\n\t\t\t\t66B9C3D4189B750100CCC971 /* Default-568h@2x.png */,\n\t\t\t\t6693C292158A8E4000950D42 /* Icon-72.png */,\n\t\t\t\t6693C293158A8E4000950D42 /* Icon-Small-50.png */,\n\t\t\t\t6693C294158A8E4000950D42 /* Icon-Small.png */,\n\t\t\t\t6693C295158A8E4000950D42 /* Icon-Small@2x.png */,\n\t\t\t\t6693C296158A8E4000950D42 /* Icon.png */,\n\t\t\t\t6693C297158A8E4000950D42 /* Icon@2x.png */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tpath = ../../src/resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C2DC158A9A0E00950D42 /* Attributed Label */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C2DE158A9A3E00950D42 /* BasicInstantiationAttributedLabelViewController.h */,\n\t\t\t\t669A15CF158D38E700A0990A /* BasicInstantiationAttributedLabelViewController.m */,\n\t\t\t\t6693C2EC158AB5B600950D42 /* CustomTextAttributedLabelViewController.h */,\n\t\t\t\t6693C2ED158AB5B600950D42 /* CustomTextAttributedLabelViewController.m */,\n\t\t\t\t669A15CB158D318B00A0990A /* LinksAttributedLabelViewController.h */,\n\t\t\t\t669A15CC158D318B00A0990A /* LinksAttributedLabelViewController.m */,\n\t\t\t\t669A15D1158E6C7C00A0990A /* DataTypesAttributedLabelViewController.h */,\n\t\t\t\t669A15D2158E6C7C00A0990A /* DataTypesAttributedLabelViewController.m */,\n\t\t\t\t6633D21D15DDBD4100A4B07E /* ImagesAttributedLabelViewController.h */,\n\t\t\t\t6633D21E15DDBD4100A4B07E /* ImagesAttributedLabelViewController.m */,\n\t\t\t\t669A15D4158E81D200A0990A /* PerformanceAttributedLabelViewController.h */,\n\t\t\t\t669A15D5158E81D200A0990A /* PerformanceAttributedLabelViewController.m */,\n\t\t\t\t66B6692D159BD22500FE4AE8 /* LongTapAttributedLabelViewController.h */,\n\t\t\t\t66B6692E159BD22500FE4AE8 /* LongTapAttributedLabelViewController.m */,\n\t\t\t\t6633C7ED158F08A40054D240 /* InterfaceBuilderAttributedLabelViewController.h */,\n\t\t\t\t6633C7EE158F08A40054D240 /* InterfaceBuilderAttributedLabelViewController.m */,\n\t\t\t\t3616212916812222002A9078 /* AlignmentAttributedLabelViewController.h */,\n\t\t\t\t3616212A16812222002A9078 /* AlignmentAttributedLabelViewController.m */,\n\t\t\t\t3616212B16812222002A9078 /* AlignmentAttributedLabelViewController.xib */,\n\t\t\t\t6633C7F1158F08EA0054D240 /* AttributedLabelMashup.xib */,\n\t\t\t);\n\t\t\tname = \"Attributed Label\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C2E1158AA13900950D42 /* Attributed Label */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C2E2158AA21E00950D42 /* NIAttributedLabel.h */,\n\t\t\t\t6693C2E3158AA21E00950D42 /* NIAttributedLabel.m */,\n\t\t\t\t6693C2E4158AA21E00950D42 /* NimbusAttributedLabel.h */,\n\t\t\t\t6693C2E6158AA21E00950D42 /* NSMutableAttributedString+NimbusAttributedLabel.h */,\n\t\t\t\t6693C2E7158AA21E00950D42 /* NSMutableAttributedString+NimbusAttributedLabel.m */,\n\t\t\t);\n\t\t\tname = \"Attributed Label\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693EFEA18A7290800A600A0 /* Collection Models */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693EFFE18A7A3E700A600A0 /* Collection Cells */,\n\t\t\t\t6693EFEB18A7293700A600A0 /* BasicInstantiationCollectionModelViewController.h */,\n\t\t\t\t6693EFEC18A7293700A600A0 /* BasicInstantiationCollectionModelViewController.m */,\n\t\t\t\t6617AF1E18A8138500037E75 /* NibCollectionModelViewController.h */,\n\t\t\t\t6617AF1F18A8138500037E75 /* NibCollectionModelViewController.m */,\n\t\t\t\t6617AF2618A8188000037E75 /* CustomNibCollectionModelViewController.h */,\n\t\t\t\t6617AF2718A8188000037E75 /* CustomNibCollectionModelViewController.m */,\n\t\t\t);\n\t\t\tname = \"Collection Models\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693EFEE18A7A33400A600A0 /* Collections */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693EFEF18A7A34A00A600A0 /* NICollectionViewActions.h */,\n\t\t\t\t6693EFF018A7A34A00A600A0 /* NICollectionViewActions.m */,\n\t\t\t\t6693EFF118A7A34A00A600A0 /* NICollectionViewCellFactory.h */,\n\t\t\t\t6693EFF218A7A34A00A600A0 /* NICollectionViewCellFactory.m */,\n\t\t\t\t6693EFF318A7A34A00A600A0 /* NICollectionViewModel.h */,\n\t\t\t\t6693EFF418A7A34A00A600A0 /* NICollectionViewModel.m */,\n\t\t\t\t6693EFF518A7A34A00A600A0 /* NICollectionViewModel+Private.h */,\n\t\t\t\t6693EFF618A7A34A00A600A0 /* NimbusCollections.h */,\n\t\t\t\t6693EFF718A7A34A00A600A0 /* NIMutableCollectionViewModel.h */,\n\t\t\t\t6693EFF818A7A34A00A600A0 /* NIMutableCollectionViewModel.m */,\n\t\t\t\t6693EFF918A7A34A00A600A0 /* NIMutableCollectionViewModel+Private.h */,\n\t\t\t);\n\t\t\tname = Collections;\n\t\t\tpath = ../../src/collections/src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693EFFE18A7A3E700A600A0 /* Collection Cells */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693EFFF18A7A40A00A600A0 /* ColorCell.h */,\n\t\t\t\t6693F00018A7A40A00A600A0 /* ColorCell.m */,\n\t\t\t\t6617AF2118A813FC00037E75 /* NibCellObject.h */,\n\t\t\t\t6617AF2218A813FC00037E75 /* NibCellObject.m */,\n\t\t\t\t6617AF2918A8189D00037E75 /* CustomTextCell.h */,\n\t\t\t\t6617AF2A18A8189D00037E75 /* CustomTextCell.m */,\n\t\t\t\t6617AF2418A817D600037E75 /* CustomTextCell.xib */,\n\t\t\t\t6693F00518A7B0B900A600A0 /* NimbusKitCell.xib */,\n\t\t\t);\n\t\t\tname = \"Collection Cells\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A29F80159507D700F6EA64 /* Launcher */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A29F8F1595082C00F6EA64 /* BasicInstantiationLauncherViewController.h */,\n\t\t\t\t66A29F901595082C00F6EA64 /* BasicInstantiationLauncherViewController.m */,\n\t\t\t\t66BB4FA615958A6F00020EE8 /* ModelLauncherViewController.h */,\n\t\t\t\t66BB4FA715958A6F00020EE8 /* ModelLauncherViewController.m */,\n\t\t\t\t66BB4FAD159594E300020EE8 /* ModifyingLauncherViewController.h */,\n\t\t\t\t66BB4FAE159594E300020EE8 /* ModifyingLauncherViewController.m */,\n\t\t\t\t66BB4FCC15959B5000020EE8 /* RestoringLauncherViewController.h */,\n\t\t\t\t66BB4FCD15959B5000020EE8 /* RestoringLauncherViewController.m */,\n\t\t\t\t6692F58D159920E200FA074E /* BadgedLauncherViewController.h */,\n\t\t\t\t6692F58E159920E200FA074E /* BadgedLauncherViewController.m */,\n\t\t\t\t660C6F2715992B2500209EB3 /* BadgedLauncherButtonView.h */,\n\t\t\t\t660C6F2815992B2500209EB3 /* BadgedLauncherButtonView.m */,\n\t\t\t);\n\t\t\tname = Launcher;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A29F82159507DF00F6EA64 /* Launcher */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A29F92159509EE00F6EA64 /* NILauncherButtonView.h */,\n\t\t\t\t66A29F831595080E00F6EA64 /* NILauncherButtonView.m */,\n\t\t\t\t66BB4F50159527E200020EE8 /* NILauncherPageView.h */,\n\t\t\t\t66BB4F51159527E200020EE8 /* NILauncherPageView.m */,\n\t\t\t\t66A29F851595080E00F6EA64 /* NILauncherView.h */,\n\t\t\t\t66A29F861595080E00F6EA64 /* NILauncherView.m */,\n\t\t\t\t66A29F871595080E00F6EA64 /* NILauncherViewController.h */,\n\t\t\t\t66A29F881595080E00F6EA64 /* NILauncherViewController.m */,\n\t\t\t\t66BB4F6815957E4300020EE8 /* NILauncherViewModel.h */,\n\t\t\t\t66BB4F6915957E4300020EE8 /* NILauncherViewModel.m */,\n\t\t\t\t66BB4F6B1595801900020EE8 /* NILauncherViewObject.h */,\n\t\t\t\t66BB4F6C1595801900020EE8 /* NILauncherViewObject.m */,\n\t\t\t\t66A29F891595080E00F6EA64 /* NimbusLauncher.h */,\n\t\t\t);\n\t\t\tname = Launcher;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A29F9415951BF700F6EA64 /* Paging Scroll View */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66EBCC4A18AAC7AE00A98C3C /* NimbusPagingScrollView.h */,\n\t\t\t\t66EBCC4B18AAC7AE00A98C3C /* NimbusPagingScrollView+Namespace.h */,\n\t\t\t\t66EBCC4C18AAC7AE00A98C3C /* NIPagingScrollView.h */,\n\t\t\t\t66EBCC4D18AAC7AE00A98C3C /* NIPagingScrollView.m */,\n\t\t\t\t66EBCC4E18AAC7AE00A98C3C /* NIPagingScrollView+Subclassing.h */,\n\t\t\t\t66EBCC4F18AAC7AE00A98C3C /* NIPagingScrollViewPage.h */,\n\t\t\t\t66EBCC5018AAC7AE00A98C3C /* NIPagingScrollViewPage.m */,\n\t\t\t);\n\t\t\tname = \"Paging Scroll View\";\n\t\t\tpath = ../../src/pagingscrollview/src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66B941461592E2E200AEA1D2 /* Interapp */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66B941471592E30100AEA1D2 /* NIInterapp.h */,\n\t\t\t\t66B941481592E30100AEA1D2 /* NIInterapp.m */,\n\t\t\t\t66B941491592E30100AEA1D2 /* NimbusInterapp.h */,\n\t\t\t);\n\t\t\tname = Interapp;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66B9414C1592E33900AEA1D2 /* Interapp */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66B941501592E36900AEA1D2 /* InterappViewController.h */,\n\t\t\t\t66B941511592E36900AEA1D2 /* InterappViewController.m */,\n\t\t\t);\n\t\t\tname = Interapp;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66B941581593865E00AEA1D2 /* Web Controller */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66B941591593866900AEA1D2 /* NimbusWebController.h */,\n\t\t\t\t66B9415B1593866900AEA1D2 /* NIWebController.h */,\n\t\t\t\t66B9415C1593866900AEA1D2 /* NIWebController.m */,\n\t\t\t);\n\t\t\tname = \"Web Controller\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t6693C0EA158A63E600950D42 /* Nimbus */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6693C103158A63E600950D42 /* Build configuration list for PBXNativeTarget \"Nimbus\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6693C0E7158A63E600950D42 /* Sources */,\n\t\t\t\t6693C0E8158A63E600950D42 /* Frameworks */,\n\t\t\t\t6693C0E9158A63E600950D42 /* 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 = Nimbus;\n\t\t\tproductName = Catalog;\n\t\t\tproductReference = 6693C0EB158A63E600950D42 /* Nimbus.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t6693C0E2158A63E600950D42 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1000;\n\t\t\t\tORGANIZATIONNAME = Nimbus;\n\t\t\t};\n\t\t\tbuildConfigurationList = 6693C0E5158A63E600950D42 /* Build configuration list for PBXProject \"NimbusCatalog\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 6693C0E0158A63E600950D42;\n\t\t\tproductRefGroup = 6693C0EC158A63E600950D42 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t6693C0EA158A63E600950D42 /* Nimbus */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t6693C0E9158A63E600950D42 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6693C0FA158A63E600950D42 /* InfoPlist.strings in Resources */,\n\t\t\t\t6693C299158A8E4000950D42 /* Default.png in Resources */,\n\t\t\t\t6693C29A158A8E4000950D42 /* Default@2x.png in Resources */,\n\t\t\t\t6693C29B158A8E4000950D42 /* Icon-72.png in Resources */,\n\t\t\t\t6693C29C158A8E4000950D42 /* Icon-Small-50.png in Resources */,\n\t\t\t\t6693C29D158A8E4000950D42 /* Icon-Small.png in Resources */,\n\t\t\t\t664D94AF22731A1C00A2F6A5 /* Launch Screen.storyboard in Resources */,\n\t\t\t\t6693C29E158A8E4000950D42 /* Icon-Small@2x.png in Resources */,\n\t\t\t\t6617AF2518A817D600037E75 /* CustomTextCell.xib in Resources */,\n\t\t\t\t6693C29F158A8E4000950D42 /* Icon.png in Resources */,\n\t\t\t\t6693C2A0158A8E4000950D42 /* Icon@2x.png in Resources */,\n\t\t\t\t6633C7F2158F08EA0054D240 /* AttributedLabelMashup.xib in Resources */,\n\t\t\t\t6693F00618A7B0B900A600A0 /* NimbusKitCell.xib in Resources */,\n\t\t\t\t661F293315929E2300D11FC3 /* ApplicationBadges.xib in Resources */,\n\t\t\t\t66B9C3D5189B750100CCC971 /* Default-568h@2x.png in Resources */,\n\t\t\t\t66B941561592EB4500AEA1D2 /* dilly.jpg in Resources */,\n\t\t\t\t66B9415F159386D300AEA1D2 /* NimbusWebController.bundle in Resources */,\n\t\t\t\t6677FEE515AC8D1600517ABC /* circle.png in Resources */,\n\t\t\t\t6677FEE715AC8D1C00517ABC /* star.png in Resources */,\n\t\t\t\t2B960E8415AE41FC005714CA /* navigationbar.png in Resources */,\n\t\t\t\t3616212D16812222002A9078 /* AlignmentAttributedLabelViewController.xib 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\t6693C0E7158A63E600950D42 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6693C0FC158A63E600950D42 /* main.m in Sources */,\n\t\t\t\t6693C100158A63E600950D42 /* AppDelegate.m in Sources */,\n\t\t\t\t6693C1D3158A80A000950D42 /* CatalogViewController.m in Sources */,\n\t\t\t\t6693C202158A81D300950D42 /* NICommonMetrics.m in Sources */,\n\t\t\t\t6693C204158A81D300950D42 /* NIDebuggingTools.m in Sources */,\n\t\t\t\t66F01FC622F3300D007656B4 /* AFHTTPSessionManager.m in Sources */,\n\t\t\t\t6693C205158A81D300950D42 /* NIDeviceOrientation.m in Sources */,\n\t\t\t\t6693C206158A81D300950D42 /* NIError.m in Sources */,\n\t\t\t\t6693C207158A81D300950D42 /* NIFoundationMethods.m in Sources */,\n\t\t\t\t66F01FB322F33004007656B4 /* AFNetworkActivityIndicatorManager.m in Sources */,\n\t\t\t\t6693C208158A81D300950D42 /* NIInMemoryCache.m in Sources */,\n\t\t\t\t66F01FAE22F33004007656B4 /* UIActivityIndicatorView+AFNetworking.m in Sources */,\n\t\t\t\t66F01FB422F33004007656B4 /* UIRefreshControl+AFNetworking.m in Sources */,\n\t\t\t\t6693C20A158A81D300950D42 /* NINetworkActivity.m in Sources */,\n\t\t\t\t6693C20B158A81D300950D42 /* NINonEmptyCollectionTesting.m in Sources */,\n\t\t\t\t6693C20C158A81D300950D42 /* NINonRetainingCollections.m in Sources */,\n\t\t\t\t6693C20D158A81D400950D42 /* NIOperations.m in Sources */,\n\t\t\t\t6693C20E158A81D400950D42 /* NIPaths.m in Sources */,\n\t\t\t\t6617B06418A9102A00037E75 /* NIImageResponseSerializer.m in Sources */,\n\t\t\t\t6693C20F158A81D400950D42 /* NIRuntimeClassModifications.m in Sources */,\n\t\t\t\t6693C210158A81D400950D42 /* NISDKAvailability.m in Sources */,\n\t\t\t\t6693C211158A81D400950D42 /* NIState.m in Sources */,\n\t\t\t\t66F01FC922F3300D007656B4 /* AFURLResponseSerialization.m in Sources */,\n\t\t\t\t6693C212158A81D400950D42 /* NIViewRecycler.m in Sources */,\n\t\t\t\t6693C227158A81DD00950D42 /* NICellCatalog.m in Sources */,\n\t\t\t\t6693C228158A81DD00950D42 /* NICellFactory.m in Sources */,\n\t\t\t\t66F01FAF22F33004007656B4 /* UIImageView+AFNetworking.m in Sources */,\n\t\t\t\t6693EFFB18A7A34A00A600A0 /* NICollectionViewCellFactory.m in Sources */,\n\t\t\t\t6693C229158A81DD00950D42 /* NIFormCellCatalog.m in Sources */,\n\t\t\t\t6693C22A158A81DD00950D42 /* NIRadioGroup.m in Sources */,\n\t\t\t\t66F01FC522F3300D007656B4 /* AFNetworkReachabilityManager.m in Sources */,\n\t\t\t\t6693C22B158A81DD00950D42 /* NIRadioGroupController.m in Sources */,\n\t\t\t\t6693C22C158A81DD00950D42 /* NITableViewActions.m in Sources */,\n\t\t\t\t6693C22D158A81DD00950D42 /* NITableViewModel.m in Sources */,\n\t\t\t\t66F01FCA22F3300D007656B4 /* AFURLRequestSerialization.m in Sources */,\n\t\t\t\t6693C2E8158AA21E00950D42 /* NIAttributedLabel.m in Sources */,\n\t\t\t\t6693C2E9158AA21E00950D42 /* NSMutableAttributedString+NimbusAttributedLabel.m in Sources */,\n\t\t\t\t6693C2EE158AB5B600950D42 /* CustomTextAttributedLabelViewController.m in Sources */,\n\t\t\t\t669A15CD158D318B00A0990A /* LinksAttributedLabelViewController.m in Sources */,\n\t\t\t\t669A15D0158D38E700A0990A /* BasicInstantiationAttributedLabelViewController.m in Sources */,\n\t\t\t\t6693EFFC18A7A34A00A600A0 /* NICollectionViewModel.m in Sources */,\n\t\t\t\t6617AF2318A813FC00037E75 /* NibCellObject.m in Sources */,\n\t\t\t\t6617AF2B18A8189D00037E75 /* CustomTextCell.m in Sources */,\n\t\t\t\t669A15D3158E6C7C00A0990A /* DataTypesAttributedLabelViewController.m in Sources */,\n\t\t\t\t669A15D6158E81D200A0990A /* PerformanceAttributedLabelViewController.m in Sources */,\n\t\t\t\t6633C7EF158F08A40054D240 /* InterfaceBuilderAttributedLabelViewController.m in Sources */,\n\t\t\t\t661F28EE159292B800D11FC3 /* BasicInstantiationBadgeViewController.m in Sources */,\n\t\t\t\t66EBCC5118AAC7AE00A98C3C /* NIPagingScrollView.m in Sources */,\n\t\t\t\t66F01FB522F33004007656B4 /* AFImageDownloader.m in Sources */,\n\t\t\t\t661F28F3159292E800D11FC3 /* NIBadgeView.m in Sources */,\n\t\t\t\t661F28F6159299C900D11FC3 /* CustomizingBadgesViewController.m in Sources */,\n\t\t\t\t66F01FB022F33004007656B4 /* AFAutoPurgingImageCache.m in Sources */,\n\t\t\t\t661F293215929E2300D11FC3 /* InterfaceBuilderBadgeViewController.m in Sources */,\n\t\t\t\t66B9414B1592E30100AEA1D2 /* NIInterapp.m in Sources */,\n\t\t\t\t66B941521592E36900AEA1D2 /* InterappViewController.m in Sources */,\n\t\t\t\t66B9415D1593866900AEA1D2 /* NIWebController.m in Sources */,\n\t\t\t\t668B766F15938C8400EA86F6 /* ExtraActionsWebViewController.m in Sources */,\n\t\t\t\t668B7673159394A200EA86F6 /* BasicInstantiationNetworkImageViewController.m in Sources */,\n\t\t\t\t6617AF2818A8188000037E75 /* CustomNibCollectionModelViewController.m in Sources */,\n\t\t\t\t6693F00118A7A40A00A600A0 /* ColorCell.m in Sources */,\n\t\t\t\t668B767B159394EF00EA86F6 /* NIImageProcessing.m in Sources */,\n\t\t\t\t668B767C159394EF00EA86F6 /* NINetworkImageView.m in Sources */,\n\t\t\t\t66D2FDB81593D5D000B2BEFD /* ContentModesNetworkImageViewController.m in Sources */,\n\t\t\t\t6617AF2018A8138500037E75 /* NibCollectionModelViewController.m in Sources */,\n\t\t\t\t66A29F8B1595080E00F6EA64 /* NILauncherButtonView.m in Sources */,\n\t\t\t\t66A29F8D1595080E00F6EA64 /* NILauncherView.m in Sources */,\n\t\t\t\t66A29F8E1595080E00F6EA64 /* NILauncherViewController.m in Sources */,\n\t\t\t\t66A29F911595082C00F6EA64 /* BasicInstantiationLauncherViewController.m in Sources */,\n\t\t\t\t66BB4F52159527E200020EE8 /* NILauncherPageView.m in Sources */,\n\t\t\t\t66EBCC5218AAC7AE00A98C3C /* NIPagingScrollViewPage.m in Sources */,\n\t\t\t\t6693EFFD18A7A34A00A600A0 /* NIMutableCollectionViewModel.m in Sources */,\n\t\t\t\t66BB4F6A15957E4300020EE8 /* NILauncherViewModel.m in Sources */,\n\t\t\t\t66BB4F6D1595801900020EE8 /* NILauncherViewObject.m in Sources */,\n\t\t\t\t66BB4FA815958A6F00020EE8 /* ModelLauncherViewController.m in Sources */,\n\t\t\t\t66BB4FAF159594E300020EE8 /* ModifyingLauncherViewController.m in Sources */,\n\t\t\t\t66F01FB222F33004007656B4 /* UIProgressView+AFNetworking.m in Sources */,\n\t\t\t\t66BB4FCE15959B5000020EE8 /* RestoringLauncherViewController.m in Sources */,\n\t\t\t\t6692F58F159920E200FA074E /* BadgedLauncherViewController.m in Sources */,\n\t\t\t\t660C6F2915992B2500209EB3 /* BadgedLauncherButtonView.m in Sources */,\n\t\t\t\t44707C77159B06A700B83149 /* BasicInstantiationPagingScrollViewController.m in Sources */,\n\t\t\t\t66F01FB622F33004007656B4 /* UIWebView+AFNetworking.m in Sources */,\n\t\t\t\t66B6692F159BD22500FE4AE8 /* LongTapAttributedLabelViewController.m in Sources */,\n\t\t\t\t66B67087159CC32D00FE4AE8 /* VerticalPagingScrollViewController.m in Sources */,\n\t\t\t\t6693EFFA18A7A34A00A600A0 /* NICollectionViewActions.m in Sources */,\n\t\t\t\t66B6708B159CC39E00FE4AE8 /* SamplePageView.m in Sources */,\n\t\t\t\t66B6714315AB751E00FE4AE8 /* NICellBackgrounds.m in Sources */,\n\t\t\t\t6677FEBD15AB8A0300517ABC /* BasicInstantiationTableModelViewController.m in Sources */,\n\t\t\t\t6677FEDC15AB96BF00517ABC /* SectionedTableModelViewController.m in Sources */,\n\t\t\t\t66F01FB122F33004007656B4 /* UIButton+AFNetworking.m in Sources */,\n\t\t\t\t6677FEE015ABA9A300517ABC /* IndexedTableModelViewController.m in Sources */,\n\t\t\t\t6677FEE315ABACC500517ABC /* FormCellCatalogViewController.m in Sources */,\n\t\t\t\t66F01FC722F3300D007656B4 /* AFURLSessionManager.m in Sources */,\n\t\t\t\t6677FEEA15AC92C800517ABC /* RadioGroupTableModelViewController.m in Sources */,\n\t\t\t\t66F01FC822F3300D007656B4 /* AFSecurityPolicy.m in Sources */,\n\t\t\t\t6677FEED15ACA60400517ABC /* NestedRadioGroupTableModelViewController.m in Sources */,\n\t\t\t\t66CB01A415ACA85E0048E189 /* BlockCellsViewController.m in Sources */,\n\t\t\t\t661B9AB615AFF9DC00B743F1 /* NetworkBlockCellsViewController.m in Sources */,\n\t\t\t\t66559AFA15C8BE6800ED9047 /* ActionsTableModelViewController.m in Sources */,\n\t\t\t\t66559AFE15CC3F9B00ED9047 /* ModalRadioGroupTableModelViewController.m in Sources */,\n\t\t\t\t669819DF159B953A00C2D3EF /* NISnapshotRotation.m in Sources */,\n\t\t\t\t6613335E15D3A66B00369333 /* SnapshotRotationTableViewController.m in Sources */,\n\t\t\t\t6633D21F15DDBD4100A4B07E /* ImagesAttributedLabelViewController.m in Sources */,\n\t\t\t\t66D2E54B15D9613800281511 /* NIMutableTableViewModel.m in Sources */,\n\t\t\t\t6693EFED18A7293700A600A0 /* BasicInstantiationCollectionModelViewController.m in Sources */,\n\t\t\t\t66D2E54F15D9616500281511 /* MutableTableModelViewController.m in Sources */,\n\t\t\t\t3616212C16812222002A9078 /* AlignmentAttributedLabelViewController.m in Sources */,\n\t\t\t\t668EA9C417206F640056C8C3 /* NIActions.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t6693C0F8158A63E600950D42 /* InfoPlist.strings */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C0F9158A63E600950D42 /* en */,\n\t\t\t);\n\t\t\tname = InfoPlist.strings;\n\t\t\tpath = Catalog;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t6693C101158A63E600950D42 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6693C102158A63E600950D42 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tOTHER_CFLAGS = \"-DNS_BLOCK_ASSERTIONS=1\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6693C104158A63E600950D42 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"Catalog/NimbusCatalog-Prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Catalog/NimbusCatalog-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.jeffverkoeyen.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = Nimbus;\n\t\t\t\tWARNING_CFLAGS = \"-Wobjc-property-assign-on-object-type\";\n\t\t\t\tWRAPPER_EXTENSION = app;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6693C105158A63E600950D42 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"Catalog/NimbusCatalog-Prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Catalog/NimbusCatalog-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.jeffverkoeyen.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = Nimbus;\n\t\t\t\tWARNING_CFLAGS = \"-Wobjc-property-assign-on-object-type\";\n\t\t\t\tWRAPPER_EXTENSION = app;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t6693C0E5158A63E600950D42 /* Build configuration list for PBXProject \"NimbusCatalog\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6693C101158A63E600950D42 /* Debug */,\n\t\t\t\t6693C102158A63E600950D42 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6693C103158A63E600950D42 /* Build configuration list for PBXNativeTarget \"Nimbus\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6693C104158A63E600950D42 /* Debug */,\n\t\t\t\t6693C105158A63E600950D42 /* 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 = 6693C0E2158A63E600950D42 /* Project object */;\n}\n"
  },
  {
    "path": "examples/css/CSSDemo/AppDelegate.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : NSObject <UIApplicationDelegate> {\n  UIWindow* _window;\n  UIViewController* _rootController;\n  NIChameleonObserver* _chameleonObserver;\n  NIStylesheetCache* _stylesheetCache;\n}\n\n@property (nonatomic, retain) UIWindow* window;\n@property (nonatomic, readonly, retain) NIStylesheetCache* stylesheetCache;\n\n@end\n\n"
  },
  {
    "path": "examples/css/CSSDemo/AppDelegate.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"AppDelegate.h\"\n\n// View Controllers\n#import \"RootViewController.h\"\n\n\n@implementation AppDelegate\n\n\n\n#pragma mark - Application lifecycle\n\n\n- (BOOL)              application:(UIApplication *)application\n    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];\n\n  NSString* pathPrefix = NIPathForBundleResource(nil, @\"\");\n  NSString* host = @\"http://localhost:8888/\";\n  \n  _stylesheetCache = [[NIStylesheetCache alloc] initWithPathPrefix:pathPrefix];\n  \n  _chameleonObserver = [[NIChameleonObserver alloc] initWithStylesheetCache:_stylesheetCache\n                                                                       host:host];\n  [_chameleonObserver watchSkinChanges];\n\n  RootViewController* mainController = [[RootViewController alloc] initWithNibName:nil bundle:nil];\n  \n  _rootController = [[UINavigationController alloc] initWithRootViewController:mainController];\n  self.window.rootViewController = _rootController;\n\n  [self.window makeKeyAndVisible];\n  \n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "examples/css/CSSDemo/CSSDemo-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>UIPrerenderedIcon</key>\n\t<true/>\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\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "examples/css/CSSDemo/CSSDemo-Prefix.pch",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Availability.h>\n\n#ifndef __IPHONE_3_0\n#warning \"This project uses features only available in iOS SDK 3.0 and later.\"\n#endif\n\n#ifdef __OBJC__\n  #import <UIKit/UIKit.h>\n  #import <Foundation/Foundation.h>\n#import \"NimbusCore.h\"\n#import \"NimbusCSS.h\"\n#endif\n"
  },
  {
    "path": "examples/css/CSSDemo/RootViewController.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface RootViewController : UIViewController {\n@private\n  NIDOM* _dom;\n  UIView* _backgroundView;\n  UIActivityIndicatorView* _activityIndicator;\n  UILabel* _testLabel;\n  UIButton* _button;\n}\n\n@end\n"
  },
  {
    "path": "examples/css/CSSDemo/RootViewController.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"RootViewController.h\"\n#import \"UIView+NIStyleable.h\"\n#import \"NIUserInterfaceString.h\"\n#import \"NIFoundationMethods.h\"\n#import \"NITextField.h\"\n\n#import \"AppDelegate.h\"\n\n@implementation RootViewController\n{\n  BOOL animationToggle;\n}\n\n- (void)dealloc {\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    NIStylesheetCache* stylesheetCache =\n    [(AppDelegate *)[UIApplication sharedApplication].delegate stylesheetCache];\n    NIStylesheet* stylesheet = [stylesheetCache stylesheetWithPath:@\"css/root/root.css\"];\n    NIStylesheet* common = [stylesheetCache stylesheetWithPath:@\"css/common.css\"];\n    _dom = [NIDOM domWithStylesheet:stylesheet andParentStyles:common];\n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(stylesheetDidChange)\n                                                 name:NIStylesheetDidChangeNotification\n                                               object:stylesheet];\n    self.title = @\"Nimbus CSS Demo\";\n  }\n  return self;\n}\n\n- (void)loadView {\n  [super loadView];\n\n  [_dom registerView:self.view withCSSClass:@\"background\"];\n  [self.view buildSubviews:@[\n   _backgroundView = [[UIView alloc] init], @\".noticeBox\",\n   @[\n      _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge],\n      [[UILabel alloc] init], @\".titleLabel\"\n   ],\n   [[UILabel alloc] init], @\".rightMiddleLabel\", NILocalizedStringWithDefault(@\"RightLabel\", @\"Right Middle Label\"),\n   [[UILabel alloc] init], @\".bottomLabel\", NILocalizedStringWithDefault(@\"BottomLabel\", @\"Bottom Left Label\"),\n   _button = [UIButton buttonWithType:UIButtonTypeCustom], NIInvocationWithInstanceTarget(self,@selector(buttonPress)), NILocalizedStringWithDefault(@\"TestButton\", @\"Test Button\"), @\"#TestButton\",\n   [[NITextField alloc] init], @\".textField\"\n   ]\n   inDOM:_dom];\n  \n  for (int i = 1; i <= 7; i++) {\n    UIView *box = [[UIView alloc] init];\n    [self.view addSubview:box];\n    [_dom registerView:box withCSSClass:@\"colorBox\" andId:[NSString stringWithFormat:@\"box%d\",i]];\n  }\n  [_activityIndicator startAnimating];\n  \n  NSLog(@\"%@\", [_dom descriptionForAllViews]);\n}\n\n-(void)viewWillLayoutSubviews\n{\n  [super viewWillLayoutSubviews];\n  [_dom refresh];\n}\n\n- (void)viewDidUnload {\n  [_dom unregisterAllViews];\n  \n  _activityIndicator = nil;\n  _backgroundView = nil;\n  _testLabel = nil;\n  [super viewDidUnload];\n}\n\n-(void)buttonPress\n{\n  animationToggle = !animationToggle;\n  [_dom removeCssClass:animationToggle?@\"noticeBox\":@\"noticeBoxEndpoint\" fromView: _backgroundView];\n  [UIView animateWithDuration:.5 animations:^{\n    [_dom addCssClass:animationToggle?@\"noticeBoxEndpoint\":@\"noticeBox\" toView:_backgroundView];\n  }];\n}\n\n- (void)stylesheetDidChange {\n  [_dom refresh];\n}\n\n@end\n"
  },
  {
    "path": "examples/css/CSSDemo/en.lproj/InfoPlist.strings",
    "content": "/* Localized versions of Info.plist keys */\n\n"
  },
  {
    "path": "examples/css/CSSDemo/main.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n#import \"AppDelegate.h\"\n\nint main(int argc, char *argv[]) {\n  @autoreleasepool {\n    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n  }\n}\n"
  },
  {
    "path": "examples/css/CSSDemo/resources/css/common.css",
    "content": "\nUINavigationBar {\n  -ios-tint-color: orange;\n}\n\nUIActivityIndicatorView {\n  -ios-activity-indicator-style: white-large;\n  -ios-autoresizing: left right bottom;\n  width: auto;\n  height: auto;\n  -mobile-halign: center;\n  top: 50px;\n}\n\nUILabel {\n  -ios-autoresizing: left right height width;\n  background-color: clear;\n  -ios-number-of-lines: 0;\n  color: white;\n  text-shadow: rgba(0, 0, 0, 0.5) 0 -1;\n  text-align: center;\n  font-size: 17;\n}\n\n.colorBox {\n  width: 20px;\n  height: 20px;\n}\n"
  },
  {
    "path": "examples/css/CSSDemo/resources/css/root/root.css",
    "content": ".background {\n  background-color: #aaaaaa;\n}\n\n.noticeBox {\n  background-color: rgba(32, 32, 32, 0.5);\n  border-radius: 20px;\n  border: none;\n  width: -300px;\n  height: -400px;\n  top: 10px;\n  -mobile-halign: center;\n}\n\n/* This is used in an animation block to move the view down */\n.noticeBoxEndpoint {\n  bottom: 10px;\n}\n\n.titleLabel {\n  -mobile-text-key: \"RootViewTitle\";\n  width: 100%;\n  height: auto;\n  -mobile-relative: .prev;\n  margin-top: 100px;\n}\n\n.rightMiddleLabel\n{\n  width: auto;\n  height: auto;\n  -ios-autoresizing: none;\n  -mobile-valign: middle;\n  -mobile-halign: right;\n}\n\n.bottomLabel\n{\n  width: auto;\n  height: auto;\n  -ios-autoresizing: none;\n  bottom: 0px;\n}\n\n#TestButton {\n  left: 10px;\n  -mobile-valign: middle;\n  width: 200px;\n  border-radius: 20px;\n  -ios-button-adjust: none;\n}\n\nUIButton\n{\n  color: white;\n  text-shadow: rgba(0,0,0,.9) 2px 2px;\n  background-image: url(\"btn_blue_active\");\n  -mobile-background-stretch: 0 20px 0 20px;\n  border-radius: 5px;\n  height: 77px;\n}\n\nUIButton:disabled\n{\n  color: black;\n}\n\nUIButton:selected\n{\n  color: blue;\n}\n\nUIButton:highlighted\n{\n  color: green;\n}\n\n.textField {\n  height: 70px;\n  border: 1px black;\n  width: 200px;\n  bottom: 30px;\n  right: 30px;\n  -mobile-content-valign: middle;\n  -mobile-content-halign: center;\n  -mobile-title-insets: 20px;\n}\n\n.textField:empty {\n  -mobile-text-key: \"This is blue\";\n  color: blue;\n}\n\n#box1 {\n  background-color: white;\n  bottom: 180px;\n  -mobile-halign: center;\n}\n\n#box2 {\n  background-color: green;\n  -mobile-relative: #box1;\n  margin-top: 0;\n  margin-right: 0;\n}\n\n#box3 {\n  background-color: orange;\n  -mobile-relative: #box1;\n  margin-top: 0;\n  margin-left: 0;\n}\n\n#box4 {\n  background-color: purple;\n  -mobile-relative: #box1;\n  margin-left: auto;\n  margin-top: 20px;\n}\n\n#box5 {\n  background-color: black;\n  -mobile-relative: #box4;\n  margin-left: -50%;\n  margin-top: -50%;\n}\n\n#box6 {\n  background-color: brown;\n  -mobile-relative: #box4;\n  margin-right: -50%;\n  margin-top: -50%;\n}\n#box7 {\n  background-color: blue;\n  -mobile-relative: #box1;\n  margin-top: 0;\n  margin-left: auto;\n}\n"
  },
  {
    "path": "examples/css/CSSDemo/resources/en.lproj/Localizable.strings",
    "content": "/* Remove this comment while chameleon is running and you will see string keys instead of values */\n/* SHOW KEYS */\n/*\n Localizable.strings\n */\n\"RootViewTitle\" = \"Chameleon changes skins in real time.\\n\\nStop compiling.\\nStart building.\";"
  },
  {
    "path": "examples/css/CSSDemo.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\t6601E34618B02F0700E91A07 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6601E34518B02F0700E91A07 /* SystemConfiguration.framework */; };\n\t\t6601E34718B02F0E00E91A07 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6601E34318B02EFB00E91A07 /* Security.framework */; };\n\t\t663BF6071587339A0066B814 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5FE1587339A0066B814 /* Icon-72.png */; };\n\t\t663BF6081587339A0066B814 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5FF1587339A0066B814 /* Icon-Small-50.png */; };\n\t\t663BF6091587339A0066B814 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF6001587339A0066B814 /* Icon-Small.png */; };\n\t\t663BF60A1587339A0066B814 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF6011587339A0066B814 /* Icon-Small@2x.png */; };\n\t\t663BF60B1587339A0066B814 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF6021587339A0066B814 /* Icon.png */; };\n\t\t663BF60C1587339A0066B814 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF6031587339A0066B814 /* Icon@2x.png */; };\n\t\t664EFB6615598E3D009826AB /* UIActivityIndicatorView+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 664EFB6515598E3D009826AB /* UIActivityIndicatorView+NIStyleable.m */; };\n\t\t66832D2514421450003E413C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D2414421450003E413C /* UIKit.framework */; };\n\t\t66832D2714421450003E413C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D2614421450003E413C /* Foundation.framework */; };\n\t\t66832D2914421450003E413C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D2814421450003E413C /* CoreGraphics.framework */; };\n\t\t66832D2F14421450003E413C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 66832D2D14421450003E413C /* InfoPlist.strings */; };\n\t\t66832D3114421450003E413C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832D3014421450003E413C /* main.m */; };\n\t\t66832D3514421450003E413C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832D3414421450003E413C /* AppDelegate.m */; };\n\t\t66832D9914421530003E413C /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832D9814421530003E413C /* RootViewController.m */; };\n\t\t66832DD514434FB2003E413C /* NICommonMetrics.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DAF14434FB2003E413C /* NICommonMetrics.m */; };\n\t\t66832DD714434FB2003E413C /* NIDebuggingTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DB314434FB2003E413C /* NIDebuggingTools.m */; };\n\t\t66832DD814434FB2003E413C /* NIDeviceOrientation.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DB514434FB2003E413C /* NIDeviceOrientation.m */; };\n\t\t66832DD914434FB2003E413C /* NIError.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DB714434FB2003E413C /* NIError.m */; };\n\t\t66832DDA14434FB2003E413C /* NIFoundationMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DB914434FB2003E413C /* NIFoundationMethods.m */; };\n\t\t66832DDB14434FB2003E413C /* NIInMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DBB14434FB2003E413C /* NIInMemoryCache.m */; };\n\t\t66832DDD14434FB2003E413C /* NINetworkActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DC114434FB2003E413C /* NINetworkActivity.m */; };\n\t\t66832DDE14434FB2003E413C /* NINonEmptyCollectionTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DC314434FB2003E413C /* NINonEmptyCollectionTesting.m */; };\n\t\t66832DDF14434FB2003E413C /* NINonRetainingCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DC514434FB2003E413C /* NINonRetainingCollections.m */; };\n\t\t66832DE014434FB2003E413C /* NIOperations.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DC714434FB2003E413C /* NIOperations.m */; };\n\t\t66832DE114434FB2003E413C /* NIPaths.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DC914434FB2003E413C /* NIPaths.m */; };\n\t\t66832DE214434FB2003E413C /* NIRuntimeClassModifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DCC14434FB2003E413C /* NIRuntimeClassModifications.m */; };\n\t\t66832DE314434FB2003E413C /* NISDKAvailability.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DCE14434FB2003E413C /* NISDKAvailability.m */; };\n\t\t66832DE414434FB2003E413C /* NIState.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DD014434FB2003E413C /* NIState.m */; };\n\t\t66832DFA14434FBE003E413C /* NIDOM.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DEA14434FBE003E413C /* NIDOM.m */; };\n\t\t66832DFB14434FBE003E413C /* NIStylesheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DEC14434FBE003E413C /* NIStylesheet.m */; };\n\t\t66832DFC14434FBE003E413C /* NICSSRuleSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DEE14434FBE003E413C /* NICSSRuleSet.m */; };\n\t\t66832DFD14434FBE003E413C /* UILabel+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DF014434FBE003E413C /* UILabel+NIStyleable.m */; };\n\t\t66832DFE14434FBE003E413C /* UIView+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DF214434FBE003E413C /* UIView+NIStyleable.m */; };\n\t\t66832DFF14434FBE003E413C /* UINavigationBar+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DF414434FBE003E413C /* UINavigationBar+NIStyleable.m */; };\n\t\t66832E0014434FBE003E413C /* NICSSParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DF614434FBE003E413C /* NICSSParser.m */; };\n\t\t66832E0114434FBE003E413C /* CSSTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DF714434FBE003E413C /* CSSTokenizer.m */; };\n\t\t66832E0214434FBE003E413C /* CSSTokens.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DF914434FBE003E413C /* CSSTokens.m */; };\n\t\t66832E0A14435A07003E413C /* NIChameleonObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832E0914435A07003E413C /* NIChameleonObserver.m */; };\n\t\t66832E1814442D17003E413C /* css in Resources */ = {isa = PBXBuildFile; fileRef = 66832E1714442D17003E413C /* css */; };\n\t\t668ECDCB1456438C00455266 /* NIStylesheetCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 668ECDCA1456438C00455266 /* NIStylesheetCache.m */; };\n\t\t668ECDCE145656F400455266 /* UIButton+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 668ECDCD145656F400455266 /* UIButton+NIStyleable.m */; };\n\t\t66F01FDC22F334F5007656B4 /* AFURLRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FCE22F334F4007656B4 /* AFURLRequestSerialization.m */; };\n\t\t66F01FDD22F334F5007656B4 /* AFURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FD022F334F5007656B4 /* AFURLSessionManager.m */; };\n\t\t66F01FDE22F334F5007656B4 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FD222F334F5007656B4 /* AFURLResponseSerialization.m */; };\n\t\t66F01FDF22F334F5007656B4 /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FD322F334F5007656B4 /* AFSecurityPolicy.m */; };\n\t\t66F01FE022F334F5007656B4 /* AFNetworkReachabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FD822F334F5007656B4 /* AFNetworkReachabilityManager.m */; };\n\t\t66F01FE122F334F5007656B4 /* AFHTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FDB22F334F5007656B4 /* AFHTTPSessionManager.m */; };\n\t\t66F01FF722F3361D007656B4 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66F01FF622F3361D007656B4 /* MobileCoreServices.framework */; };\n\t\t8BA77A4019468C32005ED95A /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 8BA77A3D19468C32005ED95A /* Default.png */; };\n\t\t8BA77A4119468C32005ED95A /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8BA77A3E19468C32005ED95A /* Default@2x.png */; };\n\t\t8BA77A4219468C32005ED95A /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8BA77A3F19468C32005ED95A /* Default-568h@2x.png */; };\n\t\tC743F6E416D1F4EB00A933B7 /* btn_blue_active.png in Resources */ = {isa = PBXBuildFile; fileRef = C743F6E016D1F4EB00A933B7 /* btn_blue_active.png */; };\n\t\tC743F6E516D1F4EB00A933B7 /* btn_blue_active@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C743F6E116D1F4EB00A933B7 /* btn_blue_active@2x.png */; };\n\t\tC743F6E616D1F4EB00A933B7 /* btn_blue_inactive.png in Resources */ = {isa = PBXBuildFile; fileRef = C743F6E216D1F4EB00A933B7 /* btn_blue_inactive.png */; };\n\t\tC743F6E716D1F4EB00A933B7 /* btn_blue_inactive@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C743F6E316D1F4EB00A933B7 /* btn_blue_inactive@2x.png */; };\n\t\tC743F6F416D29F2500A933B7 /* NIUserInterfaceString.m in Sources */ = {isa = PBXBuildFile; fileRef = C743F6F316D29F2500A933B7 /* NIUserInterfaceString.m */; };\n\t\tC7A8793316D7C8EC00A0C23F /* NITextField+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A8792816D7C8E900A0C23F /* NITextField+NIStyleable.m */; };\n\t\tC7A8793416D7C8EC00A0C23F /* UIScrollView+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A8792A16D7C8EA00A0C23F /* UIScrollView+NIStyleable.m */; };\n\t\tC7A8793516D7C8EC00A0C23F /* UISearchBar+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A8792C16D7C8EB00A0C23F /* UISearchBar+NIStyleable.m */; };\n\t\tC7A8793616D7C8EC00A0C23F /* UITableView+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A8792E16D7C8EB00A0C23F /* UITableView+NIStyleable.m */; };\n\t\tC7A8793716D7C8EC00A0C23F /* UITextField+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A8793016D7C8EC00A0C23F /* UITextField+NIStyleable.m */; };\n\t\tC7A8793816D7C8EC00A0C23F /* UIToolbar+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A8793216D7C8EC00A0C23F /* UIToolbar+NIStyleable.m */; };\n\t\tC7B9283F16D2B45A001BF61C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C7B9283D16D2B45A001BF61C /* Localizable.strings */; };\n\t\tC7BBC70816DDC2A600833DC9 /* NITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BBC70716DDC2A600833DC9 /* NITextField.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t6601E34318B02EFB00E91A07 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };\n\t\t6601E34518B02F0700E91A07 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };\n\t\t663BF5FE1587339A0066B814 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-72.png\"; sourceTree = \"<group>\"; };\n\t\t663BF5FF1587339A0066B814 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-Small-50.png\"; sourceTree = \"<group>\"; };\n\t\t663BF6001587339A0066B814 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-Small.png\"; sourceTree = \"<group>\"; };\n\t\t663BF6011587339A0066B814 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-Small@2x.png\"; sourceTree = \"<group>\"; };\n\t\t663BF6021587339A0066B814 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = \"<group>\"; };\n\t\t663BF6031587339A0066B814 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon@2x.png\"; sourceTree = \"<group>\"; };\n\t\t664EFB6415598E3D009826AB /* UIActivityIndicatorView+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIActivityIndicatorView+NIStyleable.h\"; path = \"../../src/css/src/UIActivityIndicatorView+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\t664EFB6515598E3D009826AB /* UIActivityIndicatorView+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UIActivityIndicatorView+NIStyleable.m\"; path = \"../../src/css/src/UIActivityIndicatorView+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\t66832D2014421450003E413C /* CSSDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CSSDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66832D2414421450003E413C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };\n\t\t66832D2614421450003E413C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };\n\t\t66832D2814421450003E413C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };\n\t\t66832D2C14421450003E413C /* CSSDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = \"CSSDemo-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t66832D2E14421450003E413C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\t66832D3014421450003E413C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = \"<group>\"; };\n\t\t66832D3214421450003E413C /* CSSDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"CSSDemo-Prefix.pch\"; sourceTree = \"<group>\"; };\n\t\t66832D3314421450003E413C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t66832D3414421450003E413C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = \"<group>\"; };\n\t\t66832D9714421530003E413C /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = \"<group>\"; };\n\t\t66832D9814421530003E413C /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = \"<group>\"; };\n\t\t66832DAE14434FB2003E413C /* NICommonMetrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICommonMetrics.h; path = ../../src/core/src/NICommonMetrics.h; sourceTree = \"<group>\"; };\n\t\t66832DAF14434FB2003E413C /* NICommonMetrics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICommonMetrics.m; path = ../../src/core/src/NICommonMetrics.m; sourceTree = \"<group>\"; };\n\t\t66832DB214434FB2003E413C /* NIDebuggingTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIDebuggingTools.h; path = ../../src/core/src/NIDebuggingTools.h; sourceTree = \"<group>\"; };\n\t\t66832DB314434FB2003E413C /* NIDebuggingTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIDebuggingTools.m; path = ../../src/core/src/NIDebuggingTools.m; sourceTree = \"<group>\"; };\n\t\t66832DB414434FB2003E413C /* NIDeviceOrientation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIDeviceOrientation.h; path = ../../src/core/src/NIDeviceOrientation.h; sourceTree = \"<group>\"; };\n\t\t66832DB514434FB2003E413C /* NIDeviceOrientation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIDeviceOrientation.m; path = ../../src/core/src/NIDeviceOrientation.m; sourceTree = \"<group>\"; };\n\t\t66832DB614434FB2003E413C /* NIError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIError.h; path = ../../src/core/src/NIError.h; sourceTree = \"<group>\"; };\n\t\t66832DB714434FB2003E413C /* NIError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIError.m; path = ../../src/core/src/NIError.m; sourceTree = \"<group>\"; };\n\t\t66832DB814434FB2003E413C /* NIFoundationMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIFoundationMethods.h; path = ../../src/core/src/NIFoundationMethods.h; sourceTree = \"<group>\"; };\n\t\t66832DB914434FB2003E413C /* NIFoundationMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIFoundationMethods.m; path = ../../src/core/src/NIFoundationMethods.m; sourceTree = \"<group>\"; };\n\t\t66832DBA14434FB2003E413C /* NIInMemoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIInMemoryCache.h; path = ../../src/core/src/NIInMemoryCache.h; sourceTree = \"<group>\"; };\n\t\t66832DBB14434FB2003E413C /* NIInMemoryCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIInMemoryCache.m; path = ../../src/core/src/NIInMemoryCache.m; sourceTree = \"<group>\"; };\n\t\t66832DBC14434FB2003E413C /* NimbusCore+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NimbusCore+Additions.h\"; path = \"../../src/core/src/NimbusCore+Additions.h\"; sourceTree = \"<group>\"; };\n\t\t66832DBD14434FB2003E413C /* NimbusCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusCore.h; path = ../../src/core/src/NimbusCore.h; sourceTree = \"<group>\"; };\n\t\t66832DC014434FB2003E413C /* NINetworkActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINetworkActivity.h; path = ../../src/core/src/NINetworkActivity.h; sourceTree = \"<group>\"; };\n\t\t66832DC114434FB2003E413C /* NINetworkActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINetworkActivity.m; path = ../../src/core/src/NINetworkActivity.m; sourceTree = \"<group>\"; };\n\t\t66832DC214434FB2003E413C /* NINonEmptyCollectionTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINonEmptyCollectionTesting.h; path = ../../src/core/src/NINonEmptyCollectionTesting.h; sourceTree = \"<group>\"; };\n\t\t66832DC314434FB2003E413C /* NINonEmptyCollectionTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINonEmptyCollectionTesting.m; path = ../../src/core/src/NINonEmptyCollectionTesting.m; sourceTree = \"<group>\"; };\n\t\t66832DC414434FB2003E413C /* NINonRetainingCollections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINonRetainingCollections.h; path = ../../src/core/src/NINonRetainingCollections.h; sourceTree = \"<group>\"; };\n\t\t66832DC514434FB2003E413C /* NINonRetainingCollections.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINonRetainingCollections.m; path = ../../src/core/src/NINonRetainingCollections.m; sourceTree = \"<group>\"; };\n\t\t66832DC614434FB2003E413C /* NIOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOperations.h; path = ../../src/core/src/NIOperations.h; sourceTree = \"<group>\"; };\n\t\t66832DC714434FB2003E413C /* NIOperations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOperations.m; path = ../../src/core/src/NIOperations.m; sourceTree = \"<group>\"; };\n\t\t66832DC814434FB2003E413C /* NIPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPaths.h; path = ../../src/core/src/NIPaths.h; sourceTree = \"<group>\"; };\n\t\t66832DC914434FB2003E413C /* NIPaths.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIPaths.m; path = ../../src/core/src/NIPaths.m; sourceTree = \"<group>\"; };\n\t\t66832DCA14434FB2003E413C /* NIPreprocessorMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPreprocessorMacros.h; path = ../../src/core/src/NIPreprocessorMacros.h; sourceTree = \"<group>\"; };\n\t\t66832DCB14434FB2003E413C /* NIRuntimeClassModifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIRuntimeClassModifications.h; path = ../../src/core/src/NIRuntimeClassModifications.h; sourceTree = \"<group>\"; };\n\t\t66832DCC14434FB2003E413C /* NIRuntimeClassModifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIRuntimeClassModifications.m; path = ../../src/core/src/NIRuntimeClassModifications.m; sourceTree = \"<group>\"; };\n\t\t66832DCD14434FB2003E413C /* NISDKAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NISDKAvailability.h; path = ../../src/core/src/NISDKAvailability.h; sourceTree = \"<group>\"; };\n\t\t66832DCE14434FB2003E413C /* NISDKAvailability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NISDKAvailability.m; path = ../../src/core/src/NISDKAvailability.m; sourceTree = \"<group>\"; };\n\t\t66832DCF14434FB2003E413C /* NIState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIState.h; path = ../../src/core/src/NIState.h; sourceTree = \"<group>\"; };\n\t\t66832DD014434FB2003E413C /* NIState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIState.m; path = ../../src/core/src/NIState.m; sourceTree = \"<group>\"; };\n\t\t66832DE714434FBE003E413C /* NimbusCSS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusCSS.h; path = ../../src/css/src/NimbusCSS.h; sourceTree = \"<group>\"; };\n\t\t66832DE814434FBE003E413C /* NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIStyleable.h; path = ../../src/css/src/NIStyleable.h; sourceTree = \"<group>\"; };\n\t\t66832DE914434FBE003E413C /* NIDOM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIDOM.h; path = ../../src/css/src/NIDOM.h; sourceTree = \"<group>\"; };\n\t\t66832DEA14434FBE003E413C /* NIDOM.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIDOM.m; path = ../../src/css/src/NIDOM.m; sourceTree = \"<group>\"; };\n\t\t66832DEB14434FBE003E413C /* NIStylesheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIStylesheet.h; path = ../../src/css/src/NIStylesheet.h; sourceTree = \"<group>\"; };\n\t\t66832DEC14434FBE003E413C /* NIStylesheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIStylesheet.m; path = ../../src/css/src/NIStylesheet.m; sourceTree = \"<group>\"; };\n\t\t66832DED14434FBE003E413C /* NICSSRuleSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICSSRuleSet.h; path = ../../src/css/src/NICSSRuleSet.h; sourceTree = \"<group>\"; };\n\t\t66832DEE14434FBE003E413C /* NICSSRuleSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICSSRuleSet.m; path = ../../src/css/src/NICSSRuleSet.m; sourceTree = \"<group>\"; };\n\t\t66832DEF14434FBE003E413C /* UILabel+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UILabel+NIStyleable.h\"; path = \"../../src/css/src/UILabel+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\t66832DF014434FBE003E413C /* UILabel+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UILabel+NIStyleable.m\"; path = \"../../src/css/src/UILabel+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\t66832DF114434FBE003E413C /* UIView+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIView+NIStyleable.h\"; path = \"../../src/css/src/UIView+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\t66832DF214434FBE003E413C /* UIView+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; name = \"UIView+NIStyleable.m\"; path = \"../../src/css/src/UIView+NIStyleable.m\"; sourceTree = \"<group>\"; tabWidth = 2; };\n\t\t66832DF314434FBE003E413C /* UINavigationBar+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UINavigationBar+NIStyleable.h\"; path = \"../../src/css/src/UINavigationBar+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\t66832DF414434FBE003E413C /* UINavigationBar+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UINavigationBar+NIStyleable.m\"; path = \"../../src/css/src/UINavigationBar+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\t66832DF514434FBE003E413C /* NICSSParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICSSParser.h; path = ../../src/css/src/NICSSParser.h; sourceTree = \"<group>\"; };\n\t\t66832DF614434FBE003E413C /* NICSSParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICSSParser.m; path = ../../src/css/src/NICSSParser.m; sourceTree = \"<group>\"; };\n\t\t66832DF714434FBE003E413C /* CSSTokenizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CSSTokenizer.m; path = ../../src/css/src/CSSTokenizer.m; sourceTree = \"<group>\"; };\n\t\t66832DF814434FBE003E413C /* CSSTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSTokens.h; path = ../../src/css/src/CSSTokens.h; sourceTree = \"<group>\"; };\n\t\t66832DF914434FBE003E413C /* CSSTokens.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CSSTokens.m; path = ../../src/css/src/CSSTokens.m; sourceTree = \"<group>\"; };\n\t\t66832E0814435A07003E413C /* NIChameleonObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIChameleonObserver.h; path = ../../src/css/src/NIChameleonObserver.h; sourceTree = \"<group>\"; };\n\t\t66832E0914435A07003E413C /* NIChameleonObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIChameleonObserver.m; path = ../../src/css/src/NIChameleonObserver.m; sourceTree = \"<group>\"; };\n\t\t66832E1714442D17003E413C /* css */ = {isa = PBXFileReference; lastKnownFileType = folder; name = css; path = resources/css; sourceTree = \"<group>\"; };\n\t\t668ECDC91456438C00455266 /* NIStylesheetCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIStylesheetCache.h; path = ../../src/css/src/NIStylesheetCache.h; sourceTree = \"<group>\"; };\n\t\t668ECDCA1456438C00455266 /* NIStylesheetCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIStylesheetCache.m; path = ../../src/css/src/NIStylesheetCache.m; sourceTree = \"<group>\"; };\n\t\t668ECDCC145656F300455266 /* UIButton+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIButton+NIStyleable.h\"; path = \"../../src/css/src/UIButton+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\t668ECDCD145656F400455266 /* UIButton+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UIButton+NIStyleable.m\"; path = \"../../src/css/src/UIButton+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\t66F01FCE22F334F4007656B4 /* AFURLRequestSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLRequestSerialization.m; sourceTree = \"<group>\"; };\n\t\t66F01FCF22F334F5007656B4 /* AFCompatibilityMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFCompatibilityMacros.h; sourceTree = \"<group>\"; };\n\t\t66F01FD022F334F5007656B4 /* AFURLSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLSessionManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FD122F334F5007656B4 /* AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworking.h; sourceTree = \"<group>\"; };\n\t\t66F01FD222F334F5007656B4 /* AFURLResponseSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLResponseSerialization.m; sourceTree = \"<group>\"; };\n\t\t66F01FD322F334F5007656B4 /* AFSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSecurityPolicy.m; sourceTree = \"<group>\"; };\n\t\t66F01FD422F334F5007656B4 /* AFURLRequestSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLRequestSerialization.h; sourceTree = \"<group>\"; };\n\t\t66F01FD522F334F5007656B4 /* AFURLSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLSessionManager.h; sourceTree = \"<group>\"; };\n\t\t66F01FD622F334F5007656B4 /* AFNetworkReachabilityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworkReachabilityManager.h; sourceTree = \"<group>\"; };\n\t\t66F01FD722F334F5007656B4 /* AFSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSecurityPolicy.h; sourceTree = \"<group>\"; };\n\t\t66F01FD822F334F5007656B4 /* AFNetworkReachabilityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFNetworkReachabilityManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FD922F334F5007656B4 /* AFHTTPSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPSessionManager.h; sourceTree = \"<group>\"; };\n\t\t66F01FDA22F334F5007656B4 /* AFURLResponseSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLResponseSerialization.h; sourceTree = \"<group>\"; };\n\t\t66F01FDB22F334F5007656B4 /* AFHTTPSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPSessionManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FF622F3361D007656B4 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };\n\t\t8BA77A3D19468C32005ED95A /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = \"<group>\"; };\n\t\t8BA77A3E19468C32005ED95A /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Default@2x.png\"; sourceTree = \"<group>\"; };\n\t\t8BA77A3F19468C32005ED95A /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Default-568h@2x.png\"; sourceTree = \"<group>\"; };\n\t\tC743F6E016D1F4EB00A933B7 /* btn_blue_active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = btn_blue_active.png; path = resources/btn_blue_active.png; sourceTree = \"<group>\"; };\n\t\tC743F6E116D1F4EB00A933B7 /* btn_blue_active@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = \"btn_blue_active@2x.png\"; path = \"resources/btn_blue_active@2x.png\"; sourceTree = \"<group>\"; };\n\t\tC743F6E216D1F4EB00A933B7 /* btn_blue_inactive.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = btn_blue_inactive.png; path = resources/btn_blue_inactive.png; sourceTree = \"<group>\"; };\n\t\tC743F6E316D1F4EB00A933B7 /* btn_blue_inactive@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = \"btn_blue_inactive@2x.png\"; path = \"resources/btn_blue_inactive@2x.png\"; sourceTree = \"<group>\"; };\n\t\tC743F6F316D29F2500A933B7 /* NIUserInterfaceString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIUserInterfaceString.m; path = ../../src/css/src/NIUserInterfaceString.m; sourceTree = \"<group>\"; };\n\t\tC743F6F516D2AAC200A933B7 /* NIUserInterfaceString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIUserInterfaceString.h; path = ../../src/css/src/NIUserInterfaceString.h; sourceTree = \"<group>\"; };\n\t\tC7A8792716D7C8E900A0C23F /* NITextField+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NITextField+NIStyleable.h\"; path = \"../../src/css/src/NITextField+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\tC7A8792816D7C8E900A0C23F /* NITextField+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"NITextField+NIStyleable.m\"; path = \"../../src/css/src/NITextField+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\tC7A8792916D7C8EA00A0C23F /* UIScrollView+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIScrollView+NIStyleable.h\"; path = \"../../src/css/src/UIScrollView+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\tC7A8792A16D7C8EA00A0C23F /* UIScrollView+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UIScrollView+NIStyleable.m\"; path = \"../../src/css/src/UIScrollView+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\tC7A8792B16D7C8EA00A0C23F /* UISearchBar+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UISearchBar+NIStyleable.h\"; path = \"../../src/css/src/UISearchBar+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\tC7A8792C16D7C8EB00A0C23F /* UISearchBar+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UISearchBar+NIStyleable.m\"; path = \"../../src/css/src/UISearchBar+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\tC7A8792D16D7C8EB00A0C23F /* UITableView+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UITableView+NIStyleable.h\"; path = \"../../src/css/src/UITableView+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\tC7A8792E16D7C8EB00A0C23F /* UITableView+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UITableView+NIStyleable.m\"; path = \"../../src/css/src/UITableView+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\tC7A8792F16D7C8EB00A0C23F /* UITextField+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UITextField+NIStyleable.h\"; path = \"../../src/css/src/UITextField+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\tC7A8793016D7C8EC00A0C23F /* UITextField+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UITextField+NIStyleable.m\"; path = \"../../src/css/src/UITextField+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\tC7A8793116D7C8EC00A0C23F /* UIToolbar+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIToolbar+NIStyleable.h\"; path = \"../../src/css/src/UIToolbar+NIStyleable.h\"; sourceTree = \"<group>\"; };\n\t\tC7A8793216D7C8EC00A0C23F /* UIToolbar+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UIToolbar+NIStyleable.m\"; path = \"../../src/css/src/UIToolbar+NIStyleable.m\"; sourceTree = \"<group>\"; };\n\t\tC7B9283E16D2B45A001BF61C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = resources/en.lproj/Localizable.strings; sourceTree = \"<group>\"; };\n\t\tC7BBC70616DDC2A600833DC9 /* NITextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NITextField.h; path = ../../src/textfield/src/NITextField.h; sourceTree = \"<group>\"; };\n\t\tC7BBC70716DDC2A600833DC9 /* NITextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NITextField.m; path = ../../src/textfield/src/NITextField.m; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t66832D1D14421450003E413C /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66F01FF722F3361D007656B4 /* MobileCoreServices.framework in Frameworks */,\n\t\t\t\t6601E34718B02F0E00E91A07 /* Security.framework in Frameworks */,\n\t\t\t\t6601E34618B02F0700E91A07 /* SystemConfiguration.framework in Frameworks */,\n\t\t\t\t66832D2514421450003E413C /* UIKit.framework in Frameworks */,\n\t\t\t\t66832D2714421450003E413C /* Foundation.framework in Frameworks */,\n\t\t\t\t66832D2914421450003E413C /* CoreGraphics.framework 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\t663BF6041587339A0066B814 /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8BA77A3D19468C32005ED95A /* Default.png */,\n\t\t\t\t8BA77A3E19468C32005ED95A /* Default@2x.png */,\n\t\t\t\t8BA77A3F19468C32005ED95A /* Default-568h@2x.png */,\n\t\t\t\t663BF5FE1587339A0066B814 /* Icon-72.png */,\n\t\t\t\t663BF5FF1587339A0066B814 /* Icon-Small-50.png */,\n\t\t\t\t663BF6001587339A0066B814 /* Icon-Small.png */,\n\t\t\t\t663BF6011587339A0066B814 /* Icon-Small@2x.png */,\n\t\t\t\t663BF6021587339A0066B814 /* Icon.png */,\n\t\t\t\t663BF6031587339A0066B814 /* Icon@2x.png */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tpath = ../../src/resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D1514421450003E413C = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832D2A14421450003E413C /* CSSDemo */,\n\t\t\t\t66832D40144214CD003E413C /* Nimbus */,\n\t\t\t\t66D2FE0B15941EEB00B2BEFD /* AFNetworking */,\n\t\t\t\t66832D2314421450003E413C /* Frameworks */,\n\t\t\t\t66832D2114421450003E413C /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D2114421450003E413C /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832D2014421450003E413C /* CSSDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D2314421450003E413C /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66F01FF622F3361D007656B4 /* MobileCoreServices.framework */,\n\t\t\t\t6601E34518B02F0700E91A07 /* SystemConfiguration.framework */,\n\t\t\t\t6601E34318B02EFB00E91A07 /* Security.framework */,\n\t\t\t\t66832D2414421450003E413C /* UIKit.framework */,\n\t\t\t\t66832D2614421450003E413C /* Foundation.framework */,\n\t\t\t\t66832D2814421450003E413C /* CoreGraphics.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D2A14421450003E413C /* CSSDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832D3214421450003E413C /* CSSDemo-Prefix.pch */,\n\t\t\t\t66832D3F14421483003E413C /* Source */,\n\t\t\t\t66832D2B14421450003E413C /* Resources */,\n\t\t\t);\n\t\t\tpath = CSSDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D2B14421450003E413C /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC7B9283D16D2B45A001BF61C /* Localizable.strings */,\n\t\t\t\tC743F6E016D1F4EB00A933B7 /* btn_blue_active.png */,\n\t\t\t\tC743F6E116D1F4EB00A933B7 /* btn_blue_active@2x.png */,\n\t\t\t\tC743F6E216D1F4EB00A933B7 /* btn_blue_inactive.png */,\n\t\t\t\tC743F6E316D1F4EB00A933B7 /* btn_blue_inactive@2x.png */,\n\t\t\t\t66832E1714442D17003E413C /* css */,\n\t\t\t\t66832D2C14421450003E413C /* CSSDemo-Info.plist */,\n\t\t\t\t66832D2D14421450003E413C /* InfoPlist.strings */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D3F14421483003E413C /* Source */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832D961442151B003E413C /* Controllers */,\n\t\t\t\t66832D3314421450003E413C /* AppDelegate.h */,\n\t\t\t\t66832D3414421450003E413C /* AppDelegate.m */,\n\t\t\t\t66832D3014421450003E413C /* main.m */,\n\t\t\t);\n\t\t\tname = Source;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D40144214CD003E413C /* Nimbus */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC7BBC70516DDC20100833DC9 /* TextField */,\n\t\t\t\t663BF6041587339A0066B814 /* Resources */,\n\t\t\t\t66832D41144214DA003E413C /* Core */,\n\t\t\t\t66832D7C144214EF003E413C /* CSS */,\n\t\t\t);\n\t\t\tname = Nimbus;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D41144214DA003E413C /* Core */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832DAE14434FB2003E413C /* NICommonMetrics.h */,\n\t\t\t\t66832DAF14434FB2003E413C /* NICommonMetrics.m */,\n\t\t\t\t66832DB214434FB2003E413C /* NIDebuggingTools.h */,\n\t\t\t\t66832DB314434FB2003E413C /* NIDebuggingTools.m */,\n\t\t\t\t66832DB414434FB2003E413C /* NIDeviceOrientation.h */,\n\t\t\t\t66832DB514434FB2003E413C /* NIDeviceOrientation.m */,\n\t\t\t\t66832DB614434FB2003E413C /* NIError.h */,\n\t\t\t\t66832DB714434FB2003E413C /* NIError.m */,\n\t\t\t\t66832DB814434FB2003E413C /* NIFoundationMethods.h */,\n\t\t\t\t66832DB914434FB2003E413C /* NIFoundationMethods.m */,\n\t\t\t\t66832DBA14434FB2003E413C /* NIInMemoryCache.h */,\n\t\t\t\t66832DBB14434FB2003E413C /* NIInMemoryCache.m */,\n\t\t\t\t66832DBC14434FB2003E413C /* NimbusCore+Additions.h */,\n\t\t\t\t66832DBD14434FB2003E413C /* NimbusCore.h */,\n\t\t\t\t66832DC014434FB2003E413C /* NINetworkActivity.h */,\n\t\t\t\t66832DC114434FB2003E413C /* NINetworkActivity.m */,\n\t\t\t\t66832DC214434FB2003E413C /* NINonEmptyCollectionTesting.h */,\n\t\t\t\t66832DC314434FB2003E413C /* NINonEmptyCollectionTesting.m */,\n\t\t\t\t66832DC414434FB2003E413C /* NINonRetainingCollections.h */,\n\t\t\t\t66832DC514434FB2003E413C /* NINonRetainingCollections.m */,\n\t\t\t\t66832DC614434FB2003E413C /* NIOperations.h */,\n\t\t\t\t66832DC714434FB2003E413C /* NIOperations.m */,\n\t\t\t\t66832DC814434FB2003E413C /* NIPaths.h */,\n\t\t\t\t66832DC914434FB2003E413C /* NIPaths.m */,\n\t\t\t\t66832DCA14434FB2003E413C /* NIPreprocessorMacros.h */,\n\t\t\t\t66832DCB14434FB2003E413C /* NIRuntimeClassModifications.h */,\n\t\t\t\t66832DCC14434FB2003E413C /* NIRuntimeClassModifications.m */,\n\t\t\t\t66832DCD14434FB2003E413C /* NISDKAvailability.h */,\n\t\t\t\t66832DCE14434FB2003E413C /* NISDKAvailability.m */,\n\t\t\t\t66832DCF14434FB2003E413C /* NIState.h */,\n\t\t\t\t66832DD014434FB2003E413C /* NIState.m */,\n\t\t\t);\n\t\t\tname = Core;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D7C144214EF003E413C /* CSS */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC7A8792716D7C8E900A0C23F /* NITextField+NIStyleable.h */,\n\t\t\t\tC7A8792816D7C8E900A0C23F /* NITextField+NIStyleable.m */,\n\t\t\t\tC7A8792916D7C8EA00A0C23F /* UIScrollView+NIStyleable.h */,\n\t\t\t\tC7A8792A16D7C8EA00A0C23F /* UIScrollView+NIStyleable.m */,\n\t\t\t\tC7A8792B16D7C8EA00A0C23F /* UISearchBar+NIStyleable.h */,\n\t\t\t\tC7A8792C16D7C8EB00A0C23F /* UISearchBar+NIStyleable.m */,\n\t\t\t\tC7A8792D16D7C8EB00A0C23F /* UITableView+NIStyleable.h */,\n\t\t\t\tC7A8792E16D7C8EB00A0C23F /* UITableView+NIStyleable.m */,\n\t\t\t\tC7A8792F16D7C8EB00A0C23F /* UITextField+NIStyleable.h */,\n\t\t\t\tC7A8793016D7C8EC00A0C23F /* UITextField+NIStyleable.m */,\n\t\t\t\tC7A8793116D7C8EC00A0C23F /* UIToolbar+NIStyleable.h */,\n\t\t\t\tC7A8793216D7C8EC00A0C23F /* UIToolbar+NIStyleable.m */,\n\t\t\t\t66832DE714434FBE003E413C /* NimbusCSS.h */,\n\t\t\t\t66832DE814434FBE003E413C /* NIStyleable.h */,\n\t\t\t\t66832DED14434FBE003E413C /* NICSSRuleSet.h */,\n\t\t\t\t66832DEE14434FBE003E413C /* NICSSRuleSet.m */,\n\t\t\t\t66832DE914434FBE003E413C /* NIDOM.h */,\n\t\t\t\t66832DEA14434FBE003E413C /* NIDOM.m */,\n\t\t\t\t66832DEB14434FBE003E413C /* NIStylesheet.h */,\n\t\t\t\t66832DEC14434FBE003E413C /* NIStylesheet.m */,\n\t\t\t\t668ECDC91456438C00455266 /* NIStylesheetCache.h */,\n\t\t\t\t668ECDCA1456438C00455266 /* NIStylesheetCache.m */,\n\t\t\t\t664EFB6415598E3D009826AB /* UIActivityIndicatorView+NIStyleable.h */,\n\t\t\t\t664EFB6515598E3D009826AB /* UIActivityIndicatorView+NIStyleable.m */,\n\t\t\t\t668ECDCC145656F300455266 /* UIButton+NIStyleable.h */,\n\t\t\t\t668ECDCD145656F400455266 /* UIButton+NIStyleable.m */,\n\t\t\t\t66832DEF14434FBE003E413C /* UILabel+NIStyleable.h */,\n\t\t\t\t66832DF014434FBE003E413C /* UILabel+NIStyleable.m */,\n\t\t\t\t66832DF114434FBE003E413C /* UIView+NIStyleable.h */,\n\t\t\t\t66832DF214434FBE003E413C /* UIView+NIStyleable.m */,\n\t\t\t\t66832DF314434FBE003E413C /* UINavigationBar+NIStyleable.h */,\n\t\t\t\t66832DF414434FBE003E413C /* UINavigationBar+NIStyleable.m */,\n\t\t\t\t66832DF514434FBE003E413C /* NICSSParser.h */,\n\t\t\t\t66832DF614434FBE003E413C /* NICSSParser.m */,\n\t\t\t\t66832DF714434FBE003E413C /* CSSTokenizer.m */,\n\t\t\t\t66832DF814434FBE003E413C /* CSSTokens.h */,\n\t\t\t\t66832DF914434FBE003E413C /* CSSTokens.m */,\n\t\t\t\t66832E0814435A07003E413C /* NIChameleonObserver.h */,\n\t\t\t\t66832E0914435A07003E413C /* NIChameleonObserver.m */,\n\t\t\t\tC743F6F516D2AAC200A933B7 /* NIUserInterfaceString.h */,\n\t\t\t\tC743F6F316D29F2500A933B7 /* NIUserInterfaceString.m */,\n\t\t\t);\n\t\t\tname = CSS;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D961442151B003E413C /* Controllers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832D9714421530003E413C /* RootViewController.h */,\n\t\t\t\t66832D9814421530003E413C /* RootViewController.m */,\n\t\t\t);\n\t\t\tname = Controllers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66D2FE0B15941EEB00B2BEFD /* AFNetworking */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66F01FCF22F334F5007656B4 /* AFCompatibilityMacros.h */,\n\t\t\t\t66F01FD922F334F5007656B4 /* AFHTTPSessionManager.h */,\n\t\t\t\t66F01FDB22F334F5007656B4 /* AFHTTPSessionManager.m */,\n\t\t\t\t66F01FD122F334F5007656B4 /* AFNetworking.h */,\n\t\t\t\t66F01FD622F334F5007656B4 /* AFNetworkReachabilityManager.h */,\n\t\t\t\t66F01FD822F334F5007656B4 /* AFNetworkReachabilityManager.m */,\n\t\t\t\t66F01FD722F334F5007656B4 /* AFSecurityPolicy.h */,\n\t\t\t\t66F01FD322F334F5007656B4 /* AFSecurityPolicy.m */,\n\t\t\t\t66F01FD422F334F5007656B4 /* AFURLRequestSerialization.h */,\n\t\t\t\t66F01FCE22F334F4007656B4 /* AFURLRequestSerialization.m */,\n\t\t\t\t66F01FDA22F334F5007656B4 /* AFURLResponseSerialization.h */,\n\t\t\t\t66F01FD222F334F5007656B4 /* AFURLResponseSerialization.m */,\n\t\t\t\t66F01FD522F334F5007656B4 /* AFURLSessionManager.h */,\n\t\t\t\t66F01FD022F334F5007656B4 /* AFURLSessionManager.m */,\n\t\t\t);\n\t\t\tname = AFNetworking;\n\t\t\tpath = ../../thirdparty/AFNetworking/AFNetworking;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC7BBC70516DDC20100833DC9 /* TextField */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC7BBC70616DDC2A600833DC9 /* NITextField.h */,\n\t\t\t\tC7BBC70716DDC2A600833DC9 /* NITextField.m */,\n\t\t\t);\n\t\t\tname = TextField;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t66832D1F14421450003E413C /* CSSDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66832D3814421450003E413C /* Build configuration list for PBXNativeTarget \"CSSDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66832D1C14421450003E413C /* Sources */,\n\t\t\t\t66832D1D14421450003E413C /* Frameworks */,\n\t\t\t\t66832D1E14421450003E413C /* 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 = CSSDemo;\n\t\t\tproductName = CSSDemo;\n\t\t\tproductReference = 66832D2014421450003E413C /* CSSDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t66832D1714421450003E413C /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1100;\n\t\t\t};\n\t\t\tbuildConfigurationList = 66832D1A14421450003E413C /* Build configuration list for PBXProject \"CSSDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 66832D1514421450003E413C;\n\t\t\tproductRefGroup = 66832D2114421450003E413C /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t66832D1F14421450003E413C /* CSSDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t66832D1E14421450003E413C /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66832D2F14421450003E413C /* InfoPlist.strings in Resources */,\n\t\t\t\t66832E1814442D17003E413C /* css in Resources */,\n\t\t\t\t663BF6071587339A0066B814 /* Icon-72.png in Resources */,\n\t\t\t\t663BF6081587339A0066B814 /* Icon-Small-50.png in Resources */,\n\t\t\t\t663BF6091587339A0066B814 /* Icon-Small.png in Resources */,\n\t\t\t\t663BF60A1587339A0066B814 /* Icon-Small@2x.png in Resources */,\n\t\t\t\t663BF60B1587339A0066B814 /* Icon.png in Resources */,\n\t\t\t\t663BF60C1587339A0066B814 /* Icon@2x.png in Resources */,\n\t\t\t\tC743F6E416D1F4EB00A933B7 /* btn_blue_active.png in Resources */,\n\t\t\t\tC743F6E516D1F4EB00A933B7 /* btn_blue_active@2x.png in Resources */,\n\t\t\t\tC743F6E616D1F4EB00A933B7 /* btn_blue_inactive.png in Resources */,\n\t\t\t\t8BA77A4019468C32005ED95A /* Default.png in Resources */,\n\t\t\t\t8BA77A4119468C32005ED95A /* Default@2x.png in Resources */,\n\t\t\t\t8BA77A4219468C32005ED95A /* Default-568h@2x.png in Resources */,\n\t\t\t\tC743F6E716D1F4EB00A933B7 /* btn_blue_inactive@2x.png in Resources */,\n\t\t\t\tC7B9283F16D2B45A001BF61C /* Localizable.strings 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\t66832D1C14421450003E413C /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66832D3114421450003E413C /* main.m in Sources */,\n\t\t\t\t66832D3514421450003E413C /* AppDelegate.m in Sources */,\n\t\t\t\t66832D9914421530003E413C /* RootViewController.m in Sources */,\n\t\t\t\t66832DD514434FB2003E413C /* NICommonMetrics.m in Sources */,\n\t\t\t\t66832DD714434FB2003E413C /* NIDebuggingTools.m in Sources */,\n\t\t\t\t66832DD814434FB2003E413C /* NIDeviceOrientation.m in Sources */,\n\t\t\t\t66F01FDC22F334F5007656B4 /* AFURLRequestSerialization.m in Sources */,\n\t\t\t\t66832DD914434FB2003E413C /* NIError.m in Sources */,\n\t\t\t\t66832DDA14434FB2003E413C /* NIFoundationMethods.m in Sources */,\n\t\t\t\t66832DDB14434FB2003E413C /* NIInMemoryCache.m in Sources */,\n\t\t\t\t66832DDD14434FB2003E413C /* NINetworkActivity.m in Sources */,\n\t\t\t\t66832DDE14434FB2003E413C /* NINonEmptyCollectionTesting.m in Sources */,\n\t\t\t\t66F01FE022F334F5007656B4 /* AFNetworkReachabilityManager.m in Sources */,\n\t\t\t\t66832DDF14434FB2003E413C /* NINonRetainingCollections.m in Sources */,\n\t\t\t\t66832DE014434FB2003E413C /* NIOperations.m in Sources */,\n\t\t\t\t66832DE114434FB2003E413C /* NIPaths.m in Sources */,\n\t\t\t\t66832DE214434FB2003E413C /* NIRuntimeClassModifications.m in Sources */,\n\t\t\t\t66832DE314434FB2003E413C /* NISDKAvailability.m in Sources */,\n\t\t\t\t66832DE414434FB2003E413C /* NIState.m in Sources */,\n\t\t\t\t66832DFA14434FBE003E413C /* NIDOM.m in Sources */,\n\t\t\t\t66832DFB14434FBE003E413C /* NIStylesheet.m in Sources */,\n\t\t\t\t66832DFC14434FBE003E413C /* NICSSRuleSet.m in Sources */,\n\t\t\t\t66832DFD14434FBE003E413C /* UILabel+NIStyleable.m in Sources */,\n\t\t\t\t66832DFE14434FBE003E413C /* UIView+NIStyleable.m in Sources */,\n\t\t\t\t66832DFF14434FBE003E413C /* UINavigationBar+NIStyleable.m in Sources */,\n\t\t\t\t66832E0014434FBE003E413C /* NICSSParser.m in Sources */,\n\t\t\t\t66F01FDD22F334F5007656B4 /* AFURLSessionManager.m in Sources */,\n\t\t\t\t66F01FE122F334F5007656B4 /* AFHTTPSessionManager.m in Sources */,\n\t\t\t\t66832E0114434FBE003E413C /* CSSTokenizer.m in Sources */,\n\t\t\t\t66832E0214434FBE003E413C /* CSSTokens.m in Sources */,\n\t\t\t\t66F01FDF22F334F5007656B4 /* AFSecurityPolicy.m in Sources */,\n\t\t\t\t66832E0A14435A07003E413C /* NIChameleonObserver.m in Sources */,\n\t\t\t\t668ECDCB1456438C00455266 /* NIStylesheetCache.m in Sources */,\n\t\t\t\t668ECDCE145656F400455266 /* UIButton+NIStyleable.m in Sources */,\n\t\t\t\t664EFB6615598E3D009826AB /* UIActivityIndicatorView+NIStyleable.m in Sources */,\n\t\t\t\tC743F6F416D29F2500A933B7 /* NIUserInterfaceString.m in Sources */,\n\t\t\t\tC7A8793316D7C8EC00A0C23F /* NITextField+NIStyleable.m in Sources */,\n\t\t\t\tC7A8793416D7C8EC00A0C23F /* UIScrollView+NIStyleable.m in Sources */,\n\t\t\t\tC7A8793516D7C8EC00A0C23F /* UISearchBar+NIStyleable.m in Sources */,\n\t\t\t\tC7A8793616D7C8EC00A0C23F /* UITableView+NIStyleable.m in Sources */,\n\t\t\t\tC7A8793716D7C8EC00A0C23F /* UITextField+NIStyleable.m in Sources */,\n\t\t\t\t66F01FDE22F334F5007656B4 /* AFURLResponseSerialization.m in Sources */,\n\t\t\t\tC7A8793816D7C8EC00A0C23F /* UIToolbar+NIStyleable.m in Sources */,\n\t\t\t\tC7BBC70816DDC2A600833DC9 /* NITextField.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t66832D2D14421450003E413C /* InfoPlist.strings */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t66832D2E14421450003E413C /* en */,\n\t\t\t);\n\t\t\tname = InfoPlist.strings;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC7B9283D16D2B45A001BF61C /* Localizable.strings */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tC7B9283E16D2B45A001BF61C /* en */,\n\t\t\t);\n\t\t\tname = Localizable.strings;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t66832D3614421450003E413C /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66832D3714421450003E413C /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tOTHER_CFLAGS = \"-DNS_BLOCK_ASSERTIONS=1\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66832D3914421450003E413C /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer: Jeffrey Verkoeyen (MCEM7RED85)\";\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = c11;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"CSSDemo/CSSDemo-Prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"CSSDemo/CSSDemo-Info.plist\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.nimbus.css.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE = \"06911D0B-8A67-4981-A7DE-12C7A0C08610\";\n\t\t\t\tWRAPPER_EXTENSION = app;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66832D3A14421450003E413C /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer: Jeffrey Verkoeyen (MCEM7RED85)\";\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = c11;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"CSSDemo/CSSDemo-Prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"CSSDemo/CSSDemo-Info.plist\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.nimbus.css.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE = \"06911D0B-8A67-4981-A7DE-12C7A0C08610\";\n\t\t\t\tWRAPPER_EXTENSION = app;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t66832D1A14421450003E413C /* Build configuration list for PBXProject \"CSSDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66832D3614421450003E413C /* Debug */,\n\t\t\t\t66832D3714421450003E413C /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66832D3814421450003E413C /* Build configuration list for PBXNativeTarget \"CSSDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66832D3914421450003E413C /* Debug */,\n\t\t\t\t66832D3A14421450003E413C /* 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 = 66832D1714421450003E413C /* Project object */;\n}\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/NetworkPhotoAlbum.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\t1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };\n\t\t1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };\n\t\t288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; };\n\t\t660F62BD18AEA881005AAA18 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 660F62BC18AEA881005AAA18 /* Security.framework */; };\n\t\t6631671713D680A500FF0CBE /* NetworkPhotoAlbumViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6631671613D680A500FF0CBE /* NetworkPhotoAlbumViewController.m */; };\n\t\t6631673613D6825800FF0CBE /* CatalogTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6631673513D6825800FF0CBE /* CatalogTableViewController.m */; };\n\t\t6631680D13D6891F00FF0CBE /* DribbblePhotoAlbumViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6631680C13D6891F00FF0CBE /* DribbblePhotoAlbumViewController.m */; };\n\t\t663B52831445130E00CC26DF /* NIPagingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 663B527F1445130E00CC26DF /* NIPagingScrollView.m */; };\n\t\t663BF5F3158732280066B814 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5EA158732280066B814 /* Default.png */; };\n\t\t663BF5F4158732280066B814 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5EB158732280066B814 /* Default@2x.png */; };\n\t\t663BF5F5158732280066B814 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5EC158732280066B814 /* Icon-72.png */; };\n\t\t663BF5F6158732280066B814 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5ED158732280066B814 /* Icon-Small-50.png */; };\n\t\t663BF5F7158732280066B814 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5EE158732280066B814 /* Icon-Small.png */; };\n\t\t663BF5F8158732280066B814 /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5EF158732280066B814 /* Icon-Small@2x.png */; };\n\t\t663BF5F9158732280066B814 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5F0158732280066B814 /* Icon.png */; };\n\t\t663BF5FA158732280066B814 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 663BF5F1158732280066B814 /* Icon@2x.png */; };\n\t\t66409FA013E25C5300E9BA5A /* NIDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 66409F9213E25C5300E9BA5A /* NIDeviceInfo.m */; };\n\t\t66409FA113E25C5300E9BA5A /* NIOverview.m in Sources */ = {isa = PBXBuildFile; fileRef = 66409F9513E25C5300E9BA5A /* NIOverview.m */; };\n\t\t66409FA213E25C5300E9BA5A /* NIOverviewGraphView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66409F9713E25C5300E9BA5A /* NIOverviewGraphView.m */; };\n\t\t66409FA313E25C5300E9BA5A /* NIOverviewLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 66409F9913E25C5300E9BA5A /* NIOverviewLogger.m */; };\n\t\t66409FA413E25C5300E9BA5A /* NIOverviewPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66409F9B13E25C5300E9BA5A /* NIOverviewPageView.m */; };\n\t\t66409FA513E25C5300E9BA5A /* NIOverviewSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = 66409F9D13E25C5300E9BA5A /* NIOverviewSwizzling.m */; };\n\t\t66409FA613E25C5300E9BA5A /* NIOverviewView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66409F9F13E25C5300E9BA5A /* NIOverviewView.m */; };\n\t\t66409FA813E25C5E00E9BA5A /* NimbusOverviewer.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 66409FA713E25C5E00E9BA5A /* NimbusOverviewer.bundle */; };\n\t\t665E0BB813CE815D008A1D21 /* NIDebuggingTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0B9B13CE815D008A1D21 /* NIDebuggingTools.m */; };\n\t\t665E0BB913CE815D008A1D21 /* NIDeviceOrientation.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0B9D13CE815D008A1D21 /* NIDeviceOrientation.m */; };\n\t\t665E0BBA13CE815D008A1D21 /* NIFoundationMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0B9F13CE815D008A1D21 /* NIFoundationMethods.m */; };\n\t\t665E0BBB13CE815D008A1D21 /* NIInMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BA113CE815D008A1D21 /* NIInMemoryCache.m */; };\n\t\t665E0BBC13CE815D008A1D21 /* NINetworkActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BA513CE815D008A1D21 /* NINetworkActivity.m */; };\n\t\t665E0BBD13CE815D008A1D21 /* NINonEmptyCollectionTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BA713CE815D008A1D21 /* NINonEmptyCollectionTesting.m */; };\n\t\t665E0BBE13CE815D008A1D21 /* NINonRetainingCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BA913CE815D008A1D21 /* NINonRetainingCollections.m */; };\n\t\t665E0BBF13CE815D008A1D21 /* NIOperations.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BAB13CE815D008A1D21 /* NIOperations.m */; };\n\t\t665E0BC013CE815D008A1D21 /* NIPaths.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BAD13CE815D008A1D21 /* NIPaths.m */; };\n\t\t665E0BC113CE815D008A1D21 /* NIRuntimeClassModifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BB013CE815D008A1D21 /* NIRuntimeClassModifications.m */; };\n\t\t665E0BC213CE815D008A1D21 /* NISDKAvailability.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BB213CE815D008A1D21 /* NISDKAvailability.m */; };\n\t\t665E0BC313CE815D008A1D21 /* NIState.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BB413CE815D008A1D21 /* NIState.m */; };\n\t\t665E0BCF13CE816E008A1D21 /* NIPhotoAlbumScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BCA13CE816E008A1D21 /* NIPhotoAlbumScrollView.m */; };\n\t\t665E0BD013CE816E008A1D21 /* NIPhotoScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BCC13CE816E008A1D21 /* NIPhotoScrollView.m */; };\n\t\t665E0BD113CE816E008A1D21 /* NIToolbarPhotoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0BCE13CE816E008A1D21 /* NIToolbarPhotoViewController.m */; };\n\t\t665E0C0813CE82A1008A1D21 /* FacebookPhotoAlbumViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 665E0C0713CE82A1008A1D21 /* FacebookPhotoAlbumViewController.m */; };\n\t\t667DC2BE13D89FD100C1B0ED /* NIPhotoScrubberView.m in Sources */ = {isa = PBXBuildFile; fileRef = 667DC2BD13D89FD100C1B0ED /* NIPhotoScrubberView.m */; };\n\t\t668EA9C81720714D0056C8C3 /* NIActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 668EA9C61720714D0056C8C3 /* NIActions.m */; };\n\t\t668FD7AD1482C1A600BA7009 /* CaptionedPhotoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 668FD7AC1482C1A600BA7009 /* CaptionedPhotoView.m */; };\n\t\t669815F613D5082E00417E8B /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 669815F513D5082E00417E8B /* libz.dylib */; };\n\t\t669815F813D5083200417E8B /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 669815F713D5083200417E8B /* MobileCoreServices.framework */; };\n\t\t669815FC13D5083600417E8B /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 669815FB13D5083600417E8B /* SystemConfiguration.framework */; };\n\t\t6698160013D5083A00417E8B /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 669815FF13D5083A00417E8B /* CFNetwork.framework */; };\n\t\t669F0D03158002B60069B972 /* NIOverviewMemoryCacheController.m in Sources */ = {isa = PBXBuildFile; fileRef = 669F0D02158002B60069B972 /* NIOverviewMemoryCacheController.m */; };\n\t\t669F0D17158002DD0069B972 /* NITableViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 669F0D09158002DD0069B972 /* NITableViewModel.m */; };\n\t\t669F0D18158002DD0069B972 /* NICellCatalog.m in Sources */ = {isa = PBXBuildFile; fileRef = 669F0D0C158002DD0069B972 /* NICellCatalog.m */; };\n\t\t669F0D19158002DD0069B972 /* NIFormCellCatalog.m in Sources */ = {isa = PBXBuildFile; fileRef = 669F0D0E158002DD0069B972 /* NIFormCellCatalog.m */; };\n\t\t669F0D1A158002DD0069B972 /* NICellFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 669F0D10158002DD0069B972 /* NICellFactory.m */; };\n\t\t669F0D1B158002DD0069B972 /* NIRadioGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 669F0D12158002DD0069B972 /* NIRadioGroup.m */; };\n\t\t669F0D1C158002DD0069B972 /* NIRadioGroupController.m in Sources */ = {isa = PBXBuildFile; fileRef = 669F0D14158002DD0069B972 /* NIRadioGroupController.m */; };\n\t\t669F0D1D158002DD0069B972 /* NITableViewActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 669F0D16158002DD0069B972 /* NITableViewActions.m */; };\n\t\t66EA058313C011D6004FFE1A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 66EA058113C011D6004FFE1A /* AppDelegate.m */; };\n\t\t66EA058813C011EC004FFE1A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 66EA058713C011EC004FFE1A /* main.m */; };\n\t\t66EAC64D13D28D9A00BDFF34 /* NICommonMetrics.m in Sources */ = {isa = PBXBuildFile; fileRef = 66EAC64C13D28D9A00BDFF34 /* NICommonMetrics.m */; };\n\t\t66EAC7DC13D2A77D00BDFF34 /* NimbusPhotos.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 66EAC7DB13D2A77D00BDFF34 /* NimbusPhotos.bundle */; };\n\t\t66F01FF022F334FD007656B4 /* AFHTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FE522F334FD007656B4 /* AFHTTPSessionManager.m */; };\n\t\t66F01FF122F334FD007656B4 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FE722F334FD007656B4 /* AFURLResponseSerialization.m */; };\n\t\t66F01FF222F334FD007656B4 /* AFURLRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FE822F334FD007656B4 /* AFURLRequestSerialization.m */; };\n\t\t66F01FF322F334FD007656B4 /* AFNetworkReachabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FEA22F334FD007656B4 /* AFNetworkReachabilityManager.m */; };\n\t\t66F01FF422F334FD007656B4 /* AFURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FED22F334FD007656B4 /* AFURLSessionManager.m */; };\n\t\t66F01FF522F334FD007656B4 /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F01FEE22F334FD007656B4 /* AFSecurityPolicy.m */; };\n\t\t66F27D5D145B7DF500AFCA08 /* NIViewRecycler.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F27D5C145B7DF500AFCA08 /* NIViewRecycler.m */; };\n\t\t8BA77A4419468C3D005ED95A /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8BA77A4319468C3D005ED95A /* Default-568h@2x.png */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };\n\t\t1D6058910D05DD3D006BFB54 /* NetworkPhotoAlbum.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetworkPhotoAlbum.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };\n\t\t288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };\n\t\t660F629F18AEA69B005AAA18 /* NIPagingScrollView+Subclassing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = \"NIPagingScrollView+Subclassing.h\"; path = \"../../../src/pagingscrollview/src/NIPagingScrollView+Subclassing.h\"; sourceTree = \"<group>\"; };\n\t\t660F62BC18AEA881005AAA18 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };\n\t\t6631671513D680A500FF0CBE /* NetworkPhotoAlbumViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkPhotoAlbumViewController.h; path = src/NetworkPhotoAlbumViewController.h; sourceTree = \"<group>\"; };\n\t\t6631671613D680A500FF0CBE /* NetworkPhotoAlbumViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NetworkPhotoAlbumViewController.m; path = src/NetworkPhotoAlbumViewController.m; sourceTree = \"<group>\"; };\n\t\t6631673413D6825800FF0CBE /* CatalogTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CatalogTableViewController.h; path = src/CatalogTableViewController.h; sourceTree = \"<group>\"; };\n\t\t6631673513D6825800FF0CBE /* CatalogTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CatalogTableViewController.m; path = src/CatalogTableViewController.m; sourceTree = \"<group>\"; };\n\t\t6631680B13D6891F00FF0CBE /* DribbblePhotoAlbumViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DribbblePhotoAlbumViewController.h; path = src/DribbblePhotoAlbumViewController.h; sourceTree = \"<group>\"; };\n\t\t6631680C13D6891F00FF0CBE /* DribbblePhotoAlbumViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DribbblePhotoAlbumViewController.m; path = src/DribbblePhotoAlbumViewController.m; sourceTree = \"<group>\"; };\n\t\t663B527D1445130E00CC26DF /* NimbusPagingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusPagingScrollView.h; path = ../../../src/pagingscrollview/src/NimbusPagingScrollView.h; sourceTree = \"<group>\"; };\n\t\t663B527E1445130E00CC26DF /* NIPagingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPagingScrollView.h; path = ../../../src/pagingscrollview/src/NIPagingScrollView.h; sourceTree = \"<group>\"; };\n\t\t663B527F1445130E00CC26DF /* NIPagingScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIPagingScrollView.m; path = ../../../src/pagingscrollview/src/NIPagingScrollView.m; sourceTree = \"<group>\"; };\n\t\t663B52801445130E00CC26DF /* NIPagingScrollViewPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPagingScrollViewPage.h; path = ../../../src/pagingscrollview/src/NIPagingScrollViewPage.h; sourceTree = \"<group>\"; };\n\t\t663BF5EA158732280066B814 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = \"<group>\"; };\n\t\t663BF5EB158732280066B814 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Default@2x.png\"; sourceTree = \"<group>\"; };\n\t\t663BF5EC158732280066B814 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-72.png\"; sourceTree = \"<group>\"; };\n\t\t663BF5ED158732280066B814 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-Small-50.png\"; sourceTree = \"<group>\"; };\n\t\t663BF5EE158732280066B814 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-Small.png\"; sourceTree = \"<group>\"; };\n\t\t663BF5EF158732280066B814 /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon-Small@2x.png\"; sourceTree = \"<group>\"; };\n\t\t663BF5F0158732280066B814 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = \"<group>\"; };\n\t\t663BF5F1158732280066B814 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Icon@2x.png\"; sourceTree = \"<group>\"; };\n\t\t66409F9113E25C5300E9BA5A /* NIDeviceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIDeviceInfo.h; path = ../../../src/overview/src/NIDeviceInfo.h; sourceTree = \"<group>\"; };\n\t\t66409F9213E25C5300E9BA5A /* NIDeviceInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIDeviceInfo.m; path = ../../../src/overview/src/NIDeviceInfo.m; sourceTree = \"<group>\"; };\n\t\t66409F9313E25C5300E9BA5A /* NimbusOverview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusOverview.h; path = ../../../src/overview/src/NimbusOverview.h; sourceTree = \"<group>\"; };\n\t\t66409F9413E25C5300E9BA5A /* NIOverview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOverview.h; path = ../../../src/overview/src/NIOverview.h; sourceTree = \"<group>\"; };\n\t\t66409F9513E25C5300E9BA5A /* NIOverview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOverview.m; path = ../../../src/overview/src/NIOverview.m; sourceTree = \"<group>\"; };\n\t\t66409F9613E25C5300E9BA5A /* NIOverviewGraphView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOverviewGraphView.h; path = ../../../src/overview/src/NIOverviewGraphView.h; sourceTree = \"<group>\"; };\n\t\t66409F9713E25C5300E9BA5A /* NIOverviewGraphView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOverviewGraphView.m; path = ../../../src/overview/src/NIOverviewGraphView.m; sourceTree = \"<group>\"; };\n\t\t66409F9813E25C5300E9BA5A /* NIOverviewLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOverviewLogger.h; path = ../../../src/overview/src/NIOverviewLogger.h; sourceTree = \"<group>\"; };\n\t\t66409F9913E25C5300E9BA5A /* NIOverviewLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOverviewLogger.m; path = ../../../src/overview/src/NIOverviewLogger.m; sourceTree = \"<group>\"; };\n\t\t66409F9A13E25C5300E9BA5A /* NIOverviewPageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOverviewPageView.h; path = ../../../src/overview/src/NIOverviewPageView.h; sourceTree = \"<group>\"; };\n\t\t66409F9B13E25C5300E9BA5A /* NIOverviewPageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOverviewPageView.m; path = ../../../src/overview/src/NIOverviewPageView.m; sourceTree = \"<group>\"; };\n\t\t66409F9C13E25C5300E9BA5A /* NIOverviewSwizzling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOverviewSwizzling.h; path = ../../../src/overview/src/NIOverviewSwizzling.h; sourceTree = \"<group>\"; };\n\t\t66409F9D13E25C5300E9BA5A /* NIOverviewSwizzling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOverviewSwizzling.m; path = ../../../src/overview/src/NIOverviewSwizzling.m; sourceTree = \"<group>\"; };\n\t\t66409F9E13E25C5300E9BA5A /* NIOverviewView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOverviewView.h; path = ../../../src/overview/src/NIOverviewView.h; sourceTree = \"<group>\"; };\n\t\t66409F9F13E25C5300E9BA5A /* NIOverviewView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOverviewView.m; path = ../../../src/overview/src/NIOverviewView.m; sourceTree = \"<group>\"; };\n\t\t66409FA713E25C5E00E9BA5A /* NimbusOverviewer.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; name = NimbusOverviewer.bundle; path = ../../../src/overview/resources/NimbusOverviewer.bundle; sourceTree = \"<group>\"; };\n\t\t665E0B9A13CE815D008A1D21 /* NIDebuggingTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIDebuggingTools.h; path = ../../../src/core/src/NIDebuggingTools.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0B9B13CE815D008A1D21 /* NIDebuggingTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIDebuggingTools.m; path = ../../../src/core/src/NIDebuggingTools.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0B9C13CE815D008A1D21 /* NIDeviceOrientation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIDeviceOrientation.h; path = ../../../src/core/src/NIDeviceOrientation.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0B9D13CE815D008A1D21 /* NIDeviceOrientation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIDeviceOrientation.m; path = ../../../src/core/src/NIDeviceOrientation.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0B9E13CE815D008A1D21 /* NIFoundationMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIFoundationMethods.h; path = ../../../src/core/src/NIFoundationMethods.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0B9F13CE815D008A1D21 /* NIFoundationMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIFoundationMethods.m; path = ../../../src/core/src/NIFoundationMethods.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA013CE815D008A1D21 /* NIInMemoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIInMemoryCache.h; path = ../../../src/core/src/NIInMemoryCache.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA113CE815D008A1D21 /* NIInMemoryCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIInMemoryCache.m; path = ../../../src/core/src/NIInMemoryCache.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA213CE815D008A1D21 /* NimbusCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusCore.h; path = ../../../src/core/src/NimbusCore.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA313CE815D008A1D21 /* NimbusCore+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NimbusCore+Additions.h\"; path = \"../../../src/core/src/NimbusCore+Additions.h\"; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA413CE815D008A1D21 /* NINetworkActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINetworkActivity.h; path = ../../../src/core/src/NINetworkActivity.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA513CE815D008A1D21 /* NINetworkActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINetworkActivity.m; path = ../../../src/core/src/NINetworkActivity.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA613CE815D008A1D21 /* NINonEmptyCollectionTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINonEmptyCollectionTesting.h; path = ../../../src/core/src/NINonEmptyCollectionTesting.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA713CE815D008A1D21 /* NINonEmptyCollectionTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINonEmptyCollectionTesting.m; path = ../../../src/core/src/NINonEmptyCollectionTesting.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA813CE815D008A1D21 /* NINonRetainingCollections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINonRetainingCollections.h; path = ../../../src/core/src/NINonRetainingCollections.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BA913CE815D008A1D21 /* NINonRetainingCollections.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINonRetainingCollections.m; path = ../../../src/core/src/NINonRetainingCollections.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BAA13CE815D008A1D21 /* NIOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOperations.h; path = ../../../src/core/src/NIOperations.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BAB13CE815D008A1D21 /* NIOperations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOperations.m; path = ../../../src/core/src/NIOperations.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BAC13CE815D008A1D21 /* NIPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPaths.h; path = ../../../src/core/src/NIPaths.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BAD13CE815D008A1D21 /* NIPaths.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIPaths.m; path = ../../../src/core/src/NIPaths.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BAE13CE815D008A1D21 /* NIPreprocessorMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPreprocessorMacros.h; path = ../../../src/core/src/NIPreprocessorMacros.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BAF13CE815D008A1D21 /* NIRuntimeClassModifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIRuntimeClassModifications.h; path = ../../../src/core/src/NIRuntimeClassModifications.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BB013CE815D008A1D21 /* NIRuntimeClassModifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIRuntimeClassModifications.m; path = ../../../src/core/src/NIRuntimeClassModifications.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BB113CE815D008A1D21 /* NISDKAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NISDKAvailability.h; path = ../../../src/core/src/NISDKAvailability.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BB213CE815D008A1D21 /* NISDKAvailability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NISDKAvailability.m; path = ../../../src/core/src/NISDKAvailability.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BB313CE815D008A1D21 /* NIState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIState.h; path = ../../../src/core/src/NIState.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BB413CE815D008A1D21 /* NIState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIState.m; path = ../../../src/core/src/NIState.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BC813CE816E008A1D21 /* NimbusPhotos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusPhotos.h; path = ../../../src/photos/src/NimbusPhotos.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BC913CE816E008A1D21 /* NIPhotoAlbumScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPhotoAlbumScrollView.h; path = ../../../src/photos/src/NIPhotoAlbumScrollView.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BCA13CE816E008A1D21 /* NIPhotoAlbumScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIPhotoAlbumScrollView.m; path = ../../../src/photos/src/NIPhotoAlbumScrollView.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BCB13CE816E008A1D21 /* NIPhotoScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPhotoScrollView.h; path = ../../../src/photos/src/NIPhotoScrollView.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BCC13CE816E008A1D21 /* NIPhotoScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIPhotoScrollView.m; path = ../../../src/photos/src/NIPhotoScrollView.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0BCD13CE816E008A1D21 /* NIToolbarPhotoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIToolbarPhotoViewController.h; path = ../../../src/photos/src/NIToolbarPhotoViewController.h; sourceTree = SOURCE_ROOT; };\n\t\t665E0BCE13CE816E008A1D21 /* NIToolbarPhotoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIToolbarPhotoViewController.m; path = ../../../src/photos/src/NIToolbarPhotoViewController.m; sourceTree = SOURCE_ROOT; };\n\t\t665E0C0613CE82A1008A1D21 /* FacebookPhotoAlbumViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FacebookPhotoAlbumViewController.h; path = src/FacebookPhotoAlbumViewController.h; sourceTree = \"<group>\"; };\n\t\t665E0C0713CE82A1008A1D21 /* FacebookPhotoAlbumViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FacebookPhotoAlbumViewController.m; path = src/FacebookPhotoAlbumViewController.m; sourceTree = \"<group>\"; };\n\t\t667A89FE148C65F3000779BD /* NIOperations+Subclassing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NIOperations+Subclassing.h\"; path = \"../../../src/core/src/NIOperations+Subclassing.h\"; sourceTree = \"<group>\"; };\n\t\t667DC2BC13D89FD100C1B0ED /* NIPhotoScrubberView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIPhotoScrubberView.h; path = ../../../src/photos/src/NIPhotoScrubberView.h; sourceTree = \"<group>\"; };\n\t\t667DC2BD13D89FD100C1B0ED /* NIPhotoScrubberView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIPhotoScrubberView.m; path = ../../../src/photos/src/NIPhotoScrubberView.m; sourceTree = \"<group>\"; };\n\t\t668EA9C51720714D0056C8C3 /* NIActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIActions.h; path = ../../../src/core/src/NIActions.h; sourceTree = \"<group>\"; };\n\t\t668EA9C61720714D0056C8C3 /* NIActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIActions.m; path = ../../../src/core/src/NIActions.m; sourceTree = \"<group>\"; };\n\t\t668EA9C71720714D0056C8C3 /* NIActions+Subclassing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NIActions+Subclassing.h\"; path = \"../../../src/core/src/NIActions+Subclassing.h\"; sourceTree = \"<group>\"; };\n\t\t668FD7AB1482C1A600BA7009 /* CaptionedPhotoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CaptionedPhotoView.h; path = src/CaptionedPhotoView.h; sourceTree = \"<group>\"; };\n\t\t668FD7AC1482C1A600BA7009 /* CaptionedPhotoView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CaptionedPhotoView.m; path = src/CaptionedPhotoView.m; sourceTree = \"<group>\"; };\n\t\t669815F513D5082E00417E8B /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = \"compiled.mach-o.dylib\"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };\n\t\t669815F713D5083200417E8B /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };\n\t\t669815FB13D5083600417E8B /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };\n\t\t669815FF13D5083A00417E8B /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };\n\t\t669F0D01158002B60069B972 /* NIOverviewMemoryCacheController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIOverviewMemoryCacheController.h; path = ../../../src/overview/src/NIOverviewMemoryCacheController.h; sourceTree = \"<group>\"; };\n\t\t669F0D02158002B60069B972 /* NIOverviewMemoryCacheController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIOverviewMemoryCacheController.m; path = ../../../src/overview/src/NIOverviewMemoryCacheController.m; sourceTree = \"<group>\"; };\n\t\t669F0D06158002DD0069B972 /* NimbusModels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusModels.h; path = ../../../src/models/src/NimbusModels.h; sourceTree = \"<group>\"; };\n\t\t669F0D07158002DD0069B972 /* NimbusModels+Namespace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NimbusModels+Namespace.h\"; path = \"../../../src/models/src/NimbusModels+Namespace.h\"; sourceTree = \"<group>\"; };\n\t\t669F0D08158002DD0069B972 /* NITableViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NITableViewModel.h; path = ../../../src/models/src/NITableViewModel.h; sourceTree = \"<group>\"; };\n\t\t669F0D09158002DD0069B972 /* NITableViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NITableViewModel.m; path = ../../../src/models/src/NITableViewModel.m; sourceTree = \"<group>\"; };\n\t\t669F0D0A158002DD0069B972 /* NITableViewModel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NITableViewModel+Private.h\"; path = \"../../../src/models/src/NITableViewModel+Private.h\"; sourceTree = \"<group>\"; };\n\t\t669F0D0B158002DD0069B972 /* NICellCatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICellCatalog.h; path = ../../../src/models/src/NICellCatalog.h; sourceTree = \"<group>\"; };\n\t\t669F0D0C158002DD0069B972 /* NICellCatalog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICellCatalog.m; path = ../../../src/models/src/NICellCatalog.m; sourceTree = \"<group>\"; };\n\t\t669F0D0D158002DD0069B972 /* NIFormCellCatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIFormCellCatalog.h; path = ../../../src/models/src/NIFormCellCatalog.h; sourceTree = \"<group>\"; };\n\t\t669F0D0E158002DD0069B972 /* NIFormCellCatalog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIFormCellCatalog.m; path = ../../../src/models/src/NIFormCellCatalog.m; sourceTree = \"<group>\"; };\n\t\t669F0D0F158002DD0069B972 /* NICellFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICellFactory.h; path = ../../../src/models/src/NICellFactory.h; sourceTree = \"<group>\"; };\n\t\t669F0D10158002DD0069B972 /* NICellFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICellFactory.m; path = ../../../src/models/src/NICellFactory.m; sourceTree = \"<group>\"; };\n\t\t669F0D11158002DD0069B972 /* NIRadioGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIRadioGroup.h; path = ../../../src/models/src/NIRadioGroup.h; sourceTree = \"<group>\"; };\n\t\t669F0D12158002DD0069B972 /* NIRadioGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIRadioGroup.m; path = ../../../src/models/src/NIRadioGroup.m; sourceTree = \"<group>\"; };\n\t\t669F0D13158002DD0069B972 /* NIRadioGroupController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIRadioGroupController.h; path = ../../../src/models/src/NIRadioGroupController.h; sourceTree = \"<group>\"; };\n\t\t669F0D14158002DD0069B972 /* NIRadioGroupController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIRadioGroupController.m; path = ../../../src/models/src/NIRadioGroupController.m; sourceTree = \"<group>\"; };\n\t\t669F0D15158002DD0069B972 /* NITableViewActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NITableViewActions.h; path = ../../../src/models/src/NITableViewActions.h; sourceTree = \"<group>\"; };\n\t\t669F0D16158002DD0069B972 /* NITableViewActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NITableViewActions.m; path = ../../../src/models/src/NITableViewActions.m; sourceTree = \"<group>\"; };\n\t\t66EA058013C011D6004FFE1A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = src/AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t66EA058113C011D6004FFE1A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = src/AppDelegate.m; sourceTree = \"<group>\"; };\n\t\t66EA058213C011D6004FFE1A /* NetworkPhotoAlbum_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkPhotoAlbum_Prefix.pch; path = src/NetworkPhotoAlbum_Prefix.pch; sourceTree = \"<group>\"; };\n\t\t66EA058713C011EC004FFE1A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = src/main.m; sourceTree = \"<group>\"; };\n\t\t66EA05A213C01297004FFE1A /* NetworkPhotoAlbum-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = \"NetworkPhotoAlbum-Info.plist\"; path = \"resources/NetworkPhotoAlbum-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t66EAC47F13D2368100BDFF34 /* README.mdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.mdown; sourceTree = \"<group>\"; };\n\t\t66EAC64B13D28D9A00BDFF34 /* NICommonMetrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICommonMetrics.h; path = ../../../src/core/src/NICommonMetrics.h; sourceTree = SOURCE_ROOT; };\n\t\t66EAC64C13D28D9A00BDFF34 /* NICommonMetrics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICommonMetrics.m; path = ../../../src/core/src/NICommonMetrics.m; sourceTree = SOURCE_ROOT; };\n\t\t66EAC7DB13D2A77D00BDFF34 /* NimbusPhotos.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; name = NimbusPhotos.bundle; path = ../../../src/photos/resources/NimbusPhotos.bundle; sourceTree = SOURCE_ROOT; };\n\t\t66F01FE222F334FC007656B4 /* AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworking.h; sourceTree = \"<group>\"; };\n\t\t66F01FE322F334FD007656B4 /* AFURLResponseSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLResponseSerialization.h; sourceTree = \"<group>\"; };\n\t\t66F01FE422F334FD007656B4 /* AFURLRequestSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLRequestSerialization.h; sourceTree = \"<group>\"; };\n\t\t66F01FE522F334FD007656B4 /* AFHTTPSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPSessionManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FE622F334FD007656B4 /* AFNetworkReachabilityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworkReachabilityManager.h; sourceTree = \"<group>\"; };\n\t\t66F01FE722F334FD007656B4 /* AFURLResponseSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLResponseSerialization.m; sourceTree = \"<group>\"; };\n\t\t66F01FE822F334FD007656B4 /* AFURLRequestSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLRequestSerialization.m; sourceTree = \"<group>\"; };\n\t\t66F01FE922F334FD007656B4 /* AFHTTPSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPSessionManager.h; sourceTree = \"<group>\"; };\n\t\t66F01FEA22F334FD007656B4 /* AFNetworkReachabilityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFNetworkReachabilityManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FEB22F334FD007656B4 /* AFCompatibilityMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFCompatibilityMacros.h; sourceTree = \"<group>\"; };\n\t\t66F01FEC22F334FD007656B4 /* AFSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSecurityPolicy.h; sourceTree = \"<group>\"; };\n\t\t66F01FED22F334FD007656B4 /* AFURLSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLSessionManager.m; sourceTree = \"<group>\"; };\n\t\t66F01FEE22F334FD007656B4 /* AFSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSecurityPolicy.m; sourceTree = \"<group>\"; };\n\t\t66F01FEF22F334FD007656B4 /* AFURLSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLSessionManager.h; sourceTree = \"<group>\"; };\n\t\t66F27D5B145B7DF500AFCA08 /* NIViewRecycler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIViewRecycler.h; path = ../../../src/core/src/NIViewRecycler.h; sourceTree = \"<group>\"; };\n\t\t66F27D5C145B7DF500AFCA08 /* NIViewRecycler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIViewRecycler.m; path = ../../../src/core/src/NIViewRecycler.m; sourceTree = \"<group>\"; };\n\t\t8BA77A4319468C3D005ED95A /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = \"Default-568h@2x.png\"; sourceTree = \"<group>\"; };\n\t\tD526CF2818B6CC7E00991F7A /* NICellFactory+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = \"NICellFactory+Private.h\"; path = \"../../../src/models/src/NICellFactory+Private.h\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t1D60588F0D05DD3D006BFB54 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t660F62BD18AEA881005AAA18 /* Security.framework in Frameworks */,\n\t\t\t\t1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,\n\t\t\t\t1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,\n\t\t\t\t288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t669815F613D5082E00417E8B /* libz.dylib in Frameworks */,\n\t\t\t\t669815F813D5083200417E8B /* MobileCoreServices.framework in Frameworks */,\n\t\t\t\t669815FC13D5083600417E8B /* SystemConfiguration.framework in Frameworks */,\n\t\t\t\t6698160013D5083A00417E8B /* CFNetwork.framework 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\t19C28FACFE9D520D11CA2CBB /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t1D6058910D05DD3D006BFB54 /* NetworkPhotoAlbum.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66EAC47F13D2368100BDFF34 /* README.mdown */,\n\t\t\t\t66EA058213C011D6004FFE1A /* NetworkPhotoAlbum_Prefix.pch */,\n\t\t\t\t66EA057A13C011C0004FFE1A /* Source */,\n\t\t\t\t66EA058E13C0126F004FFE1A /* Nimbus */,\n\t\t\t\t66D2FE2C1594202500B2BEFD /* AFNetworking */,\n\t\t\t\t66EA059D13C0128E004FFE1A /* Resources */,\n\t\t\t\t29B97323FDCFA39411CA2CEA /* Frameworks */,\n\t\t\t\t19C28FACFE9D520D11CA2CBB /* Products */,\n\t\t\t);\n\t\t\tindentWidth = 2;\n\t\t\tname = CustomTemplate;\n\t\t\tsourceTree = \"<group>\";\n\t\t\ttabWidth = 2;\n\t\t};\n\t\t29B97323FDCFA39411CA2CEA /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t660F62BC18AEA881005AAA18 /* Security.framework */,\n\t\t\t\t669815F513D5082E00417E8B /* libz.dylib */,\n\t\t\t\t669815F713D5083200417E8B /* MobileCoreServices.framework */,\n\t\t\t\t669815FB13D5083600417E8B /* SystemConfiguration.framework */,\n\t\t\t\t669815FF13D5083A00417E8B /* CFNetwork.framework */,\n\t\t\t\t1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,\n\t\t\t\t1D30AB110D05D00D00671497 /* Foundation.framework */,\n\t\t\t\t288765FC0DF74451002DB57D /* CoreGraphics.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6631673713D6825D00FF0CBE /* Photo Album View Controllers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6631671513D680A500FF0CBE /* NetworkPhotoAlbumViewController.h */,\n\t\t\t\t6631671613D680A500FF0CBE /* NetworkPhotoAlbumViewController.m */,\n\t\t\t\t6631680213D688FC00FF0CBE /* Dribbble */,\n\t\t\t\t6631673813D6826600FF0CBE /* Facebook */,\n\t\t\t);\n\t\t\tname = \"Photo Album View Controllers\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6631673813D6826600FF0CBE /* Facebook */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t665E0C0613CE82A1008A1D21 /* FacebookPhotoAlbumViewController.h */,\n\t\t\t\t665E0C0713CE82A1008A1D21 /* FacebookPhotoAlbumViewController.m */,\n\t\t\t\t668FD7AB1482C1A600BA7009 /* CaptionedPhotoView.h */,\n\t\t\t\t668FD7AC1482C1A600BA7009 /* CaptionedPhotoView.m */,\n\t\t\t);\n\t\t\tname = Facebook;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6631680213D688FC00FF0CBE /* Dribbble */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6631680B13D6891F00FF0CBE /* DribbblePhotoAlbumViewController.h */,\n\t\t\t\t6631680C13D6891F00FF0CBE /* DribbblePhotoAlbumViewController.m */,\n\t\t\t);\n\t\t\tname = Dribbble;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t663B527B1445130100CC26DF /* Paging Scroll View */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t663B527D1445130E00CC26DF /* NimbusPagingScrollView.h */,\n\t\t\t\t663B527E1445130E00CC26DF /* NIPagingScrollView.h */,\n\t\t\t\t663B527F1445130E00CC26DF /* NIPagingScrollView.m */,\n\t\t\t\t660F629F18AEA69B005AAA18 /* NIPagingScrollView+Subclassing.h */,\n\t\t\t\t663B52801445130E00CC26DF /* NIPagingScrollViewPage.h */,\n\t\t\t);\n\t\t\tname = \"Paging Scroll View\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t663BF5F2158732280066B814 /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t663BF5EA158732280066B814 /* Default.png */,\n\t\t\t\t663BF5EB158732280066B814 /* Default@2x.png */,\n\t\t\t\t8BA77A4319468C3D005ED95A /* Default-568h@2x.png */,\n\t\t\t\t663BF5EC158732280066B814 /* Icon-72.png */,\n\t\t\t\t663BF5ED158732280066B814 /* Icon-Small-50.png */,\n\t\t\t\t663BF5EE158732280066B814 /* Icon-Small.png */,\n\t\t\t\t663BF5EF158732280066B814 /* Icon-Small@2x.png */,\n\t\t\t\t663BF5F0158732280066B814 /* Icon.png */,\n\t\t\t\t663BF5F1158732280066B814 /* Icon@2x.png */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tpath = ../../../src/resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t665E0B9513CE814D008A1D21 /* Core */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t668EA9C51720714D0056C8C3 /* NIActions.h */,\n\t\t\t\t668EA9C61720714D0056C8C3 /* NIActions.m */,\n\t\t\t\t668EA9C71720714D0056C8C3 /* NIActions+Subclassing.h */,\n\t\t\t\t66EAC64B13D28D9A00BDFF34 /* NICommonMetrics.h */,\n\t\t\t\t66EAC64C13D28D9A00BDFF34 /* NICommonMetrics.m */,\n\t\t\t\t665E0B9A13CE815D008A1D21 /* NIDebuggingTools.h */,\n\t\t\t\t665E0B9B13CE815D008A1D21 /* NIDebuggingTools.m */,\n\t\t\t\t665E0B9C13CE815D008A1D21 /* NIDeviceOrientation.h */,\n\t\t\t\t665E0B9D13CE815D008A1D21 /* NIDeviceOrientation.m */,\n\t\t\t\t665E0B9E13CE815D008A1D21 /* NIFoundationMethods.h */,\n\t\t\t\t665E0B9F13CE815D008A1D21 /* NIFoundationMethods.m */,\n\t\t\t\t665E0BA013CE815D008A1D21 /* NIInMemoryCache.h */,\n\t\t\t\t665E0BA113CE815D008A1D21 /* NIInMemoryCache.m */,\n\t\t\t\t665E0BA213CE815D008A1D21 /* NimbusCore.h */,\n\t\t\t\t665E0BA313CE815D008A1D21 /* NimbusCore+Additions.h */,\n\t\t\t\t665E0BA413CE815D008A1D21 /* NINetworkActivity.h */,\n\t\t\t\t665E0BA513CE815D008A1D21 /* NINetworkActivity.m */,\n\t\t\t\t665E0BA613CE815D008A1D21 /* NINonEmptyCollectionTesting.h */,\n\t\t\t\t665E0BA713CE815D008A1D21 /* NINonEmptyCollectionTesting.m */,\n\t\t\t\t665E0BA813CE815D008A1D21 /* NINonRetainingCollections.h */,\n\t\t\t\t665E0BA913CE815D008A1D21 /* NINonRetainingCollections.m */,\n\t\t\t\t665E0BAA13CE815D008A1D21 /* NIOperations.h */,\n\t\t\t\t665E0BAB13CE815D008A1D21 /* NIOperations.m */,\n\t\t\t\t667A89FE148C65F3000779BD /* NIOperations+Subclassing.h */,\n\t\t\t\t665E0BAC13CE815D008A1D21 /* NIPaths.h */,\n\t\t\t\t665E0BAD13CE815D008A1D21 /* NIPaths.m */,\n\t\t\t\t665E0BAE13CE815D008A1D21 /* NIPreprocessorMacros.h */,\n\t\t\t\t665E0BAF13CE815D008A1D21 /* NIRuntimeClassModifications.h */,\n\t\t\t\t665E0BB013CE815D008A1D21 /* NIRuntimeClassModifications.m */,\n\t\t\t\t665E0BB113CE815D008A1D21 /* NISDKAvailability.h */,\n\t\t\t\t665E0BB213CE815D008A1D21 /* NISDKAvailability.m */,\n\t\t\t\t665E0BB313CE815D008A1D21 /* NIState.h */,\n\t\t\t\t665E0BB413CE815D008A1D21 /* NIState.m */,\n\t\t\t\t66F27D5B145B7DF500AFCA08 /* NIViewRecycler.h */,\n\t\t\t\t66F27D5C145B7DF500AFCA08 /* NIViewRecycler.m */,\n\t\t\t);\n\t\t\tname = Core;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t665E0BC613CE8161008A1D21 /* Photos */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t665E0BC813CE816E008A1D21 /* NimbusPhotos.h */,\n\t\t\t\t665E0BC913CE816E008A1D21 /* NIPhotoAlbumScrollView.h */,\n\t\t\t\t665E0BCA13CE816E008A1D21 /* NIPhotoAlbumScrollView.m */,\n\t\t\t\t665E0BCB13CE816E008A1D21 /* NIPhotoScrollView.h */,\n\t\t\t\t665E0BCC13CE816E008A1D21 /* NIPhotoScrollView.m */,\n\t\t\t\t665E0BCD13CE816E008A1D21 /* NIToolbarPhotoViewController.h */,\n\t\t\t\t665E0BCE13CE816E008A1D21 /* NIToolbarPhotoViewController.m */,\n\t\t\t\t667DC2BC13D89FD100C1B0ED /* NIPhotoScrubberView.h */,\n\t\t\t\t667DC2BD13D89FD100C1B0ED /* NIPhotoScrubberView.m */,\n\t\t\t);\n\t\t\tname = Photos;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t669F0D05158002C90069B972 /* Models */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t669F0D06158002DD0069B972 /* NimbusModels.h */,\n\t\t\t\t669F0D07158002DD0069B972 /* NimbusModels+Namespace.h */,\n\t\t\t\t669F0D08158002DD0069B972 /* NITableViewModel.h */,\n\t\t\t\t669F0D09158002DD0069B972 /* NITableViewModel.m */,\n\t\t\t\t669F0D0A158002DD0069B972 /* NITableViewModel+Private.h */,\n\t\t\t\t669F0D0B158002DD0069B972 /* NICellCatalog.h */,\n\t\t\t\t669F0D0C158002DD0069B972 /* NICellCatalog.m */,\n\t\t\t\t669F0D0D158002DD0069B972 /* NIFormCellCatalog.h */,\n\t\t\t\t669F0D0E158002DD0069B972 /* NIFormCellCatalog.m */,\n\t\t\t\t669F0D0F158002DD0069B972 /* NICellFactory.h */,\n\t\t\t\tD526CF2818B6CC7E00991F7A /* NICellFactory+Private.h */,\n\t\t\t\t669F0D10158002DD0069B972 /* NICellFactory.m */,\n\t\t\t\t669F0D11158002DD0069B972 /* NIRadioGroup.h */,\n\t\t\t\t669F0D12158002DD0069B972 /* NIRadioGroup.m */,\n\t\t\t\t669F0D13158002DD0069B972 /* NIRadioGroupController.h */,\n\t\t\t\t669F0D14158002DD0069B972 /* NIRadioGroupController.m */,\n\t\t\t\t669F0D15158002DD0069B972 /* NITableViewActions.h */,\n\t\t\t\t669F0D16158002DD0069B972 /* NITableViewActions.m */,\n\t\t\t);\n\t\t\tname = Models;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66C52CC313DAA79E00D6BA6F /* Overview */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66409F9113E25C5300E9BA5A /* NIDeviceInfo.h */,\n\t\t\t\t66409F9213E25C5300E9BA5A /* NIDeviceInfo.m */,\n\t\t\t\t66409F9313E25C5300E9BA5A /* NimbusOverview.h */,\n\t\t\t\t66409F9413E25C5300E9BA5A /* NIOverview.h */,\n\t\t\t\t66409F9513E25C5300E9BA5A /* NIOverview.m */,\n\t\t\t\t66409F9613E25C5300E9BA5A /* NIOverviewGraphView.h */,\n\t\t\t\t66409F9713E25C5300E9BA5A /* NIOverviewGraphView.m */,\n\t\t\t\t66409F9813E25C5300E9BA5A /* NIOverviewLogger.h */,\n\t\t\t\t66409F9913E25C5300E9BA5A /* NIOverviewLogger.m */,\n\t\t\t\t66409F9A13E25C5300E9BA5A /* NIOverviewPageView.h */,\n\t\t\t\t66409F9B13E25C5300E9BA5A /* NIOverviewPageView.m */,\n\t\t\t\t66409F9C13E25C5300E9BA5A /* NIOverviewSwizzling.h */,\n\t\t\t\t66409F9D13E25C5300E9BA5A /* NIOverviewSwizzling.m */,\n\t\t\t\t66409F9E13E25C5300E9BA5A /* NIOverviewView.h */,\n\t\t\t\t66409F9F13E25C5300E9BA5A /* NIOverviewView.m */,\n\t\t\t\t669F0D01158002B60069B972 /* NIOverviewMemoryCacheController.h */,\n\t\t\t\t669F0D02158002B60069B972 /* NIOverviewMemoryCacheController.m */,\n\t\t\t);\n\t\t\tname = Overview;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66D2FE2C1594202500B2BEFD /* AFNetworking */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66F01FEB22F334FD007656B4 /* AFCompatibilityMacros.h */,\n\t\t\t\t66F01FE922F334FD007656B4 /* AFHTTPSessionManager.h */,\n\t\t\t\t66F01FE522F334FD007656B4 /* AFHTTPSessionManager.m */,\n\t\t\t\t66F01FE222F334FC007656B4 /* AFNetworking.h */,\n\t\t\t\t66F01FE622F334FD007656B4 /* AFNetworkReachabilityManager.h */,\n\t\t\t\t66F01FEA22F334FD007656B4 /* AFNetworkReachabilityManager.m */,\n\t\t\t\t66F01FEC22F334FD007656B4 /* AFSecurityPolicy.h */,\n\t\t\t\t66F01FEE22F334FD007656B4 /* AFSecurityPolicy.m */,\n\t\t\t\t66F01FE422F334FD007656B4 /* AFURLRequestSerialization.h */,\n\t\t\t\t66F01FE822F334FD007656B4 /* AFURLRequestSerialization.m */,\n\t\t\t\t66F01FE322F334FD007656B4 /* AFURLResponseSerialization.h */,\n\t\t\t\t66F01FE722F334FD007656B4 /* AFURLResponseSerialization.m */,\n\t\t\t\t66F01FEF22F334FD007656B4 /* AFURLSessionManager.h */,\n\t\t\t\t66F01FED22F334FD007656B4 /* AFURLSessionManager.m */,\n\t\t\t);\n\t\t\tname = AFNetworking;\n\t\t\tpath = ../../../thirdparty/AFNetworking/AFNetworking;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66EA057A13C011C0004FFE1A /* Source */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66EA058013C011D6004FFE1A /* AppDelegate.h */,\n\t\t\t\t66EA058113C011D6004FFE1A /* AppDelegate.m */,\n\t\t\t\t66EA058713C011EC004FFE1A /* main.m */,\n\t\t\t\t6631673413D6825800FF0CBE /* CatalogTableViewController.h */,\n\t\t\t\t6631673513D6825800FF0CBE /* CatalogTableViewController.m */,\n\t\t\t\t6631673713D6825D00FF0CBE /* Photo Album View Controllers */,\n\t\t\t);\n\t\t\tname = Source;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66EA058E13C0126F004FFE1A /* Nimbus */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t663BF5F2158732280066B814 /* Resources */,\n\t\t\t\t665E0B9513CE814D008A1D21 /* Core */,\n\t\t\t\t669F0D05158002C90069B972 /* Models */,\n\t\t\t\t66C52CC313DAA79E00D6BA6F /* Overview */,\n\t\t\t\t663B527B1445130100CC26DF /* Paging Scroll View */,\n\t\t\t\t665E0BC613CE8161008A1D21 /* Photos */,\n\t\t\t);\n\t\t\tname = Nimbus;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66EA059D13C0128E004FFE1A /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66409FA713E25C5E00E9BA5A /* NimbusOverviewer.bundle */,\n\t\t\t\t66EAC7DB13D2A77D00BDFF34 /* NimbusPhotos.bundle */,\n\t\t\t\t66EA05A213C01297004FFE1A /* NetworkPhotoAlbum-Info.plist */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t1D6058900D05DD3D006BFB54 /* NetworkPhotoAlbum */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget \"NetworkPhotoAlbum\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t1D60588D0D05DD3D006BFB54 /* Resources */,\n\t\t\t\t1D60588E0D05DD3D006BFB54 /* Sources */,\n\t\t\t\t1D60588F0D05DD3D006BFB54 /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = NetworkPhotoAlbum;\n\t\t\tproductName = NetworkPhotoAlbum;\n\t\t\tproductReference = 1D6058910D05DD3D006BFB54 /* NetworkPhotoAlbum.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t29B97313FDCFA39411CA2CEA /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1100;\n\t\t\t};\n\t\t\tbuildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject \"NetworkPhotoAlbum\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 1;\n\t\t\tknownRegions = (\n\t\t\t\tde,\n\t\t\t\tja,\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t\tfr,\n\t\t\t);\n\t\t\tmainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t1D6058900D05DD3D006BFB54 /* NetworkPhotoAlbum */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t1D60588D0D05DD3D006BFB54 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66EAC7DC13D2A77D00BDFF34 /* NimbusPhotos.bundle in Resources */,\n\t\t\t\t8BA77A4419468C3D005ED95A /* Default-568h@2x.png in Resources */,\n\t\t\t\t66409FA813E25C5E00E9BA5A /* NimbusOverviewer.bundle in Resources */,\n\t\t\t\t663BF5F3158732280066B814 /* Default.png in Resources */,\n\t\t\t\t663BF5F4158732280066B814 /* Default@2x.png in Resources */,\n\t\t\t\t663BF5F5158732280066B814 /* Icon-72.png in Resources */,\n\t\t\t\t663BF5F6158732280066B814 /* Icon-Small-50.png in Resources */,\n\t\t\t\t663BF5F7158732280066B814 /* Icon-Small.png in Resources */,\n\t\t\t\t663BF5F8158732280066B814 /* Icon-Small@2x.png in Resources */,\n\t\t\t\t663BF5F9158732280066B814 /* Icon.png in Resources */,\n\t\t\t\t663BF5FA158732280066B814 /* Icon@2x.png 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\t1D60588E0D05DD3D006BFB54 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66EA058313C011D6004FFE1A /* AppDelegate.m in Sources */,\n\t\t\t\t66EA058813C011EC004FFE1A /* main.m in Sources */,\n\t\t\t\t665E0BB813CE815D008A1D21 /* NIDebuggingTools.m in Sources */,\n\t\t\t\t665E0BB913CE815D008A1D21 /* NIDeviceOrientation.m in Sources */,\n\t\t\t\t665E0BBA13CE815D008A1D21 /* NIFoundationMethods.m in Sources */,\n\t\t\t\t665E0BBB13CE815D008A1D21 /* NIInMemoryCache.m in Sources */,\n\t\t\t\t665E0BBC13CE815D008A1D21 /* NINetworkActivity.m in Sources */,\n\t\t\t\t665E0BBD13CE815D008A1D21 /* NINonEmptyCollectionTesting.m in Sources */,\n\t\t\t\t665E0BBE13CE815D008A1D21 /* NINonRetainingCollections.m in Sources */,\n\t\t\t\t665E0BBF13CE815D008A1D21 /* NIOperations.m in Sources */,\n\t\t\t\t665E0BC013CE815D008A1D21 /* NIPaths.m in Sources */,\n\t\t\t\t665E0BC113CE815D008A1D21 /* NIRuntimeClassModifications.m in Sources */,\n\t\t\t\t665E0BC213CE815D008A1D21 /* NISDKAvailability.m in Sources */,\n\t\t\t\t665E0BC313CE815D008A1D21 /* NIState.m in Sources */,\n\t\t\t\t665E0BCF13CE816E008A1D21 /* NIPhotoAlbumScrollView.m in Sources */,\n\t\t\t\t665E0BD013CE816E008A1D21 /* NIPhotoScrollView.m in Sources */,\n\t\t\t\t66F01FF322F334FD007656B4 /* AFNetworkReachabilityManager.m in Sources */,\n\t\t\t\t665E0BD113CE816E008A1D21 /* NIToolbarPhotoViewController.m in Sources */,\n\t\t\t\t665E0C0813CE82A1008A1D21 /* FacebookPhotoAlbumViewController.m in Sources */,\n\t\t\t\t66EAC64D13D28D9A00BDFF34 /* NICommonMetrics.m in Sources */,\n\t\t\t\t6631671713D680A500FF0CBE /* NetworkPhotoAlbumViewController.m in Sources */,\n\t\t\t\t6631673613D6825800FF0CBE /* CatalogTableViewController.m in Sources */,\n\t\t\t\t6631680D13D6891F00FF0CBE /* DribbblePhotoAlbumViewController.m in Sources */,\n\t\t\t\t667DC2BE13D89FD100C1B0ED /* NIPhotoScrubberView.m in Sources */,\n\t\t\t\t66409FA013E25C5300E9BA5A /* NIDeviceInfo.m in Sources */,\n\t\t\t\t66409FA113E25C5300E9BA5A /* NIOverview.m in Sources */,\n\t\t\t\t66409FA213E25C5300E9BA5A /* NIOverviewGraphView.m in Sources */,\n\t\t\t\t66F01FF122F334FD007656B4 /* AFURLResponseSerialization.m in Sources */,\n\t\t\t\t66F01FF522F334FD007656B4 /* AFSecurityPolicy.m in Sources */,\n\t\t\t\t66F01FF222F334FD007656B4 /* AFURLRequestSerialization.m in Sources */,\n\t\t\t\t66409FA313E25C5300E9BA5A /* NIOverviewLogger.m in Sources */,\n\t\t\t\t66409FA413E25C5300E9BA5A /* NIOverviewPageView.m in Sources */,\n\t\t\t\t66409FA513E25C5300E9BA5A /* NIOverviewSwizzling.m in Sources */,\n\t\t\t\t66409FA613E25C5300E9BA5A /* NIOverviewView.m in Sources */,\n\t\t\t\t663B52831445130E00CC26DF /* NIPagingScrollView.m in Sources */,\n\t\t\t\t66F27D5D145B7DF500AFCA08 /* NIViewRecycler.m in Sources */,\n\t\t\t\t668FD7AD1482C1A600BA7009 /* CaptionedPhotoView.m in Sources */,\n\t\t\t\t669F0D03158002B60069B972 /* NIOverviewMemoryCacheController.m in Sources */,\n\t\t\t\t669F0D17158002DD0069B972 /* NITableViewModel.m in Sources */,\n\t\t\t\t669F0D18158002DD0069B972 /* NICellCatalog.m in Sources */,\n\t\t\t\t66F01FF422F334FD007656B4 /* AFURLSessionManager.m in Sources */,\n\t\t\t\t669F0D19158002DD0069B972 /* NIFormCellCatalog.m in Sources */,\n\t\t\t\t669F0D1A158002DD0069B972 /* NICellFactory.m in Sources */,\n\t\t\t\t669F0D1B158002DD0069B972 /* NIRadioGroup.m in Sources */,\n\t\t\t\t669F0D1C158002DD0069B972 /* NIRadioGroupController.m in Sources */,\n\t\t\t\t66F01FF022F334FD007656B4 /* AFHTTPSessionManager.m in Sources */,\n\t\t\t\t669F0D1D158002DD0069B972 /* NITableViewActions.m in Sources */,\n\t\t\t\t668EA9C81720714D0056C8C3 /* NIActions.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t1D6058940D05DD3E006BFB54 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = src/NetworkPhotoAlbum_Prefix.pch;\n\t\t\t\t\"GCC_PREPROCESSOR_DEFINITIONS[arch=*]\" = DEBUG;\n\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;\n\t\t\t\tINFOPLIST_FILE = \"resources/NetworkPhotoAlbum-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.yourcompany.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = NetworkPhotoAlbum;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t1D6058950D05DD3E006BFB54 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = src/NetworkPhotoAlbum_Prefix.pch;\n\t\t\t\tGCC_VERSION = com.apple.compilers.llvm.clang.1_0;\n\t\t\t\tINFOPLIST_FILE = \"resources/NetworkPhotoAlbum-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.yourcompany.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = NetworkPhotoAlbum;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC01FCF4F08A954540054247B /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = c99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC01FCF5008A954540054247B /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = c99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tOTHER_CFLAGS = \"-DNS_BLOCK_ASSERTIONS=1\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget \"NetworkPhotoAlbum\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t1D6058940D05DD3E006BFB54 /* Debug */,\n\t\t\t\t1D6058950D05DD3E006BFB54 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC01FCF4E08A954540054247B /* Build configuration list for PBXProject \"NetworkPhotoAlbum\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC01FCF4F08A954540054247B /* Debug */,\n\t\t\t\tC01FCF5008A954540054247B /* 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 = 29B97313FDCFA39411CA2CEA /* Project object */;\n}\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/README.mdown",
    "content": "Network Photo Albums Sample Application\n=======================================\n\nThis sample application demos the use of the multiple photo APIs to fetch photos from public\nphoto albums and display them in high-definition on the iPad and iPhone.\n\nThe following APIs are currently demoed:\n\n- Facebook Graph API\n- Dribbble Shots\n\nPlease run the following to check the JSONKit submodule out:\n\n> git submodule init\n> git submodule update\n\n\nProduct Information\n-------------------\n\nMinimum Deployment Target:  iOS 4.0\nSupported Hardware:         iPod touch, iPhone, and iPad\n\n\nDependencies\n------------\n\n### Nimbus Core\n\nEvery Nimbus feature depends on the Core for a variety of common features.\n\n### Nimbus Photos\n\nThis is the primary feature being demoed in this application. The\nNetworkPhotoAlbumViewController subclasses the NIToolbarPhotoViewController and implements\nthe necessary data source methods. It fetches the photo album information from the Facebook\nGraph API using ASIHTTPRequest and parses the JSON using JSONKit.\n\n### Nimbus Processors\n\nThis application uses the NIJSONKitProcessorHTTPRequest to process the API results on a\nseparate thread instead of blocking on the main UI.\n\n### ASIHTTPRequest\n\nThe network framework used to make the requests to the API.\n\n### JSONKit\n\nThe JSON parser used to parse the JSON responses from the Graph API.\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/resources/NetworkPhotoAlbum-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>English</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>CFBundleIconFile</key>\n\t<string></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>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>v1.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>NSAppTransportSecurity</key>\n\t<dict>\n\t\t<key>NSAllowsArbitraryLoads</key>\n\t\t<true/>\n\t</dict>\n\t<key>UIPrerenderedIcon</key>\n\t<true/>\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\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/AppDelegate.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : NSObject <UIApplicationDelegate> {\n@private\n  UIWindow* _window;\n  UIViewController* _rootViewController;\n}\n\n@property (nonatomic, retain) UIWindow* window;\n\n@end\n\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/AppDelegate.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"AppDelegate.h\"\n\n#import \"FacebookPhotoAlbumViewController.h\"\n#import \"CatalogTableViewController.h\"\n#import \"NimbusOverview.h\"\n\n\n@implementation AppDelegate\n\n\n#pragma mark - Application lifecycle\n\n\n- (BOOL)              application:(UIApplication *)application\n    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n\n  [NIOverview applicationDidFinishLaunching];\n\n  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];\n\n  CatalogTableViewController* catalogVC =\n    [[CatalogTableViewController alloc] initWithStyle:UITableViewStyleGrouped];\n\n  _rootViewController = [[UINavigationController alloc] initWithRootViewController:catalogVC];\n  self.window.rootViewController = _rootViewController;\n\n  [self.window makeKeyAndVisible];\n\n  [NIOverview addOverviewToWindow:self.window];\n  \n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/CaptionedPhotoView.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n/**\n * A subclass of NIPhotoScrollView that shows a caption beneath the picture.\n *\n * This class is purposefully lightweight and simply presents the caption without providing\n * any means of configuring the caption. This is left as an exercise to the developer.\n */\n@interface CaptionedPhotoView : NIPhotoScrollView\n\n@property (nonatomic, copy) NSString* caption;\n@property (nonatomic, retain) UIView* captionWell;\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/CaptionedPhotoView.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"CaptionedPhotoView.h\"\n\nstatic UIEdgeInsets kWellPadding = {0}; // see +initialize\n\n@interface CaptionedPhotoView ()\n@property (nonatomic, retain) UILabel* captionLabel;\n@end\n\n\n@implementation CaptionedPhotoView\n\n\n\n+ (void)initialize {\n  kWellPadding = UIEdgeInsetsMake(10, 10, 10, 10);\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    _captionWell = [[UIView alloc] initWithFrame:self.bounds];\n    _captionWell.autoresizingMask = (UIViewAutoresizingFlexibleWidth\n                                     | UIViewAutoresizingFlexibleTopMargin);\n\n    _captionLabel = [[UILabel alloc] initWithFrame:self.bounds];\n    _captionLabel.backgroundColor = [UIColor clearColor];\n    _captionLabel.lineBreakMode = NSLineBreakByTruncatingTail;\n    _captionLabel.numberOfLines = 0;\n    _captionLabel.font = [UIFont systemFontOfSize:14];\n    _captionLabel.textColor = [UIColor whiteColor];\n    _captionLabel.shadowOffset = CGSizeMake(0, 1);\n    _captionLabel.shadowColor = [UIColor colorWithWhite:0 alpha:0.5];\n\n    UIView* topBorder = [[UIView alloc] initWithFrame:CGRectZero];\n    topBorder.frame = CGRectMake(0, 0, self.bounds.size.width, 1);\n    topBorder.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin\n                                  | UIViewAutoresizingFlexibleWidth);\n\n    _captionWell.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7];\n    topBorder.backgroundColor = [UIColor colorWithWhite:0.2 alpha:1];\n\n    [_captionWell addSubview:topBorder];\n    [_captionWell addSubview:_captionLabel];\n    [self addSubview:_captionWell];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  CGFloat availableWidth = self.bounds.size.width - kWellPadding.left - kWellPadding.right;\n\n  CGSize labelSize =  [self.captionLabel.text sizeWithFont:self.captionLabel.font\n                                         constrainedToSize:CGSizeMake(availableWidth, CGFLOAT_MAX)\n                                             lineBreakMode:self.captionLabel.lineBreakMode];\n  CGFloat wellHeight = labelSize.height + kWellPadding.top + kWellPadding.bottom;\n  self.captionWell.frame = CGRectMake(0, self.bounds.size.height - wellHeight - NIToolbarHeightForOrientation(NIInterfaceOrientation()),\n                                      self.bounds.size.width, wellHeight);\n  self.captionLabel.frame = UIEdgeInsetsInsetRect(self.captionWell.bounds, kWellPadding);\n}\n\n#pragma mark - Public\n\n\n- (void)setCaption:(NSString *)caption {\n  if (_captionLabel.text != caption) {\n    _captionLabel.text = caption;\n    [self setNeedsLayout];\n  }\n}\n\n- (NSString *)caption {\n  return _captionLabel.text;\n}\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/CatalogTableViewController.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n@interface CatalogTableViewController : UITableViewController <NITableViewModelDelegate> {\n@private\n  NITableViewModel* _model;\n}\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/CatalogTableViewController.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"CatalogTableViewController.h\"\n\n#import \"FacebookPhotoAlbumViewController.h\"\n#import \"DribbblePhotoAlbumViewController.h\"\n#import \"AFNetworking.h\"\n\n\n@implementation CatalogTableViewController\n\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  if ((self = [super initWithStyle:style])) {\n    self.title = NSLocalizedString(@\"Photo Album Catalog\", @\"\");\n\n    NSArray* tableContents =\n    [NSArray arrayWithObjects:\n     @\"Dribbble\",\n     [NSDictionary dictionaryWithObjectsAndKeys:\n      [DribbblePhotoAlbumViewController class], @\"class\",\n      @\"Popular Shots\", @\"title\",\n      @\"/shots\", @\"initWith\",\n      nil],\n     [NSDictionary dictionaryWithObjectsAndKeys:\n      [DribbblePhotoAlbumViewController class], @\"class\",\n      @\"Everyone's Shots\", @\"title\",\n      @\"/shots/everyone\", @\"initWith\",\n      nil],\n     [NSDictionary dictionaryWithObjectsAndKeys:\n      [DribbblePhotoAlbumViewController class], @\"class\",\n      @\"Debuts\", @\"title\",\n      @\"/shots/debuts\", @\"initWith\",\n      nil],\n     \n     @\"Facebook Albums\",\n     [NSDictionary dictionaryWithObjectsAndKeys:\n      [FacebookPhotoAlbumViewController class], @\"class\",\n      @\"120th Commencement in Pictures\", @\"title\",\n      @\"10150219083838418\", @\"initWith\",\n      nil],\n     [NSDictionary dictionaryWithObjectsAndKeys:\n      [FacebookPhotoAlbumViewController class], @\"class\",\n      @\"Stanford 40th Annual Powwow\", @\"title\",\n      @\"10150185938728418\", @\"initWith\",\n      nil],\n     [NSDictionary dictionaryWithObjectsAndKeys:\n      [FacebookPhotoAlbumViewController class], @\"class\",\n      @\"Spring blossoms at Stanford\", @\"title\",\n      @\"10150160584103418\", @\"initWith\",\n      nil],\n     [NSDictionary dictionaryWithObjectsAndKeys:\n      [FacebookPhotoAlbumViewController class], @\"class\",\n      @\"Shark Week\", @\"title\",\n      @\"208546235826221\", @\"initWith\",\n      nil],\n     [NSDictionary dictionaryWithObjectsAndKeys:\n      [FacebookPhotoAlbumViewController class], @\"class\",\n      @\"Game of Thrones\", @\"title\",\n      @\"489714642733\", @\"initWith\",\n      nil],\n     nil];\n    _model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                     delegate:self];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.tableView.dataSource = _model;\n}\n\n- (void)viewWillAppear:(BOOL)animated {\n  [super viewWillAppear:animated];\n\n  [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleDefault\n                                              animated: animated];\n\n  UINavigationBar* navBar = self.navigationController.navigationBar;\n  navBar.barStyle = UIBarStyleDefault;\n  navBar.translucent = NO;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {\n  return NIIsSupportedOrientation(toInterfaceOrientation);\n}\n\n#pragma mark - NITableViewModelDelegate\n\n\n- (UITableViewCell *)tableViewModel: (NITableViewModel *)tableViewModel\n                   cellForTableView: (UITableView *)tableView\n                        atIndexPath: (NSIndexPath *)indexPath\n                         withObject: (id)object {\n  UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@\"row\"];\n\n  if (nil == cell) {\n    cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault\n                                   reuseIdentifier: @\"row\"];\n    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;\n  }\n\n  cell.textLabel.text = [object objectForKey:@\"title\"];\n\n  return cell;\n}\n\n#pragma mark - UITableViewDelegate\n\n\n- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {\n  id object = [_model objectAtIndexPath:indexPath];\n\n  Class vcClass = [object objectForKey:@\"class\"];\n  id initWith = [object objectForKey:@\"initWith\"];\n  NSString* title = [object objectForKey:@\"title\"];\n  UIViewController* vc = [[vcClass alloc] initWith:initWith];\n  vc.title = title;\n\n  [self.navigationController pushViewController:vc animated:YES];\n}\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/DribbblePhotoAlbumViewController.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NetworkPhotoAlbumViewController.h\"\n\n/**\n * Shows a Dribbble shot list.\n *\n *      Minimum iOS SDK Version: 4.0\n *      SDK Requirements: Blocks (4.0)\n */\n@interface DribbblePhotoAlbumViewController : NetworkPhotoAlbumViewController <\n  NIPhotoAlbumScrollViewDataSource,\n  NIPhotoScrubberViewDataSource,\n  NIOperationDelegate\n> {\n@private\n  NSString* _apiPath;\n\n  NSArray* _photoInformation;\n}\n\n/**\n * The generic entry point used by the catalog view controller to initialize this controller.\n *\n * Expects a value to be appended to http://api.dribbble.com that will return a list of shots.\n */\n- (id)initWith:(id)object;\n\n@property (nonatomic, copy) NSString* apiPath;\n\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/DribbblePhotoAlbumViewController.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"DribbblePhotoAlbumViewController.h\"\n#import \"AFNetworking.h\"\n\n\n@interface DribbblePhotoAlbumViewController ()\n@property (nonatomic,strong) AFHTTPSessionManager *albumHttpSessionManager;\n@end\n\n@implementation DribbblePhotoAlbumViewController\n\n\n- (id)initWith:(id)object {\n  if ((self = [self initWithNibName:nil bundle:nil])) {\n    self.apiPath = object;\n    self.albumHttpSessionManager = [AFHTTPSessionManager manager];\n    self.albumHttpSessionManager.responseSerializer = [AFJSONResponseSerializer serializer];\n  }\n  return self;\n}\n\n- (void)loadThumbnails {\n  for (NSInteger ix = 0; ix < [_photoInformation count]; ++ix) {\n    NSDictionary* photo = [_photoInformation objectAtIndex:ix];\n\n    NSString* photoIndexKey = [self cacheKeyForPhotoIndex:ix];\n\n    // Don't load the thumbnail if it's already in memory.\n    if (![self.thumbnailImageCache containsObjectWithName:photoIndexKey]) {\n      NSString* source = [photo objectForKey:@\"thumbnailSource\"];\n      [self requestImageFromSource: source\n                         photoSize: NIPhotoScrollViewPhotoSizeThumbnail\n                        photoIndex: ix];\n    }\n  }\n}\n\n- (void)loadAlbumInformation {\n  NSString* albumURLPath = [@\"http://api.dribbble.com\" stringByAppendingString:self.apiPath];\n\n  // Nimbus processors allow us to perform complex computations on a separate thread before\n  // returning the object to the main thread. This is useful here because we perform sorting\n  // operations and pruning on the results.\n  NSURL* url = [NSURL URLWithString:albumURLPath];\n\n  [self.albumHttpSessionManager GET:url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {\n    NSArray* data = [responseObject objectForKey:@\"shots\"];\n\n    NSMutableArray* photoInformation = [NSMutableArray arrayWithCapacity:[data count]];\n    for (NSDictionary* photo in data) {\n\n      // Gather the high-quality photo information.\n      NSString* originalImageSource = [photo objectForKey:@\"image_url\"];\n      NSInteger width = [[photo objectForKey:@\"width\"] intValue];\n      NSInteger height = [[photo objectForKey:@\"height\"] intValue];\n\n      // We gather the highest-quality photo's dimensions so that we can size the thumbnails\n      // correctly until the high-quality image is downloaded.\n      CGSize dimensions = CGSizeMake(width, height);\n\n      NSString* thumbnailImageSource = [photo objectForKey:@\"image_teaser_url\"];\n\n      NSDictionary* prunedPhotoInfo = [NSDictionary dictionaryWithObjectsAndKeys:\n                                       originalImageSource, @\"originalSource\",\n                                       thumbnailImageSource, @\"thumbnailSource\",\n                                       [NSValue valueWithCGSize:dimensions], @\"dimensions\",\n                                       nil];\n      [photoInformation addObject:prunedPhotoInfo];\n    }\n\n    _photoInformation = photoInformation;\n\n    [self loadThumbnails];\n    [self.photoAlbumView reloadData];\n    [self.photoScrubberView reloadData];\n\n    [self refreshChromeState];\n  } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {\n    NSLog(@\"Hi\");\n  }];\n}\n\n#pragma mark - UIViewController\n\n\n- (void)loadView {\n  [super loadView];\n\n  self.photoAlbumView.dataSource = self;\n  self.photoScrubberView.dataSource = self;\n\n  // Dribbble is for mockups and designs, so we don't want to allow the photos to be zoomed\n  // in and become blurry.\n  self.photoAlbumView.zoomingAboveOriginalSizeIsEnabled = NO;\n\n  // This title will be displayed until we get the results back for the album information.\n  self.title = NSLocalizedString(@\"Loading...\", @\"Navigation bar title - Loading a photo album\");\n\n  [self loadAlbumInformation];\n}\n\n- (void)viewDidUnload {\n  _photoInformation = nil;\n\n  [super viewDidUnload];\n}\n\n#pragma mark - NIPhotoScrubberViewDataSource\n\n\n- (NSInteger)numberOfPhotosInScrubberView:(NIPhotoScrubberView *)photoScrubberView {\n  return [_photoInformation count];\n}\n\n- (UIImage *)photoScrubberView: (NIPhotoScrubberView *)photoScrubberView\n              thumbnailAtIndex: (NSInteger)thumbnailIndex {\n  NSString* photoIndexKey = [self cacheKeyForPhotoIndex:thumbnailIndex];\n  \n  UIImage* image = [self.thumbnailImageCache objectWithName:photoIndexKey];\n  if (nil == image) {\n    NSDictionary* photo = [_photoInformation objectAtIndex:thumbnailIndex];\n    \n    NSString* thumbnailSource = [photo objectForKey:@\"thumbnailSource\"];\n    [self requestImageFromSource: thumbnailSource\n                       photoSize: NIPhotoScrollViewPhotoSizeThumbnail\n                      photoIndex: thumbnailIndex];\n  }\n  \n  return image;\n}\n\n#pragma mark - NIPhotoAlbumScrollViewDataSource\n\n\n- (NSInteger)numberOfPagesInPagingScrollView:(NIPhotoAlbumScrollView *)photoScrollView {\n  return [_photoInformation count];\n}\n\n- (UIImage *)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView\n                     photoAtIndex: (NSInteger)photoIndex\n                        photoSize: (NIPhotoScrollViewPhotoSize *)photoSize\n                        isLoading: (BOOL *)isLoading\n          originalPhotoDimensions: (CGSize *)originalPhotoDimensions {\n  UIImage* image = nil;\n\n  NSString* photoIndexKey = [self cacheKeyForPhotoIndex:photoIndex];\n\n  NSDictionary* photo = [_photoInformation objectAtIndex:photoIndex];\n\n  // Let the photo album view know how large the photo will be once it's fully loaded.\n  *originalPhotoDimensions = [[photo objectForKey:@\"dimensions\"] CGSizeValue];\n\n  image = [self.highQualityImageCache objectWithName:photoIndexKey];\n  if (nil != image) {\n    *photoSize = NIPhotoScrollViewPhotoSizeOriginal;\n\n  } else {\n    NSString* source = [photo objectForKey:@\"originalSource\"];\n    [self requestImageFromSource: source\n                       photoSize: NIPhotoScrollViewPhotoSizeOriginal\n                      photoIndex: photoIndex];\n\n    *isLoading = YES;\n\n    // Try to return the thumbnail image if we can.\n    image = [self.thumbnailImageCache objectWithName:photoIndexKey];\n    if (nil != image) {\n      *photoSize = NIPhotoScrollViewPhotoSizeThumbnail;\n\n    } else {\n      // Load the thumbnail as well.\n      NSString* thumbnailSource = [photo objectForKey:@\"thumbnailSource\"];\n      [self requestImageFromSource: thumbnailSource\n                         photoSize: NIPhotoScrollViewPhotoSizeThumbnail\n                        photoIndex: photoIndex];\n\n    }\n  }\n\n  return image;\n}\n\n- (void)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView\n     stopLoadingPhotoAtIndex: (NSInteger)photoIndex {\n  // TODO: Figure out how to implement this with AFNetworking.\n}\n\n- (id<NIPagingScrollViewPage>)pagingScrollView:(NIPagingScrollView *)pagingScrollView pageViewForIndex:(NSInteger)pageIndex {\n  return [self.photoAlbumView pagingScrollView:pagingScrollView pageViewForIndex:pageIndex];\n}\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/FacebookPhotoAlbumViewController.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NetworkPhotoAlbumViewController.h\"\n\n/**\n * Shows a Facebook photo album accessed through the Graph API.\n *\n *      Minimum iOS SDK Version: 4.0\n *      SDK Requirements: Blocks (4.0)\n */\n@interface FacebookPhotoAlbumViewController : NetworkPhotoAlbumViewController <\n  NIPhotoAlbumScrollViewDataSource,\n  NIPhotoScrubberViewDataSource,\n  NIOperationDelegate\n> {\n@private\n  NSString* _facebookAlbumId;\n\n  NSArray* _photoInformation;\n}\n\n/**\n * The generic entry point used by the catalog view controller to initialize this controller.\n *\n * Expects a photo album id.\n *\n *      @see facebookAlbumId\n */\n- (id)initWith:(id)object;\n\n/**\n * The album id of the Facebook album to load.\n *\n * You can preview what the Graph API will generate by fetching the following url:\n *\n * http://graph.facebook.com/<facebookAlbumId>/photos\n *\n * Album IDs to play with from the Stanford page at https://www.facebook.com/stanford\n *\n * - 10150219083838418 120th Commencement in Pictures\n * - 10150185938728418 Stanford 40th Annual Powwow\n * - 10150160584103418 Spring blossoms at Stanford\n */\n@property (nonatomic, copy) NSString* facebookAlbumId;\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/FacebookPhotoAlbumViewController.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"FacebookPhotoAlbumViewController.h\"\n\n#import \"CaptionedPhotoView.h\"\n#import \"NIPagingScrollView+Subclassing.h\"\n#import \"AFNetworking.h\"\n\n\n@interface FacebookPhotoAlbumViewController ()\n@property (nonatomic,strong) AFHTTPSessionManager *albumHttpSessionManager;\n@end\n\n@implementation FacebookPhotoAlbumViewController\n\n\n- (id)initWith:(id)object {\n  if ((self = [self initWithNibName:nil bundle:nil])) {\n    self.facebookAlbumId = object;\n    self.albumHttpSessionManager = [AFHTTPSessionManager manager];\n    self.albumHttpSessionManager.responseSerializer = [AFJSONResponseSerializer serializer];\n  }\n  return self;\n}\n\n- (void)loadThumbnails {\n  for (NSInteger ix = 0; ix < [_photoInformation count]; ++ix) {\n    NSDictionary* photo = [_photoInformation objectAtIndex:ix];\n\n    NSString* photoIndexKey = [self cacheKeyForPhotoIndex:ix];\n\n    // Don't load the thumbnail if it's already in memory.\n    if (![self.thumbnailImageCache containsObjectWithName:photoIndexKey]) {\n      NSString* source = [photo objectForKey:@\"thumbnailSource\"];\n      [self requestImageFromSource: source\n                         photoSize: NIPhotoScrollViewPhotoSizeThumbnail\n                        photoIndex: ix];\n    }\n  }\n}\n\n- (void)loadAlbumInformation {\n  NSString* albumURLPath = [NSString stringWithFormat:\n                            @\"http://graph.facebook.com/%@/photos?limit=200\",\n                            self.facebookAlbumId];\n\n  // Nimbus processors allow us to perform complex computations on a separate thread before\n  // returning the object to the main thread. This is useful here because we perform sorting\n  // operations and pruning on the results.\n  NSURL* url = [NSURL URLWithString:albumURLPath];\n\n  [self.albumHttpSessionManager GET:url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {\n    NSArray* data = [responseObject objectForKey:@\"data\"];\n\n    NSMutableArray* photoInformation = [NSMutableArray arrayWithCapacity:[data count]];\n    for (NSDictionary* photo in data) {\n      NSArray* images = [photo objectForKey:@\"images\"];\n\n      if ([images count] > 0) {\n        // Sort the images in descending order by image size.\n        NSArray* sortedImages =\n        [images sortedArrayUsingDescriptors:\n         [NSArray arrayWithObject:\n          [[NSSortDescriptor alloc] initWithKey:@\"width\" ascending:NO]]];\n\n        // Gather the high-quality photo information.\n        NSDictionary* originalImage = [sortedImages objectAtIndex:0];\n        NSString* originalImageSource = [originalImage objectForKey:@\"source\"];\n        NSInteger width = [[originalImage objectForKey:@\"width\"] intValue];\n        NSInteger height = [[originalImage objectForKey:@\"height\"] intValue];\n\n        // We gather the highest-quality photo's dimensions so that we can size the thumbnails\n        // correctly until the high-quality image is downloaded.\n        CGSize dimensions = CGSizeMake(width, height);\n\n        NSInteger numberOfImages = [sortedImages count];\n\n        // 0 being the lowest quality. On larger screens we fetch larger thumbnails.\n        NSInteger qualityLevel = (NIIsPad() || NIScreenScale() > 1) ? 1 : 0;\n\n        NSInteger thumbnailIndex = ((numberOfImages - 1)\n                                    - MIN(qualityLevel, numberOfImages - 2));\n\n        NSString* thumbnailImageSource = nil;\n        if (0 < thumbnailIndex) {\n          thumbnailImageSource = [[sortedImages objectAtIndex:thumbnailIndex] objectForKey:@\"source\"];\n        }\n\n        NSString* caption = [photo objectForKey:@\"name\"];\n        NSDictionary* prunedPhotoInfo = [NSDictionary dictionaryWithObjectsAndKeys:\n                                         originalImageSource, @\"originalSource\",\n                                         thumbnailImageSource, @\"thumbnailSource\",\n                                         [NSValue valueWithCGSize:dimensions], @\"dimensions\",\n                                         caption, @\"caption\",\n                                         nil];\n        [photoInformation addObject:prunedPhotoInfo];\n      }\n    }\n\n    _photoInformation = photoInformation;\n\n    [self loadThumbnails];\n    [self.photoAlbumView reloadData];\n    [self.photoScrubberView reloadData];\n\n    [self refreshChromeState];\n  } failure:nil];\n\n}\n\n#pragma mark - UIViewController\n\n\n- (void)loadView {\n  [super loadView];\n\n  self.photoAlbumView.dataSource = self;\n  self.photoScrubberView.dataSource = self;\n\n  // This title will be displayed until we get the results back for the album information.\n  self.title = NSLocalizedString(@\"Loading...\", @\"Navigation bar title - Loading a photo album\");\n\n  [self loadAlbumInformation];\n}\n\n- (void)viewDidUnload {\n  _photoInformation = nil;\n\n  [super viewDidUnload];\n}\n\n#pragma mark - NIPhotoScrubberViewDataSource\n\n\n- (NSInteger)numberOfPhotosInScrubberView:(NIPhotoScrubberView *)photoScrubberView {\n  return [_photoInformation count];\n}\n\n- (UIImage *)photoScrubberView: (NIPhotoScrubberView *)photoScrubberView\n              thumbnailAtIndex: (NSInteger)thumbnailIndex {\n  NSString* photoIndexKey = [self cacheKeyForPhotoIndex:thumbnailIndex];\n\n  UIImage* image = [self.thumbnailImageCache objectWithName:photoIndexKey];\n  if (nil == image) {\n    NSDictionary* photo = [_photoInformation objectAtIndex:thumbnailIndex];\n\n    NSString* thumbnailSource = [photo objectForKey:@\"thumbnailSource\"];\n    [self requestImageFromSource: thumbnailSource\n                       photoSize: NIPhotoScrollViewPhotoSizeThumbnail\n                      photoIndex: thumbnailIndex];\n  }\n\n  return image;\n}\n\n- (void)setChromeVisibility:(BOOL)isVisible animated:(BOOL)animated {\n  [super setChromeVisibility:isVisible animated:animated];\n\n  // TODO(jverkoey June 19, 2012): This is not the ideal way to do access the visible pages.\n  // Let's consider adding a new API for this.\n  [UIView beginAnimations:nil context:nil];\n  [UIView setAnimationCurve:NIStatusBarAnimationCurve()];\n  [UIView setAnimationDuration:NIStatusBarAnimationDuration()];\n  for (CaptionedPhotoView* captionedPageView in self.photoAlbumView.visiblePages) {\n    captionedPageView.captionWell.alpha = isVisible ? 1 : 0;\n  }\n  [UIView commitAnimations];\n}\n\n#pragma mark - NIPhotoAlbumScrollViewDataSource\n\n\n- (NSInteger)numberOfPagesInPagingScrollView:(NIPhotoAlbumScrollView *)photoScrollView {\n  return [_photoInformation count];\n}\n\n- (UIImage *)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView\n                     photoAtIndex: (NSInteger)photoIndex\n                        photoSize: (NIPhotoScrollViewPhotoSize *)photoSize\n                        isLoading: (BOOL *)isLoading\n          originalPhotoDimensions: (CGSize *)originalPhotoDimensions {\n  UIImage* image = nil;\n\n  NSString* photoIndexKey = [self cacheKeyForPhotoIndex:photoIndex];\n\n  NSDictionary* photo = [_photoInformation objectAtIndex:photoIndex];\n\n  // Let the photo album view know how large the photo will be once it's fully loaded.\n  *originalPhotoDimensions = [[photo objectForKey:@\"dimensions\"] CGSizeValue];\n\n  image = [self.highQualityImageCache objectWithName:photoIndexKey];\n  if (nil != image) {\n    *photoSize = NIPhotoScrollViewPhotoSizeOriginal;\n\n  } else {\n    NSString* source = [photo objectForKey:@\"originalSource\"];\n    [self requestImageFromSource: source\n                       photoSize: NIPhotoScrollViewPhotoSizeOriginal\n                      photoIndex: photoIndex];\n\n    *isLoading = YES;\n\n    // Try to return the thumbnail image if we can.\n    image = [self.thumbnailImageCache objectWithName:photoIndexKey];\n    if (nil != image) {\n      *photoSize = NIPhotoScrollViewPhotoSizeThumbnail;\n\n    } else {\n      // Load the thumbnail as well.\n      NSString* thumbnailSource = [photo objectForKey:@\"thumbnailSource\"];\n      [self requestImageFromSource: thumbnailSource\n                         photoSize: NIPhotoScrollViewPhotoSizeThumbnail\n                        photoIndex: photoIndex];\n    }\n  }\n\n  return image;\n}\n\n- (void)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView\n     stopLoadingPhotoAtIndex: (NSInteger)photoIndex {\n  // TODO: Figure out how to implement this with AFNetworking.\n}\n\n- (UIView<NIPagingScrollViewPage>*)pagingScrollView:(NIPagingScrollView *)pagingScrollView pageViewForIndex:(NSInteger)pageIndex {\n  // TODO (jverkoey Nov 27, 2011): We should make this sort of custom logic easier to build.\n  UIView<NIPagingScrollViewPage>* pageView = nil;\n  NSString* reuseIdentifier = NSStringFromClass([CaptionedPhotoView class]);\n  pageView = [pagingScrollView dequeueReusablePageWithIdentifier:reuseIdentifier];\n  if (nil == pageView) {\n    pageView = [[CaptionedPhotoView alloc] init];\n    pageView.reuseIdentifier = reuseIdentifier;\n  }\n\n  NIPhotoScrollView* photoScrollView = (NIPhotoScrollView *)pageView;\n  photoScrollView.photoScrollViewDelegate = self.photoAlbumView;\n  photoScrollView.zoomingAboveOriginalSizeIsEnabled = [self.photoAlbumView isZoomingAboveOriginalSizeEnabled];\n\n  CaptionedPhotoView* captionedView = (CaptionedPhotoView *)pageView;\n  captionedView.caption = [[_photoInformation objectAtIndex:pageIndex] objectForKey:@\"caption\"];\n  \n  return pageView;\n}\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/NetworkPhotoAlbumViewController.h",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n/**\n * A network-based photo album view controller.\n *\n *      Minimum iOS SDK Version: 4.0\n *      SDK Requirements: Blocks (4.0)\n *\n * This controller provides the necessary image caches and queue for loading images from\n * the network.\n *\n * <h2>Caching Architectural Design Considerations</h2>\n *\n * This controller maintains two image caches, one for high quality images and one for\n * thumbnails. The thumbnail cache is unbounded and the high quality cache has a limit of about\n * 3 1024x1024 images.\n *\n * The primary benefit of containing the image caches in this controller instead of using the\n * global image cache is that when this controller is no longer being used, all of its memory\n * is relinquished. If this controller were to use the global image cache it's also likely that\n * we might push out other application-wide images unnecessarily. In a production environment\n * we would depend on the network disk cache to load the photos back into memory when we return\n * to this controller.\n *\n * By default the thumbnail cache has no limit to its size, though it may be advantageous to\n * cap the cache at something reasonable.\n */\n@interface NetworkPhotoAlbumViewController : NIToolbarPhotoViewController {\n@private\n  \n  NSMutableSet* _activeRequests;\n\n  NIImageMemoryCache* _highQualityImageCache;\n  NIImageMemoryCache* _thumbnailImageCache;\n}\n\n/**\n * The high quality image cache.\n *\n * All original-sized photos are stored in this cache.\n *\n * By default the cache is unlimited with a max stress size of 1024*1024*3 pixels.\n *\n * Images are stored with a name that corresponds directly to the photo index in the form \"%d\".\n *\n * This is unloaded when the controller's view is unloaded from memory.\n */\n@property (nonatomic, readonly, retain) NIImageMemoryCache* highQualityImageCache;\n\n/**\n * The thumbnail image cache.\n *\n * All thumbnail photos are stored in this cache.\n *\n * By default the cache is unlimited.\n *\n * Images are stored with a name that corresponds directly to the photo index in the form \"%d\".\n *\n * This is unloaded when the controller's view is unloaded from memory.\n */\n@property (nonatomic, readonly, retain) NIImageMemoryCache* thumbnailImageCache;\n\n/**\n * Generate the in-memory cache key for the given index.\n */\n- (NSString *)cacheKeyForPhotoIndex:(NSInteger)photoIndex;\n\n/**\n * Request an image from a source URL and store the result in the corresponding image cache.\n *\n *      @param source       The image's source URL path.\n *      @param photoSize    The size of the photo being requested.\n *      @param photoIndex   The photo index used to store the image in the memory cache.\n */\n- (void)requestImageFromSource: (NSString *)source\n                     photoSize: (NIPhotoScrollViewPhotoSize)photoSize\n                    photoIndex: (NSInteger)photoIndex;\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/NetworkPhotoAlbumViewController.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NetworkPhotoAlbumViewController.h\"\n\n#import \"NIOverviewMemoryCacheController.h\"\n#import \"NimbusOverview.h\"\n#import \"NIOverviewView.h\"\n#import \"NIOverviewPageView.h\"\n#import \"AFNetworking.h\"\n\n#ifdef DEBUG\n@interface NetworkPhotoAlbumViewController()\n@property (nonatomic, retain) NIOverviewMemoryCachePageView* highQualityPage;\n@property (nonatomic, retain) NIOverviewMemoryCachePageView* thumbnailPage;\n@end\n#endif\n\n@interface NetworkPhotoAlbumViewController()\n@property (nonatomic,strong) AFHTTPSessionManager *httpSessionManager;\n@end\n\n@implementation NetworkPhotoAlbumViewController\n\n- (void)shutdown_NetworkPhotoAlbumViewController {\n  [self.httpSessionManager invalidateSessionCancelingTasks:YES];\n\n#ifdef DEBUG\n  [[NIOverview view] removePageView:self.highQualityPage];\n  [[NIOverview view] removePageView:self.thumbnailPage];\n#endif\n}\n\n- (void)dealloc {\n  [self shutdown_NetworkPhotoAlbumViewController];\n}\n\n- (NSString *)cacheKeyForPhotoIndex:(NSInteger)photoIndex {\n  return [NSString stringWithFormat:@\"%zd\", photoIndex];\n}\n\n- (NSInteger)identifierWithPhotoSize:(NIPhotoScrollViewPhotoSize)photoSize\n                          photoIndex:(NSInteger)photoIndex {\n  BOOL isThumbnail = (NIPhotoScrollViewPhotoSizeThumbnail == photoSize);\n  NSInteger identifier = isThumbnail ? -(photoIndex + 1) : photoIndex;\n  return identifier;\n}\n\n- (id)identifierKeyFromIdentifier:(NSInteger)identifier {\n  return [NSNumber numberWithInteger:identifier];\n}\n\n- (void)requestImageFromSource:(NSString *)source\n                     photoSize:(NIPhotoScrollViewPhotoSize)photoSize\n                    photoIndex:(NSInteger)photoIndex {\n  BOOL isThumbnail = (NIPhotoScrollViewPhotoSizeThumbnail == photoSize);\n  NSInteger identifier = [self identifierWithPhotoSize:photoSize photoIndex:photoIndex];\n  id identifierKey = [self identifierKeyFromIdentifier:identifier];\n\n  // Avoid duplicating requests.\n  if ([_activeRequests containsObject:identifierKey]) {\n    return;\n  }\n\n  NSURL* url = [NSURL URLWithString:source];\n  \n  NSString* photoIndexKey = [self cacheKeyForPhotoIndex:photoIndex];\n\n  [self.httpSessionManager GET:url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, UIImage* image) {\n    // Store the image in the correct image cache.\n    if (isThumbnail) {\n      [_thumbnailImageCache storeObject: image\n                               withName: photoIndexKey];\n\n    } else {\n      [_highQualityImageCache storeObject: image\n                                 withName: photoIndexKey];\n    }\n\n    // If you decide to move this code around then ensure that this method is called from\n    // the main thread. Calling it from any other thread will have undefined results.\n    [self.photoAlbumView didLoadPhoto: image\n                              atIndex: photoIndex\n                            photoSize: photoSize];\n\n    if (isThumbnail) {\n      [self.photoScrubberView didLoadThumbnail:image atIndex:photoIndex];\n    }\n\n    [_activeRequests removeObject:identifierKey];\n\n  } failure:nil];\n\n  // Start the operation.\n  [_activeRequests addObject:identifierKey];\n}\n\n#pragma mark - UIViewController\n\n\n- (void)loadView {\n  [super loadView];\n\n  _activeRequests = [[NSMutableSet alloc] init];\n\n  _highQualityImageCache = [[NIImageMemoryCache alloc] init];\n  _thumbnailImageCache = [[NIImageMemoryCache alloc] init];\n\n  self.httpSessionManager = [AFHTTPSessionManager manager];\n  AFImageResponseSerializer *serializer = [AFImageResponseSerializer serializer];\n  serializer.imageScale = 1;\n  self.httpSessionManager.responseSerializer = serializer;\n  self.httpSessionManager.operationQueue.maxConcurrentOperationCount = 5;\n\n  [_highQualityImageCache setMaxNumberOfPixels:1024L*1024L*10L];\n  [_thumbnailImageCache setMaxNumberOfPixelsUnderStress:1024L*1024L*3L];\n\n  // Set the default loading image.\n  self.photoAlbumView.loadingImage = [UIImage imageWithContentsOfFile:\n                                      NIPathForBundleResource(nil, @\"NimbusPhotos.bundle/gfx/default.png\")];\n\n#ifdef DEBUG\n  self.highQualityPage = [NIOverviewMemoryCachePageView pageWithCache:self.highQualityImageCache];\n  [[NIOverview view] addPageView:self.highQualityPage];\n  self.thumbnailPage = [NIOverviewMemoryCachePageView pageWithCache:self.thumbnailImageCache];\n  [[NIOverview view] addPageView:self.thumbnailPage];\n#endif\n}\n\n- (void)viewDidUnload {\n  [self shutdown_NetworkPhotoAlbumViewController];\n\n  [super viewDidUnload];\n}\n\n@end\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/NetworkPhotoAlbum_Prefix.pch",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#ifdef __OBJC__\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n#import <QuartzCore/QuartzCore.h>\n#import \"NimbusCore.h\"\n#import \"NimbusPhotos.h\"\n#import \"NimbusModels.h\"\n#endif\n"
  },
  {
    "path": "examples/photos/NetworkPhotoAlbums/src/main.m",
    "content": "//\n// Copyright 2011-2014 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n#import \"AppDelegate.h\"\n\nint main(int argc, char *argv[]) {\n  @autoreleasepool {\n    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n  }\n}\n"
  },
  {
    "path": "scripts/Paths.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\"\"\"\nPaths.py\n\nCreated by Jeff Verkoeyen on 2010-10-18.\nCopyright 2009-2010 Facebook\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\"\"\"\n\nimport os\n\nscript_dir = os.path.dirname(os.path.realpath(__file__))\nsrc_dir = os.path.dirname(script_dir)\n"
  },
  {
    "path": "scripts/Pbxproj.html",
    "content": "\n<!doctype html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n<html><head><title>Python: module Pbxproj</title>\n</head><body bgcolor=\"#f0f0f8\">\n\n<table width=\"100%\" cellspacing=0 cellpadding=2 border=0 summary=\"heading\">\n<tr bgcolor=\"#7799ee\">\n<td valign=bottom>&nbsp;<br>\n<font color=\"#ffffff\" face=\"helvetica, arial\">&nbsp;<br><big><big><strong>Pbxproj</strong></big></big></font></td\n><td align=right valign=bottom\n><font color=\"#ffffff\" face=\"helvetica, arial\"><a href=\".\">index</a><br><a href=\"file:/Users/featherless/workbench/ios/three20/src/scripts/Pbxproj.py\">/Users/featherless/workbench/ios/three20/src/scripts/Pbxproj.py</a></font></td></tr></table>\n    <p><tt><a href=\"#Pbxproj\">Pbxproj</a>.py<br>\n&nbsp;<br>\nWorking&nbsp;with&nbsp;the&nbsp;pbxproj&nbsp;file&nbsp;format&nbsp;is&nbsp;a&nbsp;pain&nbsp;in&nbsp;the&nbsp;ass.<br>\n&nbsp;<br>\nThis&nbsp;<a href=\"__builtin__.html#object\">object</a>&nbsp;provides&nbsp;a&nbsp;couple&nbsp;basic&nbsp;features&nbsp;for&nbsp;parsing&nbsp;pbxproj&nbsp;files:<br>\n&nbsp;<br>\n*&nbsp;Getting&nbsp;a&nbsp;dependency&nbsp;list<br>\n*&nbsp;Adding&nbsp;one&nbsp;pbxproj&nbsp;to&nbsp;another&nbsp;pbxproj&nbsp;as&nbsp;a&nbsp;dependency<br>\n&nbsp;<br>\nVersion&nbsp;1.0.<br>\n&nbsp;<br>\nHistory:<br>\n1.0&nbsp;-&nbsp;October&nbsp;20,&nbsp;2010:&nbsp;Initial&nbsp;hacked-together&nbsp;version&nbsp;finished.&nbsp;It&nbsp;is&nbsp;alive!<br>\n&nbsp;<br>\nCreated&nbsp;by&nbsp;Jeff&nbsp;Verkoeyen&nbsp;on&nbsp;2010-10-18.<br>\nCopyright&nbsp;2009-2010&nbsp;Facebook<br>\n&nbsp;<br>\nLicensed&nbsp;under&nbsp;the&nbsp;Apache&nbsp;License,&nbsp;Version&nbsp;2.0&nbsp;(the&nbsp;\"License\");<br>\nyou&nbsp;may&nbsp;not&nbsp;use&nbsp;this&nbsp;file&nbsp;except&nbsp;in&nbsp;compliance&nbsp;with&nbsp;the&nbsp;License.<br>\nYou&nbsp;may&nbsp;obtain&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;License&nbsp;at<br>\n&nbsp;<br>\n&nbsp;&nbsp;&nbsp;<a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a><br>\n&nbsp;<br>\nUnless&nbsp;required&nbsp;by&nbsp;applicable&nbsp;law&nbsp;or&nbsp;agreed&nbsp;to&nbsp;in&nbsp;writing,&nbsp;software<br>\ndistributed&nbsp;under&nbsp;the&nbsp;License&nbsp;is&nbsp;distributed&nbsp;on&nbsp;an&nbsp;\"AS&nbsp;IS\"&nbsp;BASIS,<br>\nWITHOUT&nbsp;WARRANTIES&nbsp;OR&nbsp;CONDITIONS&nbsp;OF&nbsp;ANY&nbsp;KIND,&nbsp;either&nbsp;express&nbsp;or&nbsp;implied.<br>\nSee&nbsp;the&nbsp;License&nbsp;for&nbsp;the&nbsp;specific&nbsp;language&nbsp;governing&nbsp;permissions&nbsp;and<br>\nlimitations&nbsp;under&nbsp;the&nbsp;License.</tt></p>\n<p>\n<table width=\"100%\" cellspacing=0 cellpadding=2 border=0 summary=\"section\">\n<tr bgcolor=\"#aa55cc\">\n<td colspan=3 valign=bottom>&nbsp;<br>\n<font color=\"#ffffff\" face=\"helvetica, arial\"><big><strong>Modules</strong></big></font></td></tr>\n    \n<tr><td bgcolor=\"#aa55cc\"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>\n<td width=\"100%\"><table width=\"100%\" summary=\"list\"><tr><td width=\"25%\" valign=top><a href=\"Paths.html\">Paths</a><br>\n<a href=\"hashlib.html\">hashlib</a><br>\n</td><td width=\"25%\" valign=top><a href=\"logging.html\">logging</a><br>\n<a href=\"os.html\">os</a><br>\n</td><td width=\"25%\" valign=top><a href=\"re.html\">re</a><br>\n<a href=\"sys.html\">sys</a><br>\n</td><td width=\"25%\" valign=top></td></tr></table></td></tr></table><p>\n<table width=\"100%\" cellspacing=0 cellpadding=2 border=0 summary=\"section\">\n<tr bgcolor=\"#ee77aa\">\n<td colspan=3 valign=bottom>&nbsp;<br>\n<font color=\"#ffffff\" face=\"helvetica, arial\"><big><strong>Classes</strong></big></font></td></tr>\n    \n<tr><td bgcolor=\"#ee77aa\"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>\n<td width=\"100%\"><dl>\n<dt><font face=\"helvetica, arial\"><a href=\"__builtin__.html#object\">__builtin__.object</a>\n</font></dt><dd>\n<dl>\n<dt><font face=\"helvetica, arial\"><a href=\"Pbxproj.html#Pbxproj\">Pbxproj</a>\n</font></dt></dl>\n</dd>\n</dl>\n <p>\n<table width=\"100%\" cellspacing=0 cellpadding=2 border=0 summary=\"section\">\n<tr bgcolor=\"#ffc8d8\">\n<td colspan=3 valign=bottom>&nbsp;<br>\n<font color=\"#000000\" face=\"helvetica, arial\"><a name=\"Pbxproj\">class <strong>Pbxproj</strong></a>(<a href=\"__builtin__.html#object\">__builtin__.object</a>)</font></td></tr>\n    \n<tr><td bgcolor=\"#ffc8d8\"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>\n<td width=\"100%\">Methods defined here:<br>\n<dl><dt><a name=\"Pbxproj-__init__\"><strong>__init__</strong></a>(self, name)</dt><dd><tt>#&nbsp;Valid&nbsp;names<br>\n#&nbsp;Three20<br>\n#&nbsp;Three20:Three20-Xcode3.2.5<br>\n#&nbsp;/path/to/project.xcodeproj/project.pbxproj</tt></dd></dl>\n\n<dl><dt><a name=\"Pbxproj-__str__\"><strong>__str__</strong></a>(self)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-add_build_setting\"><strong>add_build_setting</strong></a>(self, configuration, setting_name, value)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-add_buildfile\"><strong>add_buildfile</strong></a>(self, name, file_ref_hash, default_guid)</dt><dd><tt>#&nbsp;Add&nbsp;a&nbsp;line&nbsp;to&nbsp;the&nbsp;PBXBuildFile&nbsp;section.<br>\n#<br>\n#&nbsp;&lt;default_guid&gt;&nbsp;/*&nbsp;&lt;name&gt;&nbsp;in&nbsp;Frameworks&nbsp;*/&nbsp;=&nbsp;{isa&nbsp;=&nbsp;PBXBuildFile;&nbsp;fileRef&nbsp;=&nbsp;&lt;file_ref_hash&gt;&nbsp;/*&nbsp;&lt;name&gt;&nbsp;*/;&nbsp;};<br>\n#<br>\n#&nbsp;Returns:&nbsp;&lt;default_guid&gt;&nbsp;if&nbsp;a&nbsp;line&nbsp;was&nbsp;added.<br>\n#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Otherwise,&nbsp;the&nbsp;existing&nbsp;guid&nbsp;is&nbsp;returned.</tt></dd></dl>\n\n<dl><dt><a name=\"Pbxproj-add_dependency\"><strong>add_dependency</strong></a>(self, dep)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-add_file_to_frameworks\"><strong>add_file_to_frameworks</strong></a>(self, name, guid)</dt><dd><tt>#&nbsp;Add&nbsp;a&nbsp;file&nbsp;to&nbsp;the&nbsp;Frameworks&nbsp;PBXGroup.<br>\n#<br>\n#&nbsp;&lt;guid&gt;&nbsp;/*&nbsp;&lt;name&gt;&nbsp;*/,</tt></dd></dl>\n\n<dl><dt><a name=\"Pbxproj-add_file_to_frameworks_phase\"><strong>add_file_to_frameworks_phase</strong></a>(self, name, guid)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-add_filereference\"><strong>add_filereference</strong></a>(self, name, file_type, default_guid, rel_path, source_tree)</dt><dd><tt>#&nbsp;Add&nbsp;a&nbsp;line&nbsp;to&nbsp;the&nbsp;PBXFileReference&nbsp;section.<br>\n#<br>\n#&nbsp;&lt;default_guid&gt;&nbsp;/*&nbsp;&lt;name&gt;&nbsp;*/&nbsp;=&nbsp;{isa&nbsp;=&nbsp;PBXFileReference;&nbsp;lastKnownFileType&nbsp;=&nbsp;\"wrapper.&lt;file_type&gt;\";&nbsp;name&nbsp;=&nbsp;&lt;name&gt;;&nbsp;path&nbsp;=&nbsp;&lt;rel_path&gt;;&nbsp;sourceTree&nbsp;=&nbsp;&lt;source_tree&gt;;&nbsp;};<br>\n#<br>\n#&nbsp;Returns:&nbsp;&lt;default_guid&gt;&nbsp;if&nbsp;a&nbsp;line&nbsp;was&nbsp;added.<br>\n#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Otherwise,&nbsp;the&nbsp;existing&nbsp;guid&nbsp;is&nbsp;returned.</tt></dd></dl>\n\n<dl><dt><a name=\"Pbxproj-add_framework\"><strong>add_framework</strong></a>(self, framework)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-add_header_search_path\"><strong>add_header_search_path</strong></a>(self, configuration)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-dependencies\"><strong>dependencies</strong></a>(self)</dt><dd><tt>#&nbsp;Get&nbsp;and&nbsp;cache&nbsp;the&nbsp;dependencies&nbsp;for&nbsp;this&nbsp;project.</tt></dd></dl>\n\n<dl><dt><a name=\"Pbxproj-get_hash_base\"><strong>get_hash_base</strong></a>(self, uniquename)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-get_project_data\"><strong>get_project_data</strong></a>(self)</dt><dd><tt>#&nbsp;Load&nbsp;the&nbsp;project&nbsp;data&nbsp;from&nbsp;disk.</tt></dd></dl>\n\n<dl><dt><a name=\"Pbxproj-guid\"><strong>guid</strong></a>(self)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-path\"><strong>path</strong></a>(self)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-set_project_data\"><strong>set_project_data</strong></a>(self, project_data)</dt><dd><tt>#&nbsp;Write&nbsp;the&nbsp;project&nbsp;data&nbsp;to&nbsp;disk.</tt></dd></dl>\n\n<dl><dt><a name=\"Pbxproj-uniqueid\"><strong>uniqueid</strong></a>(self)</dt></dl>\n\n<dl><dt><a name=\"Pbxproj-xcodeprojpath\"><strong>xcodeprojpath</strong></a>(self)</dt><dd><tt>#&nbsp;A&nbsp;pbxproj&nbsp;file&nbsp;is&nbsp;contained&nbsp;within&nbsp;an&nbsp;xcodeproj&nbsp;file.<br>\n#&nbsp;This&nbsp;method&nbsp;simply&nbsp;strips&nbsp;off&nbsp;the&nbsp;project.pbxproj&nbsp;part&nbsp;of&nbsp;the&nbsp;path.</tt></dd></dl>\n\n<hr>\nStatic methods defined here:<br>\n<dl><dt><a name=\"Pbxproj-get_pbxproj_by_name\"><strong>get_pbxproj_by_name</strong></a>(name)</dt></dl>\n\n<hr>\nData descriptors defined here:<br>\n<dl><dt><strong>__dict__</strong></dt>\n<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>\n</dl>\n<dl><dt><strong>__weakref__</strong></dt>\n<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>\n</dl>\n</td></tr></table></td></tr></table><p>\n<table width=\"100%\" cellspacing=0 cellpadding=2 border=0 summary=\"section\">\n<tr bgcolor=\"#eeaa77\">\n<td colspan=3 valign=bottom>&nbsp;<br>\n<font color=\"#ffffff\" face=\"helvetica, arial\"><big><strong>Functions</strong></big></font></td></tr>\n    \n<tr><td bgcolor=\"#eeaa77\"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>\n<td width=\"100%\"><dl><dt><a name=\"-commonpath\"><strong>commonpath</strong></a>(l1, l2, common<font color=\"#909090\">=[]</font>)</dt></dl>\n <dl><dt><a name=\"-pathsplit\"><strong>pathsplit</strong></a>(p, rest<font color=\"#909090\">=[]</font>)</dt><dd><tt>#&nbsp;The&nbsp;following&nbsp;relative&nbsp;path&nbsp;methods&nbsp;recyled&nbsp;from:<br>\n#&nbsp;<a href=\"http://code.activestate.com/recipes/208993-compute-relative-path-from-one-directory-to-anothe/\">http://code.activestate.com/recipes/208993-compute-relative-path-from-one-directory-to-anothe/</a><br>\n#&nbsp;Author:&nbsp;Cimarron&nbsp;Taylor<br>\n#&nbsp;Date:&nbsp;July&nbsp;6,&nbsp;2003</tt></dd></dl>\n <dl><dt><a name=\"-relpath\"><strong>relpath</strong></a>(p1, p2)</dt></dl>\n</td></tr></table><p>\n<table width=\"100%\" cellspacing=0 cellpadding=2 border=0 summary=\"section\">\n<tr bgcolor=\"#55aa55\">\n<td colspan=3 valign=bottom>&nbsp;<br>\n<font color=\"#ffffff\" face=\"helvetica, arial\"><big><strong>Data</strong></big></font></td></tr>\n    \n<tr><td bgcolor=\"#55aa55\"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>\n<td width=\"100%\"><strong>pbxproj_cache</strong> = {}</td></tr></table>\n</body></html>"
  },
  {
    "path": "scripts/Pbxproj.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\"\"\"\nPbxproj.py\n\nWorking with the pbxproj file format is a pain in the ass.\n\nThis object provides a couple basic features for parsing pbxproj files:\n\n* Getting a dependency list\n* Adding one pbxproj to another pbxproj as a dependency\n\nVersion 1.1.\n\nHistory:\n1.0 - October 20, 2010: Initial hacked-together version finished. It is alive!\n1.1 - January 11, 2011: Add configuration settings to all configurations by default.\n\nCreated by Jeff Verkoeyen on 2010-10-18.\nCopyright 2009-2011 Facebook\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\"\"\"\n\nimport hashlib\nimport logging\nimport os\nimport re\nimport sys\nimport Paths\n\npbxproj_cache = {}\n\n# The following relative path methods recyled from:\n# http://code.activestate.com/recipes/208993-compute-relative-path-from-one-directory-to-anothe/\n# Author: Cimarron Taylor\n# Date: July 6, 2003\ndef pathsplit(p, rest=[]):\n    (h,t) = os.path.split(p)\n    if len(h) < 1: return [t]+rest\n    if len(t) < 1: return [h]+rest\n    return pathsplit(h,[t]+rest)\n\ndef commonpath(l1, l2, common=[]):\n    if len(l1) < 1: return (common, l1, l2)\n    if len(l2) < 1: return (common, l1, l2)\n    if l1[0] != l2[0]: return (common, l1, l2)\n    return commonpath(l1[1:], l2[1:], common+[l1[0]])\n\ndef relpath(p1, p2):\n    (common,l1,l2) = commonpath(pathsplit(p1), pathsplit(p2))\n    p = []\n    if len(l1) > 0:\n        p = [ '../' * len(l1) ]\n    p = p + l2\n    return os.path.join( *p )\n\nclass Pbxproj(object):\n\n\t@staticmethod\n\tdef get_pbxproj_by_name(name, xcode_version = None):\n\t\tif name not in pbxproj_cache:\n\t\t\tpbxproj_cache[name] = Pbxproj(name, xcode_version = xcode_version)\n\n\t\treturn pbxproj_cache[name]\n\n\t# Valid names\n\t# Three20\n\t# Three20:Three20-Xcode3.2.5\n\t# /path/to/project.xcodeproj/project.pbxproj\n\tdef __init__(self, name, xcode_version = None):\n\t\tself._project_data = None\n\n\t\tparts = name.split(':')\n\t\tself.name = parts[0]\n\n\t\tif len(parts) > 1:\n\t\t\tself.target = parts[1]\n\t\telse:\n\t\t\tvalid_file_chars = '[a-zA-Z0-9\\.\\-:+ \"\\'!@#$%^&*\\(\\)]';\n\t\t\tif re.match('^'+valid_file_chars+'+$', self.name):\n\t\t\t\tself.target = self.name\n\t\t\telse:\n\t\t\t\tresult = re.search('('+valid_file_chars+'+)\\.xcodeproj', self.name)\n\t\t\t\tif not result:\n\t\t\t\t\tself.target = self.name\n\t\t\t\telse:\n\t\t\t\t\t(self.target, ) = result.groups()\n\n\t\tmatch = re.search('([^/\\\\\\\\]+)\\.xcodeproj', self.name)\n\t\tif not match:\n\t\t\tself._project_name = self.name\n\t\telse:\n\t\t\t(self._project_name, ) = match.groups()\n\n\t\tself._guid = None\n\t\tself._deps = None\n\t\tself._xcode_version = xcode_version\n\t\tself._projectVersion = None\n\t\tself.guid()\n\n\tdef __str__(self):\n\t\treturn str(self.name)+\" target:\"+str(self.target)+\" guid:\"+str(self._guid)+\" prodguid: \"+self._product_guid+\" prodname: \"+self._product_name\n\n\tdef uniqueid(self):\n\t\treturn self.name + ':' + self.target\n\n\tdef path(self):\n\t\t# TODO: No sense calculating this every time, just store it when we get the name.\n\t\tif re.match('^[a-zA-Z0-9\\.\\-:+\"]+$', self.name):\n\t\t\treturn os.path.join(Paths.src_dir, self.name.strip('\"'), self.name.strip('\"')+'.xcodeproj', 'project.pbxproj')\n\t\telif not re.match('project.pbxproj$', self.name):\n\t\t\treturn os.path.join(self.name, 'project.pbxproj')\n\t\telse:\n\t\t\treturn self.name\n\n\t# A pbxproj file is contained within an xcodeproj file.\n\t# This method simply strips off the project.pbxproj part of the path.\n\tdef xcodeprojpath(self):\n\t\treturn os.path.dirname(self.path())\n\n\tdef guid(self):\n\t\tif not self._guid:\n\t\t\tself.dependencies()\n\n\t\treturn self._guid\n\n\tdef version(self):\n\t\tif not self._projectVersion:\n\t\t\tself.dependencies()\n\n\t\treturn self._projectVersion\n\n\t# Load the project data from disk.\n\tdef get_project_data(self):\n\t\tif self._project_data is None:\n\t\t\tif not os.path.exists(self.path()):\n\t\t\t\tlogging.info(\"Couldn't find the project at this path:\")\n\t\t\t\tlogging.info(self.path())\n\t\t\t\treturn None\n\n\t\t\tproject_file = open(self.path(), 'r')\n\t\t\tself._project_data = project_file.read()\n\n\t\treturn self._project_data\n\n\t# Write the project data to disk.\n\tdef set_project_data(self, project_data):\n\t\tif self._project_data != project_data:\n\t\t\tself._project_data = project_data\n\t\t\tproject_file = open(self.path(), 'w')\n\t\t\tproject_file.write(self._project_data)\n\n\t# Get and cache the dependencies for this project.\n\tdef dependencies(self):\n\t\tif self._deps is not None:\n\t\t\treturn self._deps\n\n\t\tproject_data = self.get_project_data()\n\t\t\n\t\tif project_data is None:\n\t\t\tlogging.error(\"Unable to open the project file at this path (is it readable?): \"+self.path())\n\t\t\treturn None\n\n\t\t# Get project file format version\n\n\t\tresult = re.search('\\tobjectVersion = ([0-9]+);', project_data)\n\n\t\tif not result:\n\t\t\tlogging.error(\"Can't recover: unable to find the project version for your target at: \"+self.path())\n\t\t\treturn None\n\t\n\t\t(self._projectVersion,) = result.groups()\n\t\tself._projectVersion = int(self._projectVersion)\n\n\t\t# Get configuration list guid\n\n\t\tresult = re.search('[A-Z0-9]+ \\/\\* '+re.escape(self.target)+' \\*\\/ = {\\n[ \\t]+isa = PBXNativeTarget;(?:.|\\n)+?buildConfigurationList = ([A-Z0-9]+) \\/\\* Build configuration list for PBXNativeTarget \"'+re.escape(self.target)+'\" \\*\\/;',\n\t\t                   project_data)\n\n\t\tif result:\n\t\t\t(self.configurationListGuid, ) = result.groups()\n\t\telse:\n\t\t\tself.configurationListGuid = None\n\n\n\t\t# Get configuration list\n\t\t\n\t\tif self.configurationListGuid:\n\t\t\tmatch = re.search(re.escape(self.configurationListGuid)+' \\/\\* Build configuration list for PBXNativeTarget \"'+re.escape(self.target)+'\" \\*\\/ = \\{\\n[ \\t]+isa = XCConfigurationList;\\n[ \\t]+buildConfigurations = \\(\\n((?:.|\\n)+?)\\);', project_data)\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the configuration list.\")\n\t\t\t\treturn False\n\n\t\t\t(configurationList,) = match.groups()\n\t\t\tself.configurations = re.findall('[ \\t]+([A-Z0-9]+) \\/\\* (.+) \\*\\/,\\n', configurationList)\n\n\t\t# Get build phases\n\n\t\tresult = re.search('([A-Z0-9]+) \\/\\* '+re.escape(self.target)+' \\*\\/ = {\\n[ \\t]+isa = PBXNativeTarget;(?:.|\\n)+?buildPhases = \\(\\n((?:.|\\n)+?)\\);',\n\t\t                   project_data)\n\t\n\t\tif not result:\n\t\t\tlogging.error(\"Can't recover: Unable to find the build phases from your target at: \"+self.path())\n\t\t\treturn None\n\t\n\t\t(self._guid, buildPhases, ) = result.groups()\n\n\t\t# Get the build phases we care about.\n\n\t\tmatch = re.search('([A-Z0-9]+) \\/\\* Resources \\*\\/', buildPhases)\n\t\tif match:\n\t\t\t(self._resources_guid, ) = match.groups()\n\t\telse:\n\t\t\tself._resources_guid = None\n\t\t\n\t\tmatch = re.search('([A-Z0-9]+) \\/\\* Frameworks \\*\\/', buildPhases)\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the Frameworks phase from: \"+self.path())\n\t\t\tlogging.error(\"Please add a New Link Binary With Libraries Build Phase to your target\")\n\t\t\tlogging.error(\"Right click your target in the project, Add, New Build Phase,\")\n\t\t\tlogging.error(\"  \\\"New Link Binary With Libraries Build Phase\\\"\")\n\t\t\treturn None\n\n\t\t(self._frameworks_guid, ) = match.groups()\n\n\t\t# Get the dependencies\n\n\t\tresult = re.search(re.escape(self._guid)+' \\/\\* '+re.escape(self.target)+' \\*\\/ = {\\n[ \\t]+isa = PBXNativeTarget;(?:.|\\n)+?dependencies = \\(\\n((?:[ \\t]+[A-Z0-9]+ \\/\\* PBXTargetDependency \\*\\/,\\n)*)[ \\t]*\\);\\n',\n\t\t                   project_data)\n\t\n\t\tif not result:\n\t\t\tlogging.error(\"Unable to get dependencies from: \"+self.path())\n\t\t\treturn None\n\t\n\t\t(dependency_set, ) = result.groups()\n\t\tdependency_guids = re.findall('[ \\t]+([A-Z0-9]+) \\/\\* PBXTargetDependency \\*\\/,\\n', dependency_set)\n\n\t\t# Parse the dependencies\n\n\t\tdependency_names = []\n\n\t\tfor guid in dependency_guids:\n\t\t\tresult = re.search(guid+' \\/\\* PBXTargetDependency \\*\\/ = \\{\\n[ \\t]+isa = PBXTargetDependency;\\n[ \\t]*name = ([\"a-zA-Z0-9\\.\\-]+);',\n\t\t\t                   project_data)\n\t\t\n\t\t\tif result:\n\t\t\t\t(dependency_name, ) = result.groups()\n\t\t\t\tdependency_names.append(dependency_name)\n\n\t\tself._deps = dependency_names\n\n\n\t\t# Get the product guid and name.\n\n\t\tresult = re.search(re.escape(self._guid)+' \\/\\* '+re.escape(self.target)+' \\*\\/ = {\\n[ \\t]+isa = PBXNativeTarget;(?:.|\\n)+?productReference = ([A-Z0-9]+) \\/\\* (.+?) \\*\\/;',\n\t\t                   project_data)\n\t\n\t\tif not result:\n\t\t\tlogging.error(\"Unable to get product guid from: \"+self.path())\n\t\t\treturn None\n\t\n\t\t(self._product_guid, self._product_name, ) = result.groups()\n\n\t\treturn self._deps\n\n\t# Add a line to the PBXBuildFile section.\n\t#\n\t# <default_guid> /* <name> in Frameworks */ = {isa = PBXBuildFile; fileRef = <file_ref_hash> /* <name> */; };\n\t#\n\t# Returns: <default_guid> if a line was added.\n\t#          Otherwise, the existing guid is returned.\n\tdef add_buildfile(self, name, file_ref_hash, default_guid):\n\t\tproject_data = self.get_project_data()\n\n\t\tmatch = re.search('\\/\\* Begin PBXBuildFile section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXBuildFile section \\*\\/', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXBuildFile section.\")\n\t\t\treturn None\n\n\t\t(subtext, ) = match.groups()\n\n\t\tbuildfile_hash = None\n\t\t\n\t\tmatch = re.search('([A-Z0-9]+).+?fileRef = '+re.escape(file_ref_hash), subtext)\n\t\tif match:\n\t\t\t(buildfile_hash, ) = match.groups()\n\t\t\tlogging.info(\"This build file already exists: \"+buildfile_hash)\n\t\t\n\t\tif buildfile_hash is None:\n\t\t\tmatch = re.search('\\/\\* Begin PBXBuildFile section \\*\\/\\n', project_data)\n\n\t\t\tbuildfile_hash = default_guid\n\t\t\n\t\t\tlibfiletext = \"\\t\\t\"+buildfile_hash+\" /* \"+name+\" in Frameworks */ = {isa = PBXBuildFile; fileRef = \"+file_ref_hash+\" /* \"+name+\" */; };\\n\"\n\t\t\tproject_data = project_data[:match.end()] + libfiletext + project_data[match.end():]\n\t\t\n\t\tself.set_project_data(project_data)\n\t\t\n\t\treturn buildfile_hash\n\n\t# Add a line to the PBXFileReference section.\n\t#\n\t# <default_guid> /* <name> */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.<file_type>\"; name = <name>; path = <rel_path>; sourceTree = <source_tree>; };\n\t#\n\t# Returns: <default_guid> if a line was added.\n\t#          Otherwise, the existing guid is returned.\n\tdef add_filereference(self, name, file_type, default_guid, rel_path, source_tree):\n\t\tproject_data = self.get_project_data()\n\n\t\tquoted_rel_path = '\"'+rel_path.strip('\"')+'\"'\n\n\t\tfileref_hash = None\n\n\t\tmatch = re.search('([A-Z0-9]+) \\/\\* '+re.escape(name)+' \\*\\/ = \\{isa = PBXFileReference; lastKnownFileType = \"wrapper.'+file_type+'\"; name = '+re.escape(name)+'; path = '+re.escape(rel_path)+';', project_data)\n\n\t\tif not match:\n\t\t\t# Check again for quoted versions, just to be sure.\n\t\t\tmatch = re.search('([A-Z0-9]+) \\/\\* '+re.escape(name)+' \\*\\/ = \\{isa = PBXFileReference; lastKnownFileType = \"wrapper.'+file_type+'\"; name = '+re.escape(name)+'; path = '+re.escape(quoted_rel_path)+';', project_data)\n\n\t\tif match:\n\t\t\tlogging.info(\"This file has already been added.\")\n\t\t\t(fileref_hash, ) = match.groups()\n\t\t\t\n\t\telse:\n\t\t\tmatch = re.search('\\/\\* Begin PBXFileReference section \\*\\/\\n', project_data)\n\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the PBXFileReference section.\")\n\t\t\t\treturn False\n\n\t\t\tfileref_hash = default_guid\n\t\t\t\n\t\t\tpbxfileref = \"\\t\\t\"+fileref_hash+\" /* \"+name+\" */ = {isa = PBXFileReference; lastKnownFileType = \\\"wrapper.\"+file_type+\"\\\"; name = \"+name+\"; path = \"+quoted_rel_path+\"; sourceTree = \"+source_tree+\"; };\\n\"\n\n\t\t\tproject_data = project_data[:match.end()] + pbxfileref + project_data[match.end():]\n\n\t\tself.set_project_data(project_data)\n\n\t\treturn fileref_hash\n\n\t# Add a file to the given PBXGroup.\n\t#\n\t# <guid> /* <name> */,\n\tdef add_file_to_group(self, name, guid, group):\n\t\tproject_data = self.get_project_data()\n\n\t\tmatch = re.search('\\/\\* '+re.escape(group)+' \\*\\/ = \\{\\n[ \\t]+isa = PBXGroup;\\n[ \\t]+children = \\(\\n((?:.|\\n)+?)\\);', project_data)\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the \"+group+\" children.\")\n\t\t\treturn False\n\n\t\t(children,) = match.groups()\n\t\tmatch = re.search(re.escape(guid), children)\n\t\tif match:\n\t\t\tlogging.info(\"This file is already a member of the \"+name+\" group.\")\n\t\telse:\n\t\t\tmatch = re.search('\\/\\* '+re.escape(group)+' \\*\\/ = \\{\\n[ \\t]+isa = PBXGroup;\\n[ \\t]+children = \\(\\n', project_data)\n\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the \"+group+\" group.\")\n\t\t\t\treturn False\n\n\t\t\tpbxgroup = \"\\t\\t\\t\\t\"+guid+\" /* \"+name+\" */,\\n\"\n\t\t\tproject_data = project_data[:match.end()] + pbxgroup + project_data[match.end():]\n\n\t\tself.set_project_data(project_data)\n\n\t\treturn True\n\n\t# Add a file to the Frameworks PBXGroup.\n\t#\n\t# <guid> /* <name> */,\n\tdef add_file_to_frameworks(self, name, guid):\n\t\treturn self.add_file_to_group(name, guid, 'Frameworks')\n\n\t# Add a file to the Resources PBXGroup.\n\t#\n\t# <guid> /* <name> */,\n\tdef add_file_to_resources(self, name, guid):\n\t\tmatch = re.search('\\/\\* '+re.escape('Resources')+' \\*\\/ = \\{\\n[ \\t]+isa = PBXGroup;\\n[ \\t]+children = \\(\\n((?:.|\\n)+?)\\);', self.get_project_data())\n\t\tif not match:\n\t\t\treturn self.add_file_to_group(name, guid, 'Supporting Files')\n\n\t\treturn self.add_file_to_group(name, guid, 'Resources')\n\n\tdef add_file_to_phase(self, name, guid, phase_guid, phase):\n\t\tproject_data = self.get_project_data()\n\n\t\tmatch = re.search(re.escape(phase_guid)+\" \\/\\* \"+re.escape(phase)+\" \\*\\/ = {(?:.|\\n)+?files = \\(((?:.|\\n)+?)\\);\", project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the \"+phase+\" phase.\")\n\t\t\treturn False\n\n\t\t(files, ) = match.groups()\n\n\t\tmatch = re.search(re.escape(guid), files)\n\t\tif match:\n\t\t\tlogging.info(\"The file has already been added.\")\n\t\telse:\n\t\t\tmatch = re.search(re.escape(phase_guid)+\" \\/\\* \"+phase+\" \\*\\/ = {(?:.|\\n)+?files = \\(\\n\", project_data)\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the \"+phase+\" files\")\n\t\t\t\treturn False\n\n\t\t\tframeworktext = \"\\t\\t\\t\\t\"+guid+\" /* \"+name+\" in \"+phase+\" */,\\n\"\n\t\t\tproject_data = project_data[:match.end()] + frameworktext + project_data[match.end():]\n\n\t\tself.set_project_data(project_data)\n\n\t\treturn True\n\n\tdef get_rel_path_to_products_dir(self):\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\tbuild_path = os.path.join(os.path.join(os.path.dirname(Paths.src_dir), 'Build'), 'Products')\n\t\treturn relpath(project_path, build_path)\n\n\tdef add_file_to_frameworks_phase(self, name, guid):\n\t\treturn self.add_file_to_phase(name, guid, self._frameworks_guid, 'Frameworks')\n\n\tdef add_file_to_resources_phase(self, name, guid):\n\t\tif self._resources_guid is None:\n\t\t\tlogging.error(\"No resources build phase found in the destination project\")\n\t\t\tlogging.error(\"Please add a New Copy Bundle Resources Build Phase to your target\")\n\t\t\tlogging.error(\"Right click your target in the project, Add, New Build Phase,\")\n\t\t\tlogging.error(\"  \\\"New Copy Bundle Resources Build Phase\\\"\")\n\t\t\treturn False\n\n\t\treturn self.add_file_to_phase(name, guid, self._resources_guid, 'Resources')\n\n\tdef add_header_search_path(self, configuration):\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\tbuild_path = os.path.join(os.path.join(os.path.join(os.path.dirname(Paths.src_dir), 'Build'), 'Products'), 'three20')\n\t\trel_path = relpath(project_path, build_path)\n\n\t\tdid_add_build_setting = self.add_build_setting(configuration, 'HEADER_SEARCH_PATHS', '\"'+rel_path+'\"')\n\t\tif not did_add_build_setting:\n\t\t\treturn did_add_build_setting\n\t\t\n\t\t# Version 46 is Xcode 4's file format.\n\t\ttry:\n\t\t\tprimary_version = int(self._xcode_version.split('.')[0])\n\t\texcept ValueError, e:\n\t\t\tprimary_version = 0\n\t\tif self._projectVersion >= 46 or primary_version >= 4:\n\t\t\tdid_add_build_setting = self.add_build_setting(configuration, 'HEADER_SEARCH_PATHS', '\"$(BUILT_PRODUCTS_DIR)/../../three20\"')\n\t\t\tif not did_add_build_setting:\n\t\t\t\treturn did_add_build_setting\n\n\t\t\tdid_add_build_setting = self.add_build_setting(configuration, 'HEADER_SEARCH_PATHS', '\"$(BUILT_PRODUCTS_DIR)/../three20\"')\n\t\t\tif not did_add_build_setting:\n\t\t\t\treturn did_add_build_setting\n\n\t\treturn did_add_build_setting\n\t\n\tdef add_build_setting(self, configuration, setting_name, value):\n\t\tproject_data = self.get_project_data()\n\n\t\tmatch = re.search('\\/\\* '+configuration+' \\*\\/ = {\\n[ \\t]+isa = XCBuildConfiguration;\\n(?:.|\\n)+?[ \\t]+buildSettings = \\{\\n((?:.|\\n)+?)\\};', project_data)\n\t\tif not match:\n\t\t\tprint \"Couldn't find the \"+configuration+\" configuration in \"+self.path()\n\t\t\treturn False\n\n\t\tsettings_start = match.start(1)\n\t\tsettings_end = match.end(1)\n\n\t\t(build_settings, ) = match.groups()\n\n\t\tmatch = re.search(re.escape(setting_name)+' = ((?:.|\\n)+?);', build_settings)\n\n\t\tif not match:\n\t\t\t# Add a brand new build setting. No checking for existing settings necessary.\n\t\t\tsettingtext = '\\t\\t\\t\\t'+setting_name+' = '+value+';\\n'\n\n\t\t\tproject_data = project_data[:settings_start] + settingtext + project_data[settings_start:]\n\t\telse:\n\t\t\t# Build settings already exist. Is there one or many?\n\t\t\t(search_paths,) = match.groups()\n\t\t\tif re.search('\\(\\n', search_paths):\n\t\t\t\t# Many\n\t\t\t\tmatch = re.search(re.escape(value), search_paths)\n\t\t\t\tif not match:\n\t\t\t\t\t# If value has any spaces in it, Xcode will split it up into\n\t\t\t\t\t# multiple entries.\n\t\t\t\t\tescaped_value = re.escape(value).replace(' ', '\",\\n[ \\t]+\"')\n\t\t\t\t\tmatch = re.search(escaped_value, search_paths)\n\t\t\t\t\tif not match and not re.search(re.escape(value.strip('\"')), search_paths):\n\t\t\t\t\t\tmatch = re.search(re.escape(setting_name)+' = \\(\\n', build_settings)\n\n\t\t\t\t\t\tbuild_settings = build_settings[:match.end()] + '\\t\\t\\t\\t\\t'+value+',\\n' + build_settings[match.end():]\n\t\t\t\t\t\tproject_data = project_data[:settings_start] + build_settings + project_data[settings_end:]\n\t\t\telse:\n\t\t\t\t# One\n\t\t\t\tif search_paths.strip('\"') != value.strip('\"'):\n\t\t\t\t\texisting_path = search_paths\n\t\t\t\t\tpath_set = '(\\n\\t\\t\\t\\t\\t'+value+',\\n\\t\\t\\t\\t\\t'+existing_path+'\\n\\t\\t\\t\\t)'\n\t\t\t\t\tbuild_settings = build_settings[:match.start(1)] + path_set + build_settings[match.end(1):]\n\t\t\t\t\tproject_data = project_data[:settings_start] + build_settings + project_data[settings_end:]\n\n\t\tself.set_project_data(project_data)\n\n\t\treturn True\n\n\tdef get_hash_base(self, uniquename):\n\t\texamplehash = '320FFFEEEDDDCCCBBBAAA000'\n\t\tuniquehash = hashlib.sha224(uniquename).hexdigest().upper()\n\t\tuniquehash = uniquehash[:len(examplehash) - 4]\n\t\treturn '320'+uniquehash\n\n\tdef add_framework(self, framework):\n\t\ttthash_base = self.get_hash_base(framework)\n\t\t\n\t\tfileref_hash = self.add_filereference(framework, 'frameworks', tthash_base+'0', 'System/Library/Frameworks/'+framework, 'SDKROOT')\n\t\tlibfile_hash = self.add_buildfile(framework, fileref_hash, tthash_base+'1')\n\t\tif not self.add_file_to_frameworks(framework, fileref_hash):\n\t\t\treturn False\n\t\t\n\t\tif not self.add_file_to_frameworks_phase(framework, libfile_hash):\n\t\t\treturn False\n\t\t\n\t\treturn True\n\n\tdef add_bundle(self):\n\t\ttthash_base = self.get_hash_base('Three20.bundle')\n\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\tbuild_path = os.path.join(Paths.src_dir, 'Three20.bundle')\n\t\trel_path = relpath(project_path, build_path)\n\t\t\n\t\tfileref_hash = self.add_filereference('Three20.bundle', 'plug-in', tthash_base+'0', rel_path, 'SOURCE_ROOT')\n\n\t\tlibfile_hash = self.add_buildfile('Three20.bundle', fileref_hash, tthash_base+'1')\n\n\t\tif not self.add_file_to_resources('Three20.bundle', fileref_hash):\n\t\t\treturn False\n\n\t\tif not self.add_file_to_resources_phase('Three20.bundle', libfile_hash):\n\t\t\treturn False\n\n\t\treturn True\n\n\t# Get the PBXFileReference from the given PBXBuildFile guid.\n\tdef get_filerefguid_from_buildfileguid(self, buildfileguid):\n\t\tproject_data = self.get_project_data()\n\t\tmatch = re.search(buildfileguid+' \\/\\* .+ \\*\\/ = {isa = PBXBuildFile; fileRef = ([A-Z0-9]+) \\/\\* .+ \\*\\/;', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXBuildFile row.\")\n\t\t\treturn None\n\n\t\t(filerefguid, ) = match.groups()\n\t\t\n\t\treturn filerefguid\n\n\tdef get_filepath_from_filerefguid(self, filerefguid):\n\t\tproject_data = self.get_project_data()\n\t\tmatch = re.search(filerefguid+' \\/\\* .+ \\*\\/ = {isa = PBXFileReference; .+ path = (.+); .+ };', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXFileReference row.\")\n\t\t\treturn None\n\n\t\t(path, ) = match.groups()\n\t\t\n\t\treturn path\n\n\n\t# Get all source files that are \"built\" in this project. This includes files built for\n\t# libraries, executables, and unit testing.\n\tdef get_built_sources(self):\n\t\tproject_data = self.get_project_data()\n\t\tmatch = re.search('\\/\\* Begin PBXSourcesBuildPhase section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXSourcesBuildPhase section \\*\\/', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXSourcesBuildPhase section.\")\n\t\t\treturn None\n\t\t\n\t\t(buildphasedata, ) = match.groups()\n\t\t\n\t\tbuildfileguids = re.findall('[ \\t]+([A-Z0-9]+) \\/\\* .+ \\*\\/,\\n', buildphasedata)\n\t\t\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\t\n\t\tfilenames = []\n\t\t\n\t\tfor buildfileguid in buildfileguids:\n\t\t\tfilerefguid = self.get_filerefguid_from_buildfileguid(buildfileguid)\n\t\t\tfilepath = self.get_filepath_from_filerefguid(filerefguid)\n\n\t\t\tfilenames.append(os.path.join(project_path, filepath.strip('\"')))\n\n\t\treturn filenames\n\n\n\t# Get all header files that are \"built\" in this project. This includes files built for\n\t# libraries, executables, and unit testing.\n\tdef get_built_headers(self):\n\t\tproject_data = self.get_project_data()\n\t\tmatch = re.search('\\/\\* Begin PBXHeadersBuildPhase section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXHeadersBuildPhase section \\*\\/', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXHeadersBuildPhase section.\")\n\t\t\treturn None\n\t\t\n\t\t(buildphasedata, ) = match.groups()\n\n\t\tbuildfileguids = re.findall('[ \\t]+([A-Z0-9]+) \\/\\* .+ \\*\\/,\\n', buildphasedata)\n\t\t\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\t\n\t\tfilenames = []\n\t\t\n\t\tfor buildfileguid in buildfileguids:\n\t\t\tfilerefguid = self.get_filerefguid_from_buildfileguid(buildfileguid)\n\t\t\tfilepath = self.get_filepath_from_filerefguid(filerefguid)\n\t\t\t\n\t\t\tfilenames.append(os.path.join(project_path, filepath.strip('\"')))\n\n\t\treturn filenames\n\n\n\tdef add_dependency(self, dep):\n\t\tproject_data = self.get_project_data()\n\t\tdep_data = dep.get_project_data()\n\t\t\n\t\tif project_data is None or dep_data is None:\n\t\t\treturn False\n\n\t\tlogging.info(\"\\nAdding \"+str(dep)+\" to \"+str(self))\n\t\t\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\tdep_path = os.path.abspath(dep.xcodeprojpath())\n\t\trel_path = relpath(project_path, dep_path)\n\t\t\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Project path:    \"+project_path)\n\t\tlogging.info(\"Dependency path: \"+dep_path)\n\t\tlogging.info(\"Relative path:   \"+rel_path)\n\t\t\n\t\ttthash_base = self.get_hash_base(dep.uniqueid())\n\t\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 1: Add file reference to the dependency...\")\n\t\t\n\t\tself.set_project_data(project_data)\n\t\tpbxfileref_hash = self.add_filereference(dep._project_name+'.xcodeproj', 'pb-project', tthash_base+'0', rel_path, 'SOURCE_ROOT')\n\t\tproject_data = self.get_project_data()\n\n\t\tlogging.info(\"Done: Added file reference: \"+pbxfileref_hash)\n\t\t\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 2: Add file to Frameworks group...\")\n\t\t\n\t\tself.set_project_data(project_data)\n\t\tif not self.add_file_to_frameworks(dep._project_name+\".xcodeproj\", pbxfileref_hash):\n\t\t\treturn False\n\t\tproject_data = self.get_project_data()\n\n\t\tlogging.info(\"Done: Added file to Frameworks group.\")\n\t\t\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 3: Add dependencies...\")\n\t\t\n\t\tpbxtargetdependency_hash = None\n\t\tpbxcontaineritemproxy_hash = None\n\t\t\n\t\tmatch = re.search('\\/\\* Begin PBXTargetDependency section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXTargetDependency section \\*\\/', project_data)\n\t\tif not match:\n\t\t\tlogging.info(\"\\tAdding a PBXTargetDependency section...\")\n\t\t\tmatch = re.search('\\/\\* End PBXSourcesBuildPhase section \\*\\/\\n', project_data)\n\t\t\t\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the PBXSourcesBuildPhase section.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tproject_data = project_data[:match.end()] + \"\\n/* Begin PBXTargetDependency section */\\n\\n/* End PBXTargetDependency section */\\n\" + project_data[match.end():]\n\t\telse:\n\t\t\t(subtext, ) = match.groups()\n\t\t\tmatch = re.search('([A-Z0-9]+) \\/\\* PBXTargetDependency \\*\\/ = {\\n[ \\t]+isa = PBXTargetDependency;\\n[ \\t]+name = '+re.escape(dep._project_name)+';\\n[ \\t]+targetProxy = ([A-Z0-9]+) \\/\\* PBXContainerItemProxy \\*\\/;', project_data)\n\t\t\tif match:\n\t\t\t\t(pbxtargetdependency_hash, pbxcontaineritemproxy_hash,) = match.groups()\n\t\t\t\tlogging.info(\"This dependency already exists.\")\n\n\t\tif pbxtargetdependency_hash is None or pbxcontaineritemproxy_hash is None:\n\t\t\tmatch = re.search('\\/\\* Begin PBXTargetDependency section \\*\\/\\n', project_data)\n\t\t\n\t\t\tpbxtargetdependency_hash = tthash_base+'1'\n\t\t\tpbxcontaineritemproxy_hash = tthash_base+'2'\n\t\t\n\t\t\tpbxtargetdependency = \"\\t\\t\"+pbxtargetdependency_hash+\" /* PBXTargetDependency */ = {\\n\\t\\t\\tisa = PBXTargetDependency;\\n\\t\\t\\tname = \"+dep._project_name+\";\\n\\t\\t\\ttargetProxy = \"+pbxcontaineritemproxy_hash+\" /* PBXContainerItemProxy */;\\n\\t\\t};\\n\"\n\t\t\tproject_data = project_data[:match.end()] + pbxtargetdependency + project_data[match.end():]\n\n\t\tlogging.info(\"Done: Added dependency.\")\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 3.1: Add container proxy for dependencies...\")\n\n\t\tcontainerExists = False\n\n\t\tmatch = re.search('\\/\\* Begin PBXContainerItemProxy section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXContainerItemProxy section \\*\\/', project_data)\n\t\tif not match:\n\t\t\tlogging.info(\"\\tAdding a PBXContainerItemProxy section...\")\n\t\t\tmatch = re.search('\\/\\* End PBXBuildFile section \\*\\/\\n', project_data)\n\t\t\t\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the PBXBuildFile section.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tproject_data = project_data[:match.end()] + \"\\n/* Begin PBXContainerItemProxy section */\\n\\n/* End PBXContainerItemProxy section */\\n\" + project_data[match.end():]\n\t\telse:\n\t\t\t(subtext, ) = match.groups()\n\t\t\tmatch = re.search(re.escape(pbxcontaineritemproxy_hash), subtext)\n\t\t\tif match:\n\t\t\t\tlogging.info(\"This container proxy already exists.\")\n\t\t\t\tcontainerExists = True\n\n\t\tif not containerExists:\n\t\t\tmatch = re.search('\\/\\* Begin PBXContainerItemProxy section \\*\\/\\n', project_data)\n\n\t\t\tpbxcontaineritemproxy = \"\\t\\t\"+pbxcontaineritemproxy_hash+\" /* PBXContainerItemProxy */ = {\\n\\t\\t\\tisa = PBXContainerItemProxy;\\n\\t\\t\\tcontainerPortal = \"+pbxfileref_hash+\" /* \"+dep._project_name+\".xcodeproj */;\\n\\t\\t\\tproxyType = 1;\\n\\t\\t\\tremoteGlobalIDString = \"+dep.guid()+\";\\n\\t\\t\\tremoteInfo = \"+dep._project_name+\";\\n\\t\\t};\\n\"\n\t\t\tproject_data = project_data[:match.end()] + pbxcontaineritemproxy + project_data[match.end():]\n\n\t\tlogging.info(\"Done: Added container proxy.\")\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 3.2: Add module to the dependency list...\")\n\n\t\tmatch = re.search(self.guid()+' \\/\\* .+? \\*\\/ = {\\n[ \\t]+(?:.|\\n)+?[ \\t]+dependencies = \\(\\n((?:.|\\n)+?)\\);', project_data)\n\t\t\n\t\tdependency_exists = False\n\t\t\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the dependency list.\")\n\t\t\treturn False\n\t\telse:\n\t\t\t(dependencylist, ) = match.groups()\n\t\t\tmatch = re.search(re.escape(pbxtargetdependency_hash), dependencylist)\n\t\t\tif match:\n\t\t\t\tlogging.info(\"This dependency has already been added.\")\n\t\t\t\tdependency_exists = True\n\t\t\n\t\tif not dependency_exists:\n\t\t\tmatch = re.search(self.guid()+' \\/\\* .+? \\*\\/ = {\\n[ \\t]+(?:.|\\n)+?[ \\t]+dependencies = \\(\\n', project_data)\n\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the dependency list.\")\n\t\t\t\treturn False\n\n\t\t\tdependency_item = '\\t\\t\\t\\t'+pbxtargetdependency_hash+' /* PBXTargetDependency */,\\n'\n\t\t\tproject_data = project_data[:match.end()] + dependency_item + project_data[match.end():]\n\n\t\tlogging.info(\"Done: Added module to the dependency list.\")\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 4: Create project references...\")\n\n\t\tmatch = re.search('\\/\\* Begin PBXProject section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXProject section \\*\\/', project_data)\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the project section.\")\n\t\t\treturn False\n\n\t\tproject_start = match.start(1)\n\t\tproject_end = match.end(1)\n\n\t\t(project_section, ) = match.groups()\n\t\t\n\t\treference_exists = False\n\t\tdid_change = False\n\t\t\n\t\tproductgroup_hash = None\n\t\t\n\t\tmatch = re.search('projectReferences = \\(\\n((?:.|\\n)+?)\\n[ \\t]+\\);', project_section)\n\t\tif not match:\n\t\t\tlogging.info(\"Creating project references...\")\n\t\t\tmatch = re.search('projectDirPath = \".*?\";\\n', project_section)\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find project references anchor.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tdid_change = True\n\t\t\tproject_section = project_section[:match.end()] + '\\t\\t\\tprojectReferences = (\\n\\t\\t\\t);\\n' + project_section[match.end():]\n\n\t\telse:\n\t\t\t(refs, ) = match.groups()\n\n\t\t\tmatch = re.search('\\{\\n[ \\t]+ProductGroup = ([A-Z0-9]+) \\/\\* Products \\*\\/;\\n[ \\t]+ProjectRef = '+re.escape(pbxfileref_hash), refs)\n\t\t\tif match:\n\t\t\t\t(productgroup_hash, ) = match.groups()\n\t\t\t\tlogging.info(\"This product group already exists: \"+productgroup_hash)\n\t\t\t\treference_exists = True\n\n\n\t\tif not reference_exists:\n\t\t\tmatch = re.search('projectReferences = \\(\\n', project_section)\n\t\t\t\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Missing the project references item.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tproductgroup_hash = tthash_base+'3'\n\n\t\t\treference_text = '\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tProductGroup = '+productgroup_hash+' /* Products */;\\n\\t\\t\\t\\t\\tProjectRef = '+pbxfileref_hash+' /* '+dep._project_name+'.xcodeproj */;\\n\\t\\t\\t\\t},\\n'\n\t\t\tproject_section = project_section[:match.end()] + reference_text + project_section[match.end():]\n\t\t\tdid_change = True\n\t\t\t\n\t\tif did_change:\n\t\t\tproject_data = project_data[:project_start] + project_section + project_data[project_end:]\n\n\t\tlogging.info(\"Done: Created project reference.\")\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 4.1: Create product group...\")\n\n\t\tmatch = re.search('\\/\\* Begin PBXGroup section \\*\\/\\n', project_data)\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the group section.\")\n\t\t\treturn False\n\t\t\n\t\tgroup_start = match.end()\n\n\t\tlib_hash = None\n\n\t\tmatch = re.search(re.escape(productgroup_hash)+\" \\/\\* Products \\*\\/ = \\{\\n[ \\t]+isa = PBXGroup;\\n[ \\t]+children = \\(\\n((?:.|\\n)+?)\\);\", project_data)\n\t\tif match:\n\t\t\tlogging.info(\"This product group already exists.\")\n\t\t\t(children, ) = match.groups()\n\t\t\tmatch = re.search('([A-Z0-9]+) \\/\\* '+re.escape(dep._product_name)+' \\*\\/', children)\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"No product found\")\n\t\t\t\treturn False\n\t\t\t\t# TODO: Add this product.\n\t\t\telse:\n\t\t\t\t(lib_hash, ) = match.groups()\n\t\t\t\n\t\telse:\n\t\t\tlib_hash = tthash_base+'4'\n\n\t\t\tproductgrouptext = \"\\t\\t\"+productgroup_hash+\" /* Products */ = {\\n\\t\\t\\tisa = PBXGroup;\\n\\t\\t\\tchildren = (\\n\\t\\t\\t\\t\"+lib_hash+\" /* \"+dep._product_name+\" */,\\n\\t\\t\\t);\\n\\t\\t\\tname = Products;\\n\\t\\t\\tsourceTree = \\\"<group>\\\";\\n\\t\\t};\\n\"\n\t\t\tproject_data = project_data[:group_start] + productgrouptext + project_data[group_start:]\n\n\t\tlogging.info(\"Done: Created product group: \"+lib_hash)\n\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 4.2: Add container proxy for target product...\")\n\n\t\tcontainerExists = False\n\t\t\n\t\ttargetproduct_hash = tthash_base+'6'\n\n\t\tmatch = re.search('\\/\\* Begin PBXContainerItemProxy section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXContainerItemProxy section \\*\\/', project_data)\n\t\tif not match:\n\t\t\tlogging.info(\"\\tAdding a PBXContainerItemProxy section...\")\n\t\t\tmatch = re.search('\\/\\* End PBXBuildFile section \\*\\/\\n', project_data)\n\t\t\t\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the PBXBuildFile section.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tproject_data = project_data[:match.end()] + \"\\n/* Begin PBXContainerItemProxy section */\\n\\n/* End PBXContainerItemProxy section */\\n\" + project_data[match.end():]\n\t\telse:\n\t\t\t(subtext, ) = match.groups()\n\t\t\tmatch = re.search(re.escape(targetproduct_hash), subtext)\n\t\t\tif match:\n\t\t\t\tlogging.info(\"This container proxy already exists.\")\n\t\t\t\tcontainerExists = True\n\n\t\tif not containerExists:\n\t\t\tmatch = re.search('\\/\\* Begin PBXContainerItemProxy section \\*\\/\\n', project_data)\n\n\t\t\tpbxcontaineritemproxy = \"\\t\\t\"+targetproduct_hash+\" /* PBXContainerItemProxy */ = {\\n\\t\\t\\tisa = PBXContainerItemProxy;\\n\\t\\t\\tcontainerPortal = \"+pbxfileref_hash+\" /* \"+dep._project_name+\".xcodeproj */;\\n\\t\\t\\tproxyType = 2;\\n\\t\\t\\tremoteGlobalIDString = \"+dep._product_guid+\";\\n\\t\\t\\tremoteInfo = \"+dep._project_name+\";\\n\\t\\t};\\n\"\n\t\t\tproject_data = project_data[:match.end()] + pbxcontaineritemproxy + project_data[match.end():]\n\n\t\tlogging.info(\"Done: Added target container proxy.\")\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 4.3: Create reference proxy...\")\n\n\t\treferenceExists = False\n\n\t\tmatch = re.search('\\/\\* Begin PBXReferenceProxy section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXReferenceProxy section \\*\\/', project_data)\n\t\tif not match:\n\t\t\tlogging.info(\"\\tAdding a PBXReferenceProxy section...\")\n\t\t\tmatch = re.search('\\/\\* End PBXProject section \\*\\/\\n', project_data)\n\t\t\t\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the PBXProject section.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tproject_data = project_data[:match.end()] + \"\\n/* Begin PBXReferenceProxy section */\\n\\n/* End PBXReferenceProxy section */\\n\" + project_data[match.end():]\n\t\telse:\n\t\t\t(subtext, ) = match.groups()\n\t\t\tmatch = re.search(re.escape(lib_hash), subtext)\n\t\t\tif match:\n\t\t\t\tlogging.info(\"This reference proxy already exists.\")\n\t\t\t\treferenceExists = True\n\n\t\tif not referenceExists:\n\t\t\tmatch = re.search('\\/\\* Begin PBXReferenceProxy section \\*\\/\\n', project_data)\n\n\t\t\treferenceproxytext = \"\\t\\t\"+lib_hash+\" /* \"+dep._product_name+\" */ = {\\n\\t\\t\\tisa = PBXReferenceProxy;\\n\\t\\t\\tfileType = archive.ar;\\n\\t\\t\\tpath = \\\"\"+dep._product_name+\"\\\";\\n\\t\\t\\tremoteRef = \"+targetproduct_hash+\" /* PBXContainerItemProxy */;\\n\\t\\t\\tsourceTree = BUILT_PRODUCTS_DIR;\\n\\t\\t};\\n\"\n\t\t\tproject_data = project_data[:match.end()] + referenceproxytext + project_data[match.end():]\n\n\t\tlogging.info(\"Done: Created reference proxy.\")\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 5: Add target file...\")\n\n\t\tself.set_project_data(project_data)\n\t\tlibfile_hash = self.add_buildfile(dep._product_name, lib_hash, tthash_base+'5')\n\t\tproject_data = self.get_project_data()\n\n\t\tlogging.info(\"Done: Added target file.\")\n\t\t\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 6: Add frameworks...\")\n\n\t\tself.set_project_data(project_data)\n\t\tself.add_file_to_frameworks_phase(dep._product_name, libfile_hash)\n\t\tproject_data = self.get_project_data()\n\n\t\tlogging.info(\"Done: Adding module.\")\n\n\t\tself.set_project_data(project_data)\n\n\t\treturn True\n"
  },
  {
    "path": "scripts/generate_coverage.applescript",
    "content": "on run argv\n\t\n\ttell application \"/Applications/CoverStory.app\"\n\t    quit\n\t\tactivate\n\t\tset x to open (item 1 of argv)\n\t\ttell x to export to HTML in (item 2 of argv)\n\t\tquit\n\tend tell\n\t\n\treturn item 1 of argv & \"|\" & item 2 of argv\n\t\nend run"
  },
  {
    "path": "scripts/generate_namespace_header",
    "content": "header=$SRCROOT/$NIMBUS_FEATURE_NAME/src/$PRODUCT_NAME+Namespace.h\n\necho \"//\n// Copyright 2011-2014 Jeff Verkoeyen\n// This file has been automatically generated by Nimbus' namespacing script.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \\\"AS IS\\\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#ifndef __NIMBUS_NAMESPACE_PREFIX_\n#error You must define __NIMBUS_NAMESPACE_PREFIX_ in your project settings in order to use a Nimbus namespace.\n#else\n\n#ifndef __NIMBUS_NS_SYMBOL\n// We need to have multiple levels of macros here so that __NIMBUS_NAMESPACE_PREFIX_ is\n// properly replaced by the time we concatenate the namespace prefix.\n#define __NIMBUS_NS_REWRITE(ns, symbol) ns ## _ ## symbol\n#define __NIMBUS_NS_BRIDGE(ns, symbol) __NIMBUS_NS_REWRITE(ns, symbol)\n#define __NIMBUS_NS_SYMBOL(symbol) __NIMBUS_NS_BRIDGE(__NIMBUS_NAMESPACE_PREFIX_, symbol)\n#endif\n\" > $header\n\n# The following one-liner is a bit of a pain in the ass.\n# Breakdown:\n#\n# nm $CODESIGNING_FOLDER_PATH -j\n# Dump all of the symbols from the compiled library. This will include all UIKit\n# and Foundation symbols as well.\n#\n# | grep \"^_OBJC_CLASS_$_\"\n# Filter out the interfaces.\n#\n# | grep -v \"\\$_NS\"\n# Remove all Foundation classes.\n#\n# | grep -v \"\\$_UI\"\n# Remove all UIKit classes.\n#\n# | sed -e 's/_OBJC_CLASS_\\$_\\(.*\\)/#ifndef \\1\\'$'\\n''#define \\1 __NIMBUS_NS_SYMBOL(\\1)\\'$'\\n''#endif/g'\n# I use the syntax outlined here:\n# http://stackoverflow.com/questions/6761796/bash-perl-or-sed-insert-on-new-line-after-found-phrase\n# to create newlines so that we can write the following on separate lines:\n#\n#  #ifndef ...\n#  #define ...\n#  #endif\n#\n\necho \"// Classes\" >> $header\n\nnm $CODESIGNING_FOLDER_PATH -j | sort | uniq | grep \"^_OBJC_CLASS_$_\" | grep -v \"\\$_NS\" | grep -v \"\\$_UI\" | sed -e 's/_OBJC_CLASS_\\$_\\(.*\\)/#ifndef \\1\\'$'\\n''#define \\1 __NIMBUS_NS_SYMBOL(\\1)\\'$'\\n''#endif/g' >> $header\n\necho \"// Functions\" >> $header\n\nnm $CODESIGNING_FOLDER_PATH | sort | uniq | grep \" T \" | cut -d' ' -f3 | grep -v \"\\$_NS\" | grep -v \"\\$_UI\" | sed -e 's/_\\(.*\\)/#ifndef \\1\\'$'\\n''#define \\1 __NIMBUS_NS_SYMBOL(\\1)\\'$'\\n''#endif/g' >> $header\n\necho \"// Externs\" >> $header\n\nnm $CODESIGNING_FOLDER_PATH | sort | uniq | grep \" D \" | cut -d' ' -f3 | grep -v \"\\$_NS\" | grep -v \"\\$_UI\" | sed -e 's/_\\(.*\\)/#ifndef \\1\\'$'\\n''#define \\1 __NIMBUS_NS_SYMBOL(\\1)\\'$'\\n''#endif/g' >> $header\n\nnm $CODESIGNING_FOLDER_PATH | sort | uniq | grep \" S \" | cut -d' ' -f3 | grep -v \"\\$_NS\" | grep -v \".eh\" | grep -v \"\\$_UI\" | grep -v \"OBJC_\" | sed -e 's/_\\(.*\\)/#ifndef \\1\\'$'\\n''#define \\1 __NIMBUS_NS_SYMBOL(\\1)\\'$'\\n''#endif/g' >> $header\n\necho \"#endif\" >> $header\n\n"
  },
  {
    "path": "scripts/ios/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\"\"\"\nCreated by Jeff Verkoeyen on 2011-06-07.\nCopyright 2011 Jeff Verkoeyen\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\"\"\"\n\n# The exposed interfaces for the ios module.\n\nfrom pbxproj import pbxproj\nfrom relpath import relpath\n\n"
  },
  {
    "path": "scripts/ios/pbxproj.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\"\"\"\npbxproj.py\n\nWorking with the pbxproj file format is a pain in the ass.\n\nThis script provides a couple basic features for parsing pbxproj files:\n\n* Getting a dependency list\n* Adding one pbxproj to another pbxproj as a dependency\n\nVersion 1.2.\n\nHistory:\n1.0 - October 20, 2010: Initial hacked-together version finished. It is alive!\n1.1 - January 11, 2011: Add configuration settings to all configurations by default.\n1.2 - June 7, 2011: Rewrote the pbxproj family of code as an ios module and made the class\n                    more generic (no assumptions made about the project layout).\n\nBranched from Three20's ttmodule script 2011-06-07.\nCreated by Jeff Verkoeyen on 2010-10-18.\nCopyright 2011 Jeff Verkoeyen\nCopyright 2009-2011 Facebook\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\"\"\"\n\nimport hashlib\nimport logging\nimport os\nimport re\nimport sys\nfrom relpath import relpath\n\npbxproj_cache = {}\n\nclass PbxprojTarget(object):\n\tdef __init__(self, name, project, guid = None):\n\t\tself._name = name\n\t\tself._project = project\n\t\t\n\t\t# This target's GUID.\n\t\tself._guid = guid\n\t\t\n\t\t# The configuration list GUID points to the list of configurations for a given target.\n\t\tself._configuration_list_guid = None\n\t\t\n\t\t# The list of configuration GUIDs for this target.\n\t\tself._configuration_guids = None\n\t\t\n\t\t# The GUID for the resources build phase.\n\t\tself._resources_build_phase_guid = None\n\t\t\n\t\t# The GUID for the frameworks builds phase.\n\t\tself._frameworks_build_phase_guid = None\n\t\t\n\t\t# An array of dependency GUIDs.\n\t\tself._dependency_guids = None\n\t\t\n\t\t# An array of dependency names in the same order as the dependency guids array.\n\t\tself._dependency_names = None\n\t\t\n\t\t# An array of path:target strings.\n\t\tself._dependency_paths = None\n\t\t\n\t\t# This target's product GUID.\n\t\tself._product_guid = None\n\t\t\n\t\t# This target's product name.\n\t\tself._product_name = None\n\n\n\tdef name(self):\n\t\treturn self._name\n\n\n\tdef configuration_list_guid(self):\n\t\tif self._configuration_list_guid is None:\n\t\t\tproject_data = project.get_project_data()\n\n\t\t\tresult = re.search('[A-Z0-9]+ \\/\\* '+re.escape(self._name)+' \\*\\/ = {\\n[ \\t]+isa = PBXNativeTarget;(?:.|\\n)+?buildConfigurationList = ([A-Z0-9]+) \\/\\* Build configuration list for PBXNativeTarget \"'+re.escape(self._name)+'\" \\*\\/;',\n\t\t\t                   project_data)\n\n\t\t\tif result:\n\t\t\t\t(self._configuration_list_guid, ) = result.groups()\n\t\t\telse:\n\t\t\t\t# False indicates that we could not find a configuration list GUID.\n\t\t\t\tself._configuration_list_guid = False\n\t\t\n\t\treturn self._configuration_list_guid\n\n\n\tdef configuration_guids(self):\n\t\tif not self._configuration_guids and self.configuration_list_guid():\n\t\t\tproject_data = project.get_project_data()\n\n\t\t\tmatch = re.search(re.escape(self.configuration_list_guid())+' \\/\\* Build configuration list for PBXNativeTarget \"'+re.escape(self._name)+'\" \\*\\/ = \\{\\n[ \\t]+isa = XCConfigurationList;\\n[ \\t]+buildConfigurations = \\(\\n((?:.|\\n)+?)\\);', project_data)\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the configuration list for the project.\")\n\t\t\t\treturn False\n\n\t\t\t(configuration_list,) = match.groups()\n\t\t\tself._configuration_guids = re.findall('[ \\t]+([A-Z0-9]+) \\/\\* (.+) \\*\\/,\\n', configuration_list)\n\t\t\n\t\treturn self._configuration_guids\n\n\n\tdef guid(self):\n\t\tif not self._guid:\n\t\t\tproject_data = self._project.get_project_data()\n\t\t\tresult = re.search('([A-Z0-9]+) \\/\\* '+re.escape(self._name)+' \\*\\/ = {\\n[ \\t]+isa = PBXNativeTarget;(?:.|\\n)+?buildPhases =',\n\t\t\t                   project_data)\n\t\n\t\t\tif not result:\n\t\t\t\tlogging.error(\"Can't recover: Unable to find the GUID for the target named \\\"\"+self._name+\"\\\" from the project loaded from: \"+self._project.path())\n\t\t\t\treturn False\n\n\t\t\t(self._guid, ) = result.groups()\n\t\t\n\t\treturn self._guid\n\n\n\tdef _gather_build_phases(self):\t\n\t\tproject_data = self._project.get_project_data()\n\t\t\n\t\tresult = re.search('[A-Z0-9]+ \\/\\* '+re.escape(self._name)+' \\*\\/ = {\\n[ \\t]+isa = PBXNativeTarget;(?:.|\\n)+?buildPhases = \\(\\n((?:.|\\n)+?)\\);',\n\t\t                   project_data)\n\t\n\t\tif not result:\n\t\t\tlogging.error(\"Can't recover: Unable to find the build phases for the target named \\\"\"+self._name+\"\\\" from the project loaded from: \"+self._project.path())\n\t\t\treturn False\n\n\t\t(build_phases, ) = result.groups()\n\n\t\t# Get the build phases we care about.\n\n\t\tmatch = re.search('([A-Z0-9]+) \\/\\* Resources \\*\\/', build_phases)\n\t\tif match:\n\t\t\t(self._resources_build_phase_guid, ) = match.groups()\n\t\telse:\n\t\t\tself._resources_build_phase_guid = False\n\t\t\n\t\tmatch = re.search('([A-Z0-9]+) \\/\\* Frameworks \\*\\/', build_phases)\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the Frameworks phase for the target named \\\"\"+self._name+\"\\\" from the project loaded from: \"+self._project.path())\n\t\t\tlogging.error(\"Please add a New Link Binary With Libraries Build Phase to your target\")\n\t\t\tlogging.error(\"Right click your target in the project, then click Add, then New Build Phase,\")\n\t\t\tlogging.error(\"  \\\"New Link Binary With Libraries Build Phase\\\"\")\n\t\t\treturn False\n\n\t\t(self._frameworks_build_phase_guid, ) = match.groups()\n\n\n\tdef resources_build_phase_guid(self):\n\t\tif not self._resources_build_phase_guid:\n\t\t\tself._gather_build_phases()\n\t\t\n\t\treturn self._resources_build_phase_guid\n\n\n\tdef frameworks_build_phase_guid(self):\n\t\tif not self._frameworks_build_phase_guid:\n\t\t\tself._gather_build_phases()\n\t\t\n\t\treturn self._frameworks_build_phase_guid\n\n\n\tdef dependency_guids(self):\n\t\tif not self._dependency_guids:\n\t\t\tproject_data = self._project.get_project_data()\n\n\t\t\tresult = re.search(re.escape(self.guid())+' \\/\\* '+re.escape(self._name)+' \\*\\/ = {\\n[ \\t]+isa = PBXNativeTarget;(?:.|\\n)+?dependencies = \\(\\n((?:[ \\t]+[A-Z0-9]+ \\/\\* PBXTargetDependency \\*\\/,\\n)*)[ \\t]*\\);\\n',\n\t\t\t                   project_data)\n\t\n\t\t\tif not result:\n\t\t\t\tlogging.error(\"Unable to get dependencies from: \"+self._project.path())\n\t\t\t\treturn False\n\t\n\t\t\t(dependency_set, ) = result.groups()\n\t\t\tself._dependency_guids = re.findall('[ \\t]+([A-Z0-9]+) \\/\\* PBXTargetDependency \\*\\/,\\n', dependency_set)\n\t\t\n\t\treturn self._dependency_guids\n\n\n\tdef dependency_names(self):\n\t\tif not self._dependency_names:\n\t\t\tproject_data = self._project.get_project_data()\n\t\t\tdependency_names = []\n\n\t\t\tfor guid in self.dependency_guids():\n\t\t\t\tresult = re.search(guid+' \\/\\* PBXTargetDependency \\*\\/ = \\{\\n[ \\t]+isa = PBXTargetDependency;\\n[ \\t]*name = ([\"a-zA-Z0-9\\.\\-]+);',\n\t\t\t\t                   project_data)\n\n\t\t\t\tif result:\n\t\t\t\t\t(dependency_name, ) = result.groups()\n\t\t\t\t\tdependency_names.append(dependency_name)\n\n\t\t\tself._dependency_names = dependency_names\n\t\t\n\t\treturn self._dependency_names\n\n\tdef dependency_paths(self):\n\t\tif self._dependency_paths:\n\t\t\treturn self._dependency_paths\n\n\t\tdependency_guids = self.dependency_guids()\n\t\tif dependency_guids:\n\t\t\tproject_data = self._project.get_project_data()\n\t\t\t\n\t\t\ttarget_proxy_guids = []\n\t\t\t\n\t\t\tfor guid in dependency_guids:\n\t\t\t\tresult = re.search(guid+' \\/\\* PBXTargetDependency \\*\\/ = \\{\\n(?:.|\\n)+?targetProxy = ([A-Z0-9]+) \\/\\* PBXContainerItemProxy \\*\\/;',\n\t\t\t\t                   project_data)\n\t\t\t\t\n\t\t\t\tif result:\n\t\t\t\t\t(target_proxy_guid, ) = result.groups()\n\t\t\t\t\ttarget_proxy_guids.append(target_proxy_guid)\n\n\t\t\tcontainer_portal_guids = []\n\t\t\tremote_guids = []\n\t\t\t\n\t\t\tfor guid in target_proxy_guids:\n\t\t\t\tresult = re.search(guid+' \\/\\* PBXContainerItemProxy \\*\\/ = \\{\\n(?:.|\\n)+?containerPortal = ([A-Z0-9]+) \\/\\* .+? \\*\\/;(?:.|\\n)+?remoteGlobalIDString = ([A-Z0-9]+)',\n\t\t\t\t                   project_data)\n\t\t\t\t\n\t\t\t\tif result:\n\t\t\t\t\t(container_portal_guid, remote_guid, ) = result.groups()\n\t\t\t\t\tcontainer_portal_guids.append(container_portal_guid)\n\t\t\t\t\tremote_guids.append(remote_guid)\n\n\t\t\tdependency_paths = []\n\n\t\t\tindex = 0\n\t\t\tfor guid in container_portal_guids:\n\t\t\t\tresult = re.search(guid+' \\/\\* .+? \\*\\/ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = .+?; path = (.+?); sourceTree = .+?; };',\n\t\t\t\t                   project_data)\n\t\t\t\t\n\t\t\t\tif result:\n\t\t\t\t\t(dependency_path, ) = result.groups()\n\t\t\t\t\tdependency_path = dependency_path + \":\" + remote_guids[index]\n\t\t\t\t\tdependency_paths.append(dependency_path)\n\t\t\t\telse:\n\t\t\t\t\tlogging.error(\"Unable to find the path for GUID: \"+guid)\n\t\t\t\t\n\t\t\t\tindex += 1\n\n\t\t\tif len(dependency_paths) != len(container_portal_guids):\n\t\t\t\tlogging.error(\"Unable to load all dependency information from the project.\")\n\t\t\t\treturn False\n\n\t\t\tself._dependency_paths = dependency_paths\n\t\t\t\n\t\telif dependency_guids is not None and dependency_guids is not False and len(dependency_guids) == 0:\n\t\t\tself._dependency_paths = []\n\n\t\treturn self._dependency_paths\n\n\n\tdef _gather_product_details(self):\n\t\tproject_data = self._project.get_project_data()\n\n\t\tresult = re.search(re.escape(self.guid())+' \\/\\* '+re.escape(self._name)+' \\*\\/ = {\\n[ \\t]+isa = PBXNativeTarget;(?:.|\\n)+?productReference = ([A-Z0-9]+) \\/\\* (.+?) \\*\\/;',\n\t\t                   project_data)\n\n\t\tif not result:\n\t\t\tlogging.error(\"Unable to get product guid from: \"+self.path())\n\t\t\treturn False\n\n\t\t(self._product_guid, self._product_name, ) = result.groups()\n\t\t\n\t\treturn True\n\n\n\tdef product_guid(self):\n\t\tif not self._product_guid:\n\t\t\tself._gather_product_details()\n\n\t\treturn self._product_guid\n\n\n\tdef product_name(self):\n\t\tif not self._product_name:\n\t\t\tself._gather_product_details()\n\n\t\treturn self._product_name\n\n\nclass pbxproj(object):\n\n\t@staticmethod\n\tdef get_pbxproj_by_path(path, xcode_version = None):\n\t\tif path not in pbxproj_cache:\n\t\t\tpbxproj_cache[path] = pbxproj(path, xcode_version = xcode_version)\n\n\t\treturn pbxproj_cache[path]\n\n\tdef __init__(self, path, xcode_version = None):\n\t\t# The contents of the pbxproj file loaded into memory.\n\t\tself._project_data = None\n\t\t\n\t\tself._active_target = None\n\t\t\n\t\tself._project_name = os.path.basename(os.path.dirname(path)).replace('.xcodeproj', '')\n\n\t\t# The path to the pbxproj file.\n\t\tself._path = path\n\n\t\t# Mapping of target names to PbxprojTarget objects.\n\t\tself._targets_by_name = {}\n\t\t\n\t\t# Mapping of target guids to PbxprojTarget objects.\n\t\tself._targets_by_guid = {}\n\t\t\n\t\t# ???\n\t\tself._xcode_version = xcode_version\n\t\t\n\t\t# The file format version for this project.\n\t\tself._file_format_version = None\n\n\t\tself._is_loaded = self._load_from_disk()\n\n\tdef __str__(self):\n\t\tdetails = \"\\t   path: \\\"\"+str(self._path)+\"\\\"\\n\\ttargets:\"\n\t\tfor target_name in self._targets_by_name:\n\t\t\ttarget = self._targets_by_name[target_name]\n\t\t\tdetails += \"\\n            -> \"+target.name() + \" (\"+target.guid()+\")\"\n\t\tif self._active_target:\n\t\t\tdetails += \"\\n  active target: \"+self._active_target\n\t\treturn details\n\n\tdef is_loaded(self):\n\t\treturn self._is_loaded\n\n\tdef uniqueid_for_target(self, target):\n\t\treturn self._path + ':' + target\n\n\tdef path(self):\n\t\treturn self._path\n\n\tdef active_target(self):\n\t\tif self._active_target is None:\n\t\t\treturn None\n\t\t\n\t\treturn self.target_by_name(self._active_target)\n\n\tdef set_active_target(self, target_name):\n\t\tself._active_target = target_name\n\n\t# A pbxproj file is contained within an xcodeproj file.\n\t# This method simply strips off the project.pbxproj part of the path.\n\tdef xcodeprojpath(self):\n\t\treturn os.path.dirname(self.path())\n\n\tdef version(self):\n\t\tif not self._file_format_version:\n\t\t\tresult = re.search('\\tobjectVersion = ([0-9]+);', project_data)\n\n\t\t\tif not result:\n\t\t\t\tlogging.error(\"Can't recover: unable to find the project version for your target at: \"+self.path())\n\t\t\t\treturn False\n\t\n\t\t\t(self._file_format_version,) = result.groups()\n\t\t\tself._file_format_version = int(self._file_format_version)\n\n\t\treturn self._file_format_version\n\n\t# Fetch a specific target by its name.\n\tdef target_by_name(self, name):\n\t\tif name in self._targets_by_guid:\n\t\t\ttarget = self._targets_by_guid[name]\n\t\t\ttarget._guid = name\n\t\t\treturn target\n\n\t\tif name not in self._targets_by_name:\n\t\t\ttarget = PbxprojTarget(name, self)\n\t\t\tself._targets_by_name[name] = target\n\t\t\tself._targets_by_guid[target.guid()] = target\n\t\t\n\t\treturn self._targets_by_name[name]\n\n\t# Load the project data from disk.\n\tdef get_project_data(self):\n\t\tif self._project_data is None:\n\t\t\tif not os.path.exists(self.path()):\n\t\t\t\tlogging.info(\"Couldn't find the project at this path:\")\n\t\t\t\tlogging.info(self.path())\n\t\t\t\treturn None\n\n\t\t\tproject_file = open(self.path(), 'r')\n\t\t\tself._project_data = project_file.read()\n\n\t\treturn self._project_data\n\n\t# Write the project data to disk.\n\tdef set_project_data(self, project_data, flush=False):\n\t\tif self._project_data != project_data or flush:\n\t\t\tself._project_data = project_data\n\t\t\tif flush:\n\t\t\t\tproject_file = open(self.path(), 'w')\n\t\t\t\tproject_file.write(self._project_data)\n\n\tdef _load_from_disk(self):\n\t\tproject_data = self.get_project_data()\n\n\t\tif project_data is None:\n\t\t\tlogging.error(\"Can't recover: unable to load the project data from disk, check the path:\\n    path: \\\"\"+self.path()+\"\\\"\")\n\t\t\treturn False\n\n\t\tself._gather_all_targets()\n\n\t\treturn True\n\n\tdef _gather_all_targets(self):\n\t\tproject_data = self.get_project_data()\n\t\t\n\t\tresult = re.search('targets = \\(\\n((?:.|\\n)+?)\\);',\n\t\t                   project_data)\n\t\t\n\t\tif not result:\n\t\t\tlogging.error(\"Couldn't find any targets.\")\n\t\t\treturn None\n\t\t\n\t\t(target_list, ) = result.groups()\n\n\t\ttargets = re.findall('([A-Z0-9]+) \\/\\* (.+?) \\*\\/', target_list)\n\t\tif not targets:\n\t\t\tlogging.error(\"Unable to read the targets.\")\n\t\t\treturn None\n\t\t\n\t\tfor target in targets:\n\t\t\tname = target[1]\n\t\t\ttarget = PbxprojTarget(name, project = self, guid = target[0])\n\t\t\tself._targets_by_name[name] = target\n\t\t\tself._targets_by_guid[target.guid()] = target\n\n\t\treturn True\n\n\n\tdef dependency_names_for_target_name(self, target_name):\n\t\ttarget = self.target_by_name(target_name)\n\t\treturn target.dependency_names()\n\n\n\tdef dependency_paths_for_target_name(self, target_name):\n\t\ttarget = self.target_by_name(target_name)\n\t\treturn target.dependency_paths()\n\n\n\t# Add a line to the PBXBuildFile section.\n\t#\n\t# <default_guid> /* <name> in Frameworks */ = {isa = PBXBuildFile; fileRef = <file_ref_hash> /* <name> */; };\n\t#\n\t# Returns: <default_guid> if a line was added.\n\t#          Otherwise, the existing guid is returned.\n\tdef add_buildfile(self, name, file_ref_hash, default_guid):\n\t\tproject_data = self.get_project_data()\n\n\t\tmatch = re.search('\\/\\* Begin PBXBuildFile section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXBuildFile section \\*\\/', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXBuildFile section.\")\n\t\t\treturn None\n\n\t\t(subtext, ) = match.groups()\n\n\t\tbuildfile_hash = None\n\t\t\n\t\tmatch = re.search('([A-Z0-9]+).+?fileRef = '+re.escape(file_ref_hash), subtext)\n\t\tif match:\n\t\t\t(buildfile_hash, ) = match.groups()\n\t\t\tlogging.info(\"This build file already exists: \"+buildfile_hash)\n\t\t\n\t\tif buildfile_hash is None:\n\t\t\tmatch = re.search('\\/\\* Begin PBXBuildFile section \\*\\/\\n', project_data)\n\n\t\t\tbuildfile_hash = default_guid\n\t\t\n\t\t\tlibfiletext = \"\\t\\t\"+buildfile_hash+\" /* \"+name+\" in Frameworks */ = {isa = PBXBuildFile; fileRef = \"+file_ref_hash+\" /* \"+name+\" */; };\\n\"\n\t\t\tproject_data = project_data[:match.end()] + libfiletext + project_data[match.end():]\n\t\t\n\t\tself.set_project_data(project_data)\n\t\t\n\t\treturn buildfile_hash\n\n\t# Add a line to the PBXFileReference section.\n\t#\n\t# <default_guid> /* <name> */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.<file_type>\"; name = <name>; path = <rel_path>; sourceTree = <source_tree>; };\n\t#\n\t# Returns: <default_guid> if a line was added.\n\t#          Otherwise, the existing guid is returned.\n\tdef add_filereference(self, name, file_type, default_guid, rel_path, source_tree):\n\t\tproject_data = self.get_project_data()\n\n\t\tquoted_rel_path = '\"'+rel_path.strip('\"')+'\"'\n\n\t\tfileref_hash = None\n\n\t\tmatch = re.search('([A-Z0-9]+) \\/\\* '+re.escape(name)+' \\*\\/ = \\{isa = PBXFileReference; lastKnownFileType = \"wrapper.'+file_type+'\"; name = '+re.escape(name)+'; path = '+re.escape(rel_path)+';', project_data)\n\n\t\tif not match:\n\t\t\t# Check again for quoted versions, just to be sure.\n\t\t\tmatch = re.search('([A-Z0-9]+) \\/\\* '+re.escape(name)+' \\*\\/ = \\{isa = PBXFileReference; lastKnownFileType = \"wrapper.'+file_type+'\"; name = '+re.escape(name)+'; path = '+re.escape(quoted_rel_path)+';', project_data)\n\n\t\tif match:\n\t\t\tlogging.info(\"This file has already been added.\")\n\t\t\t(fileref_hash, ) = match.groups()\n\t\t\t\n\t\telse:\n\t\t\tmatch = re.search('\\/\\* Begin PBXFileReference section \\*\\/\\n', project_data)\n\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the PBXFileReference section.\")\n\t\t\t\treturn False\n\n\t\t\tfileref_hash = default_guid\n\t\t\t\n\t\t\tpbxfileref = \"\\t\\t\"+fileref_hash+\" /* \"+name+\" */ = {isa = PBXFileReference; lastKnownFileType = \\\"wrapper.\"+file_type+\"\\\"; name = \"+name+\"; path = \"+quoted_rel_path+\"; sourceTree = \"+source_tree+\"; };\\n\"\n\n\t\t\tproject_data = project_data[:match.end()] + pbxfileref + project_data[match.end():]\n\n\t\tself.set_project_data(project_data)\n\n\t\treturn fileref_hash\n\n\t# Add a file to the given PBXGroup.\n\t#\n\t# <guid> /* <name> */,\n\tdef add_file_to_group(self, name, guid, group):\n\t\tproject_data = self.get_project_data()\n\n\t\tmatch = re.search('\\/\\* '+re.escape(group)+' \\*\\/ = \\{\\n[ \\t]+isa = PBXGroup;\\n[ \\t]+children = \\(\\n((?:.|\\n)+?)\\);', project_data)\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the \"+group+\" children.\")\n\t\t\treturn False\n\n\t\t(children,) = match.groups()\n\t\tmatch = re.search(re.escape(guid), children)\n\t\tif match:\n\t\t\tlogging.info(\"This file is already a member of the \"+name+\" group.\")\n\t\telse:\n\t\t\tmatch = re.search('\\/\\* '+re.escape(group)+' \\*\\/ = \\{\\n[ \\t]+isa = PBXGroup;\\n[ \\t]+children = \\(\\n', project_data)\n\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the \"+group+\" group.\")\n\t\t\t\treturn False\n\n\t\t\tpbxgroup = \"\\t\\t\\t\\t\"+guid+\" /* \"+name+\" */,\\n\"\n\t\t\tproject_data = project_data[:match.end()] + pbxgroup + project_data[match.end():]\n\n\t\tself.set_project_data(project_data)\n\n\t\treturn True\n\n\t# Add a file to the Frameworks PBXGroup.\n\t#\n\t# <guid> /* <name> */,\n\tdef add_file_to_frameworks(self, name, guid):\n\t\treturn self.add_file_to_group(name, guid, 'Frameworks')\n\n\t# Add a file to the Resources PBXGroup.\n\t#\n\t# <guid> /* <name> */,\n\tdef add_file_to_resources(self, name, guid):\n\t\tmatch = re.search('\\/\\* '+re.escape('Resources')+' \\*\\/ = \\{\\n[ \\t]+isa = PBXGroup;\\n[ \\t]+children = \\(\\n((?:.|\\n)+?)\\);', self.get_project_data())\n\t\tif not match:\n\t\t\treturn self.add_file_to_group(name, guid, 'Supporting Files')\n\n\t\treturn self.add_file_to_group(name, guid, 'Resources')\n\n\tdef add_file_to_phase(self, name, guid, phase_guid, phase):\n\t\tproject_data = self.get_project_data()\n\n\t\tmatch = re.search(re.escape(phase_guid)+\" \\/\\* \"+re.escape(phase)+\" \\*\\/ = {(?:.|\\n)+?files = \\(((?:.|\\n)+?)\\);\", project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the \"+phase+\" phase.\")\n\t\t\treturn False\n\n\t\t(files, ) = match.groups()\n\n\t\tmatch = re.search(re.escape(guid), files)\n\t\tif match:\n\t\t\tlogging.info(\"The file has already been added.\")\n\t\telse:\n\t\t\tmatch = re.search(re.escape(phase_guid)+\" \\/\\* \"+phase+\" \\*\\/ = {(?:.|\\n)+?files = \\(\\n\", project_data)\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the \"+phase+\" files\")\n\t\t\t\treturn False\n\n\t\t\tframeworktext = \"\\t\\t\\t\\t\"+guid+\" /* \"+name+\" in \"+phase+\" */,\\n\"\n\t\t\tproject_data = project_data[:match.end()] + frameworktext + project_data[match.end():]\n\n\t\tself.set_project_data(project_data)\n\n\t\treturn True\n\n\tdef get_rel_path_to_products_dir(self):\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\tbuild_path = os.path.join(os.path.join(os.path.dirname(Paths.src_dir), 'Build'), 'Products')\n\t\treturn relpath(project_path, build_path)\n\n\tdef add_file_to_frameworks_phase(self, name, guid):\n\t\ttarget = self.active_target()\n\t\treturn self.add_file_to_phase(name, guid, target.frameworks_build_phase_guid(), 'Frameworks')\n\n\tdef add_file_to_resources_phase(self, name, guid):\n\t\tif self._resources_guid is None:\n\t\t\tlogging.error(\"No resources build phase found in the destination project\")\n\t\t\tlogging.error(\"Please add a New Copy Bundle Resources Build Phase to your target\")\n\t\t\tlogging.error(\"Right click your target in the project, Add, New Build Phase,\")\n\t\t\tlogging.error(\"  \\\"New Copy Bundle Resources Build Phase\\\"\")\n\t\t\treturn False\n\n\t\treturn self.add_file_to_phase(name, guid, self._resources_guid, 'Resources')\n\n\tdef add_header_search_path(self, configuration):\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\tbuild_path = os.path.join(os.path.join(os.path.join(os.path.dirname(Paths.src_dir), 'Build'), 'Products'), 'three20')\n\t\trel_path = relpath(project_path, build_path)\n\n\t\tdid_add_build_setting = self.add_build_setting(configuration, 'HEADER_SEARCH_PATHS', '\"'+rel_path+'\"')\n\t\tif not did_add_build_setting:\n\t\t\treturn did_add_build_setting\n\t\t\n\t\t# Version 46 is Xcode 4's file format.\n\t\ttry:\n\t\t\tprimary_version = int(self._xcode_version.split('.')[0])\n\t\texcept ValueError, e:\n\t\t\tprimary_version = 0\n\t\tif self._file_format_version >= 46 or primary_version >= 4:\n\t\t\tdid_add_build_setting = self.add_build_setting(configuration, 'HEADER_SEARCH_PATHS', '\"$(BUILT_PRODUCTS_DIR)/../../three20\"')\n\t\t\tif not did_add_build_setting:\n\t\t\t\treturn did_add_build_setting\n\n\t\t\tdid_add_build_setting = self.add_build_setting(configuration, 'HEADER_SEARCH_PATHS', '\"$(BUILT_PRODUCTS_DIR)/../three20\"')\n\t\t\tif not did_add_build_setting:\n\t\t\t\treturn did_add_build_setting\n\n\t\treturn did_add_build_setting\n\t\n\tdef add_build_setting(self, configuration, setting_name, value):\n\t\tproject_data = self.get_project_data()\n\n\t\tmatch = re.search('\\/\\* '+configuration+' \\*\\/ = {\\n[ \\t]+isa = XCBuildConfiguration;\\n[ \\t]+buildSettings = \\{\\n((?:.|\\n)+?)\\};', project_data)\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find this configuration.\")\n\t\t\treturn False\n\n\t\tsettings_start = match.start(1)\n\t\tsettings_end = match.end(1)\n\n\t\t(build_settings, ) = match.groups()\n\n\t\tmatch = re.search(re.escape(setting_name)+' = ((?:.|\\n)+?);', build_settings)\n\n\t\tif not match:\n\t\t\t# Add a brand new build setting. No checking for existing settings necessary.\n\t\t\tsettingtext = '\\t\\t\\t\\t'+setting_name+' = '+value+';\\n'\n\n\t\t\tproject_data = project_data[:settings_start] + settingtext + project_data[settings_start:]\n\t\telse:\n\t\t\t# Build settings already exist. Is there one or many?\n\t\t\t(search_paths,) = match.groups()\n\t\t\tif re.search('\\(\\n', search_paths):\n\t\t\t\t# Many\n\t\t\t\tmatch = re.search(re.escape(value), search_paths)\n\t\t\t\tif not match:\n\t\t\t\t\t# If value has any spaces in it, Xcode will split it up into\n\t\t\t\t\t# multiple entries.\n\t\t\t\t\tescaped_value = re.escape(value).replace(' ', '\",\\n[ \\t]+\"')\n\t\t\t\t\tmatch = re.search(escaped_value, search_paths)\n\t\t\t\t\tif not match and not re.search(re.escape(value.strip('\"')), search_paths):\n\t\t\t\t\t\tmatch = re.search(re.escape(setting_name)+' = \\(\\n', build_settings)\n\n\t\t\t\t\t\tbuild_settings = build_settings[:match.end()] + '\\t\\t\\t\\t\\t'+value+',\\n' + build_settings[match.end():]\n\t\t\t\t\t\tproject_data = project_data[:settings_start] + build_settings + project_data[settings_end:]\n\t\t\telse:\n\t\t\t\t# One\n\t\t\t\tif search_paths.strip('\"') != value.strip('\"'):\n\t\t\t\t\texisting_path = search_paths\n\t\t\t\t\tpath_set = '(\\n\\t\\t\\t\\t\\t'+value+',\\n\\t\\t\\t\\t\\t'+existing_path+'\\n\\t\\t\\t\\t)'\n\t\t\t\t\tbuild_settings = build_settings[:match.start(1)] + path_set + build_settings[match.end(1):]\n\t\t\t\t\tproject_data = project_data[:settings_start] + build_settings + project_data[settings_end:]\n\n\t\tself.set_project_data(project_data)\n\n\t\treturn True\n\n\tdef get_hash_base(self, uniquename):\n\t\texamplehash = '320FFFEEEDDDCCCBBBAAA000'\n\t\tuniquehash = hashlib.sha224(uniquename).hexdigest().upper()\n\t\tuniquehash = uniquehash[:len(examplehash) - 4]\n\t\treturn '320'+uniquehash\n\n\tdef add_framework(self, framework):\n\t\ttthash_base = self.get_hash_base(framework)\n\t\t\n\t\tfileref_hash = self.add_filereference(framework, 'frameworks', tthash_base+'0', 'System/Library/Frameworks/'+framework, 'SDKROOT')\n\t\tlibfile_hash = self.add_buildfile(framework, fileref_hash, tthash_base+'1')\n\t\tif not self.add_file_to_frameworks(framework, fileref_hash):\n\t\t\treturn False\n\t\t\n\t\tif not self.add_file_to_frameworks_phase(framework, libfile_hash):\n\t\t\treturn False\n\t\t\n\t\treturn True\n\n\tdef add_bundle(self):\n\t\ttthash_base = self.get_hash_base('Three20.bundle')\n\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\tbuild_path = os.path.join(Paths.src_dir, 'Three20.bundle')\n\t\trel_path = relpath(project_path, build_path)\n\t\t\n\t\tfileref_hash = self.add_filereference('Three20.bundle', 'plug-in', tthash_base+'0', rel_path, 'SOURCE_ROOT')\n\n\t\tlibfile_hash = self.add_buildfile('Three20.bundle', fileref_hash, tthash_base+'1')\n\n\t\tif not self.add_file_to_resources('Three20.bundle', fileref_hash):\n\t\t\treturn False\n\n\t\tif not self.add_file_to_resources_phase('Three20.bundle', libfile_hash):\n\t\t\treturn False\n\n\t\treturn True\n\n\t# Get the PBXFileReference from the given PBXBuildFile guid.\n\tdef get_filerefguid_from_buildfileguid(self, buildfileguid):\n\t\tproject_data = self.get_project_data()\n\t\tmatch = re.search(buildfileguid+' \\/\\* .+ \\*\\/ = {isa = PBXBuildFile; fileRef = ([A-Z0-9]+) \\/\\* .+ \\*\\/;', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXBuildFile row.\")\n\t\t\treturn None\n\n\t\t(filerefguid, ) = match.groups()\n\t\t\n\t\treturn filerefguid\n\n\tdef get_filepath_from_filerefguid(self, filerefguid):\n\t\tproject_data = self.get_project_data()\n\t\tmatch = re.search(filerefguid+' \\/\\* .+ \\*\\/ = {isa = PBXFileReference; .+ path = (.+); .+ };', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXFileReference row.\")\n\t\t\treturn None\n\n\t\t(path, ) = match.groups()\n\t\t\n\t\treturn path\n\n\n\t# Get all source files that are \"built\" in this project. This includes files built for\n\t# libraries, executables, and unit testing.\n\tdef get_built_sources(self):\n\t\tproject_data = self.get_project_data()\n\t\tmatch = re.search('\\/\\* Begin PBXSourcesBuildPhase section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXSourcesBuildPhase section \\*\\/', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXSourcesBuildPhase section.\")\n\t\t\treturn None\n\t\t\n\t\t(buildphasedata, ) = match.groups()\n\t\t\n\t\tbuildfileguids = re.findall('[ \\t]+([A-Z0-9]+) \\/\\* .+ \\*\\/,\\n', buildphasedata)\n\t\t\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\t\n\t\tfilenames = []\n\t\t\n\t\tfor buildfileguid in buildfileguids:\n\t\t\tfilerefguid = self.get_filerefguid_from_buildfileguid(buildfileguid)\n\t\t\tfilepath = self.get_filepath_from_filerefguid(filerefguid)\n\n\t\t\tfilenames.append(os.path.join(project_path, filepath.strip('\"')))\n\n\t\treturn filenames\n\n\n\t# Get all header files that are \"built\" in this project. This includes files built for\n\t# libraries, executables, and unit testing.\n\tdef get_built_headers(self):\n\t\tproject_data = self.get_project_data()\n\t\tmatch = re.search('\\/\\* Begin PBXHeadersBuildPhase section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXHeadersBuildPhase section \\*\\/', project_data)\n\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find PBXHeadersBuildPhase section.\")\n\t\t\treturn None\n\t\t\n\t\t(buildphasedata, ) = match.groups()\n\n\t\tbuildfileguids = re.findall('[ \\t]+([A-Z0-9]+) \\/\\* .+ \\*\\/,\\n', buildphasedata)\n\t\t\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\t\n\t\tfilenames = []\n\t\t\n\t\tfor buildfileguid in buildfileguids:\n\t\t\tfilerefguid = self.get_filerefguid_from_buildfileguid(buildfileguid)\n\t\t\tfilepath = self.get_filepath_from_filerefguid(filerefguid)\n\t\t\t\n\t\t\tfilenames.append(os.path.join(project_path, filepath.strip('\"')))\n\n\t\treturn filenames\n\n\n\tdef add_dependency(self, dep):\n\t\tproject_data = self.get_project_data()\n\t\tdep_data = dep.get_project_data()\n\t\tproject_target = self.active_target()\n\t\tdep_target = dep.active_target()\n\t\t\n\t\tif project_data is None or dep_data is None:\n\t\t\treturn False\n\n\t\tlogging.info(\"\\nAdding \"+str(dep)+\"\\nto\\n\"+str(self))\n\t\t\n\t\tproject_path = os.path.dirname(os.path.abspath(self.xcodeprojpath()))\n\t\tdep_path = os.path.abspath(dep.xcodeprojpath())\n\t\trel_path = relpath(project_path, dep_path)\n\t\t\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Project path:    \"+project_path)\n\t\tlogging.info(\"Dependency path: \"+dep_path)\n\t\tlogging.info(\"Relative path:   \"+rel_path)\n\t\t\n\t\ttthash_base = self.get_hash_base(dep.uniqueid_for_target(dep._active_target))\n\t\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 1: Add file reference to the dependency...\")\n\t\t\n\t\tpbxfileref_hash = self.add_filereference(dep._project_name+'.xcodeproj', 'pb-project', tthash_base+'0', rel_path, 'SOURCE_ROOT')\n\t\tproject_data = self.get_project_data()\n\n\t\tlogging.info(\"Done: Added file reference: \"+pbxfileref_hash)\n\t\tself.set_project_data(project_data)\n\t\t\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 2: Add file to Frameworks group...\")\n\t\t\n\t\tif not self.add_file_to_frameworks(dep._project_name+\".xcodeproj\", pbxfileref_hash):\n\t\t\treturn False\n\t\tproject_data = self.get_project_data()\n\n\t\tlogging.info(\"Done: Added file to Frameworks group.\")\n\t\tself.set_project_data(project_data)\n\t\t\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 3: Add dependencies...\")\n\t\t\n\t\tpbxtargetdependency_hash = None\n\t\tpbxcontaineritemproxy_hash = None\n\t\t\n\t\tmatch = re.search('\\/\\* Begin PBXTargetDependency section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXTargetDependency section \\*\\/', project_data)\n\t\tif not match:\n\t\t\tlogging.info(\"\\tAdding a PBXTargetDependency section...\")\n\t\t\tmatch = re.search('\\/\\* End PBXSourcesBuildPhase section \\*\\/\\n', project_data)\n\t\t\t\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the PBXSourcesBuildPhase section.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tproject_data = project_data[:match.end()] + \"\\n/* Begin PBXTargetDependency section */\\n\\n/* End PBXTargetDependency section */\\n\" + project_data[match.end():]\n\t\telse:\n\t\t\t(subtext, ) = match.groups()\n\t\t\tmatch = re.search('([A-Z0-9]+) \\/\\* PBXTargetDependency \\*\\/ = {\\n[ \\t]+isa = PBXTargetDependency;\\n[ \\t]+name = '+re.escape(dep._project_name)+';\\n[ \\t]+targetProxy = ([A-Z0-9]+) \\/\\* PBXContainerItemProxy \\*\\/;', project_data)\n\t\t\tif match:\n\t\t\t\t(pbxtargetdependency_hash, pbxcontaineritemproxy_hash,) = match.groups()\n\t\t\t\tlogging.info(\"This dependency already exists.\")\n\n\t\tself.set_project_data(project_data)\n\n\t\tif pbxtargetdependency_hash is None or pbxcontaineritemproxy_hash is None:\n\t\t\tmatch = re.search('\\/\\* Begin PBXTargetDependency section \\*\\/\\n', project_data)\n\t\t\n\t\t\tpbxtargetdependency_hash = tthash_base+'1'\n\t\t\tpbxcontaineritemproxy_hash = tthash_base+'2'\n\t\t\n\t\t\tpbxtargetdependency = \"\\t\\t\"+pbxtargetdependency_hash+\" /* PBXTargetDependency */ = {\\n\\t\\t\\tisa = PBXTargetDependency;\\n\\t\\t\\tname = \"+dep._project_name+\";\\n\\t\\t\\ttargetProxy = \"+pbxcontaineritemproxy_hash+\" /* PBXContainerItemProxy */;\\n\\t\\t};\\n\"\n\t\t\tproject_data = project_data[:match.end()] + pbxtargetdependency + project_data[match.end():]\n\n\t\tlogging.info(\"Done: Added dependency.\")\n\t\tself.set_project_data(project_data)\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 3.1: Add container proxy for dependencies...\")\n\n\t\tcontainerExists = False\n\n\t\tmatch = re.search('\\/\\* Begin PBXContainerItemProxy section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXContainerItemProxy section \\*\\/', project_data)\n\t\tif not match:\n\t\t\tlogging.info(\"\\tAdding a PBXContainerItemProxy section...\")\n\t\t\tmatch = re.search('\\/\\* End PBXBuildFile section \\*\\/\\n', project_data)\n\t\t\t\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the PBXBuildFile section.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tproject_data = project_data[:match.end()] + \"\\n/* Begin PBXContainerItemProxy section */\\n\\n/* End PBXContainerItemProxy section */\\n\" + project_data[match.end():]\n\t\telse:\n\t\t\t(subtext, ) = match.groups()\n\t\t\tmatch = re.search(re.escape(pbxcontaineritemproxy_hash), subtext)\n\t\t\tif match:\n\t\t\t\tlogging.info(\"This container proxy already exists.\")\n\t\t\t\tcontainerExists = True\n\n\t\tself.set_project_data(project_data)\n\n\t\tif not containerExists:\n\t\t\tmatch = re.search('\\/\\* Begin PBXContainerItemProxy section \\*\\/\\n', project_data)\n\n\t\t\tpbxcontaineritemproxy = \"\\t\\t\"+pbxcontaineritemproxy_hash+\" /* PBXContainerItemProxy */ = {\\n\\t\\t\\tisa = PBXContainerItemProxy;\\n\\t\\t\\tcontainerPortal = \"+pbxfileref_hash+\" /* \"+dep._project_name+\".xcodeproj */;\\n\\t\\t\\tproxyType = 1;\\n\\t\\t\\tremoteGlobalIDString = \"+dep_target.guid()+\";\\n\\t\\t\\tremoteInfo = \"+dep._project_name+\";\\n\\t\\t};\\n\"\n\t\t\tproject_data = project_data[:match.end()] + pbxcontaineritemproxy + project_data[match.end():]\n\n\t\tlogging.info(\"Done: Added container proxy.\")\n\t\tself.set_project_data(project_data)\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 3.2: Add module to the dependency list...\")\n\n\t\tmatch = re.search(project_target.guid()+' \\/\\* .+? \\*\\/ = {\\n[ \\t]+(?:.|\\n)+?[ \\t]+dependencies = \\(\\n((?:.|\\n)+?)\\);', project_data)\n\t\t\n\t\tdependency_exists = False\n\t\t\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the dependency list.\")\n\t\t\treturn False\n\t\telse:\n\t\t\t(dependencylist, ) = match.groups()\n\t\t\tmatch = re.search(re.escape(pbxtargetdependency_hash), dependencylist)\n\t\t\tif match:\n\t\t\t\tlogging.info(\"This dependency has already been added.\")\n\t\t\t\tdependency_exists = True\n\t\t\n\t\tif not dependency_exists:\n\t\t\tmatch = re.search(project_target.guid()+' \\/\\* .+? \\*\\/ = {\\n[ \\t]+(?:.|\\n)+?[ \\t]+dependencies = \\(\\n', project_data)\n\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the dependency list.\")\n\t\t\t\treturn False\n\n\t\t\tdependency_item = '\\t\\t\\t\\t'+pbxtargetdependency_hash+' /* PBXTargetDependency */,\\n'\n\t\t\tproject_data = project_data[:match.end()] + dependency_item + project_data[match.end():]\n\n\t\tlogging.info(\"Done: Added module to the dependency list.\")\n\t\tself.set_project_data(project_data)\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 4: Create project references...\")\n\n\t\tmatch = re.search('\\/\\* Begin PBXProject section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXProject section \\*\\/', project_data)\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the project section.\")\n\t\t\treturn False\n\n\t\tproject_start = match.start(1)\n\t\tproject_end = match.end(1)\n\n\t\t(project_section, ) = match.groups()\n\t\t\n\t\treference_exists = False\n\t\tdid_change = False\n\t\t\n\t\tproductgroup_hash = None\n\t\t\n\t\tmatch = re.search('projectReferences = \\(\\n((?:.|\\n)+?)\\n[ \\t]+\\);', project_section)\n\t\tif not match:\n\t\t\tlogging.info(\"Creating project references...\")\n\t\t\tmatch = re.search('projectDirPath = \".*?\";\\n', project_section)\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find project references anchor.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tdid_change = True\n\t\t\tproject_section = project_section[:match.end()] + '\\t\\t\\tprojectReferences = (\\n\\t\\t\\t);\\n' + project_section[match.end():]\n\n\t\telse:\n\t\t\t(refs, ) = match.groups()\n\n\t\t\tmatch = re.search('\\{\\n[ \\t]+ProductGroup = ([A-Z0-9]+) \\/\\* Products \\*\\/;\\n[ \\t]+ProjectRef = '+re.escape(pbxfileref_hash), refs)\n\t\t\tif match:\n\t\t\t\t(productgroup_hash, ) = match.groups()\n\t\t\t\tlogging.info(\"This product group already exists: \"+productgroup_hash)\n\t\t\t\treference_exists = True\n\n\n\t\tif not reference_exists:\n\t\t\tmatch = re.search('projectReferences = \\(\\n', project_section)\n\t\t\t\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Missing the project references item.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tproductgroup_hash = tthash_base+'3'\n\n\t\t\treference_text = '\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tProductGroup = '+productgroup_hash+' /* Products */;\\n\\t\\t\\t\\t\\tProjectRef = '+pbxfileref_hash+' /* '+dep._project_name+'.xcodeproj */;\\n\\t\\t\\t\\t},\\n'\n\t\t\tproject_section = project_section[:match.end()] + reference_text + project_section[match.end():]\n\t\t\tdid_change = True\n\t\t\t\n\t\tif did_change:\n\t\t\tproject_data = project_data[:project_start] + project_section + project_data[project_end:]\n\n\t\tlogging.info(\"Done: Created project reference.\")\n\t\tself.set_project_data(project_data)\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 4.1: Create product group...\")\n\n\t\tmatch = re.search('\\/\\* Begin PBXGroup section \\*\\/\\n', project_data)\n\t\tif not match:\n\t\t\tlogging.error(\"Couldn't find the group section.\")\n\t\t\treturn False\n\t\t\n\t\tgroup_start = match.end()\n\n\t\tlib_hash = None\n\n\t\tmatch = re.search(re.escape(productgroup_hash)+\" \\/\\* Products \\*\\/ = \\{\\n[ \\t]+isa = PBXGroup;\\n[ \\t]+children = \\(\\n((?:.|\\n)+?)\\);\", project_data)\n\t\tif match:\n\t\t\tlogging.info(\"This product group already exists.\")\n\t\t\t(children, ) = match.groups()\n\t\t\tmatch = re.search('([A-Z0-9]+) \\/\\* '+re.escape(dep_target.product_name())+' \\*\\/', children)\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"No product found\")\n\t\t\t\treturn False\n\t\t\t\t# TODO: Add this product.\n\t\t\telse:\n\t\t\t\t(lib_hash, ) = match.groups()\n\t\t\t\n\t\telse:\n\t\t\tlib_hash = tthash_base+'4'\n\n\t\t\tproductgrouptext = \"\\t\\t\"+productgroup_hash+\" /* Products */ = {\\n\\t\\t\\tisa = PBXGroup;\\n\\t\\t\\tchildren = (\\n\\t\\t\\t\\t\"+lib_hash+\" /* \"+dep_target.product_name()+\" */,\\n\\t\\t\\t);\\n\\t\\t\\tname = Products;\\n\\t\\t\\tsourceTree = \\\"<group>\\\";\\n\\t\\t};\\n\"\n\t\t\tproject_data = project_data[:group_start] + productgrouptext + project_data[group_start:]\n\n\t\tlogging.info(\"Done: Created product group: \"+lib_hash)\n\t\tself.set_project_data(project_data)\n\t\t\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 4.2: Add container proxy for target product...\")\n\n\t\tcontainerExists = False\n\t\t\n\t\ttargetproduct_hash = tthash_base+'6'\n\n\t\tmatch = re.search('\\/\\* Begin PBXContainerItemProxy section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXContainerItemProxy section \\*\\/', project_data)\n\t\tif not match:\n\t\t\tlogging.info(\"\\tAdding a PBXContainerItemProxy section...\")\n\t\t\tmatch = re.search('\\/\\* End PBXBuildFile section \\*\\/\\n', project_data)\n\t\t\t\n\t\t\tif not match:\n\t\t\t\tlogging.error(\"Couldn't find the PBXBuildFile section.\")\n\t\t\t\treturn False\n\t\t\t\n\t\t\tproject_data = project_data[:match.end()] + \"\\n/* Begin PBXContainerItemProxy section */\\n\\n/* End PBXContainerItemProxy section */\\n\" + project_data[match.end():]\n\t\telse:\n\t\t\t(subtext, ) = match.groups()\n\t\t\tmatch = re.search(re.escape(targetproduct_hash), subtext)\n\t\t\tif match:\n\t\t\t\tlogging.info(\"This container proxy already exists.\")\n\t\t\t\tcontainerExists = True\n\n\t\tself.set_project_data(project_data)\n\t\t\n\t\tif not containerExists:\n\t\t\tmatch = re.search('\\/\\* Begin PBXContainerItemProxy section \\*\\/\\n', project_data)\n\n\t\t\tpbxcontaineritemproxy = \"\\t\\t\"+targetproduct_hash+\" /* PBXContainerItemProxy */ = {\\n\\t\\t\\tisa = PBXContainerItemProxy;\\n\\t\\t\\tcontainerPortal = \"+pbxfileref_hash+\" /* \"+dep._project_name+\".xcodeproj */;\\n\\t\\t\\tproxyType = 2;\\n\\t\\t\\tremoteGlobalIDString = \"+dep_target.guid()+\";\\n\\t\\t\\tremoteInfo = \"+dep._project_name+\";\\n\\t\\t};\\n\"\n\t\t\tproject_data = project_data[:match.end()] + pbxcontaineritemproxy + project_data[match.end():]\n\n\t\tlogging.info(\"Done: Added target container proxy.\")\n\t\tself.set_project_data(project_data)\n\n\n\t\t###############################################\n\t\t# This code seems to break the xcode project but doesn't seem completely crucial.\n\t\t# Gr.\n\n\t\t# logging.info(\"\")\n\t\t# logging.info(\"Step 4.3: Create reference proxy...\")\n\t\t# \n\t\t# referenceExists = False\n\t\t# \n\t\t# match = re.search('\\/\\* Begin PBXReferenceProxy section \\*\\/\\n((?:.|\\n)+?)\\/\\* End PBXReferenceProxy section \\*\\/', project_data)\n\t\t# if not match:\n\t\t# \tlogging.info(\"\\tAdding a PBXReferenceProxy section...\")\n\t\t# \tmatch = re.search('\\/\\* End PBXProject section \\*\\/\\n', project_data)\n\t\t# \t\n\t\t# \tif not match:\n\t\t# \t\tlogging.error(\"Couldn't find the PBXProject section.\")\n\t\t# \t\treturn False\n\t\t# \t\n\t\t# \tproject_data = project_data[:match.end()] + \"\\n/* Begin PBXReferenceProxy section */\\n\\n/* End PBXReferenceProxy section */\\n\" + project_data[match.end():]\n\t\t# else:\n\t\t# \t(subtext, ) = match.groups()\n\t\t# \tmatch = re.search(re.escape(lib_hash), subtext)\n\t\t# \tif match:\n\t\t# \t\tlogging.info(\"This reference proxy already exists.\")\n\t\t# \t\treferenceExists = True\n\t\t# \n\t\t# self.set_project_data(project_data)\n\t\t# \n\t\t# if not referenceExists:\n\t\t# \tmatch = re.search('\\/\\* Begin PBXReferenceProxy section \\*\\/\\n', project_data)\n\t\t# \n\t\t# \treferenceproxytext = \"\\t\\t\"+lib_hash+\" /* \"+dep_target.product_name()+\" */ = {\\n\\t\\t\\tisa = PBXReferenceProxy;\\n\\t\\t\\tfileType = archive.ar;\\n\\t\\t\\tpath = \\\"\"+dep_target.product_name()+\"\\\";\\n\\t\\t\\tremoteRef = \"+targetproduct_hash+\" /* PBXContainerItemProxy */;\\n\\t\\t\\tsourceTree = BUILT_PRODUCTS_DIR;\\n\\t\\t};\\n\"\n\t\t# \tproject_data = project_data[:match.end()] + referenceproxytext + project_data[match.end():]\n\t\t# \n\t\t# logging.info(\"Done: Created reference proxy.\")\n\t\t# self.set_project_data(project_data)\n\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 5: Add target file...\")\n\n\t\tlibfile_hash = self.add_buildfile(dep_target.product_name(), lib_hash, tthash_base+'5')\n\t\tproject_data = self.get_project_data()\n\n\t\tlogging.info(\"Done: Added target file.\")\n\t\t\n\n\t\t###############################################\n\t\tlogging.info(\"\")\n\t\tlogging.info(\"Step 6: Add frameworks...\")\n\n\t\tself.add_file_to_frameworks_phase(dep_target.product_name(), libfile_hash)\n\t\tproject_data = self.get_project_data()\n\n\t\tlogging.info(\"Done: Adding module.\")\n\n\t\tself.set_project_data(project_data, flush = True)\n\n\t\treturn True\n"
  },
  {
    "path": "scripts/ios/relpath.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\"\"\"\nrelpath.py\n\nA method for calculating the relative path from one directory to another.\n\nOriginally written by Cimarron Taylor:\nhttp://code.activestate.com/recipes/208993-compute-relative-path-from-one-directory-to-anothe/\nDate: July 6, 2003\n\nModifications Copyright 2011 Jeff Verkoeyen\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\"\"\"\n\nimport os\n\ndef pathsplit(p, rest=[]):\n    (h,t) = os.path.split(p)\n    if len(h) < 1: return [t]+rest\n    if len(t) < 1: return [h]+rest\n    return pathsplit(h,[t]+rest)\n\ndef commonpath(l1, l2, common=[]):\n    if len(l1) < 1: return (common, l1, l2)\n    if len(l2) < 1: return (common, l1, l2)\n    if l1[0] != l2[0]: return (common, l1, l2)\n    return commonpath(l1[1:], l2[1:], common+[l1[0]])\n\ndef relpath(p1, p2):\n    (common,l1,l2) = commonpath(pathsplit(p1), pathsplit(p2))\n    p = []\n    if len(l1) > 0:\n        p = [ '../' * len(l1) ]\n    p = p + l2\n    return os.path.join( *p )\n"
  },
  {
    "path": "scripts/lint",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\"\"\"\nlint\n\nValidate style guidelines for a given source file.\n\nWhen run from Xcode, the linter will automatically lint all of the built source files\nand headers.\n\nVersion 1.0\n\nHistory:\n1.0 - February 27, 2011: Includes a set of simple linters and a delinter for most lints.\n\nCreated by Jeff Verkoeyen on 2011-02-27.\nCopyright 2009-2011 Facebook\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\"\"\"\n\nimport ConfigParser\nimport logging\nimport os\nimport Paths\nimport pickle\nimport re\nimport string\nimport sys\nfrom optparse import OptionParser\n\nfrom Pbxproj import Pbxproj\nfrom Pbxproj import relpath\n\ngcopyrightyears = '2009-2011'\ngdivider = '///////////////////////////////////////////////////////////////////////////////////////////////////'\n\n# Program entry. The meat of this script happens in the lint() method below.\ndef main():\n\tusage = '''%prog filename\n\nThe Nimbus Linter.\nVerify Nimbus style guidelines for source code.'''\n\n\tparser = OptionParser(usage = usage)\n\tparser.add_option(\"-d\", \"--delint\", dest=\"delint\",\n\t                  help=\"Delint the source\",\n\t                  action=\"store_true\")\n\n\t(options, args) = parser.parse_args()\n\t\n\tif len(args) == 0:\n\t\tparser.print_help()\n\n\tenabled_for_projects = True\n\t\n\t# Allow third-party developers to disable the linter entirely. See config.template for\n\t# more information in the \"lint\" section.\n\tconfigpath = os.path.join(os.path.dirname(Paths.src_dir), 'config')\n\tif os.path.exists(configpath):\n\t\tconfig = ConfigParser.ConfigParser()\n\t\tconfig.read(configpath)\n\t\tenabled_for_projects = config.getboolean('lint', 'enabled_for_projects')\n\n\t# If we're running the linter from Xcode, let's just process the project.\n\tif 'PROJECT_FILE_PATH' in os.environ:\n\t\tif enabled_for_projects:\n\t\t\tlint_project(os.environ['PROJECT_FILE_PATH'], options)\n\telse:\n\t\tfor filename in args:\n\t\t\tlint(filename, options)\n\n\n# This filter makes it possible to set the line number on logging.error calls.\nclass FilenameFilter(logging.Filter):\n\tdef __init__(self):\n\t\tself.lineno = -1\n\n\tdef filter(self, record):\n\t\trecord.linenumber = self.lineno\n\t\treturn True\n\n\ndef lint_project(project_path, options):\n\tproject = Pbxproj.get_pbxproj_by_name(project_path)\n\t\n\ttempdir = None\n\tif os.environ['TEMP_FILES_DIR']:\n\t\ttempdir = os.environ['TEMP_FILES_DIR']\n\t\n\t# We avoid relinting the same file over and over again by maintaining a mapping of filenames\n\t# to modified times on disk. We store this information in the project's build directory and\n\t# load it each time we run the linter for this project.\n\t# Because we store the mtimes on a per project basis, we shouldn't run into any performance\n\t# issues with a lint.dat file that's becoming completely massive.\n\tmtimes = {}\n\t\n\t# Read the lint.dat file and unpickle it if we find it.\n\tif tempdir:\n\t\tlintdatpath = os.path.join(os.path.abspath(tempdir), 'lint.dat')\n\t\tif os.path.exists(lintdatpath):\n\t\t\tlintdatfile = open(lintdatpath, 'rb')\n\t\t\tmtimes = pickle.load(lintdatfile)\n\n\t# The linter script may have changed since we last ran this project, so we might have to\n\t# force lint every file to update them because there may be new linters.\n\t\n\t# Assume that the linter hasn't been run for this project.\n\tforcelint = True\n\t\n\t# Get this script's path\n\tlintfilename = os.path.realpath(__file__)\n\t\n\t# Check the mtime.\n\tmtime = os.path.getmtime(lintfilename)\n\tif lintfilename in mtimes:\n\t\tif mtime <= mtimes[lintfilename]:\n\t\t\t# The lint script hasn't changed since we last ran this, so we don't have to force\n\t\t\t# lint.\n\t\t\tforcelint = False\n\n\t# Store the linter's mtime for future runs.\n\tmtimes[lintfilename] = mtime\n\n\t#\n\t# Get all of the \"built\" filenames in this project.\n\t\n\t# The \"Compile sources\" phase files\n\tfilenames = project.get_built_sources()\n\t\n\t# The \"Copy headers\" phase files\n\tfilenames = filenames + project.get_built_headers()\n\t\n\t# Iterate through and lint each of the files that have been modified since we last ran\n\t# the linter, unless we're forcelinting, in which case we lint everything.\n\tfor filename in filenames:\n\t\tmtime = os.path.getmtime(filename)\n\t\t\n\t\t# If the filename isn't in the lint data, we have no idea when it was last modified so\n\t\t# we'll run the linter anyway.\n\t\tif not forcelint and filename in mtimes:\n\t\t\t# Is it older or unchanged?\n\t\t\tif mtime <= mtimes[filename]:\n\t\t\t\t# Yeah, let's skip it then.\n\t\t\t\tcontinue\n\n\t\t# The beef.\n\t\tif lint(filename, options):\n\t\t\t# Only update the last known modification time if there weren't any errors.\n\t\t\tmtimes[filename] = mtime\n\t\telse:\n\t\t\tprint \"If you would like to disable the lint tool, please read the instructions in config.template in the root of the Nimbus project\"\n\t\t\tif filename in mtimes:\n\t\t\t\tdel mtimes[filename]\n\t\n\t# Write out the lint data once we're done with this project. Thanks, pickle!\n\tif tempdir:\n\t\tlintdatfile = open(lintdatpath, 'wb')\n\t\tpickle.dump(mtimes, lintdatfile)\n\n\n# Lint the given filename.\ndef lint(filename, options):\n\tlogger = logging.getLogger()\n\t\n\tf = FilenameFilter()\n\tlogger.addFilter(f)\n\n\t# Set up the warning logger format.\n\tch = logging.StreamHandler()\n\tif 'PROJECT_FILE_PATH' in os.environ:\n\t\tformatter = logging.Formatter(filename+\":%(linenumber)s: warning: \"+relpath(os.getcwd(), filename)+\":%(linenumber)s: %(message)s\")\n\telse:\n\t\tformatter = logging.Formatter(filename+\":%(linenumber)s: %(message)s\")\n\tch.setFormatter(formatter)\n\tlogger.addHandler(ch)\n\n\tfile = open(filename, 'r')\n\tfiledata = file.read()\n\t\n\tdid_lint_cleanly = True\n\t\n\t# Everything is set up now, let's run through the linters!\n\tif not lint_basics(filedata, filename, f, options.delint):\n\t\tdid_lint_cleanly = False\n\n\tlogger.removeFilter(f)\n\tlogger.removeHandler(ch)\n\t\n\treturn did_lint_cleanly\n\t\n\n# Basic lint tests that only look at one line's information.\n# If isdelinting is True, this method will try to fix as many lint issues as it can and then\n# write the results out to disk.\ndef lint_basics(filedata, filename, linenofilter, isdelinting = False):\n\tlogger = logging.getLogger()\n\n\tlines = string.split(filedata, \"\\n\")\n\tlinenofilter.lineno = 1\n\n\tprevline = None\n\t\n\tdid_lint_cleanly = True\n\t\n\tnwarningsfixed = 0\n\tnwarnings = 0\n\tif isdelinting:\n\t\tnewfilelines = []\n\t\n\tfor line in lines:\n\t\t# Check line lengths.\n\t\tif len(line) > 100:\n\t\t\tdid_lint_cleanly = False\n\t\t\tnwarnings = nwarnings + 1\n\t\t\t\n\t\t\t# This is not something we can fix with the delinter.\n\t\t\tif isdelinting:\n\t\t\t\tlogger.error('I don\\'t know how to split this line up.')\n\t\t\telse:\n\t\t\t\tlogger.error('Line length > 100')\n\n\t\t# Check method dividers.\n\t\tif not re.search(r'.h$', filename) and re.search(r'^[-+][ ]*\\([\\w\\s*]+\\)', line):\n\t\t\tif prevline != gdivider and prevline != ' */':\n\t\t\t\tdid_lint_cleanly = False\n\t\t\t\tnwarnings = nwarnings + 1\n\t\t\t\n\t\t\t\t# This is not something we can fix with the delinter.\n\t\t\t\tif isdelinting:\n\t\t\t\t\tif re.match(r'/+', prevline):\n\t\t\t\t\t\tnewfilelines.pop()\n\t\t\t\t\tnewfilelines.append(gdivider)\n\t\t\t\t\tnwarningsfixed = nwarningsfixed + 1\n\t\t\t\telse:\n\t\t\t\t\tlogger.error('This method is missing a correct divider before it')\n\n\t\t# Properties\n\t\tif re.search(r'^@property', line):\n\t\t\tif re.search(r'(NSString|NSArray|NSDictionary|NSSet)[ ]*\\*', line) and not re.search(r'copy|readonly', line):\n\t\t\t\tnwarnings = nwarnings + 1\n\t\t\t\tif isdelinting:\n\t\t\t\t\tline = re.sub(r'\\bretain\\b', r'copy', line)\n\t\t\t\t\tnwarningsfixed = nwarningsfixed + 1\n\t\t\t\telse:\n\t\t\t\t\tdid_lint_cleanly = False\n\t\t\t\t\tlogger.error('Objects that have mutable subclasses, such as NSString, should be copied, not retained')\n\t\t\t\t\n\t\t\tif re.search(r'^@property\\(', line):\n\t\t\t\tnwarnings = nwarnings + 1\n\t\t\t\tif isdelinting:\n\t\t\t\t\tline = line.rstrip(' \\t')\n\t\t\t\t\tnwarningsfixed = nwarningsfixed + 1\n\t\t\t\telse:\n\t\t\t\t\tdid_lint_cleanly = False\n\t\t\t\t\tlogger.error('Must be a space after the @property declarator')\n\n\t\t# Trailing whitespace\n\t\tif re.search('[ \\t]+$', line):\n\t\t\tnwarnings = nwarnings + 1\n\t\t\tif isdelinting:\n\t\t\t\tline = line.rstrip(' \\t')\n\t\t\t\tnwarningsfixed = nwarningsfixed + 1\n\t\t\telse:\n\t\t\t\tdid_lint_cleanly = False\n\t\t\t\tlogger.error('Trailing whitespace')\n\n\t\t# Spaces after logical constructs\n\t\tif re.search('(if|while|for)\\(', line, re.IGNORECASE):\n\t\t\tnwarnings = nwarnings + 1\n\t\t\tif isdelinting:\n\t\t\t\tline = re.sub(r'(if|while|for)\\(', r'\\1 (', line)\n\t\t\t\tnwarningsfixed = nwarningsfixed + 1\n\t\t\telse:\n\t\t\t\tdid_lint_cleanly = False\n\t\t\t\tlogger.error('Missing space after logical construct')\n\n\t\t# Boolean checks against non-boolean objects\n\t\t# This test is really hard to do without knowing the type of the object.\n\t\t#if re.search('[^!]!(?!TTIs|[a-z0-9_.]*\\.is|is|_is|has|_has|\\[|self\\.is|[a-z0-9_]+\\.)[a-z0-9_]+', line, re.IGNORECASE):\n\t\t#\tdid_lint_cleanly = False\n\t\t#\tlogger.error('Use if (nil == value) instead of boolean checks for pointers')\n\n\t\t# Else statements must have one empty line before them\n\t\tif re.search('}[ ]+else', line, re.IGNORECASE) and prevline != '' and not re.search(r'^[ ]*//', prevline):\n\t\t\tnwarnings = nwarnings + 1\n\t\t\tif isdelinting:\n\t\t\t\tnewfilelines.append('')\n\t\t\t\tnwarningsfixed = nwarningsfixed + 1\n\t\t\telse:\n\t\t\t\tdid_lint_cleanly = False\n\t\t\t\tlogger.error('There must be one empty line before an else statement')\n\n\t\t# Copyright statement for Facebook\n\t\tmatch = re.match('\\/\\/ Copyright ([0-9]+-[0-9]+) Facebook', line, re.IGNORECASE)\n\t\tif match:\n\t\t\t(copyrightyears, ) = match.groups()\n\t\t\tif copyrightyears != gcopyrightyears:\n\t\t\t\tnwarnings = nwarnings + 1\n\t\t\t\tif isdelinting:\n\t\t\t\t\tline = re.sub(r'([0-9]+-[0-9]+)', gcopyrightyears, line)\n\t\t\t\t\tnwarningsfixed = nwarningsfixed + 1\n\t\t\t\telse:\n\t\t\t\t\tdid_lint_cleanly = False\n\t\t\t\t\tlogger.error('The copyright statement on this file is outdated. Should be 2009-2011')\n\n\t\tif isdelinting:\n\t\t\tnewfilelines.append(line)\n\n\t\tprevline = line\n\t\tlinenofilter.lineno = linenofilter.lineno + 1\n\n\tif isdelinting and nwarnings > 0:\n\t\tnewfiledata = '\\n'.join(newfilelines)\n\t\tfile = open(filename, 'w')\n\t\tfile.write(newfiledata)\n\n\treturn did_lint_cleanly\n\nif __name__ == \"__main__\":\n\tsys.exit(main())\n"
  },
  {
    "path": "scripts/nimbus",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\"\"\"\nnimbus\n\nMost of the documentation is found in the ios module.\n\nBranched from Three20's ttmodule script 2011-06-07.\nCreated by Jeff Verkoeyen on 2010-10-18.\nCopyright 2011 Jeff Verkoeyen\nCopyright 2009-2010 Facebook\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\"\"\"\n\nimport logging\nimport re\nimport os\nimport sys\nfrom optparse import OptionParser\nimport ios\n\nscript_dir = os.path.dirname(os.path.realpath(__file__))\nsrc_dir = os.path.dirname(script_dir)\n\ndef path_and_target_from_name(name):\n\tparts = name.split(':')\n\tname = parts[0]\n\t\n\tpath = None\n\tsuggested_target = None\n\t\n\tif name:\n\t\tpath = name.strip('\"')\n\n\t\tif re.match('^[^/]+$', path):\n\t\t\t# Not a path, create a path to a Nimbus library\n\t\t\tpath = os.path.join(src_dir, path, path+'.xcodeproj', 'project.pbxproj')\n\n\t\telif not re.match('project\\.pbxproj$', path):\n\t\t\t# Is a path, but doesn't include project.pbxproj\n\t\t\tpath = os.path.join(path, 'project.pbxproj')\n\n\t# Make an educated guess at the target. We can't be certain until after we load the project\n\t# as to whether this target exists.\n\tif len(parts) > 1:\n\t\tsuggested_target = parts[1]\n\n\telif re.match('^[^/]+$', name):\n\t\t# No path information in the name, so let's just assume that the target is the name.\n\t\tsuggested_target = name\n\n\telse:\n\t\t# The name is a path, so split out the xcodeproj's name and use that as the target.\n\t\tresult = re.search('([^/]+)\\.xcodeproj', name)\n\t\tif not result:\n\t\t\tsuggested_target = name\n\n\t\telse:\n\t\t\t(suggested_target, ) = result.groups()\n\n\treturn (path, suggested_target)\n\n# Print the given project's dependencies to stdout.\ndef print_dependencies(name):\n\t(path, target) = path_and_target_from_name(name)\n\tproj = ios.pbxproj.get_pbxproj_by_path(path)\n\tif not proj.is_loaded():\n\t\treturn\n\tprint \"Printing dependencies for the following project:\"\n\tprint str(proj)\n\tprint\n\tprint \"Dependencies for target \\\"\"+target+\"\\\":\"\n\tdependency_names = proj.dependency_names_for_target_name(target)\n\tif dependency_names:\n\t\t[sys.stdout.write(\"\\t\"+x+\"\\n\") for x in dependency_names]\n\ndef get_dependency_projects(dependency_names):\n\tdependency_projects = {}\n\tif not dependency_names:\n\t\treturn dependency_projects\n\n\tfor name in dependency_names:\n\t\t(path, target) = path_and_target_from_name(name)\n\t\t\n\t\tproject = ios.pbxproj.get_pbxproj_by_path(path)\n\t\tdependency_projects[project.uniqueid_for_target(target)] = project\n\t\tproject.set_active_target(target)\n\n\t\tdependency_paths = project.dependency_paths_for_target_name(target)\n\t\tif dependency_paths is None:\n\t\t\tprint \"Failed to get dependencies; it's possible that the given target doesn't exist.\"\n\t\t\tsys.exit(0)\n\n\t\tabsolute_paths = absolute_paths_from_dependency_paths(dependency_paths, project)\n\t\t\n\t\tsubmodules = get_dependency_projects(absolute_paths)\n\t\tfor guid, subprojects in submodules.items():\n\t\t\tdependency_projects[guid] = subprojects\n\n\treturn dependency_projects\n\ndef absolute_path_to_lib_from_project(lib_path, project):\n\tabs_path = lib_path\n\tif not abs_path[0] == '/':\n\t\tbase_project_path = os.path.dirname(os.path.dirname(os.path.realpath(project.path())))\n\t\tabs_path = os.path.join(base_project_path, lib_path)\n\treturn os.path.realpath(os.path.dirname(abs_path))\n\ndef absolute_paths_from_dependency_paths(dependency_paths, project):\n\tif dependency_paths is None:\n\t\tlogging.error(\"Failed to get dependencies.\")\n\t\tsys.exit(0)\n\n\tabsolute_paths = []\n\tfor name in dependency_paths:\n\t\t(path, target) = path_and_target_from_name(name)\n\t\tpath = absolute_path_to_lib_from_project(path, project)\n\t\tabsolute_paths.append(path + ':' + target)\n\t\n\treturn absolute_paths\n\ndef add_modules_to_project(module_names, project, target, configs):\n\tlogging.info(project)\n\tlogging.info(\"Checking dependencies...\")\n\tdependency_paths = project.dependency_paths_for_target_name(target)\n\tabsolute_paths = absolute_paths_from_dependency_paths(dependency_paths, project)\n\n\tif len(absolute_paths) == 0:\n\t\tlogging.info(\"\\tNo dependencies.\")\n\telse:\n\t\tlogging.info(\"Existing dependencies:\")\n\t\t[logging.info(\"\\t\"+x) for x in absolute_paths]\n\n\tmodules = get_dependency_projects(module_names)\n\n\tlogging.info(\"Requested dependency list:\")\n\t[logging.info(str(x)+\"\\n\") for k,x in modules.items()]\n\t\n\tlogging.info(\"Adding dependencies...\")\n\tfailed = []\n\tfor k,v in modules.items():\n\t\tif not project.add_dependency(v):\n\t\t\tfailed.append(k)\n\n\treturn\n\t\n\tif configs:\n\t\tfor config in configs:\n\t\t\tproject.add_header_search_path(config)\n\n\t\t\tproject.add_build_setting(config, 'OTHER_LDFLAGS', '-ObjC')\n\telse:\n\t\tfor configuration in project.configurations:\n\t\t\tproject.add_header_search_path(configuration[1])\n\n\t\t\tfor k,v in modules.items():\n\t\t\t\tproject.add_build_setting(configuration[1], 'OTHER_LDFLAGS', '-ObjC')\n\n\tif len(failed) > 0:\n\t\tlogging.error(\"Some dependencies failed to be added:\")\n\t\t[logging.error(\"\\t\"+str(x)+\"\\n\") for x in failed]\n\ndef action_from_args(args, available_actions):\n\tfor arg in args:\n\t\tif arg.lower() in available_actions:\n\t\t\treturn arg.lower()\n\treturn None\n\ndef remove_actions_from_args(args, available_actions):\n\tpruned_args = []\n\tfor arg in args:\n\t\tif arg.lower() not in available_actions:\n\t\t\tpruned_args.append(arg)\n\treturn pruned_args\n\ndef main():\n\tusage = '''%prog command (options)\n\nNimbus library management.\nEasily add Nimbus libraries to your projects.\n\nVOCABULARY\n\n    library             An iOS static library. A library can be referred to by name if it is\n                        within the nimbus framework. Otherwise, libraries must be referred to by\n                        specifiying the path to the library's pbxproj directory.\n\n    target              A target within a library. Some libraries may have multiple targets.\n                        By default, the library's name is used as the target. If no such target\n                        exists, the first target is used. To specify a target explicitly, use\n                        library:target. For example: NimbusJSON:SBJSON.\n\nCOMMANDS\n\n    add                 Add one or more libraries to the target project.\n\n    list                Show all existing dependencies for the target project.\n\nOPTIONS\n\n    -p \"project path\"   Set the target project's xcodeproj path.\n\n'''\n\tparser = OptionParser(usage = usage)\n\n\tparser.add_option(\"-v\", \"--verbose\", dest=\"verbose\",\n\t                  action=\"store_true\")\n\n\tparser.add_option(\"-p\", \"--project\", dest=\"projects\", action=\"append\")\n\n\tparser.add_option(\"--xcode-version\", dest=\"xcode_version\")\n\t\n\tparser.add_option(\"-c\", \"--config\", dest=\"configs\", action=\"append\")\n\n\t(options, args) = parser.parse_args()\n\n\tif options.verbose:\n\t\tlog_level = logging.INFO\n\telse:\n\t\tlog_level = logging.WARNING\n\n\tlogger = logging.getLogger()\n\tlogger.setLevel(log_level)\n\tch = logging.StreamHandler()\n\tformatter = logging.Formatter(\"%(message)s\")\n\tch.setFormatter(formatter)\n\tlogger.addHandler(ch)\n\n\tavailable_actions = ['add', 'list']\n\t\n\taction = action_from_args(args, available_actions)\n\targs = remove_actions_from_args(args, available_actions)\n\n\tif action == 'list' and options.projects is not None:\n\t\t[print_dependencies(x) for x in options.projects]\n\n\telif action == 'add' and options.projects is not None:\n\t\tif not options.xcode_version:\n\t\t\tf=os.popen(\"xcodebuild -version\")\n\t\t\txcodebuild_version = f.readlines()[0]\n\t\t\tmatch = re.search('Xcode ([a-zA-Z0-9.]+)', xcodebuild_version)\n\t\t\tif match:\n\t\t\t\t(options.xcode_version, ) = match.groups()\n\n\t\tfor name in options.projects:\n\t\t\t(path, target) = path_and_target_from_name(name)\n\t\t\tproject = ios.pbxproj.get_pbxproj_by_path(path, xcode_version = options.xcode_version)\n\t\t\tproject.set_active_target(target)\n\t\t\tadd_modules_to_project(args, project, target, options.configs)\n\telse:\n\t\tparser.print_help()\n\n\tlogger.removeHandler(ch)\n\n\nif __name__ == \"__main__\":\n\tsys.exit(main())\n"
  },
  {
    "path": "scripts/run_unit_test.sh",
    "content": "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n\nexit 0\n\n# Short circuit if the library hasn't changed.\nif [[ ! \"${CONFIGURATION_BUILD_DIR}/${NIMBUS_TARGET_NAME}Tests.octest/${NIMBUS_TARGET_NAME}Tests\" -nt \"${PROJECT_DIR}/../coverage/${NIMBUS_FEATURE_NAME}/index.html\" ]]\nthen\n    exit 0\nfi\n\nmkdir -p \"${PROJECT_DIR}/../coverage\"\nrm -rf \"${PROJECT_DIR}/../coverage/${NIMBUS_FEATURE_NAME}\"\nosascript ../scripts/generate_coverage.applescript \"${CONFIGURATION_TEMP_DIR}/${NIMBUS_TARGET_NAME}.build/\" \"${PROJECT_DIR}/../coverage/${NIMBUS_FEATURE_NAME}\"\n"
  },
  {
    "path": "src/Doxygen.h",
    "content": "//\n// Copyright 2011-2012 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * @mainpage\n *\n * Nimbus is an iOS framework whose feature set grows only as fast as its documentation.\n * \n * By focusing on documentation first and features second, Nimbus accelerates the development\n * process of any application while being easy to use and simple to understand.\n *\n * <h2>Why Use Nimbus?</h2>\n *\n * Nimbus' goal is to provide tools that fill missing gaps in Apple's frameworks. This includes\n * simplifying common tasks, such as @link RGBCOLOR creating RGB colors@endlink, and providing\n * additional features that Apple has not yet or may not implement, such as\n * @link NimbusPhotos photo viewers@endlink.\n *\n * By using Nimbus you will save countless hours of development time. We've found that after a point\n * you won't want to build a project without it.\n *\n * <h2>Navigating the Documentation</h2>\n *\n * There are two primary forms of documentation for Nimbus: autogenerated documentation and\n * community documentation. You are currently reading the autogenerated documentation, which has\n * been generated from the Nimbus source code and focuses on individual Nimbus features.\n *\n * The community documentation is available via the\n * <a href=\"http://wiki.nimbuskit.info/\">Nimbus Wiki</a> and contains articles relevant to broader\n * topics such as installing Xcode docsets and best practices. The community wiki is editable by\n * anyone with a Github account.\n * \n * <h2>Getting Started</h2>\n * \n * - <a href=\"http://wiki.nimbuskit.info/Add-Nimbus-to-your-project\">Add Nimbus to your project</a>.\n * - Learn about Nimbus' features by checking out the Catalog app in the examples folder.\n * - Follow Nimbus' development through its <a href=\"http://docs.nimbuskit.info/Version-History.html\">version history</a>.\n * - See the <a href=\"http://docs.nimbuskit.info/Version-1-0-0.html\">latest API diffs</a>.\n * - Read the <a href=\"http://wiki.nimbuskit.info/Three20-Migration-Guide\">Three20 Migration Guide</a>.\n * - Ask questions and get updates via the <a href=\"http://groups.google.com/group/nimbusios\">Nimbus mailing list</a>.\n * \n * <h2>Nimbus' Development Roadmap</h2>\n * \n * Most of the discussion revolving around Nimbus' roadmap is in the Github issue tracker. In\n * particular, check out the grab bag of tasks that are actively being worked on here:\n * \n * https://github.com/jverkoey/nimbus/issues?milestone=5&sort=created&direction=desc&state=open\n */\n\n/**\n * @defgroup Version-History Version History\n *\n * Presented here are the API diffs for each major release of Nimbus.\n */\n\n/**\n * @defgroup Version-1-2-1 Version 1.2.1 Release\n * @ingroup Version-1-0-0\n *\n * Version 1.2.1 of Nimbus was released on February 21, 2014. This patch version closes some bugs\n * introduced by changes in 1.1.0 and 1.2.0.\n *\n * git log 1.2.0...1.2.1\n *\n * <h2>Misc Notes</h2>\n *\n * - 9 commits went into this release (git log 1.2.0...1.2.1 --pretty=oneline | wc -l)\n * - Commits grouped by feature: git log 1.2.0...1.2.1 --pretty=oneline | cut -d' ' -f 2- | sort\n * - Fixed -Wundef warnings.\n *\n * <h2>Attributed Label</h2>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed a linebreak bug introduced in 1.1.0.\n *\n * <h2>Models</h2>\n *\n * - <span class=\"apiDiffAdded\">Bugfix</span> Restore preexisting designated initializer contracts\n *   for cell objects. Details available on Github:\n *   https://github.com/jverkoey/nimbus/commit/377393af109410f99e6b63e4613cfaa209df7f6f\n *\n * <h2>Paging Scroll View</h2>\n *\n * - Re-added deleted methods as deprecated so that.\n * - Move NIPageView to a separate header and source so that projects can choose not to import a\n *   deprecated class.\n */\n\n/**\n * @defgroup Version-1-2-0 Version 1.2.0 Release\n * @ingroup Version-1-0-0\n *\n * Version 1.2.0 of Nimbus was released on February 15, 2014. This minor version closes out all\n * remaining bugs on Github and adds support for loading table view cells from nibs in table view\n * models (this was meant to go in 1.1.0 and is why this is a minor version bump rather than a\n * patch version).\n *\n * git log 1.1.0...1.2.0\n *\n * <h2>Misc Notes</h2>\n *\n * - 24 commits went into this release.\n * - Commits grouped by feature: git log 1.1.0...1.2.0 --pretty=oneline | cut -d' ' -f 2- | sort\n * - Added support for loading table view cells from nibs with table view models.\n *\n * <h2>Attributed Label</h2>\n *\n * - <span class=\"apiDiffAdded\">Added</span> @link NIAttributedLabel::tailTruncationString tailTruncationString@endlink.\n * - <span class=\"apiDiffAdded\">Added</span> support for iOS 7's intrinsicContentSize.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed an alignment bug introduced in 1.1.0.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Properly apply all label styles when setting plain\n *   text.\n *\n * <h2>CSS</h2>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Use the correct key when working with tableViewCellSeparatorStyle.\n *\n * <h2>Models</h2>\n *\n * - <span class=\"apiDiffAdded\">Added</span> @link NINibCellObject NINibCellObject@endlink protocol\n *   for loading table view cells from nibs.\n *\n * <h2>Network Image</h2>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Now more aggressively discards canceled operations.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Now uses the cropRect in the cache key.\n *\n * <h2>Web Controller</h2>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Now adds the toolbar above the webview so that the\n *   toolbar's border is visible.\n * - <span class=\"apiDiffAdded\">Added</span> @link NIWebController::toolbar toolbar@endlink property\n *   to allow for customizing the toolbar.\n */\n\n/**\n * @defgroup Version-1-1-0 Version 1.1.0 Release\n * @ingroup Version-1-0-0\n *\n * Version 1.1.0 of Nimbus was released on February 14, 2014. This minor release brings Nimbus\n * up-to-date with iOS 7 and drops support for iOS 5 and below. The code has been modernized with\n * new Objective-C syntax and a number of bugs on various components have been resolved.\n *\n * git log 1.0.0...1.1.0\n *\n * from the command line.\n *\n * <h2>Misc Notes</h2>\n *\n * - 400 commits went into this release.\n * - Commits grouped by feature: git log 1.0.0...1.1.0 --pretty=oneline | cut -d' ' -f 2- | sort\n * - iOS 7 support throughout all of the features.\n * - Dropped iOS 5 support.\n * - Massive stylistic changes throughout the codebase.\n * - Added support for loading collection view cells from nibs with collection view models.\n *\n * <h2>Attributed Label</h2>\n *\n * - Exposed the internal NIAttributedLabelLinkAttributeName value for NIAttributedLabel's links\n *   that are attached to its NSAttributedString.\n * - Deprecated self.attributedString in favor of self.attributedText.\n * - Added -invalidateAccessibleElements for resetting the attributed label's accessibility elements\n *   when the position of any of the label's parent views changes.3\n *\n * <h2>Badge</h2>\n *\n * - Supported iOS 7 styling and the new tintColor property.\n *\n * <h2>Collections (New!)</h2>\n *\n * - Similar to [models], this feature allows you to store collection view data source objects in a\n *   model and map those objects to collection view cell classes.\n *\n * <h2>Core</h2>\n *\n * - Pulled NIActions out of [models] into the core for reuse in the [collections] feature.\n * - Added new button utility methods (NIButtonUtilities.h).\n * - Deprecated NILinkedList in favor of NSMutableOrderedSet.\n * - Added NIIsLandscapePhoneOrientation method.\n * - Added NIInvocation* methods for creation NSInvocation objects.\n * - Added NIEdgeInsetsOutsetRect, NICenterX, and NICenterY.\n * - Replaced NSString+Nimbus category methods with C-style methods.\n * - Added CGFloat methods for dealing with 64 bit architectures.\n * - Deprecated boundf/boundi in favor of NIBoundf/NIBoundi.\n * - Added NIStretchableImageFromImage.\n * - [NIMemoryCache] Deprecated willSetObject:withName:previousObject: in favor of\n *   shouldSetObject:withName:previousObject:.\n * - [NIImageMemoryCache] Uses unsigned long longs instead of NSUInteger for storing pixel counts.\n * - [NINavigationAppearance] Deprecated. Please wind down any use of this class.\n * - Added NIIsPhone and NIIsTintColorGloballySupported methods.\n * - Deprecated NIUIPopoverControllerClass and NIUITapGestureRecognizerClass.\n * - Added new iOS 7 compatibility API definitions.\n * - Added nimbus_currentFirstResponder category method to UIResponder for quickly fetching the\n *   current responder.\n *\n * <h2>CSS</h2>\n *\n * - Massive updates to the CSS framework by Max Metral.\n *\n * <h2>Interapp</h2>\n *\n * - Support Chrome vs Safari.\n * - Added Google Maps URLs.\n *\n * <h2>Models</h2>\n *\n * - Improved support for custom cell backgrounds.\n *\n * <h2>Network Image</h2>\n *\n * - Updated to support AFNetworking 2.\n *\n * <h2>Overview</h2>\n *\n * - Updated to work on iOS 7.\n * - Added live inspector tool.\n *\n * <h2>Paging Scroll View</h2>\n *\n * - Consolidated the code.\n * - This feature is deprecated by collection views and will be replaced by a simpler solution in\n *   a future NimbusKit version.\n *\n * <h2>Photos</h2>\n *\n * - Fixed layout issues caused by new features on iOS 7 that were making photos slide in every\n *   direction.\n *\n * <h2>Text Field (New!)</h2>\n *\n * - New feature providing support for customizing the look and feel of UITextField.\n *\n * <h2>Web Controller</h2>\n *\n * - Fixed layout issues caused by new features on iOS 7.\n *\n * <h2>Github Issues Closed</h2>\n *\n * <a href=\"https://github.com/jverkoey/nimbus/pull/313\">313</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/316\">316</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/317\">317</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/320\">320</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/323\">323</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/324\">324</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/335\">335</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/337\">337</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/340\">340</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/341\">341</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/342\">342</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/345\">345</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/348\">348</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/352\">352</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/353\">353</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/356\">356</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/358\">358</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/374\">374</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/376\">376</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/377\">377</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/379\">379</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/383\">383</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/388\">388</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/391\">391</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/393\">393</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/396\">396</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/397\">397</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/405\">405</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/406\">406</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/407\">407</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/410\">410</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/413\">413</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/416\">416</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/417\">417</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/421\">421</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/423\">423</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/426\">426</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/427\">427</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/429\">429</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/431\">431</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/440\">440</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/445\">445</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/446\">446</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/449\">449</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/451\">451</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/464\">464</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/469\">469</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/475\">475</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/477\">477</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/480\">480</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/481\">481</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/482\">482</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/484\">484</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/485\">485</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/486\">486</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/489\">489</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/492\">492</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/494\">494</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/499\">499</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/500\">500</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/501\">501</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/505\">505</a>,\n <a href=\"https://github.com/jverkoey/nimbus/pull/506\">506</a>, and\n <a href=\"https://github.com/jverkoey/nimbus/pull/507\">507</a>.\n */\n\n/**\n * @defgroup Version-1-0-0 Version 1.0.0 Release\n * @ingroup Version-History\n *\n * Version 1.0.0 of Nimbus was released on December 10, 2012. This first major release includes\n * major improvements to the Nimbus documentation formatting, ARC support, and numerous API changes\n * and deprecations.\n *\n * Due to the incredibly large number of changes that have gone into this release we will not be\n * providing the hand-crafted API diffs as per previous versions. You can see a list of all changes\n * by running the command\n *\n * git log 0.9.3-arc...master\n *\n * from the command line.\n *\n * <h2>Notable Changes</h2>\n *\n * <h3>Example Apps</h3>\n *\n * - New Nimbus Catalog sample app demoing a variety of Nimbus' features.\n *\n * <h3>Core</h3>\n *\n * - Snapshot rotation via NISnapshotRotation.\n * - Removed a few category methods in favor of C-style methods.\n *\n * <h3>Attributed Label</h3>\n *\n * - Substantial improvements to the NIAttributedLabel, including inline image support.\n * - Accessibility for NIAttributedLabel links.\n * - Improvements to NIAttributedLabel link interactions.\n * - New method for calculating the size of NSAttributedStrings:\n *   NISizeOfAttributedStringConstrainedToSize.\n *\n * <h3>Badge (New!)</h3>\n *\n * - A new badge feature for creating NIBadgeView views to display notification-style badges.\n *\n * <h3>CSS</h3>\n *\n * - New selectors added to the CSS feature.\n *\n * <h3>Models</h3>\n *\n * - NITableViewActions' interface has changed substantially from 0.9.3. All of the original methods\n *   have been deprecated in favor of an improved syntax. Support for attaching selectors to objects\n *   has been added. Selectors are often much cleaner than blocks when implementing complex actions.\n * - New table view cells.\n * - Standardized dynamic cell height calculation via NICellFactory.\n * - NIMutableTableViewModel :)\n *\n * <h3>Paging Scroll View</h3>\n *\n * - Vertical paging scroll views.\n * - Numerous bug fixes and improvements to the paging scroll view.\n */\n\n/**\n * @defgroup Version-9-3 Version 0.9.3 API Changes\n * @ingroup Version-9-0\n *\n * Version 0.9.3 of Nimbus was released on June 10, 2012. This minor version introduces\n * <a href=\"http://latest.docs.nimbuskit.info/group___model_tools.html\">table view actions and radio groups</a>.\n *\n * <h2>Misc Changes</h2>\n *\n * - Code coverage is no longer automatically generated when the Nimbus targets are built.\n * - Removed the unmaintained \"Getting Started\" example project.\n *\n *\n * <h2>Attributed Label</h2>\n *\n * <h3>NIAttributedLabel</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix <a href=\"https://github.com/jverkoey/nimbus/pull/183\">183</a></span> Don't incorrectly disable user interaction (thanks to <a href=\"http://github.com/SevInf\">SevInf</a>).\n * - <span class=\"apiDiffAdded\">Added</span> <code>[NIAttributedLabel @link NIAttributedLabel::linksHaveUnderlines linksHaveUnderlines@endlink]</code>.\n * - <span class=\"apiDiffBugfix\">Bugfix <a href=\"https://github.com/jverkoey/nimbus/pull/issue\">194</a></span> Don't allow attributed labels with multiple lines to have line break modes other than word wrap.\n *\n *\n * <h2>Core</h2>\n *\n * <h3>NIOperations</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix <a href=\"https://github.com/jverkoey/nimbus/pull/172\">172</a></span> Correctly handle error codes in NINetworkRequestOperation (thanks to <a href=\"http://github.com/Vaseltior\">Vaseltior</a>).\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIOperation.@link NIOperation::didStart didStart@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)operationDidStart</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)didStart</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIOperation.@link NIOperation::didFinish didFinish@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)operationDidFinish</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)didFinish</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIOperation.@link NIOperation::didFailWithError: didFailWithError:@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)operationDidFailWithError:(NSError *)error</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)didFailWithError:(NSError *)error</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIOperation.@link NIOperation::willFinish willFinish@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)operationWillFinish</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)willFinish</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIOperationDelegate.@link NIOperationDelegate::nimbusOperationDidStart: nimbusOperationDidStart:@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)operationDidStart:(NSOperation *)operation</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)nimbusOperationDidStart:(NIOperation *)operation</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIOperationDelegate.@link NIOperationDelegate::nimbusOperationWillFinish: nimbusOperationWillFinish:@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)operationWillFinish:(NSOperation *)operation</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)nimbusOperationWillFinish:(NIOperation *)operation</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIOperationDelegate.@link NIOperationDelegate::nimbusOperationDidFinish: nimbusOperationDidFinish:@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)operationDidFinish:(NSOperation *)operation</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)nimbusOperationDidFinish:(NIOperation *)operation</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIOperationDelegate.@link NIOperationDelegate::nimbusOperationDidFail:withError: nimbusOperationDidStart:@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)operationDidFail:(NSOperation *)operation withError:(NSError *)error</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)nimbusOperationDidFail:(NIOperation *)operation withError:(NSError *)error</tt></td></tr></table>@endhtmlonly\n *\n * <h2>Css</h2>\n *\n * <h3>README</h3>\n *\n * - Fixed the command line statements in the README for setting up Chameleon.\n * - Fixed analyzer warnings in CSSTokenizer.m.\n * - <span class=\"apiDiffAdded\">Added <a href=\"https://github.com/jverkoey/nimbus/pull/192\">192</a></span> Add UIToolbar and UISearchBar CSS theming (thanks to <a href=\"http://github.com/subsymbolic\">subsymbolic</a>).\n * - <span class=\"apiDiffAdded\">Added</span> Add UIActivityIndicatorView CSS theming.\n * - <span class=\"apiDiffAdded\">Added</span> Add UIScrollView and UITableView CSS theming.\n * - <span class=\"apiDiffAdded\">Added</span> Add support for autoresizing masks via the new -ios-autoresizing css property.\n * - <span class=\"apiDiffBugfix\">Bugfix <a href=\"https://github.com/jverkoey/nimbus/issue/185\">185</a></span> Maintain the casing of css property values so that fonts can be loaded correctly.\n *\n *\n * <h2>Launcher</h2>\n *\n * <h3>NILauncherView</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix <a href=\"https://github.com/jverkoey/nimbus/pull/156\">156</a></span> NILauncherView can now be used in interface builder (thanks to <a href=\"http://github.com/onomated\">onomated</a>).\n *\n *\n * <h2>Models</h2>\n *\n * <h3>NIFormCellCatalog</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix <a href=\"https://github.com/jverkoey/nimbus/pull/162\">162</a></span> NILauncherView can now be used in interface builder (thanks to <a href=\"http://github.com/kermitology\">kermitology</a>).\n * - <span class=\"apiDiffAdded\">Added <a href=\"https://github.com/jverkoey/nimbus/pull/155\">155</a></span> Documentation written for heightForObject:atIndexPath:tableView: (thanks to <a href=\"http://github.com/alist\">alist</a>).\n * - <span class=\"apiDiffRemoved\">Removed</span> NIButtonFormElement. Use NITableViewActions instead.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Switch table cells now take into account the image when laying out their labels.\n *\n * <h3>Added NICellCatalog</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> Add @link NITitleCellObject NITitleCellObject@endlink, @link NISubtitleCellObject NISubtitleCellObject@endlink.\n * - <span class=\"apiDiffAdded\">Added</span> Add @link NITextCell NITextCell@endlink, @link NISubtitleCellObject NISubtitleCellObject@endlink.\n *\n * <h3>Added NIRadioGroup</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> Add @link NIRadioGroup NIRadioGroup@endlink.\n *\n * <h3>Added NITableViewActions</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> Add @link NITableViewActions NITableViewActions@endlink.\n *\n *\n * <h2>Network Image</h2>\n *\n * <h3>NINetworkImageView</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>NINetworkImageView.@link NINetworkImageView::networkImageViewDidFailWithError: networkImageViewDidFailWithError:@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)networkImageViewDidFailToLoad:(NSError *)error</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)networkImageViewDidFailWithError:(NSError *)error</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NINetworkImageViewDelegate.@link NINetworkImageViewDelegate::networkImageView:didFailWithError: networkImageView:didFailWithError:@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)networkImageViewDidFailLoad:(NINetworkImageView *)imageView</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)networkImageView:(NINetworkImageView *)imageView didFailWithError:(NSError *)error</tt></td></tr></table>@endhtmlonly\n *\n *\n * <h2>Overview</h2>\n *\n * <h3>NIOverviewMemoryCacheController</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> Add @link NIOverviewMemoryCacheController NIOverviewMemoryCacheController@endlink.\n * - <span class=\"apiDiffAdded\">Added</span> Added an overview page for displaying image cache memory usage.\n *\n *\n * <h2>WebController</h2>\n *\n * <h3>NIWebController</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> NIWebController properly stores display information in the event of a memory warning now.\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/0e839cb7e618a246e3ce56b8ff08c576?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Mia Alexiou</div> \n * <div class=\"github\"><a href=\"http://github.com/subsymbolic\">subsymbolic</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/56d524aa457bb26be5347c9070e92e97?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Samuel Grau</div> \n * <div class=\"github\"><a href=\"http://github.com/Vaseltior\">Vaseltior</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/e5c8353e8b304bcd65b990995131c3d0?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Pierre de La Morinerie</div> \n * <div class=\"github\"><a href=\"http://github.com/kemenaran\">kemenaran</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/05bb8de11fcbea02c10f291a124cd500?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Daniel Lemmon</div> \n * <div class=\"github\"><a href=\"http://github.com/kermitology\">kermitology</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/c104314a899ea33d9f59c8d3f20dc998?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Alexander List</div> \n * <div class=\"github\"><a href=\"http://github.com/alist\">alist</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/9fa531dce22a639fd6167369bf7813dc?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Onome</div> \n * <div class=\"github\"><a href=\"http://github.com/onomated\">onomated</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/3a66f80e7c43cb8217d44a6cf898148d?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Sergej Tatarincev</div> \n * <div class=\"github\"><a href=\"http://github.com/SevInf\">SevInf</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\">\n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Jeff Verkoeyen</div> \n * <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"https://github.com/nimbusios/Doxygen\">Nimbus Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-9-2 Version 0.9.2 API Changes\n * @ingroup Version-9-0\n *\n * Version 0.9.2 of Nimbus was released on February 19, 2012. This minor version fixes various bugs.\n *\n *\n * <h2>Misc Changes</h2>\n *\n * - Code coverage is now generated for the entire Nimbus framework.\n * - <a href=\"http://wiki.nimbuskit.info/Nimbus-Namespacing\">Namespace support</a>.\n *\n * <h2>AttributedLabel</h2>\n *\n * <h3>NIAttributedLabel[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Attributed labels now invalidate the core text object when the frame or bounds changes.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed bug in highlight frame calculation (bug fixed by <a href=\"http://github.com/lipeiqiang\">lipeiqiang</a>).\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed setStrokeColor:range: to use correct ivar (bug fixed by <a href=\"http://github.com/rogchap\">rogchap</a>).\n *\n * <h2>Core</h2>\n *\n * <h3>NIBlocks.h</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIBasicBlock</code> (fixed by <a href=\"http://github.com/gurgeous\">gurgeous</a>)\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>typedef void (^NIBasicBlock)(void)</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>typedef void (^NIBasicBlock)(NIOperation *operation)</tt></td></tr></table>@endhtmlonly\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIErrorBlock</code> (fixed by <a href=\"http://github.com/gurgeous\">gurgeous</a>)\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>typedef void (^NIErrorBlock)(NSError* error)</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>typedef void (^NIErrorBlock)(NIOperation *operation, NSError* error)</tt></td></tr></table>@endhtmlonly\n *\n * <h3>NIDebuggingTools.h</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> NIDASSERT now breaks on the device as well.\n *\n * <h3>NIFoundationMethods.h</h3>\n *\n * - <span class=\"apiDiffRemoved\">Removed</span> NIRectInset (previously deprecated).\n *\n * <h3>NIInMemoryCache.h</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIMemoryCache::@link NIMemoryCache::willSetObject:withName:previousObject: willSetObject:withName:previousObject:@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\"><tt>- (void)willSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject</tt></td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (BOOL)willSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject</tt></td></tr></table>@endhtmlonly\n *\n * <h3>NINonRetainingCollections.m</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> Simplified the various non-retaining collection implementations.\n *\n * <h3>NIOperations.m</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> @link NINetworkRequestOperation::cachePolicy cachePolicy@endlink.\n *\n * <h3>NIPaths.m</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> @link NIPathForCachesResource NIPathForCachesResource@endlink (added by <a href=\"http://github.com/superquadratic\">superquadratic</a>).\n *\n * <h3>UIView.m</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> centerWithin:\n *\n * <h2>CSS</h2>\n *\n * <h3>NIStylesheet</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> @link NIStylesheet::rulesetForClassName: rulesetForClassName:@endlink.\n *\n * <h2>Models</h2>\n *\n * <h3>NICellFactory</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> @link NICell::heightForObject:atIndexPath:tableView: heightForObject:atIndexPath:tableView::@endlink.\n *\n * <h2>NetworkImages</h2>\n *\n * <h3>NINetworkImageView</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> networkImageViewDidLoadImage: when loading images from memory.\n *\n * <h2>PagingScrollView</h2>\n *\n * <h3>NIPagingScrollView[.h]</h3>\n *\n * - <span class=\"apiDiffModified\">Deprecated</span> <code>setCenterPageIndex:animated:</code> deprecated in favor of <code>moveToPageAtIndex:animated:</code>.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Don't ask for pages if the data source is empty (bug fixed by <a href=\"http://github.com/gurgeous\">gurgeous</a>).\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Added initWithCoder to NIPagingScrollView (bug fixed by <a href=\"http://github.com/gurgeous\">gurgeous</a>).\n *\n * <h2>Photos</h2>\n *\n * <h3>NetworkPhotoAlbums</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed bug in the photo album example app where photo requests would not be properly canceled.\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/c28f6b282ad61bff6aa9aba06c62ad66?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Roger Chapman</div> \n * <div class=\"github\"><a href=\"http://github.com/rogchap\">rogchap</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/2ea33a461b2c20894f62958bcd9a4fb2?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Adam Doppelt</div> \n * <div class=\"github\"><a href=\"http://github.com/gurgeous\">gurgeous</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <div class=\"name\">lipeiqiang</div> \n * <div class=\"github\"><a href=\"http://github.com/lipeiqiang\">lipeiqiang</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\">\n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/4366e6b67ae5107e30b1c039353dd100?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">superquadratic</div> \n * <div class=\"github\"><a href=\"http://github.com/superquadratic\">superquadratic</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\">\n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Jeff Verkoeyen</div> \n * <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"https://github.com/nimbusios/Doxygen\">Nimbus Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-9-1 Version 0.9.1 API Changes\n * @ingroup Version-9-0\n *\n * Version 0.9.1 of Nimbus was released on December 5, 2011. This minor version removed ASI and JSONKit from\n * Nimbus as strict dependencies. It is now easier to use other networking features for the networked image\n * view. This release adds the new pagingscrollview feature which the photos feature now uses as a dependency.\n * The processors feature has been renamed to operations and greatly simplified to only provide special-case\n * implementations of operations.\n *\n *\n * <h2>Misc Changes</h2>\n *\n * - Non-PCH audit to ensure that Nimbus compiles when not using a pre-compiled header.\n *\n *\n * <h2>Added Frameworks</h2>\n *\n * - @link NimbusPagingScrollView Paging Scroll View@endlink\n *\n *\n * <h2>Renamed Frameworks</h2>\n *\n * - Processors renamed to @link NimbusOperations Operations@endlink\n *\n *\n * <h2>Attributed Label</h2>\n *\n * <h3>NIAttributedLabel[.h|m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Cleaned up the label implementation and optimized when the text frame is recalculated.\n *\n *\n * <h2>Core</h2>\n *\n * <h3>NIFoundationMethods[.h]</h3>\n *\n * - <span class=\"apiDiffModified\">Deprecated</span> <code>NIRectInset</code> deprecated in favor of <code>UIEdgeInsetsInsetRect</code>.\n *\n * <h3>NIInMemoryCache[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Memory leak in <code>NIMemoryCache</code> when removeAllObjects was called (bug reported by <a href=\"http://github.com/lada\">lada</a>).\n * - <span class=\"apiDiffBugfix\">Bugfix</span> numberOfPixels is now reset in <code>NIImageMemoryCache</code> when removeAllObjects is called (bug reported by <a href=\"http://github.com/lada\">lada</a>).\n *\n * <h3>Added NIOperations+Subclassing[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> Anonymous category for subclassing NIOperation objects.\n *\n * <h3>NIOperations[.h|m]</h3>\n *\n * - <span class=\"apiDiffRemoved\">Removed</span> <code>NIReadFileFromDiskOperation</code> because NINetworkRequestOperation now implements the same functionality.\n *\n * <h3>Added NIViewRecycler[.h|m]</h3>\n *\n *\n * <h2>CSS</h2>\n *\n * <h3>NIChameleonObserver[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fix assertion bug when using the Chameleon observer the first time.\n *\n *\n * <h2>Models</h2>\n *\n * <h3>NICellFactory[.h|m]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> NICellFactory now implements NITableViewModelDelegate so that you can create a NICellFactory object and set up explicit bindings between objects and cells using <code>[NICellFactory @link NICellFactory::mapObjectClass:toCellClass: mapObjectClass:toCellClass:@endlink]</code>.\n * - <span class=\"apiDiffAdded\">Added</span> NICellObject may be used to create mappings within the model.\n *\n * <h3>NIFormCellCatalog[.h|m]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> NIButtonFormElement may be used to create a button cell in a table view.\n *\n *\n * <h2>Network Image View</h2>\n *\n * <h3>Added NINetworkImageRequest[.h|m]</h3>\n *\n * <h3>NINetworkImageView[.h|m]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> NINetworkImageOperation protocol for creating operations that can be used with the network image view.\n * - <span class=\"apiDiffAdded\">Added</span> <code>[NINetworkImageView @link NINetworkImageView::setNetworkImageOperation:forDisplaySize:contentMode:cropRect: setNetworkImageOperation:forDisplaySize:contentMode:cropRect:@endlink]</code>.\n * - <span class=\"apiDiffRemoved\">Removed</span> <code>NINetworkImageView.@link NINetworkImageView::imageDiskCache imageDiskCache@endlink</code>.\n * - <span class=\"apiDiffRemoved\">Removed</span> <code>NINetworkImageView.@link NINetworkImageView::diskCacheLifetime diskCacheLifetime@endlink</code>.\n * - <span class=\"apiDiffModified\">Modified</span> <code>NINetworkImageView.@link NINetworkImageView::loading loading@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Getter Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">@property (nonatomic, readonly, assign) BOOL isLoading</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>@property (nonatomic, readonly, assign, getter=isLoading) BOOL loading</tt></td></tr></table>@endhtmlonly\n * - Read the article on adding disk caching to your network requests: <a href=\"http://wiki.nimbuskit.info/Network-Disk-Caching\">Network Disk Caching</a>.\n *\n * <h2>Renamed Processors to Operations</h2>\n *\n *\n * <h2>Overview</h2>\n *\n * <h3>NIOverviewSwizzling[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Correctly intercept status bar calls for applications that don't use a navigation controller.\n *\n *\n * <h2>Photos</h2>\n *\n * <h3>NIPhotoAlbumScrollView[.m]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIPhotoAlbumScrollView.@link NIPhotoAlbumScrollView::photoViewBackgroundColor photoViewBackgroundColor@endlink</code> (added by <a href=\"https://github.com/baz\">baz</a>).\n *\n * <h3>NIPhotoScrubberView[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> The initial scrubber thumbnail is now loaded correctly.\n *\n * <h3>NIToolbarPhotoViewController[.h|m]</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIToolbarPhotoViewController.@link NIToolbarPhotoViewController::toolbarIsTranslucent toolbarIsTranslucent@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">@property (nonatomic, readwrite, assign) BOOL showPhotoAlbumBeneathToolbar</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>@property (nonatomic, readwrite, assign, getter=isToolbarTranslucent) BOOL toolbarIsTranslucent</tt></td></tr></table>@endhtmlonly\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>[NetworkPhotoAlbums] Added an example of showing a caption beneath Facebook photos.</h3>\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n * <div class=\"name\">bubnov</div> \n * <div class=\"github\"><a href=\"http://github.com/bubnov\">bubnov</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/c28f6b282ad61bff6aa9aba06c62ad66?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Roger Chapman</div> \n * <div class=\"github\"><a href=\"http://github.com/rogchap\">rogchap</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/87c842e2d3f2b9e87e339cbc86463e8d?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Manu Cornet</div> \n * <div class=\"github\"><a href=\"http://github.com/lmanul\">lmanul</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/56d524aa457bb26be5347c9070e92e97?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Samuel Grau</div> \n * <div class=\"github\"><a href=\"http://github.com/Vaseltior\">Vaseltior</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/2d7becdc5b983d5be55a0a2d28a361c2?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Anthony Lobay</div> \n * <div class=\"github\"><a href=\"http://github.com/TheMadGamer\">TheMadGamer</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/afbdf3579731eb934cd946451b53e0bc?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Mike</div> \n * <div class=\"github\"><a href=\"http://github.com/prime31\">prime31</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\" style=\"padding: 5px;margin: 0 5px;margin-bottom: 20px;border: 1px solid #DDD;background-color: white;float: left;\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/ec5d7ba9c004f79817c76146247e787e?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Basil Shkara</div> \n * <div class=\"github\"><a href=\"http://github.com/baz\">baz</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\">\n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Jeff Verkoeyen</div> \n * <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"https://github.com/nimbusios/Doxygen\">Nimbus Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-9-0 Version 0.9 API Changes\n * @ingroup Version-History\n *\n * Version 0.9.0 of Nimbus was released on October 24, 2011. This major version introduced\n * the new Nimbus @link NimbusCSS CSS@endlink and Chameleon, a new way to rapidly prototype\n * styling your iOS applications using CSS.\n *\n * Watch the Chameleon Youtube video: http://www.youtube.com/watch?v=i_5LbQ8e9BU\n *\n * Read the Chameleon blog post: http://blog.jeffverkoeyen.com/nimbus-chameleon\n *\n *\n * <h2>Added Frameworks</h2>\n *\n * - @link NimbusCSS CSS@endlink\n *\n *\n * <h2>Attributed Label</h2>\n *\n * <h3>NIAttributedLabel[.h|m]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>[NIAttributedLabel @link NIAttributedLabel::removeAllLinks removeAllLinks@endlink]</code> (thanks to <a href=\"http://github.com/hboon\">hboon</a>.)\n *\n *\n * <h2>Core</h2>\n *\n * <h3>NIDataStructures[.h|m]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>[NILinkedList @link NILinkedList::addObjectsFromArray: addObjectsFromArray:@endlink]</code>\n *\n * <h3>NIPreprocessorMacros.h</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>RGBCOLOR</code> and <code>RGBACOLOR</code>\n *\n *\n * <h2>Models</h2>\n *\n * <h3>ModelCatalog</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed a crashing bug due to setting textField.textColor to nil (thanks to <a href=\"http://github.com/lmanul\">lmanul</a>.)\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>CSSDemo [added]</h3>\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n * <div class=\"name\">bubnov</div> \n * <div class=\"github\"><a href=\"http://github.com/bubnov\">bubnov</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/c28f6b282ad61bff6aa9aba06c62ad66?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Roger Chapman</div> \n * <div class=\"github\"><a href=\"http://github.com/rogchap\">rogchap</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/87c842e2d3f2b9e87e339cbc86463e8d?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Manu Cornet</div> \n * <div class=\"github\"><a href=\"http://github.com/lmanul\">lmanul</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\">\n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Jeff Verkoeyen</div> \n * <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n * \n * <div class=\"contributor_profile\">\n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/b0190e056d8b13400d4ae6eba8a7018d?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Hwee-Boon Yar</div> \n * <div class=\"github\"><a href=\"http://github.com/hboon\">hboon</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"https://github.com/nimbusios/Doxygen\">Nimbus Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-8-0 Version 0.8 API Changes\n * @ingroup Version-History\n *\n * Version 0.8.0 of Nimbus was released on September 28, 2011. This major version introduced\n * the new Nimbus @link NimbusAttributedLabel Attributed Label@endlink, an iOS SDK-based\n * solution for styled text built by Roger Chapman (<a href=\"http://github.com/rogchap\">rogchap</a>).\n *\n *  @image html NIAttributedLabelExample1.png \"A mashup of possible label styles\"\n *\n *\n * <h2>Added Frameworks</h2>\n *\n * - @link NimbusAttributedLabel Attributed Label@endlink\n *\n *\n * <h2>Core</h2>\n *\n * <h3>NIFoundationMethods[.h|m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Make boundf and boundi perform consistently for invalid bounds (e.g. max < min).\n *\n * <h3>NINavigationAppearance[.h|m] Added</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NINavigationAppearance NINavigationAppearance@endlink</code> (thanks to <a href=\"http://github.com/baz\">baz</a>.)\n *\n *\n * <h2>Interapp</h2>\n *\n * <h3>NIInterapp[.h|m]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIInterapp::applicationIsInstalledWithScheme: applicationIsInstalledWithScheme:@endlink</code> (thanks to <a href=\"http://github.com/alias1\">alias1</a>.)\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIInterapp::applicationWithScheme: applicationWithScheme:@endlink</code> (thanks to <a href=\"http://github.com/alias1\">alias1</a>.)\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIInterapp::applicationWithScheme:andAppStoreId: applicationWithScheme:andAppStoreId:@endlink</code> (thanks to <a href=\"http://github.com/alias1\">alias1</a>.)\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIInterapp::applicationWithScheme:andPath: applicationWithScheme:andPath:@endlink</code> (thanks to <a href=\"http://github.com/alias1\">alias1</a>.)\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIInterapp::applicationWithScheme:appStoreId:andPath: applicationWithScheme:appStoreId:andPath:@endlink</code> (thanks to <a href=\"http://github.com/alias1\">alias1</a>.)\n *\n *\n * <h2>Models</h2>\n *\n * <h3>NITableViewModel[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed a minor bug related to using nil in Nimbus table view models.\n *\n * <h3>NITableViewModelTests[.m] Added</h3>\n *\n *\n * <h2>Network Image</h2>\n *\n * <h3>NINetworkImageView[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed a bug with redirected image URLs not being cached properly (thanks to <a href=\"http://github.com/aviell\">aviell</a>.)\n *\n * <h3>NITableViewModelTests[.m] Added</h3>\n *\n *\n * <h2>Photos</h2>\n *\n * <h3>NIToolbarPhotoViewController[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed a crashing bug due to sending dealloc at the wrong time (thanks to <a href=\"http://github.com/baz\">baz</a>.)\n *\n *\n * <h2>Web Controller</h2>\n *\n * <h3>NIWebController[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed misc bugs related to web controller action sheets (thanks to <a href=\"http://github.com/bmeurer\">bmeurer</a>.)\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>Basic Attributed Label [added]</h3>\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\" style=\"padding: 5px;margin: 0 5px;margin-bottom: 20px;border: 1px solid #DDD;background-color: white;float: left;\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/c28f6b282ad61bff6aa9aba06c62ad66?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Roger Chapman</div> \n * <div class=\"github\"><a href=\"http://github.com/rogchap\">rogchap</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\" style=\"padding: 5px;margin: 0 5px;margin-bottom: 20px;border: 1px solid #DDD;background-color: white;float: left;\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/a7acedfd4044ad79252e3b062aef25e7?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Glenn Grant</div> \n * <div class=\"github\"><a href=\"http://github.com/alias1\">alias1</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\" style=\"padding: 5px;margin: 0 5px;margin-bottom: 20px;border: 1px solid #DDD;background-color: white;float: left;\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/ca1536c2ef2e263ed2aec69c1d147677?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Aviel Lazar</div> \n * <div class=\"github\"><a href=\"http://github.com/aviell\">aviell</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/22f25c7b3f0f15a6854fae62bbd3482f?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Benedikt Meurer</div> \n * <div class=\"github\"><a href=\"http://github.com/bmeurer\">bmeurer</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\" style=\"padding: 5px;margin: 0 5px;margin-bottom: 20px;border: 1px solid #DDD;background-color: white;float: left;\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/ec5d7ba9c004f79817c76146247e787e?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Basil Shkara</div> \n * <div class=\"github\"><a href=\"http://github.com/baz\">baz</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Jeff Verkoeyen</div> \n * <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"https://github.com/nimbusios/Doxygen\">Nimbus Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-7-0 Version 0.7 API Changes\n * @ingroup Version-History\n *\n * Version 0.7.0 of Nimbus was released on August 19, 2011. This major version introduced the new\n * Nimbus @link NimbusModels Models@endlink, a feature that makes building table views a breeze.\n *\n *\n * <h2>Added Frameworks</h2>\n *\n * - @link NimbusModels Models@endlink\n *\n *\n * <h2>Core</h2>\n *\n * <h3>NICommonMetrics[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NICellContentPadding()</code>\n *\n * <h3>NIInMemoryCache[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIMemoryCache::nameOfLeastRecentlyUsedObject nameOfLeastRecentlyUsedObject@endlink</code> (thanks to <a href=\"http://github.com/candersonmiller\">candersonmiller</a>.)\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIMemoryCache::nameOfMostRecentlyUsedObject nameOfMostRecentlyUsedObject@endlink</code> (thanks to <a href=\"http://github.com/candersonmiller\">candersonmiller</a>.)\n *\n * <h2>WebController</h2>\n *\n * <h3>NIWebController[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIWebController::shouldPresentActionSheet: shouldPresentActionSheet:@endlink</code> (thanks to <a href=\"http://github.com/bmeurer\">bmeurer</a>.)\n * - <span class=\"apiDiffFeature\">Feature</span> \"Copy this URL\" option added to the web controller's action sheet. (thanks to <a href=\"http://github.com/bmeurer\">bmeurer</a>.)\n * - <span class=\"apiDiffFeature\">Feature</span> The current web page's URL is shown in the action sheet title. (thanks to <a href=\"http://github.com/bmeurer\">bmeurer</a>.)\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>Model Catalog [added]</h3>\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/22f25c7b3f0f15a6854fae62bbd3482f?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Benedikt Meurer</div> \n * <div class=\"github\"><a href=\"http://github.com/bmeurer\">bmeurer</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/8d33edcb6695ab66b1e48067e4e3723c?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Anderson Miller</div> \n * <div class=\"github\"><a href=\"http://github.com/candersonmiller\">candersonmiller</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Jeff Verkoeyen</div> \n * <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"https://github.com/nimbusios/Doxygen\">Nimbus Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-6-1 Version 0.6.1 API Changes\n * @ingroup Version-6-0\n *\n * Version 0.6.1 of Nimbus was released on August 8, 2011. This minor version introduced the new\n * Nimbus @link NimbusWebController WebController@endlink, a ported version of Three20's\n * TTWebController.\n *\n *\n * <h2>Added Frameworks</h2>\n *\n * - @link NimbusWebController Nimbus WebController@endlink\n *\n * @image html webcontroller-iphone-example1.png \"Screenshot of a basic web controller on the iPhone\"\n *\n *\n * <h2>Noteworthy Non-API Changes</h2>\n *\n * - Added the Three20 lint tool.\n *   (thanks to <a href=\"http://github.com/rogchap\">rogchap</a>.)\n * - Added migration information from TTWebController to NIWebController.\n *   (thanks to <a href=\"http://github.com/rogchap\">rogchap</a>.)\n * - LICENSE and NOTICE files have been added to the project.\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>Basic Web Controller [added]</h3>\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\" style=\"padding: 5px;margin: 0 5px;margin-bottom: 20px;border: 1px solid #DDD;background-color: white;float: left;\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/c28f6b282ad61bff6aa9aba06c62ad66?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Roger Chapman</div> \n * <div class=\"github\"><a href=\"http://github.com/rogchap\">rogchap</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Jeff Verkoeyen</div> \n * <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/03a8bbdb4e0ca0078241c9b6ab04b906?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">John Wang</div> \n * <div class=\"github\"><a href=\"http://github.com/jwang\">jwang</a></div> \n * </div>\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"https://github.com/nimbusios/Doxygen\">Nimbus Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-6-0 Version 0.6 API Changes\n * @ingroup Version-History\n *\n * Version 0.6.0 of Nimbus was released on August 4, 2011. This major version introduced the new\n * Nimbus @link NimbusInterapp Interapp@endlink, a feature for making it easy to interact with\n * the exposed interfaces of other apps installed on the device.\n *\n *\n * <h2>Minor Releases</h2>\n *\n * - Version @link Version-6-1 0.6.1.0@endlink - Released on August 8, 2011\n *\n *\n * <h2>Added Frameworks</h2>\n *\n * - @link NimbusInterapp Nimbus Interapp@endlink\n *\n *\n * <h2>Noteworthy Non-API Changes</h2>\n *\n * - Xcode 4 sample project have been added\n *   (thanks to <a href=\"http://github.com/rogchap\">rogchap</a>.)\n * - The README and HACKERS files have been updated.\n * - AUTHORS and DONORS have been added to keep track of all the generous contributions to Nimbus.\n * - All Nimbus features have been combined into one Xcode project (one project to rule them all).\n * - Removed the use of the NIMBUS_STATIC_LIBRARY preprocessor macro. This removes the duplication\n *   of all imports throughout the project. I'm now solely recommending that you add Nimbus\n *   directly to your project (instead of as a dependent static library).\n * - Xcode docsets are now available for download. The docsets will automatically update whenever\n *   a new version of Nimbus is released if you subscribe to the RSS feed.\n *\n * @image html docsets1.png \"The new Nimbus Xcode docset allows you to Alt+Click any Nimbus class to get detailed documentation.\"\n *\n * <h2>Subscribing to the Nimbus Docset Feed</h2>\n *\n * Nimbus now provides automatic updates for integrated docsets. To set this up you simply need\n * to add the docset feed URL to Xcode. Follow these basic steps:\n *\n * - Open the Xcode Preferences (Cmd+, while Xcode is focused)\n * - Open the Documentation tab.\n * - Click the plus (+) button to add a new docset feed url.\n * - Paste http://jverkoey.github.com/nimbus/nimbusdocset.atom into the form.\n * - Click Add.\n * - Click the \"Get\" button next to the Nimbus docset.\n * - Wait a bit while the docset downloads...\n * - Voila! You now have the Nimbus documentation built in to Xcode! Try Alt+Clicking some Nimbus\n *   classes and methods to give it a whirl.\n *\n *\n * <h2>Core</h2>\n *\n * <h3>NICommonMetrics[.h]</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIStatusBarBoundsChangeAnimationCurve()</code>\n * <table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">UIViewAnimationCurve NIStatusBarFrameAnimationCurve()</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>UIViewAnimationCurve NIStatusBarBoundsChangeAnimationCurve(void)</tt></td></tr></table>\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIStatusBarBoundsChangeAnimationDuration()</code>\n * <table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">NSTimeInterval NIStatusBarFrameAnimationDuration()</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>NSTimeInterval NIStatusBarBoundsChangeAnimationDuration(void)</tt></td></tr></table>\n *\n * <h3>NIDataStructures[.h]</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>-[NILinkedList @link NILinkedList::count count@endlink]</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Declaration and Type</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">@property (nonatomic, readonly) unsigned long count</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (NSUInteger)count</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>-[NILinkedList @link NILinkedList::firstObject firstObject@endlink]</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">@property (nonatomic, readonly) id firstObject</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (id)firstObject</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>-[NILinkedList @link NILinkedList::lastObject lastObject@endlink]</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">@property (nonatomic, readonly) id lastObject</td></tr>\n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (id)lastObject</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffAdded\">Added</span> <code>+[NILinkedList @link NILinkedList::linkedListWithArray: linkedListWithArray:@endlink]</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>-[NILinkedList @link NILinkedList::initWithArray: initWithArray:@endlink]</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>-[NILinkedList @link NILinkedList::allObjects allObjects@endlink]</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>-[NILinkedList @link NILinkedList::containsObject: containsObject:@endlink]</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>-[NILinkedList @link NILinkedList::description description@endlink]</code>\n *\n * <h3>NIDebuggingTools[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIDebugAssertionsShouldBreak</code>\n *\n * <h3>NIError[.h|m] Added</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NINimbusErrorDomain</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIImageErrorKey</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIImageTooSmall</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NINimbusErrorDomainCode</code>\n *\n * <h3>NIFoundationMethods[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>boundf()</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>boundi()</code>\n *\n * <h3>NIInMemoryCache[.h]</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>-[NIMemoryCache @link NIMemoryCache::containsObjectWithName: containsObjectWithName:@endlink]</code>\n * <table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">- (BOOL)hasObjectWithName:(NSString *)name</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (BOOL)containsObjectWithName:(NSString *)name</tt></td></tr></table>\n *\n *\n * <h2>Network Image</h2>\n *\n * <h3>NIHTTPImageRequest[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed a potential memory leak caused by not releasing the color space when the bitmap failed to be created.\n *\n * <h3>NINetworkImageView[.h]</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>-[NINetworkImageView @link NINetworkImageView::setPathToNetworkImage:forDisplaySize:contentMode:cropRect: setPathToNetworkImage:forDisplaySize:contentMode:cropRect:@endlink]</code>\n * <table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage cropRect:(CGRect)cropRect forDisplaySize:(CGSize)displaySize contentMode:(UIViewContentMode)contentMode</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage forDisplaySize:(CGSize)displaySize contentMode:(UIViewContentMode)contentMode cropRect:(CGRect)cropRect</tt></td></tr></table>\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>Interapp Catalog [added]</h3>\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\" style=\"padding: 5px;margin: 0 5px;margin-bottom: 20px;border: 1px solid #DDD;background-color: white;float: left;\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/c28f6b282ad61bff6aa9aba06c62ad66?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Roger Chapman</div> \n * <div class=\"github\"><a href=\"http://github.com/rogchap\">rogchap</a></div> \n * </div>\n * \n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/261d7ac023a174844c46e5f9f7a096b0?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Avi Itskovich</div> \n * <div class=\"github\"><a href=\"http://github.com/aitskovi\">aitskovi</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n * <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n * <div class=\"name\">Jeff Verkoeyen</div> \n * <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"http://www.stack.nl/~dimitri/doxygen/\">Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-5-0 Version 0.5 API Changes\n * @ingroup Version-History\n *\n * Version 0.5.0 of Nimbus was released on July 29, 2011. This major version introduced the new\n * Nimbus @link NimbusOverview Overview@endlink, a debugging tool that shows detailed information\n * about the state of your device and application in the device's status bar area.\n *\n * @image html overview1.png \"The Overview added to the network photo album app.\"\n *\n *\n * <h2>Added Frameworks</h2>\n *\n * - @link NimbusOverview Nimbus Overview@endlink\n *\n *\n * <h2>Core</h2>\n *\n * <h3>NICommonMetrics[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIStatusBarFrameAnimationCurve()</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIStatusBarFrameAnimationDuration()</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIStatusBarHeight()</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIDeviceRotationDuration()</code>\n *\n * <h3>NIDataStructures[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>[NILinkedList @link NILinkedList::objectEnumerator objectEnumerator@endlink]</code>\n *\n * <h3>NIDeviceOrientation[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIRotateTransformForOrientation()</code>\n *\n *\n * <h2>Network Image</h2>\n *\n * <h3>NINetworkImageView[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Cancel network requests without blocking on the main thread.\n *\n *\n * <h2>Photos</h2>\n *\n * <h3>NIToolbarPhotoViewController[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fix various memory leaks related to not releasing views on dealloc.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fix memory leak when toggling the toolbar mode between a scrubber and buttons.\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>NetworkPhotoAlbums</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fix various memory leaks related to not releasing views on dealloc.\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n *  <div class=\"name\">Jeff Verkoeyen</div> \n *  <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"http://www.stack.nl/~dimitri/doxygen/\">Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-4 Version 0.4 API Changes\n * @ingroup Version-History\n *\n * Version 0.4 of Nimbus was released on July 20, 2011. This major version introduced the new\n * Nimbus @link NimbusPhotos photo viewer@endlink, a high-performance, low memory footprint photo\n * viewer built for the iPhone and iPad. This version of Nimbus also introduced\n * @link NimbusProcessors Processors@endlink and JSONKit.\n *\n * <h2>Minor Releases</h2>\n *\n * - Version @link Version-4-1 0.4.1.0@endlink - Released on July 22, 2011\n *\n *\n * <h2>Added Frameworks</h2>\n *\n * - @link NimbusPhotos Nimbus Photos@endlink\n * - @link NimbusProcessors Nimbus Processors@endlink\n * - JSONKit\n *\n *\n * <h2>Core</h2>\n *\n * <h3>NIBlocks[.h] <span class=\"apiDiffAdded\">Added</span></h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIBasicBlock</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIErrorBlock</code>\n *\n * <h3>NICommonMetrics[.h/m] <span class=\"apiDiffAdded\">Added</span></h3>\n *\n * @link Common-Metrics Common Metrics@endlink\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIToolbarHeightForOrientation()</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIStatusBarAnimationCurve()</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIStatusBarAnimationDuration()</code>\n *\n * <h3>NIDataStructures[.h]</h3>\n *\n * @link Data-Structures Data Structures@endlink\n *\n * - Documentation updated for NILinkedList.\n *\n * <h3>NIDebuggingTools[.h]</h3>\n *\n * @link Debugging-Tools Debugging Tools@endlink\n *\n * - Documentation updated.\n *\n * <h3>NIDeviceOrientation[.h]</h3>\n *\n * @link Device-Orientation Device Orientation@endlink\n *\n * - Documentation updated.\n *\n * <h3>NIInMemoryCache[.h]</h3>\n *\n * - Documentation updated for NIMemoryCache and NIImageMemoryCache.\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIMemoryCache::hasObjectWithName: -[NIMemoryCache hasObjectWithName:]@endlink</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIMemoryCache::dateOfLastAccessWithName: -[NIMemoryCache dateOfLastAccessWithName:]@endlink</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIMemoryCache::didSetObject:withName: -[NIMemoryCache didSetObject:withName:]@endlink</code>\n * - <span class=\"apiDiffBugfix\">Bugfix</span> NIMemoryCache now automatically responds to <code>UIApplicationDidReceiveMemoryWarningNotification</code> notifications.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed infinite loop in NIImageMemoryCache when adding images to an empty cache that was\n *            too small to fit the image.\n *\n * <h3>NIOperations[.h/m] <span class=\"apiDiffAdded\">Added</span></h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIOperation</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIOperationDelegate</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIReadFileFromDiskOperation</code>\n *\n * <h3>NISDKAvailability[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIScreenScale()</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIUITapGestureRecognizerClass()</code>\n *\n * <h3>NIState[.h]</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>+[Nimbus @link Nimbus::imageMemoryCache imageMemoryCache@endlink]</code>\n * <table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">+ (NIImageMemoryCache *)globalImageMemoryCache</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>+ (NIImageMemoryCache *)imageMemoryCache</tt></td></tr></table>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>+[Nimbus @link Nimbus::networkOperationQueue networkOperationQueue@endlink]</code>\n * <table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">+ (NSOperationQueue *)globalNetworkOperationQueue</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>+ (NSOperationQueue *)networkOperationQueue</tt></td></tr></table>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>+[Nimbus @link Nimbus::setImageMemoryCache: setImageMemoryCache:@endlink]</code>\n * <table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">+ (void)setGlobalImageMemoryCache:(NIImageMemoryCache *)imageMemoryCache</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>+ (void)setImageMemoryCache:(NIImageMemoryCache *)imageMemoryCache</tt></td></tr></table>\n *\n * - <span class=\"apiDiffModified\">Modified</span> <code>+[Nimbus @link Nimbus::setNetworkOperationQueue: setNetworkOperationQueue:@endlink]</code>\n * <table class=\"modificationtable\"><tr><th></th><th>Declaration</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">+ (void)setGlobalNetworkOperationQueue:(NSOperationQueue *)queue</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>+ (void)setNetworkOperationQueue:(NSOperationQueue *)queue</tt></td></tr></table>\n *\n *\n * <h2>Network Image</h2>\n *\n * <h3>NIHTTPImageRequest[.h]</h3>\n *\n * - <span class=\"apiDiffRemoved\">Removed</span> <code>NIHTTPImageRequest.cropImageForDisplay</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIHTTPImageRequest::scaleOptions NIHTTPImageRequest.scaleOptions@endlink</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIHTTPImageRequest::interpolationQuality NIHTTPImageRequest.interpolationQuality@endlink</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NIHTTPImageRequest::imageFromSource:withContentMode:cropRect:displaySize:scaleOptions:interpolationQuality: +[NIHTTPImageRequest imageFromSource:withContentMode:cropRect:displaySize:scaleOptions:interpolationQuality:]@endlink</code>\n * - <span class=\"apiDiffFeature\">Feature</span> Better configuration for image scaling and cropping via @link NINetworkImageViewScaleOptions@endlink.\n *\n * <h3>NINetworkImageView[.h]</h3>\n *\n * - <span class=\"apiDiffRemoved\">Removed</span> <code>NINetworkImageView.cropImageForDisplay</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NINetworkImageViewScaleToFitLeavesExcessAndScaleToFillCropsExcess</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NINetworkImageViewScaleToFitCropsExcess</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NINetworkImageViewScaleToFillLeavesExcess</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NINetworkImageView::scaleOptions NINetworkImageView.scaleOptions@endlink</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>@link NINetworkImageView::interpolationQuality NINetworkImageView.interpolationQuality@endlink</code>\n * - <span class=\"apiDiffFeature\">Feature</span> Added support for loading images from disk.\n * - <span class=\"apiDiffFeature\">Feature</span> Better configuration for image scaling and cropping via @link NINetworkImageViewScaleOptions@endlink.\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n *  <div class=\"name\">Jeff Verkoeyen</div> \n *  <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"http://www.stack.nl/~dimitri/doxygen/\">Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-4-1 Version 0.4.1 API Changes\n * @ingroup Version-4\n *\n * Version 0.4.1 of Nimbus was released on July 22, 2011. This minor version introduced the new\n * Nimbus @link NIPhotoScrubberView photo scrubber@endlink, a highly responsive photo\n * scrubber built for the iPhone and iPad and modeled after Apple's own Photos.app's photo\n * scrubber.\n *\n * @image html scrubber1.png \"Screenshot of NIPhotoScrubberView on the iPad.\"\n *\n * <h2>Core</h2>\n *\n * <h3>NICommonMetrics[.h]</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> Fixed incorrect documentation for <code>NIStatusBarAnimationCurve()</code>.\n *\n * <h3>NIDataStructures[.h]</h3>\n *\n * - <span class=\"apiDiffModified\">Modified</span> Added a new documentation section @link Data-Structures Comparison of Data Structures@endlink.\n *\n * <h3>NIInMemoryCache[.m]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed a memory leak in NIMemoryCache.\n *\n *\n * <h2>Photos</h2>\n *\n * <h3>NIPhotoAlbumScrollView[.h]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fixed race condition where loading the thumbnail disabled zooming.\n *   (thanks to <a href=\"http://github.com/steipete\">steipete</a>.)\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIPhotoAlbumScrollView.@link NIPhotoAlbumScrollView::zoomingAboveOriginalSizeIsEnabled zoomingAboveOriginalSizeIsEnabled@endlink</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>- [NIPhotoAlbumScrollView @link NIPhotoAlbumScrollView::setCenterPhotoIndex:animated: setCenterPhotoIndex:animated:@endlink]</code>\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIPhotoAlbumScrollView.@link NIPhotoAlbumScrollView::zoomingIsEnabled zoomingIsEnabled@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Accessor Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">@property (nonatomic, readwrite, assign) BOOL zoomingIsEnabled</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>@property (nonatomic, readwrite, assign, getter=isZoomingEnabled) BOOL zoomingIsEnabled</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIPhotoAlbumScrollView.@link NIPhotoAlbumScrollView::centerPhotoIndex centerPhotoIndex@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Method Name and Access</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">@property (nonatomic, readonly, assign) NSInteger currentCenterPhotoIndex</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>@property (nonatomic, readwrite, assign) NSInteger centerPhotoIndex</tt></td></tr></table>@endhtmlonly\n *\n * <h3>NIPhotoScrollView[.h]</h3>\n *\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Fix thumbnail size calculations for photos that are smaller than the screen so that the thumbnail is placed exactly where the photo will appear.\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIPhotoScrollView.@link NIPhotoScrollView::zoomingAboveOriginalSizeIsEnabled zoomingAboveOriginalSizeIsEnabled@endlink</code>\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIPhotoScrollView.@link NIPhotoScrollView::zoomingIsEnabled zoomingIsEnabled@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Accessor Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">@property (nonatomic, readwrite, assign) BOOL zoomingIsEnabled</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>@property (nonatomic, readwrite, assign, getter=isZoomingEnabled) BOOL zoomingIsEnabled</tt></td></tr></table>@endhtmlonly\n * - <span class=\"apiDiffModified\">Modified</span> <code>NIPhotoScrollView.@link NIPhotoScrollView::doubleTapToZoomIsEnabled doubleTapToZoomIsEnabled@endlink</code>\n * @htmlonly<table class=\"modificationtable\"><tr><th></th><th>Accessor Name</th></tr> \n * <tr><th>From</th><td class='Declaration' scope=\"row\">@property (nonatomic, readwrite, assign, getter=isDoubleTapToZoomIsEnabled) BOOL doubleTapToZoomIsEnabled</td></tr> \n * <tr><th>To</th><td class='Declaration' scope=\"row\"><tt>@property (nonatomic, readwrite, assign, getter=isDoubleTapToZoomEnabled) BOOL doubleTapToZoomIsEnabled</tt></td></tr></table>@endhtmlonly\n *\n *\n * <h3>NIPhotoScrubberView[.h/m] <span class=\"apiDiffAdded\">Added</span></h3>\n *\n *\n * <h3>NIToolbarPhotoViewController[.h]</h3>\n *\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIToolbarPhotoViewController.@link NIToolbarPhotoViewController::scrubberIsEnabled scrubberIsEnabled@endlink</code>\n * - <span class=\"apiDiffAdded\">Added</span> <code>NIToolbarPhotoViewController.@link NIToolbarPhotoViewController::photoScrubberView photoScrubberView@endlink</code>\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>NetworkPhotoAlbums</h3>\n *\n * - <span class=\"apiDiffFeature\">Feature</span> Added Shark Week and Game of Thrones albums to the example application.\n * - <span class=\"apiDiffFeature\">Feature</span> Implemented the photo scrubber data source in the Facebook and Dribbble controllers.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Network requests are no longer duplicated.\n * - <span class=\"apiDiffBugfix\">Bugfix</span> Cancel network requests when the controller is released to avoid crashing.\n *   (thanks to <a href=\"http://github.com/steipete\">steipete</a>.)\n *\n *\n * <h2>Real Live People Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/7adfa1038eb46b001fd5c85a47dffc13?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n *  <div class=\"name\">Peter Steinberger</div> \n *  <div class=\"github\"><a href=\"http://github.com/steipete\">steipete</a></div> \n * </div>\n *\n * <div class=\"contributor_profile\"> \n *  <img width=\"135px\" height=\"135px\" src=\"http://www.gravatar.com/avatar/f3c8603c353afa79b9f1c77f35efd566?s=135&amp;d=http://three20.info/gfx/team/silhouette.gif\" /> \n *  <div class=\"name\">Jeff Verkoeyen</div> \n *  <div class=\"github\"><a href=\"http://github.com/jverkoey\">jverkoey</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n *\n * <h3>Add Your Name to This List</h3>\n *\n * Contributions are highly encouraged! If you have a feature that you feel would fit within the\n * Nimbus framework, feel free to fire off a pull request on GitHub. Bugs may be reported\n * using the issue tracker on GitHub as well.\n *\n * Check out the <a href=\"https://github.com/jverkoey/nimbus/issues?sort=created&direction=desc&state=open&page=1&milestone=5\">tasks grab bag</a>\n * for opportunities to help out.\n *\n * <h2>Robots Involved in this Release</h2>\n *\n * <div class=\"contributor_profile\"> \n *  <div class=\"name\"><a href=\"http://www.stack.nl/~dimitri/doxygen/\">Doxygen</a></div> \n * </div>\n *\n * <div class=\"clearfix\"></div>\n */\n\n/**\n * @defgroup Version-3 Version 0.3\n * @ingroup Version-History\n *\n * <h2>0.3.4 - Monday, July 4, 2011</h2>\n *\n * Add network images to Nimbus.\n *\n * Goal tasks:\n *\n * - Migrate the new TTNetworkImageView object and the network image stack using ASIHTTPRequest\n *   to Nimbus. (+1)\n * - Build an in-memory object cache (+1)\n * - Build an in-memory image cache from the in-memory object cache (+1)\n * - Refactor the core library so that it's easier to jump to headers from source files (+1)\n */\n\n/**\n * @defgroup Version-2 Version 0.2\n * @ingroup Version-History\n *\n * <h2>0.2.1 - Tuesday June 14, 2011</h2>\n *\n * The first feature release of Nimbus.\n *\n * Goal tasks:\n *\n * - Migrate Three20's Launcher to Nimbus (+1)\n */\n\n/**\n * @defgroup Version-1 Version 0.1\n * @ingroup Version-History\n *\n * <h2>0.1.4 - Friday June 10, 2011</h2>\n *\n * The first public release of Nimbus.\n *\n * Goal tasks for this release:\n * \n * Migrate the following from Three20:\n *\n * - Global core methods (+1)\n * - Debugging tools (+1)\n * - Availability (+1)\n * - Additions (+1)\n */\n"
  },
  {
    "path": "src/Nimbus.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\t443589C8155190B300757E50 /* UISearchBar+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 443589BF1551909D00757E50 /* UISearchBar+NIStyleable.h */; };\n\t\t443589C9155190CA00757E50 /* UIToolbar+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 443589C11551909E00757E50 /* UIToolbar+NIStyleable.h */; };\n\t\t443589CA1551914400757E50 /* UISearchBar+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 443589C01551909D00757E50 /* UISearchBar+NIStyleable.m */; };\n\t\t443589CB1551914800757E50 /* UIToolbar+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 443589C21551909E00757E50 /* UIToolbar+NIStyleable.m */; };\n\t\t6607851C14D245BF00FE3283 /* NINetworkActivityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6607851B14D245BE00FE3283 /* NINetworkActivityTests.m */; };\n\t\t6607852014D33EAA00FE3283 /* NIStateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6607851F14D33EA900FE3283 /* NIStateTests.m */; };\n\t\t6613332F15D2E23900369333 /* NSMutableAttributedString+NimbusAttributedLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6693C2F4158BB8E900950D42 /* NSMutableAttributedString+NimbusAttributedLabel.m */; };\n\t\t6617B01518A90D5D00037E75 /* NIImageResponseSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 6617B01318A90D5D00037E75 /* NIImageResponseSerializer.h */; };\n\t\t6617B01618A90D5D00037E75 /* NIImageResponseSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617B01418A90D5D00037E75 /* NIImageResponseSerializer.m */; };\n\t\t6617FD0A171F6A92006E0DF8 /* NIActions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6617FD08171F6A92006E0DF8 /* NIActions.h */; };\n\t\t6617FD0B171F6A92006E0DF8 /* NIActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617FD09171F6A92006E0DF8 /* NIActions.m */; };\n\t\t6623EB6D1402ECE400E0E61A /* NITableViewModelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6623EB6C1402ECE400E0E61A /* NITableViewModelTests.m */; };\n\t\t6623EB721402EDB100E0E61A /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t6626330C14995C4600B99898 /* NITableViewModel+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 6626330B14995C4600B99898 /* NITableViewModel+Private.h */; };\n\t\t663B524F1445052800CC26DF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t663B52521445052800CC26DF /* libNimbusPagingScrollView.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 663B523F1445052700CC26DF /* libNimbusPagingScrollView.a */; };\n\t\t663B52671445061B00CC26DF /* NimbusPagingScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 663B52661445061B00CC26DF /* NimbusPagingScrollView.h */; };\n\t\t663B526A1445070100CC26DF /* NIPagingScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 663B52681445070100CC26DF /* NIPagingScrollView.h */; };\n\t\t663B526B1445070100CC26DF /* NIPagingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 663B52691445070100CC26DF /* NIPagingScrollView.m */; };\n\t\t6641617B156B516E0018AC1C /* NITableViewActions.h in Headers */ = {isa = PBXBuildFile; fileRef = 66416179156B516E0018AC1C /* NITableViewActions.h */; };\n\t\t6641617C156B516E0018AC1C /* NITableViewActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6641617A156B516E0018AC1C /* NITableViewActions.m */; };\n\t\t664EFB6215598CDF009826AB /* UIActivityIndicatorView+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 664EFB6015598CDF009826AB /* UIActivityIndicatorView+NIStyleable.h */; };\n\t\t664EFB6315598CDF009826AB /* UIActivityIndicatorView+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 664EFB6115598CDF009826AB /* UIActivityIndicatorView+NIStyleable.m */; };\n\t\t6661BBDC13F1A3BB00D14F92 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t6661BBE013F1A3BB00D14F92 /* libNimbusModels.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6661BBCC13F1A3BB00D14F92 /* libNimbusModels.a */; };\n\t\t6668867F156AD148006E874F /* NICellCatalog.h in Headers */ = {isa = PBXBuildFile; fileRef = 6668867D156AD148006E874F /* NICellCatalog.h */; };\n\t\t66688680156AD148006E874F /* NICellCatalog.m in Sources */ = {isa = PBXBuildFile; fileRef = 6668867E156AD148006E874F /* NICellCatalog.m */; };\n\t\t66688688156ADDB3006E874F /* NIRadioGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 66688686156ADDB0006E874F /* NIRadioGroup.h */; };\n\t\t66688689156ADDB3006E874F /* NIRadioGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 66688687156ADDB1006E874F /* NIRadioGroup.m */; };\n\t\t666903851561B46900C44A70 /* UITableView+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 666903831561B46900C44A70 /* UITableView+NIStyleable.h */; };\n\t\t666903861561B46900C44A70 /* UITableView+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 666903841561B46900C44A70 /* UITableView+NIStyleable.m */; };\n\t\t666903891561B6A000C44A70 /* UIScrollView+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 666903871561B6A000C44A70 /* UIScrollView+NIStyleable.h */; };\n\t\t6669038A1561B6A000C44A70 /* UIScrollView+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 666903881561B6A000C44A70 /* UIScrollView+NIStyleable.m */; };\n\t\t666C3D1C14D0AB7E00F337D6 /* NIAttributedLabelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 666C3D1B14D0AB7E00F337D6 /* NIAttributedLabelTests.m */; };\n\t\t666C3D1F14D0AC2100F337D6 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 666C3D1E14D0AC2100F337D6 /* CoreText.framework */; };\n\t\t666C3D2014D0AC3800F337D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t666C3D2114D0AC3E00F337D6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t666C3D2314D0AC6C00F337D6 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t666C3D2714D0ACA900F337D6 /* NIInterappTests.m in Resources */ = {isa = PBXBuildFile; fileRef = 666C3D2614D0ACA900F337D6 /* NIInterappTests.m */; };\n\t\t666C3D2B14D0ACD900F337D6 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t666C3D2F14D0ADF800F337D6 /* NIInterappTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 666C3D2614D0ACA900F337D6 /* NIInterappTests.m */; };\n\t\t666C3D3014D0AE0C00F337D6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t666C3D3114D0AE1100F337D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t666C3D3314D0AE4F00F337D6 /* NILauncherViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 666C3D3214D0AE4F00F337D6 /* NILauncherViewTests.m */; };\n\t\t666C3D3514D0AE7B00F337D6 /* NIPagingScrollViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 666C3D3414D0AE7B00F337D6 /* NIPagingScrollViewTests.m */; };\n\t\t666C3D3714D0AEA300F337D6 /* NIPhotoScrollViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 666C3D3614D0AEA300F337D6 /* NIPhotoScrollViewTests.m */; };\n\t\t666C3D3914D0AEBF00F337D6 /* NIWebControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 666C3D3814D0AEBF00F337D6 /* NIWebControllerTests.m */; };\n\t\t666C3D3D14D0AF0C00F337D6 /* NIOverviewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 666C3D3C14D0AF0C00F337D6 /* NIOverviewTests.m */; };\n\t\t666C3D4014D0AF7200F337D6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t666C3D4114D0AF7C00F337D6 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t666C3D4414D0AF8C00F337D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t666C3D4D14D0B05C00F337D6 /* NINetworkTableViewControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 666C3D4C14D0B05800F337D6 /* NINetworkTableViewControllerTests.m */; };\n\t\t666C3D5014D0B0F200F337D6 /* NINetworkImageViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 666C3D4F14D0B0ED00F337D6 /* NINetworkImageViewTests.m */; };\n\t\t666C3D5114D0B11800F337D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t666C3D5214D0B11B00F337D6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t666C3D5314D0B13F00F337D6 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t666C3D5A14D0B18900F337D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t666C3D5B14D0B18C00F337D6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t666C3D5C14D0B19400F337D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t666C3D5D14D0B19900F337D6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t666C3D6014D0B19F00F337D6 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t666C3D6114D0B1A600F337D6 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t666C3D6214D0B1A600F337D6 /* libNimbusPagingScrollView.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 663B523F1445052700CC26DF /* libNimbusPagingScrollView.a */; };\n\t\t666C3D6714D0B1AF00F337D6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t666C3D6814D0B1B500F337D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t666C3D6B14D0B1C400F337D6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t666C3D6C14D0B1C900F337D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t666C3D6F14D0B1D400F337D6 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t6672DAB515B87E4B00DFE81F /* NICellFactoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6672DAB415B87E4B00DFE81F /* NICellFactoryTests.m */; };\n\t\t6675723913E765BF0076F555 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t6675723D13E765BF0076F555 /* libNimbusOverview.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6675722913E765BF0076F555 /* libNimbusOverview.a */; };\n\t\t6675726313E765F70076F555 /* NIDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675725313E765F70076F555 /* NIDeviceInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675726413E765F70076F555 /* NIDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675725413E765F70076F555 /* NIDeviceInfo.m */; };\n\t\t6675726513E765F70076F555 /* NimbusOverview.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675725513E765F70076F555 /* NimbusOverview.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675726613E765F70076F555 /* NIOverview.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675725613E765F70076F555 /* NIOverview.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675726713E765F70076F555 /* NIOverview.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675725713E765F70076F555 /* NIOverview.m */; };\n\t\t6675726813E765F70076F555 /* NIOverviewGraphView.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675725813E765F70076F555 /* NIOverviewGraphView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675726913E765F70076F555 /* NIOverviewGraphView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675725913E765F70076F555 /* NIOverviewGraphView.m */; };\n\t\t6675726A13E765F70076F555 /* NIOverviewLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675725A13E765F70076F555 /* NIOverviewLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675726B13E765F70076F555 /* NIOverviewLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675725B13E765F70076F555 /* NIOverviewLogger.m */; };\n\t\t6675726C13E765F70076F555 /* NIOverviewPageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675725C13E765F70076F555 /* NIOverviewPageView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675726D13E765F70076F555 /* NIOverviewPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675725D13E765F70076F555 /* NIOverviewPageView.m */; };\n\t\t6675726E13E765F70076F555 /* NIOverviewSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675725E13E765F70076F555 /* NIOverviewSwizzling.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675726F13E765F70076F555 /* NIOverviewSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675725F13E765F70076F555 /* NIOverviewSwizzling.m */; };\n\t\t6675727013E765F70076F555 /* NIOverviewView.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675726013E765F70076F555 /* NIOverviewView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675727113E765F70076F555 /* NIOverviewView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675726113E765F70076F555 /* NIOverviewView.m */; };\n\t\t6675728A13E769150076F555 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t6675728E13E769150076F555 /* libNimbusPhotos.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6675727A13E769150076F555 /* libNimbusPhotos.a */; };\n\t\t667572AE13E7692F0076F555 /* NimbusPhotos.h in Headers */ = {isa = PBXBuildFile; fileRef = 667572A213E7692F0076F555 /* NimbusPhotos.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t667572AF13E7692F0076F555 /* NIPhotoAlbumScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 667572A313E7692F0076F555 /* NIPhotoAlbumScrollView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t667572B013E7692F0076F555 /* NIPhotoAlbumScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 667572A413E7692F0076F555 /* NIPhotoAlbumScrollView.m */; };\n\t\t667572B113E7692F0076F555 /* NIPhotoScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 667572A513E7692F0076F555 /* NIPhotoScrollView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t667572B213E7692F0076F555 /* NIPhotoScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 667572A613E7692F0076F555 /* NIPhotoScrollView.m */; };\n\t\t667572B313E7692F0076F555 /* NIPhotoScrubberView.h in Headers */ = {isa = PBXBuildFile; fileRef = 667572A713E7692F0076F555 /* NIPhotoScrubberView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t667572B413E7692F0076F555 /* NIPhotoScrubberView.m in Sources */ = {isa = PBXBuildFile; fileRef = 667572A813E7692F0076F555 /* NIPhotoScrubberView.m */; };\n\t\t667572B513E7692F0076F555 /* NIToolbarPhotoViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 667572A913E7692F0076F555 /* NIToolbarPhotoViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t667572B613E7692F0076F555 /* NIToolbarPhotoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 667572AA13E7692F0076F555 /* NIToolbarPhotoViewController.m */; };\n\t\t6675732213E771380076F555 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t6675732613E771380076F555 /* libNimbusInterapp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6675731213E771380076F555 /* libNimbusInterapp.a */; };\n\t\t6675733E13E7718B0076F555 /* NIInterapp.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675733B13E7718B0076F555 /* NIInterapp.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675733F13E7718B0076F555 /* NIInterapp.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675733C13E7718B0076F555 /* NIInterapp.m */; };\n\t\t6675734513E773AA0076F555 /* NimbusInterapp.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675734413E773AA0076F555 /* NimbusInterapp.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t6675E4B31455FCC5007D172F /* NIViewRecycler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6675E4B11455FCC5007D172F /* NIViewRecycler.h */; };\n\t\t6675E4B41455FCC5007D172F /* NIViewRecycler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675E4B21455FCC5007D172F /* NIViewRecycler.m */; };\n\t\t6675E4B614560359007D172F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t6675E4B714560372007D172F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t6675E4BC145603DA007D172F /* NIViewRecyclerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675E4B914560397007D172F /* NIViewRecyclerTests.m */; };\n\t\t667A749F13FE20BD009D277D /* NIFormCellCatalog.h in Headers */ = {isa = PBXBuildFile; fileRef = 667A749913FE20BD009D277D /* NIFormCellCatalog.h */; };\n\t\t667A74A013FE20BD009D277D /* NIFormCellCatalog.m in Sources */ = {isa = PBXBuildFile; fileRef = 667A749A13FE20BD009D277D /* NIFormCellCatalog.m */; };\n\t\t667A74A113FE20BD009D277D /* NICellFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 667A749B13FE20BD009D277D /* NICellFactory.h */; };\n\t\t667A74A213FE20BD009D277D /* NICellFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 667A749C13FE20BD009D277D /* NICellFactory.m */; };\n\t\t667DD36B156D78980045ABBB /* NIRadioGroupController.h in Headers */ = {isa = PBXBuildFile; fileRef = 667DD369156D78980045ABBB /* NIRadioGroupController.h */; };\n\t\t667DD36C156D78980045ABBB /* NIRadioGroupController.m in Sources */ = {isa = PBXBuildFile; fileRef = 667DD36A156D78980045ABBB /* NIRadioGroupController.m */; };\n\t\t66832CB9143D681B003E413C /* NimbusCSS.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832CB7143D681B003E413C /* NimbusCSS.h */; };\n\t\t66832CC1143D7883003E413C /* NICSSParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832CC0143D7883003E413C /* NICSSParserTests.m */; };\n\t\t66832CC4143D7898003E413C /* NICSSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832CC2143D7898003E413C /* NICSSParser.h */; };\n\t\t66832CC5143D7898003E413C /* NICSSParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832CC3143D7898003E413C /* NICSSParser.m */; };\n\t\t66832CCC143D7AA4003E413C /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t66832CCE143D7B2C003E413C /* empty-rulesets.css in Resources */ = {isa = PBXBuildFile; fileRef = 66832CCD143D7B2C003E413C /* empty-rulesets.css */; };\n\t\t66832CD0143D7B38003E413C /* empty.css in Resources */ = {isa = PBXBuildFile; fileRef = 66832CCF143D7B38003E413C /* empty.css */; };\n\t\t66832CD2143D833B003E413C /* comments.css in Resources */ = {isa = PBXBuildFile; fileRef = 66832CD1143D833B003E413C /* comments.css */; };\n\t\t66832CD4143D8989003E413C /* rulesets.css in Resources */ = {isa = PBXBuildFile; fileRef = 66832CD3143D8989003E413C /* rulesets.css */; };\n\t\t66832CD6143D8AB7003E413C /* rulesets-overrides.css in Resources */ = {isa = PBXBuildFile; fileRef = 66832CD5143D8AB7003E413C /* rulesets-overrides.css */; };\n\t\t66832CD8143E062C003E413C /* malformed.css in Resources */ = {isa = PBXBuildFile; fileRef = 66832CD7143E062C003E413C /* malformed.css */; };\n\t\t66832CF1143E0AD9003E413C /* CSSTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832CEE143E0AD9003E413C /* CSSTokenizer.m */; };\n\t\t66832CF2143E0AD9003E413C /* CSSTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832CEF143E0AD9003E413C /* CSSTokens.h */; };\n\t\t66832CF3143E0AD9003E413C /* CSSTokens.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832CF0143E0AD9003E413C /* CSSTokens.m */; };\n\t\t66832CF6143E0C35003E413C /* NIStylesheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832CF4143E0C35003E413C /* NIStylesheet.h */; };\n\t\t66832CF7143E0C35003E413C /* NIStylesheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832CF5143E0C35003E413C /* NIStylesheet.m */; };\n\t\t66832CF9143E1C0C003E413C /* NIStylesheetTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832CF8143E1C0C003E413C /* NIStylesheetTests.m */; };\n\t\t66832CFC143E2C0D003E413C /* NIDOM.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832CFA143E2C0D003E413C /* NIDOM.h */; };\n\t\t66832CFD143E2C0D003E413C /* NIDOM.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832CFB143E2C0D003E413C /* NIDOM.m */; };\n\t\t66832CFF143E3294003E413C /* UILabel.css in Resources */ = {isa = PBXBuildFile; fileRef = 66832CFE143E3294003E413C /* UILabel.css */; };\n\t\t66832D03143E38F0003E413C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t66832D04143E39DF003E413C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t66832D07143E3A30003E413C /* NICSSRuleset.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832D05143E3A30003E413C /* NICSSRuleset.h */; };\n\t\t66832D08143E3A30003E413C /* NICSSRuleset.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832D06143E3A30003E413C /* NICSSRuleset.m */; };\n\t\t66832D0A143E3B55003E413C /* NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832D09143E3B55003E413C /* NIStyleable.h */; };\n\t\t66832D0F143E3C32003E413C /* UILabel+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832D0D143E3C32003E413C /* UILabel+NIStyleable.h */; };\n\t\t66832D10143E3C32003E413C /* UILabel+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832D0E143E3C32003E413C /* UILabel+NIStyleable.m */; };\n\t\t66832D1314416368003E413C /* UIView+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832D1114416368003E413C /* UIView+NIStyleable.h */; };\n\t\t66832D1414416368003E413C /* UIView+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832D1214416368003E413C /* UIView+NIStyleable.m */; };\n\t\t66832DA214421B4A003E413C /* UINavigationBar+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832DA014421B4A003E413C /* UINavigationBar+NIStyleable.h */; };\n\t\t66832DA314421B4A003E413C /* UINavigationBar+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832DA114421B4A003E413C /* UINavigationBar+NIStyleable.m */; };\n\t\t66832E0614435071003E413C /* NIChameleonObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 66832E0414435071003E413C /* NIChameleonObserver.h */; };\n\t\t66832E0714435071003E413C /* NIChameleonObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 66832E0514435071003E413C /* NIChameleonObserver.m */; };\n\t\t668EA9BD17206DF70056C8C3 /* NIActions+Subclassing.h in Headers */ = {isa = PBXBuildFile; fileRef = 668EA9BC17206DF70056C8C3 /* NIActions+Subclassing.h */; };\n\t\t668ECDC71455C17200455266 /* NIStylesheetCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 668ECDC51455C17100455266 /* NIStylesheetCache.h */; };\n\t\t668ECDC81455C17200455266 /* NIStylesheetCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 668ECDC61455C17100455266 /* NIStylesheetCache.m */; };\n\t\t669819DB159B927B00C2D3EF /* NISnapshotRotation.h in Headers */ = {isa = PBXBuildFile; fileRef = 669819D9159B927B00C2D3EF /* NISnapshotRotation.h */; };\n\t\t669819DC159B927B00C2D3EF /* NISnapshotRotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 669819DA159B927B00C2D3EF /* NISnapshotRotation.m */; };\n\t\t669F0CFF158000810069B972 /* NIOverviewMemoryCacheController.h in Headers */ = {isa = PBXBuildFile; fileRef = 669F0CFD158000810069B972 /* NIOverviewMemoryCacheController.h */; };\n\t\t669F0D00158000810069B972 /* NIOverviewMemoryCacheController.m in Sources */ = {isa = PBXBuildFile; fileRef = 669F0CFE158000810069B972 /* NIOverviewMemoryCacheController.m */; };\n\t\t66A03C1E13E6E85E00B514F3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t66A03C2313E6E85E00B514F3 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t66A03C7113E6E8D100B514F3 /* NICommonMetrics.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C4113E6E8D100B514F3 /* NICommonMetrics.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C7213E6E8D100B514F3 /* NICommonMetrics.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C4213E6E8D100B514F3 /* NICommonMetrics.m */; };\n\t\t66A03C7513E6E8D100B514F3 /* NIDebuggingTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C4513E6E8D100B514F3 /* NIDebuggingTools.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C7613E6E8D100B514F3 /* NIDebuggingTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C4613E6E8D100B514F3 /* NIDebuggingTools.m */; };\n\t\t66A03C7713E6E8D100B514F3 /* NIDeviceOrientation.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C4713E6E8D100B514F3 /* NIDeviceOrientation.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C7813E6E8D100B514F3 /* NIDeviceOrientation.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C4813E6E8D100B514F3 /* NIDeviceOrientation.m */; };\n\t\t66A03C7913E6E8D100B514F3 /* NIError.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C4913E6E8D100B514F3 /* NIError.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C7A13E6E8D100B514F3 /* NIError.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C4A13E6E8D100B514F3 /* NIError.m */; };\n\t\t66A03C7B13E6E8D100B514F3 /* NIFoundationMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C4B13E6E8D100B514F3 /* NIFoundationMethods.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C7C13E6E8D100B514F3 /* NIFoundationMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C4C13E6E8D100B514F3 /* NIFoundationMethods.m */; };\n\t\t66A03C7D13E6E8D100B514F3 /* NIInMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C4D13E6E8D100B514F3 /* NIInMemoryCache.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C7E13E6E8D100B514F3 /* NIInMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C4E13E6E8D100B514F3 /* NIInMemoryCache.m */; };\n\t\t66A03C7F13E6E8D100B514F3 /* NimbusCore+Additions.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C4F13E6E8D100B514F3 /* NimbusCore+Additions.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C8013E6E8D100B514F3 /* NimbusCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C5013E6E8D100B514F3 /* NimbusCore.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C8113E6E8D100B514F3 /* NINetworkActivity.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C5113E6E8D100B514F3 /* NINetworkActivity.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C8213E6E8D100B514F3 /* NINetworkActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C5213E6E8D100B514F3 /* NINetworkActivity.m */; };\n\t\t66A03C8413E6E8D100B514F3 /* NINonEmptyCollectionTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C5413E6E8D100B514F3 /* NINonEmptyCollectionTesting.m */; };\n\t\t66A03C8513E6E8D100B514F3 /* NINonRetainingCollections.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C5513E6E8D100B514F3 /* NINonRetainingCollections.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C8613E6E8D100B514F3 /* NINonRetainingCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C5613E6E8D100B514F3 /* NINonRetainingCollections.m */; };\n\t\t66A03C8713E6E8D100B514F3 /* NIOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C5713E6E8D100B514F3 /* NIOperations.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C8813E6E8D100B514F3 /* NIOperations.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C5813E6E8D100B514F3 /* NIOperations.m */; };\n\t\t66A03C8913E6E8D100B514F3 /* NIPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C5913E6E8D100B514F3 /* NIPaths.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C8A13E6E8D100B514F3 /* NIPaths.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C5A13E6E8D100B514F3 /* NIPaths.m */; };\n\t\t66A03C8B13E6E8D100B514F3 /* NIPreprocessorMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C5B13E6E8D100B514F3 /* NIPreprocessorMacros.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C8C13E6E8D100B514F3 /* NIRuntimeClassModifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C5C13E6E8D100B514F3 /* NIRuntimeClassModifications.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C8D13E6E8D100B514F3 /* NIRuntimeClassModifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C5D13E6E8D100B514F3 /* NIRuntimeClassModifications.m */; };\n\t\t66A03C8E13E6E8D100B514F3 /* NISDKAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C5E13E6E8D100B514F3 /* NISDKAvailability.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C8F13E6E8D100B514F3 /* NISDKAvailability.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C5F13E6E8D100B514F3 /* NISDKAvailability.m */; };\n\t\t66A03C9013E6E8D100B514F3 /* NIState.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C6013E6E8D100B514F3 /* NIState.h */; settings = {ATTRIBUTES = (); }; };\n\t\t66A03C9113E6E8D100B514F3 /* NIState.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03C6113E6E8D100B514F3 /* NIState.m */; };\n\t\t66A03CAA13E6E90500B514F3 /* NICoreAdditionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03CA013E6E90500B514F3 /* NICoreAdditionTests.m */; };\n\t\t66A03CAC13E6E90500B514F3 /* NIFoundationMethodsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03CA213E6E90500B514F3 /* NIFoundationMethodsTests.m */; };\n\t\t66A03CAD13E6E90500B514F3 /* NIMemoryCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03CA313E6E90500B514F3 /* NIMemoryCacheTests.m */; };\n\t\t66A03CAE13E6E90500B514F3 /* NINonEmptyCollectionTestingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03CA413E6E90500B514F3 /* NINonEmptyCollectionTestingTests.m */; };\n\t\t66A03CAF13E6E90500B514F3 /* NINonRetainingCollectionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03CA513E6E90500B514F3 /* NINonRetainingCollectionsTests.m */; };\n\t\t66A03CB113E6E90500B514F3 /* NIRuntimeClassModificationsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03CA713E6E90500B514F3 /* NIRuntimeClassModificationsTests.m */; };\n\t\t66A03CB213E6E90500B514F3 /* NSDate+UnitTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03CA913E6E90500B514F3 /* NSDate+UnitTesting.m */; };\n\t\t66A03CB413E6EF1F00B514F3 /* nimbus64x64.png in Resources */ = {isa = PBXBuildFile; fileRef = 66A03CB313E6EF1F00B514F3 /* nimbus64x64.png */; };\n\t\t66A03CCF13E6F0EE00B514F3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t66A03CD313E6F0EE00B514F3 /* libNimbusLauncher.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03CBF13E6F0ED00B514F3 /* libNimbusLauncher.a */; };\n\t\t66A03D3713E6F97500B514F3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t66A03D3B13E6F97500B514F3 /* libNimbusNetworkImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03D2713E6F97500B514F3 /* libNimbusNetworkImage.a */; };\n\t\t66A03D5813E6F99400B514F3 /* NimbusNetworkImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03D5213E6F99400B514F3 /* NimbusNetworkImage.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t66A03D5913E6F99400B514F3 /* NINetworkImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03D5313E6F99400B514F3 /* NINetworkImageView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t66A03D5A13E6F99400B514F3 /* NINetworkImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A03D5413E6F99400B514F3 /* NINetworkImageView.m */; };\n\t\t66A0B09A14BD1069003FA413 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t66A0B0A814BD1069003FA413 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t66A0B0A914BD1069003FA413 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t66A0B0AC14BD1069003FA413 /* libNimbusNetworkControllers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A0B09914BD1069003FA413 /* libNimbusNetworkControllers.a */; };\n\t\t66A0B0C214BD1116003FA413 /* NimbusNetworkControllers.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A0B0BF14BD1116003FA413 /* NimbusNetworkControllers.h */; };\n\t\t66A0B0C314BD1116003FA413 /* NINetworkTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A0B0C014BD1116003FA413 /* NINetworkTableViewController.h */; };\n\t\t66A0B0C414BD1116003FA413 /* NINetworkTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66A0B0C114BD1116003FA413 /* NINetworkTableViewController.m */; };\n\t\t66AF0BCA189C1E2700020FEE /* UIResponder+NimbusCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 66AF0BC8189C1E2700020FEE /* UIResponder+NimbusCore.h */; };\n\t\t66AF0BCB189C1E2700020FEE /* UIResponder+NimbusCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 66AF0BC9189C1E2700020FEE /* UIResponder+NimbusCore.m */; };\n\t\t66B10900144C931F004576D1 /* UIButton+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = 66B108FE144C931F004576D1 /* UIButton+NIStyleable.h */; };\n\t\t66B10901144C931F004576D1 /* UIButton+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B108FF144C931F004576D1 /* UIButton+NIStyleable.m */; };\n\t\t66B6710715AA820700FE4AE8 /* NICellBackgrounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 66B6710515AA820700FE4AE8 /* NICellBackgrounds.h */; };\n\t\t66B6710815AA820700FE4AE8 /* NICellBackgrounds.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B6710615AA820700FE4AE8 /* NICellBackgrounds.m */; };\n\t\t66BB4F9815958A5800020EE8 /* NILauncherButtonView.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BB4F8A15958A5800020EE8 /* NILauncherButtonView.h */; };\n\t\t66BB4F9915958A5800020EE8 /* NILauncherButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4F8B15958A5800020EE8 /* NILauncherButtonView.m */; };\n\t\t66BB4F9A15958A5800020EE8 /* NILauncherPageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BB4F8C15958A5800020EE8 /* NILauncherPageView.h */; };\n\t\t66BB4F9B15958A5800020EE8 /* NILauncherPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4F8D15958A5800020EE8 /* NILauncherPageView.m */; };\n\t\t66BB4F9C15958A5800020EE8 /* NILauncherView.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BB4F8E15958A5800020EE8 /* NILauncherView.h */; };\n\t\t66BB4F9D15958A5800020EE8 /* NILauncherView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4F8F15958A5800020EE8 /* NILauncherView.m */; };\n\t\t66BB4F9E15958A5800020EE8 /* NILauncherViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BB4F9015958A5800020EE8 /* NILauncherViewController.h */; };\n\t\t66BB4F9F15958A5800020EE8 /* NILauncherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4F9115958A5800020EE8 /* NILauncherViewController.m */; };\n\t\t66BB4FA015958A5800020EE8 /* NILauncherViewModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BB4F9215958A5800020EE8 /* NILauncherViewModel.h */; };\n\t\t66BB4FA115958A5800020EE8 /* NILauncherViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4F9315958A5800020EE8 /* NILauncherViewModel.m */; };\n\t\t66BB4FA215958A5800020EE8 /* NILauncherViewObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BB4F9415958A5800020EE8 /* NILauncherViewObject.h */; };\n\t\t66BB4FA315958A5800020EE8 /* NILauncherViewObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BB4F9515958A5800020EE8 /* NILauncherViewObject.m */; };\n\t\t66BB4FA415958A5800020EE8 /* NimbusLauncher.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BB4F9615958A5800020EE8 /* NimbusLauncher.h */; };\n\t\t66C113E5147DD0F1003C9AC6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t66C115411486ACE3003C9AC6 /* NIOperations+Subclassing.h in Headers */ = {isa = PBXBuildFile; fileRef = 66C1153F1486ACDD003C9AC6 /* NIOperations+Subclassing.h */; };\n\t\t66C1D83D16B9CE90003E855B /* NIImageUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 66C1D83B16B9CE90003E855B /* NIImageUtilities.h */; };\n\t\t66C1D83E16B9CE90003E855B /* NIImageUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 66C1D83C16B9CE90003E855B /* NIImageUtilities.m */; };\n\t\t66C1D8C116B9ED65003E855B /* NIButtonUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 66C1D8BF16B9ED65003E855B /* NIButtonUtilities.h */; };\n\t\t66C1D8C216B9ED65003E855B /* NIButtonUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 66C1D8C016B9ED65003E855B /* NIButtonUtilities.m */; };\n\t\t66C3A6B1143D61140048542F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t66C3A6B4143D61140048542F /* libNimbusCss.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66C3A6A1143D61130048542F /* libNimbusCss.a */; };\n\t\t66CB9A211654307A00FFB4BF /* NIPagingScrollView+Subclassing.h in Headers */ = {isa = PBXBuildFile; fileRef = 66CB9A201654307A00FFB4BF /* NIPagingScrollView+Subclassing.h */; };\n\t\t66D2E53F15D9432000281511 /* NIMutableTableViewModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 66D2E53D15D9432000281511 /* NIMutableTableViewModel.h */; };\n\t\t66D2E54015D9432000281511 /* NIMutableTableViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 66D2E53E15D9432000281511 /* NIMutableTableViewModel.m */; };\n\t\t66D2E54315D9438D00281511 /* NIMutableTableViewModel+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 66D2E54115D9438D00281511 /* NIMutableTableViewModel+Private.h */; };\n\t\t66D2E54715D9503100281511 /* NIMutableTableViewModelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66D2E54615D9503100281511 /* NIMutableTableViewModelTests.m */; };\n\t\t66D2FDDD1593F3A600B2BEFD /* NIImageProcessing.h in Headers */ = {isa = PBXBuildFile; fileRef = 66D2FDDB1593F3A600B2BEFD /* NIImageProcessing.h */; };\n\t\t66D2FDDE1593F3A600B2BEFD /* NIImageProcessing.m in Sources */ = {isa = PBXBuildFile; fileRef = 66D2FDDC1593F3A600B2BEFD /* NIImageProcessing.m */; };\n\t\t66DCB78B1717755B00205745 /* NICollectionViewActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 66DCB78A1717755B00205745 /* NICollectionViewActions.m */; };\n\t\t66E1CDE0159161ED004DA4A2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t66E1CDEF159161EE004DA4A2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\t66E1CDF0159161EE004DA4A2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t66E1CDF3159161EE004DA4A2 /* libNimbusBadge.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E1CDDF159161ED004DA4A2 /* libNimbusBadge.a */; };\n\t\t66E1CE0615916220004DA4A2 /* NIBadgeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66E1CE0415916220004DA4A2 /* NIBadgeView.m */; };\n\t\t66E8CED214D089E500600592 /* NICommonMetricsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66E8CED114D089E500600592 /* NICommonMetricsTests.m */; };\n\t\t66E8CEE414D08F8200600592 /* NINonEmptyCollectionTesting.h in Headers */ = {isa = PBXBuildFile; fileRef = 66A03C5313E6E8D100B514F3 /* NINonEmptyCollectionTesting.h */; };\n\t\t66F27D55145B7A5F00AFCA08 /* NIPagingScrollViewPage.h in Headers */ = {isa = PBXBuildFile; fileRef = 66F27D53145B7A5F00AFCA08 /* NIPagingScrollViewPage.h */; };\n\t\t66F27D56145B7A5F00AFCA08 /* NIPagingScrollViewPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F27D54145B7A5F00AFCA08 /* NIPagingScrollViewPage.m */; };\n\t\t66F27D60145BA32500AFCA08 /* NIPhotoAlbumScrollViewDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 66F27D5F145BA32500AFCA08 /* NIPhotoAlbumScrollViewDataSource.h */; };\n\t\t66F27D62145BA35C00AFCA08 /* NIPhotoAlbumScrollViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 66F27D61145BA35B00AFCA08 /* NIPhotoAlbumScrollViewDelegate.h */; };\n\t\t66F27D64145BA4E500AFCA08 /* NIPhotoScrollViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 66F27D63145BA4E500AFCA08 /* NIPhotoScrollViewDelegate.h */; };\n\t\t66F27D66145BA56400AFCA08 /* NIPhotoScrollViewPhotoSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 66F27D65145BA56400AFCA08 /* NIPhotoScrollViewPhotoSize.h */; };\n\t\t66FC984B1703F9D7004E8FB8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\t66FC98631703FA51004E8FB8 /* NICollectionViewCellFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 66FC985B1703FA51004E8FB8 /* NICollectionViewCellFactory.m */; };\n\t\t66FC98651703FA51004E8FB8 /* NICollectionViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 66FC98611703FA51004E8FB8 /* NICollectionViewModel.m */; };\n\t\t66FCC634144FB42E0029F1A6 /* includee.css in Resources */ = {isa = PBXBuildFile; fileRef = 66FCC632144FB42E0029F1A6 /* includee.css */; };\n\t\t66FCC635144FB42E0029F1A6 /* includer.css in Resources */ = {isa = PBXBuildFile; fileRef = 66FCC633144FB42E0029F1A6 /* includer.css */; };\n\t\t66FE7D6B13FB83620061B987 /* NimbusModels.h in Headers */ = {isa = PBXBuildFile; fileRef = 66FE7D6413FB83620061B987 /* NimbusModels.h */; };\n\t\t66FE7D6C13FB83620061B987 /* NITableViewModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 66FE7D6513FB83620061B987 /* NITableViewModel.h */; };\n\t\t66FE7D6D13FB83620061B987 /* NITableViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 66FE7D6613FB83620061B987 /* NITableViewModel.m */; };\n\t\t8B4E85A7194629DC005FDD25 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t8B4E85AB19462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85AC19462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85AD19462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85AE19462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85AF19462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85B019462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85B119462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85B219462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85B319462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85B419462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85B519462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85B619462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85B719462A5C005FDD25 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t8B4E85B819462DA6005FDD25 /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AFD018A90CDE00037E75 /* AFHTTPRequestOperation.m */; };\n\t\t8B4E85B919462DB8005FDD25 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AFDF18A90CDE00037E75 /* AFURLResponseSerialization.m */; };\n\t\t8B4E85BA1946303D005FDD25 /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AFDB18A90CDE00037E75 /* AFURLConnectionOperation.m */; };\n\t\t8B4E85BB1946304E005FDD25 /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AFD918A90CDE00037E75 /* AFSecurityPolicy.m */; };\n\t\t8B4E85BD19463074005FDD25 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85BC19463074005FDD25 /* Security.framework */; };\n\t\t8B4E85C919463715005FDD25 /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AFD018A90CDE00037E75 /* AFHTTPRequestOperation.m */; };\n\t\t8B4E85CA1946371D005FDD25 /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AFDB18A90CDE00037E75 /* AFURLConnectionOperation.m */; };\n\t\t8B4E85CB19463721005FDD25 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AFDF18A90CDE00037E75 /* AFURLResponseSerialization.m */; };\n\t\t8B4E85CC19463733005FDD25 /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6617AFD918A90CDE00037E75 /* AFSecurityPolicy.m */; };\n\t\t8B4E85CD1946374B005FDD25 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85BC19463074005FDD25 /* Security.framework */; };\n\t\t8B94F8721946642400A63185 /* NIPagingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 663B52691445070100CC26DF /* NIPagingScrollView.m */; };\n\t\t8B94F8731946643C00A63185 /* NIPagingScrollViewPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F27D54145B7A5F00AFCA08 /* NIPagingScrollViewPage.m */; };\n\t\t8B94F878194664F000A63185 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t8B94F879194664F000A63185 /* libNimbusModels.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6661BBCC13F1A3BB00D14F92 /* libNimbusModels.a */; };\n\t\t8B94F87C194665DF00A63185 /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\t8B94F87D1946662600A63185 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\t8B94F87F1946676B00A63185 /* NIBadgeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B94F87E1946676B00A63185 /* NIBadgeTests.m */; };\n\t\t8BB611A01946891500C851CC /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\t9B22BD991725E75E000FDB01 /* NIMutableCollectionViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B22BD981725E75E000FDB01 /* NIMutableCollectionViewModel.m */; };\n\t\tC743F6EA16D2652F00A933B7 /* NIUserInterfaceString.h in Headers */ = {isa = PBXBuildFile; fileRef = C743F6E816D2652F00A933B7 /* NIUserInterfaceString.h */; };\n\t\tC743F6EB16D2652F00A933B7 /* NIUserInterfaceString.m in Sources */ = {isa = PBXBuildFile; fileRef = C743F6E916D2652F00A933B7 /* NIUserInterfaceString.m */; };\n\t\tC7A8791D16D7348700A0C23F /* NITextField+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = C7A8791B16D7348700A0C23F /* NITextField+NIStyleable.h */; };\n\t\tC7A8791F16D7348C00A0C23F /* NITextField+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A8791C16D7348700A0C23F /* NITextField+NIStyleable.m */; };\n\t\tC7A8792216D7B96200A0C23F /* UITextField+NIStyleable.h in Headers */ = {isa = PBXBuildFile; fileRef = C7A8792016D7B96200A0C23F /* UITextField+NIStyleable.h */; };\n\t\tC7A8792316D7B96200A0C23F /* UITextField+NIStyleable.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A8792116D7B96200A0C23F /* UITextField+NIStyleable.m */; };\n\t\tC7BBC6BA16DDC0DB00833DC9 /* NITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BBC6B816DDC0DB00833DC9 /* NITextField.m */; };\n\t\tC7BBC6FE16DDC0E700833DC9 /* NITextField.h in Headers */ = {isa = PBXBuildFile; fileRef = C7BBC6B716DDC0DB00833DC9 /* NITextField.h */; };\n\t\tC7BBC70416DDC12800833DC9 /* NITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = C7BBC6B816DDC0DB00833DC9 /* NITextField.m */; };\n\t\tC7BBC71116DE66BD00833DC9 /* media-rulesets.css in Resources */ = {isa = PBXBuildFile; fileRef = C7BBC71016DE66BD00833DC9 /* media-rulesets.css */; };\n\t\tD526CF4B18B826A600991F7A /* NICellCatalogTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D526CF4A18B826A600991F7A /* NICellCatalogTests.m */; };\n\t\tD5BCE8AD1D7539A300B6715F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D02143E38F0003E413C /* CoreGraphics.framework */; };\n\t\tD5BCE8AE1D7539A300B6715F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66832D00143E38E6003E413C /* UIKit.framework */; };\n\t\tD5BCE8AF1D7539A300B6715F /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4E85AA19462A5C005FDD25 /* XCTest.framework */; };\n\t\tD5BCE8B01D7539A300B6715F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\tD5BCE8B31D7539A300B6715F /* nimbus64x64.png in Resources */ = {isa = PBXBuildFile; fileRef = 66A03CB313E6EF1F00B514F3 /* nimbus64x64.png */; };\n\t\tD5BCE8BB1D753A1500B6715F /* NimbusCollectionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D5BCE8B91D753A1100B6715F /* NimbusCollectionsTests.m */; };\n\t\tD5BCE8BE1D753B9100B6715F /* libNimbusCollections.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66FC984A1703F9D7004E8FB8 /* libNimbusCollections.a */; };\n\t\tD5BCE8C11D753BCE00B6715F /* libNimbusCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */; };\n\t\tD5BCE8C41D762F1600B6715F /* libNimbusModels.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6661BBCC13F1A3BB00D14F92 /* libNimbusModels.a */; };\n\t\tD5E5929D221246140076B697 /* NIAttributedLabel+Testing.h in Headers */ = {isa = PBXBuildFile; fileRef = D5E59299221245200076B697 /* NIAttributedLabel+Testing.h */; };\n\t\tDB3A231913FD4B8E00614220 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\tDB3A231D13FD4B8E00614220 /* libNimbusAttributedLabel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB3A230913FD4B8E00614220 /* libNimbusAttributedLabel.a */; };\n\t\tDB3A233613FD4BE500614220 /* NIAttributedLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = DB3A233213FD4BE500614220 /* NIAttributedLabel.h */; };\n\t\tDB3A233713FD4BE500614220 /* NIAttributedLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = DB3A233313FD4BE500614220 /* NIAttributedLabel.m */; };\n\t\tDB3A233813FD4BE500614220 /* NimbusAttributedLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = DB3A233413FD4BE500614220 /* NimbusAttributedLabel.h */; };\n\t\tDB84BD8413EFDDCA00DACCFE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66A03C0C13E6E85E00B514F3 /* Foundation.framework */; };\n\t\tDB84BD8813EFDDCA00DACCFE /* libNimbusWebController.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB84BD7413EFDDC900DACCFE /* libNimbusWebController.a */; };\n\t\tDB84BDAC13EFDF5900DACCFE /* NimbusWebController.h in Headers */ = {isa = PBXBuildFile; fileRef = DB84BDA813EFDF5900DACCFE /* NimbusWebController.h */; };\n\t\tDB84BDAD13EFDF5900DACCFE /* NIWebController.h in Headers */ = {isa = PBXBuildFile; fileRef = DB84BDA913EFDF5900DACCFE /* NIWebController.h */; };\n\t\tDB84BDAE13EFDF5900DACCFE /* NIWebController.m in Sources */ = {isa = PBXBuildFile; fileRef = DB84BDAA13EFDF5900DACCFE /* NIWebController.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t663B52501445052800CC26DF /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 663B523E1445052700CC26DF;\n\t\t\tremoteInfo = NimbusPagingScrollView;\n\t\t};\n\t\t664EFAEA15598A07009826AB /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 664EFAE215598A07009826AB /* CSSDemo.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 66832D2014421450003E413C;\n\t\t\tremoteInfo = CSSDemo;\n\t\t};\n\t\t664EFB2015598A5E009826AB /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 664EFB1815598A5E009826AB /* NetworkPhotoAlbum.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 1D6058910D05DD3D006BFB54;\n\t\t\tremoteInfo = NetworkPhotoAlbum;\n\t\t};\n\t\t6661BBDE13F1A3BB00D14F92 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 6661BBCB13F1A3BB00D14F92;\n\t\t\tremoteInfo = NimbusTables;\n\t\t};\n\t\t666C3D2414D0AC7300F337D6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t666C3D2D14D0ACDD00F337D6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t666C3D4214D0AF8000F337D6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t666C3D5414D0B14200F337D6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t666C3D5E14D0B19C00F337D6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t666C3D6314D0B1AA00F337D6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t666C3D6514D0B1AA00F337D6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 663B523E1445052700CC26DF;\n\t\t\tremoteInfo = NimbusPagingScrollView;\n\t\t};\n\t\t666C3D6914D0B1BA00F337D6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t666C3D6D14D0B1CF00F337D6 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t6675723B13E765BF0076F555 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 6675722813E765BF0076F555;\n\t\t\tremoteInfo = NimbusOverview;\n\t\t};\n\t\t6675728C13E769150076F555 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 6675727913E769150076F555;\n\t\t\tremoteInfo = NimbusPhotos;\n\t\t};\n\t\t6675732413E771380076F555 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 6675731113E771380076F555;\n\t\t\tremoteInfo = NimbusInterapp;\n\t\t};\n\t\t66832CCA143D7A92003E413C /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t6693C14C158A648500950D42 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 6693C106158A63E600950D42 /* NimbusCatalog.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 6693C0EB158A63E600950D42;\n\t\t\tremoteInfo = NimbusCatalog;\n\t\t};\n\t\t66A03C2113E6E85E00B514F3 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t66A03CD113E6F0EE00B514F3 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03CBE13E6F0ED00B514F3;\n\t\t\tremoteInfo = NimbusLauncher;\n\t\t};\n\t\t66A03D3913E6F97500B514F3 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03D2613E6F97500B514F3;\n\t\t\tremoteInfo = NimbusNetworkImage;\n\t\t};\n\t\t66A0B0AA14BD1069003FA413 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A0B09814BD1069003FA413;\n\t\t\tremoteInfo = NetworkControllers;\n\t\t};\n\t\t66C3A6B2143D61140048542F /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66C3A6A0143D61130048542F;\n\t\t\tremoteInfo = NimbusCss;\n\t\t};\n\t\t66E1CDF1159161EE004DA4A2 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66E1CDDE159161ED004DA4A2;\n\t\t\tremoteInfo = NimbusBadge;\n\t\t};\n\t\t8B94F874194664D500A63185 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\t8B94F876194664D900A63185 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 6661BBCB13F1A3BB00D14F92;\n\t\t\tremoteInfo = NimbusModels;\n\t\t};\n\t\t8B94F87A194665DB00A63185 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\tD5BCE8BC1D753A7600B6715F /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66FC98491703F9D7004E8FB8;\n\t\t\tremoteInfo = NimbusCollections;\n\t\t};\n\t\tD5BCE8BF1D753BCA00B6715F /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 66A03C0813E6E85E00B514F3;\n\t\t\tremoteInfo = NimbusCore;\n\t\t};\n\t\tD5BCE8C21D762F1200B6715F /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 6661BBCB13F1A3BB00D14F92;\n\t\t\tremoteInfo = NimbusModels;\n\t\t};\n\t\tDB3A231B13FD4B8E00614220 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = DB3A230813FD4B8E00614220;\n\t\t\tremoteInfo = NimbusAttributedLabel;\n\t\t};\n\t\tDB84BD8613EFDDCA00DACCFE /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 66A03BFE13E6E84800B514F3 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = DB84BD7313EFDDC900DACCFE;\n\t\t\tremoteInfo = NimbusWebController;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t66E1CDDD159161ED004DA4A2 /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"include/${PRODUCT_NAME}\";\n\t\t\tdstSubfolderSpec = 16;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66FC98481703F9D7004E8FB8 /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"include/${PRODUCT_NAME}\";\n\t\t\tdstSubfolderSpec = 16;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t443589BF1551909D00757E50 /* UISearchBar+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UISearchBar+NIStyleable.h\"; path = \"css/src/UISearchBar+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\t443589C01551909D00757E50 /* UISearchBar+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UISearchBar+NIStyleable.m\"; path = \"css/src/UISearchBar+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\t443589C11551909E00757E50 /* UIToolbar+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIToolbar+NIStyleable.h\"; path = \"css/src/UIToolbar+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\t443589C21551909E00757E50 /* UIToolbar+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UIToolbar+NIStyleable.m\"; path = \"css/src/UIToolbar+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\t6607851B14D245BE00FE3283 /* NINetworkActivityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NINetworkActivityTests.m; sourceTree = \"<group>\"; };\n\t\t6607851F14D33EA900FE3283 /* NIStateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIStateTests.m; sourceTree = \"<group>\"; };\n\t\t6617AFCF18A90CDE00037E75 /* AFHTTPRequestOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperation.h; sourceTree = \"<group>\"; };\n\t\t6617AFD018A90CDE00037E75 /* AFHTTPRequestOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFHTTPRequestOperation.m; sourceTree = \"<group>\"; };\n\t\t6617AFD118A90CDE00037E75 /* AFHTTPRequestOperationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperationManager.h; sourceTree = \"<group>\"; };\n\t\t6617AFD218A90CDE00037E75 /* AFHTTPRequestOperationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFHTTPRequestOperationManager.m; sourceTree = \"<group>\"; };\n\t\t6617AFD318A90CDE00037E75 /* AFHTTPSessionManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFHTTPSessionManager.h; sourceTree = \"<group>\"; };\n\t\t6617AFD418A90CDE00037E75 /* AFHTTPSessionManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFHTTPSessionManager.m; sourceTree = \"<group>\"; };\n\t\t6617AFD518A90CDE00037E75 /* AFNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFNetworking.h; sourceTree = \"<group>\"; };\n\t\t6617AFD618A90CDE00037E75 /* AFNetworkReachabilityManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFNetworkReachabilityManager.h; sourceTree = \"<group>\"; };\n\t\t6617AFD718A90CDE00037E75 /* AFNetworkReachabilityManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFNetworkReachabilityManager.m; sourceTree = \"<group>\"; };\n\t\t6617AFD818A90CDE00037E75 /* AFSecurityPolicy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFSecurityPolicy.h; sourceTree = \"<group>\"; };\n\t\t6617AFD918A90CDE00037E75 /* AFSecurityPolicy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFSecurityPolicy.m; sourceTree = \"<group>\"; };\n\t\t6617AFDA18A90CDE00037E75 /* AFURLConnectionOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFURLConnectionOperation.h; sourceTree = \"<group>\"; };\n\t\t6617AFDB18A90CDE00037E75 /* AFURLConnectionOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFURLConnectionOperation.m; sourceTree = \"<group>\"; };\n\t\t6617AFDC18A90CDE00037E75 /* AFURLRequestSerialization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFURLRequestSerialization.h; sourceTree = \"<group>\"; };\n\t\t6617AFDD18A90CDE00037E75 /* AFURLRequestSerialization.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFURLRequestSerialization.m; sourceTree = \"<group>\"; };\n\t\t6617AFDE18A90CDE00037E75 /* AFURLResponseSerialization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFURLResponseSerialization.h; sourceTree = \"<group>\"; };\n\t\t6617AFDF18A90CDE00037E75 /* AFURLResponseSerialization.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFURLResponseSerialization.m; sourceTree = \"<group>\"; };\n\t\t6617AFE018A90CDE00037E75 /* AFURLSessionManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFURLSessionManager.h; sourceTree = \"<group>\"; };\n\t\t6617AFE118A90CDE00037E75 /* AFURLSessionManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFURLSessionManager.m; sourceTree = \"<group>\"; };\n\t\t6617B00118A90CFD00037E75 /* AFNetworkActivityIndicatorManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AFNetworkActivityIndicatorManager.h; sourceTree = \"<group>\"; };\n\t\t6617B00218A90CFD00037E75 /* AFNetworkActivityIndicatorManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AFNetworkActivityIndicatorManager.m; sourceTree = \"<group>\"; };\n\t\t6617B00318A90CFD00037E75 /* UIActivityIndicatorView+AFNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"UIActivityIndicatorView+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t6617B00418A90CFD00037E75 /* UIActivityIndicatorView+AFNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = \"UIActivityIndicatorView+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t6617B00518A90CFD00037E75 /* UIAlertView+AFNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"UIAlertView+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t6617B00618A90CFD00037E75 /* UIAlertView+AFNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = \"UIAlertView+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t6617B00718A90CFD00037E75 /* UIButton+AFNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"UIButton+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t6617B00818A90CFD00037E75 /* UIButton+AFNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = \"UIButton+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t6617B00918A90CFD00037E75 /* UIImageView+AFNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"UIImageView+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t6617B00A18A90CFD00037E75 /* UIImageView+AFNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = \"UIImageView+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t6617B00B18A90CFD00037E75 /* UIKit+AFNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"UIKit+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t6617B00C18A90CFD00037E75 /* UIProgressView+AFNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"UIProgressView+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t6617B00D18A90CFD00037E75 /* UIProgressView+AFNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = \"UIProgressView+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t6617B00E18A90CFD00037E75 /* UIWebView+AFNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"UIWebView+AFNetworking.h\"; sourceTree = \"<group>\"; };\n\t\t6617B00F18A90CFD00037E75 /* UIWebView+AFNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = \"UIWebView+AFNetworking.m\"; sourceTree = \"<group>\"; };\n\t\t6617B01318A90D5D00037E75 /* NIImageResponseSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIImageResponseSerializer.h; sourceTree = \"<group>\"; };\n\t\t6617B01418A90D5D00037E75 /* NIImageResponseSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIImageResponseSerializer.m; sourceTree = \"<group>\"; };\n\t\t6617FD08171F6A92006E0DF8 /* NIActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIActions.h; sourceTree = \"<group>\"; };\n\t\t6617FD09171F6A92006E0DF8 /* NIActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIActions.m; sourceTree = \"<group>\"; };\n\t\t661BC070160B95120049E5B7 /* CONTRIBUTING.mdown */ = {isa = PBXFileReference; lastKnownFileType = text; name = CONTRIBUTING.mdown; path = ../CONTRIBUTING.mdown; sourceTree = \"<group>\"; };\n\t\t661F28AA1591B03400D11FC3 /* deps */ = {isa = PBXFileReference; lastKnownFileType = text; name = deps; path = badge/deps; sourceTree = SOURCE_ROOT; };\n\t\t6623EB6C1402ECE400E0E61A /* NITableViewModelTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NITableViewModelTests.m; sourceTree = \"<group>\"; };\n\t\t6626330B14995C4600B99898 /* NITableViewModel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NITableViewModel+Private.h\"; sourceTree = \"<group>\"; };\n\t\t66325D5713EB0302008D6EAD /* README.mdown */ = {isa = PBXFileReference; lastKnownFileType = text; name = README.mdown; path = ../README.mdown; sourceTree = \"<group>\"; };\n\t\t663B523F1445052700CC26DF /* libNimbusPagingScrollView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusPagingScrollView.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t663B524C1445052800CC26DF /* NimbusPagingScrollViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusPagingScrollViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t663B52641445059C00CC26DF /* NimbusPagingScrollViewTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = \"NimbusPagingScrollViewTests-Info.plist\"; path = \"pagingscrollview/unittests/NimbusPagingScrollViewTests-Info.plist\"; sourceTree = SOURCE_ROOT; };\n\t\t663B52651445060000CC26DF /* deps */ = {isa = PBXFileReference; lastKnownFileType = text; name = deps; path = pagingscrollview/deps; sourceTree = SOURCE_ROOT; };\n\t\t663B52661445061B00CC26DF /* NimbusPagingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusPagingScrollView.h; sourceTree = \"<group>\"; };\n\t\t663B52681445070100CC26DF /* NIPagingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPagingScrollView.h; sourceTree = \"<group>\"; };\n\t\t663B52691445070100CC26DF /* NIPagingScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPagingScrollView.m; sourceTree = \"<group>\"; };\n\t\t663B52761445129400CC26DF /* deps */ = {isa = PBXFileReference; lastKnownFileType = text; name = deps; path = photos/deps; sourceTree = SOURCE_ROOT; };\n\t\t663B52E7144675BF00CC26DF /* NimbusOverviewer.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; name = NimbusOverviewer.bundle; path = ../resources/NimbusOverviewer.bundle; sourceTree = \"<group>\"; };\n\t\t66416179156B516E0018AC1C /* NITableViewActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NITableViewActions.h; sourceTree = \"<group>\"; };\n\t\t6641617A156B516E0018AC1C /* NITableViewActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NITableViewActions.m; sourceTree = \"<group>\"; };\n\t\t664EFAE215598A07009826AB /* CSSDemo.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = CSSDemo.xcodeproj; path = ../examples/css/CSSDemo.xcodeproj; sourceTree = \"<group>\"; };\n\t\t664EFB1815598A5E009826AB /* NetworkPhotoAlbum.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = NetworkPhotoAlbum.xcodeproj; path = ../examples/photos/NetworkPhotoAlbums/NetworkPhotoAlbum.xcodeproj; sourceTree = \"<group>\"; };\n\t\t664EFB6015598CDF009826AB /* UIActivityIndicatorView+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIActivityIndicatorView+NIStyleable.h\"; path = \"css/src/UIActivityIndicatorView+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\t664EFB6115598CDF009826AB /* UIActivityIndicatorView+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UIActivityIndicatorView+NIStyleable.m\"; path = \"css/src/UIActivityIndicatorView+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\t6661BAFF13F0AA6000D14F92 /* deps */ = {isa = PBXFileReference; lastKnownFileType = text; name = deps; path = webcontroller/deps; sourceTree = \"<group>\"; };\n\t\t6661BB0813F0B37000D14F92 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = \"<group>\"; };\n\t\t6661BB0A13F0B38D00D14F92 /* NOTICE */ = {isa = PBXFileReference; lastKnownFileType = text; name = NOTICE; path = ../NOTICE; sourceTree = \"<group>\"; };\n\t\t6661BBCC13F1A3BB00D14F92 /* libNimbusModels.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusModels.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6661BBD913F1A3BB00D14F92 /* NimbusModelsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusModelsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6668867D156AD148006E874F /* NICellCatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICellCatalog.h; sourceTree = \"<group>\"; };\n\t\t6668867E156AD148006E874F /* NICellCatalog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICellCatalog.m; sourceTree = \"<group>\"; };\n\t\t66688686156ADDB0006E874F /* NIRadioGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIRadioGroup.h; sourceTree = \"<group>\"; };\n\t\t66688687156ADDB1006E874F /* NIRadioGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIRadioGroup.m; sourceTree = \"<group>\"; };\n\t\t666903831561B46900C44A70 /* UITableView+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UITableView+NIStyleable.h\"; path = \"css/src/UITableView+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\t666903841561B46900C44A70 /* UITableView+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UITableView+NIStyleable.m\"; path = \"css/src/UITableView+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\t666903871561B6A000C44A70 /* UIScrollView+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIScrollView+NIStyleable.h\"; path = \"css/src/UIScrollView+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\t666903881561B6A000C44A70 /* UIScrollView+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UIScrollView+NIStyleable.m\"; path = \"css/src/UIScrollView+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\t666C3D1B14D0AB7E00F337D6 /* NIAttributedLabelTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIAttributedLabelTests.m; sourceTree = \"<group>\"; };\n\t\t666C3D1E14D0AC2100F337D6 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };\n\t\t666C3D2614D0ACA900F337D6 /* NIInterappTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIInterappTests.m; sourceTree = \"<group>\"; };\n\t\t666C3D3214D0AE4F00F337D6 /* NILauncherViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NILauncherViewTests.m; path = launcher/unittests/NILauncherViewTests.m; sourceTree = SOURCE_ROOT; };\n\t\t666C3D3414D0AE7B00F337D6 /* NIPagingScrollViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPagingScrollViewTests.m; sourceTree = \"<group>\"; };\n\t\t666C3D3614D0AEA300F337D6 /* NIPhotoScrollViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPhotoScrollViewTests.m; sourceTree = \"<group>\"; };\n\t\t666C3D3814D0AEBF00F337D6 /* NIWebControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIWebControllerTests.m; sourceTree = \"<group>\"; };\n\t\t666C3D3C14D0AF0C00F337D6 /* NIOverviewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIOverviewTests.m; sourceTree = \"<group>\"; };\n\t\t666C3D4B14D0B05800F337D6 /* NetworkControllersTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = \"NetworkControllersTests-Info.plist\"; path = \"networkcontrollers/unittests/NetworkControllersTests-Info.plist\"; sourceTree = SOURCE_ROOT; };\n\t\t666C3D4C14D0B05800F337D6 /* NINetworkTableViewControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = NINetworkTableViewControllerTests.m; path = networkcontrollers/unittests/NINetworkTableViewControllerTests.m; sourceTree = SOURCE_ROOT; };\n\t\t666C3D4E14D0B0ED00F337D6 /* NimbusNetworkImageTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = \"NimbusNetworkImageTests-Info.plist\"; path = \"networkimage/unittests/NimbusNetworkImageTests-Info.plist\"; sourceTree = SOURCE_ROOT; };\n\t\t666C3D4F14D0B0ED00F337D6 /* NINetworkImageViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = NINetworkImageViewTests.m; path = networkimage/unittests/NINetworkImageViewTests.m; sourceTree = SOURCE_ROOT; };\n\t\t666F73B614BBFFD600D1A32F /* generate_namespace_header */ = {isa = PBXFileReference; lastKnownFileType = text; name = generate_namespace_header; path = ../scripts/generate_namespace_header; sourceTree = \"<group>\"; };\n\t\t6672DAB415B87E4B00DFE81F /* NICellFactoryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICellFactoryTests.m; sourceTree = \"<group>\"; };\n\t\t6675722913E765BF0076F555 /* libNimbusOverview.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusOverview.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6675723613E765BF0076F555 /* NimbusOverviewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusOverviewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6675724F13E765F70076F555 /* deps */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = deps; path = overview/deps; sourceTree = SOURCE_ROOT; };\n\t\t6675725313E765F70076F555 /* NIDeviceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIDeviceInfo.h; sourceTree = \"<group>\"; };\n\t\t6675725413E765F70076F555 /* NIDeviceInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIDeviceInfo.m; sourceTree = \"<group>\"; };\n\t\t6675725513E765F70076F555 /* NimbusOverview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusOverview.h; sourceTree = \"<group>\"; };\n\t\t6675725613E765F70076F555 /* NIOverview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIOverview.h; sourceTree = \"<group>\"; };\n\t\t6675725713E765F70076F555 /* NIOverview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIOverview.m; sourceTree = \"<group>\"; };\n\t\t6675725813E765F70076F555 /* NIOverviewGraphView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIOverviewGraphView.h; sourceTree = \"<group>\"; };\n\t\t6675725913E765F70076F555 /* NIOverviewGraphView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIOverviewGraphView.m; sourceTree = \"<group>\"; };\n\t\t6675725A13E765F70076F555 /* NIOverviewLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIOverviewLogger.h; sourceTree = \"<group>\"; };\n\t\t6675725B13E765F70076F555 /* NIOverviewLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIOverviewLogger.m; sourceTree = \"<group>\"; };\n\t\t6675725C13E765F70076F555 /* NIOverviewPageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIOverviewPageView.h; sourceTree = \"<group>\"; };\n\t\t6675725D13E765F70076F555 /* NIOverviewPageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIOverviewPageView.m; sourceTree = \"<group>\"; };\n\t\t6675725E13E765F70076F555 /* NIOverviewSwizzling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIOverviewSwizzling.h; sourceTree = \"<group>\"; };\n\t\t6675725F13E765F70076F555 /* NIOverviewSwizzling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIOverviewSwizzling.m; sourceTree = \"<group>\"; };\n\t\t6675726013E765F70076F555 /* NIOverviewView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIOverviewView.h; sourceTree = \"<group>\"; };\n\t\t6675726113E765F70076F555 /* NIOverviewView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIOverviewView.m; sourceTree = \"<group>\"; };\n\t\t6675727313E766400076F555 /* NimbusOverviewTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = \"NimbusOverviewTests-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t6675727A13E769150076F555 /* libNimbusPhotos.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusPhotos.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6675728713E769150076F555 /* NimbusPhotosTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusPhotosTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t667572A213E7692F0076F555 /* NimbusPhotos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusPhotos.h; sourceTree = \"<group>\"; };\n\t\t667572A313E7692F0076F555 /* NIPhotoAlbumScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPhotoAlbumScrollView.h; sourceTree = \"<group>\"; };\n\t\t667572A413E7692F0076F555 /* NIPhotoAlbumScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPhotoAlbumScrollView.m; sourceTree = \"<group>\"; };\n\t\t667572A513E7692F0076F555 /* NIPhotoScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPhotoScrollView.h; sourceTree = \"<group>\"; };\n\t\t667572A613E7692F0076F555 /* NIPhotoScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPhotoScrollView.m; sourceTree = \"<group>\"; };\n\t\t667572A713E7692F0076F555 /* NIPhotoScrubberView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPhotoScrubberView.h; sourceTree = \"<group>\"; };\n\t\t667572A813E7692F0076F555 /* NIPhotoScrubberView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPhotoScrubberView.m; sourceTree = \"<group>\"; };\n\t\t667572A913E7692F0076F555 /* NIToolbarPhotoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIToolbarPhotoViewController.h; sourceTree = \"<group>\"; };\n\t\t667572AA13E7692F0076F555 /* NIToolbarPhotoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIToolbarPhotoViewController.m; sourceTree = \"<group>\"; };\n\t\t667572AC13E7692F0076F555 /* NimbusPhotosTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = \"NimbusPhotosTests-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t6675731213E771380076F555 /* libNimbusInterapp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusInterapp.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6675731F13E771380076F555 /* NimbusInterappTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusInterappTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6675733713E7718B0076F555 /* deps */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = deps; path = interapp/deps; sourceTree = SOURCE_ROOT; };\n\t\t6675733B13E7718B0076F555 /* NIInterapp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIInterapp.h; sourceTree = \"<group>\"; };\n\t\t6675733C13E7718B0076F555 /* NIInterapp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIInterapp.m; sourceTree = \"<group>\"; };\n\t\t6675734313E772100076F555 /* NimbusInterappTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = \"NimbusInterappTests-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t6675734413E773AA0076F555 /* NimbusInterapp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusInterapp.h; sourceTree = \"<group>\"; };\n\t\t6675E4B11455FCC5007D172F /* NIViewRecycler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIViewRecycler.h; sourceTree = \"<group>\"; };\n\t\t6675E4B21455FCC5007D172F /* NIViewRecycler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIViewRecycler.m; sourceTree = \"<group>\"; };\n\t\t6675E4B914560397007D172F /* NIViewRecyclerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIViewRecyclerTests.m; sourceTree = \"<group>\"; };\n\t\t667A749913FE20BD009D277D /* NIFormCellCatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIFormCellCatalog.h; sourceTree = \"<group>\"; };\n\t\t667A749A13FE20BD009D277D /* NIFormCellCatalog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIFormCellCatalog.m; sourceTree = \"<group>\"; };\n\t\t667A749B13FE20BD009D277D /* NICellFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICellFactory.h; sourceTree = \"<group>\"; };\n\t\t667A749C13FE20BD009D277D /* NICellFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICellFactory.m; sourceTree = \"<group>\"; };\n\t\t667DD369156D78980045ABBB /* NIRadioGroupController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIRadioGroupController.h; sourceTree = \"<group>\"; };\n\t\t667DD36A156D78980045ABBB /* NIRadioGroupController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIRadioGroupController.m; sourceTree = \"<group>\"; };\n\t\t66832C98143D63D2003E413C /* css.grammar */ = {isa = PBXFileReference; lastKnownFileType = text; name = css.grammar; path = css/grammar/css.grammar; sourceTree = SOURCE_ROOT; };\n\t\t66832CA1143D64CF003E413C /* generate */ = {isa = PBXFileReference; lastKnownFileType = text; name = generate; path = css/grammar/generate; sourceTree = SOURCE_ROOT; };\n\t\t66832CA8143D6642003E413C /* CSSTokenizerPrefix */ = {isa = PBXFileReference; lastKnownFileType = text; name = CSSTokenizerPrefix; path = css/grammar/CSSTokenizerPrefix; sourceTree = SOURCE_ROOT; };\n\t\t66832CA9143D6642003E413C /* CSSTokens.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CSSTokens.cpp; path = css/grammar/CSSTokens.cpp; sourceTree = SOURCE_ROOT; };\n\t\t66832CAA143D6642003E413C /* CSSTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CSSTokens.h; path = css/grammar/CSSTokens.h; sourceTree = SOURCE_ROOT; };\n\t\t66832CB7143D681B003E413C /* NimbusCSS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusCSS.h; path = css/src/NimbusCSS.h; sourceTree = SOURCE_ROOT; };\n\t\t66832CC0143D7883003E413C /* NICSSParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; name = NICSSParserTests.m; path = css/unittests/NICSSParserTests.m; sourceTree = SOURCE_ROOT; tabWidth = 4; };\n\t\t66832CC2143D7898003E413C /* NICSSParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICSSParser.h; path = css/src/NICSSParser.h; sourceTree = SOURCE_ROOT; };\n\t\t66832CC3143D7898003E413C /* NICSSParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICSSParser.m; path = css/src/NICSSParser.m; sourceTree = SOURCE_ROOT; };\n\t\t66832CC9143D7994003E413C /* NimbusCSSTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = \"NimbusCSSTests-Info.plist\"; path = \"css/unittests/NimbusCSSTests-Info.plist\"; sourceTree = SOURCE_ROOT; };\n\t\t66832CCD143D7B2C003E413C /* empty-rulesets.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = \"empty-rulesets.css\"; path = \"css/unittests/empty-rulesets.css\"; sourceTree = SOURCE_ROOT; };\n\t\t66832CCF143D7B38003E413C /* empty.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = empty.css; path = css/unittests/empty.css; sourceTree = SOURCE_ROOT; };\n\t\t66832CD1143D833B003E413C /* comments.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = comments.css; path = css/unittests/comments.css; sourceTree = SOURCE_ROOT; };\n\t\t66832CD3143D8989003E413C /* rulesets.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = rulesets.css; path = css/unittests/rulesets.css; sourceTree = SOURCE_ROOT; };\n\t\t66832CD5143D8AB7003E413C /* rulesets-overrides.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = \"rulesets-overrides.css\"; path = \"css/unittests/rulesets-overrides.css\"; sourceTree = SOURCE_ROOT; };\n\t\t66832CD7143E062C003E413C /* malformed.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = malformed.css; path = css/unittests/malformed.css; sourceTree = SOURCE_ROOT; };\n\t\t66832CEE143E0AD9003E413C /* CSSTokenizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CSSTokenizer.m; path = css/src/CSSTokenizer.m; sourceTree = SOURCE_ROOT; };\n\t\t66832CEF143E0AD9003E413C /* CSSTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSTokens.h; path = css/src/CSSTokens.h; sourceTree = SOURCE_ROOT; };\n\t\t66832CF0143E0AD9003E413C /* CSSTokens.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CSSTokens.m; path = css/src/CSSTokens.m; sourceTree = SOURCE_ROOT; };\n\t\t66832CF4143E0C35003E413C /* NIStylesheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIStylesheet.h; path = css/src/NIStylesheet.h; sourceTree = SOURCE_ROOT; };\n\t\t66832CF5143E0C35003E413C /* NIStylesheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIStylesheet.m; path = css/src/NIStylesheet.m; sourceTree = SOURCE_ROOT; };\n\t\t66832CF8143E1C0C003E413C /* NIStylesheetTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIStylesheetTests.m; path = css/unittests/NIStylesheetTests.m; sourceTree = SOURCE_ROOT; };\n\t\t66832CFA143E2C0D003E413C /* NIDOM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIDOM.h; path = css/src/NIDOM.h; sourceTree = SOURCE_ROOT; };\n\t\t66832CFB143E2C0D003E413C /* NIDOM.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIDOM.m; path = css/src/NIDOM.m; sourceTree = SOURCE_ROOT; };\n\t\t66832CFE143E3294003E413C /* UILabel.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = UILabel.css; path = css/unittests/UILabel.css; sourceTree = SOURCE_ROOT; };\n\t\t66832D00143E38E6003E413C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };\n\t\t66832D02143E38F0003E413C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };\n\t\t66832D05143E3A30003E413C /* NICSSRuleset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NICSSRuleset.h; path = css/src/NICSSRuleset.h; sourceTree = SOURCE_ROOT; };\n\t\t66832D06143E3A30003E413C /* NICSSRuleset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NICSSRuleset.m; path = css/src/NICSSRuleset.m; sourceTree = SOURCE_ROOT; };\n\t\t66832D09143E3B55003E413C /* NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIStyleable.h; path = css/src/NIStyleable.h; sourceTree = SOURCE_ROOT; };\n\t\t66832D0D143E3C32003E413C /* UILabel+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UILabel+NIStyleable.h\"; path = \"css/src/UILabel+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\t66832D0E143E3C32003E413C /* UILabel+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UILabel+NIStyleable.m\"; path = \"css/src/UILabel+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\t66832D1114416368003E413C /* UIView+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIView+NIStyleable.h\"; path = \"css/src/UIView+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\t66832D1214416368003E413C /* UIView+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UIView+NIStyleable.m\"; path = \"css/src/UIView+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\t66832DA014421B4A003E413C /* UINavigationBar+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UINavigationBar+NIStyleable.h\"; path = \"css/src/UINavigationBar+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\t66832DA114421B4A003E413C /* UINavigationBar+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UINavigationBar+NIStyleable.m\"; path = \"css/src/UINavigationBar+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\t66832E0414435071003E413C /* NIChameleonObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIChameleonObserver.h; path = css/src/NIChameleonObserver.h; sourceTree = SOURCE_ROOT; };\n\t\t66832E0514435071003E413C /* NIChameleonObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIChameleonObserver.m; path = css/src/NIChameleonObserver.m; sourceTree = SOURCE_ROOT; };\n\t\t668EA9BC17206DF70056C8C3 /* NIActions+Subclassing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NIActions+Subclassing.h\"; sourceTree = \"<group>\"; };\n\t\t668ECDC51455C17100455266 /* NIStylesheetCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIStylesheetCache.h; path = css/src/NIStylesheetCache.h; sourceTree = SOURCE_ROOT; };\n\t\t668ECDC61455C17100455266 /* NIStylesheetCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIStylesheetCache.m; path = css/src/NIStylesheetCache.m; sourceTree = SOURCE_ROOT; };\n\t\t668ECDCF14565AB200455266 /* README.mdown */ = {isa = PBXFileReference; lastKnownFileType = text; name = README.mdown; path = css/chameleon/README.mdown; sourceTree = SOURCE_ROOT; };\n\t\t66922F1C150C7CE400667191 /* run_unit_test.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = run_unit_test.sh; path = ../scripts/run_unit_test.sh; sourceTree = \"<group>\"; };\n\t\t6693C106158A63E600950D42 /* NimbusCatalog.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = NimbusCatalog.xcodeproj; path = ../examples/Catalog/NimbusCatalog.xcodeproj; sourceTree = \"<group>\"; };\n\t\t6693C2F3158BB8E900950D42 /* NSMutableAttributedString+NimbusAttributedLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSMutableAttributedString+NimbusAttributedLabel.h\"; sourceTree = \"<group>\"; };\n\t\t6693C2F4158BB8E900950D42 /* NSMutableAttributedString+NimbusAttributedLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSMutableAttributedString+NimbusAttributedLabel.m\"; sourceTree = \"<group>\"; };\n\t\t6693C3AC158BFC7E00950D42 /* deps */ = {isa = PBXFileReference; lastKnownFileType = text; name = deps; path = attributedlabel/deps; sourceTree = SOURCE_ROOT; };\n\t\t669819D9159B927B00C2D3EF /* NISnapshotRotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NISnapshotRotation.h; sourceTree = \"<group>\"; };\n\t\t669819DA159B927B00C2D3EF /* NISnapshotRotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NISnapshotRotation.m; sourceTree = \"<group>\"; };\n\t\t669F0CFD158000810069B972 /* NIOverviewMemoryCacheController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIOverviewMemoryCacheController.h; sourceTree = \"<group>\"; };\n\t\t669F0CFE158000810069B972 /* NIOverviewMemoryCacheController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIOverviewMemoryCacheController.m; sourceTree = \"<group>\"; };\n\t\t66A03C0913E6E85E00B514F3 /* libNimbusCore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusCore.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66A03C0C13E6E85E00B514F3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };\n\t\t66A03C1913E6E85E00B514F3 /* NimbusCoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusCoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66A03C4113E6E8D100B514F3 /* NICommonMetrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICommonMetrics.h; sourceTree = \"<group>\"; };\n\t\t66A03C4213E6E8D100B514F3 /* NICommonMetrics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICommonMetrics.m; sourceTree = \"<group>\"; };\n\t\t66A03C4513E6E8D100B514F3 /* NIDebuggingTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIDebuggingTools.h; sourceTree = \"<group>\"; };\n\t\t66A03C4613E6E8D100B514F3 /* NIDebuggingTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIDebuggingTools.m; sourceTree = \"<group>\"; };\n\t\t66A03C4713E6E8D100B514F3 /* NIDeviceOrientation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIDeviceOrientation.h; sourceTree = \"<group>\"; };\n\t\t66A03C4813E6E8D100B514F3 /* NIDeviceOrientation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIDeviceOrientation.m; sourceTree = \"<group>\"; };\n\t\t66A03C4913E6E8D100B514F3 /* NIError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIError.h; sourceTree = \"<group>\"; };\n\t\t66A03C4A13E6E8D100B514F3 /* NIError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIError.m; sourceTree = \"<group>\"; };\n\t\t66A03C4B13E6E8D100B514F3 /* NIFoundationMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIFoundationMethods.h; sourceTree = \"<group>\"; };\n\t\t66A03C4C13E6E8D100B514F3 /* NIFoundationMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIFoundationMethods.m; sourceTree = \"<group>\"; };\n\t\t66A03C4D13E6E8D100B514F3 /* NIInMemoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIInMemoryCache.h; sourceTree = \"<group>\"; };\n\t\t66A03C4E13E6E8D100B514F3 /* NIInMemoryCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIInMemoryCache.m; sourceTree = \"<group>\"; };\n\t\t66A03C4F13E6E8D100B514F3 /* NimbusCore+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NimbusCore+Additions.h\"; sourceTree = \"<group>\"; };\n\t\t66A03C5013E6E8D100B514F3 /* NimbusCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusCore.h; sourceTree = \"<group>\"; };\n\t\t66A03C5113E6E8D100B514F3 /* NINetworkActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NINetworkActivity.h; sourceTree = \"<group>\"; };\n\t\t66A03C5213E6E8D100B514F3 /* NINetworkActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NINetworkActivity.m; sourceTree = \"<group>\"; };\n\t\t66A03C5313E6E8D100B514F3 /* NINonEmptyCollectionTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NINonEmptyCollectionTesting.h; sourceTree = \"<group>\"; };\n\t\t66A03C5413E6E8D100B514F3 /* NINonEmptyCollectionTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NINonEmptyCollectionTesting.m; sourceTree = \"<group>\"; };\n\t\t66A03C5513E6E8D100B514F3 /* NINonRetainingCollections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NINonRetainingCollections.h; sourceTree = \"<group>\"; };\n\t\t66A03C5613E6E8D100B514F3 /* NINonRetainingCollections.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NINonRetainingCollections.m; sourceTree = \"<group>\"; };\n\t\t66A03C5713E6E8D100B514F3 /* NIOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIOperations.h; sourceTree = \"<group>\"; };\n\t\t66A03C5813E6E8D100B514F3 /* NIOperations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIOperations.m; sourceTree = \"<group>\"; };\n\t\t66A03C5913E6E8D100B514F3 /* NIPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPaths.h; sourceTree = \"<group>\"; };\n\t\t66A03C5A13E6E8D100B514F3 /* NIPaths.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPaths.m; sourceTree = \"<group>\"; };\n\t\t66A03C5B13E6E8D100B514F3 /* NIPreprocessorMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPreprocessorMacros.h; sourceTree = \"<group>\"; };\n\t\t66A03C5C13E6E8D100B514F3 /* NIRuntimeClassModifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIRuntimeClassModifications.h; sourceTree = \"<group>\"; };\n\t\t66A03C5D13E6E8D100B514F3 /* NIRuntimeClassModifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIRuntimeClassModifications.m; sourceTree = \"<group>\"; };\n\t\t66A03C5E13E6E8D100B514F3 /* NISDKAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NISDKAvailability.h; sourceTree = \"<group>\"; };\n\t\t66A03C5F13E6E8D100B514F3 /* NISDKAvailability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NISDKAvailability.m; sourceTree = \"<group>\"; };\n\t\t66A03C6013E6E8D100B514F3 /* NIState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIState.h; sourceTree = \"<group>\"; };\n\t\t66A03C6113E6E8D100B514F3 /* NIState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIState.m; sourceTree = \"<group>\"; };\n\t\t66A03C9E13E6E8D900B514F3 /* deps */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = deps; path = core/deps; sourceTree = SOURCE_ROOT; };\n\t\t66A03CA013E6E90500B514F3 /* NICoreAdditionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICoreAdditionTests.m; sourceTree = \"<group>\"; };\n\t\t66A03CA113E6E90500B514F3 /* NIDataStructureTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIDataStructureTests.m; sourceTree = \"<group>\"; };\n\t\t66A03CA213E6E90500B514F3 /* NIFoundationMethodsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIFoundationMethodsTests.m; sourceTree = \"<group>\"; };\n\t\t66A03CA313E6E90500B514F3 /* NIMemoryCacheTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIMemoryCacheTests.m; sourceTree = \"<group>\"; };\n\t\t66A03CA413E6E90500B514F3 /* NINonEmptyCollectionTestingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NINonEmptyCollectionTestingTests.m; sourceTree = \"<group>\"; };\n\t\t66A03CA513E6E90500B514F3 /* NINonRetainingCollectionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NINonRetainingCollectionsTests.m; sourceTree = \"<group>\"; };\n\t\t66A03CA713E6E90500B514F3 /* NIRuntimeClassModificationsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIRuntimeClassModificationsTests.m; sourceTree = \"<group>\"; };\n\t\t66A03CA813E6E90500B514F3 /* NSDate+UnitTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSDate+UnitTesting.h\"; sourceTree = \"<group>\"; };\n\t\t66A03CA913E6E90500B514F3 /* NSDate+UnitTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSDate+UnitTesting.m\"; sourceTree = \"<group>\"; };\n\t\t66A03CB313E6EF1F00B514F3 /* nimbus64x64.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = nimbus64x64.png; path = resources/nimbus64x64.png; sourceTree = SOURCE_ROOT; };\n\t\t66A03CBA13E6F03600B514F3 /* Doxygen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Doxygen.h; sourceTree = \"<group>\"; };\n\t\t66A03CBF13E6F0ED00B514F3 /* libNimbusLauncher.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusLauncher.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66A03CCC13E6F0EE00B514F3 /* NimbusLauncherTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusLauncherTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66A03CF613E6F13700B514F3 /* deps */ = {isa = PBXFileReference; lastKnownFileType = text; name = deps; path = launcher/deps; sourceTree = SOURCE_ROOT; };\n\t\t66A03D2713E6F97500B514F3 /* libNimbusNetworkImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusNetworkImage.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66A03D3413E6F97500B514F3 /* NimbusNetworkImageTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusNetworkImageTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66A03D4C13E6F99400B514F3 /* deps */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = deps; path = networkimage/deps; sourceTree = SOURCE_ROOT; };\n\t\t66A03D5213E6F99400B514F3 /* NimbusNetworkImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusNetworkImage.h; sourceTree = \"<group>\"; };\n\t\t66A03D5313E6F99400B514F3 /* NINetworkImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NINetworkImageView.h; sourceTree = \"<group>\"; };\n\t\t66A03D5413E6F99400B514F3 /* NINetworkImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NINetworkImageView.m; sourceTree = \"<group>\"; };\n\t\t66A03D5B13E6F9A900B514F3 /* NimbusCoreTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = \"NimbusCoreTests-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t66A03D5E13E6F9C700B514F3 /* NimbusLauncherTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = \"NimbusLauncherTests-Info.plist\"; path = \"launcher/unittests/NimbusLauncherTests-Info.plist\"; sourceTree = SOURCE_ROOT; };\n\t\t66A03DF513E6FD1800B514F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/MobileCoreServices.framework; sourceTree = DEVELOPER_DIR; };\n\t\t66A03DF713E6FD2700B514F3 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; };\n\t\t66A03DF913E6FD3000B514F3 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; };\n\t\t66A03DFB13E6FE1700B514F3 /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; name = AUTHORS; path = ../AUTHORS; sourceTree = \"<group>\"; };\n\t\t66A03DFC13E6FE1800B514F3 /* DONORS */ = {isa = PBXFileReference; lastKnownFileType = text; name = DONORS; path = ../DONORS; sourceTree = \"<group>\"; };\n\t\t66A0B09914BD1069003FA413 /* libNimbusNetworkControllers.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusNetworkControllers.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66A0B0A614BD1069003FA413 /* NimbusNetworkControllersTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusNetworkControllersTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66A0B0BF14BD1116003FA413 /* NimbusNetworkControllers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusNetworkControllers.h; path = networkcontrollers/src/NimbusNetworkControllers.h; sourceTree = SOURCE_ROOT; };\n\t\t66A0B0C014BD1116003FA413 /* NINetworkTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NINetworkTableViewController.h; path = networkcontrollers/src/NINetworkTableViewController.h; sourceTree = SOURCE_ROOT; };\n\t\t66A0B0C114BD1116003FA413 /* NINetworkTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NINetworkTableViewController.m; path = networkcontrollers/src/NINetworkTableViewController.m; sourceTree = SOURCE_ROOT; };\n\t\t66A0B0C814BD1586003FA413 /* deps */ = {isa = PBXFileReference; lastKnownFileType = text; name = deps; path = networkcontrollers/deps; sourceTree = SOURCE_ROOT; };\n\t\t66AF0BC8189C1E2700020FEE /* UIResponder+NimbusCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIResponder+NimbusCore.h\"; sourceTree = \"<group>\"; };\n\t\t66AF0BC9189C1E2700020FEE /* UIResponder+NimbusCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIResponder+NimbusCore.m\"; sourceTree = \"<group>\"; };\n\t\t66B108FE144C931F004576D1 /* UIButton+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UIButton+NIStyleable.h\"; path = \"css/src/UIButton+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\t66B108FF144C931F004576D1 /* UIButton+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UIButton+NIStyleable.m\"; path = \"css/src/UIButton+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\t66B10906144D4C15004576D1 /* deps */ = {isa = PBXFileReference; lastKnownFileType = text; name = deps; path = css/deps; sourceTree = SOURCE_ROOT; };\n\t\t66B6710515AA820700FE4AE8 /* NICellBackgrounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICellBackgrounds.h; sourceTree = \"<group>\"; };\n\t\t66B6710615AA820700FE4AE8 /* NICellBackgrounds.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICellBackgrounds.m; sourceTree = \"<group>\"; };\n\t\t66BB4F8A15958A5800020EE8 /* NILauncherButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NILauncherButtonView.h; sourceTree = \"<group>\"; };\n\t\t66BB4F8B15958A5800020EE8 /* NILauncherButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NILauncherButtonView.m; sourceTree = \"<group>\"; };\n\t\t66BB4F8C15958A5800020EE8 /* NILauncherPageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NILauncherPageView.h; sourceTree = \"<group>\"; };\n\t\t66BB4F8D15958A5800020EE8 /* NILauncherPageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NILauncherPageView.m; sourceTree = \"<group>\"; };\n\t\t66BB4F8E15958A5800020EE8 /* NILauncherView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NILauncherView.h; sourceTree = \"<group>\"; };\n\t\t66BB4F8F15958A5800020EE8 /* NILauncherView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NILauncherView.m; sourceTree = \"<group>\"; };\n\t\t66BB4F9015958A5800020EE8 /* NILauncherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NILauncherViewController.h; sourceTree = \"<group>\"; };\n\t\t66BB4F9115958A5800020EE8 /* NILauncherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NILauncherViewController.m; sourceTree = \"<group>\"; };\n\t\t66BB4F9215958A5800020EE8 /* NILauncherViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NILauncherViewModel.h; sourceTree = \"<group>\"; };\n\t\t66BB4F9315958A5800020EE8 /* NILauncherViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NILauncherViewModel.m; sourceTree = \"<group>\"; };\n\t\t66BB4F9415958A5800020EE8 /* NILauncherViewObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NILauncherViewObject.h; sourceTree = \"<group>\"; };\n\t\t66BB4F9515958A5800020EE8 /* NILauncherViewObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NILauncherViewObject.m; sourceTree = \"<group>\"; };\n\t\t66BB4F9615958A5800020EE8 /* NimbusLauncher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusLauncher.h; sourceTree = \"<group>\"; };\n\t\t66C1153F1486ACDD003C9AC6 /* NIOperations+Subclassing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NIOperations+Subclassing.h\"; sourceTree = \"<group>\"; };\n\t\t66C1D83B16B9CE90003E855B /* NIImageUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIImageUtilities.h; sourceTree = \"<group>\"; };\n\t\t66C1D83C16B9CE90003E855B /* NIImageUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIImageUtilities.m; sourceTree = \"<group>\"; };\n\t\t66C1D8BF16B9ED65003E855B /* NIButtonUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIButtonUtilities.h; sourceTree = \"<group>\"; };\n\t\t66C1D8C016B9ED65003E855B /* NIButtonUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIButtonUtilities.m; sourceTree = \"<group>\"; };\n\t\t66C3A6A1143D61130048542F /* libNimbusCss.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusCss.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66C3A6AE143D61140048542F /* NimbusCssTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusCssTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66CB9A201654307A00FFB4BF /* NIPagingScrollView+Subclassing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NIPagingScrollView+Subclassing.h\"; sourceTree = \"<group>\"; };\n\t\t66D2E53D15D9432000281511 /* NIMutableTableViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIMutableTableViewModel.h; sourceTree = \"<group>\"; };\n\t\t66D2E53E15D9432000281511 /* NIMutableTableViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIMutableTableViewModel.m; sourceTree = \"<group>\"; };\n\t\t66D2E54115D9438D00281511 /* NIMutableTableViewModel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NIMutableTableViewModel+Private.h\"; sourceTree = \"<group>\"; };\n\t\t66D2E54615D9503100281511 /* NIMutableTableViewModelTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIMutableTableViewModelTests.m; sourceTree = \"<group>\"; };\n\t\t66D2FDDB1593F3A600B2BEFD /* NIImageProcessing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIImageProcessing.h; sourceTree = \"<group>\"; };\n\t\t66D2FDDC1593F3A600B2BEFD /* NIImageProcessing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIImageProcessing.m; sourceTree = \"<group>\"; };\n\t\t66DCB7891717755B00205745 /* NICollectionViewActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICollectionViewActions.h; sourceTree = \"<group>\"; };\n\t\t66DCB78A1717755B00205745 /* NICollectionViewActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICollectionViewActions.m; sourceTree = \"<group>\"; };\n\t\t66E1CDDF159161ED004DA4A2 /* libNimbusBadge.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusBadge.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66E1CDED159161EE004DA4A2 /* NimbusBadgeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusBadgeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66E1CE0315916220004DA4A2 /* NIBadgeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIBadgeView.h; path = badge/src/NIBadgeView.h; sourceTree = SOURCE_ROOT; };\n\t\t66E1CE0415916220004DA4A2 /* NIBadgeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIBadgeView.m; path = badge/src/NIBadgeView.m; sourceTree = SOURCE_ROOT; };\n\t\t66E1CE0515916220004DA4A2 /* NimbusBadge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NimbusBadge.h; path = badge/src/NimbusBadge.h; sourceTree = SOURCE_ROOT; };\n\t\t66E1CE071591622B004DA4A2 /* NimbusBadgeTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = \"NimbusBadgeTests-Info.plist\"; path = \"badge/unittests/NimbusBadgeTests-Info.plist\"; sourceTree = SOURCE_ROOT; };\n\t\t66E8CED114D089E500600592 /* NICommonMetricsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICommonMetricsTests.m; sourceTree = \"<group>\"; };\n\t\t66E8CED514D08B9F00600592 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = lib.xcconfig; path = resources/lib.xcconfig; sourceTree = \"<group>\"; };\n\t\t66E8CED614D08BAE00600592 /* unittest.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = unittest.xcconfig; path = resources/unittest.xcconfig; sourceTree = \"<group>\"; };\n\t\t66F27D53145B7A5F00AFCA08 /* NIPagingScrollViewPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPagingScrollViewPage.h; sourceTree = \"<group>\"; };\n\t\t66F27D54145B7A5F00AFCA08 /* NIPagingScrollViewPage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIPagingScrollViewPage.m; sourceTree = \"<group>\"; };\n\t\t66F27D5F145BA32500AFCA08 /* NIPhotoAlbumScrollViewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPhotoAlbumScrollViewDataSource.h; sourceTree = \"<group>\"; };\n\t\t66F27D61145BA35B00AFCA08 /* NIPhotoAlbumScrollViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPhotoAlbumScrollViewDelegate.h; sourceTree = \"<group>\"; };\n\t\t66F27D63145BA4E500AFCA08 /* NIPhotoScrollViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPhotoScrollViewDelegate.h; sourceTree = \"<group>\"; };\n\t\t66F27D65145BA56400AFCA08 /* NIPhotoScrollViewPhotoSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIPhotoScrollViewPhotoSize.h; sourceTree = \"<group>\"; };\n\t\t66FC984A1703F9D7004E8FB8 /* libNimbusCollections.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusCollections.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t66FC985A1703FA51004E8FB8 /* NICollectionViewCellFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICollectionViewCellFactory.h; sourceTree = \"<group>\"; };\n\t\t66FC985B1703FA51004E8FB8 /* NICollectionViewCellFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICollectionViewCellFactory.m; sourceTree = \"<group>\"; };\n\t\t66FC985C1703FA51004E8FB8 /* NimbusCollections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusCollections.h; sourceTree = \"<group>\"; };\n\t\t66FC98601703FA51004E8FB8 /* NICollectionViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NICollectionViewModel.h; sourceTree = \"<group>\"; };\n\t\t66FC98611703FA51004E8FB8 /* NICollectionViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICollectionViewModel.m; sourceTree = \"<group>\"; };\n\t\t66FC98621703FA51004E8FB8 /* NICollectionViewModel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NICollectionViewModel+Private.h\"; sourceTree = \"<group>\"; };\n\t\t66FCC632144FB42E0029F1A6 /* includee.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = includee.css; path = css/unittests/includee.css; sourceTree = SOURCE_ROOT; };\n\t\t66FCC633144FB42E0029F1A6 /* includer.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = includer.css; path = css/unittests/includer.css; sourceTree = SOURCE_ROOT; };\n\t\t66FE7D5613FB550A0061B987 /* ExampleRuntimeDebugging.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleRuntimeDebugging.m; sourceTree = \"<group>\"; };\n\t\t66FE7D5E13FB83620061B987 /* deps */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = deps; path = models/deps; sourceTree = SOURCE_ROOT; };\n\t\t66FE7D6013FB83620061B987 /* ExampleStaticTableModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleStaticTableModel.m; sourceTree = \"<group>\"; };\n\t\t66FE7D6413FB83620061B987 /* NimbusModels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusModels.h; sourceTree = \"<group>\"; };\n\t\t66FE7D6513FB83620061B987 /* NITableViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NITableViewModel.h; sourceTree = \"<group>\"; };\n\t\t66FE7D6613FB83620061B987 /* NITableViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NITableViewModel.m; sourceTree = \"<group>\"; };\n\t\t66FE7D6813FB83620061B987 /* NimbusModelsTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = \"NimbusModelsTests-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t8B4E85AA19462A5C005FDD25 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Developer/Library/Frameworks/XCTest.framework; sourceTree = SDKROOT; };\n\t\t8B4E85BC19463074005FDD25 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };\n\t\t8B94F87E1946676B00A63185 /* NIBadgeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIBadgeTests.m; path = badge/unittests/NIBadgeTests.m; sourceTree = SOURCE_ROOT; };\n\t\t9B22BD971725E75E000FDB01 /* NIMutableCollectionViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIMutableCollectionViewModel.h; sourceTree = \"<group>\"; };\n\t\t9B22BD981725E75E000FDB01 /* NIMutableCollectionViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIMutableCollectionViewModel.m; sourceTree = \"<group>\"; };\n\t\t9B22BD9B1725ECB4000FDB01 /* NIMutableCollectionViewModel+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NIMutableCollectionViewModel+Private.h\"; sourceTree = \"<group>\"; };\n\t\tC743F6E816D2652F00A933B7 /* NIUserInterfaceString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NIUserInterfaceString.h; path = css/src/NIUserInterfaceString.h; sourceTree = SOURCE_ROOT; };\n\t\tC743F6E916D2652F00A933B7 /* NIUserInterfaceString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NIUserInterfaceString.m; path = css/src/NIUserInterfaceString.m; sourceTree = SOURCE_ROOT; };\n\t\tC7A8791B16D7348700A0C23F /* NITextField+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"NITextField+NIStyleable.h\"; path = \"css/src/NITextField+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\tC7A8791C16D7348700A0C23F /* NITextField+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"NITextField+NIStyleable.m\"; path = \"css/src/NITextField+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\tC7A8792016D7B96200A0C23F /* UITextField+NIStyleable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"UITextField+NIStyleable.h\"; path = \"css/src/UITextField+NIStyleable.h\"; sourceTree = SOURCE_ROOT; };\n\t\tC7A8792116D7B96200A0C23F /* UITextField+NIStyleable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = \"UITextField+NIStyleable.m\"; path = \"css/src/UITextField+NIStyleable.m\"; sourceTree = SOURCE_ROOT; };\n\t\tC7BBC6B516DDC0DB00833DC9 /* deps */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = deps; path = textfield/deps; sourceTree = \"<group>\"; };\n\t\tC7BBC6B716DDC0DB00833DC9 /* NITextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NITextField.h; sourceTree = \"<group>\"; };\n\t\tC7BBC6B816DDC0DB00833DC9 /* NITextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NITextField.m; sourceTree = \"<group>\"; };\n\t\tC7BBC70216DDC0E700833DC9 /* libNimbusTextField.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusTextField.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tC7BBC71016DE66BD00833DC9 /* media-rulesets.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = \"media-rulesets.css\"; path = \"css/unittests/media-rulesets.css\"; sourceTree = SOURCE_ROOT; };\n\t\tD526CF4A18B826A600991F7A /* NICellCatalogTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NICellCatalogTests.m; sourceTree = \"<group>\"; };\n\t\tD5BCE8B71D7539A300B6715F /* NimbusCollectionsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusCollectionsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tD5BCE8B91D753A1100B6715F /* NimbusCollectionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NimbusCollectionsTests.m; path = unittests/NimbusCollectionsTests.m; sourceTree = \"<group>\"; };\n\t\tD5BCE8C51D76359200B6715F /* NimbusCollectionsTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = \"NimbusCollectionsTests-Info.plist\"; path = \"unittests/NimbusCollectionsTests-Info.plist\"; sourceTree = \"<group>\"; };\n\t\tD5E59299221245200076B697 /* NIAttributedLabel+Testing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"NIAttributedLabel+Testing.h\"; sourceTree = \"<group>\"; };\n\t\tDB3A230913FD4B8E00614220 /* libNimbusAttributedLabel.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusAttributedLabel.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tDB3A231613FD4B8E00614220 /* NimbusAttributedLabelTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusAttributedLabelTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tDB3A233213FD4BE500614220 /* NIAttributedLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIAttributedLabel.h; sourceTree = \"<group>\"; };\n\t\tDB3A233313FD4BE500614220 /* NIAttributedLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIAttributedLabel.m; sourceTree = \"<group>\"; };\n\t\tDB3A233413FD4BE500614220 /* NimbusAttributedLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusAttributedLabel.h; sourceTree = \"<group>\"; };\n\t\tDB3A233A13FD4C2900614220 /* NimbusAttributedLabelTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = \"NimbusAttributedLabelTests-Info.plist\"; sourceTree = \"<group>\"; };\n\t\tDB84BD7413EFDDC900DACCFE /* libNimbusWebController.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNimbusWebController.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tDB84BD8113EFDDCA00DACCFE /* NimbusWebControllerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbusWebControllerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tDB84BDA813EFDF5900DACCFE /* NimbusWebController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NimbusWebController.h; sourceTree = \"<group>\"; };\n\t\tDB84BDA913EFDF5900DACCFE /* NIWebController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NIWebController.h; sourceTree = \"<group>\"; };\n\t\tDB84BDAA13EFDF5900DACCFE /* NIWebController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NIWebController.m; sourceTree = \"<group>\"; };\n\t\tDB84BDB013EFDF6900DACCFE /* NimbusWebControllerTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = \"NimbusWebControllerTests-Info.plist\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t663B523C1445052700CC26DF /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t663B52481445052800CC26DF /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D6014D0B19F00F337D6 /* libNimbusCore.a in Frameworks */,\n\t\t\t\t8B4E85B419462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t666C3D5D14D0B19900F337D6 /* UIKit.framework in Frameworks */,\n\t\t\t\t666C3D5C14D0B19400F337D6 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t663B524F1445052800CC26DF /* Foundation.framework in Frameworks */,\n\t\t\t\t663B52521445052800CC26DF /* libNimbusPagingScrollView.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6661BBC913F1A3BB00D14F92 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6661BBD513F1A3BB00D14F92 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8B4E85A7194629DC005FDD25 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t8B4E85B619462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t66C113E5147DD0F1003C9AC6 /* UIKit.framework in Frameworks */,\n\t\t\t\t6623EB721402EDB100E0E61A /* libNimbusCore.a in Frameworks */,\n\t\t\t\t6661BBDC13F1A3BB00D14F92 /* Foundation.framework in Frameworks */,\n\t\t\t\t6661BBE013F1A3BB00D14F92 /* libNimbusModels.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675722613E765BF0076F555 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675723213E765BF0076F555 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8B94F878194664F000A63185 /* libNimbusCore.a in Frameworks */,\n\t\t\t\t8B94F879194664F000A63185 /* libNimbusModels.a in Frameworks */,\n\t\t\t\t666C3D5B14D0B18C00F337D6 /* UIKit.framework in Frameworks */,\n\t\t\t\t8B4E85B319462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t666C3D5A14D0B18900F337D6 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t6675723913E765BF0076F555 /* Foundation.framework in Frameworks */,\n\t\t\t\t6675723D13E765BF0076F555 /* libNimbusOverview.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675727713E769150076F555 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675728313E769150076F555 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D6814D0B1B500F337D6 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t8B4E85B519462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t666C3D6714D0B1AF00F337D6 /* UIKit.framework in Frameworks */,\n\t\t\t\t666C3D6114D0B1A600F337D6 /* libNimbusCore.a in Frameworks */,\n\t\t\t\t666C3D6214D0B1A600F337D6 /* libNimbusPagingScrollView.a in Frameworks */,\n\t\t\t\t6675728A13E769150076F555 /* Foundation.framework in Frameworks */,\n\t\t\t\t6675728E13E769150076F555 /* libNimbusPhotos.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675730F13E771380076F555 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675731B13E771380076F555 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D3114D0AE1100F337D6 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t8B4E85AF19462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t666C3D3014D0AE0C00F337D6 /* UIKit.framework in Frameworks */,\n\t\t\t\t666C3D2B14D0ACD900F337D6 /* libNimbusCore.a in Frameworks */,\n\t\t\t\t6675732213E771380076F555 /* Foundation.framework in Frameworks */,\n\t\t\t\t6675732613E771380076F555 /* libNimbusInterapp.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03C0613E6E85E00B514F3 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03C1513E6E85E00B514F3 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6675E4B714560372007D172F /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t6675E4B614560359007D172F /* UIKit.framework in Frameworks */,\n\t\t\t\t8B4E85AD19462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t66A03C1E13E6E85E00B514F3 /* Foundation.framework in Frameworks */,\n\t\t\t\t66A03C2313E6E85E00B514F3 /* libNimbusCore.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03CBC13E6F0ED00B514F3 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03CC813E6F0EE00B514F3 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D4414D0AF8C00F337D6 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t8B4E85B019462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t666C3D4114D0AF7C00F337D6 /* libNimbusCore.a in Frameworks */,\n\t\t\t\t666C3D4014D0AF7200F337D6 /* UIKit.framework in Frameworks */,\n\t\t\t\t66A03CCF13E6F0EE00B514F3 /* Foundation.framework in Frameworks */,\n\t\t\t\t66A03CD313E6F0EE00B514F3 /* libNimbusLauncher.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03D2413E6F97500B514F3 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03D3013E6F97500B514F3 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D5314D0B13F00F337D6 /* libNimbusCore.a in Frameworks */,\n\t\t\t\t8B4E85B219462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t666C3D5214D0B11B00F337D6 /* UIKit.framework in Frameworks */,\n\t\t\t\t666C3D5114D0B11800F337D6 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t8B4E85CD1946374B005FDD25 /* Security.framework in Frameworks */,\n\t\t\t\t66A03D3713E6F97500B514F3 /* Foundation.framework in Frameworks */,\n\t\t\t\t66A03D3B13E6F97500B514F3 /* libNimbusNetworkImage.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A0B09614BD1069003FA413 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66A0B09A14BD1069003FA413 /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A0B0A214BD1069003FA413 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8B94F87D1946662600A63185 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t8B94F87C194665DF00A63185 /* libNimbusCore.a in Frameworks */,\n\t\t\t\t66A0B0A814BD1069003FA413 /* UIKit.framework in Frameworks */,\n\t\t\t\t66A0B0A914BD1069003FA413 /* Foundation.framework in Frameworks */,\n\t\t\t\t66A0B0AC14BD1069003FA413 /* libNimbusNetworkControllers.a in Frameworks */,\n\t\t\t\t8B4E85B119462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66C3A69E143D61130048542F /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8BB611A01946891500C851CC /* XCTest.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66C3A6AA143D61140048542F /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66832D04143E39DF003E413C /* UIKit.framework in Frameworks */,\n\t\t\t\t8B4E85AE19462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t66832D03143E38F0003E413C /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t66832CCC143D7AA4003E413C /* libNimbusCore.a in Frameworks */,\n\t\t\t\t8B4E85BD19463074005FDD25 /* Security.framework in Frameworks */,\n\t\t\t\t66C3A6B1143D61140048542F /* Foundation.framework in Frameworks */,\n\t\t\t\t66C3A6B4143D61140048542F /* libNimbusCss.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66E1CDDC159161ED004DA4A2 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66E1CDE0159161ED004DA4A2 /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66E1CDE9159161EE004DA4A2 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66E1CDEF159161EE004DA4A2 /* UIKit.framework in Frameworks */,\n\t\t\t\t66E1CDF0159161EE004DA4A2 /* Foundation.framework in Frameworks */,\n\t\t\t\t66E1CDF3159161EE004DA4A2 /* libNimbusBadge.a in Frameworks */,\n\t\t\t\t8B4E85AC19462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66FC98471703F9D7004E8FB8 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66FC984B1703F9D7004E8FB8 /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC7BBC6DB16DDC0E700833DC9 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tD5BCE8AC1D7539A300B6715F /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tD5BCE8C41D762F1600B6715F /* libNimbusModels.a in Frameworks */,\n\t\t\t\tD5BCE8C11D753BCE00B6715F /* libNimbusCore.a in Frameworks */,\n\t\t\t\tD5BCE8BE1D753B9100B6715F /* libNimbusCollections.a in Frameworks */,\n\t\t\t\tD5BCE8AD1D7539A300B6715F /* CoreGraphics.framework in Frameworks */,\n\t\t\t\tD5BCE8AE1D7539A300B6715F /* UIKit.framework in Frameworks */,\n\t\t\t\tD5BCE8AF1D7539A300B6715F /* XCTest.framework in Frameworks */,\n\t\t\t\tD5BCE8B01D7539A300B6715F /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB3A230613FD4B8E00614220 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB3A231213FD4B8E00614220 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D2314D0AC6C00F337D6 /* libNimbusCore.a in Frameworks */,\n\t\t\t\t8B4E85AB19462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t666C3D2114D0AC3E00F337D6 /* UIKit.framework in Frameworks */,\n\t\t\t\t666C3D2014D0AC3800F337D6 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t666C3D1F14D0AC2100F337D6 /* CoreText.framework in Frameworks */,\n\t\t\t\tDB3A231913FD4B8E00614220 /* Foundation.framework in Frameworks */,\n\t\t\t\tDB3A231D13FD4B8E00614220 /* libNimbusAttributedLabel.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB84BD7113EFDDC900DACCFE /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB84BD7D13EFDDCA00DACCFE /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D6F14D0B1D400F337D6 /* libNimbusCore.a in Frameworks */,\n\t\t\t\t8B4E85B719462A5C005FDD25 /* XCTest.framework in Frameworks */,\n\t\t\t\t666C3D6C14D0B1C900F337D6 /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t666C3D6B14D0B1C400F337D6 /* UIKit.framework in Frameworks */,\n\t\t\t\tDB84BD8413EFDDCA00DACCFE /* Foundation.framework in Frameworks */,\n\t\t\t\tDB84BD8813EFDDCA00DACCFE /* libNimbusWebController.a 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\t6617AFCE18A90CCC00037E75 /* UIKit */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6617B00118A90CFD00037E75 /* AFNetworkActivityIndicatorManager.h */,\n\t\t\t\t6617B00218A90CFD00037E75 /* AFNetworkActivityIndicatorManager.m */,\n\t\t\t\t6617B00318A90CFD00037E75 /* UIActivityIndicatorView+AFNetworking.h */,\n\t\t\t\t6617B00418A90CFD00037E75 /* UIActivityIndicatorView+AFNetworking.m */,\n\t\t\t\t6617B00518A90CFD00037E75 /* UIAlertView+AFNetworking.h */,\n\t\t\t\t6617B00618A90CFD00037E75 /* UIAlertView+AFNetworking.m */,\n\t\t\t\t6617B00718A90CFD00037E75 /* UIButton+AFNetworking.h */,\n\t\t\t\t6617B00818A90CFD00037E75 /* UIButton+AFNetworking.m */,\n\t\t\t\t6617B00918A90CFD00037E75 /* UIImageView+AFNetworking.h */,\n\t\t\t\t6617B00A18A90CFD00037E75 /* UIImageView+AFNetworking.m */,\n\t\t\t\t6617B00B18A90CFD00037E75 /* UIKit+AFNetworking.h */,\n\t\t\t\t6617B00C18A90CFD00037E75 /* UIProgressView+AFNetworking.h */,\n\t\t\t\t6617B00D18A90CFD00037E75 /* UIProgressView+AFNetworking.m */,\n\t\t\t\t6617B00E18A90CFD00037E75 /* UIWebView+AFNetworking.h */,\n\t\t\t\t6617B00F18A90CFD00037E75 /* UIWebView+AFNetworking.m */,\n\t\t\t);\n\t\t\tname = UIKit;\n\t\t\tpath = \"../UIKit+AFNetworking\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t661F28A91591B01D00D11FC3 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66E1CE0515916220004DA4A2 /* NimbusBadge.h */,\n\t\t\t\t66E1CE0315916220004DA4A2 /* NIBadgeView.h */,\n\t\t\t\t66E1CE0415916220004DA4A2 /* NIBadgeView.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t661F28AB1591B03700D11FC3 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66E1CE071591622B004DA4A2 /* NimbusBadgeTests-Info.plist */,\n\t\t\t\t8B94F87E1946676B00A63185 /* NIBadgeTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t663B52411445052800CC26DF /* NimbusPagingScrollView */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t663B52651445060000CC26DF /* deps */,\n\t\t\t\t663B52631445054900CC26DF /* src */,\n\t\t\t\t663B52621445054300CC26DF /* unittests */,\n\t\t\t);\n\t\t\tname = NimbusPagingScrollView;\n\t\t\tpath = pagingscrollview;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t663B52621445054300CC26DF /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t663B52641445059C00CC26DF /* NimbusPagingScrollViewTests-Info.plist */,\n\t\t\t\t666C3D3414D0AE7B00F337D6 /* NIPagingScrollViewTests.m */,\n\t\t\t);\n\t\t\tpath = unittests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t663B52631445054900CC26DF /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t663B52661445061B00CC26DF /* NimbusPagingScrollView.h */,\n\t\t\t\t663B52681445070100CC26DF /* NIPagingScrollView.h */,\n\t\t\t\t663B52691445070100CC26DF /* NIPagingScrollView.m */,\n\t\t\t\t66CB9A201654307A00FFB4BF /* NIPagingScrollView+Subclassing.h */,\n\t\t\t\t66F27D53145B7A5F00AFCA08 /* NIPagingScrollViewPage.h */,\n\t\t\t\t66F27D54145B7A5F00AFCA08 /* NIPagingScrollViewPage.m */,\n\t\t\t);\n\t\t\tpath = src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t664D442E14992FE0008B4C42 /* Third Party */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66D2FDE01594083800B2BEFD /* AFNetworking */,\n\t\t\t);\n\t\t\tname = \"Third Party\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t664EFAD6155989D9009826AB /* Examples */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C106158A63E600950D42 /* NimbusCatalog.xcodeproj */,\n\t\t\t\t664EFAE215598A07009826AB /* CSSDemo.xcodeproj */,\n\t\t\t\t664EFB1815598A5E009826AB /* NetworkPhotoAlbum.xcodeproj */,\n\t\t\t);\n\t\t\tname = Examples;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t664EFAE315598A07009826AB /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t664EFAEB15598A07009826AB /* CSSDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t664EFB1915598A5E009826AB /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t664EFB2115598A5E009826AB /* NetworkPhotoAlbum.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6661BBCE13F1A3BB00D14F92 /* NimbusModels */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66FE7D5E13FB83620061B987 /* deps */,\n\t\t\t\t66FE7D6313FB83620061B987 /* src */,\n\t\t\t\t66FE7D6713FB83620061B987 /* unittests */,\n\t\t\t\t66FE7D5F13FB83620061B987 /* examples */,\n\t\t\t);\n\t\t\tname = NimbusModels;\n\t\t\tpath = NimbusTables;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6675722B13E765BF0076F555 /* NimbusOverview */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6675724F13E765F70076F555 /* deps */,\n\t\t\t\t6675725213E765F70076F555 /* src */,\n\t\t\t\t6675727213E766400076F555 /* unittests */,\n\t\t\t);\n\t\t\tpath = NimbusOverview;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6675725213E765F70076F555 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6675725513E765F70076F555 /* NimbusOverview.h */,\n\t\t\t\t6675725313E765F70076F555 /* NIDeviceInfo.h */,\n\t\t\t\t6675725413E765F70076F555 /* NIDeviceInfo.m */,\n\t\t\t\t6675725613E765F70076F555 /* NIOverview.h */,\n\t\t\t\t6675725713E765F70076F555 /* NIOverview.m */,\n\t\t\t\t6675725813E765F70076F555 /* NIOverviewGraphView.h */,\n\t\t\t\t6675725913E765F70076F555 /* NIOverviewGraphView.m */,\n\t\t\t\t6675725A13E765F70076F555 /* NIOverviewLogger.h */,\n\t\t\t\t6675725B13E765F70076F555 /* NIOverviewLogger.m */,\n\t\t\t\t6675725C13E765F70076F555 /* NIOverviewPageView.h */,\n\t\t\t\t6675725D13E765F70076F555 /* NIOverviewPageView.m */,\n\t\t\t\t6675725E13E765F70076F555 /* NIOverviewSwizzling.h */,\n\t\t\t\t6675725F13E765F70076F555 /* NIOverviewSwizzling.m */,\n\t\t\t\t6675726013E765F70076F555 /* NIOverviewView.h */,\n\t\t\t\t6675726113E765F70076F555 /* NIOverviewView.m */,\n\t\t\t\t669F0CFD158000810069B972 /* NIOverviewMemoryCacheController.h */,\n\t\t\t\t669F0CFE158000810069B972 /* NIOverviewMemoryCacheController.m */,\n\t\t\t\t663B52E7144675BF00CC26DF /* NimbusOverviewer.bundle */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = overview/src;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t6675727213E766400076F555 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6675727313E766400076F555 /* NimbusOverviewTests-Info.plist */,\n\t\t\t\t666C3D3C14D0AF0C00F337D6 /* NIOverviewTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tpath = overview/unittests;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t6675727C13E769150076F555 /* NimbusPhotos */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t663B52761445129400CC26DF /* deps */,\n\t\t\t\t667572A113E7692F0076F555 /* src */,\n\t\t\t\t667572AB13E7692F0076F555 /* unittests */,\n\t\t\t);\n\t\t\tpath = NimbusPhotos;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t667572A113E7692F0076F555 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t667572A213E7692F0076F555 /* NimbusPhotos.h */,\n\t\t\t\t667572A313E7692F0076F555 /* NIPhotoAlbumScrollView.h */,\n\t\t\t\t667572A413E7692F0076F555 /* NIPhotoAlbumScrollView.m */,\n\t\t\t\t66F27D5F145BA32500AFCA08 /* NIPhotoAlbumScrollViewDataSource.h */,\n\t\t\t\t66F27D61145BA35B00AFCA08 /* NIPhotoAlbumScrollViewDelegate.h */,\n\t\t\t\t667572A513E7692F0076F555 /* NIPhotoScrollView.h */,\n\t\t\t\t667572A613E7692F0076F555 /* NIPhotoScrollView.m */,\n\t\t\t\t66F27D63145BA4E500AFCA08 /* NIPhotoScrollViewDelegate.h */,\n\t\t\t\t66F27D65145BA56400AFCA08 /* NIPhotoScrollViewPhotoSize.h */,\n\t\t\t\t667572A713E7692F0076F555 /* NIPhotoScrubberView.h */,\n\t\t\t\t667572A813E7692F0076F555 /* NIPhotoScrubberView.m */,\n\t\t\t\t667572A913E7692F0076F555 /* NIToolbarPhotoViewController.h */,\n\t\t\t\t667572AA13E7692F0076F555 /* NIToolbarPhotoViewController.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = photos/src;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t667572AB13E7692F0076F555 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t667572AC13E7692F0076F555 /* NimbusPhotosTests-Info.plist */,\n\t\t\t\t666C3D3614D0AEA300F337D6 /* NIPhotoScrollViewTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tpath = photos/unittests;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t6675731413E771380076F555 /* NimbusInterapp */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6675733713E7718B0076F555 /* deps */,\n\t\t\t\t6675733A13E7718B0076F555 /* src */,\n\t\t\t\t6675734213E772100076F555 /* unittests */,\n\t\t\t);\n\t\t\tpath = NimbusInterapp;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6675733A13E7718B0076F555 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6675734413E773AA0076F555 /* NimbusInterapp.h */,\n\t\t\t\t6675733B13E7718B0076F555 /* NIInterapp.h */,\n\t\t\t\t6675733C13E7718B0076F555 /* NIInterapp.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = interapp/src;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t6675734213E772100076F555 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6675734313E772100076F555 /* NimbusInterappTests-Info.plist */,\n\t\t\t\t666C3D2614D0ACA900F337D6 /* NIInterappTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tpath = interapp/unittests;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t66832C93143D63B4003E413C /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832CB7143D681B003E413C /* NimbusCSS.h */,\n\t\t\t\t66832CC2143D7898003E413C /* NICSSParser.h */,\n\t\t\t\t66832CC3143D7898003E413C /* NICSSParser.m */,\n\t\t\t\t66832D05143E3A30003E413C /* NICSSRuleset.h */,\n\t\t\t\t66832D06143E3A30003E413C /* NICSSRuleset.m */,\n\t\t\t\t66832CFA143E2C0D003E413C /* NIDOM.h */,\n\t\t\t\t66832CFB143E2C0D003E413C /* NIDOM.m */,\n\t\t\t\t66832D09143E3B55003E413C /* NIStyleable.h */,\n\t\t\t\t66832CF4143E0C35003E413C /* NIStylesheet.h */,\n\t\t\t\t66832CF5143E0C35003E413C /* NIStylesheet.m */,\n\t\t\t\t668ECDC51455C17100455266 /* NIStylesheetCache.h */,\n\t\t\t\t668ECDC61455C17100455266 /* NIStylesheetCache.m */,\n\t\t\t\tC743F6E816D2652F00A933B7 /* NIUserInterfaceString.h */,\n\t\t\t\tC743F6E916D2652F00A933B7 /* NIUserInterfaceString.m */,\n\t\t\t\tC7A8791A16D7344F00A0C23F /* Styleable Nimbus Views */,\n\t\t\t\t668ECDD014565AB800455266 /* Chameleon */,\n\t\t\t\t66832D0C143E3C1C003E413C /* Styleable UIKit Views */,\n\t\t\t\t66832D0B143E3C0E003E413C /* Tokenizer */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832C95143D63BF003E413C /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832CC8143D797B003E413C /* resources */,\n\t\t\t\t66832CC0143D7883003E413C /* NICSSParserTests.m */,\n\t\t\t\t66832CF8143E1C0C003E413C /* NIStylesheetTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832C96143D63C6003E413C /* grammar */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832CA1143D64CF003E413C /* generate */,\n\t\t\t\t66832CA8143D6642003E413C /* CSSTokenizerPrefix */,\n\t\t\t\t66832CA9143D6642003E413C /* CSSTokens.cpp */,\n\t\t\t\t66832CAA143D6642003E413C /* CSSTokens.h */,\n\t\t\t\t66832C98143D63D2003E413C /* css.grammar */,\n\t\t\t);\n\t\t\tname = grammar;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832CC8143D797B003E413C /* resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832CFE143E3294003E413C /* UILabel.css */,\n\t\t\t\t66832CD1143D833B003E413C /* comments.css */,\n\t\t\t\t66832CCF143D7B38003E413C /* empty.css */,\n\t\t\t\t66832CCD143D7B2C003E413C /* empty-rulesets.css */,\n\t\t\t\t66832CD7143E062C003E413C /* malformed.css */,\n\t\t\t\t66832CD3143D8989003E413C /* rulesets.css */,\n\t\t\t\t66832CD5143D8AB7003E413C /* rulesets-overrides.css */,\n\t\t\t\t66FCC632144FB42E0029F1A6 /* includee.css */,\n\t\t\t\t66FCC633144FB42E0029F1A6 /* includer.css */,\n\t\t\t\t66832CC9143D7994003E413C /* NimbusCSSTests-Info.plist */,\n\t\t\t\tC7BBC71016DE66BD00833DC9 /* media-rulesets.css */,\n\t\t\t);\n\t\t\tname = resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D0B143E3C0E003E413C /* Tokenizer */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66832CEE143E0AD9003E413C /* CSSTokenizer.m */,\n\t\t\t\t66832CEF143E0AD9003E413C /* CSSTokens.h */,\n\t\t\t\t66832CF0143E0AD9003E413C /* CSSTokens.m */,\n\t\t\t);\n\t\t\tname = Tokenizer;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66832D0C143E3C1C003E413C /* Styleable UIKit Views */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t664EFB6015598CDF009826AB /* UIActivityIndicatorView+NIStyleable.h */,\n\t\t\t\t664EFB6115598CDF009826AB /* UIActivityIndicatorView+NIStyleable.m */,\n\t\t\t\t66B108FE144C931F004576D1 /* UIButton+NIStyleable.h */,\n\t\t\t\t66B108FF144C931F004576D1 /* UIButton+NIStyleable.m */,\n\t\t\t\t66832D0D143E3C32003E413C /* UILabel+NIStyleable.h */,\n\t\t\t\t66832D0E143E3C32003E413C /* UILabel+NIStyleable.m */,\n\t\t\t\t66832DA014421B4A003E413C /* UINavigationBar+NIStyleable.h */,\n\t\t\t\t66832DA114421B4A003E413C /* UINavigationBar+NIStyleable.m */,\n\t\t\t\t443589BF1551909D00757E50 /* UISearchBar+NIStyleable.h */,\n\t\t\t\t443589C01551909D00757E50 /* UISearchBar+NIStyleable.m */,\n\t\t\t\t666903871561B6A000C44A70 /* UIScrollView+NIStyleable.h */,\n\t\t\t\t666903881561B6A000C44A70 /* UIScrollView+NIStyleable.m */,\n\t\t\t\t666903831561B46900C44A70 /* UITableView+NIStyleable.h */,\n\t\t\t\t666903841561B46900C44A70 /* UITableView+NIStyleable.m */,\n\t\t\t\t443589C11551909E00757E50 /* UIToolbar+NIStyleable.h */,\n\t\t\t\t443589C21551909E00757E50 /* UIToolbar+NIStyleable.m */,\n\t\t\t\t66832D1114416368003E413C /* UIView+NIStyleable.h */,\n\t\t\t\t66832D1214416368003E413C /* UIView+NIStyleable.m */,\n\t\t\t\tC7A8792016D7B96200A0C23F /* UITextField+NIStyleable.h */,\n\t\t\t\tC7A8792116D7B96200A0C23F /* UITextField+NIStyleable.m */,\n\t\t\t);\n\t\t\tname = \"Styleable UIKit Views\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t668ECDD014565AB800455266 /* Chameleon */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t668ECDCF14565AB200455266 /* README.mdown */,\n\t\t\t\t66832E0414435071003E413C /* NIChameleonObserver.h */,\n\t\t\t\t66832E0514435071003E413C /* NIChameleonObserver.m */,\n\t\t\t);\n\t\t\tname = Chameleon;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6693C149158A648500950D42 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C14D158A648500950D42 /* Nimbus.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A03BFC13E6E84800B514F3 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66325D5713EB0302008D6EAD /* README.mdown */,\n\t\t\t\t661BC070160B95120049E5B7 /* CONTRIBUTING.mdown */,\n\t\t\t\t66A03CBA13E6F03600B514F3 /* Doxygen.h */,\n\t\t\t\t66A03DFB13E6FE1700B514F3 /* AUTHORS */,\n\t\t\t\t66A03DFC13E6FE1800B514F3 /* DONORS */,\n\t\t\t\t6661BB0813F0B37000D14F92 /* LICENSE */,\n\t\t\t\t6661BB0A13F0B38D00D14F92 /* NOTICE */,\n\t\t\t\t666F73B614BBFFD600D1A32F /* generate_namespace_header */,\n\t\t\t\t66922F1C150C7CE400667191 /* run_unit_test.sh */,\n\t\t\t\t66E8CED414D08B8000600592 /* Configs */,\n\t\t\t\tDB3A230B13FD4B8E00614220 /* NimbusAttributedLabel */,\n\t\t\t\t66E1CDE1159161ED004DA4A2 /* NimbusBadge */,\n\t\t\t\t66FC984C1703F9D7004E8FB8 /* NimbusCollections */,\n\t\t\t\t66A03C0E13E6E85E00B514F3 /* NimbusCore */,\n\t\t\t\t66C3A6A3143D61130048542F /* NimbusCss */,\n\t\t\t\t6675731413E771380076F555 /* NimbusInterapp */,\n\t\t\t\t66A03CC113E6F0ED00B514F3 /* NimbusLauncher */,\n\t\t\t\t6661BBCE13F1A3BB00D14F92 /* NimbusModels */,\n\t\t\t\t66A0B09B14BD1069003FA413 /* NimbusNetworkControllers */,\n\t\t\t\t66A03D2913E6F97500B514F3 /* NimbusNetworkImage */,\n\t\t\t\t6675722B13E765BF0076F555 /* NimbusOverview */,\n\t\t\t\t663B52411445052800CC26DF /* NimbusPagingScrollView */,\n\t\t\t\t6675727C13E769150076F555 /* NimbusPhotos */,\n\t\t\t\tC7BBC6B116DDC09400833DC9 /* NimbusTextField */,\n\t\t\t\tDB84BD9A13EFDE3C00DACCFE /* NimbusWebController */,\n\t\t\t\t664D442E14992FE0008B4C42 /* Third Party */,\n\t\t\t\t66A03C0B13E6E85E00B514F3 /* Frameworks */,\n\t\t\t\t664EFAD6155989D9009826AB /* Examples */,\n\t\t\t\t66A03C0A13E6E85E00B514F3 /* Products */,\n\t\t\t);\n\t\t\tindentWidth = 2;\n\t\t\tsourceTree = \"<group>\";\n\t\t\ttabWidth = 2;\n\t\t};\n\t\t66A03C0A13E6E85E00B514F3 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03C0913E6E85E00B514F3 /* libNimbusCore.a */,\n\t\t\t\t66A03C1913E6E85E00B514F3 /* NimbusCoreTests.xctest */,\n\t\t\t\t66A03CBF13E6F0ED00B514F3 /* libNimbusLauncher.a */,\n\t\t\t\t66A03CCC13E6F0EE00B514F3 /* NimbusLauncherTests.xctest */,\n\t\t\t\t66A03D2713E6F97500B514F3 /* libNimbusNetworkImage.a */,\n\t\t\t\t66A03D3413E6F97500B514F3 /* NimbusNetworkImageTests.xctest */,\n\t\t\t\t6675722913E765BF0076F555 /* libNimbusOverview.a */,\n\t\t\t\t6675723613E765BF0076F555 /* NimbusOverviewTests.xctest */,\n\t\t\t\t6675727A13E769150076F555 /* libNimbusPhotos.a */,\n\t\t\t\t6675728713E769150076F555 /* NimbusPhotosTests.xctest */,\n\t\t\t\t6675731213E771380076F555 /* libNimbusInterapp.a */,\n\t\t\t\t6675731F13E771380076F555 /* NimbusInterappTests.xctest */,\n\t\t\t\tDB84BD7413EFDDC900DACCFE /* libNimbusWebController.a */,\n\t\t\t\tDB84BD8113EFDDCA00DACCFE /* NimbusWebControllerTests.xctest */,\n\t\t\t\t6661BBCC13F1A3BB00D14F92 /* libNimbusModels.a */,\n\t\t\t\t6661BBD913F1A3BB00D14F92 /* NimbusModelsTests.xctest */,\n\t\t\t\tDB3A230913FD4B8E00614220 /* libNimbusAttributedLabel.a */,\n\t\t\t\tDB3A231613FD4B8E00614220 /* NimbusAttributedLabelTests.xctest */,\n\t\t\t\t66C3A6A1143D61130048542F /* libNimbusCss.a */,\n\t\t\t\t66C3A6AE143D61140048542F /* NimbusCssTests.xctest */,\n\t\t\t\t663B523F1445052700CC26DF /* libNimbusPagingScrollView.a */,\n\t\t\t\t663B524C1445052800CC26DF /* NimbusPagingScrollViewTests.xctest */,\n\t\t\t\t66A0B09914BD1069003FA413 /* libNimbusNetworkControllers.a */,\n\t\t\t\t66A0B0A614BD1069003FA413 /* NimbusNetworkControllersTests.xctest */,\n\t\t\t\t66E1CDDF159161ED004DA4A2 /* libNimbusBadge.a */,\n\t\t\t\t66E1CDED159161EE004DA4A2 /* NimbusBadgeTests.xctest */,\n\t\t\t\tC7BBC70216DDC0E700833DC9 /* libNimbusTextField.a */,\n\t\t\t\t66FC984A1703F9D7004E8FB8 /* libNimbusCollections.a */,\n\t\t\t\tD5BCE8B71D7539A300B6715F /* NimbusCollectionsTests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A03C0B13E6E85E00B514F3 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8B4E85BC19463074005FDD25 /* Security.framework */,\n\t\t\t\t8B4E85AA19462A5C005FDD25 /* XCTest.framework */,\n\t\t\t\t666C3D1E14D0AC2100F337D6 /* CoreText.framework */,\n\t\t\t\t66832D02143E38F0003E413C /* CoreGraphics.framework */,\n\t\t\t\t66832D00143E38E6003E413C /* UIKit.framework */,\n\t\t\t\t66A03DF913E6FD3000B514F3 /* SystemConfiguration.framework */,\n\t\t\t\t66A03DF713E6FD2700B514F3 /* CFNetwork.framework */,\n\t\t\t\t66A03DF513E6FD1800B514F3 /* MobileCoreServices.framework */,\n\t\t\t\t66A03C0C13E6E85E00B514F3 /* Foundation.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A03C0E13E6E85E00B514F3 /* NimbusCore */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03C9E13E6E8D900B514F3 /* deps */,\n\t\t\t\t66A03C3F13E6E8D100B514F3 /* src */,\n\t\t\t\t66A03C9F13E6E90500B514F3 /* unittests */,\n\t\t\t\t66FE7D5513FB550A0061B987 /* examples */,\n\t\t\t);\n\t\t\tpath = NimbusCore;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A03C3F13E6E8D100B514F3 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03C5013E6E8D100B514F3 /* NimbusCore.h */,\n\t\t\t\t66A03C4F13E6E8D100B514F3 /* NimbusCore+Additions.h */,\n\t\t\t\t6617FD08171F6A92006E0DF8 /* NIActions.h */,\n\t\t\t\t6617FD09171F6A92006E0DF8 /* NIActions.m */,\n\t\t\t\t668EA9BC17206DF70056C8C3 /* NIActions+Subclassing.h */,\n\t\t\t\t66C1D8BF16B9ED65003E855B /* NIButtonUtilities.h */,\n\t\t\t\t66C1D8C016B9ED65003E855B /* NIButtonUtilities.m */,\n\t\t\t\t66A03C4113E6E8D100B514F3 /* NICommonMetrics.h */,\n\t\t\t\t66A03C4213E6E8D100B514F3 /* NICommonMetrics.m */,\n\t\t\t\t66A03C4513E6E8D100B514F3 /* NIDebuggingTools.h */,\n\t\t\t\t66A03C4613E6E8D100B514F3 /* NIDebuggingTools.m */,\n\t\t\t\t66A03C4713E6E8D100B514F3 /* NIDeviceOrientation.h */,\n\t\t\t\t66A03C4813E6E8D100B514F3 /* NIDeviceOrientation.m */,\n\t\t\t\t66A03C4913E6E8D100B514F3 /* NIError.h */,\n\t\t\t\t66A03C4A13E6E8D100B514F3 /* NIError.m */,\n\t\t\t\t66A03C4B13E6E8D100B514F3 /* NIFoundationMethods.h */,\n\t\t\t\t66A03C4C13E6E8D100B514F3 /* NIFoundationMethods.m */,\n\t\t\t\t66C1D83B16B9CE90003E855B /* NIImageUtilities.h */,\n\t\t\t\t66C1D83C16B9CE90003E855B /* NIImageUtilities.m */,\n\t\t\t\t66A03C4D13E6E8D100B514F3 /* NIInMemoryCache.h */,\n\t\t\t\t66A03C4E13E6E8D100B514F3 /* NIInMemoryCache.m */,\n\t\t\t\t66A03C5113E6E8D100B514F3 /* NINetworkActivity.h */,\n\t\t\t\t66A03C5213E6E8D100B514F3 /* NINetworkActivity.m */,\n\t\t\t\t66A03C5313E6E8D100B514F3 /* NINonEmptyCollectionTesting.h */,\n\t\t\t\t66A03C5413E6E8D100B514F3 /* NINonEmptyCollectionTesting.m */,\n\t\t\t\t66A03C5513E6E8D100B514F3 /* NINonRetainingCollections.h */,\n\t\t\t\t66A03C5613E6E8D100B514F3 /* NINonRetainingCollections.m */,\n\t\t\t\t66C1153F1486ACDD003C9AC6 /* NIOperations+Subclassing.h */,\n\t\t\t\t66A03C5713E6E8D100B514F3 /* NIOperations.h */,\n\t\t\t\t66A03C5813E6E8D100B514F3 /* NIOperations.m */,\n\t\t\t\t66A03C5913E6E8D100B514F3 /* NIPaths.h */,\n\t\t\t\t66A03C5A13E6E8D100B514F3 /* NIPaths.m */,\n\t\t\t\t66A03C5B13E6E8D100B514F3 /* NIPreprocessorMacros.h */,\n\t\t\t\t66A03C5C13E6E8D100B514F3 /* NIRuntimeClassModifications.h */,\n\t\t\t\t66A03C5D13E6E8D100B514F3 /* NIRuntimeClassModifications.m */,\n\t\t\t\t66A03C5E13E6E8D100B514F3 /* NISDKAvailability.h */,\n\t\t\t\t66A03C5F13E6E8D100B514F3 /* NISDKAvailability.m */,\n\t\t\t\t669819D9159B927B00C2D3EF /* NISnapshotRotation.h */,\n\t\t\t\t669819DA159B927B00C2D3EF /* NISnapshotRotation.m */,\n\t\t\t\t66A03C6013E6E8D100B514F3 /* NIState.h */,\n\t\t\t\t66A03C6113E6E8D100B514F3 /* NIState.m */,\n\t\t\t\t6675E4B11455FCC5007D172F /* NIViewRecycler.h */,\n\t\t\t\t6675E4B21455FCC5007D172F /* NIViewRecycler.m */,\n\t\t\t\t66AF0BC8189C1E2700020FEE /* UIResponder+NimbusCore.h */,\n\t\t\t\t66AF0BC9189C1E2700020FEE /* UIResponder+NimbusCore.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = core/src;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t66A03C9F13E6E90500B514F3 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03CB513E6EF6D00B514F3 /* resources */,\n\t\t\t\t66E8CED114D089E500600592 /* NICommonMetricsTests.m */,\n\t\t\t\t66A03CA013E6E90500B514F3 /* NICoreAdditionTests.m */,\n\t\t\t\t66A03CA113E6E90500B514F3 /* NIDataStructureTests.m */,\n\t\t\t\t66A03CA213E6E90500B514F3 /* NIFoundationMethodsTests.m */,\n\t\t\t\t66A03CA313E6E90500B514F3 /* NIMemoryCacheTests.m */,\n\t\t\t\t6607851B14D245BE00FE3283 /* NINetworkActivityTests.m */,\n\t\t\t\t66A03CA413E6E90500B514F3 /* NINonEmptyCollectionTestingTests.m */,\n\t\t\t\t66A03CA513E6E90500B514F3 /* NINonRetainingCollectionsTests.m */,\n\t\t\t\t66A03CA713E6E90500B514F3 /* NIRuntimeClassModificationsTests.m */,\n\t\t\t\t6607851F14D33EA900FE3283 /* NIStateTests.m */,\n\t\t\t\t6675E4B914560397007D172F /* NIViewRecyclerTests.m */,\n\t\t\t\t66A03CA813E6E90500B514F3 /* NSDate+UnitTesting.h */,\n\t\t\t\t66A03CA913E6E90500B514F3 /* NSDate+UnitTesting.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tpath = core/unittests;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t66A03CB513E6EF6D00B514F3 /* resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03D5B13E6F9A900B514F3 /* NimbusCoreTests-Info.plist */,\n\t\t\t\t66A03CB313E6EF1F00B514F3 /* nimbus64x64.png */,\n\t\t\t);\n\t\t\tname = resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A03CC113E6F0ED00B514F3 /* NimbusLauncher */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03CF613E6F13700B514F3 /* deps */,\n\t\t\t\t66A03CE613E6F10C00B514F3 /* src */,\n\t\t\t\t66A03D5C13E6F9B100B514F3 /* unittests */,\n\t\t\t);\n\t\t\tpath = NimbusLauncher;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A03CE613E6F10C00B514F3 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66BB4F8A15958A5800020EE8 /* NILauncherButtonView.h */,\n\t\t\t\t66BB4F8B15958A5800020EE8 /* NILauncherButtonView.m */,\n\t\t\t\t66BB4F8C15958A5800020EE8 /* NILauncherPageView.h */,\n\t\t\t\t66BB4F8D15958A5800020EE8 /* NILauncherPageView.m */,\n\t\t\t\t66BB4F8E15958A5800020EE8 /* NILauncherView.h */,\n\t\t\t\t66BB4F8F15958A5800020EE8 /* NILauncherView.m */,\n\t\t\t\t66BB4F9015958A5800020EE8 /* NILauncherViewController.h */,\n\t\t\t\t66BB4F9115958A5800020EE8 /* NILauncherViewController.m */,\n\t\t\t\t66BB4F9215958A5800020EE8 /* NILauncherViewModel.h */,\n\t\t\t\t66BB4F9315958A5800020EE8 /* NILauncherViewModel.m */,\n\t\t\t\t66BB4F9415958A5800020EE8 /* NILauncherViewObject.h */,\n\t\t\t\t66BB4F9515958A5800020EE8 /* NILauncherViewObject.m */,\n\t\t\t\t66BB4F9615958A5800020EE8 /* NimbusLauncher.h */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = launcher/src;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t66A03D2913E6F97500B514F3 /* NimbusNetworkImage */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03D4C13E6F99400B514F3 /* deps */,\n\t\t\t\t66A03D4F13E6F99400B514F3 /* src */,\n\t\t\t\t66A03D5F13E6F9DF00B514F3 /* unittests */,\n\t\t\t);\n\t\t\tpath = NimbusNetworkImage;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A03D4F13E6F99400B514F3 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03D5213E6F99400B514F3 /* NimbusNetworkImage.h */,\n\t\t\t\t66D2FDDB1593F3A600B2BEFD /* NIImageProcessing.h */,\n\t\t\t\t66D2FDDC1593F3A600B2BEFD /* NIImageProcessing.m */,\n\t\t\t\t66A03D5313E6F99400B514F3 /* NINetworkImageView.h */,\n\t\t\t\t66A03D5413E6F99400B514F3 /* NINetworkImageView.m */,\n\t\t\t\t6617B01318A90D5D00037E75 /* NIImageResponseSerializer.h */,\n\t\t\t\t6617B01418A90D5D00037E75 /* NIImageResponseSerializer.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = networkimage/src;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t66A03D5C13E6F9B100B514F3 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03D5D13E6F9BA00B514F3 /* resources */,\n\t\t\t\t666C3D3214D0AE4F00F337D6 /* NILauncherViewTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A03D5D13E6F9BA00B514F3 /* resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A03D5E13E6F9C700B514F3 /* NimbusLauncherTests-Info.plist */,\n\t\t\t);\n\t\t\tname = resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A03D5F13E6F9DF00B514F3 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t666C3D4E14D0B0ED00F337D6 /* NimbusNetworkImageTests-Info.plist */,\n\t\t\t\t666C3D4F14D0B0ED00F337D6 /* NINetworkImageViewTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tpath = ../networkimage/unittests;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t66A0B09B14BD1069003FA413 /* NimbusNetworkControllers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A0B0C814BD1586003FA413 /* deps */,\n\t\t\t\t66A0B0BD14BD1083003FA413 /* src */,\n\t\t\t\t66A0B0BE14BD1087003FA413 /* unittests */,\n\t\t\t);\n\t\t\tname = NimbusNetworkControllers;\n\t\t\tpath = NetworkControllers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A0B0BD14BD1083003FA413 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66A0B0BF14BD1116003FA413 /* NimbusNetworkControllers.h */,\n\t\t\t\t66A0B0C014BD1116003FA413 /* NINetworkTableViewController.h */,\n\t\t\t\t66A0B0C114BD1116003FA413 /* NINetworkTableViewController.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66A0B0BE14BD1087003FA413 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t666C3D4B14D0B05800F337D6 /* NetworkControllersTests-Info.plist */,\n\t\t\t\t666C3D4C14D0B05800F337D6 /* NINetworkTableViewControllerTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66C3A6A3143D61130048542F /* NimbusCss */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66B10906144D4C15004576D1 /* deps */,\n\t\t\t\t66832C93143D63B4003E413C /* src */,\n\t\t\t\t66832C95143D63BF003E413C /* unittests */,\n\t\t\t\t66832C96143D63C6003E413C /* grammar */,\n\t\t\t);\n\t\t\tpath = NimbusCss;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66D2FDE01594083800B2BEFD /* AFNetworking */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6617AFCE18A90CCC00037E75 /* UIKit */,\n\t\t\t\t6617AFCF18A90CDE00037E75 /* AFHTTPRequestOperation.h */,\n\t\t\t\t6617AFD018A90CDE00037E75 /* AFHTTPRequestOperation.m */,\n\t\t\t\t6617AFD118A90CDE00037E75 /* AFHTTPRequestOperationManager.h */,\n\t\t\t\t6617AFD218A90CDE00037E75 /* AFHTTPRequestOperationManager.m */,\n\t\t\t\t6617AFD318A90CDE00037E75 /* AFHTTPSessionManager.h */,\n\t\t\t\t6617AFD418A90CDE00037E75 /* AFHTTPSessionManager.m */,\n\t\t\t\t6617AFD518A90CDE00037E75 /* AFNetworking.h */,\n\t\t\t\t6617AFD618A90CDE00037E75 /* AFNetworkReachabilityManager.h */,\n\t\t\t\t6617AFD718A90CDE00037E75 /* AFNetworkReachabilityManager.m */,\n\t\t\t\t6617AFD818A90CDE00037E75 /* AFSecurityPolicy.h */,\n\t\t\t\t6617AFD918A90CDE00037E75 /* AFSecurityPolicy.m */,\n\t\t\t\t6617AFDA18A90CDE00037E75 /* AFURLConnectionOperation.h */,\n\t\t\t\t6617AFDB18A90CDE00037E75 /* AFURLConnectionOperation.m */,\n\t\t\t\t6617AFDC18A90CDE00037E75 /* AFURLRequestSerialization.h */,\n\t\t\t\t6617AFDD18A90CDE00037E75 /* AFURLRequestSerialization.m */,\n\t\t\t\t6617AFDE18A90CDE00037E75 /* AFURLResponseSerialization.h */,\n\t\t\t\t6617AFDF18A90CDE00037E75 /* AFURLResponseSerialization.m */,\n\t\t\t\t6617AFE018A90CDE00037E75 /* AFURLSessionManager.h */,\n\t\t\t\t6617AFE118A90CDE00037E75 /* AFURLSessionManager.m */,\n\t\t\t);\n\t\t\tname = AFNetworking;\n\t\t\tpath = ../thirdparty/AFNetworking/AFNetworking;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66E1CDE1159161ED004DA4A2 /* NimbusBadge */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t661F28AA1591B03400D11FC3 /* deps */,\n\t\t\t\t661F28A91591B01D00D11FC3 /* src */,\n\t\t\t\t661F28AB1591B03700D11FC3 /* unittests */,\n\t\t\t);\n\t\t\tpath = NimbusBadge;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66E8CED414D08B8000600592 /* Configs */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66E8CED514D08B9F00600592 /* lib.xcconfig */,\n\t\t\t\t66E8CED614D08BAE00600592 /* unittest.xcconfig */,\n\t\t\t);\n\t\t\tname = Configs;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66FC984C1703F9D7004E8FB8 /* NimbusCollections */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66FC98591703F9F5004E8FB8 /* src */,\n\t\t\t\tD5BCE8991D75397600B6715F /* unittests */,\n\t\t\t);\n\t\t\tname = NimbusCollections;\n\t\t\tpath = collections;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66FC98591703F9F5004E8FB8 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66DCB7891717755B00205745 /* NICollectionViewActions.h */,\n\t\t\t\t66DCB78A1717755B00205745 /* NICollectionViewActions.m */,\n\t\t\t\t66FC985A1703FA51004E8FB8 /* NICollectionViewCellFactory.h */,\n\t\t\t\t66FC985B1703FA51004E8FB8 /* NICollectionViewCellFactory.m */,\n\t\t\t\t66FC98601703FA51004E8FB8 /* NICollectionViewModel.h */,\n\t\t\t\t66FC98611703FA51004E8FB8 /* NICollectionViewModel.m */,\n\t\t\t\t66FC98621703FA51004E8FB8 /* NICollectionViewModel+Private.h */,\n\t\t\t\t66FC985C1703FA51004E8FB8 /* NimbusCollections.h */,\n\t\t\t\t9B22BD971725E75E000FDB01 /* NIMutableCollectionViewModel.h */,\n\t\t\t\t9B22BD981725E75E000FDB01 /* NIMutableCollectionViewModel.m */,\n\t\t\t\t9B22BD9B1725ECB4000FDB01 /* NIMutableCollectionViewModel+Private.h */,\n\t\t\t);\n\t\t\tpath = src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66FE7D5513FB550A0061B987 /* examples */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66FE7D5613FB550A0061B987 /* ExampleRuntimeDebugging.m */,\n\t\t\t);\n\t\t\tname = examples;\n\t\t\tpath = core/examples;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t66FE7D5F13FB83620061B987 /* examples */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66FE7D6013FB83620061B987 /* ExampleStaticTableModel.m */,\n\t\t\t);\n\t\t\tname = examples;\n\t\t\tpath = models/examples;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t66FE7D6313FB83620061B987 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66FE7D6413FB83620061B987 /* NimbusModels.h */,\n\t\t\t\t66FE7D6513FB83620061B987 /* NITableViewModel.h */,\n\t\t\t\t66FE7D6613FB83620061B987 /* NITableViewModel.m */,\n\t\t\t\t6626330B14995C4600B99898 /* NITableViewModel+Private.h */,\n\t\t\t\t66D2E53D15D9432000281511 /* NIMutableTableViewModel.h */,\n\t\t\t\t66D2E53E15D9432000281511 /* NIMutableTableViewModel.m */,\n\t\t\t\t66D2E54115D9438D00281511 /* NIMutableTableViewModel+Private.h */,\n\t\t\t\t6668867D156AD148006E874F /* NICellCatalog.h */,\n\t\t\t\t6668867E156AD148006E874F /* NICellCatalog.m */,\n\t\t\t\t66B6710515AA820700FE4AE8 /* NICellBackgrounds.h */,\n\t\t\t\t66B6710615AA820700FE4AE8 /* NICellBackgrounds.m */,\n\t\t\t\t667A749913FE20BD009D277D /* NIFormCellCatalog.h */,\n\t\t\t\t667A749A13FE20BD009D277D /* NIFormCellCatalog.m */,\n\t\t\t\t667A749B13FE20BD009D277D /* NICellFactory.h */,\n\t\t\t\t667A749C13FE20BD009D277D /* NICellFactory.m */,\n\t\t\t\t66688686156ADDB0006E874F /* NIRadioGroup.h */,\n\t\t\t\t66688687156ADDB1006E874F /* NIRadioGroup.m */,\n\t\t\t\t667DD369156D78980045ABBB /* NIRadioGroupController.h */,\n\t\t\t\t667DD36A156D78980045ABBB /* NIRadioGroupController.m */,\n\t\t\t\t66416179156B516E0018AC1C /* NITableViewActions.h */,\n\t\t\t\t6641617A156B516E0018AC1C /* NITableViewActions.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = models/src;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t66FE7D6713FB83620061B987 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66FE7D6813FB83620061B987 /* NimbusModelsTests-Info.plist */,\n\t\t\t\t6623EB6C1402ECE400E0E61A /* NITableViewModelTests.m */,\n\t\t\t\t66D2E54615D9503100281511 /* NIMutableTableViewModelTests.m */,\n\t\t\t\t6672DAB415B87E4B00DFE81F /* NICellFactoryTests.m */,\n\t\t\t\tD526CF4A18B826A600991F7A /* NICellCatalogTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tpath = models/unittests;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\tC7A8791A16D7344F00A0C23F /* Styleable Nimbus Views */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC7A8791B16D7348700A0C23F /* NITextField+NIStyleable.h */,\n\t\t\t\tC7A8791C16D7348700A0C23F /* NITextField+NIStyleable.m */,\n\t\t\t);\n\t\t\tname = \"Styleable Nimbus Views\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC7BBC6B116DDC09400833DC9 /* NimbusTextField */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC7BBC6B516DDC0DB00833DC9 /* deps */,\n\t\t\t\tC7BBC6B616DDC0DB00833DC9 /* src */,\n\t\t\t);\n\t\t\tname = NimbusTextField;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC7BBC6B616DDC0DB00833DC9 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC7BBC6B716DDC0DB00833DC9 /* NITextField.h */,\n\t\t\t\tC7BBC6B816DDC0DB00833DC9 /* NITextField.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = textfield/src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tD5BCE8991D75397600B6715F /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD5BCE8C51D76359200B6715F /* NimbusCollectionsTests-Info.plist */,\n\t\t\t\tD5BCE8B91D753A1100B6715F /* NimbusCollectionsTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tDB3A230B13FD4B8E00614220 /* NimbusAttributedLabel */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6693C3AC158BFC7E00950D42 /* deps */,\n\t\t\t\tDB3A233113FD4BE500614220 /* src */,\n\t\t\t\tDB3A233913FD4C2900614220 /* unittests */,\n\t\t\t);\n\t\t\tpath = NimbusAttributedLabel;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tDB3A233113FD4BE500614220 /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tDB3A233413FD4BE500614220 /* NimbusAttributedLabel.h */,\n\t\t\t\tDB3A233213FD4BE500614220 /* NIAttributedLabel.h */,\n\t\t\t\tD5E59299221245200076B697 /* NIAttributedLabel+Testing.h */,\n\t\t\t\tDB3A233313FD4BE500614220 /* NIAttributedLabel.m */,\n\t\t\t\t6693C2F3158BB8E900950D42 /* NSMutableAttributedString+NimbusAttributedLabel.h */,\n\t\t\t\t6693C2F4158BB8E900950D42 /* NSMutableAttributedString+NimbusAttributedLabel.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = attributedlabel/src;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\tDB3A233913FD4C2900614220 /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tDB3A233A13FD4C2900614220 /* NimbusAttributedLabelTests-Info.plist */,\n\t\t\t\t666C3D1B14D0AB7E00F337D6 /* NIAttributedLabelTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tpath = attributedlabel/unittests;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\tDB84BD9A13EFDE3C00DACCFE /* NimbusWebController */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6661BAFF13F0AA6000D14F92 /* deps */,\n\t\t\t\tDB84BDA713EFDF5900DACCFE /* src */,\n\t\t\t\tDB84BDAF13EFDF6900DACCFE /* unittests */,\n\t\t\t);\n\t\t\tname = NimbusWebController;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tDB84BDA713EFDF5900DACCFE /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tDB84BDA813EFDF5900DACCFE /* NimbusWebController.h */,\n\t\t\t\tDB84BDA913EFDF5900DACCFE /* NIWebController.h */,\n\t\t\t\tDB84BDAA13EFDF5900DACCFE /* NIWebController.m */,\n\t\t\t);\n\t\t\tname = src;\n\t\t\tpath = webcontroller/src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tDB84BDAF13EFDF6900DACCFE /* unittests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tDB84BDB013EFDF6900DACCFE /* NimbusWebControllerTests-Info.plist */,\n\t\t\t\t666C3D3814D0AEBF00F337D6 /* NIWebControllerTests.m */,\n\t\t\t);\n\t\t\tname = unittests;\n\t\t\tpath = webcontroller/unittests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\t663B523D1445052700CC26DF /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t663B52671445061B00CC26DF /* NimbusPagingScrollView.h in Headers */,\n\t\t\t\t663B526A1445070100CC26DF /* NIPagingScrollView.h in Headers */,\n\t\t\t\t66F27D55145B7A5F00AFCA08 /* NIPagingScrollViewPage.h in Headers */,\n\t\t\t\t66CB9A211654307A00FFB4BF /* NIPagingScrollView+Subclassing.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6661BBCA13F1A3BB00D14F92 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66FE7D6B13FB83620061B987 /* NimbusModels.h in Headers */,\n\t\t\t\t66FE7D6C13FB83620061B987 /* NITableViewModel.h in Headers */,\n\t\t\t\t667A749F13FE20BD009D277D /* NIFormCellCatalog.h in Headers */,\n\t\t\t\t667A74A113FE20BD009D277D /* NICellFactory.h in Headers */,\n\t\t\t\t6626330C14995C4600B99898 /* NITableViewModel+Private.h in Headers */,\n\t\t\t\t6668867F156AD148006E874F /* NICellCatalog.h in Headers */,\n\t\t\t\t66688688156ADDB3006E874F /* NIRadioGroup.h in Headers */,\n\t\t\t\t6641617B156B516E0018AC1C /* NITableViewActions.h in Headers */,\n\t\t\t\t667DD36B156D78980045ABBB /* NIRadioGroupController.h in Headers */,\n\t\t\t\t66B6710715AA820700FE4AE8 /* NICellBackgrounds.h in Headers */,\n\t\t\t\t66D2E53F15D9432000281511 /* NIMutableTableViewModel.h in Headers */,\n\t\t\t\t66D2E54315D9438D00281511 /* NIMutableTableViewModel+Private.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675722713E765BF0076F555 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6675726313E765F70076F555 /* NIDeviceInfo.h in Headers */,\n\t\t\t\t6675726513E765F70076F555 /* NimbusOverview.h in Headers */,\n\t\t\t\t6675726613E765F70076F555 /* NIOverview.h in Headers */,\n\t\t\t\t6675726813E765F70076F555 /* NIOverviewGraphView.h in Headers */,\n\t\t\t\t6675726A13E765F70076F555 /* NIOverviewLogger.h in Headers */,\n\t\t\t\t6675726C13E765F70076F555 /* NIOverviewPageView.h in Headers */,\n\t\t\t\t6675726E13E765F70076F555 /* NIOverviewSwizzling.h in Headers */,\n\t\t\t\t6675727013E765F70076F555 /* NIOverviewView.h in Headers */,\n\t\t\t\t669F0CFF158000810069B972 /* NIOverviewMemoryCacheController.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675727813E769150076F555 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t667572AE13E7692F0076F555 /* NimbusPhotos.h in Headers */,\n\t\t\t\t667572AF13E7692F0076F555 /* NIPhotoAlbumScrollView.h in Headers */,\n\t\t\t\t667572B113E7692F0076F555 /* NIPhotoScrollView.h in Headers */,\n\t\t\t\t667572B313E7692F0076F555 /* NIPhotoScrubberView.h in Headers */,\n\t\t\t\t667572B513E7692F0076F555 /* NIToolbarPhotoViewController.h in Headers */,\n\t\t\t\t66F27D60145BA32500AFCA08 /* NIPhotoAlbumScrollViewDataSource.h in Headers */,\n\t\t\t\t66F27D62145BA35C00AFCA08 /* NIPhotoAlbumScrollViewDelegate.h in Headers */,\n\t\t\t\t66F27D64145BA4E500AFCA08 /* NIPhotoScrollViewDelegate.h in Headers */,\n\t\t\t\t66F27D66145BA56400AFCA08 /* NIPhotoScrollViewPhotoSize.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675731013E771380076F555 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6675733E13E7718B0076F555 /* NIInterapp.h in Headers */,\n\t\t\t\t6675734513E773AA0076F555 /* NimbusInterapp.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03C0713E6E85E00B514F3 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66A03C7113E6E8D100B514F3 /* NICommonMetrics.h in Headers */,\n\t\t\t\t66A03C7513E6E8D100B514F3 /* NIDebuggingTools.h in Headers */,\n\t\t\t\t66A03C7713E6E8D100B514F3 /* NIDeviceOrientation.h in Headers */,\n\t\t\t\t66A03C7913E6E8D100B514F3 /* NIError.h in Headers */,\n\t\t\t\t66A03C7B13E6E8D100B514F3 /* NIFoundationMethods.h in Headers */,\n\t\t\t\t66A03C7D13E6E8D100B514F3 /* NIInMemoryCache.h in Headers */,\n\t\t\t\t66A03C7F13E6E8D100B514F3 /* NimbusCore+Additions.h in Headers */,\n\t\t\t\t66A03C8013E6E8D100B514F3 /* NimbusCore.h in Headers */,\n\t\t\t\t66A03C8113E6E8D100B514F3 /* NINetworkActivity.h in Headers */,\n\t\t\t\t66A03C8513E6E8D100B514F3 /* NINonRetainingCollections.h in Headers */,\n\t\t\t\t66A03C8713E6E8D100B514F3 /* NIOperations.h in Headers */,\n\t\t\t\t66A03C8913E6E8D100B514F3 /* NIPaths.h in Headers */,\n\t\t\t\t66A03C8B13E6E8D100B514F3 /* NIPreprocessorMacros.h in Headers */,\n\t\t\t\t66AF0BCA189C1E2700020FEE /* UIResponder+NimbusCore.h in Headers */,\n\t\t\t\t66A03C8C13E6E8D100B514F3 /* NIRuntimeClassModifications.h in Headers */,\n\t\t\t\t66A03C8E13E6E8D100B514F3 /* NISDKAvailability.h in Headers */,\n\t\t\t\t66A03C9013E6E8D100B514F3 /* NIState.h in Headers */,\n\t\t\t\t6675E4B31455FCC5007D172F /* NIViewRecycler.h in Headers */,\n\t\t\t\t66C115411486ACE3003C9AC6 /* NIOperations+Subclassing.h in Headers */,\n\t\t\t\t66E8CEE414D08F8200600592 /* NINonEmptyCollectionTesting.h in Headers */,\n\t\t\t\t669819DB159B927B00C2D3EF /* NISnapshotRotation.h in Headers */,\n\t\t\t\t66C1D83D16B9CE90003E855B /* NIImageUtilities.h in Headers */,\n\t\t\t\t66C1D8C116B9ED65003E855B /* NIButtonUtilities.h in Headers */,\n\t\t\t\tC7A8791D16D7348700A0C23F /* NITextField+NIStyleable.h in Headers */,\n\t\t\t\t6617FD0A171F6A92006E0DF8 /* NIActions.h in Headers */,\n\t\t\t\t668EA9BD17206DF70056C8C3 /* NIActions+Subclassing.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03CBD13E6F0ED00B514F3 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66BB4F9815958A5800020EE8 /* NILauncherButtonView.h in Headers */,\n\t\t\t\t66BB4F9A15958A5800020EE8 /* NILauncherPageView.h in Headers */,\n\t\t\t\t66BB4F9C15958A5800020EE8 /* NILauncherView.h in Headers */,\n\t\t\t\t66BB4F9E15958A5800020EE8 /* NILauncherViewController.h in Headers */,\n\t\t\t\t66BB4FA015958A5800020EE8 /* NILauncherViewModel.h in Headers */,\n\t\t\t\t66BB4FA215958A5800020EE8 /* NILauncherViewObject.h in Headers */,\n\t\t\t\t66BB4FA415958A5800020EE8 /* NimbusLauncher.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03D2513E6F97500B514F3 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6617B01518A90D5D00037E75 /* NIImageResponseSerializer.h in Headers */,\n\t\t\t\t66A03D5813E6F99400B514F3 /* NimbusNetworkImage.h in Headers */,\n\t\t\t\t66A03D5913E6F99400B514F3 /* NINetworkImageView.h in Headers */,\n\t\t\t\t66D2FDDD1593F3A600B2BEFD /* NIImageProcessing.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A0B09714BD1069003FA413 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66A0B0C214BD1116003FA413 /* NimbusNetworkControllers.h in Headers */,\n\t\t\t\t66A0B0C314BD1116003FA413 /* NINetworkTableViewController.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66C3A69F143D61130048542F /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66832CB9143D681B003E413C /* NimbusCSS.h in Headers */,\n\t\t\t\t66832CC4143D7898003E413C /* NICSSParser.h in Headers */,\n\t\t\t\t66832CF2143E0AD9003E413C /* CSSTokens.h in Headers */,\n\t\t\t\t66832CF6143E0C35003E413C /* NIStylesheet.h in Headers */,\n\t\t\t\t66832CFC143E2C0D003E413C /* NIDOM.h in Headers */,\n\t\t\t\t66832D07143E3A30003E413C /* NICSSRuleset.h in Headers */,\n\t\t\t\t66832D0A143E3B55003E413C /* NIStyleable.h in Headers */,\n\t\t\t\t66832D0F143E3C32003E413C /* UILabel+NIStyleable.h in Headers */,\n\t\t\t\t66832D1314416368003E413C /* UIView+NIStyleable.h in Headers */,\n\t\t\t\t66832DA214421B4A003E413C /* UINavigationBar+NIStyleable.h in Headers */,\n\t\t\t\t66832E0614435071003E413C /* NIChameleonObserver.h in Headers */,\n\t\t\t\t66B10900144C931F004576D1 /* UIButton+NIStyleable.h in Headers */,\n\t\t\t\t668ECDC71455C17200455266 /* NIStylesheetCache.h in Headers */,\n\t\t\t\t443589C8155190B300757E50 /* UISearchBar+NIStyleable.h in Headers */,\n\t\t\t\t443589C9155190CA00757E50 /* UIToolbar+NIStyleable.h in Headers */,\n\t\t\t\t664EFB6215598CDF009826AB /* UIActivityIndicatorView+NIStyleable.h in Headers */,\n\t\t\t\t666903851561B46900C44A70 /* UITableView+NIStyleable.h in Headers */,\n\t\t\t\t666903891561B6A000C44A70 /* UIScrollView+NIStyleable.h in Headers */,\n\t\t\t\tC743F6EA16D2652F00A933B7 /* NIUserInterfaceString.h in Headers */,\n\t\t\t\tC7A8792216D7B96200A0C23F /* UITextField+NIStyleable.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC7BBC6DD16DDC0E700833DC9 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC7BBC6FE16DDC0E700833DC9 /* NITextField.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB3A230713FD4B8E00614220 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tD5E5929D221246140076B697 /* NIAttributedLabel+Testing.h in Headers */,\n\t\t\t\tDB3A233613FD4BE500614220 /* NIAttributedLabel.h in Headers */,\n\t\t\t\tDB3A233813FD4BE500614220 /* NimbusAttributedLabel.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB84BD7213EFDDC900DACCFE /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tDB84BDAC13EFDF5900DACCFE /* NimbusWebController.h in Headers */,\n\t\t\t\tDB84BDAD13EFDF5900DACCFE /* NIWebController.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\t663B523E1445052700CC26DF /* NimbusPagingScrollView */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 663B525C1445052800CC26DF /* Build configuration list for PBXNativeTarget \"NimbusPagingScrollView\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t663B523B1445052700CC26DF /* Sources */,\n\t\t\t\t663B523C1445052700CC26DF /* Frameworks */,\n\t\t\t\t666F739914BBFD6400D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\t663B523D1445052700CC26DF /* 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 = NimbusPagingScrollView;\n\t\t\tproductName = NimbusPagingScrollView;\n\t\t\tproductReference = 663B523F1445052700CC26DF /* libNimbusPagingScrollView.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t663B524B1445052800CC26DF /* NimbusPagingScrollViewTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 663B525F1445052800CC26DF /* Build configuration list for PBXNativeTarget \"NimbusPagingScrollViewTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t663B52471445052800CC26DF /* Sources */,\n\t\t\t\t663B52481445052800CC26DF /* Frameworks */,\n\t\t\t\t663B52491445052800CC26DF /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t666C3D5F14D0B19C00F337D6 /* PBXTargetDependency */,\n\t\t\t\t663B52511445052800CC26DF /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusPagingScrollViewTests;\n\t\t\tproductName = NimbusPagingScrollViewTests;\n\t\t\tproductReference = 663B524C1445052800CC26DF /* NimbusPagingScrollViewTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t6661BBCB13F1A3BB00D14F92 /* NimbusModels */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6661BBEA13F1A3BC00D14F92 /* Build configuration list for PBXNativeTarget \"NimbusModels\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6661BBC813F1A3BB00D14F92 /* Sources */,\n\t\t\t\t6661BBC913F1A3BB00D14F92 /* Frameworks */,\n\t\t\t\t666F739C14BBFD7400D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\t6661BBCA13F1A3BB00D14F92 /* 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 = NimbusModels;\n\t\t\tproductName = NimbusTables;\n\t\t\tproductReference = 6661BBCC13F1A3BB00D14F92 /* libNimbusModels.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t6661BBD813F1A3BB00D14F92 /* NimbusModelsTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6661BBED13F1A3BC00D14F92 /* Build configuration list for PBXNativeTarget \"NimbusModelsTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6661BBD413F1A3BB00D14F92 /* Sources */,\n\t\t\t\t6661BBD513F1A3BB00D14F92 /* Frameworks */,\n\t\t\t\t6661BBD613F1A3BB00D14F92 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t666C3D6A14D0B1BA00F337D6 /* PBXTargetDependency */,\n\t\t\t\t6661BBDF13F1A3BB00D14F92 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusModelsTests;\n\t\t\tproductName = NimbusTablesTests;\n\t\t\tproductReference = 6661BBD913F1A3BB00D14F92 /* NimbusModelsTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t6675722813E765BF0076F555 /* NimbusOverview */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6675724C13E765BF0076F555 /* Build configuration list for PBXNativeTarget \"NimbusOverview\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6675722513E765BF0076F555 /* Sources */,\n\t\t\t\t6675722613E765BF0076F555 /* Frameworks */,\n\t\t\t\t666F739814BBFD5F00D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\t6675722713E765BF0076F555 /* 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 = NimbusOverview;\n\t\t\tproductName = NimbusOverview;\n\t\t\tproductReference = 6675722913E765BF0076F555 /* libNimbusOverview.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t6675723513E765BF0076F555 /* NimbusOverviewTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6675724D13E765BF0076F555 /* Build configuration list for PBXNativeTarget \"NimbusOverviewTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6675723113E765BF0076F555 /* Sources */,\n\t\t\t\t6675723213E765BF0076F555 /* Frameworks */,\n\t\t\t\t6675723313E765BF0076F555 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t8B94F877194664D900A63185 /* PBXTargetDependency */,\n\t\t\t\t8B94F875194664D500A63185 /* PBXTargetDependency */,\n\t\t\t\t6675723C13E765BF0076F555 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusOverviewTests;\n\t\t\tproductName = NimbusOverviewTests;\n\t\t\tproductReference = 6675723613E765BF0076F555 /* NimbusOverviewTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t6675727913E769150076F555 /* NimbusPhotos */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6675729913E769150076F555 /* Build configuration list for PBXNativeTarget \"NimbusPhotos\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6675727613E769150076F555 /* Sources */,\n\t\t\t\t6675727713E769150076F555 /* Frameworks */,\n\t\t\t\t666F739A14BBFD6900D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\t6675727813E769150076F555 /* 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 = NimbusPhotos;\n\t\t\tproductName = NimbusPhotos;\n\t\t\tproductReference = 6675727A13E769150076F555 /* libNimbusPhotos.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t6675728613E769150076F555 /* NimbusPhotosTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6675729C13E769150076F555 /* Build configuration list for PBXNativeTarget \"NimbusPhotosTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6675728213E769150076F555 /* Sources */,\n\t\t\t\t6675728313E769150076F555 /* Frameworks */,\n\t\t\t\t6675728413E769150076F555 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t666C3D6414D0B1AA00F337D6 /* PBXTargetDependency */,\n\t\t\t\t666C3D6614D0B1AA00F337D6 /* PBXTargetDependency */,\n\t\t\t\t6675728D13E769150076F555 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusPhotosTests;\n\t\t\tproductName = NimbusPhotosTests;\n\t\t\tproductReference = 6675728713E769150076F555 /* NimbusPhotosTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t6675731113E771380076F555 /* NimbusInterapp */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6675733113E771380076F555 /* Build configuration list for PBXNativeTarget \"NimbusInterapp\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6675730E13E771380076F555 /* Sources */,\n\t\t\t\t6675730F13E771380076F555 /* Frameworks */,\n\t\t\t\t666F739514BBFD4F00D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\t6675731013E771380076F555 /* 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 = NimbusInterapp;\n\t\t\tproductName = NimbusInterapp;\n\t\t\tproductReference = 6675731213E771380076F555 /* libNimbusInterapp.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t6675731E13E771380076F555 /* NimbusInterappTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6675733413E771380076F555 /* Build configuration list for PBXNativeTarget \"NimbusInterappTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6675731A13E771380076F555 /* Sources */,\n\t\t\t\t6675731B13E771380076F555 /* Frameworks */,\n\t\t\t\t6675731C13E771380076F555 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t666C3D2E14D0ACDD00F337D6 /* PBXTargetDependency */,\n\t\t\t\t6675732513E771380076F555 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusInterappTests;\n\t\t\tproductName = NimbusInterappTests;\n\t\t\tproductReference = 6675731F13E771380076F555 /* NimbusInterappTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t66A03C0813E6E85E00B514F3 /* NimbusCore */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66A03C2E13E6E85E00B514F3 /* Build configuration list for PBXNativeTarget \"NimbusCore\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66A03C0513E6E85E00B514F3 /* Sources */,\n\t\t\t\t66A03C0613E6E85E00B514F3 /* Frameworks */,\n\t\t\t\t666F736214BBBFF300D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\t66A03C0713E6E85E00B514F3 /* 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 = NimbusCore;\n\t\t\tproductName = NimbusCore;\n\t\t\tproductReference = 66A03C0913E6E85E00B514F3 /* libNimbusCore.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t66A03C1813E6E85E00B514F3 /* NimbusCoreTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66A03C3113E6E85E00B514F3 /* Build configuration list for PBXNativeTarget \"NimbusCoreTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66A03C1413E6E85E00B514F3 /* Sources */,\n\t\t\t\t66A03C1513E6E85E00B514F3 /* Frameworks */,\n\t\t\t\t66A03C1613E6E85E00B514F3 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t66A03C2213E6E85E00B514F3 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusCoreTests;\n\t\t\tproductName = NimbusCoreTests;\n\t\t\tproductReference = 66A03C1913E6E85E00B514F3 /* NimbusCoreTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t66A03CBE13E6F0ED00B514F3 /* NimbusLauncher */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66A03CDE13E6F0EE00B514F3 /* Build configuration list for PBXNativeTarget \"NimbusLauncher\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66A03CBB13E6F0ED00B514F3 /* Sources */,\n\t\t\t\t66A03CBC13E6F0ED00B514F3 /* Frameworks */,\n\t\t\t\t666F739614BBFD5500D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\t66A03CBD13E6F0ED00B514F3 /* 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 = NimbusLauncher;\n\t\t\tproductName = NimbusLauncher;\n\t\t\tproductReference = 66A03CBF13E6F0ED00B514F3 /* libNimbusLauncher.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t66A03CCB13E6F0EE00B514F3 /* NimbusLauncherTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66A03CE113E6F0EE00B514F3 /* Build configuration list for PBXNativeTarget \"NimbusLauncherTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66A03CC713E6F0EE00B514F3 /* Sources */,\n\t\t\t\t66A03CC813E6F0EE00B514F3 /* Frameworks */,\n\t\t\t\t66A03CC913E6F0EE00B514F3 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t666C3D4314D0AF8000F337D6 /* PBXTargetDependency */,\n\t\t\t\t66A03CD213E6F0EE00B514F3 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusLauncherTests;\n\t\t\tproductName = NimbusLauncherTests;\n\t\t\tproductReference = 66A03CCC13E6F0EE00B514F3 /* NimbusLauncherTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t66A03D2613E6F97500B514F3 /* NimbusNetworkImage */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66A03D4613E6F97600B514F3 /* Build configuration list for PBXNativeTarget \"NimbusNetworkImage\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66A03D2313E6F97500B514F3 /* Sources */,\n\t\t\t\t66A03D2413E6F97500B514F3 /* Frameworks */,\n\t\t\t\t666F739714BBFD5A00D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\t66A03D2513E6F97500B514F3 /* 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 = NimbusNetworkImage;\n\t\t\tproductName = NimbusNetworkImage;\n\t\t\tproductReference = 66A03D2713E6F97500B514F3 /* libNimbusNetworkImage.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t66A03D3313E6F97500B514F3 /* NimbusNetworkImageTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66A03D4913E6F97600B514F3 /* Build configuration list for PBXNativeTarget \"NimbusNetworkImageTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66A03D2F13E6F97500B514F3 /* Sources */,\n\t\t\t\t66A03D3013E6F97500B514F3 /* Frameworks */,\n\t\t\t\t66A03D3113E6F97500B514F3 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t666C3D5514D0B14200F337D6 /* PBXTargetDependency */,\n\t\t\t\t66A03D3A13E6F97500B514F3 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusNetworkImageTests;\n\t\t\tproductName = NimbusNetworkImageTests;\n\t\t\tproductReference = 66A03D3413E6F97500B514F3 /* NimbusNetworkImageTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t66A0B09814BD1069003FA413 /* NimbusNetworkControllers */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66A0B0BA14BD106A003FA413 /* Build configuration list for PBXNativeTarget \"NimbusNetworkControllers\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66A0B09514BD1069003FA413 /* Sources */,\n\t\t\t\t66A0B09614BD1069003FA413 /* Frameworks */,\n\t\t\t\t66A0B0CE14BD1625003FA413 /* Run Script Generate Namespace Header */,\n\t\t\t\t66A0B09714BD1069003FA413 /* 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 = NimbusNetworkControllers;\n\t\t\tproductName = NetworkControllers;\n\t\t\tproductReference = 66A0B09914BD1069003FA413 /* libNimbusNetworkControllers.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t66A0B0A514BD1069003FA413 /* NimbusNetworkControllersTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66A0B0BB14BD106A003FA413 /* Build configuration list for PBXNativeTarget \"NimbusNetworkControllersTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66A0B0A114BD1069003FA413 /* Sources */,\n\t\t\t\t66A0B0A214BD1069003FA413 /* Frameworks */,\n\t\t\t\t66A0B0A314BD1069003FA413 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t8B94F87B194665DB00A63185 /* PBXTargetDependency */,\n\t\t\t\t66A0B0AB14BD1069003FA413 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusNetworkControllersTests;\n\t\t\tproductName = NetworkControllersTests;\n\t\t\tproductReference = 66A0B0A614BD1069003FA413 /* NimbusNetworkControllersTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t66C3A6A0143D61130048542F /* NimbusCss */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66C3A6BE143D61140048542F /* Build configuration list for PBXNativeTarget \"NimbusCss\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t8B3FAB821946BD1B00C16A59 /* Run Script Generate Grammar */,\n\t\t\t\t66C3A69D143D61130048542F /* Sources */,\n\t\t\t\t66C3A69E143D61130048542F /* Frameworks */,\n\t\t\t\t666F739214BBFD3D00D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\t66C3A69F143D61130048542F /* 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 = NimbusCss;\n\t\t\tproductName = NimbusCss;\n\t\t\tproductReference = 66C3A6A1143D61130048542F /* libNimbusCss.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t66C3A6AD143D61140048542F /* NimbusCssTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66C3A6C1143D61140048542F /* Build configuration list for PBXNativeTarget \"NimbusCssTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66C3A6A9143D61140048542F /* Sources */,\n\t\t\t\t66C3A6AA143D61140048542F /* Frameworks */,\n\t\t\t\t66C3A6AB143D61140048542F /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t66832CCB143D7A92003E413C /* PBXTargetDependency */,\n\t\t\t\t66C3A6B3143D61140048542F /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusCssTests;\n\t\t\tproductName = NimbusCssTests;\n\t\t\tproductReference = 66C3A6AE143D61140048542F /* NimbusCssTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t66E1CDDE159161ED004DA4A2 /* NimbusBadge */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66E1CDFD159161EE004DA4A2 /* Build configuration list for PBXNativeTarget \"NimbusBadge\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66E1CDDB159161ED004DA4A2 /* Sources */,\n\t\t\t\t66E1CDDC159161ED004DA4A2 /* Frameworks */,\n\t\t\t\t66E1CDDD159161ED004DA4A2 /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = NimbusBadge;\n\t\t\tproductName = NimbusBadge;\n\t\t\tproductReference = 66E1CDDF159161ED004DA4A2 /* libNimbusBadge.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t66E1CDEC159161EE004DA4A2 /* NimbusBadgeTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66E1CE00159161EE004DA4A2 /* Build configuration list for PBXNativeTarget \"NimbusBadgeTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66E1CDE8159161EE004DA4A2 /* Sources */,\n\t\t\t\t66E1CDE9159161EE004DA4A2 /* Frameworks */,\n\t\t\t\t66E1CDEA159161EE004DA4A2 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t66E1CDF2159161EE004DA4A2 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusBadgeTests;\n\t\t\tproductName = NimbusBadgeTests;\n\t\t\tproductReference = 66E1CDED159161EE004DA4A2 /* NimbusBadgeTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t66FC98491703F9D7004E8FB8 /* NimbusCollections */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 66FC98581703F9D8004E8FB8 /* Build configuration list for PBXNativeTarget \"NimbusCollections\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t66FC98461703F9D7004E8FB8 /* Sources */,\n\t\t\t\t66FC98471703F9D7004E8FB8 /* Frameworks */,\n\t\t\t\t66FC98481703F9D7004E8FB8 /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = NimbusCollections;\n\t\t\tproductName = NimbusCollections;\n\t\t\tproductReference = 66FC984A1703F9D7004E8FB8 /* libNimbusCollections.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\tC7BBC6BB16DDC0E700833DC9 /* NimbusTextField */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = C7BBC6FF16DDC0E700833DC9 /* Build configuration list for PBXNativeTarget \"NimbusTextField\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tC7BBC6BC16DDC0E700833DC9 /* Sources */,\n\t\t\t\tC7BBC6DB16DDC0E700833DC9 /* Frameworks */,\n\t\t\t\tC7BBC6DC16DDC0E700833DC9 /* Run Script Generate Namespace Header */,\n\t\t\t\tC7BBC6DD16DDC0E700833DC9 /* 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 = NimbusTextField;\n\t\t\tproductName = NimbusCss;\n\t\t\tproductReference = C7BBC70216DDC0E700833DC9 /* libNimbusTextField.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\tD5BCE89D1D7539A300B6715F /* NimbusCollectionsTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = D5BCE8B41D7539A300B6715F /* Build configuration list for PBXNativeTarget \"NimbusCollectionsTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tD5BCE8A01D7539A300B6715F /* Sources */,\n\t\t\t\tD5BCE8AC1D7539A300B6715F /* Frameworks */,\n\t\t\t\tD5BCE8B21D7539A300B6715F /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tD5BCE8BD1D753A7600B6715F /* PBXTargetDependency */,\n\t\t\t\tD5BCE8C01D753BCA00B6715F /* PBXTargetDependency */,\n\t\t\t\tD5BCE8C31D762F1200B6715F /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusCollectionsTests;\n\t\t\tproductName = NimbusCoreTests;\n\t\t\tproductReference = D5BCE8B71D7539A300B6715F /* NimbusCollectionsTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\tDB3A230813FD4B8E00614220 /* NimbusAttributedLabel */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = DB3A232C13FD4B8F00614220 /* Build configuration list for PBXNativeTarget \"NimbusAttributedLabel\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tDB3A230513FD4B8E00614220 /* Sources */,\n\t\t\t\tDB3A230613FD4B8E00614220 /* Frameworks */,\n\t\t\t\t666F739414BBFD4800D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\tDB3A230713FD4B8E00614220 /* 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 = NimbusAttributedLabel;\n\t\t\tproductName = NimbusAttributedLabel;\n\t\t\tproductReference = DB3A230913FD4B8E00614220 /* libNimbusAttributedLabel.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\tDB3A231513FD4B8E00614220 /* NimbusAttributedLabelTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = DB3A232D13FD4B8F00614220 /* Build configuration list for PBXNativeTarget \"NimbusAttributedLabelTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tDB3A231113FD4B8E00614220 /* Sources */,\n\t\t\t\tDB3A231213FD4B8E00614220 /* Frameworks */,\n\t\t\t\tDB3A231313FD4B8E00614220 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t666C3D2514D0AC7300F337D6 /* PBXTargetDependency */,\n\t\t\t\tDB3A231C13FD4B8E00614220 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusAttributedLabelTests;\n\t\t\tproductName = NimbusAttributedLabelTests;\n\t\t\tproductReference = DB3A231613FD4B8E00614220 /* NimbusAttributedLabelTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\tDB84BD7313EFDDC900DACCFE /* NimbusWebController */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = DB84BD9713EFDDCA00DACCFE /* Build configuration list for PBXNativeTarget \"NimbusWebController\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tDB84BD7013EFDDC900DACCFE /* Sources */,\n\t\t\t\tDB84BD7113EFDDC900DACCFE /* Frameworks */,\n\t\t\t\t666F739D14BBFD7B00D1A32F /* Run Script Generate Namespace Header */,\n\t\t\t\tDB84BD7213EFDDC900DACCFE /* 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 = NimbusWebController;\n\t\t\tproductName = NimbusWebController;\n\t\t\tproductReference = DB84BD7413EFDDC900DACCFE /* libNimbusWebController.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\tDB84BD8013EFDDCA00DACCFE /* NimbusWebControllerTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = DB84BD9813EFDDCA00DACCFE /* Build configuration list for PBXNativeTarget \"NimbusWebControllerTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tDB84BD7C13EFDDCA00DACCFE /* Sources */,\n\t\t\t\tDB84BD7D13EFDDCA00DACCFE /* Frameworks */,\n\t\t\t\tDB84BD7E13EFDDCA00DACCFE /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t666C3D6E14D0B1CF00F337D6 /* PBXTargetDependency */,\n\t\t\t\tDB84BD8713EFDDCA00DACCFE /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = NimbusWebControllerTests;\n\t\t\tproductName = NimbusWebControllerTests;\n\t\t\tproductReference = DB84BD8113EFDDCA00DACCFE /* NimbusWebControllerTests.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\t66A03BFE13E6E84800B514F3 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1100;\n\t\t\t\tORGANIZATIONNAME = \"Jeff Verkoeyen\";\n\t\t\t};\n\t\t\tbuildConfigurationList = 66A03C0113E6E84800B514F3 /* Build configuration list for PBXProject \"Nimbus\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 66A03BFC13E6E84800B514F3;\n\t\t\tproductRefGroup = 66A03C0A13E6E85E00B514F3 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectReferences = (\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 664EFAE315598A07009826AB /* Products */;\n\t\t\t\t\tProjectRef = 664EFAE215598A07009826AB /* CSSDemo.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 664EFB1915598A5E009826AB /* Products */;\n\t\t\t\t\tProjectRef = 664EFB1815598A5E009826AB /* NetworkPhotoAlbum.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 6693C149158A648500950D42 /* Products */;\n\t\t\t\t\tProjectRef = 6693C106158A63E600950D42 /* NimbusCatalog.xcodeproj */;\n\t\t\t\t},\n\t\t\t);\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tDB3A230813FD4B8E00614220 /* NimbusAttributedLabel */,\n\t\t\t\tDB3A231513FD4B8E00614220 /* NimbusAttributedLabelTests */,\n\t\t\t\t66E1CDDE159161ED004DA4A2 /* NimbusBadge */,\n\t\t\t\t66E1CDEC159161EE004DA4A2 /* NimbusBadgeTests */,\n\t\t\t\t66FC98491703F9D7004E8FB8 /* NimbusCollections */,\n\t\t\t\tD5BCE89D1D7539A300B6715F /* NimbusCollectionsTests */,\n\t\t\t\t66A03C0813E6E85E00B514F3 /* NimbusCore */,\n\t\t\t\t66A03C1813E6E85E00B514F3 /* NimbusCoreTests */,\n\t\t\t\t66C3A6A0143D61130048542F /* NimbusCss */,\n\t\t\t\t66C3A6AD143D61140048542F /* NimbusCssTests */,\n\t\t\t\t6675731113E771380076F555 /* NimbusInterapp */,\n\t\t\t\t6675731E13E771380076F555 /* NimbusInterappTests */,\n\t\t\t\t66A03CBE13E6F0ED00B514F3 /* NimbusLauncher */,\n\t\t\t\t66A03CCB13E6F0EE00B514F3 /* NimbusLauncherTests */,\n\t\t\t\t66A0B09814BD1069003FA413 /* NimbusNetworkControllers */,\n\t\t\t\t66A0B0A514BD1069003FA413 /* NimbusNetworkControllersTests */,\n\t\t\t\t66A03D2613E6F97500B514F3 /* NimbusNetworkImage */,\n\t\t\t\t66A03D3313E6F97500B514F3 /* NimbusNetworkImageTests */,\n\t\t\t\t6675722813E765BF0076F555 /* NimbusOverview */,\n\t\t\t\t6675723513E765BF0076F555 /* NimbusOverviewTests */,\n\t\t\t\t663B523E1445052700CC26DF /* NimbusPagingScrollView */,\n\t\t\t\t663B524B1445052800CC26DF /* NimbusPagingScrollViewTests */,\n\t\t\t\t6675727913E769150076F555 /* NimbusPhotos */,\n\t\t\t\t6675728613E769150076F555 /* NimbusPhotosTests */,\n\t\t\t\t6661BBCB13F1A3BB00D14F92 /* NimbusModels */,\n\t\t\t\t6661BBD813F1A3BB00D14F92 /* NimbusModelsTests */,\n\t\t\t\tC7BBC6BB16DDC0E700833DC9 /* NimbusTextField */,\n\t\t\t\tDB84BD7313EFDDC900DACCFE /* NimbusWebController */,\n\t\t\t\tDB84BD8013EFDDCA00DACCFE /* NimbusWebControllerTests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXReferenceProxy section */\n\t\t664EFAEB15598A07009826AB /* CSSDemo.app */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.application;\n\t\t\tpath = CSSDemo.app;\n\t\t\tremoteRef = 664EFAEA15598A07009826AB /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t664EFB2115598A5E009826AB /* NetworkPhotoAlbum.app */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.application;\n\t\t\tpath = NetworkPhotoAlbum.app;\n\t\t\tremoteRef = 664EFB2015598A5E009826AB /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t6693C14D158A648500950D42 /* Nimbus.app */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.application;\n\t\t\tpath = Nimbus.app;\n\t\t\tremoteRef = 6693C14C158A648500950D42 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n/* End PBXReferenceProxy section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t663B52491445052800CC26DF /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6661BBD613F1A3BB00D14F92 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675723313E765BF0076F555 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675728413E769150076F555 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675731C13E771380076F555 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D2714D0ACA900F337D6 /* NIInterappTests.m in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03C1613E6E85E00B514F3 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66A03CB413E6EF1F00B514F3 /* nimbus64x64.png in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03CC913E6F0EE00B514F3 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03D3113E6F97500B514F3 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A0B0A314BD1069003FA413 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66C3A6AB143D61140048542F /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66832CCE143D7B2C003E413C /* empty-rulesets.css in Resources */,\n\t\t\t\t66832CD0143D7B38003E413C /* empty.css in Resources */,\n\t\t\t\t66832CD2143D833B003E413C /* comments.css in Resources */,\n\t\t\t\t66832CD4143D8989003E413C /* rulesets.css in Resources */,\n\t\t\t\t66832CD6143D8AB7003E413C /* rulesets-overrides.css in Resources */,\n\t\t\t\t66832CD8143E062C003E413C /* malformed.css in Resources */,\n\t\t\t\t66832CFF143E3294003E413C /* UILabel.css in Resources */,\n\t\t\t\t66FCC634144FB42E0029F1A6 /* includee.css in Resources */,\n\t\t\t\t66FCC635144FB42E0029F1A6 /* includer.css in Resources */,\n\t\t\t\tC7BBC71116DE66BD00833DC9 /* media-rulesets.css in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66E1CDEA159161EE004DA4A2 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tD5BCE8B21D7539A300B6715F /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tD5BCE8B31D7539A300B6715F /* nimbus64x64.png in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB3A231313FD4B8E00614220 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB84BD7E13EFDDCA00DACCFE /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t666F736214BBBFF300D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739214BBFD3D00D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739414BBFD4800D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739514BBFD4F00D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739614BBFD5500D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739714BBFD5A00D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739814BBFD5F00D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739914BBFD6400D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739A14BBFD6900D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739C14BBFD7400D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t666F739D14BBFD7B00D1A32F /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t66A0B0CE14BD1625003FA413 /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n\t\t8B3FAB821946BD1B00C16A59 /* Run Script Generate Grammar */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"$(SRCROOT)/css/grammar/CSSTokenizerPrefix\",\n\t\t\t\t\"$(SRCROOT)/css/grammar/CSSTokenizerSuffix\",\n\t\t\t\t\"$(SRCROOT)/css/grammar/generate\",\n\t\t\t\t\"$(SRCROOT)/css/grammar/CSSTokens.cpp\",\n\t\t\t\t\"$(SRCROOT)/css/grammar/CSSTokens.h\",\n\t\t\t\t\"$(SRCROOT)/css/grammar/css.grammar\",\n\t\t\t);\n\t\t\tname = \"Run Script Generate Grammar\";\n\t\t\toutputPaths = (\n\t\t\t\t\"$(SRCROOT)/css/src/CSSTokenizer.m\",\n\t\t\t\t\"$(SRCROOT)/css/src/CSSTokens.h\",\n\t\t\t\t\"$(SRCROOT)/css/src/CSSTokens.m\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"cd css/grammar\\n./generate\";\n\t\t};\n\t\tC7BBC6DC16DDC0E700833DC9 /* Run Script Generate Namespace Header */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script Generate Namespace Header\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = \"/bin/sh ../scripts/generate_namespace_header\";\n\t\t\tshellScript = \"\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t663B523B1445052700CC26DF /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t663B526B1445070100CC26DF /* NIPagingScrollView.m in Sources */,\n\t\t\t\t66F27D56145B7A5F00AFCA08 /* NIPagingScrollViewPage.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t663B52471445052800CC26DF /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D3514D0AE7B00F337D6 /* NIPagingScrollViewTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6661BBC813F1A3BB00D14F92 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66FE7D6D13FB83620061B987 /* NITableViewModel.m in Sources */,\n\t\t\t\t667A74A013FE20BD009D277D /* NIFormCellCatalog.m in Sources */,\n\t\t\t\t667A74A213FE20BD009D277D /* NICellFactory.m in Sources */,\n\t\t\t\t66688680156AD148006E874F /* NICellCatalog.m in Sources */,\n\t\t\t\t66688689156ADDB3006E874F /* NIRadioGroup.m in Sources */,\n\t\t\t\t6641617C156B516E0018AC1C /* NITableViewActions.m in Sources */,\n\t\t\t\t667DD36C156D78980045ABBB /* NIRadioGroupController.m in Sources */,\n\t\t\t\t66B6710815AA820700FE4AE8 /* NICellBackgrounds.m in Sources */,\n\t\t\t\t66D2E54015D9432000281511 /* NIMutableTableViewModel.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6661BBD413F1A3BB00D14F92 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tD526CF4B18B826A600991F7A /* NICellCatalogTests.m in Sources */,\n\t\t\t\t6623EB6D1402ECE400E0E61A /* NITableViewModelTests.m in Sources */,\n\t\t\t\t6672DAB515B87E4B00DFE81F /* NICellFactoryTests.m in Sources */,\n\t\t\t\t66D2E54715D9503100281511 /* NIMutableTableViewModelTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675722513E765BF0076F555 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6675726413E765F70076F555 /* NIDeviceInfo.m in Sources */,\n\t\t\t\t6675726713E765F70076F555 /* NIOverview.m in Sources */,\n\t\t\t\t6675726913E765F70076F555 /* NIOverviewGraphView.m in Sources */,\n\t\t\t\t6675726B13E765F70076F555 /* NIOverviewLogger.m in Sources */,\n\t\t\t\t6675726D13E765F70076F555 /* NIOverviewPageView.m in Sources */,\n\t\t\t\t6675726F13E765F70076F555 /* NIOverviewSwizzling.m in Sources */,\n\t\t\t\t6675727113E765F70076F555 /* NIOverviewView.m in Sources */,\n\t\t\t\t669F0D00158000810069B972 /* NIOverviewMemoryCacheController.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675723113E765BF0076F555 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D3D14D0AF0C00F337D6 /* NIOverviewTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675727613E769150076F555 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t667572B013E7692F0076F555 /* NIPhotoAlbumScrollView.m in Sources */,\n\t\t\t\t667572B213E7692F0076F555 /* NIPhotoScrollView.m in Sources */,\n\t\t\t\t667572B413E7692F0076F555 /* NIPhotoScrubberView.m in Sources */,\n\t\t\t\t667572B613E7692F0076F555 /* NIToolbarPhotoViewController.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675728213E769150076F555 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D3714D0AEA300F337D6 /* NIPhotoScrollViewTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675730E13E771380076F555 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6675733F13E7718B0076F555 /* NIInterapp.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6675731A13E771380076F555 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D2F14D0ADF800F337D6 /* NIInterappTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03C0513E6E85E00B514F3 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66A03C7213E6E8D100B514F3 /* NICommonMetrics.m in Sources */,\n\t\t\t\t66A03C7613E6E8D100B514F3 /* NIDebuggingTools.m in Sources */,\n\t\t\t\t66AF0BCB189C1E2700020FEE /* UIResponder+NimbusCore.m in Sources */,\n\t\t\t\t66A03C7813E6E8D100B514F3 /* NIDeviceOrientation.m in Sources */,\n\t\t\t\t66A03C7A13E6E8D100B514F3 /* NIError.m in Sources */,\n\t\t\t\t66A03C7C13E6E8D100B514F3 /* NIFoundationMethods.m in Sources */,\n\t\t\t\t66A03C7E13E6E8D100B514F3 /* NIInMemoryCache.m in Sources */,\n\t\t\t\t66A03C8213E6E8D100B514F3 /* NINetworkActivity.m in Sources */,\n\t\t\t\t66A03C8413E6E8D100B514F3 /* NINonEmptyCollectionTesting.m in Sources */,\n\t\t\t\t66A03C8613E6E8D100B514F3 /* NINonRetainingCollections.m in Sources */,\n\t\t\t\t66A03C8813E6E8D100B514F3 /* NIOperations.m in Sources */,\n\t\t\t\t66A03C8A13E6E8D100B514F3 /* NIPaths.m in Sources */,\n\t\t\t\t66A03C8D13E6E8D100B514F3 /* NIRuntimeClassModifications.m in Sources */,\n\t\t\t\t66A03C8F13E6E8D100B514F3 /* NISDKAvailability.m in Sources */,\n\t\t\t\t66A03C9113E6E8D100B514F3 /* NIState.m in Sources */,\n\t\t\t\t6675E4B41455FCC5007D172F /* NIViewRecycler.m in Sources */,\n\t\t\t\t669819DC159B927B00C2D3EF /* NISnapshotRotation.m in Sources */,\n\t\t\t\t66C1D83E16B9CE90003E855B /* NIImageUtilities.m in Sources */,\n\t\t\t\t66C1D8C216B9ED65003E855B /* NIButtonUtilities.m in Sources */,\n\t\t\t\t6617FD0B171F6A92006E0DF8 /* NIActions.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03C1413E6E85E00B514F3 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66A03CAA13E6E90500B514F3 /* NICoreAdditionTests.m in Sources */,\n\t\t\t\t66A03CAC13E6E90500B514F3 /* NIFoundationMethodsTests.m in Sources */,\n\t\t\t\t66A03CAD13E6E90500B514F3 /* NIMemoryCacheTests.m in Sources */,\n\t\t\t\t66A03CAE13E6E90500B514F3 /* NINonEmptyCollectionTestingTests.m in Sources */,\n\t\t\t\t66A03CAF13E6E90500B514F3 /* NINonRetainingCollectionsTests.m in Sources */,\n\t\t\t\t66A03CB113E6E90500B514F3 /* NIRuntimeClassModificationsTests.m in Sources */,\n\t\t\t\t66A03CB213E6E90500B514F3 /* NSDate+UnitTesting.m in Sources */,\n\t\t\t\t6675E4BC145603DA007D172F /* NIViewRecyclerTests.m in Sources */,\n\t\t\t\t66E8CED214D089E500600592 /* NICommonMetricsTests.m in Sources */,\n\t\t\t\t6607851C14D245BF00FE3283 /* NINetworkActivityTests.m in Sources */,\n\t\t\t\t6607852014D33EAA00FE3283 /* NIStateTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03CBB13E6F0ED00B514F3 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66BB4F9915958A5800020EE8 /* NILauncherButtonView.m in Sources */,\n\t\t\t\t66BB4F9B15958A5800020EE8 /* NILauncherPageView.m in Sources */,\n\t\t\t\t66BB4F9D15958A5800020EE8 /* NILauncherView.m in Sources */,\n\t\t\t\t66BB4F9F15958A5800020EE8 /* NILauncherViewController.m in Sources */,\n\t\t\t\t66BB4FA115958A5800020EE8 /* NILauncherViewModel.m in Sources */,\n\t\t\t\t66BB4FA315958A5800020EE8 /* NILauncherViewObject.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03CC713E6F0EE00B514F3 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8B94F8721946642400A63185 /* NIPagingScrollView.m in Sources */,\n\t\t\t\t8B94F8731946643C00A63185 /* NIPagingScrollViewPage.m in Sources */,\n\t\t\t\t666C3D3314D0AE4F00F337D6 /* NILauncherViewTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03D2313E6F97500B514F3 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6617B01618A90D5D00037E75 /* NIImageResponseSerializer.m in Sources */,\n\t\t\t\t66A03D5A13E6F99400B514F3 /* NINetworkImageView.m in Sources */,\n\t\t\t\t66D2FDDE1593F3A600B2BEFD /* NIImageProcessing.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A03D2F13E6F97500B514F3 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8B4E85C919463715005FDD25 /* AFHTTPRequestOperation.m in Sources */,\n\t\t\t\t8B4E85CC19463733005FDD25 /* AFSecurityPolicy.m in Sources */,\n\t\t\t\t8B4E85CA1946371D005FDD25 /* AFURLConnectionOperation.m in Sources */,\n\t\t\t\t8B4E85CB19463721005FDD25 /* AFURLResponseSerialization.m in Sources */,\n\t\t\t\t666C3D5014D0B0F200F337D6 /* NINetworkImageViewTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A0B09514BD1069003FA413 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66A0B0C414BD1116003FA413 /* NINetworkTableViewController.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66A0B0A114BD1069003FA413 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D4D14D0B05C00F337D6 /* NINetworkTableViewControllerTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66C3A69D143D61130048542F /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66832CC5143D7898003E413C /* NICSSParser.m in Sources */,\n\t\t\t\t66832CF1143E0AD9003E413C /* CSSTokenizer.m in Sources */,\n\t\t\t\t66832CF3143E0AD9003E413C /* CSSTokens.m in Sources */,\n\t\t\t\t66832CF7143E0C35003E413C /* NIStylesheet.m in Sources */,\n\t\t\t\t66832CFD143E2C0D003E413C /* NIDOM.m in Sources */,\n\t\t\t\t66832D08143E3A30003E413C /* NICSSRuleset.m in Sources */,\n\t\t\t\t66832D10143E3C32003E413C /* UILabel+NIStyleable.m in Sources */,\n\t\t\t\t66832D1414416368003E413C /* UIView+NIStyleable.m in Sources */,\n\t\t\t\t66832DA314421B4A003E413C /* UINavigationBar+NIStyleable.m in Sources */,\n\t\t\t\t66832E0714435071003E413C /* NIChameleonObserver.m in Sources */,\n\t\t\t\t66B10901144C931F004576D1 /* UIButton+NIStyleable.m in Sources */,\n\t\t\t\t668ECDC81455C17200455266 /* NIStylesheetCache.m in Sources */,\n\t\t\t\t443589CA1551914400757E50 /* UISearchBar+NIStyleable.m in Sources */,\n\t\t\t\t443589CB1551914800757E50 /* UIToolbar+NIStyleable.m in Sources */,\n\t\t\t\t664EFB6315598CDF009826AB /* UIActivityIndicatorView+NIStyleable.m in Sources */,\n\t\t\t\t666903861561B46900C44A70 /* UITableView+NIStyleable.m in Sources */,\n\t\t\t\t6669038A1561B6A000C44A70 /* UIScrollView+NIStyleable.m in Sources */,\n\t\t\t\tC743F6EB16D2652F00A933B7 /* NIUserInterfaceString.m in Sources */,\n\t\t\t\tC7A8791F16D7348C00A0C23F /* NITextField+NIStyleable.m in Sources */,\n\t\t\t\tC7A8792316D7B96200A0C23F /* UITextField+NIStyleable.m in Sources */,\n\t\t\t\tC7BBC6BA16DDC0DB00833DC9 /* NITextField.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66C3A6A9143D61140048542F /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8B4E85B819462DA6005FDD25 /* AFHTTPRequestOperation.m in Sources */,\n\t\t\t\t66832CC1143D7883003E413C /* NICSSParserTests.m in Sources */,\n\t\t\t\t8B4E85B919462DB8005FDD25 /* AFURLResponseSerialization.m in Sources */,\n\t\t\t\t66832CF9143E1C0C003E413C /* NIStylesheetTests.m in Sources */,\n\t\t\t\t8B4E85BB1946304E005FDD25 /* AFSecurityPolicy.m in Sources */,\n\t\t\t\t8B4E85BA1946303D005FDD25 /* AFURLConnectionOperation.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66E1CDDB159161ED004DA4A2 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66E1CE0615916220004DA4A2 /* NIBadgeView.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66E1CDE8159161EE004DA4A2 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8B94F87F1946676B00A63185 /* NIBadgeTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t66FC98461703F9D7004E8FB8 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66FC98631703FA51004E8FB8 /* NICollectionViewCellFactory.m in Sources */,\n\t\t\t\t66FC98651703FA51004E8FB8 /* NICollectionViewModel.m in Sources */,\n\t\t\t\t66DCB78B1717755B00205745 /* NICollectionViewActions.m in Sources */,\n\t\t\t\t9B22BD991725E75E000FDB01 /* NIMutableCollectionViewModel.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC7BBC6BC16DDC0E700833DC9 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC7BBC70416DDC12800833DC9 /* NITextField.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tD5BCE8A01D7539A300B6715F /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tD5BCE8BB1D753A1500B6715F /* NimbusCollectionsTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB3A230513FD4B8E00614220 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tDB3A233713FD4BE500614220 /* NIAttributedLabel.m in Sources */,\n\t\t\t\t6613332F15D2E23900369333 /* NSMutableAttributedString+NimbusAttributedLabel.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB3A231113FD4B8E00614220 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D1C14D0AB7E00F337D6 /* NIAttributedLabelTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB84BD7013EFDDC900DACCFE /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tDB84BDAE13EFDF5900DACCFE /* NIWebController.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tDB84BD7C13EFDDCA00DACCFE /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t666C3D3914D0AEBF00F337D6 /* NIWebControllerTests.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\t663B52511445052800CC26DF /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 663B523E1445052700CC26DF /* NimbusPagingScrollView */;\n\t\t\ttargetProxy = 663B52501445052800CC26DF /* PBXContainerItemProxy */;\n\t\t};\n\t\t6661BBDF13F1A3BB00D14F92 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 6661BBCB13F1A3BB00D14F92 /* NimbusModels */;\n\t\t\ttargetProxy = 6661BBDE13F1A3BB00D14F92 /* PBXContainerItemProxy */;\n\t\t};\n\t\t666C3D2514D0AC7300F337D6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 666C3D2414D0AC7300F337D6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t666C3D2E14D0ACDD00F337D6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 666C3D2D14D0ACDD00F337D6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t666C3D4314D0AF8000F337D6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 666C3D4214D0AF8000F337D6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t666C3D5514D0B14200F337D6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 666C3D5414D0B14200F337D6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t666C3D5F14D0B19C00F337D6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 666C3D5E14D0B19C00F337D6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t666C3D6414D0B1AA00F337D6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 666C3D6314D0B1AA00F337D6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t666C3D6614D0B1AA00F337D6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 663B523E1445052700CC26DF /* NimbusPagingScrollView */;\n\t\t\ttargetProxy = 666C3D6514D0B1AA00F337D6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t666C3D6A14D0B1BA00F337D6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 666C3D6914D0B1BA00F337D6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t666C3D6E14D0B1CF00F337D6 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 666C3D6D14D0B1CF00F337D6 /* PBXContainerItemProxy */;\n\t\t};\n\t\t6675723C13E765BF0076F555 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 6675722813E765BF0076F555 /* NimbusOverview */;\n\t\t\ttargetProxy = 6675723B13E765BF0076F555 /* PBXContainerItemProxy */;\n\t\t};\n\t\t6675728D13E769150076F555 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 6675727913E769150076F555 /* NimbusPhotos */;\n\t\t\ttargetProxy = 6675728C13E769150076F555 /* PBXContainerItemProxy */;\n\t\t};\n\t\t6675732513E771380076F555 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 6675731113E771380076F555 /* NimbusInterapp */;\n\t\t\ttargetProxy = 6675732413E771380076F555 /* PBXContainerItemProxy */;\n\t\t};\n\t\t66832CCB143D7A92003E413C /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 66832CCA143D7A92003E413C /* PBXContainerItemProxy */;\n\t\t};\n\t\t66A03C2213E6E85E00B514F3 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 66A03C2113E6E85E00B514F3 /* PBXContainerItemProxy */;\n\t\t};\n\t\t66A03CD213E6F0EE00B514F3 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03CBE13E6F0ED00B514F3 /* NimbusLauncher */;\n\t\t\ttargetProxy = 66A03CD113E6F0EE00B514F3 /* PBXContainerItemProxy */;\n\t\t};\n\t\t66A03D3A13E6F97500B514F3 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03D2613E6F97500B514F3 /* NimbusNetworkImage */;\n\t\t\ttargetProxy = 66A03D3913E6F97500B514F3 /* PBXContainerItemProxy */;\n\t\t};\n\t\t66A0B0AB14BD1069003FA413 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A0B09814BD1069003FA413 /* NimbusNetworkControllers */;\n\t\t\ttargetProxy = 66A0B0AA14BD1069003FA413 /* PBXContainerItemProxy */;\n\t\t};\n\t\t66C3A6B3143D61140048542F /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66C3A6A0143D61130048542F /* NimbusCss */;\n\t\t\ttargetProxy = 66C3A6B2143D61140048542F /* PBXContainerItemProxy */;\n\t\t};\n\t\t66E1CDF2159161EE004DA4A2 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66E1CDDE159161ED004DA4A2 /* NimbusBadge */;\n\t\t\ttargetProxy = 66E1CDF1159161EE004DA4A2 /* PBXContainerItemProxy */;\n\t\t};\n\t\t8B94F875194664D500A63185 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 8B94F874194664D500A63185 /* PBXContainerItemProxy */;\n\t\t};\n\t\t8B94F877194664D900A63185 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 6661BBCB13F1A3BB00D14F92 /* NimbusModels */;\n\t\t\ttargetProxy = 8B94F876194664D900A63185 /* PBXContainerItemProxy */;\n\t\t};\n\t\t8B94F87B194665DB00A63185 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = 8B94F87A194665DB00A63185 /* PBXContainerItemProxy */;\n\t\t};\n\t\tD5BCE8BD1D753A7600B6715F /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66FC98491703F9D7004E8FB8 /* NimbusCollections */;\n\t\t\ttargetProxy = D5BCE8BC1D753A7600B6715F /* PBXContainerItemProxy */;\n\t\t};\n\t\tD5BCE8C01D753BCA00B6715F /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 66A03C0813E6E85E00B514F3 /* NimbusCore */;\n\t\t\ttargetProxy = D5BCE8BF1D753BCA00B6715F /* PBXContainerItemProxy */;\n\t\t};\n\t\tD5BCE8C31D762F1200B6715F /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 6661BBCB13F1A3BB00D14F92 /* NimbusModels */;\n\t\t\ttargetProxy = D5BCE8C21D762F1200B6715F /* PBXContainerItemProxy */;\n\t\t};\n\t\tDB3A231C13FD4B8E00614220 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = DB3A230813FD4B8E00614220 /* NimbusAttributedLabel */;\n\t\t\ttargetProxy = DB3A231B13FD4B8E00614220 /* PBXContainerItemProxy */;\n\t\t};\n\t\tDB84BD8713EFDDCA00DACCFE /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = DB84BD7313EFDDC900DACCFE /* NimbusWebController */;\n\t\t\ttargetProxy = DB84BD8613EFDDCA00DACCFE /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\t663B525D1445052800CC26DF /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = pagingscrollview;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t663B525E1445052800CC26DF /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = pagingscrollview;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t663B52601445052800CC26DF /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"pagingscrollview/unittests/NimbusPagingScrollViewTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = pagingscrollview;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusPagingScrollView;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.paginscrollview.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t663B52611445052800CC26DF /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"pagingscrollview/unittests/NimbusPagingScrollViewTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = pagingscrollview;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusPagingScrollView;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.paginscrollview.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6661BBEB13F1A3BC00D14F92 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = models;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6661BBEC13F1A3BC00D14F92 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = models;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6661BBEE13F1A3BC00D14F92 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"models/unittests/NimbusModelsTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = models;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusModels;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.models.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6661BBEF13F1A3BC00D14F92 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"models/unittests/NimbusModelsTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = models;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusModels;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.models.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6675724813E765BF0076F555 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = overview;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6675724913E765BF0076F555 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = overview;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6675724A13E765BF0076F555 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"overview/unittests/NimbusOverviewTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = overview;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusOverview;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.overview.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6675724B13E765BF0076F555 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"overview/unittests/NimbusOverviewTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = overview;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusOverview;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.overview.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6675729A13E769150076F555 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = photos;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6675729B13E769150076F555 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = photos;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6675729D13E769150076F555 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"photos/unittests/NimbusPhotosTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = photos;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusPhotos;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.photos.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6675729E13E769150076F555 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"photos/unittests/NimbusPhotosTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = photos;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusPhotos;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.photos.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6675733213E771380076F555 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = interapp;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6675733313E771380076F555 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = interapp;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6675733513E771380076F555 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"interapp/unittests/NimbusInterappTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = interapp;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusInterapp;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.interapp.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6675733613E771380076F555 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"interapp/unittests/NimbusInterappTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = interapp;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusInterapp;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.interapp.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66A03C0313E6E84800B514F3 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(SDKROOT)/Developer/Library/Frameworks\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = Nimbus_Prefix.pch;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = \"DEBUG=1\";\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_NEWLINE = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = YES;\n\t\t\t\tGCC_WARN_SHADOW = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tRUN_CLANG_STATIC_ANALYZER = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTEST_AFTER_BUILD = NO;\n\t\t\t\tWARNING_CFLAGS = (\n\t\t\t\t\t\"-Wnewline-eof\",\n\t\t\t\t\t\"-Wendif-labels\",\n\t\t\t\t\t\"-Wall\",\n\t\t\t\t);\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66A03C0413E6E84800B514F3 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SDKROOT)/Developer/Library/Frameworks\",\n\t\t\t\t);\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = Nimbus_Prefix.pch;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_NEWLINE = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = YES;\n\t\t\t\tGCC_WARN_SHADOW = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tRUN_CLANG_STATIC_ANALYZER = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTEST_AFTER_BUILD = NO;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tWARNING_CFLAGS = (\n\t\t\t\t\t\"-Wnewline-eof\",\n\t\t\t\t\t\"-Wendif-labels\",\n\t\t\t\t\t\"-Wall\",\n\t\t\t\t);\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66A03C2F13E6E85E00B514F3 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tDSTROOT = /tmp/NimbusCore.dst;\n\t\t\t\tNIMBUS_FEATURE_NAME = core;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66A03C3013E6E85E00B514F3 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tDSTROOT = /tmp/NimbusCore.dst;\n\t\t\t\tNIMBUS_FEATURE_NAME = core;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66A03C3213E6E85E00B514F3 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tINFOPLIST_FILE = \"core/unittests/NimbusCoreTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = core;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusCore;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.core.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66A03C3313E6E85E00B514F3 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tINFOPLIST_FILE = \"core/unittests/NimbusCoreTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = core;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusCore;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.core.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66A03CDF13E6F0EE00B514F3 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = launcher;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66A03CE013E6F0EE00B514F3 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = launcher;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66A03CE213E6F0EE00B514F3 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"launcher/unittests/NimbusLauncherTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = launcher;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusLauncher;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.launcher.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66A03CE313E6F0EE00B514F3 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"launcher/unittests/NimbusLauncherTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = launcher;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusLauncher;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.launcher.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66A03D4713E6F97600B514F3 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = networkimage;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66A03D4813E6F97600B514F3 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = networkimage;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66A03D4A13E6F97600B514F3 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"networkimage/unittests/NimbusNetworkImageTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = networkimage;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusNetworkImage;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.networkimage.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66A03D4B13E6F97600B514F3 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"networkimage/unittests/NimbusNetworkImageTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = networkimage;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusNetworkImage;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.networkimage.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66A0B0B614BD1069003FA413 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = networkcontrollers;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66A0B0B714BD1069003FA413 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = networkcontrollers;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66A0B0B814BD1069003FA413 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"networkcontrollers/unittests/NetworkControllersTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = networkcontrollers;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusNetworkControllers;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.nimbus.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66A0B0B914BD1069003FA413 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"networkcontrollers/unittests/NetworkControllersTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = networkcontrollers;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusNetworkControllers;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.nimbus.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66C3A6BF143D61140048542F /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = css;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66C3A6C0143D61140048542F /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = css;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66C3A6C2143D61140048542F /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"css/unittests/NimbusCSSTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = css;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusCss;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.css.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66C3A6C3143D61140048542F /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"css/unittests/NimbusCSSTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = css;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusCss;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.css.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66E1CDFE159161EE004DA4A2 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = badge;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66E1CDFF159161EE004DA4A2 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = badge;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66E1CE01159161EE004DA4A2 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"badge/unittests/NimbusBadgeTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = badge;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusBadge;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.badgetests.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66E1CE02159161EE004DA4A2 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"badge/unittests/NimbusBadgeTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = badge;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusBadge;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.badgetests.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t66FC98531703F9D8004E8FB8 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = collections;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t66FC98541703F9D8004E8FB8 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = collections;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC7BBC70016DDC0E700833DC9 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = textfield;\n\t\t\t\tPRODUCT_NAME = NimbusTextField;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC7BBC70116DDC0E700833DC9 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = textfield;\n\t\t\t\tPRODUCT_NAME = NimbusTextField;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tD5BCE8B51D7539A300B6715F /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tINFOPLIST_FILE = \"collections/unittests/NimbusCollectionsTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = collections;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusCollections;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.collections.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tD5BCE8B61D7539A300B6715F /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tINFOPLIST_FILE = \"collections/unittests/NimbusCollectionsTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = collections;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusCollections;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.collections.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tDB3A232813FD4B8E00614220 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tGCC_WARN_SIGN_COMPARE = YES;\n\t\t\t\tNIMBUS_FEATURE_NAME = attributedlabel;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tDB3A232913FD4B8E00614220 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tGCC_WARN_SIGN_COMPARE = YES;\n\t\t\t\tNIMBUS_FEATURE_NAME = attributedlabel;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tDB3A232A13FD4B8E00614220 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"attributedlabel/unittests/NimbusAttributedLabelTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = attributedlabel;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusAttributedLabel;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.attributedlabel.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tDB3A232B13FD4B8E00614220 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"attributedlabel/unittests/NimbusAttributedLabelTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = attributedlabel;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusAttributedLabel;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.attributedlabel.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tDB84BD9313EFDDCA00DACCFE /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = webcontroller;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tDB84BD9413EFDDCA00DACCFE /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED514D08B9F00600592 /* lib.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tNIMBUS_FEATURE_NAME = webcontroller;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tDB84BD9513EFDDCA00DACCFE /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"webcontroller/unittests/NimbusWebControllerTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = webcontroller;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusWebController;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.webcontroller.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tDB84BD9613EFDDCA00DACCFE /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66E8CED614D08BAE00600592 /* unittest.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"webcontroller/unittests/NimbusWebControllerTests-Info.plist\";\n\t\t\t\tNIMBUS_FEATURE_NAME = webcontroller;\n\t\t\t\tNIMBUS_TARGET_NAME = NimbusWebController;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.nimbus.webcontroller.unittests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t663B525C1445052800CC26DF /* Build configuration list for PBXNativeTarget \"NimbusPagingScrollView\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t663B525D1445052800CC26DF /* Debug */,\n\t\t\t\t663B525E1445052800CC26DF /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t663B525F1445052800CC26DF /* Build configuration list for PBXNativeTarget \"NimbusPagingScrollViewTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t663B52601445052800CC26DF /* Debug */,\n\t\t\t\t663B52611445052800CC26DF /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6661BBEA13F1A3BC00D14F92 /* Build configuration list for PBXNativeTarget \"NimbusModels\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6661BBEB13F1A3BC00D14F92 /* Debug */,\n\t\t\t\t6661BBEC13F1A3BC00D14F92 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6661BBED13F1A3BC00D14F92 /* Build configuration list for PBXNativeTarget \"NimbusModelsTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6661BBEE13F1A3BC00D14F92 /* Debug */,\n\t\t\t\t6661BBEF13F1A3BC00D14F92 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6675724C13E765BF0076F555 /* Build configuration list for PBXNativeTarget \"NimbusOverview\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6675724813E765BF0076F555 /* Debug */,\n\t\t\t\t6675724913E765BF0076F555 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6675724D13E765BF0076F555 /* Build configuration list for PBXNativeTarget \"NimbusOverviewTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6675724A13E765BF0076F555 /* Debug */,\n\t\t\t\t6675724B13E765BF0076F555 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6675729913E769150076F555 /* Build configuration list for PBXNativeTarget \"NimbusPhotos\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6675729A13E769150076F555 /* Debug */,\n\t\t\t\t6675729B13E769150076F555 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6675729C13E769150076F555 /* Build configuration list for PBXNativeTarget \"NimbusPhotosTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6675729D13E769150076F555 /* Debug */,\n\t\t\t\t6675729E13E769150076F555 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6675733113E771380076F555 /* Build configuration list for PBXNativeTarget \"NimbusInterapp\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6675733213E771380076F555 /* Debug */,\n\t\t\t\t6675733313E771380076F555 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6675733413E771380076F555 /* Build configuration list for PBXNativeTarget \"NimbusInterappTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6675733513E771380076F555 /* Debug */,\n\t\t\t\t6675733613E771380076F555 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66A03C0113E6E84800B514F3 /* Build configuration list for PBXProject \"Nimbus\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66A03C0313E6E84800B514F3 /* Debug */,\n\t\t\t\t66A03C0413E6E84800B514F3 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66A03C2E13E6E85E00B514F3 /* Build configuration list for PBXNativeTarget \"NimbusCore\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66A03C2F13E6E85E00B514F3 /* Debug */,\n\t\t\t\t66A03C3013E6E85E00B514F3 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66A03C3113E6E85E00B514F3 /* Build configuration list for PBXNativeTarget \"NimbusCoreTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66A03C3213E6E85E00B514F3 /* Debug */,\n\t\t\t\t66A03C3313E6E85E00B514F3 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66A03CDE13E6F0EE00B514F3 /* Build configuration list for PBXNativeTarget \"NimbusLauncher\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66A03CDF13E6F0EE00B514F3 /* Debug */,\n\t\t\t\t66A03CE013E6F0EE00B514F3 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66A03CE113E6F0EE00B514F3 /* Build configuration list for PBXNativeTarget \"NimbusLauncherTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66A03CE213E6F0EE00B514F3 /* Debug */,\n\t\t\t\t66A03CE313E6F0EE00B514F3 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66A03D4613E6F97600B514F3 /* Build configuration list for PBXNativeTarget \"NimbusNetworkImage\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66A03D4713E6F97600B514F3 /* Debug */,\n\t\t\t\t66A03D4813E6F97600B514F3 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66A03D4913E6F97600B514F3 /* Build configuration list for PBXNativeTarget \"NimbusNetworkImageTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66A03D4A13E6F97600B514F3 /* Debug */,\n\t\t\t\t66A03D4B13E6F97600B514F3 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66A0B0BA14BD106A003FA413 /* Build configuration list for PBXNativeTarget \"NimbusNetworkControllers\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66A0B0B614BD1069003FA413 /* Debug */,\n\t\t\t\t66A0B0B714BD1069003FA413 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66A0B0BB14BD106A003FA413 /* Build configuration list for PBXNativeTarget \"NimbusNetworkControllersTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66A0B0B814BD1069003FA413 /* Debug */,\n\t\t\t\t66A0B0B914BD1069003FA413 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66C3A6BE143D61140048542F /* Build configuration list for PBXNativeTarget \"NimbusCss\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66C3A6BF143D61140048542F /* Debug */,\n\t\t\t\t66C3A6C0143D61140048542F /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66C3A6C1143D61140048542F /* Build configuration list for PBXNativeTarget \"NimbusCssTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66C3A6C2143D61140048542F /* Debug */,\n\t\t\t\t66C3A6C3143D61140048542F /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66E1CDFD159161EE004DA4A2 /* Build configuration list for PBXNativeTarget \"NimbusBadge\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66E1CDFE159161EE004DA4A2 /* Debug */,\n\t\t\t\t66E1CDFF159161EE004DA4A2 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66E1CE00159161EE004DA4A2 /* Build configuration list for PBXNativeTarget \"NimbusBadgeTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66E1CE01159161EE004DA4A2 /* Debug */,\n\t\t\t\t66E1CE02159161EE004DA4A2 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t66FC98581703F9D8004E8FB8 /* Build configuration list for PBXNativeTarget \"NimbusCollections\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t66FC98531703F9D8004E8FB8 /* Debug */,\n\t\t\t\t66FC98541703F9D8004E8FB8 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC7BBC6FF16DDC0E700833DC9 /* Build configuration list for PBXNativeTarget \"NimbusTextField\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC7BBC70016DDC0E700833DC9 /* Debug */,\n\t\t\t\tC7BBC70116DDC0E700833DC9 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tD5BCE8B41D7539A300B6715F /* Build configuration list for PBXNativeTarget \"NimbusCollectionsTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tD5BCE8B51D7539A300B6715F /* Debug */,\n\t\t\t\tD5BCE8B61D7539A300B6715F /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tDB3A232C13FD4B8F00614220 /* Build configuration list for PBXNativeTarget \"NimbusAttributedLabel\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tDB3A232813FD4B8E00614220 /* Debug */,\n\t\t\t\tDB3A232913FD4B8E00614220 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tDB3A232D13FD4B8F00614220 /* Build configuration list for PBXNativeTarget \"NimbusAttributedLabelTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tDB3A232A13FD4B8E00614220 /* Debug */,\n\t\t\t\tDB3A232B13FD4B8E00614220 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tDB84BD9713EFDDCA00DACCFE /* Build configuration list for PBXNativeTarget \"NimbusWebController\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tDB84BD9313EFDDCA00DACCFE /* Debug */,\n\t\t\t\tDB84BD9413EFDDCA00DACCFE /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tDB84BD9813EFDDCA00DACCFE /* Build configuration list for PBXNativeTarget \"NimbusWebControllerTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tDB84BD9513EFDDCA00DACCFE /* Debug */,\n\t\t\t\tDB84BD9613EFDDCA00DACCFE /* 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 = 66A03BFE13E6E84800B514F3 /* Project object */;\n}\n"
  },
  {
    "path": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusAttributedLabel.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"DB3A230813FD4B8E00614220\"\n               BuildableName = \"libNimbusAttributedLabel.a\"\n               BlueprintName = \"NimbusAttributedLabel\"\n               ReferencedContainer = \"container:Nimbus.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 = \"DB3A230813FD4B8E00614220\"\n            BuildableName = \"libNimbusAttributedLabel.a\"\n            BlueprintName = \"NimbusAttributedLabel\"\n            ReferencedContainer = \"container:Nimbus.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 = \"DB3A230813FD4B8E00614220\"\n            BuildableName = \"libNimbusAttributedLabel.a\"\n            BlueprintName = \"NimbusAttributedLabel\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusCollections.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"66FC98491703F9D7004E8FB8\"\n               BuildableName = \"libNimbusCollections.a\"\n               BlueprintName = \"NimbusCollections\"\n               ReferencedContainer = \"container:Nimbus.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"NO\"\n            buildForProfiling = \"NO\"\n            buildForArchiving = \"NO\"\n            buildForAnalyzing = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"D5BCE89D1D7539A300B6715F\"\n               BuildableName = \"NimbusCollectionsTests.xctest\"\n               BlueprintName = \"NimbusCollectionsTests\"\n               ReferencedContainer = \"container:Nimbus.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      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"66FC98491703F9D7004E8FB8\"\n            BuildableName = \"libNimbusCollections.a\"\n            BlueprintName = \"NimbusCollections\"\n            ReferencedContainer = \"container:Nimbus.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"D5BCE89D1D7539A300B6715F\"\n               BuildableName = \"NimbusCollectionsTests.xctest\"\n               BlueprintName = \"NimbusCollectionsTests\"\n               ReferencedContainer = \"container:Nimbus.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 = \"66FC98491703F9D7004E8FB8\"\n            BuildableName = \"libNimbusCollections.a\"\n            BlueprintName = \"NimbusCollections\"\n            ReferencedContainer = \"container:Nimbus.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 = \"66FC98491703F9D7004E8FB8\"\n            BuildableName = \"libNimbusCollections.a\"\n            BlueprintName = \"NimbusCollections\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusCore.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"66A03C0813E6E85E00B514F3\"\n               BuildableName = \"libNimbusCore.a\"\n               BlueprintName = \"NimbusCore\"\n               ReferencedContainer = \"container:Nimbus.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      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"66A03C0813E6E85E00B514F3\"\n            BuildableName = \"libNimbusCore.a\"\n            BlueprintName = \"NimbusCore\"\n            ReferencedContainer = \"container:Nimbus.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"66A03C1813E6E85E00B514F3\"\n               BuildableName = \"NimbusCoreTests.xctest\"\n               BlueprintName = \"NimbusCoreTests\"\n               ReferencedContainer = \"container:Nimbus.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 = \"66A03C0813E6E85E00B514F3\"\n            BuildableName = \"libNimbusCore.a\"\n            BlueprintName = \"NimbusCore\"\n            ReferencedContainer = \"container:Nimbus.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 = \"66A03C0813E6E85E00B514F3\"\n            BuildableName = \"libNimbusCore.a\"\n            BlueprintName = \"NimbusCore\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusCss.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"66C3A6A0143D61130048542F\"\n               BuildableName = \"libNimbusCss.a\"\n               BlueprintName = \"NimbusCss\"\n               ReferencedContainer = \"container:Nimbus.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 = \"66C3A6A0143D61130048542F\"\n            BuildableName = \"libNimbusCss.a\"\n            BlueprintName = \"NimbusCss\"\n            ReferencedContainer = \"container:Nimbus.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 = \"66C3A6A0143D61130048542F\"\n            BuildableName = \"libNimbusCss.a\"\n            BlueprintName = \"NimbusCss\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusInterapp.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"6675731113E771380076F555\"\n               BuildableName = \"libNimbusInterapp.a\"\n               BlueprintName = \"NimbusInterapp\"\n               ReferencedContainer = \"container:Nimbus.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 = \"6675731113E771380076F555\"\n            BuildableName = \"libNimbusInterapp.a\"\n            BlueprintName = \"NimbusInterapp\"\n            ReferencedContainer = \"container:Nimbus.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 = \"6675731113E771380076F555\"\n            BuildableName = \"libNimbusInterapp.a\"\n            BlueprintName = \"NimbusInterapp\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusModels.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"6661BBCB13F1A3BB00D14F92\"\n               BuildableName = \"libNimbusModels.a\"\n               BlueprintName = \"NimbusModels\"\n               ReferencedContainer = \"container:Nimbus.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 = \"6661BBCB13F1A3BB00D14F92\"\n            BuildableName = \"libNimbusModels.a\"\n            BlueprintName = \"NimbusModels\"\n            ReferencedContainer = \"container:Nimbus.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 = \"6661BBCB13F1A3BB00D14F92\"\n            BuildableName = \"libNimbusModels.a\"\n            BlueprintName = \"NimbusModels\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusNetworkImage.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"66A03D2613E6F97500B514F3\"\n               BuildableName = \"libNimbusNetworkImage.a\"\n               BlueprintName = \"NimbusNetworkImage\"\n               ReferencedContainer = \"container:Nimbus.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 = \"66A03D2613E6F97500B514F3\"\n            BuildableName = \"libNimbusNetworkImage.a\"\n            BlueprintName = \"NimbusNetworkImage\"\n            ReferencedContainer = \"container:Nimbus.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 = \"66A03D2613E6F97500B514F3\"\n            BuildableName = \"libNimbusNetworkImage.a\"\n            BlueprintName = \"NimbusNetworkImage\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusOverview.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"6675722813E765BF0076F555\"\n               BuildableName = \"libNimbusOverview.a\"\n               BlueprintName = \"NimbusOverview\"\n               ReferencedContainer = \"container:Nimbus.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 = \"6675722813E765BF0076F555\"\n            BuildableName = \"libNimbusOverview.a\"\n            BlueprintName = \"NimbusOverview\"\n            ReferencedContainer = \"container:Nimbus.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 = \"6675722813E765BF0076F555\"\n            BuildableName = \"libNimbusOverview.a\"\n            BlueprintName = \"NimbusOverview\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusPagingScrollView.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"663B523E1445052700CC26DF\"\n               BuildableName = \"libNimbusPagingScrollView.a\"\n               BlueprintName = \"NimbusPagingScrollView\"\n               ReferencedContainer = \"container:Nimbus.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 = \"663B523E1445052700CC26DF\"\n            BuildableName = \"libNimbusPagingScrollView.a\"\n            BlueprintName = \"NimbusPagingScrollView\"\n            ReferencedContainer = \"container:Nimbus.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 = \"663B523E1445052700CC26DF\"\n            BuildableName = \"libNimbusPagingScrollView.a\"\n            BlueprintName = \"NimbusPagingScrollView\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusPhotos.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"6675727913E769150076F555\"\n               BuildableName = \"libNimbusPhotos.a\"\n               BlueprintName = \"NimbusPhotos\"\n               ReferencedContainer = \"container:Nimbus.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 = \"6675727913E769150076F555\"\n            BuildableName = \"libNimbusPhotos.a\"\n            BlueprintName = \"NimbusPhotos\"\n            ReferencedContainer = \"container:Nimbus.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 = \"6675727913E769150076F555\"\n            BuildableName = \"libNimbusPhotos.a\"\n            BlueprintName = \"NimbusPhotos\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus.xcodeproj/xcshareddata/xcschemes/NimbusWebController.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\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 = \"DB84BD7313EFDDC900DACCFE\"\n               BuildableName = \"libNimbusWebController.a\"\n               BlueprintName = \"NimbusWebController\"\n               ReferencedContainer = \"container:Nimbus.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 = \"DB84BD7313EFDDC900DACCFE\"\n            BuildableName = \"libNimbusWebController.a\"\n            BlueprintName = \"NimbusWebController\"\n            ReferencedContainer = \"container:Nimbus.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 = \"DB84BD7313EFDDC900DACCFE\"\n            BuildableName = \"libNimbusWebController.a\"\n            BlueprintName = \"NimbusWebController\"\n            ReferencedContainer = \"container:Nimbus.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": "src/Nimbus_Prefix.pch",
    "content": "//\n// Copyright 2011 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#ifdef __OBJC__\n    #import <Foundation/Foundation.h>\n    #import <UIKit/UIKit.h>\n#endif\n"
  },
  {
    "path": "src/attributedlabel/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\nCoreText.framework\nQuartzCore.framework\n"
  },
  {
    "path": "src/attributedlabel/src/NIAttributedLabel+Testing.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally created by Roger Chapman\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIAttributedLabel.h\"\n\n/**\n * A category exposing methods that are exercised by unit tests.\n */\n@interface NIAttributedLabel (Testing)\n\n/**\n * The text checking result for the link that is currently being touched or nil if no link is\n * being touched.\n */\n@property (nonatomic, strong) NSTextCheckingResult *touchedLink;\n\n/**\n * An internal method that is called when the user long presses on a link.\n */\n- (void)_longPressTimerDidFire:(NSTimer *)timer;\n\n@end\n"
  },
  {
    "path": "src/attributedlabel/src/NIAttributedLabel.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally created by Roger Chapman\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n#import <CoreText/CoreText.h>\n\n#import \"NimbusCore.h\" // For __NI_DEPRECATED_METHOD\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Calculates the ideal dimensions of an attributed string fitting a given size.\n *\n * This calculation is performed off the raw attributed string so this calculation may differ\n * slightly from NIAttributedLabel's use of it due to lack of link and image attributes.\n *\n * This method is used in NIAttributedLabel to calculate its size after all additional\n * styling attributes have been set.\n */\nCGSize NISizeOfAttributedStringConstrainedToSize(NSAttributedString* attributedString, CGSize size, NSInteger numberOfLines);\n\n/**\n * By default, the size calculation (sizeThatFits:) for a multiline string (w/ newline chars) with\n * numberOfLines == 1 returns a height that would fit all lines instead of just the first line.\n * The intent was to return a width that can fit the entire string in one line, but the\n * implementation didn't account for presence of newline chars in the string.\n *\n * When enabled, it fixes such size calculation to return the size for just the first line as\n * expected. This matches the UILabel size calculation behavior as well.\n *\n * This is disabled by default due to existing clients that may depend on the legacy behavior.\n */\nvoid NIAttributedLabelEnableSingleLineSizeCalculationFix(void);\n\n#if defined __cplusplus\n}\n#endif\n\n// Vertical alignments for NIAttributedLabel.\ntypedef enum {\n  NIVerticalTextAlignmentTop = 0,\n  NIVerticalTextAlignmentMiddle,\n  NIVerticalTextAlignmentBottom,\n} NIVerticalTextAlignment;\n\ntypedef NS_ENUM(NSInteger, NILinkOrdering) {\n  NILinkOrderingFirst = 0, // Sort the links in the text as the first accessible elements\n  NILinkOrderingOriginal, // Won't do any sorting of the links, they will appear in the order in which they occur in the original text\n  NILinkOrderingLast, // Sort the links in the text as the last accessible elements\n};\n\nextern NSString* const NIAttributedLabelLinkAttributeName; // Value is an NSTextCheckingResult.\n\n@protocol NIAttributedLabelDelegate;\n/**\n * @internal\n *\n * The NIViewAccessibilityElement class encapsulates information about an item\n * that should be accessible to users with disabilities, but isn't accessible\n * by default and might be used in animations.\n *\n * Differences between UIAccessibilityElement and NIViewAccessibilityElement:\n *\n * - The accessibilityContainer must be a UIView.\n * - The accessibilityFrame is recomputed every time from the frameInContainer\n *   and the accessibilityContainer.\n * - The accessibilityPath and accessibilityActivationPoint (if applicable) are\n *   recomputed every time from the pointsInContainer and the accessibilityContainer.\n *\n * These differences cease to be as soon as the initial accessibility container\n * is changed externally, which is internally tracked by isContainerValid.\n */\n@interface NIViewAccessibilityElement : UIAccessibilityElement\n\n- (instancetype)initWithAccessibilityContainer:(id)container\n                              frameInContainer:(CGRect)frameInContainer\n                             pointsInContainer:(NSArray *)pointsInContainer;\n\n- (instancetype)initWithAccessibilityContainer:(id)container\n                              frameInContainer:(CGRect)frameInContainer;\n\n// This frame is in the accessibilityContainer coordinates.\n@property(nonatomic, readonly) CGRect frameInContainer;\n\n// The first element of the array is the accessibilityActivationPoint, the rest of the array is the\n// accessibilityPath.\n@property(nonatomic, readonly) NSArray<NSValue*> *pointsInContainer;\n\n/// If set to @c YES, this element remembers the last valid accessibility container when it receives\n/// a new one.\n@property(nonatomic) BOOL rememberLastValidContainer;\n\n@end\n\n/**\n * The NIAttributedLabel class provides support for displaying rich text with selectable links and\n * embedded images.\n *\n * Differences between UILabel and NIAttributedLabel:\n *\n * - @c NSLineBreakByTruncatingHead and @c NSLineBreakByTruncatingMiddle only apply to single\n *   lines and will not wrap the label regardless of the @c numberOfLines property. To wrap lines\n *   with any of these line break modes you must explicitly add newline characters to the string.\n * - When you assign an NSString to the text property the attributed label will create an\n *   attributed string that inherits all of the label's current styles.\n * - Text is aligned vertically to the top of the bounds by default rather than centered. You can\n *   change this behavior using @link NIAttributedLabel::verticalTextAlignment verticalTextAlignment@endlink.\n * - CoreText fills the frame with glyphs until they no longer fit. This is an important difference\n *   from UILabel because it means that CoreText will not add any glyphs that won't fit in the\n *   frame, while UILabel does. This can result in empty NIAttributedLabels if your frame is too\n *   small where UILabel would draw clipped text. It is recommended that you use sizeToFit to get\n *   the correct dimensions of the attributed label before setting the frame.\n *\n * NIAttributedLabel implements the UIAccessibilityContainer methods to expose each link as an\n * accessibility item. A note on performance, @c NIAttributedLabel generates these elements with an O(l*a)\n * complexity where l is the number of links in the text and a is the number of segments of differently\n * attributed text. Text arrangements where l~a have a complexity approaching O(a^2), while cases where\n * l<<a have a complexity that approaches O(a).\n *\n * @ingroup NimbusAttributedLabel\n */\n@interface NIAttributedLabel : UILabel\n\n// Please use attributedText instead. MAINTENANCE: Remove by Feb 28, 2014.\n@property (nonatomic, copy) NSAttributedString* attributedString __NI_DEPRECATED_METHOD;\n\n@property (nonatomic) BOOL                autoDetectLinks;    // Default: NO\n@property (nonatomic) NSTextCheckingType  dataDetectorTypes;  // Default: NSTextCheckingTypeLink\n@property (nonatomic) BOOL                deferLinkDetection; // Default: NO\n\n/**\n * Determines whether each link's accessibilityLabel will be determined by the label's text.\n * Defaults to YES.\n *\n * If enabled, each link will dynamically determine its accessibilityLabel based on the text to\n * which the link is attached.\n *\n * If disabled, each link will be set to either self.accessibilityLabel or\n * self.accessibilityAttributedLabel.\n */\n@property(nonatomic) BOOL shouldCalculateAccessibilityLabelPerLink;\n\n- (void)addLink:(NSURL *)urlLink range:(NSRange)range;\n- (void)removeAllExplicitLinks; // Removes all links that were added by addLink:range:. Does not remove autodetected links.\n\n@property (nonatomic, strong) UIColor*      linkColor;                      // Default: self.tintColor (iOS 7) or [UIColor blueColor] (iOS 6)\n@property (nonatomic, strong) UIColor*      strikethroughColor;             // Default: foreground color.\n@property (nonatomic, strong) UIColor*      highlightedLinkBackgroundColor; // Default: [UIColor colorWithWhite:0.5 alpha:0.5\n@property (nonatomic)         BOOL          linksHaveUnderlines;            // Default: NO\n@property (nonatomic, copy)   NSDictionary* attributesForLinks;             // Default: nil\n@property (nonatomic, copy)   NSDictionary* attributesForTailTruncationString;  // Default: nil\n@property (nonatomic, copy)   NSDictionary* attributesForHighlightedLink;   // Default: nil\n@property (nonatomic)         CGFloat       lineHeight;\n\n@property (nonatomic)         NIVerticalTextAlignment   verticalTextAlignment;  // Default: NIVerticalTextAlignmentTop\n@property (nonatomic)         CTUnderlineStyle          underlineStyle;\n@property (nonatomic)         CTUnderlineStyleModifiers underlineStyleModifier;\n@property (nonatomic)         CGFloat                   shadowBlur;             // Default: 0\n@property (nonatomic)         CGFloat                   strokeWidth;\n@property (nonatomic, strong) UIColor*                  strokeColor;\n@property (nonatomic)         CGFloat                   textKern;\n\n@property (nonatomic, copy) NSString* tailTruncationString;\n\n@property (nonatomic) BOOL shouldSortLinksLast DEPRECATED_MSG_ATTRIBUTE(\"Use linkOrdering instead. Besides sorting links as first or last accessible elements, we are introducing a new way which sorts links in their original order and breaks the text into fragments when necessary.\"); // Sort the links in the text as the last elements in accessible elements. Default: NO\n\n@property (nonatomic) NILinkOrdering linkOrdering; // Define how to sort links in the text. Default: NILinkOrderFirst\n@property(nonatomic) BOOL shouldMergeMultilineLinks;\n\n/**\n * Configures if the label's accessibility elements should remember their last valid accessibility\n * containers (Default: @c NO)\n *\n * An accessibility element in a @c NIAttributedLabel considers its accessibility container to be\n * valid if it knows its frame inside the container. While an element has a valid container, it can\n * dynamically compute its accessibility properties (e.g. @c accessibilityFrame) upon request to\n * ensure such properties are correct even if the label's position on screen changes.\n *\n * UIKit sometimes spontaneously changes the accessibility containers of all accessibility elements\n * in a @c NIAttributedLabel to another view. When this happens, the elements no longer know their\n * frames inside the new container, so they must fall back to static accessibility properties that\n * were computed on init. Those values only remain correct as long as their label's position on\n * screen remains unchanged since they were computed. If the label is embedded inside a scroll view,\n * those values will quickly become stale.\n *\n * Setting this property to @c YES allows @c NIAttributedLabel's accessibility elements to remember\n * their last valid containers. When asked for their accessibility properties, if they no longer\n * have a valid container, they will attempt to use their last valid containers for dynamic\n * computations if possible before defaulting to fallback static values.\n */\n@property(nonatomic) BOOL accessibleElementsRememberLastValidContainer;\n\n- (void)setFont:(UIFont *)font            range:(NSRange)range;\n- (void)setStrokeColor:(UIColor *)color   range:(NSRange)range;\n- (void)setStrokeWidth:(CGFloat)width     range:(NSRange)range;\n- (void)setTextColor:(UIColor *)textColor range:(NSRange)range;\n- (void)setTextKern:(CGFloat)kern         range:(NSRange)range;\n- (void)setUnderlineStyle:(CTUnderlineStyle)style modifier:(CTUnderlineStyleModifiers)modifier range:(NSRange)range;\n\n- (void)insertImage:(UIImage *)image atIndex:(NSInteger)index;\n- (void)insertImage:(UIImage *)image atIndex:(NSInteger)index margins:(UIEdgeInsets)margins;\n- (void)insertImage:(UIImage *)image atIndex:(NSInteger)index margins:(UIEdgeInsets)margins verticalTextAlignment:(NIVerticalTextAlignment)verticalTextAlignment;\n\n- (void)invalidateAccessibleElements;\n- (NSArray *)accessibleElements;\n\n- (NSTextCheckingResult *)linkAtPoint:(CGPoint)point;\n\n@property (nonatomic, weak) IBOutlet id<NIAttributedLabelDelegate> delegate;\n@end\n\n/**\n * The methods declared by the NIAttributedLabelDelegate protocol allow the adopting delegate to\n * respond to messages from the NIAttributedLabel class and thus respond to selections.\n *\n * @ingroup NimbusAttributedLabel\n */\n@protocol NIAttributedLabelDelegate <NSObject>\n@optional\n\n/** @name Managing Selections */\n\n/**\n * Informs the receiver that a data detector result has been selected.\n *\n * @param attributedLabel An attributed label informing the receiver of the selection.\n * @param result The data detector result that was selected.\n * @param point The point within @c attributedLabel where the result was tapped.\n */\n- (void)attributedLabel:(NIAttributedLabel *)attributedLabel didSelectTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point;\n\n/**\n * Informs the receiver that a data detector result has been long pressed.\n *\n * If this method is implemented by the receiver then\n * -attributedLabel:shouldPresentActionSheet:withTextCheckingResult:atPoint: will not be called\n * and no action sheet will be presented when long pressing a data detector result.\n *\n * @param attributedLabel An attributed label informing the receiver of the selection.\n * @param result The data detector result that was long pressed.\n * @param point The point within @c attributedLabel where the result was long pressed.\n */\n- (void)attributedLabel:(NIAttributedLabel *)attributedLabel didLongPressTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point;\n\n/**\n * Asks the receiver whether an action sheet should be displayed at the given point.\n *\n * If -attributedLabel:didLongPressTextCheckingResult:atPoint: is implemented by the receiver, this\n * delegate method will not be called and no action sheet will be displayed. If neither\n * -attributedLabel:didLongPressTextCheckingResult:atPoint: nor\n * -attributedLabel:shouldPresentActionSheet:withTextCheckingResult:atPoint: are implemented by the\n * receiver, @c actionSheet will always be displayed.\n *\n * @c actionSheet will be populated with actions that match the data type that was selected. For\n * example, a link will have the actions \"Open in Safari\" and \"Copy URL\". A phone number will have\n * @\"Call\" and \"Copy Phone Number\".\n *\n * @param attributedLabel An attributed label asking the delegate whether to display the action\n *                             sheet.\n * @param actionSheet The action sheet that will be displayed if YES is returned.\n * @param result The data detector result that was selected.\n * @param point The point within @c attributedLabel where the result was tapped.\n * @returns YES if @c actionSheet should be displayed. NO if @c actionSheet should not be\n *               displayed.\n */\n- (BOOL)attributedLabel:(NIAttributedLabel *)attributedLabel shouldPresentActionSheet:(UIActionSheet *)actionSheet withTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point NS_DEPRECATED_IOS(2_0, 8_3, \"UIActionSheet is deprecated. Use -attributedLabel:didLongPressTextCheckingResult:atPoint: and UIAlertController with a preferredStyle of UIAlertControllerStyleActionSheet instead\");\n\n@end\n\n/** @name Accessing the Text Attributes */\n\n/**\n * This method is now deprecated and will eventually be removed, please use attributedText instead.\n *\n * @fn NIAttributedLabel::attributedString\n */\n\n/** @name Accessing and Detecting Links */\n\n/**\n * A Booelan value indicating whether to automatically detect links in the string.\n *\n * By default this is disabled.\n *\n * Link detection is deferred until the label is displayed for the first time. If the text changes\n * then all of the links will be cleared and re-detected when the label displays again.\n *\n * Note that link detection is an expensive operation. If you are planning to use attributed labels\n * in table views or similar high-performance situations then you should consider enabling defered\n * link detection by setting @link NIAttributedLabel::deferLinkDetection deferLinkDetection@endlink\n * to YES.\n *\n * @sa NIAttributedLabel::dataDetectorTypes\n * @sa NIAttributedLabel::deferLinkDetection\n * @fn NIAttributedLabel::autoDetectLinks\n */\n\n/**\n * A Boolean value indicating whether to defer link detection to a separate thread.\n *\n * By default this is disabled.\n *\n * When defering is enabled, link detection will be performed on a separate thread. This will cause\n * your label to appear without any links briefly before being redrawn with the detected links.\n * This offloads the data detection to a separate thread so that your labels can be displayed\n * faster.\n *\n * @fn NIAttributedLabel::deferLinkDetection\n */\n\n/**\n * The types of data that will be detected when\n * @link NIAttributedLabel::autoDetectLinks autoDetectLinks@endlink is enabled.\n *\n * By default this is NSTextCheckingTypeLink. <a href=\"https://developer.apple.com/library/mac/#documentation/AppKit/Reference/NSTextCheckingResult_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40008798-CH1-DontLinkElementID_50\">All available data detector types</a>.\n *\n * @fn NIAttributedLabel::dataDetectorTypes\n */\n\n/**\n * Adds a link to a URL at a given range.\n *\n * Adding any links will immediately enable user interaction on this label. Explicitly added\n * links are removed whenever the text changes.\n *\n * @fn NIAttributedLabel::addLink:range:\n */\n\n/**\n * Removes all explicit links from the label.\n *\n * If you wish to remove automatically-detected links, set autoDetectLinks to NO.\n *\n * @fn NIAttributedLabel::removeAllExplicitLinks\n */\n\n/** @name Accessing Link Display Styles */\n\n/**\n * The text color of detected links.\n *\n * The default color is [UIColor blueColor] on pre-iOS 7 devices or self.tintColor on iOS 7 devices.\n * If linkColor is assigned nil then links will not be given any special color. Use\n * attributesForLinks to specify alternative styling.\n *\n *  @image html NIAttributedLabelLinkAttributes.png \"Link attributes\"\n *\n * @fn NIAttributedLabel::linkColor\n */\n\n/**\n * The background color of the link's selection frame when the user is touching the link.\n *\n * The default is [UIColor colorWithWhite:0.5 alpha:0.5].\n *\n * If you do not want links to be highlighted when touched, set this to nil.\n *\n *  @image html NIAttributedLabelLinkAttributes.png \"Link attributes\"\n *\n * @fn NIAttributedLabel::highlightedLinkBackgroundColor\n */\n\n/**\n * A Boolean value indicating whether links should have underlines.\n *\n * By default this is disabled.\n *\n * This affects all links in the label.\n *\n * @fn NIAttributedLabel::linksHaveUnderlines\n */\n\n/**\n * A dictionary of CoreText attributes to apply to links.\n *\n * This dictionary must contain CoreText attributes. These attributes are applied after the color\n * and underline styles have been applied to the link.\n *\n * @fn NIAttributedLabel::attributesForLinks\n */\n\n/**\n * A dictionary of CoreText attributes to apply to the highlighted link.\n *\n * This dictionary must contain CoreText attributes. These attributes are applied after\n * attributesForLinks have been applied to the highlighted link.\n *\n * @fn NIAttributedLabel::attributesForHighlightedLink\n */\n\n/** @name Modifying Rich Text Styles for All Text */\n\n/**\n * The vertical alignment of the text within the label's bounds.\n *\n * The default is @c NIVerticalTextAlignmentTop. This is for performance reasons because the other\n * modes require more computation. Aligning to the top is generally what you want anyway.\n *\n * @c NIVerticalTextAlignmentBottom will align the text to the bottom of the bounds, while\n * @c NIVerticalTextAlignmentMiddle will center the text vertically.\n *\n * @fn NIAttributedLabel::verticalTextAlignment\n */\n\n/**\n * The underline style for the entire label.\n *\n * By default this is @c kCTUnderlineStyleNone.\n *\n * <a href=\"https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_StringAttributes_Ref/Reference/reference.html#//apple_ref/c/tdef/CTUnderlineStyle\">View all available styles</a>.\n *\n * @fn NIAttributedLabel::underlineStyle\n */\n\n/**\n * The underline style modifier for the entire label.\n *\n * By default this is @c kCTUnderlinePatternSolid.\n *\n * <a href=\"https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_StringAttributes_Ref/Reference/reference.html#//apple_ref/c/tdef/CTUnderlineStyleModifiers\">View all available style\n * modifiers</a>.\n *\n * @fn NIAttributedLabel::underlineStyleModifier\n */\n\n/**\n * A non-negative number specifying the amount of blur to apply to the label's text shadow.\n *\n * By default this is zero.\n *\n * @fn NIAttributedLabel::shadowBlur\n */\n\n/**\n * Sets the stroke width for the text.\n *\n * By default this is zero.\n *\n * Positive numbers will draw the stroke. Negative numbers will draw the stroke and fill.\n *\n * @fn NIAttributedLabel::strokeWidth\n */\n\n/**\n * Sets the stroke color for the text.\n *\n * By default this is nil.\n *\n * @fn NIAttributedLabel::strokeColor\n */\n\n/**\n * Sets the line height for the text.\n *\n * By default this is zero.\n *\n * Setting this value to zero will make the label use the default line height for the text's font.\n *\n * @fn NIAttributedLabel::lineHeight\n */\n\n/**\n * Sets the kern for the text.\n *\n * By default this is zero.\n *\n * The text kern indicates how many points each character should be shifted from its default offset.\n * A positive kern indicates a shift farther away. A negative kern indicates a shift closer.\n *\n * @fn NIAttributedLabel::textKern\n */\n\n/** @name Modifying Tail Truncation Properties */\n\n/**\n * The string to display for tail truncation.\n *\n * By default this is nil and the default ellipses character, \\u2026, is used.\n *\n * @fn NIAttributedLabel::tailTruncationString\n */\n\n/** @name Modifying Rich Text Styles in Ranges */\n\n/**\n * Sets the text color for text in a given range.\n *\n * @fn NIAttributedLabel::setTextColor:range:\n */\n\n/**\n * Sets the font for text in a given range.\n *\n * @fn NIAttributedLabel::setFont:range:\n */\n\n/**\n * Sets the underline style and modifier for text in a given range.\n *\n * <a href=\"https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_StringAttributes_Ref/Reference/reference.html#//apple_ref/c/tdef/CTUnderlineStyle\">View all available styles</a>.\n *\n * <a href=\"https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_StringAttributes_Ref/Reference/reference.html#//apple_ref/c/tdef/CTUnderlineStyleModifiers\">View all available style\n * modifiers</a>.\n *\n * @fn NIAttributedLabel::setUnderlineStyle:modifier:range:\n */\n\n/**\n * Sets the stroke width for text in a given range.\n *\n * Positive numbers will draw the stroke. Negative numbers will draw the stroke and fill.\n *\n * @fn NIAttributedLabel::setStrokeWidth:range:\n */\n\n/**\n * Sets the stroke color for text in a given range.\n *\n * @fn NIAttributedLabel::setStrokeColor:range:\n */\n\n/**\n * Sets the kern for text in a given range.\n *\n * The text kern indicates how many points each character should be shifted from its default offset.\n * A positive kern indicates a shift farther away. A negative kern indicates a shift closer.\n *\n * @fn NIAttributedLabel::setTextKern:range:\n */\n\n/** @name Adding Inline Images */\n\n/**\n * Inserts the given image inline at the given index in the receiver's text.\n *\n * The image will have no margins.\n * The image's vertical text alignment will be NIVerticalTextAlignmentBottom.\n *\n * @param image The image to add to the receiver.\n * @param index The index into the receiver's text at which to insert the image.\n * @fn NIAttributedLabel::insertImage:atIndex:\n */\n\n/**\n * Inserts the given image inline at the given index in the receiver's text.\n *\n * The image's vertical text alignment will be NIVerticalTextAlignmentBottom.\n *\n * @param image The image to add to the receiver.\n * @param index The index into the receiver's text at which to insert the image.\n * @param margins The space around the image on all sides in points.\n * @fn NIAttributedLabel::insertImage:atIndex:margins:\n */\n\n/**\n * Inserts the given image inline at the given index in the receiver's text.\n *\n * @attention\n *      Images do not currently support NIVerticalTextAlignmentTop and the receiver will fire\n *      multiple debug assertions if you attempt to use it.\n *\n * @param image The image to add to the receiver.\n * @param index The index into the receiver's text at which to insert the image.\n * @param margins The space around the image on all sides in points.\n * @param verticalTextAlignment The position of the text relative to the image.\n * @fn NIAttributedLabel::insertImage:atIndex:margins:verticalTextAlignment:\n */\n\n/** @name Accessibility */\n\n/**\n * Invalidates this label's accessible elements.\n *\n * When a label is contained within another view and that parent view moves, the label will not be\n * informed of this change and any existing accessibility elements will still point to the old\n * screen location. If this happens you must call -invalidateAccessibleElements in order to force\n * the label to refresh its accessibile elements.\n *\n * @fn NIAttributedLabel::invalidateAccessibleElements\n */\n\n/** @name Accessing the Delegate */\n\n/**\n * The delegate of the attributed-label object.\n *\n * The delegate must adopt the NIAttributedLabelDelegate protocol. The NIAttributedLabel class,\n * which does not strong the delegate, invokes each protocol method the delegate implements.\n *\n * @fn NIAttributedLabel::delegate\n */\n"
  },
  {
    "path": "src/attributedlabel/src/NIAttributedLabel.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally created by Roger Chapman\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIAttributedLabel.h\"\n#import \"NIAttributedLabel+Testing.h\"\n\n#import \"NSMutableAttributedString+NimbusAttributedLabel.h\"\n#import <QuartzCore/QuartzCore.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n#error \"NIAttributedLabel requires iOS 6 or higher.\"\n#endif\n\n#define _NI_PUSH_SCOPED_DIAGNOSTICS_COMMAND(cmd) \\\n  _Pragma (\"clang diagnostic push\") \\\n  _Pragma (cmd)\n\n#define _NI_POP_DIAGNOSTICS() \\\n  _Pragma (\"clang diagnostic pop\")\n\n#if defined(__IPHONE_8_3) && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_3)\n#define _NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_PUSH() \\\n  _NI_PUSH_SCOPED_DIAGNOSTICS_COMMAND(\"clang diagnostic ignored \\\"-Wdeprecated-declarations\\\"\")\n#define _NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_POP() \\\n  _NI_POP_DIAGNOSTICS()\n#else\n#define _NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_PUSH()\n#define _NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_POP()\n#endif // defined(__IPHONE_8_3) && (__IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_8_3)\n\n// The number of seconds to wait before executing a long press action on the tapped link.\nstatic const NSTimeInterval kLongPressTimeInterval = 0.5;\n\n// The number of pixels the user's finger must move before cancelling the long press timer.\nstatic const CGFloat kLongPressGutter = 22;\n\n// The touch gutter is the amount of space around a link that will still register as tapping\n// \"within\" the link.\nstatic const CGFloat kTouchGutter = 22;\n\nstatic const CGFloat kVMargin = 5.0f;\n\n// \\u2026 is the Unicode horizontal ellipsis character code\nstatic NSString* const kEllipsesCharacter = @\"\\u2026\";\n\nNSString* const NIAttributedLabelLinkAttributeName = @\"NIAttributedLabel:Link\";\n\nstatic const void *kFontAttributeKey = @\"NSFont\";\nstatic const void *kStrikethroughAttributeKey = @\"NSStrikethrough\";\nstatic const void *kStrikethroughColorAttributeKey = @\"NSStrikethroughColorAttributeName\";\n\nstatic BOOL sEnableSingleLineSizeCalculationFix = NO;\n\n// For supporting images.\nCGFloat NIImageDelegateGetAscentCallback(void* refCon);\nCGFloat NIImageDelegateGetDescentCallback(void* refCon);\nCGFloat NIImageDelegateGetWidthCallback(void* refCon);\n\nvoid NIAttributedLabelEnableSingleLineSizeCalculationFix(void) {\n  sEnableSingleLineSizeCalculationFix = YES;\n}\n\nCGSize NISizeOfAttributedStringConstrainedToSize(NSAttributedString* attributedString, CGSize constraintSize, NSInteger numberOfLines) {\n  if (nil == attributedString) {\n    return CGSizeZero;\n  }\n\n  CFAttributedStringRef attributedStringRef = (__bridge CFAttributedStringRef)attributedString;\n  CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attributedStringRef);\n  NIDASSERT(NULL != framesetter);\n  if (NULL == framesetter) {\n    return CGSizeZero;\n  }\n  CFRange range = CFRangeMake(0, 0);\n\n  // This logic adapted from @mattt's TTTAttributedLabel\n  // https://github.com/mattt/TTTAttributedLabel\n\n  if (!sEnableSingleLineSizeCalculationFix && numberOfLines == 1) {\n    constraintSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);\n  } else if (numberOfLines > 0 && nil != framesetter) {\n    if (numberOfLines == 1) {\n      constraintSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);\n    }\n    CGMutablePathRef path = CGPathCreateMutable();\n    CGPathAddRect(path, NULL, CGRectMake(0, 0, constraintSize.width, constraintSize.height));\n    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);\n    CFArrayRef lines = CTFrameGetLines(frame);\n\n    if (nil != lines && CFArrayGetCount(lines) > 0) {\n      NSInteger lastVisibleLineIndex = MIN(numberOfLines, CFArrayGetCount(lines)) - 1;\n      CTLineRef lastVisibleLine = CFArrayGetValueAtIndex(lines, lastVisibleLineIndex);\n\n      CFRange rangeToLayout = CTLineGetStringRange(lastVisibleLine);\n      range = CFRangeMake(0, rangeToLayout.location + rangeToLayout.length);\n    }\n\n    CFRelease(frame);\n    CFRelease(path);\n  }\n\n  CGSize newSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, range, NULL, constraintSize, NULL);\n\n  CFRelease(framesetter);\n\n  return CGSizeMake(NICGFloatCeil(newSize.width), NICGFloatCeil(newSize.height));\n}\n\n\n@interface NIViewAccessibilityElement ()\n\n/// The last valid container (only set if @c rememberLastValidContainer is true).\n@property(nonatomic, weak) UIView *lastValidContainer;\n\n// Whether the computations done based on the container are still valid. That is, the container has\n// not been changed since the computations (see frameInContainer and pointsInContainer) were\n// performed.\n@property (nonatomic) BOOL isContainerDataValid;\n\n// This property ensures multiline NIViewAccessibilityElements have unique\n// touch points when merging multiline links into a single NIViewAccessibilityElement.\n// When the first link contains either the first or the last word in the sentence and the second\n// link spills between more than one line, the NIViewAccessibilityElement\n// frames have the same top left point, which can be used as the touch point. This causes an\n// issue where NIAttributedLabel can't determine which accessibilityElement a touchPoint\n// originated from, meaning that one of the  two links can't register events.\n// We solve this by using the bottom left of the frame, which is ensured to be unique\n// (only for links in the same text) as multiline element frames would have unique y-coordinates,\n// and is also ensured to contain the text to maintain tap-functionality.\n@property(nonatomic) BOOL shouldCalculateUniqueActivationPoint;\n\n@end\n\n@implementation NIViewAccessibilityElement\n\n// The accessibilityFrame is always needed even if we have an accessibilityPath (accessibilityPath\n// will override accessibilityFrame when VoiceOver tries to highlight this element), because the\n// screen scrolls according to the frame (will scroll until the frame fully appears).\n- (instancetype)initWithAccessibilityContainer:(id)container\n                              frameInContainer:(CGRect)frameInContainer\n                             pointsInContainer:(NSArray *)pointsInContainer {\n  NIDASSERT([container isKindOfClass:[UIView class]]);\n  if ((self = [super initWithAccessibilityContainer:container])) {\n    _frameInContainer = frameInContainer;\n    _pointsInContainer = pointsInContainer;\n    _isContainerDataValid = YES;\n  }\n  return self;\n}\n\n- (instancetype)initWithAccessibilityContainer:(id)container\n                              frameInContainer:(CGRect)frameInContainer {\n  return [self initWithAccessibilityContainer:container\n                             frameInContainer:frameInContainer\n                            pointsInContainer:nil];\n}\n\n- (instancetype)initWithAccessibilityContainer:(id)container {\n  if (self = [self initWithAccessibilityContainer:container\n                                 frameInContainer:CGRectZero\n                                pointsInContainer:nil]) {\n    self.isContainerDataValid = NO;\n  }\n  return self;\n}\n\n- (void)setRememberLastValidContainer:(BOOL)rememberLastValidContainer {\n  _rememberLastValidContainer = rememberLastValidContainer;\n  if (!rememberLastValidContainer) {\n    self.lastValidContainer = nil;\n  }\n}\n\n- (void)setAccessibilityContainer:(id)accessibilityContainer {\n  if (self.isContainerDataValid && self.rememberLastValidContainer) {\n    self.lastValidContainer = self.accessibilityContainer;\n  }\n  self.isContainerDataValid = NO;\n  [super setAccessibilityContainer:accessibilityContainer];\n}\n\n- (UIView *)validAccessibilityContainer {\n  UIView *accessibilityContainerView;\n  if (self.isContainerDataValid) {\n    accessibilityContainerView = self.accessibilityContainer;\n  } else if (self.rememberLastValidContainer && self.lastValidContainer) {\n    accessibilityContainerView = self.lastValidContainer;\n  } else {\n    return nil;\n  }\n  NIDASSERT([accessibilityContainerView isKindOfClass:[UIView class]]);\n  return accessibilityContainerView;\n}\n\n- (CGRect)accessibilityFrame {\n  UIView *accessibilityContainerView = [self validAccessibilityContainer];\n  if (accessibilityContainerView) {\n    CGRect frame = [accessibilityContainerView convertRect:self.frameInContainer toView:nil];\n    return [accessibilityContainerView.window convertRect:frame toWindow:nil];\n  }\n  return super.accessibilityFrame;\n}\n\n- (UIBezierPath *)accessibilityPath {\n  UIView *accessibilityContainerView = [self validAccessibilityContainer];\n  if (accessibilityContainerView && NIIsArrayWithObjects(_pointsInContainer)) {\n    UIBezierPath *path = [UIBezierPath bezierPath];\n    for (NSUInteger i = 1; i < _pointsInContainer.count; ++i) {\n      CGPoint p = [[_pointsInContainer objectAtIndex:i] CGPointValue];\n      p = [accessibilityContainerView convertPoint:p toView:nil];\n      p = [accessibilityContainerView.window convertPoint:p toWindow:nil];\n      if (path.empty) {\n        [path moveToPoint:p];\n      } else {\n        [path addLineToPoint:p];\n      }\n    }\n    [path closePath];\n    return path;\n  }\n  return super.accessibilityPath;\n}\n\n- (CGPoint)accessibilityActivationPoint {\n  UIView *accessibilityContainerView = [self validAccessibilityContainer];\n  if (_shouldCalculateUniqueActivationPoint) {\n    // Since links cannot overlap, use the bottom left point since it is guaranteed\n    // to not overlap and also guaranteed to contain the selected link.\n    CGPoint point = CGPointMake(_frameInContainer.origin.x,\n                                _frameInContainer.origin.y + _frameInContainer.size.height);\n    point = [accessibilityContainerView convertPoint:point toView:nil];\n    return [accessibilityContainerView.window convertPoint:point toWindow:nil];\n  } else if (accessibilityContainerView && NIIsArrayWithObjects(_pointsInContainer)) {\n    CGPoint point = [[_pointsInContainer firstObject] CGPointValue];\n    point = [accessibilityContainerView convertPoint:point toView:nil];\n    return [accessibilityContainerView.window convertPoint:point toWindow:nil];\n  }\n  return super.accessibilityActivationPoint;\n}\n\n@end\n\n@interface NIAttributedLabelImage : NSObject\n\n- (CGSize)boxSize; // imageSize + margins\n\n@property (nonatomic)           NSInteger     index;\n@property (nonatomic, strong)   UIImage*      image;\n@property (nonatomic)           UIEdgeInsets  margins;\n\n@property (nonatomic) NIVerticalTextAlignment verticalTextAlignment;\n\n@property (nonatomic) CGFloat fontAscent;\n@property (nonatomic) CGFloat fontDescent;\n\n@end\n\n@implementation NIAttributedLabelImage\n\n- (CGSize)boxSize {\n  return CGSizeMake(self.image.size.width + self.margins.left + self.margins.right,\n                    self.image.size.height + self.margins.top + self.margins.bottom);\n}\n\n@end\n\n@interface NIAttributedLabel() <UIActionSheetDelegate>\n\n@property (nonatomic, strong) NSMutableAttributedString* mutableAttributedString;\n\n@property (nonatomic) CTFrameRef textFrame; // CFType, manually managed lifetime, see setter.\n\n@property (nonatomic, assign) NSInteger linkDetectionRequestID;\n@property (nonatomic)         BOOL linksHaveBeenDetected;\n@property (nonatomic, copy)   NSArray*        detectedlinkLocations;\n@property (nonatomic, strong) NSMutableArray* explicitLinkLocations;  // Of NSTextCheckingResult.\n\n@property (nonatomic, strong) NSTextCheckingResult* originalLink;\n@property (nonatomic, strong) NSTextCheckingResult* touchedLink;\n\n@property (nonatomic, strong) NSTimer*  longPressTimer;\n@property (nonatomic)         CGPoint   touchPoint;\n\n@property (nonatomic, strong) NSTextCheckingResult* actionSheetLink;\n\n@property (nonatomic, copy) NSArray* accessibleElements;\n\n@property (nonatomic, strong) NSMutableArray *images;\n\n@end\n\n@interface NIAttributedLabel (ConversionUtilities)\n\n+ (CTTextAlignment)alignmentFromUITextAlignment:(NSTextAlignment)alignment;\n+ (CTLineBreakMode)lineBreakModeFromUILineBreakMode:(NSLineBreakMode)lineBreakMode;\n+ (NSMutableAttributedString *)mutableAttributedStringFromLabel:(UILabel *)label;\n\n@end\n\n@implementation NIAttributedLabel\n\n@synthesize textFrame = _textFrame;\n\n- (void)dealloc {\n  [_longPressTimer invalidate];\n\n  [self invalidateAccessibleElements];\n\n  // The property is marked 'assign', but retain count for this CFType is managed here and via\n  // the setter.\n  if (NULL != _textFrame) {\n    CFRelease(_textFrame);\n  }\n}\n\n- (CTFrameRef)textFrame {\n  if (NULL == _textFrame) {\n    NSMutableAttributedString* attributedStringWithLinks = [self mutableAttributedStringWithAdditions];\n    CFAttributedStringRef attributedString = (__bridge CFAttributedStringRef)attributedStringWithLinks;\n    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attributedString);\n    NIDASSERT(NULL != framesetter);\n    if (NULL == framesetter) {\n      return NULL;\n    }\n\n    CGMutablePathRef path = CGPathCreateMutable();\n    NIDASSERT(NULL != path);\n    if (NULL == path) {\n      CFRelease(framesetter);\n      return NULL;\n    }\n\n    CGPathAddRect(path, NULL, self.bounds);\n    CTFrameRef textFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);\n    self.textFrame = textFrame;\n    if (textFrame) {\n      CFRelease(textFrame);\n    }\n    CGPathRelease(path);\n    CFRelease(framesetter);\n  }\n\n  return _textFrame;\n}\n\n- (void)setTextFrame:(CTFrameRef)textFrame {\n  // The property is marked 'assign', but retain count for this CFType is managed via this setter\n  // and -dealloc.\n  if (textFrame != _textFrame) {\n    if (NULL != _textFrame) {\n      CFRelease(_textFrame);\n    }\n    if (NULL != textFrame) {\n      CFRetain(textFrame);\n    }\n    _textFrame = textFrame;\n  }\n}\n\n- (void)_configureDefaults {\n  self.verticalTextAlignment = NIVerticalTextAlignmentTop;\n  self.linkColor = NIIsTintColorGloballySupported() ? self.tintColor : [UIColor blueColor];\n  self.dataDetectorTypes = NSTextCheckingTypeLink;\n  self.highlightedLinkBackgroundColor = [UIColor colorWithWhite:0.5f alpha:0.5f];\n  self.shouldCalculateAccessibilityLabelPerLink = YES;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    [self _configureDefaults];\n  }\n  return self;\n}\n\n- (void)awakeFromNib {\n  [super awakeFromNib];\n\n  [self _configureDefaults];\n\n  self.attributedText = [[self class] mutableAttributedStringFromLabel:self];\n}\n\n- (void)resetTextFrame {\n  self.textFrame = NULL;\n  self.accessibleElements = nil;\n}\n\n- (void)attributedTextDidChange {\n  [self resetTextFrame];\n\n  [self invalidateIntrinsicContentSize];\n  [self setNeedsDisplay];\n}\n\n- (void)setFrame:(CGRect)frame {\n  BOOL frameDidChange = !CGRectEqualToRect(self.frame, frame);\n\n  [super setFrame:frame];\n\n  if (frameDidChange) {\n    [self attributedTextDidChange];\n  }\n}\n\n- (CGSize)sizeThatFits:(CGSize)size {\n  if (nil == self.mutableAttributedString) {\n    return CGSizeZero;\n  }\n\n  return NISizeOfAttributedStringConstrainedToSize([self mutableAttributedStringWithAdditions], size, self.numberOfLines);\n}\n\n- (CGSize)intrinsicContentSize {\n  return [self sizeThatFits:[super intrinsicContentSize]];\n}\n\n#pragma mark - Public\n\n- (void)setText:(NSString *)text {\n  [super setText:text];\n\n  self.attributedText = [[self class] mutableAttributedStringFromLabel:self];\n\n  // Apply NIAttributedLabel-specific styles.\n  [self.mutableAttributedString setUnderlineStyle:_underlineStyle modifier:_underlineStyleModifier];\n  [self.mutableAttributedString setStrokeWidth:_strokeWidth];\n  [self.mutableAttributedString setStrokeColor:_strokeColor];\n  [self.mutableAttributedString setKern:_textKern];\n}\n\n// Deprecated.\n- (void)setAttributedString:(NSAttributedString *)attributedString {\n  self.attributedText = attributedString;\n}\n\n// Deprecated.\n- (NSAttributedString *)attributedString {\n  return self.attributedText;\n}\n\n- (NSAttributedString *)attributedText {\n  return [self.mutableAttributedString copy];\n}\n\n- (void)setAttributedText:(NSAttributedString *)attributedText {\n  if (self.mutableAttributedString != attributedText) {\n    self.mutableAttributedString = [attributedText mutableCopy];\n\n    // Clear the link caches.\n    self.detectedlinkLocations = nil;\n    self.linksHaveBeenDetected = NO;\n    self.linkDetectionRequestID++;\n    [self removeAllExplicitLinks];\n\n    // Remove all images.\n    self.images = nil;\n\n    // Pull any explicit links from the attributed string itself\n    [self _processLinksInAttributedString:self.mutableAttributedString];\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setAutoDetectLinks:(BOOL)autoDetectLinks {\n  _autoDetectLinks = autoDetectLinks;\n\n  [self attributedTextDidChange];\n}\n\n- (void)addLink:(NSURL *)urlLink range:(NSRange)range {\n  if (nil == self.explicitLinkLocations) {\n    self.explicitLinkLocations = [[NSMutableArray alloc] init];\n  }\n\n  NSTextCheckingResult* result = [NSTextCheckingResult linkCheckingResultWithRange:range URL:urlLink];\n  [self.explicitLinkLocations addObject:result];\n\n  [self attributedTextDidChange];\n}\n\n- (void)removeAllExplicitLinks {\n  self.explicitLinkLocations = nil;\n\n  [self attributedTextDidChange];\n}\n\n- (void)setTextAlignment:(NSTextAlignment)textAlignment {\n  // We assume that the UILabel implementation will call setNeedsDisplay. Where we don't call super\n  // we call setNeedsDisplay ourselves.\n  if (NSTextAlignmentJustified == textAlignment) {\n    // iOS 6.0 Beta 2 crashes when using justified text alignments for some reason.\n    [super setTextAlignment:NSTextAlignmentLeft];\n  } else {\n    [super setTextAlignment:textAlignment];\n  }\n\n  if (nil != self.mutableAttributedString) {\n    CTTextAlignment alignment = [self.class alignmentFromUITextAlignment:textAlignment];\n    CTLineBreakMode lineBreak = [self.class lineBreakModeFromUILineBreakMode:self.lineBreakMode];\n    [self.mutableAttributedString setTextAlignment:alignment lineBreakMode:lineBreak lineHeight:self.lineHeight];\n  }\n}\n\n- (void)setLineBreakMode:(NSLineBreakMode)lineBreakMode {\n  [super setLineBreakMode:lineBreakMode];\n\n  if (nil != self.mutableAttributedString) {\n    CTTextAlignment alignment = [self.class alignmentFromUITextAlignment:self.textAlignment];\n    CTLineBreakMode lineBreak = [self.class lineBreakModeFromUILineBreakMode:lineBreakMode];\n    [self.mutableAttributedString setTextAlignment:alignment lineBreakMode:lineBreak lineHeight:self.lineHeight];\n  }\n}\n\n- (void)setTextColor:(UIColor *)textColor {\n  [super setTextColor:textColor];\n\n  [self.mutableAttributedString setTextColor:textColor];\n\n  [self attributedTextDidChange];\n}\n\n- (void)setTextColor:(UIColor *)textColor range:(NSRange)range {\n  [self.mutableAttributedString setTextColor:textColor range:range];\n\n  [self attributedTextDidChange];\n}\n\n- (void)setFont:(UIFont *)font {\n  [super setFont:font];\n\n  [self.mutableAttributedString setFont:font];\n\n  [self attributedTextDidChange];\n}\n\n- (void)setFont:(UIFont *)font range:(NSRange)range {\n  [self.mutableAttributedString setFont:font range:range];\n\n  [self attributedTextDidChange];\n}\n\n- (void)setUnderlineStyle:(CTUnderlineStyle)style {\n  if (style != _underlineStyle) {\n    _underlineStyle = style;\n    [self.mutableAttributedString setUnderlineStyle:style modifier:self.underlineStyleModifier];\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setUnderlineStyleModifier:(CTUnderlineStyleModifiers)modifier {\n  if (modifier != _underlineStyleModifier) {\n    _underlineStyleModifier = modifier;\n    [self.mutableAttributedString setUnderlineStyle:self.underlineStyle  modifier:modifier];\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setUnderlineStyle:(CTUnderlineStyle)style modifier:(CTUnderlineStyleModifiers)modifier range:(NSRange)range {\n  [self.mutableAttributedString setUnderlineStyle:style modifier:modifier range:range];\n\n  [self attributedTextDidChange];\n}\n\n- (void)setShadowBlur:(CGFloat)shadowBlur {\n  if (_shadowBlur != shadowBlur) {\n    _shadowBlur = shadowBlur;\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setStrokeWidth:(CGFloat)strokeWidth {\n  if (_strokeWidth != strokeWidth) {\n    _strokeWidth = strokeWidth;\n    [self.mutableAttributedString setStrokeWidth:strokeWidth];\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setStrokeWidth:(CGFloat)width range:(NSRange)range {\n  [self.mutableAttributedString setStrokeWidth:width range:range];\n\n  [self attributedTextDidChange];\n}\n\n- (void)setStrokeColor:(UIColor *)strokeColor {\n  if (_strokeColor != strokeColor) {\n    _strokeColor = strokeColor;\n    [self.mutableAttributedString setStrokeColor:_strokeColor];\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setStrokeColor:(UIColor*)color range:(NSRange)range {\n  [self.mutableAttributedString setStrokeColor:color range:range];\n\n  [self attributedTextDidChange];\n}\n\n- (void)setTextKern:(CGFloat)textKern {\n  if (_textKern != textKern) {\n    _textKern = textKern;\n    [self.mutableAttributedString setKern:_textKern];\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setTextKern:(CGFloat)kern range:(NSRange)range {\n  [self.mutableAttributedString setKern:kern range:range];\n\n  [self attributedTextDidChange];\n}\n\n- (void)setTailTruncationString:(NSString *)tailTruncationString {\n  if (![_tailTruncationString isEqualToString:tailTruncationString]) {\n    _tailTruncationString = [tailTruncationString copy];\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setLinkColor:(UIColor *)linkColor {\n  if (_linkColor != linkColor) {\n    _linkColor = linkColor;\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setStrikethroughColor:(UIColor *)strikethroughColor {\n  if (_strikethroughColor != strikethroughColor) {\n    _strikethroughColor = strikethroughColor;\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setLineHeight:(CGFloat)lineHeight {\n  _lineHeight = lineHeight;\n\n  if (nil != self.mutableAttributedString) {\n    CTTextAlignment alignment = [self.class alignmentFromUITextAlignment:self.textAlignment];\n    CTLineBreakMode lineBreak = [self.class lineBreakModeFromUILineBreakMode:self.lineBreakMode];\n    [self.mutableAttributedString setTextAlignment:alignment lineBreakMode:lineBreak lineHeight:self.lineHeight];\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setHighlightedLinkBackgroundColor:(UIColor *)highlightedLinkBackgroundColor {\n  if (_highlightedLinkBackgroundColor != highlightedLinkBackgroundColor) {\n    _highlightedLinkBackgroundColor = highlightedLinkBackgroundColor;\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setLinksHaveUnderlines:(BOOL)linksHaveUnderlines {\n  if (_linksHaveUnderlines != linksHaveUnderlines) {\n    _linksHaveUnderlines = linksHaveUnderlines;\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setAttributesForTailTruncationString:(NSDictionary *)attributesForTailTruncationString {\n  if (_attributesForTailTruncationString != attributesForTailTruncationString) {\n    _attributesForTailTruncationString = attributesForTailTruncationString;\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setAttributesForLinks:(NSDictionary *)attributesForLinks {\n  if (_attributesForLinks != attributesForLinks) {\n    _attributesForLinks = attributesForLinks;\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setAttributesForHighlightedLink:(NSDictionary *)attributesForHighlightedLink {\n  if (_attributesForHighlightedLink != attributesForHighlightedLink) {\n    _attributesForHighlightedLink = attributesForHighlightedLink;\n\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setExplicitLinkLocations:(NSMutableArray *)explicitLinkLocations {\n  if (_explicitLinkLocations != explicitLinkLocations) {\n    _explicitLinkLocations = explicitLinkLocations;\n    self.accessibleElements = nil;\n  }\n}\n\n- (void)setDetectedlinkLocations:(NSArray *)detectedlinkLocations{\n  if (_detectedlinkLocations != detectedlinkLocations) {\n    _detectedlinkLocations = detectedlinkLocations;\n    self.accessibleElements = nil;\n  }\n}\n\n- (void)setHighlighted:(BOOL)highlighted {\n  BOOL didChange = self.highlighted != highlighted;\n  [super setHighlighted:highlighted];\n\n  if (didChange) {\n    [self attributedTextDidChange];\n  }\n}\n\n- (void)setHighlightedTextColor:(UIColor *)highlightedTextColor {\n  BOOL didChange = self.highlightedTextColor != highlightedTextColor;\n  [super setHighlightedTextColor:highlightedTextColor];\n\n  if (didChange) {\n    [self attributedTextDidChange];\n  }\n}\n\n- (NSArray *)_matchesFromAttributedString:(NSString *)string {\n  NSError* error = nil;\n  NSDataDetector* linkDetector = [NSDataDetector dataDetectorWithTypes:(NSTextCheckingTypes)self.dataDetectorTypes\n                                                                 error:&error];\n  NSRange range = NSMakeRange(0, string.length);\n\n  return [linkDetector matchesInString:string options:0 range:range];\n}\n\n- (void)_deferLinkDetection {\n  self.linkDetectionRequestID++;\n  const NSInteger linkDetectionRequestID = self.linkDetectionRequestID;\n  NSString* string = [self.mutableAttributedString.string copy];\n  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n    NSArray* matches = [self _matchesFromAttributedString:string];\n\n    dispatch_async(dispatch_get_main_queue(), ^{\n      if (self.linkDetectionRequestID != linkDetectionRequestID) {\n        return;\n      }\n      self.detectedlinkLocations = matches;\n      self.linksHaveBeenDetected = YES;\n\n      [self attributedTextDidChange];\n    });\n  });\n}\n\n// Use an NSDataDetector to find any implicit links in the text. The results are cached until\n// the text changes.\n- (void)detectLinks {\n  if (nil == self.mutableAttributedString) {\n    return;\n  }\n\n  if (self.autoDetectLinks && !self.linksHaveBeenDetected) {\n    if (self.deferLinkDetection) {\n      [self _deferLinkDetection];\n\n    } else {\n      self.detectedlinkLocations = [self _matchesFromAttributedString:self.mutableAttributedString.string];\n      self.linksHaveBeenDetected = YES;\n    }\n  }\n}\n\n- (CGRect)getLineBounds:(CTLineRef)line point:(CGPoint) point {\n  CGFloat ascent = 0.0f;\n  CGFloat descent = 0.0f;\n  CGFloat leading = 0.0f;\n  CGFloat width = (CGFloat)CTLineGetTypographicBounds(line, &ascent, &descent, &leading);\n  CGFloat height = ascent + descent;\n\n  return CGRectMake(point.x, point.y - descent, width, height);\n}\n\n- (NSTextCheckingResult *)linkAtIndex:(CFIndex)i {\n  NSTextCheckingResult* foundResult = nil;\n\n  if (self.autoDetectLinks) {\n    [self detectLinks];\n\n    for (NSTextCheckingResult* result in self.detectedlinkLocations) {\n      if (NSLocationInRange(i, result.range)) {\n        foundResult = result;\n        break;\n      }\n    }\n  }\n\n  if (nil == foundResult) {\n    for (NSTextCheckingResult* result in self.explicitLinkLocations) {\n      if (NSLocationInRange(i, result.range)) {\n        foundResult = result;\n        break;\n      }\n    }\n  }\n\n  return foundResult;\n}\n\n- (void)_processLinksInAttributedString:(NSAttributedString *)attributedString {\n  // Pull any attributes matching the link attribute from the attributed string and store them as\n  // the current set of explicit links. This properly handles the value of the attribute being\n  // either an NSURL or an NSString.\n  __block NSMutableArray *links = [NSMutableArray array];\n  [attributedString enumerateAttribute:NIAttributedLabelLinkAttributeName\n                               inRange:NSMakeRange(0, attributedString.length)\n                               options:0\n                            usingBlock:^(NSTextCheckingResult *value, NSRange range, BOOL *stop) {\n                              if (value != nil) {\n                                [links addObject:value];\n                              }\n                            }];\n  self.explicitLinkLocations = links;\n}\n\n- (CGFloat)_verticalOffsetForBounds:(CGRect)bounds {\n  CGFloat verticalOffset = 0;\n  if (NIVerticalTextAlignmentTop != self.verticalTextAlignment) {\n    // When the text is attached to the top we can easily just start drawing and leave the\n    // remainder. This is the most performant case.\n    // With other alignment modes we must calculate the size of the text first.\n    CGSize textSize = [self sizeThatFits:CGSizeMake(bounds.size.width, CGFLOAT_MAX)];\n\n    if (NIVerticalTextAlignmentMiddle == self.verticalTextAlignment) {\n      verticalOffset = NICGFloatFloor((bounds.size.height - textSize.height) / 2.f);\n\n    } else if (NIVerticalTextAlignmentBottom == self.verticalTextAlignment) {\n      verticalOffset = bounds.size.height - textSize.height;\n    }\n  }\n  return verticalOffset;\n}\n\n- (CGAffineTransform)_transformForCoreText {\n  // CoreText context coordinates are the opposite to UIKit so we flip the bounds\n  return CGAffineTransformScale(CGAffineTransformMakeTranslation(0, self.bounds.size.height), 1.f, -1.f);\n}\n\n- (NSTextCheckingResult *)linkAtPoint:(CGPoint)point {\n  if (!CGRectContainsPoint(CGRectInset(self.bounds, 0, -kVMargin), point)) {\n    return nil;\n  }\n\n  CFArrayRef lines = CTFrameGetLines(self.textFrame);\n  if (!lines) return nil;\n  CFIndex count = CFArrayGetCount(lines);\n\n  CGPoint origins[count];\n  CTFrameGetLineOrigins(self.textFrame, CFRangeMake(0,0), origins);\n\n  CGAffineTransform transform = [self _transformForCoreText];\n  CGFloat verticalOffset = [self _verticalOffsetForBounds:self.bounds];\n\n  for (int i = 0; i < count; i++) {\n    CGPoint linePoint = origins[i];\n\n    CTLineRef line = CFArrayGetValueAtIndex(lines, i);\n    CGRect flippedRect = [self getLineBounds:line point:linePoint];\n    CGRect rect = CGRectApplyAffineTransform(flippedRect, transform);\n\n    rect = CGRectInset(rect, 0, -kVMargin);\n    rect = CGRectOffset(rect, 0, verticalOffset);\n\n    if (CGRectContainsPoint(rect, point)) {\n      CGPoint relativePoint = CGPointMake(point.x-CGRectGetMinX(rect),\n                                          point.y-CGRectGetMinY(rect));\n      CFIndex idx = CTLineGetStringIndexForPosition(line, relativePoint);\n\n      NSUInteger offset = 0;\n      for (NIAttributedLabelImage *labelImage in self.images) {\n        if (labelImage.index < idx) {\n          offset++;\n        }\n      }\n\n      NSTextCheckingResult* foundLink = [self linkAtIndex:idx - offset];\n      if (foundLink) {\n        return foundLink;\n      }\n    }\n  }\n  return nil;\n}\n\n- (CGRect)_rectForRange:(NSRange)range inLine:(CTLineRef)line lineOrigin:(CGPoint)lineOrigin {\n  CGRect rectForRange = CGRectZero;\n  CFArrayRef runs = CTLineGetGlyphRuns(line);\n  CFIndex runCount = CFArrayGetCount(runs);\n\n  // Iterate through each of the \"runs\" (i.e. a chunk of text) and find the runs that\n  // intersect with the range.\n  for (CFIndex k = 0; k < runCount; k++) {\n    CTRunRef run = CFArrayGetValueAtIndex(runs, k);\n\n    CFRange stringRunRange = CTRunGetStringRange(run);\n    NSRange lineRunRange = NSMakeRange(stringRunRange.location, stringRunRange.length);\n    NSRange intersectedRunRange = NSIntersectionRange(lineRunRange, range);\n\n    if (intersectedRunRange.length == 0) {\n      // This run doesn't intersect the range, so skip it.\n      continue;\n    }\n\n    CGFloat ascent = 0.0f;\n    CGFloat descent = 0.0f;\n    CGFloat leading = 0.0f;\n\n    // Use of 'leading' doesn't properly highlight Japanese-character link.\n    CGFloat width = (CGFloat)CTRunGetTypographicBounds(run,\n                                                       CFRangeMake(0, 0),\n                                                       &ascent,\n                                                       &descent,\n                                                       NULL); //&leading);\n    CGFloat height = ascent + descent;\n\n    CGFloat xOffset = CTLineGetOffsetForStringIndex(line, CTRunGetStringRange(run).location, nil);\n\n    CGRect linkRect = CGRectMake(lineOrigin.x + xOffset - leading, lineOrigin.y - descent, width + leading, height);\n\n    linkRect.origin.y = NICGFloatRound(linkRect.origin.y);\n    linkRect.origin.x = NICGFloatRound(linkRect.origin.x);\n    linkRect.size.width = NICGFloatRound(linkRect.size.width);\n    linkRect.size.height = NICGFloatRound(linkRect.size.height);\n\n    if (CGRectIsEmpty(rectForRange)) {\n      rectForRange = linkRect;\n\n    } else {\n      rectForRange = CGRectUnion(rectForRange, linkRect);\n    }\n  }\n\n  return rectForRange;\n}\n\n- (BOOL)isPoint:(CGPoint)point nearLink:(NSTextCheckingResult *)link {\n  CFArrayRef lines = CTFrameGetLines(self.textFrame);\n  if (nil == lines) {\n    return NO;\n  }\n  CFIndex count = CFArrayGetCount(lines);\n  CGPoint lineOrigins[count];\n  CTFrameGetLineOrigins(self.textFrame, CFRangeMake(0, 0), lineOrigins);\n\n  CGAffineTransform transform = [self _transformForCoreText];\n  CGFloat verticalOffset = [self _verticalOffsetForBounds:self.bounds];\n\n  NSRange linkRange = link.range;\n\n  BOOL isNearLink = NO;\n  for (int i = 0; i < count; i++) {\n    CTLineRef line = CFArrayGetValueAtIndex(lines, i);\n\n    CGRect linkRect = [self _rectForRange:linkRange inLine:line lineOrigin:lineOrigins[i]];\n\n    if (!CGRectIsEmpty(linkRect)) {\n      linkRect = CGRectApplyAffineTransform(linkRect, transform);\n      linkRect = CGRectOffset(linkRect, 0, verticalOffset);\n      linkRect = CGRectInset(linkRect, -kTouchGutter, -kTouchGutter);\n      if (CGRectContainsPoint(linkRect, point)) {\n        isNearLink = YES;\n        break;\n      }\n    }\n  }\n\n  return isNearLink;\n}\n\n// For a range of text, this method returns an NSArray of CGRectValue, each representing a part of\n// text in the same line.\n// The length of the array is the same as the number of lines this range covers.\n- (NSArray *)_rectsForRange:(NSRange)range {\n  CFArrayRef lines = CTFrameGetLines(self.textFrame);\n  if (nil == lines) {\n    return nil;\n  }\n  CFIndex count = CFArrayGetCount(lines);\n  CGPoint lineOrigins[count];\n  CTFrameGetLineOrigins(self.textFrame, CFRangeMake(0, 0), lineOrigins);\n\n  CGAffineTransform transform = [self _transformForCoreText];\n  CGFloat verticalOffset = [self _verticalOffsetForBounds:self.bounds];\n\n  NSMutableArray* rects = [NSMutableArray array];\n  for (int i = 0; i < count; i++) {\n    CTLineRef line = CFArrayGetValueAtIndex(lines, i);\n\n    CGRect rect = [self _rectForRange:range inLine:line lineOrigin:lineOrigins[i]];\n\n    if (!CGRectIsEmpty(rect)) {\n      rect = CGRectApplyAffineTransform(rect, transform);\n      rect = CGRectOffset(rect, 0, verticalOffset);\n      [rects addObject:[NSValue valueWithCGRect:rect]];\n    }\n  }\n  return [rects copy];\n}\n\n- (NSArray *)_multilineRectsForRange:(NSRange)range {\n  CFArrayRef lines = CTFrameGetLines(self.textFrame);\n  if (nil == lines) {\n    return nil;\n  }\n  CFIndex count = CFArrayGetCount(lines);\n  CGPoint lineOrigins[count];\n  CTFrameGetLineOrigins(self.textFrame, CFRangeMake(0, 0), lineOrigins);\n\n  NSMutableArray *rects = [[NSMutableArray alloc] initWithCapacity:count];\n\n  NSRange runningRange = NSMakeRange(0,0);\n  CGRect runningRect = CGRectZero;\n\n  for (CFIndex lineIndex = 0; lineIndex < count; lineIndex++) {\n    CTLineRef line = CFArrayGetValueAtIndex(lines, lineIndex);\n    CGAffineTransform transform = [self _transformForCoreText];\n    CGFloat verticalOffset = [self _verticalOffsetForBounds:self.bounds];\n\n    CFArrayRef runs = CTLineGetGlyphRuns(line);\n    CFIndex runCount = CFArrayGetCount(runs);\n    for (CFIndex runIndex = 0; runIndex < runCount; runIndex++) {\n      CTRunRef run = CFArrayGetValueAtIndex(runs, runIndex);\n\n      CFRange stringRunRange = CTRunGetStringRange(run);\n      NSRange lineRunRange = NSMakeRange(stringRunRange.location, stringRunRange.length);\n      NSRange intersectedRunRange = NSIntersectionRange(lineRunRange, range);\n\n      if (intersectedRunRange.length == 0) {\n        // This run is not attributed since this run does not intersect the range, add the rect for\n        // runningRange to rects and clear runningRange.\n        if (runningRange.length > 0) {\n          [rects addObject:[NSValue valueWithCGRect:runningRect]];\n          runningRange = NSMakeRange(0,0);\n          runningRect = CGRectZero;\n        }\n        continue;\n      }\n      // Run must be attributed: update the attributed runningRange.\n      CGRect intersectedRect = [self _rectForRange:intersectedRunRange\n                                            inLine:line\n                                        lineOrigin:lineOrigins[lineIndex]];\n      intersectedRect = CGRectApplyAffineTransform(intersectedRect, transform);\n      intersectedRect = CGRectOffset(intersectedRect, 0, verticalOffset);\n      if (runningRange.length == 0) {\n        runningRange = intersectedRunRange;\n        runningRect = intersectedRect;\n      } else {\n        runningRange = NSUnionRange(runningRange, intersectedRunRange);\n        runningRect = CGRectUnion(runningRect, intersectedRect);\n      }\n    }\n  }\n\n  // Add any cached runningRange to the rects.\n  if (runningRange.length > 0) {\n    [rects addObject:[NSValue valueWithCGRect:runningRect]];\n  }\n  return [rects copy];\n}\n\n// The bounds of a text fragment always look like a rectangle without a top-left corner (if the text\n// starts in the middle of the line) and without a bottom-right corner (if the text ends in the\n// middle of the line).\n//\n// Take the following as an example:\n// ***@******@\n// *  * ---- *\n// @**! ---- *\n// * ------- *\n// * -- !****@\n// * -- *    *\n// @****@*****\n//\n// Suppose the whole link (marked as '-' in the graph) goes over two lines. The boundary of the link\n// is the whole rectangle. And the two points marked as '!' are the top-left and bottom-right cut\n// points correspondingly.\n//\n// This method will calculate the 'real' boundary (aka. the accessibility path, points marked as '@'\n// and '!') in the clockwise order and return an array in which the first element is the activation\n// point and the rest is this accessibility path.\n- (NSArray *)pointsWithActivationPoint:(CGPoint)activationPoint\n                                  rect:(CGRect)rect\n                       topLeftCutPoint:(CGPoint)topLeftCutPoint\n                   bottomRightCutPoint:(CGPoint)bottomRightCutPoint {\n  CGPoint topLeft = rect.origin;\n  CGPoint topRight = CGPointMake(CGRectGetMaxX(rect), topLeft.y);\n  CGPoint bottomLeft = CGPointMake(topLeft.x, CGRectGetMaxY(rect));\n  CGPoint bottomRight = CGPointMake(topRight.x, bottomLeft.y);\n\n  NSMutableArray *array =\n      [NSMutableArray arrayWithObject:[NSValue valueWithCGPoint:activationPoint]];\n  if (CGPointEqualToPoint(topLeftCutPoint, topLeft)) {\n    [array addObject:[NSValue valueWithCGPoint:topLeft]];\n  } else {\n    [array addObject:[NSValue valueWithCGPoint:CGPointMake(topLeft.x, topLeftCutPoint.y)]];\n    [array addObject:[NSValue valueWithCGPoint:topLeftCutPoint]];\n    [array addObject:[NSValue valueWithCGPoint:CGPointMake(topLeftCutPoint.x, topLeft.y)]];\n  }\n  [array addObject:[NSValue valueWithCGPoint:topRight]];\n  if (CGPointEqualToPoint(bottomRightCutPoint, bottomRight)) {\n    [array addObject:[NSValue valueWithCGPoint:bottomRight]];\n  } else {\n    [array addObject:[NSValue valueWithCGPoint:CGPointMake(bottomRight.x, bottomRightCutPoint.y)]];\n    [array addObject:[NSValue valueWithCGPoint:bottomRightCutPoint]];\n    [array addObject:[NSValue valueWithCGPoint:CGPointMake(bottomRightCutPoint.x, bottomRight.y)]];\n  }\n  [array addObject:[NSValue valueWithCGPoint:bottomLeft]];\n\n  return array;\n}\n\n// Returns the smallest rectangle that contains all the rectangles in the array.\n- (CGRect)boundsForRects:(NSArray *)rects {\n  CGFloat minX = CGFLOAT_MAX, minY = CGFLOAT_MAX, maxX = -1, maxY = -1;\n  for (NSValue *value in rects) {\n    CGRect rect = [value CGRectValue];\n    minX = MIN(rect.origin.x, minX);\n    minY = MIN(rect.origin.y, minY);\n    maxX = MAX(rect.origin.x + rect.size.width, maxX);\n    maxY = MAX(rect.origin.y + rect.size.height, maxY);\n  }\n  return CGRectMake(minX, minY, maxX - minX, maxY - minY);\n}\n\n// Returns an accessibility element representing the text within this range, or nil if the element\n// cannot be initialised.\n- (NIViewAccessibilityElement *)accessibilityElementForRange:(NSRange)range {\n  if (range.length == 0) {\n    return nil;\n  }\n\n  NSArray *rects = [self _rectsForRange:range];\n  if (!NIIsArrayWithObjects(rects)) {\n    return nil;\n  }\n\n  // Calculate multiline link bounds using boundsForRects.\n  CGRect bounds = [self boundsForRects:rects];\n  CGRect firstRect = [[rects firstObject] CGRectValue];\n  CGRect lastRect = [[rects lastObject] CGRectValue];\n  // If we are not merging multiline links then the activation point can be any point in the\n  // element, let's use the center of the text's 'frame'. If we are merging multiline links then the\n  // activation point can be either the bottom left or top right point, let's use the bottom left\n  // point for consistency with NIViewAccessibilityElement.\n  CGPoint activationPoint = _shouldMergeMultilineLinks\n                                ? CGPointMake(CGRectGetMinX(lastRect), CGRectGetMaxY(lastRect))\n                                : CGPointMake(CGRectGetMidX(firstRect), CGRectGetMidY(firstRect));\n  NSArray *pointsArray =\n      [self pointsWithActivationPoint:activationPoint\n                                 rect:bounds\n                      topLeftCutPoint:CGPointMake(firstRect.origin.x, CGRectGetMaxY(firstRect))\n                  bottomRightCutPoint:CGPointMake(CGRectGetMaxX(lastRect), lastRect.origin.y)];\n  NIViewAccessibilityElement *element =\n      [[NIViewAccessibilityElement alloc] initWithAccessibilityContainer:self\n                                                        frameInContainer:bounds\n                                                       pointsInContainer:pointsArray];\n  NSString *accessibilityLabel = [self.mutableAttributedString.string substringWithRange:range];\n  [self updateAccessibilityLabelOnElement:element withAccessibilityLabel:accessibilityLabel];\n\n  // Set the frame to fallback on if |element|'s accessibility container is changed externally.\n  CGRect rectValueInWindowCoordinates = [self convertRect:bounds toView:nil];\n  CGRect rectValueInScreenCoordinates =\n      [self.window convertRect:rectValueInWindowCoordinates toWindow:nil];\n  element.accessibilityFrame = rectValueInScreenCoordinates;\n  // Set the activation point to fallback on if |element|'s accessibility container is changed\n  // externally.\n  CGPoint pointValueInWindowCoordinates = [self convertPoint:activationPoint toView:nil];\n  CGPoint pointValueInScreenCoordinates =\n      [self.window convertPoint:pointValueInWindowCoordinates toWindow:nil];\n  element.accessibilityActivationPoint = pointValueInScreenCoordinates;\n\n  return element;\n}\n\n- (void)setTouchedLink:(NSTextCheckingResult *)touchedLink {\n  if (_touchedLink != touchedLink) {\n    _touchedLink = touchedLink;\n\n    if (self.attributesForHighlightedLink.count > 0) {\n      [self attributedTextDidChange];\n    }\n  }\n}\n\n- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {\n  UITouch* touch = [touches anyObject];\n  CGPoint point = [touch locationInView:self];\n\n  self.touchedLink = [self linkAtPoint:point];\n  self.touchPoint = point;\n  self.originalLink = self.touchedLink;\n\n  if (self.originalLink) {\n    [self.longPressTimer invalidate];\n    if (nil != self.touchedLink) {\n      self.longPressTimer = [NSTimer scheduledTimerWithTimeInterval:kLongPressTimeInterval target:self selector:@selector(_longPressTimerDidFire:) userInfo:nil repeats:NO];\n    }\n\n  } else {\n    [super touchesBegan:touches withEvent:event];\n  }\n\n  [self setNeedsDisplay];\n}\n\n- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {\n  UITouch* touch = [touches anyObject];\n  CGPoint point = [touch locationInView:self];\n\n  if (self.originalLink) {\n    // If the user moves their finger away from the original link, deselect it.\n    // If the user moves their finger back to the original link, reselect it.\n    // Don't allow other links to be selected other than the original link.\n\n    if (nil != self.originalLink) {\n      NSTextCheckingResult* oldTouchedLink = self.touchedLink;\n\n      if ([self isPoint:point nearLink:self.originalLink]) {\n        self.touchedLink = self.originalLink;\n\n      } else {\n        self.touchedLink = nil;\n      }\n\n      if (oldTouchedLink != self.touchedLink) {\n        [self.longPressTimer invalidate];\n        self.longPressTimer = nil;\n        [self setNeedsDisplay];\n      }\n    }\n\n    // If the user moves their finger within the link beyond a certain gutter amount, reset the\n    // hold timer. The user must hold their finger still for the long press interval in order for\n    // the long press action to fire.\n    if (NICGFloatAbs(self.touchPoint.x - point.x) >= kLongPressGutter\n        || NICGFloatAbs(self.touchPoint.y - point.y) >= kLongPressGutter) {\n      [self.longPressTimer invalidate];\n      self.longPressTimer = nil;\n      if (nil != self.touchedLink) {\n        self.longPressTimer = [NSTimer scheduledTimerWithTimeInterval:kLongPressTimeInterval target:self selector:@selector(_longPressTimerDidFire:) userInfo:nil repeats:NO];\n        self.touchPoint = point;\n      }\n    }\n  } else {\n    [super touchesMoved:touches withEvent:event];\n  }\n}\n\n- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {\n  if (self.originalLink) {\n    [self.longPressTimer invalidate];\n    self.longPressTimer = nil;\n\n    UITouch* touch = [touches anyObject];\n    CGPoint point = [touch locationInView:self];\n\n    if (nil != self.originalLink) {\n      if ([self isPoint:point nearLink:self.originalLink]\n          && [self.delegate respondsToSelector:@selector(attributedLabel:didSelectTextCheckingResult:atPoint:)]) {\n        [self.delegate attributedLabel:self didSelectTextCheckingResult:self.originalLink atPoint:point];\n      }\n    }\n\n    self.touchedLink = nil;\n    self.originalLink = nil;\n    [self setNeedsDisplay];\n\n  } else {\n    [super touchesEnded:touches withEvent:event];\n  }\n}\n\n- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {\n  [super touchesCancelled:touches withEvent:event];\n\n  [self.longPressTimer invalidate];\n  self.longPressTimer = nil;\n\n  self.touchedLink = nil;\n  self.originalLink = nil;\n\n  [self setNeedsDisplay];\n}\n\n_NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_PUSH()\n- (UIActionSheet *)actionSheetForResult:(NSTextCheckingResult *)result {\n  UIActionSheet* actionSheet =\n  [[UIActionSheet alloc] initWithTitle:nil\n                              delegate:self\n                     cancelButtonTitle:nil\n                destructiveButtonTitle:nil\n                     otherButtonTitles:nil];\n\n  NSString* title = nil;\n  if (NSTextCheckingTypeLink == result.resultType) {\n    if ([result.URL.scheme isEqualToString:@\"mailto\"]) {\n      title = result.URL.resourceSpecifier;\n      [actionSheet addButtonWithTitle:NSLocalizedString(@\"Open in Mail\", @\"\")];\n      [actionSheet addButtonWithTitle:NSLocalizedString(@\"Copy Email Address\", @\"\")];\n\n    } else {\n      title = result.URL.absoluteString;\n      [actionSheet addButtonWithTitle:NSLocalizedString(@\"Open in Safari\", @\"\")];\n      [actionSheet addButtonWithTitle:NSLocalizedString(@\"Copy URL\", @\"\")];\n    }\n\n  } else if (NSTextCheckingTypePhoneNumber == result.resultType) {\n    title = result.phoneNumber;\n    [actionSheet addButtonWithTitle:NSLocalizedString(@\"Call\", @\"\")];\n    [actionSheet addButtonWithTitle:NSLocalizedString(@\"Copy Phone Number\", @\"\")];\n\n  } else if (NSTextCheckingTypeAddress == result.resultType) {\n    title = [self.mutableAttributedString.string substringWithRange:self.actionSheetLink.range];\n    [actionSheet addButtonWithTitle:NSLocalizedString(@\"Open in Maps\", @\"\")];\n    [actionSheet addButtonWithTitle:NSLocalizedString(@\"Copy Address\", @\"\")];\n\n  } else {\n    // This type has not been implemented yet.\n    NIDASSERT(NO);\n    [actionSheet addButtonWithTitle:NSLocalizedString(@\"Copy\", @\"\")];\n  }\n  actionSheet.title = title;\n\n  if (!NIIsPad()) {\n    [actionSheet setCancelButtonIndex:[actionSheet addButtonWithTitle:NSLocalizedString(@\"Cancel\", @\"\")]];\n  }\n\n  return actionSheet;\n}\n_NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_POP()\n\n_NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_PUSH()\n- (void)_longPressTimerDidFire:(NSTimer *)timer {\n  self.longPressTimer = nil;\n\n  if (nil != self.touchedLink) {\n    self.actionSheetLink = self.touchedLink;\n\n    UIActionSheet *actionSheet;\n    id<NIAttributedLabelDelegate> delegate = self.delegate;\n    if ([delegate respondsToSelector:@selector(attributedLabel:didLongPressTextCheckingResult:atPoint:)]) {\n      // Adoption of the new long press delegate callback is treated as opting out of the action sheet altogether.\n      [delegate attributedLabel:self didLongPressTextCheckingResult:self.touchedLink atPoint:self.touchPoint];\n    } else {\n      // Create the action sheet to be shown.\n      actionSheet = [self actionSheetForResult:self.actionSheetLink];\n\n      if ([delegate respondsToSelector:@selector(attributedLabel:shouldPresentActionSheet:withTextCheckingResult:atPoint:)]) {\n        // Give the delegate the opportunity to not show the action sheet.\n        if (![delegate attributedLabel:self shouldPresentActionSheet:actionSheet withTextCheckingResult:self.touchedLink atPoint:self.touchPoint]) {\n          actionSheet = nil;\n        }\n      }\n    }\n\n    if (actionSheet) {\n      if (NIIsPad()) {\n        [actionSheet showFromRect:CGRectMake(self.touchPoint.x - 22, self.touchPoint.y - 22, 44, 44) inView:self animated:YES];\n      } else {\n        [actionSheet showInView:self];\n      }\n\n    } else {\n      self.actionSheetLink = nil;\n    }\n  }\n}\n_NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_POP()\n\n- (void)_applyLinkStyleWithResults:(NSArray *)results toAttributedString:(NSMutableAttributedString *)attributedString {\n  for (NSTextCheckingResult* result in results) {\n    if (self.linkColor) {\n      [attributedString setTextColor:self.linkColor range:result.range];\n    }\n\n    // We add a no-op attribute in order to force a run to exist for each link. Otherwise the\n    // runCount will be one in this line, causing the entire line to be highlighted rather than\n    // just the link when when no special attributes are set.\n    [attributedString removeAttribute:NIAttributedLabelLinkAttributeName range:result.range];\n    [attributedString addAttribute:NIAttributedLabelLinkAttributeName\n                             value:result\n                             range:result.range];\n\n    if (self.linksHaveUnderlines) {\n      [attributedString setUnderlineStyle:kCTUnderlineStyleSingle\n                                 modifier:kCTUnderlinePatternSolid\n                                    range:result.range];\n    }\n\n    if (self.attributesForLinks.count > 0) {\n      [attributedString addAttributes:self.attributesForLinks range:result.range];\n    }\n    if (self.attributesForHighlightedLink.count > 0 && NSEqualRanges(result.range, self.touchedLink.range)) {\n      [attributedString addAttributes:self.attributesForHighlightedLink range:result.range];\n    }\n  }\n}\n\n// We apply the additional styles immediately before we render the attributed string. This\n// composites the styles with the existing styles without losing any information. This\n// makes it possible to turn off links or remove them altogether without losing the existing\n// style information.\n- (NSMutableAttributedString *)mutableAttributedStringWithAdditions {\n  NSMutableAttributedString* attributedString = [self.mutableAttributedString mutableCopy];\n\n  // Set highlighted text color for the entire string first to avoid undesired style override e.g., link color.\n  if (self.isHighlighted && self.highlightedTextColor) {\n    [attributedString setTextColor:self.highlightedTextColor];\n  }\n\n  if (self.autoDetectLinks) {\n    [self _applyLinkStyleWithResults:self.detectedlinkLocations\n                  toAttributedString:attributedString];\n  }\n\n  [self _applyLinkStyleWithResults:self.explicitLinkLocations\n                toAttributedString:attributedString];\n\n  if (self.images.count > 0) {\n    // Sort the label images in reverse order by index so that when we add them the string's indices\n    // remain relatively accurate to the original string. This is necessary because we're inserting\n    // spaces into the string.\n    [self.images sortUsingComparator:^NSComparisonResult(NIAttributedLabelImage* obj1, NIAttributedLabelImage*  obj2) {\n      if (obj1.index < obj2.index) {\n        return NSOrderedDescending;\n      } else if (obj1.index > obj2.index) {\n        return NSOrderedAscending;\n      } else {\n        return NSOrderedSame;\n      }\n    }];\n\n    for (NIAttributedLabelImage *labelImage in self.images) {\n      CTRunDelegateCallbacks callbacks;\n      memset(&callbacks, 0, sizeof(CTRunDelegateCallbacks));\n      callbacks.version = kCTRunDelegateVersion1;\n      callbacks.getAscent = NIImageDelegateGetAscentCallback;\n      callbacks.getDescent = NIImageDelegateGetDescentCallback;\n      callbacks.getWidth = NIImageDelegateGetWidthCallback;\n\n      NSDictionary *attributes = nil;\n      if (attributedString.length) {\n        NSInteger index = MAX((NSInteger)0, MIN((NSInteger)(attributedString.length - 1), labelImage.index));\n        attributes = [attributedString attributesAtIndex:index effectiveRange:NULL];\n      }\n\n      UIFont *font = attributes[NSFontAttributeName];\n      if (font) {\n        labelImage.fontAscent = font.ascender;\n        labelImage.fontDescent = -font.descender;\n      }\n\n      CTRunDelegateRef delegate = CTRunDelegateCreate(&callbacks, (__bridge void *)labelImage);\n\n      // If this asserts then we're not going to be able to attach the image to the label.\n      NIDASSERT(NULL != delegate);\n      if (NULL != delegate) {\n        // Character to use as recommended by kCTRunDelegateAttributeName documentation.\n        unichar objectReplacementChar = 0xFFFC;\n        NSString *objectReplacementString = [NSString stringWithCharacters:&objectReplacementChar length:1];\n        NSMutableAttributedString* space = [[NSMutableAttributedString alloc] initWithString:objectReplacementString];\n        if (font) {\n          [space addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, space.length)];\n        }\n\n        CFRange range = CFRangeMake(0, 1);\n        CFMutableAttributedStringRef spaceString = (__bridge_retained CFMutableAttributedStringRef)space;\n        CFAttributedStringSetAttribute(spaceString, range, kCTRunDelegateAttributeName, delegate);\n        // Explicitly set the writing direction of this string to LTR, because in 'drawImages' we draw\n        // for LTR by drawing at offset to offset + width vs to offset - width as you would for RTL.\n        CFAttributedStringSetAttribute(spaceString,\n                                       range,\n                                       kCTWritingDirectionAttributeName,\n                                       (__bridge CFArrayRef)@[@(kCTWritingDirectionLeftToRight)]);\n        CFRelease(delegate);\n        CFRelease(spaceString);\n\n        [attributedString insertAttributedString:space atIndex:labelImage.index];\n      }\n    }\n  }\n\n  return attributedString;\n}\n\n- (NSInteger)numberOfDisplayedLines {\n  CFArrayRef lines = CTFrameGetLines(self.textFrame);\n  return self.numberOfLines > 0 ? MIN(self.numberOfLines, CFArrayGetCount(lines)) : CFArrayGetCount(lines);\n}\n\n- (void)drawImages {\n  if (0 == self.images.count) {\n    return;\n  }\n\n  CGContextRef ctx = UIGraphicsGetCurrentContext();\n\n  CFArrayRef lines = CTFrameGetLines(self.textFrame);\n  CFIndex lineCount = CFArrayGetCount(lines);\n  CGPoint lineOrigins[lineCount];\n  CTFrameGetLineOrigins(self.textFrame, CFRangeMake(0, 0), lineOrigins);\n  NSInteger numberOfLines = [self numberOfDisplayedLines];\n\n  for (CFIndex i = 0; i < numberOfLines; i++) {\n    CTLineRef line = CFArrayGetValueAtIndex(lines, i);\n    CFArrayRef runs = CTLineGetGlyphRuns(line);\n    CFIndex runCount = CFArrayGetCount(runs);\n    CGPoint lineOrigin = lineOrigins[i];\n    CGFloat lineAscent;\n    CGFloat lineDescent;\n    CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, NULL);\n    CGFloat lineHeight = lineAscent + lineDescent;\n    CGFloat lineBottomY = lineOrigin.y - lineDescent;\n\n    // Iterate through each of the \"runs\" (i.e. a chunk of text) and find the runs that\n    // intersect with the range.\n    for (CFIndex k = 0; k < runCount; k++) {\n      CTRunRef run = CFArrayGetValueAtIndex(runs, k);\n      NSDictionary *runAttributes = (__bridge NSDictionary *)CTRunGetAttributes(run);\n      CTRunDelegateRef delegate = (__bridge CTRunDelegateRef)[runAttributes valueForKey:(__bridge id)kCTRunDelegateAttributeName];\n      if (nil == delegate) {\n        continue;\n      }\n      NIAttributedLabelImage* labelImage = (__bridge NIAttributedLabelImage *)CTRunDelegateGetRefCon(delegate);\n\n      CGFloat ascent = 0.0f;\n      CGFloat descent = 0.0f;\n      CGFloat width = (CGFloat)CTRunGetTypographicBounds(run,\n                                                         CFRangeMake(0, 0),\n                                                         &ascent,\n                                                         &descent,\n                                                         NULL);\n\n      CGFloat imageBoxHeight = labelImage.boxSize.height;\n\n      CGFloat xOffset = CTLineGetOffsetForStringIndex(line, CTRunGetStringRange(run).location, nil);\n\n      CGFloat imageBoxOriginY = 0.0f;\n      switch (labelImage.verticalTextAlignment) {\n        case NIVerticalTextAlignmentTop:\n          imageBoxOriginY = lineBottomY + (lineHeight - imageBoxHeight);\n          break;\n        case NIVerticalTextAlignmentMiddle:\n          imageBoxOriginY = lineBottomY + (lineHeight - imageBoxHeight) / 2.f;\n          break;\n        case NIVerticalTextAlignmentBottom:\n          imageBoxOriginY = lineBottomY;\n          break;\n      }\n\n      CGRect rect = CGRectMake(lineOrigin.x + xOffset, imageBoxOriginY, width, imageBoxHeight);\n      UIEdgeInsets flippedMargins = labelImage.margins;\n      CGFloat top = flippedMargins.top;\n      flippedMargins.top = flippedMargins.bottom;\n      flippedMargins.bottom = top;\n\n      CGRect imageRect = UIEdgeInsetsInsetRect(rect, flippedMargins);\n      imageRect = CGRectOffset(imageRect, 0, -[self _verticalOffsetForBounds:self.bounds]);\n      CGContextDrawImage(ctx, imageRect, labelImage.image.CGImage);\n    }\n  }\n}\n\n- (void)drawHighlightWithRect:(CGRect)rect {\n  if ((nil == self.touchedLink && nil == self.actionSheetLink) || nil == self.highlightedLinkBackgroundColor) {\n    return;\n  }\n  [self.highlightedLinkBackgroundColor setFill];\n\n  NSRange linkRange = nil != self.touchedLink ? self.touchedLink.range : self.actionSheetLink.range;\n\n  CFArrayRef lines = CTFrameGetLines(self.textFrame);\n  CFIndex count = CFArrayGetCount(lines);\n  CGPoint lineOrigins[count];\n  CTFrameGetLineOrigins(self.textFrame, CFRangeMake(0, 0), lineOrigins);\n  NSInteger numberOfLines = [self numberOfDisplayedLines];\n\n  CGContextRef ctx = UIGraphicsGetCurrentContext();\n\n  for (CFIndex i = 0; i < numberOfLines; i++) {\n    CTLineRef line = CFArrayGetValueAtIndex(lines, i);\n\n    CFRange stringRange = CTLineGetStringRange(line);\n    NSRange lineRange = NSMakeRange(stringRange.location, stringRange.length);\n    NSRange intersectedRange = NSIntersectionRange(lineRange, linkRange);\n    if (intersectedRange.length == 0) {\n      continue;\n    }\n\n    CGRect highlightRect = [self _rectForRange:linkRange inLine:line lineOrigin:lineOrigins[i]];\n    highlightRect = CGRectOffset(highlightRect, 0, -rect.origin.y);\n\n    if (!CGRectIsEmpty(highlightRect)) {\n      CGFloat pi = (CGFloat)M_PI;\n\n      CGFloat radius = 1.0f;\n      CGContextMoveToPoint(ctx, highlightRect.origin.x, highlightRect.origin.y + radius);\n      CGContextAddLineToPoint(ctx, highlightRect.origin.x, highlightRect.origin.y + highlightRect.size.height - radius);\n      CGContextAddArc(ctx, highlightRect.origin.x + radius, highlightRect.origin.y + highlightRect.size.height - radius,\n                      radius, pi, pi / 2.0f, 1.0f);\n      CGContextAddLineToPoint(ctx, highlightRect.origin.x + highlightRect.size.width - radius,\n                              highlightRect.origin.y + highlightRect.size.height);\n      CGContextAddArc(ctx, highlightRect.origin.x + highlightRect.size.width - radius,\n                      highlightRect.origin.y + highlightRect.size.height - radius, radius, pi / 2, 0.0f, 1.0f);\n      CGContextAddLineToPoint(ctx, highlightRect.origin.x + highlightRect.size.width, highlightRect.origin.y + radius);\n      CGContextAddArc(ctx, highlightRect.origin.x + highlightRect.size.width - radius, highlightRect.origin.y + radius,\n                      radius, 0.0f, -pi / 2.0f, 1.0f);\n      CGContextAddLineToPoint(ctx, highlightRect.origin.x + radius, highlightRect.origin.y);\n      CGContextAddArc(ctx, highlightRect.origin.x + radius, highlightRect.origin.y + radius, radius,\n                      -pi / 2, pi, 1);\n      CGContextFillPath(ctx);\n    }\n  }\n}\n\n- (void)drawAttributedString:(NSAttributedString *)attributedString rect:(CGRect)rect {\n  CGContextRef ctx = UIGraphicsGetCurrentContext();\n\n  // This logic adapted from @mattt's TTTAttributedLabel\n  // https://github.com/mattt/TTTAttributedLabel\n\n  CFArrayRef lines = CTFrameGetLines(self.textFrame);\n  NSInteger numberOfLines = [self numberOfDisplayedLines];\n  if (!numberOfLines) {\n    return;\n  }\n\n  BOOL truncatesLastLine = (self.lineBreakMode == NSLineBreakByTruncatingTail);\n  CGPoint lineOrigins[numberOfLines];\n  CTFrameGetLineOrigins(self.textFrame, CFRangeMake(0, numberOfLines), lineOrigins);\n\n  for (CFIndex lineIndex = 0; lineIndex < numberOfLines; lineIndex++) {\n    CGPoint lineOrigin = lineOrigins[lineIndex];\n    lineOrigin.y -= rect.origin.y; // adjust for verticalTextAlignment\n    CGContextSetTextPosition(ctx, lineOrigin.x, lineOrigin.y);\n    CTLineRef line = CFArrayGetValueAtIndex(lines, lineIndex);\n\n    BOOL shouldDrawLine = YES;\n\n    if (truncatesLastLine && lineIndex == numberOfLines - 1) {\n      // Does the last line need truncation?\n      CFRange lastLineRange = CTLineGetStringRange(line);\n      if (lastLineRange.location + lastLineRange.length < (CFIndex)attributedString.length) {\n        CTLineTruncationType truncationType = kCTLineTruncationEnd;\n        NSUInteger truncationAttributePosition = lastLineRange.location + lastLineRange.length - 1;\n\n        NSAttributedString* tokenAttributedString;\n        {\n          NSMutableDictionary *mutableTokenAttributes = [NSMutableDictionary new];\n          NSDictionary *tokenAttributes = [attributedString attributesAtIndex:truncationAttributePosition\n                                                               effectiveRange:NULL];\n          [mutableTokenAttributes addEntriesFromDictionary:tokenAttributes];\n          [mutableTokenAttributes addEntriesFromDictionary:_attributesForTailTruncationString];\n          NSString* tokenString = ((nil == self.tailTruncationString)\n                                   ? kEllipsesCharacter\n                                   : self.tailTruncationString);\n          tokenAttributedString =\n              [[NSAttributedString alloc] initWithString:tokenString\n                                              attributes:mutableTokenAttributes];\n        }\n\n        CTLineRef truncationToken = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)tokenAttributedString);\n\n        NSMutableAttributedString *truncationString = [[attributedString attributedSubstringFromRange:NSMakeRange(lastLineRange.location, lastLineRange.length)] mutableCopy];\n        if (lastLineRange.length > 0) {\n          // Remove any whitespace at the end of the line.\n          unichar lastCharacter = [[truncationString string] characterAtIndex:lastLineRange.length - 1];\n          if ([[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:lastCharacter]) {\n            [truncationString deleteCharactersInRange:NSMakeRange(lastLineRange.length - 1, 1)];\n          }\n        }\n        [truncationString appendAttributedString:tokenAttributedString];\n\n        CTLineRef truncationLine = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)truncationString);\n        CTLineRef truncatedLine = CTLineCreateTruncatedLine(truncationLine, rect.size.width, truncationType, truncationToken);\n        if (!truncatedLine) {\n          // If the line is not as wide as the truncationToken, truncatedLine is NULL\n          truncatedLine = CFRetain(truncationToken);\n        }\n        CFRelease(truncationLine);\n        CFRelease(truncationToken);\n\n        [self drawLine:truncatedLine context:ctx];\n        CFRelease(truncatedLine);\n\n        shouldDrawLine = NO;\n      }\n    }\n\n    if (shouldDrawLine) {\n      [self drawLine:line context:ctx];\n    }\n  }\n}\n\n- (void)drawLine:(CTLineRef)line context:(CGContextRef)ctx {\n  // Process additional NSAttributes that are not supported by CT library such as strikethrough.\n  CFArrayRef runs = CTLineGetGlyphRuns(line);\n  for (NSInteger index = 0; index < CFArrayGetCount(runs); index++) {\n    CTRunRef run = CFArrayGetValueAtIndex(runs, index);\n    CTRunDraw(run, ctx, CFRangeMake(0, 0));\n    CFDictionaryRef attributes = CTRunGetAttributes(run);\n    if (attributes) {\n      if (CFDictionaryContainsKey(attributes, kStrikethroughAttributeKey)) {\n        [self drawStrikethroughOverGlyphRun:run attributes:attributes ctx:ctx];\n      }\n    }\n  }\n}\n\n/**\n * Draws the strikethrough over the already drawn CTRunRef text. The strikethrough height is half\n * of the x-height of the current font. This means that the line is drawn in the middle of the lower\n * case 'x' char.\n */\n- (void)drawStrikethroughOverGlyphRun:(CTRunRef)run\n                           attributes:(CFDictionaryRef)attributes\n                                  ctx:(CGContextRef)ctx {\n  CFNumberRef styleRef = CFDictionaryGetValue(attributes, kStrikethroughAttributeKey);\n  NSUnderlineStyle style = 0;\n  CFNumberGetValue(styleRef, kCFNumberSInt64Type, &style);\n  if (style == NSUnderlineStyleNone) {\n    return;\n  }\n  const CGPoint *firstGlyphPosition = NULL;\n  firstGlyphPosition = CTRunGetPositionsPtr(run);\n  CGPoint *positions = NULL;\n  if (firstGlyphPosition == NULL) {\n    CFIndex glyphCount = CTRunGetGlyphCount(run);\n    positions = calloc(glyphCount, sizeof(CGPoint));\n    CTRunGetPositions(run, CFRangeMake(0, 0), positions);\n    firstGlyphPosition = positions;\n  }\n\n  CGFloat descent = 0;\n  CGFloat typographicWidth =\n      (CGFloat)CTRunGetTypographicBounds(run, CFRangeMake(0,0), NULL, &descent, NULL);\n\n  CGFloat lineWidth = 1;\n  if ((style & NSUnderlineStyleThick) == NSUnderlineStyleThick) {\n    // NSUnderlineStyleThick is 0x09 and NSUnderlineStyleSingle is 0x01. According to the Apple\n    // documentation, they are supposed to be masks...but they are not acting like masks...\n    lineWidth *= 2;\n  }\n\n  CGContextSetLineWidth(ctx, lineWidth);\n\n  CGContextBeginPath(ctx);\n\n  UIColor *strikethroughColor = CFDictionaryGetValue(attributes, kStrikethroughColorAttributeKey);\n  if (strikethroughColor) {\n    CGContextSetStrokeColorWithColor(ctx, strikethroughColor.CGColor);\n  } else if (_strikethroughColor) {\n    CGContextSetStrokeColorWithColor(ctx, _strikethroughColor.CGColor);\n  }\n\n  UIFont *font = CFDictionaryGetValue(attributes, kFontAttributeKey);\n  font = font ?: self.font;\n  CGFloat strikeHeight = font.xHeight / 2.f + (*firstGlyphPosition).y;\n\n  // Adjustment for multiline elements.\n  CGPoint pt = CGContextGetTextPosition(ctx);\n  strikeHeight += pt.y;\n\n  // For lines composed of multiple runs, (*firstGlyphPosition).x identifies the start of the run\n  // within the line.\n  CGContextMoveToPoint(ctx, pt.x + (*firstGlyphPosition).x, strikeHeight);\n  CGContextAddLineToPoint(ctx,\n                          pt.x + (*firstGlyphPosition).x + typographicWidth,\n                          strikeHeight);\n  CGContextStrokePath(ctx);\n  if (positions != NULL) {\n    free(positions);\n  }\n}\n\n- (void)drawTextInRect:(CGRect)rect {\n  if (NIVerticalTextAlignmentTop != self.verticalTextAlignment) {\n    rect.origin.y = [self _verticalOffsetForBounds:rect];\n  }\n\n  if (self.autoDetectLinks) {\n    [self detectLinks];\n  }\n\n  NSMutableAttributedString* attributedStringWithLinks = [self mutableAttributedStringWithAdditions];\n  if (self.detectedlinkLocations.count > 0 || self.explicitLinkLocations.count > 0) {\n    self.userInteractionEnabled = YES;\n  }\n\n  if (nil != attributedStringWithLinks) {\n    CGContextRef ctx = UIGraphicsGetCurrentContext();\n    CGContextSaveGState(ctx);\n\n    CGAffineTransform transform = [self _transformForCoreText];\n    CGContextConcatCTM(ctx, transform);\n\n    [self drawImages];\n    [self drawHighlightWithRect:rect];\n\n    if (nil != self.shadowColor) {\n      CGContextSetShadowWithColor(ctx, self.shadowOffset, self.shadowBlur, self.shadowColor.CGColor);\n    }\n\n    [self drawAttributedString:attributedStringWithLinks rect:rect];\n\n    CGContextRestoreGState(ctx);\n\n  } else {\n    [super drawTextInRect:rect];\n  }\n}\n\n#pragma mark - Accessibility\n\n- (void)invalidateAccessibleElements {\n  self.accessibleElements = nil;\n}\n\n- (void)updateAccessibilityLabelOnElement:(NIViewAccessibilityElement *)element\n                   withAccessibilityLabel:(NSString *)accessibilityLabel {\n  if (_shouldCalculateAccessibilityLabelPerLink) {\n    element.accessibilityLabel = accessibilityLabel;\n    return;\n  }\n\n  element.accessibilityAttributedLabel = self.accessibilityAttributedLabel;\n  element.accessibilityLabel = self.accessibilityLabel;\n}\n\n- (NSArray *)accessibleElements {\n  if (nil != _accessibleElements) {\n    return _accessibleElements;\n  }\n\n  NSMutableArray *accessibleElements = [NSMutableArray array];\n\n  // NSArray arrayWithArray:self.detectedlinkLocations ensures that we're not working with a nil\n  // array.\n  NSArray *allLinks = [[NSArray arrayWithArray:self.detectedlinkLocations]\n      arrayByAddingObjectsFromArray:self.explicitLinkLocations];\n\n  // If the entire label is a single link, then we want to only end up with one accessibility\n  // element - not one UIAccessibilityTraitLink element for the link and another\n  // UIAccessibilityTraitStaticText/UIAccessibilityTraitNone element for the entire label.\n  BOOL entireLabelIsOneLink = NO;\n  if (allLinks.count == 1) {\n    NSTextCheckingResult *onlyLink = allLinks.firstObject;\n    NSRange entireLabelRange = NSMakeRange(0, self.mutableAttributedString.length);\n    if (NSEqualRanges(onlyLink.range, entireLabelRange)) {\n      entireLabelIsOneLink = YES;\n    }\n  }\n\n  // TODO(kaikaiz): remove the first condition when shouldSortLinksLast is fully deprecated.\n  if ((_shouldSortLinksLast || (_linkOrdering != NILinkOrderingOriginal)) && !entireLabelIsOneLink) {\n    for (NSTextCheckingResult *result in allLinks) {\n      NSArray *rectsForLink = _shouldMergeMultilineLinks\n                                  ? [self _multilineRectsForRange:result.range]\n                                  : [self _rectsForRange:result.range];\n      if (!NIIsArrayWithObjects(rectsForLink)) {\n        continue;\n      }\n\n      NSString *label = [self.mutableAttributedString.string substringWithRange:result.range];\n      for (NSValue *rectValue in rectsForLink) {\n        NIViewAccessibilityElement *element = [[NIViewAccessibilityElement alloc]\n            initWithAccessibilityContainer:self\n                          frameInContainer:rectValue.CGRectValue];\n        element.shouldCalculateUniqueActivationPoint = _shouldMergeMultilineLinks;\n        [self updateAccessibilityLabelOnElement:element withAccessibilityLabel:label];\n\n        // Set the frame to fallback on if |element|'s accessibility container is changed\n        // externally.\n        CGRect rectValueInWindowCoordinates = [self convertRect:rectValue.CGRectValue toView:nil];\n        CGRect rectValueInScreenCoordinates = [self.window convertRect:rectValueInWindowCoordinates\n                                                              toWindow:nil];\n        element.accessibilityFrame = rectValueInScreenCoordinates;\n        element.accessibilityTraits = UIAccessibilityTraitLink;\n        element.rememberLastValidContainer = self.accessibleElementsRememberLastValidContainer;\n        [accessibleElements addObject:element];\n      }\n    }\n\n    NIViewAccessibilityElement *element =\n        [[NIViewAccessibilityElement alloc] initWithAccessibilityContainer:self\n                                                          frameInContainer:self.bounds];\n    element.shouldCalculateUniqueActivationPoint = _shouldMergeMultilineLinks;\n    [self updateAccessibilityLabelOnElement:element\n                     withAccessibilityLabel:self.attributedText.string];\n\n    // Set the frame to fallback on if |element|'s accessibility container is changed externally.\n    CGRect boundsInWindowCoordinates = [self convertRect:self.bounds toView:nil];\n    CGRect boundsInScreenCoordinates =\n        [self.window convertRect:boundsInWindowCoordinates toWindow:nil];\n    element.accessibilityFrame = boundsInScreenCoordinates;\n    element.accessibilityTraits =\n        _shouldMergeMultilineLinks ? UIAccessibilityTraitStaticText : UIAccessibilityTraitNone;\n    element.rememberLastValidContainer = self.accessibleElementsRememberLastValidContainer;\n    // TODO(kaikaiz): remove the first condition when shouldSortLinksLast is fully deprecated.\n    if (_shouldSortLinksLast || _linkOrdering == NILinkOrderingLast) {\n      [accessibleElements insertObject:element atIndex:0];\n    } else {\n      [accessibleElements addObject:element];\n    }\n  } else {\n    NIViewAccessibilityElement *element = nil;\n    NSUInteger start = 0;\n    for (NSTextCheckingResult *result in allLinks) {\n      NSRange range = result.range;\n      element = [self accessibilityElementForRange:NSMakeRange(start, range.location - start)];\n      if (element) {\n        element.accessibilityTraits =\n            _shouldMergeMultilineLinks ? UIAccessibilityTraitStaticText : UIAccessibilityTraitNone;\n        element.rememberLastValidContainer = self.accessibleElementsRememberLastValidContainer;\n        [accessibleElements addObject:element];\n      }\n      element = [self accessibilityElementForRange:range];\n      if (element) {\n        // Move the accessibilityActivationPoint from the center of the first frame to the\n        // bottom left of the last frame so it is externally calculable.\n        element.shouldCalculateUniqueActivationPoint = _shouldMergeMultilineLinks;\n        element.accessibilityTraits = UIAccessibilityTraitLink;\n        element.rememberLastValidContainer = self.accessibleElementsRememberLastValidContainer;\n        [accessibleElements addObject:element];\n      }\n      start = range.location + range.length;\n    }\n\n    element =\n        [self accessibilityElementForRange:NSMakeRange(start, self.attributedText.length - start)];\n    if (element) {\n      element.accessibilityTraits =\n          _shouldMergeMultilineLinks ? UIAccessibilityTraitStaticText : UIAccessibilityTraitNone;\n      element.rememberLastValidContainer = self.accessibleElementsRememberLastValidContainer;\n      [accessibleElements addObject:element];\n    }\n  }\n\n  _accessibleElements = [accessibleElements copy];\n  return _accessibleElements;\n}\n\n- (void)setAccessibleElementsRememberLastValidContainer:\n    (BOOL)accessibleElementsRememberLastValidContainer {\n  _accessibleElementsRememberLastValidContainer = accessibleElementsRememberLastValidContainer;\n  if (_accessibleElements != nil) {\n    [_accessibleElements enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {\n      if (![obj isKindOfClass:[NIViewAccessibilityElement class]]) {\n        return;\n      }\n      NIViewAccessibilityElement *element = (NIViewAccessibilityElement *)obj;\n      element.rememberLastValidContainer = accessibleElementsRememberLastValidContainer;\n    }];\n  }\n}\n\n- (BOOL)isAccessibilityElement {\n  return NO; // We handle accessibility for this element in -accessibleElements.\n}\n\n- (NSInteger)accessibilityElementCount  {\n  return self.accessibleElements.count;\n}\n\n- (id)accessibilityElementAtIndex:(NSInteger)index {\n  return [self.accessibleElements objectAtIndex:index];\n}\n\n- (NSInteger)indexOfAccessibilityElement:(id)element {\n  return [self.accessibleElements indexOfObject:element];\n}\n\n#pragma mark - UIActionSheetDelegate\n\n_NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_PUSH()\n- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {\n  if (NSTextCheckingTypeLink == self.actionSheetLink.resultType) {\n    if (buttonIndex == 0) {\n      [[UIApplication sharedApplication] openURL:self.actionSheetLink.URL];\n\n    } else if (buttonIndex == 1) {\n      if ([self.actionSheetLink.URL.scheme isEqualToString:@\"mailto\"]) {\n        [[UIPasteboard generalPasteboard] setString:self.actionSheetLink.URL.resourceSpecifier];\n\n      } else {\n        [[UIPasteboard generalPasteboard] setURL:self.actionSheetLink.URL];\n      }\n    }\n\n  } else if (NSTextCheckingTypePhoneNumber == self.actionSheetLink.resultType) {\n    if (buttonIndex == 0) {\n      [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[@\"tel:\" stringByAppendingString:self.actionSheetLink.phoneNumber]]];\n\n    } else if (buttonIndex == 1) {\n      [[UIPasteboard generalPasteboard] setString:self.actionSheetLink.phoneNumber];\n    }\n\n  } else if (NSTextCheckingTypeAddress == self.actionSheetLink.resultType) {\n    NSString* address = [self.mutableAttributedString.string substringWithRange:self.actionSheetLink.range];\n    if (buttonIndex == 0) {\n      NSString *escapedAddress =\n          NIStringByAddingPercentEscapesForURLParameterString(address);\n      NSString *URLString =\n          [NSString stringWithFormat:@\"https://maps.google.com/maps?q=%@\", escapedAddress];\n      NSURL *URL = [NSURL URLWithString:URLString];\n      [[UIApplication sharedApplication] openURL:URL];\n\n    } else if (buttonIndex == 1) {\n      [[UIPasteboard generalPasteboard] setString:address];\n    }\n\n  } else {\n    // Unsupported data type only allows the user to copy.\n    if (buttonIndex == 0) {\n      NSString* text = [self.mutableAttributedString.string substringWithRange:self.actionSheetLink.range];\n      [[UIPasteboard generalPasteboard] setString:text];\n    }\n  }\n\n  self.actionSheetLink = nil;\n  [self setNeedsDisplay];\n}\n_NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_POP()\n\n_NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_PUSH()\n- (void)actionSheetCancel:(UIActionSheet *)actionSheet {\n  self.actionSheetLink = nil;\n  [self setNeedsDisplay];\n}\n_NI_UIACTIONSHEET_DEPRECATION_SUPPRESSION_POP()\n\n#pragma mark - Inline Image Support\n\nCGFloat NIImageDelegateGetAscentCallback(void* refCon) {\n  NIAttributedLabelImage *labelImage = (__bridge NIAttributedLabelImage *)refCon;\n\n  switch (labelImage.verticalTextAlignment) {\n    case NIVerticalTextAlignmentMiddle:\n    {\n      CGFloat ascent = labelImage.fontAscent;\n      CGFloat descent = labelImage.fontDescent;\n      CGFloat baselineFromMid = (ascent + descent) / 2 - descent;\n\n      return labelImage.boxSize.height / 2 + baselineFromMid;\n    }\n    case NIVerticalTextAlignmentTop:\n      return labelImage.fontAscent;\n    case NIVerticalTextAlignmentBottom:\n    default:\n      return labelImage.boxSize.height - labelImage.fontDescent;\n  }\n}\n\nCGFloat NIImageDelegateGetDescentCallback(void* refCon) {\n  NIAttributedLabelImage *labelImage = (__bridge NIAttributedLabelImage *)refCon;\n\n  switch (labelImage.verticalTextAlignment) {\n    case NIVerticalTextAlignmentMiddle:\n    {\n      CGFloat ascent = labelImage.fontAscent;\n      CGFloat descent = labelImage.fontDescent;\n      CGFloat baselineFromMid = (ascent + descent) / 2 - descent;\n\n      return labelImage.boxSize.height / 2 - baselineFromMid;\n    }\n    case NIVerticalTextAlignmentTop:\n      return labelImage.boxSize.height - labelImage.fontAscent;\n    case NIVerticalTextAlignmentBottom:\n    default:\n      return labelImage.fontDescent;\n  }\n}\n\nCGFloat NIImageDelegateGetWidthCallback(void* refCon) {\n  NIAttributedLabelImage *labelImage = (__bridge NIAttributedLabelImage *)refCon;\n  return labelImage.image.size.width + labelImage.margins.left + labelImage.margins.right;\n}\n\n- (void)insertImage:(UIImage *)image atIndex:(NSInteger)index {\n  [self insertImage:image atIndex:index margins:UIEdgeInsetsZero verticalTextAlignment:NIVerticalTextAlignmentBottom];\n}\n\n- (void)insertImage:(UIImage *)image atIndex:(NSInteger)index margins:(UIEdgeInsets)margins {\n  [self insertImage:image atIndex:index margins:margins verticalTextAlignment:NIVerticalTextAlignmentBottom];\n}\n\n- (void)insertImage:(UIImage *)image atIndex:(NSInteger)index margins:(UIEdgeInsets)margins verticalTextAlignment:(NIVerticalTextAlignment)verticalTextAlignment {\n  NIAttributedLabelImage* labelImage = [[NIAttributedLabelImage alloc] init];\n  labelImage.index = index;\n  labelImage.image = image;\n  labelImage.margins = margins;\n  labelImage.verticalTextAlignment = verticalTextAlignment;\n  if (nil == self.images) {\n    self.images = [NSMutableArray array];\n  }\n  [self.images addObject:labelImage];\n}\n\n@end\n\n@implementation NIAttributedLabel (ConversionUtilities)\n\n+ (CTTextAlignment)alignmentFromUITextAlignment:(NSTextAlignment)alignment {\n  switch (alignment) {\n    case NSTextAlignmentLeft: return kCTTextAlignmentLeft;\n    case NSTextAlignmentCenter: return kCTTextAlignmentCenter;\n    case NSTextAlignmentRight: return kCTTextAlignmentRight;\n    case NSTextAlignmentJustified: return kCTTextAlignmentJustified;\n    default: return kCTTextAlignmentNatural;\n  }\n}\n\n+ (CTLineBreakMode)lineBreakModeFromUILineBreakMode:(NSLineBreakMode)lineBreakMode {\n  switch (lineBreakMode) {\n    case NSLineBreakByWordWrapping: return kCTLineBreakByWordWrapping;\n    case NSLineBreakByCharWrapping: return kCTLineBreakByCharWrapping;\n    case NSLineBreakByClipping: return kCTLineBreakByClipping;\n    case NSLineBreakByTruncatingHead: return kCTLineBreakByTruncatingHead;\n    case NSLineBreakByTruncatingTail: return kCTLineBreakByWordWrapping; // We handle truncation ourself.\n    case NSLineBreakByTruncatingMiddle: return kCTLineBreakByTruncatingMiddle;\n    default: return 0;\n  }\n}\n\n+ (NSMutableAttributedString *)mutableAttributedStringFromLabel:(UILabel *)label {\n  NSMutableAttributedString* attributedString = nil;\n\n  if (label.text.length > 0) {\n    attributedString = [[NSMutableAttributedString alloc] initWithString:label.text];\n\n    [attributedString setFont:label.font];\n    [attributedString setTextColor:label.textColor];\n\n    CTTextAlignment textAlignment = [self alignmentFromUITextAlignment:label.textAlignment];\n    CTLineBreakMode lineBreak = [self.class lineBreakModeFromUILineBreakMode:label.lineBreakMode];\n\n    CGFloat lineHeight = 0;\n    if ([label isKindOfClass:[NIAttributedLabel class]]) {\n      lineHeight = [(NIAttributedLabel *)label lineHeight];\n    }\n    [attributedString setTextAlignment:textAlignment lineBreakMode:lineBreak lineHeight:lineHeight];\n  }\n\n  return attributedString;\n}\n\n@end\n"
  },
  {
    "path": "src/attributedlabel/src/NSMutableAttributedString+NimbusAttributedLabel.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally created by Roger Chapman\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n#import <CoreText/CoreText.h>\n\n/**\n * For easier formatting of NSAttributedString.\n *\n * Most of these methods are called directly from NIAttributedLabel. Normally you should\n * not have to call these methods directly. Have a look at NIAttributedLabel first, it's most\n * likely what you're after.\n */\n@interface NSMutableAttributedString (NimbusAttributedLabel)\n\n/**\n * Sets the text alignment and line break mode for a given range.\n */\n- (void)setTextAlignment:(CTTextAlignment)textAlignment \n           lineBreakMode:(CTLineBreakMode)lineBreakMode\n              lineHeight:(CGFloat)lineHeight\n                   range:(NSRange)range;\n\n/**\n * Sets the text alignment and the line break mode for the entire string.\n */\n- (void)setTextAlignment:(CTTextAlignment)textAlignment \n           lineBreakMode:(CTLineBreakMode)lineBreakMode\n              lineHeight:(CGFloat)lineHeight;\n\n/**\n * Sets the text color for a given range.\n */\n- (void)setTextColor:(UIColor *)color range:(NSRange)range;\n\n/**\n * Sets the text color for the entire string.\n */\n- (void)setTextColor:(UIColor *)color;\n\n/**\n * Sets the font for a given range.\n */\n- (void)setFont:(UIFont *)font range:(NSRange)range;\n\n/**\n * Sets the font for the entire string.\n */\n- (void)setFont:(UIFont *)font;\n\n/**\n * Sets the underline style and modifier for a given range.\n */\n- (void)setUnderlineStyle:(CTUnderlineStyle)style\n                 modifier:(CTUnderlineStyleModifiers)modifier\n                    range:(NSRange)range;\n/**\n * Sets the underline style and modifier for the entire string.\n */\n- (void)setUnderlineStyle:(CTUnderlineStyle)style\n                 modifier:(CTUnderlineStyleModifiers)modifier;\n\n/**\n * Sets the stroke width for a given range.\n */\n- (void)setStrokeWidth:(CGFloat)width range:(NSRange)range;\n\n/**\n * Sets the stroke width for the entire string.\n */\n- (void)setStrokeWidth:(CGFloat)width;\n\n/**\n * Sets the stroke color for a given range.\n */\n- (void)setStrokeColor:(UIColor *)color range:(NSRange)range;\n\n/**\n * Sets the stroke color for the entire string.\n */\n- (void)setStrokeColor:(UIColor *)color;\n\n/**\n * Sets the text kern for a given range.\n */\n- (void)setKern:(CGFloat)kern range:(NSRange)range;\n\n/**\n * Sets the text kern for the entire string.\n */\n- (void)setKern:(CGFloat)kern;\n\n@end\n"
  },
  {
    "path": "src/attributedlabel/src/NSMutableAttributedString+NimbusAttributedLabel.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally created by Roger Chapman\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NSMutableAttributedString+NimbusAttributedLabel.h\"\n\n#import \"NimbusCore.h\" // For NI_FIX_CATEGORY_BUG\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n#error \"NIAttributedLabel requires iOS 6 or higher.\"\n#endif\n\nNI_FIX_CATEGORY_BUG(NSMutableAttributedStringNimbusAttributedLabel)\n\n@implementation NSMutableAttributedString (NimbusAttributedLabel)\n\n+ (NSLineBreakMode)lineBreakModeFromCTLineBreakMode:(CTLineBreakMode)mode {\n  switch (mode) {\n    case kCTLineBreakByWordWrapping: return NSLineBreakByWordWrapping;\n    case kCTLineBreakByCharWrapping: return NSLineBreakByCharWrapping;\n    case kCTLineBreakByClipping: return NSLineBreakByClipping;\n    case kCTLineBreakByTruncatingHead: return NSLineBreakByTruncatingHead;\n    case kCTLineBreakByTruncatingTail: return NSLineBreakByTruncatingTail;\n    case kCTLineBreakByTruncatingMiddle: return NSLineBreakByTruncatingMiddle;\n  }\n}\n\n- (void)setTextAlignment:(CTTextAlignment)textAlignment\n           lineBreakMode:(CTLineBreakMode)lineBreakMode\n              lineHeight:(CGFloat)lineHeight\n                   range:(NSRange)range {\n  NSMutableParagraphStyle* paragraphStyle = [[NSMutableParagraphStyle alloc] init];\n  paragraphStyle.alignment = NSTextAlignmentFromCTTextAlignment(textAlignment);\n  paragraphStyle.lineBreakMode = [[self class] lineBreakModeFromCTLineBreakMode:lineBreakMode];\n  paragraphStyle.minimumLineHeight = lineHeight;\n  paragraphStyle.maximumLineHeight = lineHeight;\n  [self addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];\n}\n\n- (void)setTextAlignment:(CTTextAlignment)textAlignment\n           lineBreakMode:(CTLineBreakMode)lineBreakMode\n              lineHeight:(CGFloat)lineHeight {\n  [self setTextAlignment:textAlignment\n           lineBreakMode:lineBreakMode\n              lineHeight:lineHeight\n                   range:NSMakeRange(0, self.length)];\n}\n\n- (void)setTextColor:(UIColor *)color range:(NSRange)range {\n  [self removeAttribute:NSForegroundColorAttributeName range:range];\n\n  if (nil != color) {\n    [self addAttribute:NSForegroundColorAttributeName value:color range:range];\n  }\n}\n\n- (void)setTextColor:(UIColor *)color {\n  [self setTextColor:color range:NSMakeRange(0, self.length)];\n}\n\n- (void)setFont:(UIFont *)font range:(NSRange)range {\n  [self removeAttribute:NSFontAttributeName range:range];\n\n  if (nil != font) {\n    [self addAttribute:NSFontAttributeName value:font range:range];\n  }\n}\n\n- (void)setFont:(UIFont*)font {\n  [self setFont:font range:NSMakeRange(0, self.length)];\n}\n\n- (void)setUnderlineStyle:(CTUnderlineStyle)style\n                 modifier:(CTUnderlineStyleModifiers)modifier\n                    range:(NSRange)range {\n  [self removeAttribute:NSUnderlineStyleAttributeName range:range];\n  [self addAttribute:NSUnderlineStyleAttributeName value:@(style|modifier) range:range];\n}\n\n- (void)setUnderlineStyle:(CTUnderlineStyle)style \n                modifier:(CTUnderlineStyleModifiers)modifier {\n  [self setUnderlineStyle:style modifier:modifier range:NSMakeRange(0, self.length)];\n}\n\n- (void)setStrokeWidth:(CGFloat)width range:(NSRange)range {\n  [self removeAttribute:NSStrokeWidthAttributeName range:range];\n  [self addAttribute:NSStrokeWidthAttributeName value:@(width) range:range];\n}\n\n- (void)setStrokeWidth:(CGFloat)width {\n  [self setStrokeWidth:width range:NSMakeRange(0, self.length)];\n}\n\n- (void)setStrokeColor:(UIColor *)color range:(NSRange)range {\n  [self removeAttribute:NSStrokeColorAttributeName range:range];\n  if (nil != color.CGColor) {\n    [self addAttribute:NSStrokeColorAttributeName value:color range:range];\n  }\n}\n\n- (void)setStrokeColor:(UIColor *)color {\n  [self setStrokeColor:color range:NSMakeRange(0, self.length)];\n}\n\n- (void)setKern:(CGFloat)kern range:(NSRange)range {\n  [self removeAttribute:NSKernAttributeName range:range];\n  [self addAttribute:NSKernAttributeName value:@(kern) range:range];\n}\n\n- (void)setKern:(CGFloat)kern {\n  [self setKern:kern range:NSMakeRange(0, self.length)];\n}\n\n@end\n"
  },
  {
    "path": "src/attributedlabel/src/NimbusAttributedLabel.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally created by Roger Chapman\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * @defgroup NimbusAttributedLabel Nimbus Attributed Label\n * @{\n *\n * <div id=\"github\" feature=\"attributedlabel\"></div>\n *\n * The Nimbus Attributed Label is a UILabel that uses NSAttributedString to render rich text labels\n * with links using CoreText.\n *\n *  @image html NIAttributedLabelExample1.png \"A mashup of possible label styles\"\n *\n * <h2>Minimum Requirements</h2>\n *\n * Required frameworks:\n *\n * - Foundation.framework\n * - UIKit.framework\n * - CoreText.framework\n * - QuartzCore.framework\n *\n * Minimum Operating System: <b>iOS 6.0</b>\n *\n * Source located in <code>src/attributedlabel/src</code>\n *\n@code\n#import \"NimbusAttributedLabel.h\"\n@endcode\n *\n * <h2>Basic Use</h2>\n *\n * NIAttributedLabel is a subclass of UILabel. The attributed label maintains an <a href=\"http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSAttributedString_Class/Reference/Reference.html\">NSAttributedString</a>\n * object internally which is used in conjunction with CoreText to draw rich-text labels. A number\n * of helper methods for modifying the text style are provided. If you need to directly modify the\n * internal NSAttributedString you may do so by accessing the @c attributedText property.\n *\n@code\nNIAttributedLabel* label = [[NIAttributedLabel alloc] initWithFrame:CGRectZero];\n\n// The internal NSAttributedString will inherit all of UILabel's text attributes when we assign\n// text.\nlabel.text = @\"Nimbus\";\n@endcode\n *\n *\n * <h2>Interface Builder</h2>\n *\n * You can use an attributed label within Interface Builder by creating a UILabel and changing its\n * class to NIAttributedLabel. This will allow you to set styles that apply to\n * the entire string. If you want to style specific parts of the string then you will\n * need to do this in code.\n *\n *  @image html NIAttributedLabelIB.png \"Configuring an attributed label in Interface Builder\"\n *\n *\n * <h2>Feature Overview</h2>\n *\n * - Automatic link detection using data detectors\n * - Link attributes\n * - Explicit links\n * - Underlining\n * - Justifying paragraphs\n * - Stroking\n * - Kerning\n * - Setting rich text styles at specific ranges\n *\n *\n * <h3>Automatic Link Detection</h3>\n *\n * Automatic link detection is provided using <a href=\"https://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSDataDetector_Class/Reference/Reference.html\">NSDataDetector</a>.\n * Link detection is off by default and can be enabled by setting\n * @link NIAttributedLabel::autoDetectLinks autoDetectLinks@endlink to YES. You may configure\n * the types of data that are detected by modifying the\n * @link NIAttributedLabel::dataDetectorTypes dataDetectorTypes@endlink property. By default only\n * urls will be detected.\n *\n * @attention NIAttributedLabel is not designed to detect html anchor tags (i.e. &lt;a>). If\n *                 you want to attach a URL to a given range of text you must use\n *                 @link NIAttributedLabel::addLink:range: addLink:range:@endlink.\n *                 You can add links to the attributed string using the attribute\n *                 NIAttributedLabelLinkAttributeName. The NIAttributedLabelLinkAttributeName value\n *                 must be a NSTextCheckingResult.\n *\n * @image html NIAttributedLabel_autoDetectLinksOff.png \"Before enabling autoDetectLinks\"\n *\n@code\n// Enable link detection on the label.\nmyLabel.autoDetectLinks = YES;\n@endcode\n *\n * @image html NIAttributedLabel_autoDetectLinksOn.png \"After enabling autoDetectLinks\"\n *\n * Enabling automatic link detection will automatically enable user interation with the label view\n * so that the user can tap the detected links.\n *\n * <h3>Link Attributes</h3>\n *\n * Detected links will use @link NIAttributedLabel::linkColor linkColor@endlink and\n * @link NIAttributedLabel::highlightedLinkColor highlightedLinkColor@endlink to differentiate\n * themselves from standard text. highlightedLinkColor is the color of the highlighting frame\n * around the text. You can easily add underlines to links by enabling\n * @link NIAttributedLabel::linksHaveUnderlines linksHaveUnderlines@endlink. You can customize link\n * attributes in more detail by directly modifying the\n * @link NIAttributedLabel::attributesForLinks attributesForLinks@endlink property.\n *\n *  @image html NIAttributedLabelLinkAttributes.png \"Link attributes\"\n *\n * <h4>A note on performance</h4>\n *\n * Automatic link detection is expensive. You can choose to defer automatic link detection by\n * enabling @link NIAttributedLabel::deferLinkDetection deferLinkDetection@endlink. This will move\n * the link detection to a separate background thread. Once the links have been detected the label\n * will be redrawn.\n *\n *\n * <h3>Handling Taps on Links</h3>\n *\n * The NIAttributedLabelDelegate protocol allows you to handle when the user taps on a given link.\n * The protocol methods provide the tap point as well as the data pertaining to the tapped link.\n *\n@code\n- (void)attributedLabel:(NIAttributedLabel *)attributedLabel didSelectTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point {\n  [[UIApplication sharedApplication] openURL:result.URL];\n}\n@endcode\n *\n * <h3>Explicit Links</h3>\n *\n * Links can be added explicitly using\n * @link NIAttributedLabel::addLink:range: addLink:range:@endlink.\n * \n@code\n// Add a link to the string 'nimbus' in myLabel.\n[myLabel addLink:[NSURL URLWithString:@\"nimbus://custom/url\"]\n           range:[myLabel.text rangeOfString:@\"nimbus\"]];\n@endcode\n *\n *\n * <h3>Underlining Text</h3>\n *\n * To underline an entire label:\n *\n@code\n// Underline the whole label with a single line.\nmyLabel.underlineStyle = kCTUnderlineStyleSingle;\n@endcode\n *\n * Underline modifiers can also be added:\n *\n@code\n// Underline the whole label with a dash dot single line.\nmyLabel.underlineStyle = kCTUnderlineStyleSingle;\nmyLabel.underlineStyleModifier = kCTUnderlinePatternDashDot;\n@endcode\n *\n * Underline styles and modifiers can be mixed to create the desired effect, which is shown in\n * the following screenshot:\n *\n * @image html NIAttributedLabelExample2.png \"Underline styles\"\n *\n *    @remarks Underline style kCTUnderlineStyleThick only over renders a single line.\n *\n *\n * <h3>Justifying Paragraphs</h3>\n *\n * NIAttributedLabel supports justified text using UITextAlignmentJustify.\n *\n@code\n myLabel.textAlignment = UITextAlignmentJustify;\n@endcode\n *\n *\n * <h3>Stroking Text</h3>\n *\n@code\nmyLabel.strokeWidth = 3.0;\nmyLabel.strokeColor = [UIColor blackColor];\n@endcode\n *\n * A positive stroke width will render only the stroke.\n *\n * @image html NIAttributedLabelExample3.png \"Black stroke of 3.0\"\n *\n * A negative number will fill the stroke with textColor:\n * \n@code\nmyLabel.strokeWidth = -3.0;\nmyLabel.strokeColor = [UIColor blackColor];\n@endcode\n *\n * @image html NIAttributedLabelExample4.png \"Black stroke of -3.0\"\n *\n *\n * <h3>Kerning Text</h3>\n *\n * Kerning is the space between characters in points. A positive kern will increase the space\n * between letters. Correspondingly a negative number will decrease the space.\n *\n@code\nmyLabel.textKern = -6.0;\n@endcode\n *\n * @image html NIAttributedLabelExample5.png \"Text kern of -6.0\"\n *\n *\n * <h3>Setting Rich Text styles at specific ranges</h3>\n *\n * All styles that can be added to the whole label (as well as default UILabel styles like font and\n * text color) can be added to just a range of text.\n *\n@code\n[myLabel setTextColor:[UIColor orangeColor] range:[myLabel.text rangeOfString:@\"Nimbus\"]];\n[myLabel setFont:[UIFont boldSystemFontOfSize:22] range:[myLabel.text rangeOfString:@\"iOS\"]];\n@endcode\n * @}\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n#import <CoreText/CoreText.h>\n\n#import \"NimbusCore.h\"\n#import \"NIAttributedLabel.h\"\n"
  },
  {
    "path": "src/attributedlabel/unittests/NIAttributedLabelTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import \"NIAttributedLabel.h\"\n#import \"NimbusAttributedLabel.h\"\n\n#import <Foundation/Foundation.h>\n#import <XCTest/XCTest.h>\n\n#import \"NIAttributedLabel+Testing.h\"\n\n@interface NIAttributedLabelTestMonitor : NSObject <NIAttributedLabelDelegate>\n\n@property(nonatomic, assign) BOOL doNotRespondToLongPressCallback;\n\n@property(nonatomic, readonly) int longPressCallbackCount;\n@property(nonatomic, readonly) int actionSheetCallbackCount;\n\n@end\n\n@implementation NIAttributedLabelTestMonitor\n\n- (BOOL)respondsToSelector:(SEL)selector {\n  if (selector == @selector(attributedLabel:didLongPressTextCheckingResult:atPoint:)) {\n    return !_doNotRespondToLongPressCallback;\n  }\n\n  return [super respondsToSelector:selector];\n}\n\n- (void)attributedLabel:(NIAttributedLabel *)attributedLabel\n    didLongPressTextCheckingResult:(NSTextCheckingResult *)result\n                           atPoint:(CGPoint)point {\n  _longPressCallbackCount++;\n}\n\n- (BOOL)attributedLabel:(NIAttributedLabel *)attributedLabel\n    shouldPresentActionSheet:(UIActionSheet *)actionSheet\n      withTextCheckingResult:(NSTextCheckingResult *)result\n                     atPoint:(CGPoint)point {\n  _actionSheetCallbackCount++;\n  return NO;\n}\n\n@end\n\n@interface NIAttributedLabelTests : XCTestCase\n@end\n\n@implementation NIAttributedLabelTests\n\n+ (NIAttributedLabel *)makeGenericMultilineLabelWithFrame:(CGRect)frame {\n  // Create an attributed string with a link.\n  NSString *string = @\"Unlinked content. Linked content.\\nLinked content. Unlinked content.\";\n  NSURL *URL = [NSURL URLWithString:@\"http://youtube.com\"];\n  NSTextCheckingResult *textCheckingResult =\n      [NSTextCheckingResult linkCheckingResultWithRange:NSMakeRange(18, 32) URL:URL];\n  NSDictionary<NSAttributedStringKey, id> *attributes =\n      @{NIAttributedLabelLinkAttributeName : textCheckingResult};\n  NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:string\n                                                                       attributes:attributes];\n\n  // Create a label.\n  NIAttributedLabel *label = [[NIAttributedLabel alloc] initWithFrame:frame];\n  label.attributedText = attributedText;\n  label.numberOfLines = 0;\n\n  return label;\n}\n\n+ (void)assertAccessibleElementsContainedByElementFramesAndUnique:\n    (NSMutableArray<NIViewAccessibilityElement *> *)accessibleElements {\n  NSMutableSet *activationPointSet = [NSMutableSet set];\n  // Expect that the activationPoints are inside of the accessibility element's frame and that\n  // each point is unique.\n  for (int elementIndex = 0; elementIndex < accessibleElements.count; elementIndex++) {\n    CGPoint activationPoint = accessibleElements[elementIndex].accessibilityActivationPoint;\n    [activationPointSet addObject:[NSValue valueWithCGPoint:activationPoint]];\n    CGRect elementFrame = [accessibleElements objectAtIndex:elementIndex].frameInContainer;\n    // CGRectContainsPoint does not check if the point is on maximum Y, we modify the lower bound\n    // of elementFrame to ensure maximum Y is contained by elementFrame.\n    XCTAssertTrue(\n        CGRectContainsPoint(CGRectMake(elementFrame.origin.x, elementFrame.origin.y,\n                                       elementFrame.size.width, elementFrame.size.height + 1),\n                            activationPoint));\n  }\n  XCTAssertEqual(activationPointSet.count, accessibleElements.count);\n}\n\n- (void)testLongPressCallbackOverridesActionSheetCallbackWhenTouchingLink {\n  // Create an attributed string with a link.\n  NSString *string = @\"NimbusKit\";\n  NSURL *URL = [NSURL URLWithString:@\"http://nimbuskit.info/\"];\n  NSTextCheckingResult *textCheckingResult =\n      [NSTextCheckingResult linkCheckingResultWithRange:NSMakeRange(0, string.length) URL:URL];\n  NSDictionary<NSAttributedStringKey, id> *attributes =\n      @{NIAttributedLabelLinkAttributeName : textCheckingResult};\n  NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:string\n                                                                       attributes:attributes];\n\n  // Create a label.\n  NIAttributedLabel *label = [[NIAttributedLabel alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];\n  label.attributedText = attributedText;\n\n  // Create a monitor for attributed label callbacks.\n  NIAttributedLabelTestMonitor *monitor = [[NIAttributedLabelTestMonitor alloc] init];\n  label.delegate = monitor;\n\n  // Simulate touching a link.\n  label.touchedLink = textCheckingResult;\n  [label _longPressTimerDidFire:nil];\n\n  // Verify expected callbacks.\n  XCTAssertEqual(monitor.longPressCallbackCount, 1);\n  XCTAssertEqual(monitor.actionSheetCallbackCount, 0);\n}\n\n- (void)testActionSheetCallbackDeliveredWhenTouchingLink {\n  // Create an attributed string with a link.\n  NSString *string = @\"NimbusKit\";\n  NSURL *URL = [NSURL URLWithString:@\"http://nimbuskit.info/\"];\n  NSTextCheckingResult *textCheckingResult =\n      [NSTextCheckingResult linkCheckingResultWithRange:NSMakeRange(0, string.length) URL:URL];\n  NSDictionary<NSAttributedStringKey, id> *attributes =\n      @{NIAttributedLabelLinkAttributeName : textCheckingResult};\n  NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:string\n                                                                       attributes:attributes];\n\n  // Create a label.\n  NIAttributedLabel *label = [[NIAttributedLabel alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];\n  label.attributedText = attributedText;\n\n  // Create a monitor for attributed label callbacks and make it not respond to the long press\n  // callback.\n  NIAttributedLabelTestMonitor *monitor = [[NIAttributedLabelTestMonitor alloc] init];\n  monitor.doNotRespondToLongPressCallback = YES;\n  label.delegate = monitor;\n\n  // Simulate touching a link.\n  label.touchedLink = textCheckingResult;\n  [label _longPressTimerDidFire:nil];\n\n  // Verify expected callbacks.\n  XCTAssertEqual(monitor.longPressCallbackCount, 0);\n  XCTAssertEqual(monitor.actionSheetCallbackCount, 1);\n}\n\n- (void)testPreOrderedLinks {\n  CGRect labelFrame = CGRectMake(0, 0, 200, 200);\n  NIAttributedLabel *label = [NIAttributedLabelTests makeGenericMultilineLabelWithFrame:labelFrame];\n\n  // Create pre-order non-merged multiline links.\n  label.linkOrdering = NILinkOrderingFirst;\n  label.shouldMergeMultilineLinks = NO;\n  NSMutableArray<NIViewAccessibilityElement *> *accessibleElements =\n      [label.accessibleElements copy];\n\n  // Given labelFrame (0, 0, 200, 200), expect {(96, 3, 81, 12), (0, 18, 85, 12), (0, 0, 200, 200)}.\n  CGRect firstFrame = [accessibleElements objectAtIndex:0].frameInContainer;\n  CGRect secondFrame = [accessibleElements objectAtIndex:1].frameInContainer;\n  // Test second frame starts at start of labelFrame.\n  XCTAssertEqual(secondFrame.origin.x, labelFrame.origin.x);\n  // Test first frame starts after second frame.\n  XCTAssertGreaterThan(firstFrame.origin.x, secondFrame.origin.x);\n  // Test first frame start above second frame.\n  XCTAssertLessThan(firstFrame.origin.y, secondFrame.origin.y);\n  // Test both frames have the same height (same attribute).\n  XCTAssertEqual(firstFrame.size.height, secondFrame.size.height);\n  // Test last element is labelFrame.\n  XCTAssertTrue(\n      CGRectEqualToRect([accessibleElements objectAtIndex:2].frameInContainer, labelFrame));\n\n  // Create pre-order merged multiline links.\n  [label invalidateAccessibleElements];\n  label.shouldMergeMultilineLinks = YES;\n  NSMutableArray<NIViewAccessibilityElement *> *accessibleMergedElements =\n      [label.accessibleElements copy];\n\n  // Given labelFrame (0, 0, 200, 200), expect {(0, 3, 177, 27), (0, 0, 200, 200)}.\n  CGRect mergedFrame = [accessibleMergedElements objectAtIndex:0].frameInContainer;\n  // Test first frame starts at start of labelFrame.\n  XCTAssertEqual(mergedFrame.origin.x, labelFrame.origin.x);\n  // Test last element is labelFrame.\n  XCTAssertTrue(\n      CGRectEqualToRect([accessibleMergedElements objectAtIndex:1].frameInContainer, labelFrame));\n\n  // Test pre-order non-merged multiline link frames union to merged multiline link frame.\n  XCTAssertTrue(CGRectEqualToRect(CGRectUnion(firstFrame, secondFrame), mergedFrame));\n}\n\n- (void)testPostOrderedLinks {\n  CGRect labelFrame = CGRectMake(0, 0, 200, 200);\n  NIAttributedLabel *label = [NIAttributedLabelTests makeGenericMultilineLabelWithFrame:labelFrame];\n\n  // Create post-order non-mergegd multiline links.\n  label.linkOrdering = NILinkOrderingLast;\n  label.shouldMergeMultilineLinks = NO;\n  NSMutableArray<NIViewAccessibilityElement *> *accessibleElements =\n      [label.accessibleElements copy];\n\n  // Given labelFrame (0, 0, 200, 200), expect {(0, 0, 200, 200), (96, 3, 81, 12), (0, 18, 85, 12)}.\n  CGRect firstFrame = [accessibleElements objectAtIndex:1].frameInContainer;\n  CGRect secondFrame = [accessibleElements objectAtIndex:2].frameInContainer;\n  // Test first frame is labelFrame.\n  XCTAssertTrue(\n      CGRectEqualToRect([accessibleElements objectAtIndex:0].frameInContainer, labelFrame));\n  // Test second frame starts at start of labelFrame.\n  XCTAssertEqual(secondFrame.origin.x, labelFrame.origin.x);\n  // Test first frame starts after second frame.\n  XCTAssertGreaterThan(firstFrame.origin.x, secondFrame.origin.x);\n  // Test first frame start above second frame.\n  XCTAssertLessThan(firstFrame.origin.y, secondFrame.origin.y);\n  // Test both frames have the same height (same attribute).\n  XCTAssertEqual(firstFrame.size.height, secondFrame.size.height);\n\n  // Create post-order merged multiline links.\n  [label invalidateAccessibleElements];\n  label.shouldMergeMultilineLinks = YES;\n  NSMutableArray<NIViewAccessibilityElement *> *accessibleMergedElements =\n      [label.accessibleElements copy];\n\n  // Test first frame is labelFrame.\n  XCTAssertTrue(\n      CGRectEqualToRect([accessibleMergedElements objectAtIndex:0].frameInContainer, labelFrame));\n  // Given labelFrame (0, 0, 200, 200), expect {(0, 0, 200, 200), (0, 3, 177, 27)}.\n  CGRect mergedFrame = [accessibleMergedElements objectAtIndex:1].frameInContainer;\n  // Test first frame starts at start of labelFrame.\n  XCTAssertEqual(mergedFrame.origin.x, labelFrame.origin.x);\n\n  // Test post-order non-merged multiline links union to merged multiline link.\n  XCTAssertTrue(CGRectEqualToRect(CGRectUnion(firstFrame, secondFrame), mergedFrame));\n}\n\n- (void)testInOrderLinks {\n  CGRect labelFrame = CGRectMake(0, 0, 200, 200);\n  NIAttributedLabel *label = [NIAttributedLabelTests makeGenericMultilineLabelWithFrame:labelFrame];\n\n  // Links in-order non-merged multiline links.\n  label.linkOrdering = NILinkOrderingOriginal;\n  label.shouldMergeMultilineLinks = NO;\n  NSMutableArray<NIViewAccessibilityElement *> *accessibleElements =\n      [label.accessibleElements copy];\n\n  // Given labelFrame (0, 0, 200, 200), expect {(0, 3, 96, 12), (0, 3, 177, 27), (85, 18, 93, 12)}.\n  CGRect firstFrame = [accessibleElements objectAtIndex:0].frameInContainer;\n  CGRect mergedFrame = [accessibleElements objectAtIndex:1].frameInContainer;\n  CGRect secondFrame = [accessibleElements objectAtIndex:2].frameInContainer;\n  // Test first frame starts at start of labelFrame.\n  XCTAssertEqual(firstFrame.origin.x, labelFrame.origin.x);\n  // Test first frame has same origin as merged frame.\n  XCTAssertTrue(CGPointEqualToPoint(firstFrame.origin, mergedFrame.origin));\n  // Test first frame has smaller width than merged frame.\n  XCTAssertLessThan(firstFrame.size.width, mergedFrame.size.width);\n  // Test first frame has smaller height than merged frame.\n  XCTAssertLessThan(firstFrame.size.height, mergedFrame.size.height);\n\n  // Test first frame start above second frame.\n  XCTAssertLessThan(firstFrame.origin.y, secondFrame.origin.y);\n  // Test second frame has smaller width than merged frame.\n  XCTAssertLessThan(secondFrame.size.width, mergedFrame.size.width);\n  // Test second frame has smaller height than merged frame.\n  XCTAssertLessThan(secondFrame.size.height, mergedFrame.size.height);\n  // Test first and second frames have the same height (same attribute).\n  XCTAssertEqual(firstFrame.size.height, secondFrame.size.height);\n\n  // Links in-order merged multiline links.\n  [label invalidateAccessibleElements];\n  label.shouldMergeMultilineLinks = YES;\n  NSMutableArray<NIViewAccessibilityElement *> *accessibleMergedElements =\n      [label.accessibleElements copy];\n\n  for (int frameIndex = 0; frameIndex < accessibleMergedElements.count; frameIndex++) {\n    XCTAssertTrue(\n        CGRectEqualToRect([accessibleElements objectAtIndex:frameIndex].frameInContainer,\n                          [accessibleMergedElements objectAtIndex:frameIndex].frameInContainer));\n  }\n}\n\n- (void)testAccessibilityActivationPoints {\n  CGRect viewFrame = CGRectMake(0, 0, 200, 200);\n  UIWindow *window = [[UIWindow alloc] initWithFrame:viewFrame];\n  UIView *view = [[UIView alloc] initWithFrame:viewFrame];\n  [window addSubview:view];\n\n  NSArray *linkOrderings =\n      @[ @(NILinkOrderingFirst), @(NILinkOrderingOriginal), @(NILinkOrderingLast) ];\n  for (int linkOrderingIndex = 0; linkOrderingIndex < linkOrderings.count; linkOrderingIndex++) {\n    // Given a label in a UIWindow's view with a specified linkOrdering.\n    NILinkOrdering linkOrdering = (NILinkOrdering)linkOrderings[linkOrderingIndex];\n    NIAttributedLabel *label =\n        [NIAttributedLabelTests makeGenericMultilineLabelWithFrame:viewFrame];\n    label.linkOrdering = linkOrdering;\n    [view addSubview:label];\n    NSMutableArray<NIViewAccessibilityElement *> *accessibleElements =\n        [label.accessibleElements copy];\n\n    [NIAttributedLabelTests\n        assertAccessibleElementsContainedByElementFramesAndUnique:accessibleElements];\n  }\n}\n\n- (void)testShouldMergeMultilineLinksAccessibilityActivationPoints {\n  CGRect viewFrame = CGRectMake(0, 0, 200, 200);\n  UIWindow *window = [[UIWindow alloc] initWithFrame:viewFrame];\n  UIView *view = [[UIView alloc] initWithFrame:viewFrame];\n  [window addSubview:view];\n\n  NSArray *linkOrderings =\n      @[ @(NILinkOrderingFirst), @(NILinkOrderingOriginal), @(NILinkOrderingLast) ];\n  for (int linkOrderingIndex = 0; linkOrderingIndex < linkOrderings.count; linkOrderingIndex++) {\n    // Given a label in a UIWindow's view with a specified linkOrdering.\n    NILinkOrdering linkOrdering = (NILinkOrdering)linkOrderings[linkOrderingIndex];\n    NIAttributedLabel *label =\n        [NIAttributedLabelTests makeGenericMultilineLabelWithFrame:viewFrame];\n    label.linkOrdering = linkOrdering;\n    [view addSubview:label];\n\n    // If we enable merging multiline links.\n    label.shouldMergeMultilineLinks = YES;\n    NSMutableArray<NIViewAccessibilityElement *> *accessibleElements =\n        [label.accessibleElements copy];\n\n    [NIAttributedLabelTests\n        assertAccessibleElementsContainedByElementFramesAndUnique:accessibleElements];\n  }\n}\n\n@end\n"
  },
  {
    "path": "src/attributedlabel/unittests/NimbusAttributedLabelTests-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": "src/badge/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\n"
  },
  {
    "path": "src/badge/src/NIBadgeView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally created by Roger Chapman\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n/**\n * A view that mimics the iOS notification badge style.\n *\n * Any NSString can be displayed in this view, though in practice you should only show numbers\n * ranging from 1...99 or the string @\"99+\". Apple is quite consistent about using the red badge\n * views to represent notification badges, so you should do your best not to attach additional\n * meaning to the red badge.\n *\n * On devices running operating systems that support the tintColor property on UIViews, these\n * badges will use the tintColor by default. This behavior may be overwritten by assigning a tint\n * color explicitly.\n *\n *  @image html badge.png \"A default NIBadgeView\"\n *  @image html badgetinted.png \"A NIBadgeView on tintColor-supporting devices\"\n *\n * @ingroup NimbusBadge\n */\n@interface NIBadgeView : UIView\n\n// Text attributes\n@property (nonatomic, copy) NSString* text;\n@property (nonatomic, strong) UIFont* font;\n@property (nonatomic, strong) UIColor* textColor;\n\n// Badge attributes\n@property (nonatomic, strong) UIColor* tintColor;\n@property (nonatomic, strong) UIColor* shadowColor;\n@property (nonatomic, assign) CGSize shadowOffset;\n@property (nonatomic, assign) CGFloat shadowBlur;\n\n@end\n\n/** @name Accessing the Text Attributes */\n\n/**\n * The text displayed within the badge.\n *\n * As with a UILabel you should call sizeToFit after setting the badgeView properties so that it\n * will update its frame to fit the contents.\n *\n * @fn NIBadgeView::text\n */\n\n/**\n * The font of the text within the badge.\n *\n * The default font is:\n *\n *   iOS 6: [UIFont boldSystemFontOfSize:17]\n *   iOS 7: [UIFont systemFontOfSize:16]\n *\n * @sa text\n * @fn NIBadgeView::font\n */\n\n/**\n * The color of the text in the badge.\n *\n * The default color is [UIColor whiteColor].\n *\n * @fn NIBadgeView::textColor\n */\n\n/** @name Accessing the Badge Attributes */\n\n/**\n * The tint color of the badge.\n *\n * This is the color drawn within the badge's borders.\n *\n * The default color is\n *\n *   iOS 6: [UIColor redColor].\n *   iOS 7: self.tintColor\n *\n * On devices that support global tintColor (iOS 7) the global tint color is used unless a tint\n * color has been explicitly assigned to this badge view, in which case the assigned tint color will be used.\n *\n * @fn NIBadgeView::tintColor\n */\n\n/**\n * The shadow color of the badge.\n *\n * This is the shadow drawn beneath the badge's outline.\n *\n * The default color is\n *\n *   iOS 6: [UIColor colorWithWhite:0 alpha:0.5].\n *   iOS 7: nil\n *\n * On devices that support global tintColor (iOS 7) it is possible, though not encouraged, to use\n * a shadow on badges.\n *\n * @sa shadowOffset\n * @sa shadowBlur\n * @fn NIBadgeView::shadowColor\n */\n\n/**\n * The shadow offset (measured in points) for the badge.\n *\n * This is the offset of the shadow drawn beneath the badge's outline.\n *\n * The default value is CGSizeMake(0, 3.f).\n *\n * @sa shadowColor\n * @sa shadowBlur\n * @fn NIBadgeView::shadowOffset\n */\n\n/**\n * The shadow blur (measured in points) for the badge.\n *\n * This is the blur of the shadow drawn beneath the badge's outline.\n *\n * The default value is 3.\n *\n * @sa shadowOffset\n * @sa shadowColor\n * @fn NIBadgeView::shadowBlur\n */\n"
  },
  {
    "path": "src/badge/src/NIBadgeView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally created by Roger Chapman\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIBadgeView.h\"\n\n#import \"NimbusCore.h\" // For NIScreenScale\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n#error \"NIBadgeView requires iOS 6 or higher.\"\n#endif\n\nstatic BOOL sUsesSolidTint = NO;\n\nstatic const CGFloat kHorizontalMargins = 20.f;\nstatic const CGFloat kVerticalMargins = 10.f;\nstatic const CGFloat kBadgeLineSize = 2.0f;\n\n@implementation NIBadgeView\n\n@synthesize tintColor = _tintColor;\n\n+ (void)initialize {\n  sUsesSolidTint = NIIsTintColorGloballySupported();\n}\n\n- (void)_configureDefaults {\n  self.contentScaleFactor = NIScreenScale();\n\n  // We check for nil values so that defaults can be set in IB.\n  if (nil == self.tintColor) {\n    if (!sUsesSolidTint) {\n      self.tintColor = [UIColor redColor];\n    }\n  }\n  if (nil == self.font) {\n    self.font = sUsesSolidTint ? [UIFont systemFontOfSize:16] : [UIFont boldSystemFontOfSize:17];\n  }\n  if (nil == self.textColor) {\n    self.textColor = [UIColor whiteColor];\n  }\n  if (nil == self.shadowColor) {\n    if (!sUsesSolidTint) {\n      self.shadowColor = [UIColor colorWithWhite:0 alpha:0.5];\n    }\n  }\n  if (CGSizeEqualToSize(self.shadowOffset, CGSizeZero)) {\n    self.shadowOffset = CGSizeMake(0, 3);\n  }\n  if (0 == self.shadowBlur) {\n    self.shadowBlur = 3;\n  }\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    [self _configureDefaults];\n  }\n  return self;\n}\n\n- (void)awakeFromNib {\n  [super awakeFromNib];\n\n  [self _configureDefaults];\n}\n\n- (CGSize)sizeThatFits:(CGSize)size {\n  CGSize stringSize = [self.text sizeWithFont:self.font];\n  CGSize zeroSize = [@\"0\" sizeWithFont:self.font];\n  CGFloat padding = 0;\n  if (sUsesSolidTint) {\n    padding = 2;\n  }\n\n  return CGSizeMake(MAX(zeroSize.width + kHorizontalMargins + padding,\n                        stringSize.width + kHorizontalMargins),\n                    stringSize.height + kVerticalMargins);\n}\n\n- (CGSize)intrinsicContentSize {\n  return [self sizeThatFits:self.bounds.size];\n}\n\n- (void)setText:(NSString *)text {\n  _text = text;\n\n  [self setNeedsDisplay];\n\n  if ([self respondsToSelector:@selector(invalidateIntrinsicContentSize)]) {\n    [self invalidateIntrinsicContentSize];\n  }\n}\n\n- (void)setFont:(UIFont *)font {\n  _font = font;\n\n  [self setNeedsDisplay];\n\n  if ([self respondsToSelector:@selector(invalidateIntrinsicContentSize)]) {\n    [self invalidateIntrinsicContentSize];\n  }\n}\n\n- (void)setTintColor:(UIColor *)tintColor {\n  _tintColor = tintColor;\n\n  [self setNeedsDisplay];\n}\n\n- (UIColor *)tintColor {\n  if (sUsesSolidTint) {\n    return (nil != _tintColor) ? _tintColor : [super tintColor];\n  } else {\n    return _tintColor;\n  }\n}\n\n- (void)tintColorDidChange {\n  [self setNeedsDisplay];\n}\n\n- (void)setTextColor:(UIColor *)textColor {\n  _textColor = textColor;\n\n  [self setNeedsDisplay];\n}\n\n- (void)drawRect:(CGRect)rect {\n  CGContextRef context = UIGraphicsGetCurrentContext();\n\n  CGSize textSize = [self.text sizeWithFont:self.font];\n\n  // Used to suppress warning: Implicit conversion shortens 64-bit value into 32-bit value\n  const CGFloat pi = (CGFloat)M_PI;\n  const CGFloat kRadius = textSize.height / 2.f + (sUsesSolidTint ? 0.5f : 0);\n\n  // The following constant offsets are chosen to make the badge match the system badge dimensions\n  // pixel-for-pixel for the default font size. Any other font size is undefined as far as a\n  // standard, so we just use these constants for everything.g\n  CGFloat minX = CGRectGetMinX(rect) + (sUsesSolidTint ? 5.f : 4.f);\n  CGFloat maxX = CGRectGetMaxX(rect) - (sUsesSolidTint ? 6.f : 5.f);\n  CGFloat minY = CGRectGetMinY(rect) + (sUsesSolidTint ? 2.f : 3.5f);\n  CGFloat maxY = CGRectGetMaxY(rect) - (sUsesSolidTint ? 6.f : 6.5f);\n\n  if (sUsesSolidTint && self.text.length <= 1) {\n    // For single digit badges we nudge the left edge slightly to match with the system badge\n    // boundaries on iOS 7.\n    minX--;\n  }\n\n  CGContextSaveGState(context);\n\n  // Draw the main rounded rectangle\n  CGContextBeginPath(context);\n  CGContextSetFillColorWithColor(context, self.tintColor.CGColor);\n  CGContextAddArc(context, maxX-kRadius, minY+kRadius, kRadius, pi+(pi/2), 0, 0);\n  CGContextAddArc(context, maxX-kRadius, maxY-kRadius, kRadius, 0, pi/2, 0);\n  CGContextAddArc(context, minX+kRadius, maxY-kRadius, kRadius, pi/2, pi, 0);\n  CGContextAddArc(context, minX+kRadius, minY+kRadius, kRadius, pi, pi+pi/2, 0);\n  if (self.shadowColor) {\n    CGContextSetShadowWithColor(context, self.shadowOffset, self.shadowBlur, self.shadowColor.CGColor);\n  }\n  CGContextFillPath(context);\n\n  CGContextRestoreGState(context);\n\n  if (!sUsesSolidTint) {\n    // Add the gloss effect\n    CGContextSaveGState(context);\n\n    CGContextBeginPath(context);\n    CGContextAddArc(context, maxX-kRadius, minY+kRadius, kRadius, pi+(pi/2), 0, 0);\n    CGContextAddArc(context, minX+kRadius, minY+kRadius, kRadius, pi, pi+pi/2, 0);\n    CGContextAddRect(context, CGRectMake(minX, minY + kRadius,\n                                         rect.size.width - kRadius + 1, CGRectGetMidY(rect) - kRadius));\n    CGContextClip(context);\n    \n    size_t num_locations = 2;\n    CGFloat locations[] = { 0.0f, 1.f };\n    CGFloat components[] = {\n      1.f, 1.f, 1.f, 0.8f,\n      1.f, 1.f, 1.f, 0.0f };\n\n    CGColorSpaceRef cspace;\n    CGGradientRef gradient;\n    cspace = CGColorSpaceCreateDeviceRGB();\n    gradient = CGGradientCreateWithColorComponents (cspace, components, locations, num_locations);\n    \n    CGPoint sPoint, ePoint;\n    sPoint.x = 0;\n    sPoint.y = 4;\n    ePoint.x = 0;\n    ePoint.y = CGRectGetMidY(rect) - 2;\n    CGContextDrawLinearGradient (context, gradient, sPoint, ePoint, 0);\n    \n    CGColorSpaceRelease(cspace);\n    CGGradientRelease(gradient);\n\n    CGContextRestoreGState(context);\n\n    // Draw the border\n    CGContextBeginPath(context);\n    CGContextSetLineWidth(context, kBadgeLineSize);\n    CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);\n    CGContextAddArc(context, maxX-kRadius, minY+kRadius, kRadius, pi+(pi/2), 0, 0);\n    CGContextAddArc(context, maxX-kRadius, maxY-kRadius, kRadius, 0, pi/2, 0);\n    CGContextAddArc(context, minX+kRadius, maxY-kRadius, kRadius, pi/2, pi, 0);\n    CGContextAddArc(context, minX+kRadius, minY+kRadius, kRadius, pi, pi+pi/2, 0);\n    CGContextClosePath(context);\n    CGContextStrokePath(context);\n  }\n\n  // Draw text\n  [self.textColor set];\n  [self.text drawAtPoint:CGPointMake(floorf((rect.size.width - textSize.width) / 2.f) - 0.f,\n                                     floorf((rect.size.height - textSize.height) / 2.f) - 2.f)\n                withFont:self.font];\n}\n\n@end\n"
  },
  {
    "path": "src/badge/src/NimbusBadge.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally created by Roger Chapman\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * @defgroup NimbusBadge Nimbus Badge\n * @{\n *\n * <div id=\"github\" feature=\"badge\"></div>\n *\n * This Nimbus badge view is a UIView that draws a customizable notification badge-like view.\n *\n * @image html badge-iphone-example1.png \"Screenshot of a Nimbus badge on the iPhone\"\n *\n * <h2>Minimum Requirements</h2>\n *\n * Required frameworks:\n *\n * - Foundation.framework\n * - UIKit.framework\n *\n * Minimum Operating System: <b>iOS 4.0</b>\n *\n * Source located in <code>src/badge/src</code>\n *\n@code\n#import \"NimbusBadge.h\"\n@endcode\n *\n * <h2>Basic Use</h2>\n *\n * The badge view works much like UILabel. Once you've assigned text and configured the attributes\n * you should call sizeToFit to have the badge determine its ideal size.\n *\n@code\nNIBadgeView* badgeView = [[NIBadgeView alloc] initWithFrame:CGRectZero];\nbadgeView.text = @\"7\";\n[badgeView sizeToFit];\n[self.view addSubview:badgeView];\n@endcode\n *\n * @}\n */\n\n#import <Foundation/Foundation.h>\n\n#import \"NimbusCore.h\"\n#import \"NIBadgeView.h\""
  },
  {
    "path": "src/badge/unittests/NIBadgeTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusOverview.h\"\n\n@interface NIOverviewTests : XCTestCase\n@end\n\n\n@implementation NIOverviewTests\n\n\n- (void)testNothing {\n}\n\n@end\n"
  },
  {
    "path": "src/badge/unittests/NimbusBadgeTests-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": "src/collections/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework"
  },
  {
    "path": "src/collections/src/NICollectionViewActions.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"NimbusCore.h\"\n\n/**\n * The NICollectionViewActions class provides an interface for attaching actions to objects from a\n * NIActionsDataSource.\n *\n * <h2>Basic Use</h2>\n *\n * NIActionsDataSource and NICollectionViewActions cooperate to solve two related tasks: data\n * representation and user actions, respectively. A NIActionsDataSource provides objects and\n * NICollectionViewActions maintains a mapping of actions to these objects. The object's\n * attached actions are executed when the user interacts with the cell representing an object.\n *\n * <h2>Delegate Forwarding</h2>\n *\n * Your delegate implementation can call the listed collectionView: methods in order for the\n * collection view to respond to user actions. Notably shouldHighlightItemAtIndexPath: allows\n * cells to be highlighted only if the cell's object has an attached action.\n * didSelectItemAtIndexPath: will execute the object's attached tap actions.\n *\n * If you use the delegate forwarders your collection view's data source must conform to\n * NIActionsDataSource.\n *\n * @ingroup CollectionViewTools\n */\n@interface NICollectionViewActions : NIActions\n\n- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath;\n- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;\n\n@end\n\n/**\n * Asks the receiver whether the object at the given index path is actionable.\n *\n * collectionView.dataSource must be a NICollectionViewModel.\n *\n *    @returns YES if the object at the given index path is actionable.\n *    @fn NICollectionViewActions::collectionView:shouldHighlightItemAtIndexPath:\n */\n\n/**\n * Asks the receiver to perform the tap action for an object at the given indexPath.\n *\n * collectionView.dataSource must be a NICollectionViewModel.\n *\n *    @fn NICollectionViewActions::collectionView:didSelectItemAtIndexPath:\n */\n"
  },
  {
    "path": "src/collections/src/NICollectionViewActions.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICollectionViewActions.h\"\n\n#import \"NICollectionViewCellFactory.h\"\n#import \"NimbusCore.h\"\n#import \"NIActions+Subclassing.h\"\n#import <objc/runtime.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NICollectionViewActions\n\n\n#pragma mark - UICollectionViewDelegate\n\n- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath {\n  BOOL shouldHighlight = NO;\n\n  NIDASSERT([collectionView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]);\n  if ([collectionView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]) {\n    id object = [(id<NIActionsDataSource>)collectionView.dataSource objectAtIndexPath:indexPath];\n\n    if ([self isObjectActionable:object]) {\n      NIObjectActions* action = [self actionForObjectOrClassOfObject:object];\n\n      // If the cell is tappable, reflect that in the selection style.\n      if (nil != action.tapAction || nil != action.tapSelector\n          || nil != action.detailAction || nil != action.detailSelector\n          || nil != action.navigateAction || nil != action.navigateSelector) {\n        shouldHighlight = YES;\n      }\n    }\n  }\n\n  return shouldHighlight;\n}\n\n- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {\n  NIDASSERT([collectionView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]);\n  if ([collectionView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]) {\n    id object = [(id<NIActionsDataSource>)collectionView.dataSource objectAtIndexPath:indexPath];\n\n    if ([self isObjectActionable:object]) {\n      NIObjectActions* action = [self actionForObjectOrClassOfObject:object];\n\n      BOOL shouldDeselect = NO;\n      if (action.tapAction) {\n        // Tap actions can deselect the cell if they return YES.\n        shouldDeselect = action.tapAction(object, self.target, indexPath);\n      }\n      if (action.tapSelector && [self.target respondsToSelector:action.tapSelector]) {\n        NSMethodSignature *methodSignature = [self.target methodSignatureForSelector:action.tapSelector];\n        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];\n        invocation.selector = action.tapSelector;\n        if (methodSignature.numberOfArguments >= 3) {\n          [invocation setArgument:&object atIndex:2];\n        }\n        if (methodSignature.numberOfArguments >= 4) {\n          [invocation setArgument:&indexPath atIndex:3];\n        }\n        [invocation invokeWithTarget:self.target];\n\n        NSUInteger length = invocation.methodSignature.methodReturnLength;\n        if (length > 0) {\n          char *buffer = (void *)malloc(length);\n          memset(buffer, 0, sizeof(char) * length);\n          [invocation getReturnValue:buffer];\n          for (NSUInteger index = 0; index < length; ++index) {\n            if (buffer[index]) {\n              shouldDeselect = YES;\n              break;\n            }\n          }\n          free(buffer);\n        }\n      }\n\n      if (action.detailAction) {\n        // Tap actions can deselect the cell if they return YES.\n        action.detailAction(object, self.target, indexPath);\n      }\n      if (action.detailSelector && [self.target respondsToSelector:action.detailSelector]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n        [self.target performSelector:action.detailSelector withObject:object withObject:indexPath];\n#pragma clang diagnostic pop\n      }\n\n      if (action.navigateAction) {\n        // Tap actions can deselect the cell if they return YES.\n        action.navigateAction(object, self.target, indexPath);\n      }\n      if (action.navigateSelector && [self.target respondsToSelector:action.navigateSelector]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n        [self.target performSelector:action.navigateSelector withObject:object withObject:indexPath];\n#pragma clang diagnostic pop\n      }\n\n      if (shouldDeselect) {\n        [collectionView deselectItemAtIndexPath:indexPath animated:YES];\n      }\n    }\n  }\n}\n\n@end\n"
  },
  {
    "path": "src/collections/src/NICollectionViewCellFactory.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NICollectionViewModel.h\"\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n/**\n * A simple factory for creating collection view cells from objects.\n *\n * This factory provides a single method that accepts an object and returns a UICollectionViewCell\n * for use in a UICollectionView. A cell will only be returned if the object passed to the factory\n * conforms to the NICollectionViewCellObject protocol. The created cell should ideally conform to\n * the NICollectionViewCell protocol. If it does, the object will be passed to it via\n * @link NICollectionViewCell::shouldUpdateCellWithObject: shouldUpdateCellWithObject:@endlink\n * before the factory method returns.\n *\n * This factory is designed to be used with NICollectionViewModel, though one could easily use\n * it with other collection view data source implementations simply by providing nil for the\n * collection view model argument.\n *\n * If you instantiate an NICollectionViewCellFactory then you can provide explicit mappings from\n * objects to cells. This is helpful if the effort required to implement the NICollectionViewCell\n * protocol on an object outweighs the benefit of using the factory, i.e. when you want to map\n * simple types such as NSString to cells.\n *\n * @ingroup CollectionViewCellFactory\n */\n@interface NICollectionViewCellFactory : NSObject <NICollectionViewModelDelegate>\n\n/**\n * Creates a cell from a given object if and only if the object conforms to the\n * NICollectionViewCellObject protocol.\n *\n * This method signature matches the NICollectionViewModelDelegate method so that you can\n * set this factory as the model's delegate:\n *\n * @code\n// Must cast to id to avoid compiler warnings.\n_model.delegate = (id)[NICollectionViewCellFactory class];\n * @endcode\n *\n * If you would like to customize the factory's output, implement the model's delegate method\n * and call the factory method. Remember that if the factory doesn't know how to map\n * the object to a cell it will return nil.\n *\n * @code\n- (UICollectionViewCell *)collectionViewModel:(id<NICollectionViewModeling>)collectionViewModel\n                        cellForCollectionView:(UICollectionView *)collectionView\n                                  atIndexPath:(NSIndexPath *)indexPath\n                                   withObject:(id)object {\n  UICollectionViewCell* cell = [NICollectionViewCellFactory collectionViewModel:collectionViewModel\n                                                          cellForCollectionView:collectionView\n                                                                    atIndexPath:indexPath\n                                                                     withObject:object];\n  if (nil == cell) {\n    // Custom cell creation here.\n  }\n  return cell;\n}\n * @endcode\n */\n+ (UICollectionViewCell *)collectionViewModel:(id<NICollectionViewModeling>)collectionViewModel cellForCollectionView:(UICollectionView *)collectionView atIndexPath:(NSIndexPath *)indexPath withObject:(id)object;\n\n/**\n * Map an object's class to a cell's class.\n *\n * If an object implements the NICollectionViewCell protocol AND is found in this factory\n * mapping, the factory mapping will take precedence. This allows you to\n * explicitly override the mapping on a case-by-case basis.\n */\n- (void)mapObjectClass:(Class)objectClass toCellClass:(Class)collectionViewCellClass;\n\n/**\n * Returns the mapped cell class for an object at a given index path.\n *\n * Explicitly mapped classes in the receiver take precedence over implicitly mapped classes.\n *\n * This method is helpful when implementing layout calculation methods for your collection view. You\n * can fetch the cell class and then perform any selectors that are necessary for calculating the\n * dimensions of the cell before it is instantiated.\n */\n- (Class)collectionViewCellClassForItemAtIndexPath:(NSIndexPath *)indexPath model:(id<NICollectionViewModeling>)model;\n\n/**\n * Returns the mapped cell class for an object at a given index path.\n *\n * This method is helpful when implementing layout calculation methods for your collection view. You\n * can fetch the cell class and then perform any selectors that are necessary for calculating the\n * dimensions of the cell before it is instantiated.\n */\n+ (Class)collectionViewCellClassForItemAtIndexPath:(NSIndexPath *)indexPath model:(id<NICollectionViewModeling>)model;\n\n@end\n\n/**\n * The protocol for an object that can be used in the NICollectionViewCellFactory.\n *\n * @ingroup CollectionViewCellFactory\n */\n@protocol NICollectionViewCellObject <NSObject>\n@required\n\n/** The class of cell to be created when this object is passed to the cell factory. */\n- (Class)collectionViewCellClass;\n\n@end\n\n/**\n * The protocol for an object that can be used in the NICollectionViewCellFactory with Interface\n * Builder nibs.\n *\n * @ingroup CollectionViewCellFactory\n */\n@protocol NICollectionViewNibCellObject <NSObject>\n@required\n\n/** A nib that contains a collection view cell to display this object's contents. */\n- (UINib *)collectionViewCellNib;\n\n@end\n\n/**\n * The protocol for a cell created in the NICollectionViewCellFactory.\n *\n * Cells that implement this protocol are given the object that implemented the\n * NICollectionViewCellObject protocol and returned this cell's class name in\n * @link NICollectionViewCellObject::collectionViewCellClass collectionViewCellClass@endlink.\n *\n * @ingroup CollectionViewCellFactory\n */\n@protocol NICollectionViewCell <NSObject>\n@required\n\n/**\n * Called both when a cell is created and when it is reused.\n *\n * Implement this method to customize the cell's properties for display using the given object.\n */\n- (BOOL)shouldUpdateCellWithObject:(id)object;\n\n@optional\n\n/**\n * Asks the receiver whether the mapped object class should be appended to the reuse identifier\n * in order to create a unique cell.object identifier key.\n *\n * This is useful when you have a cell that is intended to be used by a variety of different\n * objects.\n */\n+ (BOOL)shouldAppendObjectClassToReuseIdentifier;\n\n@end\n\n/**\n * A protocol that objects may conform to in order to provide a custom suffix to the reuse\n * identifier of its cell.\n *\n * This is useful for objects that can support different configurations, such that cells updated\n * with an instance of the object can be reused only for objects supporting the same configuration.\n * This can be used as an optimization for objects that support dynamic configurations that would be\n * inefficient to reset during -prepareForReuse.\n */\n@protocol NICollectionViewCellReuseIdentifierExtension <NSObject>\n\n/**\n * A unique reuse identifier suffix to append to the reuse identifier of the cell.\n *\n * @note Classes conforming to this protocol may return nil or the empty string to opt out of the\n * suffix.\n */\n- (NSString *)reuseIdentifierSuffix;\n\n@end\n\n/**\n * A light-weight implementation of the NICollectionViewCellObject protocol.\n *\n * Use this object in cases where you can't set up a hard binding between an object and a cell,\n * or when you simply don't want to.\n *\n * For example, let's say that you want to show a cell that shows a loading indicator.\n * Rather than create a new interface, LoadMoreObject, simply for the cell and binding it\n * to the cell view, you can create an NICollectionViewCellObject and pass the class name of the cell.\n *\n@code\n[contents addObject:[NICollectionViewCellObject objectWithCellClass:[LoadMoreCell class]]];\n@endcode\n */\n@interface NICollectionViewCellObject : NSObject <NICollectionViewCellObject>\n\n// Designated initializer.\n- (id)initWithCellClass:(Class)collectionViewCellClass userInfo:(id)userInfo;\n- (id)initWithCellClass:(Class)collectionViewCellClass;\n\n+ (id)objectWithCellClass:(Class)collectionViewCellClass userInfo:(id)userInfo;\n+ (id)objectWithCellClass:(Class)collectionViewCellClass;\n\n@property (nonatomic, readonly, strong) id userInfo;\n\n@end\n\n/**\n * An object that can be used to populate information in the cell.\n *\n * @fn NICollectionViewCellObject::userInfo\n */\n\nAPI_DEPRECATED_END"
  },
  {
    "path": "src/collections/src/NICollectionViewCellFactory.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICollectionViewCellFactory.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NICollectionViewCellFactory()\n@property (nonatomic, copy) NSMutableDictionary* objectToCellMap;\n@property (nonatomic, copy) NSMutableSet* registeredObjectClasses;\n@end\n\n\n@implementation NICollectionViewCellFactory\n\n\n\n- (id)init {\n  if ((self = [super init])) {\n    _objectToCellMap = [[NSMutableDictionary alloc] init];\n    _registeredObjectClasses = [[NSMutableSet alloc] init];\n  }\n  return self;\n}\n\n+ (UICollectionViewCell *)cellWithClass:(Class)collectionViewCellClass\n                         collectionView:(UICollectionView *)collectionView\n                              indexPath:(NSIndexPath *)indexPath\n                                 object:(id)object {\n  UICollectionViewCell* cell = nil;\n\n  NSString* identifier = NSStringFromClass(collectionViewCellClass);\n\n  if ([collectionViewCellClass respondsToSelector:@selector(shouldAppendObjectClassToReuseIdentifier)]\n      && [collectionViewCellClass shouldAppendObjectClassToReuseIdentifier]) {\n    identifier = [identifier stringByAppendingFormat:@\".%@\", NSStringFromClass([object class])];\n  }\n\n  if ([object respondsToSelector:@selector(reuseIdentifierSuffix)]) {\n    NSString* suffix = [object reuseIdentifierSuffix];\n    if (suffix.length) {\n      identifier = [identifier stringByAppendingFormat:@\".%@\", suffix];\n    }\n  }\n\n  [collectionView registerClass:collectionViewCellClass forCellWithReuseIdentifier:identifier];\n\n  cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];\n\n  // Allow the cell to configure itself with the object's information.\n  if ([cell respondsToSelector:@selector(shouldUpdateCellWithObject:)]) {\n    [(id<NICollectionViewCell>)cell shouldUpdateCellWithObject:object];\n  }\n\n  return cell;\n}\n\n+ (UICollectionViewCell *)cellWithNib:(UINib *)collectionViewCellNib\n                       collectionView:(UICollectionView *)collectionView\n                            indexPath:(NSIndexPath *)indexPath\n                               object:(id)object {\n  UICollectionViewCell* cell = nil;\n\n  NSString* identifier = NSStringFromClass([object class]);\n\n  if ([object respondsToSelector:@selector(reuseIdentifierSuffix)]) {\n    NSString* suffix = [object reuseIdentifierSuffix];\n    if (suffix.length) {\n      identifier = [identifier stringByAppendingFormat:@\".%@\", suffix];\n    }\n  }\n\n  [collectionView registerNib:collectionViewCellNib forCellWithReuseIdentifier:identifier];\n\n  cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];\n\n  // Allow the cell to configure itself with the object's information.\n  if ([cell respondsToSelector:@selector(shouldUpdateCellWithObject:)]) {\n    [(id<NICollectionViewCell>)cell shouldUpdateCellWithObject:object];\n  }\n\n  return cell;\n}\n\n+ (UICollectionViewCell *)collectionViewModel:(id<NICollectionViewModeling>)collectionViewModel\n                        cellForCollectionView:(UICollectionView *)collectionView\n                                  atIndexPath:(NSIndexPath *)indexPath\n                                   withObject:(id)object {\n  UICollectionViewCell* cell = nil;\n\n  // Only NICollectionViewCellObject-conformant objects may pass.\n  if ([object respondsToSelector:@selector(collectionViewCellClass)]) {\n    Class collectionViewCellClass = [object collectionViewCellClass];\n    cell = [self cellWithClass:collectionViewCellClass collectionView:collectionView indexPath:indexPath object:object];\n\n  } else if ([object respondsToSelector:@selector(collectionViewCellNib)]) {\n    UINib* nib = [object collectionViewCellNib];\n    cell = [self cellWithNib:nib collectionView:collectionView indexPath:indexPath object:object];\n  }\n\n  // If this assertion fires then your app is about to crash. You need to either add an explicit\n  // binding in a NICollectionViewCellFactory object or implement either\n  // NICollectionViewCellObject or NICollectionViewNibCellObject on this object and return a cell\n  // class.\n  NIDASSERT(nil != cell);\n\n  return cell;\n}\n\n- (Class)collectionViewCellClassFromObject:(id)object {\n  if (nil == object) {\n    return nil;\n  }\n  Class objectClass = [object class];\n  Class collectionViewCellClass = [self.objectToCellMap objectForKey:objectClass];\n\n  BOOL hasExplicitMapping = (nil != collectionViewCellClass && collectionViewCellClass != [NSNull class]);\n\n  if (!hasExplicitMapping && [object respondsToSelector:@selector(collectionViewCellClass)]) {\n    collectionViewCellClass = [object collectionViewCellClass];\n  }\n\n  if (nil == collectionViewCellClass) {\n    collectionViewCellClass = [NIActions objectFromKeyClass:objectClass map:self.objectToCellMap];\n  }\n\n  return collectionViewCellClass;\n}\n\n- (UICollectionViewCell *)collectionViewModel:(id<NICollectionViewModeling>)collectionViewModel\n                   cellForCollectionView:(UICollectionView *)collectionView\n                        atIndexPath:(NSIndexPath *)indexPath\n                         withObject:(id)object {\n  UICollectionViewCell* cell = nil;\n\n  Class collectionViewCellClass = [self collectionViewCellClassFromObject:object];\n\n  if (nil != collectionViewCellClass) {\n    cell = [[self class] cellWithClass:collectionViewCellClass collectionView:collectionView indexPath:indexPath object:object];\n\n  } else if ([object respondsToSelector:@selector(collectionViewCellNib)]) {\n    UINib* nib = [object collectionViewCellNib];\n    cell = [[self class] cellWithNib:nib collectionView:collectionView indexPath:indexPath object:object];\n  }\n\n  // If this assertion fires then your app is about to crash. You need to either add an explicit\n  // binding in a NICollectionViewCellFactory object or implement the NICollectionViewCellObject\n  // protocol on this object and return a cell class.\n  NIDASSERT(nil != cell);\n\n  return cell;\n}\n\n- (void)mapObjectClass:(Class)objectClass toCellClass:(Class)collectionViewCellClass {\n  [self.objectToCellMap setObject:collectionViewCellClass forKey:(id<NSCopying>)objectClass];\n}\n\n- (Class)collectionViewCellClassForItemAtIndexPath:(NSIndexPath *)indexPath model:(id<NICollectionViewModeling>)model {\n  id object = [model objectAtIndexPath:indexPath];\n  return [self collectionViewCellClassFromObject:object];\n}\n\n+ (Class)collectionViewCellClassForItemAtIndexPath:(NSIndexPath *)indexPath model:(id<NICollectionViewModeling>)model {\n  id object = [model objectAtIndexPath:indexPath];\n  Class collectionViewCellClass = nil;\n  if ([object respondsToSelector:@selector(collectionViewCellClass)]) {\n    collectionViewCellClass = [object collectionViewCellClass];\n  }\n  return collectionViewCellClass;\n}\n\n@end\n\n\n@interface NICollectionViewCellObject()\n@property (nonatomic, assign) Class collectionViewCellClass;\n@property (nonatomic, strong) id userInfo;\n@end\n\n\n@implementation NICollectionViewCellObject\n\n\n\n- (id)initWithCellClass:(Class)collectionViewCellClass userInfo:(id)userInfo {\n  if ((self = [super init])) {\n    _collectionViewCellClass = collectionViewCellClass;\n    _userInfo = userInfo;\n  }\n  return self;\n}\n\n- (id)initWithCellClass:(Class)collectionViewCellClass {\n  return [self initWithCellClass:collectionViewCellClass userInfo:nil];\n}\n\n+ (id)objectWithCellClass:(Class)collectionViewCellClass userInfo:(id)userInfo {\n  return [[self alloc] initWithCellClass:collectionViewCellClass userInfo:userInfo];\n}\n\n+ (id)objectWithCellClass:(Class)collectionViewCellClass {\n  return [[self alloc] initWithCellClass:collectionViewCellClass userInfo:nil];\n}\n\n@end\n"
  },
  {
    "path": "src/collections/src/NICollectionViewModel+Private.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"NICollectionViewModel.h\"\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n@interface NICollectionViewModelSection : NSObject\n\n+ (id)section;\n\n@property (nonatomic, copy) NSString* headerTitle;\n@property (nonatomic, copy) NSString* footerTitle;\n@property (nonatomic, strong) NSArray* rows;\n\n@end\n\n@interface NICollectionViewModel()\n\n@property (nonatomic, strong) NSArray* sections; // Array of NICollectionViewModelSection\n@property (nonatomic, strong) NSArray* sectionIndexTitles;\n@property (nonatomic, strong) NSDictionary* sectionPrefixToSectionIndex;\n\n- (void)_resetCompiledData;\n- (void)_compileDataWithListArray:(NSArray *)listArray;\n- (void)_compileDataWithSectionedArray:(NSArray *)sectionedArray;\n- (void)_setSectionsWithArray:(NSArray *)sectionsArray;\n- (NICollectionViewModelSection *)_sectionFromListArray:(NSArray *)rows;\n\n@end\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/collections/src/NICollectionViewModel.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIActions.h\"  /* for NIActionsDataSource */\n#import \"NIPreprocessorMacros.h\" /* for weak */\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n@protocol NICollectionViewModelDelegate;\n\n\n#pragma mark Sectioned Array Objects\n\n// Classes used when creating NICollectionViewModels.\n@class NICollectionViewModelFooter;  // Provides the information for a footer.\n\n/**\n * A protocol that declares the interface for a non-mutable collection view model.\n *\n * A default implementation of this protocol is provided with the NICollectionViewModel class.\n * If you want to customize the implementation of your collection view model while keeping the base\n * interface the same, conform to this protocol and implement the declared methods at minimum.\n *\n * The model class that conforms to this protocol is intended to allow you to easily create a data\n * source for a UICollectionView without having to implement the UICollectionViewDataSource methods\n * in your controller.\n *\n * @ingroup CollectionViewModels\n */\n@protocol NICollectionViewModeling <NIActionsDataSource, UICollectionViewDataSource, UICollectionViewDataSourcePrefetching>\n\n#pragma mark Accessing Objects\n\n- (nullable NSIndexPath *)indexPathForObject:(nonnull id)object;\n\n#pragma mark Creating Collection View Cells\n\n@property (nonatomic, weak, nullable) id<NICollectionViewModelDelegate> delegate;\n\n@end\n\n/**\n * A non-mutable collection view model object that provides a lightweight implementation of\n * the NICollectionViewModeling protocol.\n *\n * This base class is non-mutable, much like an NSArray. You must initialize this model with\n * the contents when you create it.\n *\n * This model simply manages the data relationship with your collection view. It is up to you to\n * implement the collection view's layout object.\n *\n * @ingroup CollectionViewModels\n */\n@interface NICollectionViewModel : NSObject <NICollectionViewModeling>\n\n- (nonnull id)initWithDelegate:(nullable id<NICollectionViewModelDelegate>)delegate NS_DESIGNATED_INITIALIZER;\n\n- (nonnull id)initWithListArray:(nonnull NSArray *)listArray delegate:(nullable id<NICollectionViewModelDelegate>)delegate;\n\n// Each NSString in the array starts a new section. Any other object is a new row (with exception of certain model-specific objects).\n- (nonnull id)initWithSectionedArray:(nonnull NSArray *)sectionedArray delegate:(nullable id<NICollectionViewModelDelegate>)delegate;\n\n// Redeclaring for property autosynthesis.\n@property (nonatomic, weak, nullable) id<NICollectionViewModelDelegate> delegate;\n\n@end\n\n/**\n * A protocol for NICollectionViewModel to fetch rows to be displayed for the collection view.\n *\n * @ingroup CollectionViewModels\n */\n@protocol NICollectionViewModelDelegate <NSObject>\n@required\n\n/**\n * Fetches a collection view cell at a given index path with a given object.\n *\n * The implementation of this method will generally use object to customize the cell.\n */\n- (nonnull UICollectionViewCell *)collectionViewModel:(nonnull id<NICollectionViewModeling>)collectionViewModel\n                                cellForCollectionView:(nonnull UICollectionView *)collectionView\n                                          atIndexPath:(nonnull NSIndexPath *)indexPath\n                                           withObject:(nonnull id)object;\n\n@optional\n\n/**\n * Fetches a supplementary collection view element at a given indexPath.\n *\n * The value of the kind property and indexPath are implementation-dependent\n * based on the type of UICollectionViewLayout being used.\n */\n- (nonnull UICollectionReusableView *)collectionViewModel:(nonnull id<NICollectionViewModeling>)collectionViewModel\n                                           collectionView:(nonnull UICollectionView *)collectionView\n                        viewForSupplementaryElementOfKind:(nonnull NSString *)kind\n                                              atIndexPath:(nonnull NSIndexPath *)indexPath;\n\n/**\n * Prefetch one or more collection view cells at given index paths with given objects.\n */\n- (void)collectionViewModel:(nonnull id<NICollectionViewModeling>)collectionViewModel\n               collectionView:(nonnull UICollectionView *)collectionView\n    prefetchItemsAtIndexPaths:(nonnull NSArray<NSIndexPath *> *)indexPaths\n                  withObjects:(nonnull NSArray<id> *)objects NS_AVAILABLE_IOS(10_0);\n\n/**\n * Cancel the running prefetching task for one or more collection view cells at given index paths with given objects.\n */\n- (void)collectionViewModel:(nonnull id<NICollectionViewModeling>)collectionViewModel\n                        collectionView:(nonnull UICollectionView *)collectionView\n    cancelPrefetchingItemsAtIndexPaths:(nonnull NSArray<NSIndexPath *> *)indexPaths\n                           withObjects:(nonnull NSArray<id> *)objects NS_AVAILABLE_IOS(10_0);\n\n@end\n\n/**\n * An object used in sectioned arrays to denote a section footer title.\n *\n * Meant to be used in a sectioned array for NICollectionViewModel.\n *\n * <h3>Example</h3>\n *\n * @code\n *  [NICollectionViewModelFooter footerWithTitle:@\"Footer\"]\n * @endcode\n */\n@interface NICollectionViewModelFooter : NSObject\n\n+ (nonnull id)footerWithTitle:(nonnull NSString *)title;\n- (nonnull id)initWithTitle:(nonnull NSString *)title;\n\n@property (nonatomic, copy, nonnull) NSString* title;\n\n@end\n\n/** @name Creating Collection View Models */\n\n/**\n * Initializes a newly allocated static model with the given delegate and empty contents.\n *\n * This method can be used to create an empty model.\n *\n * @fn NICollectionViewModel::initWithDelegate:\n */\n\n/**\n * Initializes a newly allocated static model with the contents of a list array.\n *\n * A list array is a one-dimensional array that defines a flat list of rows. There will be\n * no sectioning of contents in any way.\n *\n * <h3>Example</h3>\n *\n * @code\n * NSArray* contents =\n * [NSArray arrayWithObjects:\n *  [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n *  [NSDictionary dictionaryWithObject:@\"Row 2\" forKey:@\"title\"],\n *  [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n *  nil];\n * [[NICollectionViewModel alloc] initWithListArray:contents delegate:self];\n * @endcode\n *\n * @fn NICollectionViewModel::initWithListArray:delegate:\n */\n\n/**\n * Initializes a newly allocated static model with the contents of a sectioned array.\n *\n * A sectioned array is a one-dimensional array that defines a list of sections and each\n * section's contents. Each NSString begins a new section and any other object defines a\n * row for the current section.\n *\n * <h3>Example</h3>\n *\n * @code\n * NSArray* contents =\n * [NSArray arrayWithObjects:\n *  @\"Section 1\",\n *  [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n *  [NSDictionary dictionaryWithObject:@\"Row 2\" forKey:@\"title\"],\n *  @\"Section 2\",\n *  // This section is empty.\n *  @\"Section 3\",\n *  [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n *  [NICollectionViewModelFooter footerWithTitle:@\"Footer\"],\n *  nil];\n * [[NICollectionViewModel alloc] initWithSectionedArray:contents delegate:self];\n * @endcode\n *\n * @fn NICollectionViewModel::initWithSectionedArray:delegate:\n */\n\n\n/** @name Accessing Objects */\n\n/**\n * Returns the object at the given index path.\n *\n * If no object exists at the given index path (an invalid index path, for example) then nil\n * will be returned.\n *\n * @fn NICollectionViewModel::objectAtIndexPath:\n */\n\n/**\n * Returns the index path of the given object within the model.\n *\n * If the model does not contain the object then nil will be returned.\n *\n * @fn NICollectionViewModel::indexPathForObject:\n */\n\n\n/** @name Creating Collection View Cells */\n\n/**\n * A delegate used to fetch collection view cells for the data source.\n *\n * @fn NICollectionViewModel::delegate\n */\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/collections/src/NICollectionViewModel.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICollectionViewModel.h\"\n\n#import \"NICollectionViewModel+Private.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NICollectionViewModel\n\n\n\n- (id)initWithDelegate:(id<NICollectionViewModelDelegate>)delegate {\n  if ((self = [super init])) {\n    self.delegate = delegate;\n\n    [self _resetCompiledData];\n  }\n  return self;\n}\n\n- (id)initWithListArray:(NSArray *)listArray delegate:(id<NICollectionViewModelDelegate>)delegate {\n  if ((self = [self initWithDelegate:delegate])) {\n    [self _compileDataWithListArray:listArray];\n  }\n  return self;\n}\n\n- (id)initWithSectionedArray:(NSArray *)sectionedArray delegate:(id<NICollectionViewModelDelegate>)delegate {\n  if ((self = [self initWithDelegate:delegate])) {\n    [self _compileDataWithSectionedArray:sectionedArray];\n  }\n  return self;\n}\n\n- (id)init {\n  return [self initWithDelegate:nil];\n}\n\n#pragma mark - Compiling Data\n\n\n- (void)_resetCompiledData {\n  [self _setSectionsWithArray:nil];\n  self.sectionIndexTitles = nil;\n  self.sectionPrefixToSectionIndex = nil;\n}\n\n- (NICollectionViewModelSection *)_sectionFromListArray:(NSArray *)rows {\n  NICollectionViewModelSection* section = [NICollectionViewModelSection section];\n  section.rows = rows;\n  return section;\n}\n\n- (void)_compileDataWithListArray:(NSArray *)listArray {\n  [self _resetCompiledData];\n\n  if (nil != listArray) {\n    NICollectionViewModelSection* section = [self _sectionFromListArray:listArray];\n    [self _setSectionsWithArray:@[ section ]];\n  }\n}\n\n- (void)_compileDataWithSectionedArray:(NSArray *)sectionedArray {\n  [self _resetCompiledData];\n\n  NSMutableArray* sections = [NSMutableArray array];\n\n  NSString* currentSectionHeaderTitle = nil;\n  NSString* currentSectionFooterTitle = nil;\n  NSMutableArray* currentSectionRows = nil;\n\n  for (id object in sectionedArray) {\n    BOOL isSection = [object isKindOfClass:[NSString class]];\n    BOOL isSectionFooter = [object isKindOfClass:[NICollectionViewModelFooter class]];\n\n    NSString* nextSectionHeaderTitle = nil;\n\n    if (isSection) {\n      nextSectionHeaderTitle = object;\n\n    } else if (isSectionFooter) {\n      NICollectionViewModelFooter* footer = object;\n      currentSectionFooterTitle = footer.title;\n\n    } else {\n      if (nil == currentSectionRows) {\n        currentSectionRows = [[NSMutableArray alloc] init];\n      }\n      [currentSectionRows addObject:object];\n    }\n\n    // A section footer or title has been encountered,\n    if (nil != nextSectionHeaderTitle || nil != currentSectionFooterTitle) {\n      if (nil != currentSectionHeaderTitle\n          || nil != currentSectionFooterTitle\n          || nil != currentSectionRows) {\n        NICollectionViewModelSection* section = [NICollectionViewModelSection section];\n        section.headerTitle = currentSectionHeaderTitle;\n        section.footerTitle = currentSectionFooterTitle;\n        section.rows = currentSectionRows;\n        [sections addObject:section];\n      }\n\n      currentSectionRows = nil;\n      currentSectionHeaderTitle = nextSectionHeaderTitle;\n      currentSectionFooterTitle = nil;\n    }\n  }\n\n  // Commit any unfinished sections.\n  if ([currentSectionRows count] > 0 || nil != currentSectionHeaderTitle) {\n    NICollectionViewModelSection* section = [NICollectionViewModelSection section];\n    section.headerTitle = currentSectionHeaderTitle;\n    section.footerTitle = currentSectionFooterTitle;\n    section.rows = currentSectionRows;\n    [sections addObject:section];\n  }\n  currentSectionRows = nil;\n\n  // Update the compiled information for this data source.\n  [self _setSectionsWithArray:sections];\n}\n\n- (void)_setSectionsWithArray:(NSArray *)sectionsArray {\n  self.sections = sectionsArray;\n}\n\n#pragma mark - UICollectionViewDataSource\n\n\n- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {\n  return self.sections.count;\n}\n\n- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {\n  NIDASSERT((NSUInteger)section < self.sections.count || 0 == self.sections.count);\n  if ((NSUInteger)section < self.sections.count) {\n    return [[[self.sections objectAtIndex:section] rows] count];\n\n  } else {\n    return 0;\n  }\n}\n\n- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {\n  id object = [self objectAtIndexPath:indexPath];\n\n  return [self.delegate collectionViewModel:self\n                      cellForCollectionView:collectionView\n                                atIndexPath:indexPath\n                                 withObject:object];\n}\n\n- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {\n  if ([self.delegate respondsToSelector:\n       @selector(collectionViewModel:collectionView:viewForSupplementaryElementOfKind:atIndexPath:)]) {\n    return [self.delegate collectionViewModel:self\n                               collectionView:collectionView\n            viewForSupplementaryElementOfKind:kind\n                                  atIndexPath:indexPath];\n  }\n  return nil;\n}\n\n#pragma mark - UICollectionViewDataSourcePrefetching\n\n- (void)collectionView:(UICollectionView *)collectionView prefetchItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths {\n  NSMutableArray<id>* objects = [NSMutableArray array];\n  for (NSIndexPath* indexPath in indexPaths) {\n    id object = [self objectAtIndexPath:indexPath];\n    [objects addObject:object];\n  }\n  \n  [self.delegate collectionViewModel:self collectionView:collectionView prefetchItemsAtIndexPaths:indexPaths withObjects:objects];\n}\n\n- (void)collectionView:(UICollectionView *)collectionView cancelPrefetchingForItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths {\n  NSMutableArray<id>* objects = [NSMutableArray array];\n  for (NSIndexPath* indexPath in indexPaths) {\n    id object = [self objectAtIndexPath:indexPath];\n    [objects addObject:object];\n  }\n\n  [self.delegate collectionViewModel:self collectionView:collectionView cancelPrefetchingItemsAtIndexPaths:indexPaths withObjects:objects];\n}\n\n#pragma mark - Public\n\n\n- (id)objectAtIndexPath:(NSIndexPath *)indexPath {\n  if (nil == indexPath) {\n    return nil;\n  }\n\n  NSInteger section = [indexPath section];\n  NSInteger row = [indexPath row];\n\n  id object = nil;\n\n  NIDASSERT((NSUInteger)section < self.sections.count);\n  if ((NSUInteger)section < self.sections.count) {\n    NSArray* rows = [[self.sections objectAtIndex:section] rows];\n\n    NIDASSERT((NSUInteger)row < rows.count);\n    if ((NSUInteger)row < rows.count) {\n      object = [rows objectAtIndex:row];\n    }\n  }\n\n  return object;\n}\n\n- (NSIndexPath *)indexPathForObject:(id)object {\n  if (nil == object) {\n    return nil;\n  }\n\n  NSArray *sections = self.sections;\n  for (NSUInteger sectionIndex = 0; sectionIndex < [sections count]; sectionIndex++) {\n    NSArray* rows = [[sections objectAtIndex:sectionIndex] rows];\n    for (NSUInteger rowIndex = 0; rowIndex < [rows count]; rowIndex++) {\n      if ([object isEqual:[rows objectAtIndex:rowIndex]]) {\n        return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];\n      }\n    }\n  }\n\n  return nil;\n}\n\n- (NSString *)description {\n  NSMutableString* result = [[super description] mutableCopy];\n  [result appendString:@\" sections: \\n\"];\n  for (NICollectionViewModelSection *section in _sections) {\n    [result appendFormat:@\"section headerTitle: %@ footerTitle: %@\\n\", section.headerTitle, section.footerTitle];\n    [result appendFormat:@\"section rows: %@\\n\", section.rows];\n  }\n\n  [result appendFormat:@\"sectionIndexTitles: %@\", _sectionIndexTitles];\n  return result;\n}\n\n@end\n\n\n@implementation NICollectionViewModelFooter\n\n\n\n+ (NICollectionViewModelFooter *)footerWithTitle:(NSString *)title {\n  return [[self alloc] initWithTitle:title];\n}\n\n- (id)initWithTitle:(NSString *)title {\n  if ((self = [super init])) {\n    self.title = title;\n  }\n  return self;\n}\n\n@end\n\n\n@implementation NICollectionViewModelSection\n\n\n\n+ (id)section {\n  return [[self alloc] init];\n}\n\n@end\n"
  },
  {
    "path": "src/collections/src/NIMutableCollectionViewModel+Private.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n\n#import \"NIMutableCollectionViewModel.h\"\n#import \"NICollectionViewModel+Private.h\"\n\n@interface NIMutableCollectionViewModel (Private)\n\n@property (nonatomic, strong) NSMutableArray* sections; // Array of NICollectionViewModelSection\n\n@end\n\n\n@interface NICollectionViewModelSection (Mutable)\n\n- (NSMutableArray *)mutableRows;\n\n@end\n"
  },
  {
    "path": "src/collections/src/NIMutableCollectionViewModel.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICollectionViewModel.h\"\n\n/**\n * A protocol that declares the interface for a mutable collection view model.\n *\n * A default implementation of this protocol is provided with the NIMutableCollectionViewModel\n * class. If you want to customize the implementation of your collection view model while keeping\n * the base interface the same, conform to this protocol and implement the declared methods at\n * minimum.\n *\n * When modifications are made to the model there are two ways to reflect the changes in the\n * collection view.\n *\n * - Call reloadData on the collection view. This is the most destructive way to update the\n *   collection view.\n * - Call insert/delete/reload methods on the collection view with the returned index path arrays.\n *\n * The latter option is the recommended approach to adding new cells to a collection view. Each\n * method in the mutable collection view model returns a data structure that can be used to inform\n * the collection view of the exact modifications that have been made to the model.\n *\n * Example of adding a new section:\n @code\n // Appends a new section to the end of the model.\n NSIndexSet* indexSet = [self.model addSectionWithTitle:@\"New section\"];\n\n // Appends a cell to the last section in the model (in this case, the new section we just created).\n [self.model addObject:[TestTextCollectionViewCellObject objectWithTitle:@\"A cell\"]];\n\n // Inform the collection view that we've modified the model.\n [self.collectionView insertSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];\n @endcode\n *\n * @ingroup CollectionViewModels\n */\n@protocol NIMutableCollectionViewModeling <NICollectionViewModeling>\n\n- (NSArray *)addObject:(id)object;\n- (NSArray *)addObject:(id)object toSection:(NSUInteger)section;\n- (NSArray *)addObjectsFromArray:(NSArray *)array;\n- (NSArray *)insertObject:(id)object atRow:(NSUInteger)row inSection:(NSUInteger)section;\n- (NSArray *)removeObjectAtIndexPath:(NSIndexPath *)indexPath;\n\n- (NSIndexSet *)addSectionWithTitle:(NSString *)title;\n- (NSIndexSet *)insertSectionWithTitle:(NSString *)title atIndex:(NSUInteger)index;\n- (NSIndexSet *)removeSectionAtIndex:(NSUInteger)index;\n\n@end\n\n/**\n * A non-mutable collection view model object that provides a lightweight implementation of\n * the NIMutableCollectionViewModeling protocol.\n *\n * @ingroup CollectionViewModels\n */\n@interface NIMutableCollectionViewModel : NICollectionViewModel <NIMutableCollectionViewModeling>\n@end\n\n/** @name Modifying Objects */\n\n/**\n * Appends an object to the last section.\n *\n * If no sections exist, a section will be created without a title and the object will be added to\n * this new section.\n *\n * @param object The object to append to the last section.\n * @returns An array with a single NSIndexPath representing the index path of the new object\n *               in the model.\n * @fn NIMutableCollectionViewModel::addObject:\n */\n\n/**\n * Appends an object to the end of the given section.\n *\n * @param object The object to append to the section.\n * @param section The index of the section to which this object should be appended.\n * @returns An array with a single NSIndexPath representing the index path of the new object\n *               in the model.\n * @fn NIMutableCollectionViewModel::addObject:toSection:\n */\n\n/**\n * Appends an array of objects to the last section.\n *\n * If no section exists, a section will be created without a title and the objects will be added to\n * this new section.\n *\n * @param array The array of objects to append to the last section.\n * @returns An array of NSIndexPath objects representing the index paths of the objects in the\n *               model.\n * @fn NIMutableCollectionViewModel::addObjectsFromArray:\n */\n\n/**\n * Inserts an object into the given section at the given row.\n *\n * @param object The object to append to the section.\n * @param row The row within the section at which to insert the object.\n * @param section The index of the section in which the object should be inserted.\n * @returns An array with a single NSIndexPath representing the index path of the new object\n *               in the model.\n * @fn NIMutableCollectionViewModel::insertObject:atRow:inSection:\n */\n\n/**\n * Removes an object at the given index path.\n *\n * If the index path does not represent a valid object then a debug assertion will fire and the\n * method will return nil without removing any object.\n *\n * @param indexPath The index path at which to remove a single object.\n * @returns An array with a single NSIndexPath representing the index path of the object that\n *               was removed from the model, or nil if no object exists at the given index path.\n * @fn NIMutableCollectionViewModel::removeObjectAtIndexPath:\n */\n\n/** @name Modifying Sections */\n\n/**\n * Appends a section with a given title to the model.\n *\n * @param title The title of the new section.\n * @returns An index set with a single index representing the index of the new section.\n * @fn NIMutableCollectionViewModel::addSectionWithTitle:\n */\n\n/**\n * Inserts a section with a given title to the model at the given index.\n *\n * @param title The title of the new section.\n * @param index The index in the model at which to add the new section.\n * @returns An index set with a single index representing the index of the new section.\n * @fn NIMutableCollectionViewModel::insertSectionWithTitle:atIndex:\n */\n\n/**\n * Removes a section at the given index.\n *\n * @param index The index in the model of the section to remove.\n * @returns An index set with a single index representing the index of the removed section.\n * @fn NIMutableCollectionViewModel::removeSectionAtIndex:\n */\n"
  },
  {
    "path": "src/collections/src/NIMutableCollectionViewModel.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIMutableCollectionViewModel.h\"\n\n#import \"NICollectionViewModel.h\"\n#import \"NICollectionViewModel+Private.h\"\n#import \"NIMutableCollectionViewModel+Private.h\"\n#import \"NimbusCore.h\"\n\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n\n@implementation NIMutableCollectionViewModel\n\n\n#pragma mark - Public\n\n\n- (NSArray *)addObject:(id)object {\n  NICollectionViewModelSection* section = self.sections.count == 0 ? [self _appendSection] : self.sections.lastObject;\n  [section.mutableRows addObject:object];\n  return [NSArray arrayWithObject:[NSIndexPath indexPathForRow:section.mutableRows.count - 1\n                                                     inSection:self.sections.count - 1]];\n}\n\n- (NSArray *)addObject:(id)object toSection:(NSUInteger)sectionIndex {\n  NIDASSERT(sectionIndex >= 0 && sectionIndex < self.sections.count);\n  NICollectionViewModelSection *section = [self.sections objectAtIndex:sectionIndex];\n  [section.mutableRows addObject:object];\n  return [NSArray arrayWithObject:[NSIndexPath indexPathForRow:section.mutableRows.count - 1\n                                                     inSection:sectionIndex]];\n}\n\n- (NSArray *)addObjectsFromArray:(NSArray *)array {\n  NSMutableArray* indices = [NSMutableArray array];\n  for (id object in array) {\n    [indices addObject:[[self addObject:object] objectAtIndex:0]];\n  }\n  return indices;\n}\n\n- (NSArray *)insertObject:(id)object atRow:(NSUInteger)row inSection:(NSUInteger)sectionIndex {\n  NIDASSERT(sectionIndex >= 0 && sectionIndex < self.sections.count);\n  NICollectionViewModelSection *section = [self.sections objectAtIndex:sectionIndex];\n  [section.mutableRows insertObject:object atIndex:row];\n  return [NSArray arrayWithObject:[NSIndexPath indexPathForRow:row inSection:sectionIndex]];\n}\n\n- (NSArray *)removeObjectAtIndexPath:(NSIndexPath *)indexPath {\n  NIDASSERT(indexPath.section < (NSInteger)self.sections.count);\n  if (indexPath.section >= (NSInteger)self.sections.count) {\n    return nil;\n  }\n  NICollectionViewModelSection* section = [self.sections objectAtIndex:indexPath.section];\n  NIDASSERT(indexPath.row < (NSInteger)section.mutableRows.count);\n  if (indexPath.row >= (NSInteger)section.mutableRows.count) {\n    return nil;\n  }\n  [section.mutableRows removeObjectAtIndex:indexPath.row];\n  return [NSArray arrayWithObject:indexPath];\n}\n\n- (NSIndexSet *)addSectionWithTitle:(NSString *)title {\n  NICollectionViewModelSection* section = [self _appendSection];\n  section.headerTitle = title;\n  return [NSIndexSet indexSetWithIndex:self.sections.count - 1];\n}\n\n- (NSIndexSet *)insertSectionWithTitle:(NSString *)title atIndex:(NSUInteger)index {\n  NICollectionViewModelSection* section = [self _insertSectionAtIndex:index];\n  section.headerTitle = title;\n  return [NSIndexSet indexSetWithIndex:index];\n}\n\n- (NSIndexSet *)removeSectionAtIndex:(NSUInteger)index {\n  NIDASSERT(index >= 0 && index < self.sections.count);\n  [self.sections removeObjectAtIndex:index];\n  return [NSIndexSet indexSetWithIndex:index];\n}\n\n#pragma mark - Private\n\n\n- (NICollectionViewModelSection *)_appendSection {\n  if (nil == self.sections) {\n    self.sections = [NSMutableArray array];\n  }\n  NICollectionViewModelSection* section = nil;\n  section = [[NICollectionViewModelSection alloc] init];\n  section.rows = [NSMutableArray array];\n  [self.sections addObject:section];\n  return section;\n}\n\n- (NICollectionViewModelSection *)_insertSectionAtIndex:(NSUInteger)index {\n  if (nil == self.sections) {\n    self.sections = [NSMutableArray array];\n  }\n  NICollectionViewModelSection* section = nil;\n  section = [[NICollectionViewModelSection alloc] init];\n  section.rows = [NSMutableArray array];\n  NIDASSERT(index >= 0 && index <= self.sections.count);\n  [self.sections insertObject:section atIndex:index];\n  return section;\n}\n\n- (void)_setSectionsWithArray:(NSArray *)sectionsArray {\n  if ([sectionsArray isKindOfClass:[NSMutableArray class]]) {\n    self.sections = (NSMutableArray *)sectionsArray;\n  } else {\n    self.sections = [sectionsArray mutableCopy];\n  }\n}\n\n- (NICollectionViewModelSection *)_sectionFromListArray:(NSArray *)rows {\n  NICollectionViewModelSection* section = [NICollectionViewModelSection section];\n  section.rows = [rows isKindOfClass:[NSMutableArray class]] ? rows : [rows mutableCopy];\n  return section;\n}\n\n@end\n\n\n@implementation NICollectionViewModelSection (Mutable)\n\n\n- (NSMutableArray *)mutableRows {\n  NIDASSERT([self.rows isKindOfClass:[NSMutableArray class]] || nil == self.rows);\n\n  self.rows = nil == self.rows ? [NSMutableArray array] : self.rows;\n  return (NSMutableArray *)self.rows;\n}\n\n@end\n"
  },
  {
    "path": "src/collections/src/NimbusCollections.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#pragma mark - Nimbus Collections\n\n/**\n * @defgroup NimbusCollections Nimbus Collections\n * @{\n *\n * <div id=\"github\" feature=\"collections\"></div>\n *\n * Collection views are a new feature in iOS 6 that enable powerful collections of views to be\n * built.\n *\n * Collection views introduce a new concept of \"layout\" alongside the existing data source and\n * delegate concepts. Nimbus Collections provides support only for the data source with the\n * NICollectionViewModel. NICollectionViewModel behaves similarly to NITableViewModel in that you\n * provide it with an array of objects which are mapped to cells using a factory.\n */\n\n#pragma mark * Collection View Models\n\n/**\n * @defgroup CollectionViewModels Collection View Models\n */\n\n#pragma mark * Collection View Cell Factory\n\n/**\n * @defgroup CollectionViewCellFactory Collection View Cell Factory\n */\n\n#pragma mark * Model Tools\n\n/**\n * @defgroup CollectionViewTools Collection View Tools\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NICollectionViewActions.h\"\n#import \"NICollectionViewCellFactory.h\"\n#import \"NICollectionViewModel.h\"\n\n/**@}*/\n"
  },
  {
    "path": "src/collections/unittests/NimbusCollectionsTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/collections/unittests/NimbusCollectionsTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <UIKit/UIKit.h>\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCollections.h\"\n#import \"NimbusModels.h\"\n\nstatic UICollectionView *CollectionView() {\n  UICollectionViewLayout *layout = [[UICollectionViewLayout alloc] init];\n  UICollectionView *collectionView =\n      [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];\n  return collectionView;\n}\n\nstatic id ObjectWithTitle(NSString *title) {\n  return [NITitleCellObject objectWithTitle:title];\n}\n\n@interface NimbusCollectionsTests : XCTestCase\n@end\n\n@implementation NimbusCollectionsTests\n\n- (void)testMutableModelInitializationWithListArray {\n  NIMutableCollectionViewModel *model =\n      [[NIMutableCollectionViewModel alloc] initWithListArray:@[ ObjectWithTitle(@\"One\") ]\n                                                     delegate:nil];\n  UICollectionView *collectionView = CollectionView();\n  XCTAssertEqual([model collectionView:collectionView numberOfItemsInSection:0], 1);\n  [model addObject:ObjectWithTitle(@\"Two\")];\n  XCTAssertEqual([model collectionView:collectionView numberOfItemsInSection:0], 2);\n}\n\n@end\n"
  },
  {
    "path": "src/core/deps",
    "content": "\n[Frameworks]\nFoundation.framework\nUIKit.framework"
  },
  {
    "path": "src/core/src/NIActions+Subclassing.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIActions.h\"\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n@interface NIObjectActions : NSObject\n\n@property (nonatomic, copy) NIActionBlock tapAction;\n@property (nonatomic, copy) NIActionBlock detailAction;\n@property (nonatomic, copy) NIActionBlock navigateAction;\n\n@property (nonatomic) SEL tapSelector;\n@property (nonatomic) SEL detailSelector;\n@property (nonatomic) SEL navigateSelector;\n\n@end\n\n@interface NIActions ()\n\n@property (nonatomic, weak) id target;\n\n- (NIObjectActions *)actionForObjectOrClassOfObject:(id<NSObject>)object;\n\n@end\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIActions.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n/**\n * For attaching actions to objects.\n *\n * @ingroup NimbusCore\n * @defgroup Actions Actions\n * @{\n */\n\n/**\n * @param object An action was performed on this object.\n * @param target The target that was attached to the NIActions instance.\n * @param indexPath The index path of the object.\n */\ntypedef BOOL (^NIActionBlock)(id object, id target, NSIndexPath* indexPath);\n\n/**\n * The attachable types of actions for NIAction.\n */\ntypedef NS_OPTIONS(NSUInteger, NIActionType) {\n  NIActionTypeNone      = 0,\n  NIActionTypeTap       = 1 << 0,\n  NIActionTypeDetail    = 1 << 1,\n  NIActionTypeNavigate  = 1 << 2,\n};\n\n/**\n * The NIActions class provides a generic interface for attaching actions to objects.\n *\n * NIActions are used to implement user interaction in UITableViews and UICollectionViews via the\n * corresponding classes (NITableViewActions and NICollectionViewActions) in the respective\n * feature. NIActions separates the necessity\n *\n * <h3>Types of Actions</h3>\n *\n * The three primary types of actions are:\n *\n * - buttons,\n * - detail views,\n * - and pushing a new controller onto the navigation controller.\n *\n * <h3>Attaching Actions</h3>\n *\n * Actions may be attached to specific instances of objects or to entire classes of objects. When\n * an action is attached to both a class of object and an instance of that class, only the instance\n * action should be executed.\n *\n * All attachment methods return the object that was provided. This makes it simple to attach\n * actions within an array creation statement.\n *\n * Actions come in two forms: blocks and selector invocations. Both can be attached to an object\n * for each type of action and both will be executed, with the block being executed first. Blocks\n * should be used for simple executions while selectors should be used when the action is complex.\n *\n * The following is an example of using NITableViewActions:\n *\n@code\nNSArray *objects = @[\n  [NITitleCellObject objectWithTitle:@\"Implicit tap handler\"],\n  [self.actions attachToObject:[NITitleCellObject objectWithTitle:@\"Explicit tap handler\"]\n                      tapBlock:\n   ^BOOL(id object, id target) {\n     NSLog(@\"Object was tapped with an explicit action: %@\", object);\n   }]\n];\n\n[self.actions attachToClass:[NITitleCellObject class]\n                   tapBlock:\n ^BOOL(id object, id target) {\n   NSLog(@\"Object was tapped: %@\", object);\n }];\n@endcode\n *\n */\n@interface NIActions : NSObject\n\n// Designated initializer.\n- (id)initWithTarget:(id)target;\n\n#pragma mark Mapping Objects\n\n- (id)attachToObject:(id<NSObject>)object tapBlock:(NIActionBlock)action;\n- (id)attachToObject:(id<NSObject>)object detailBlock:(NIActionBlock)action;\n- (id)attachToObject:(id<NSObject>)object navigationBlock:(NIActionBlock)action;\n\n- (id)attachToObject:(id<NSObject>)object tapSelector:(SEL)selector;\n- (id)attachToObject:(id<NSObject>)object detailSelector:(SEL)selector;\n- (id)attachToObject:(id<NSObject>)object navigationSelector:(SEL)selector;\n\n#pragma mark Mapping Classes\n\n- (void)attachToClass:(Class)aClass tapBlock:(NIActionBlock)action;\n- (void)attachToClass:(Class)aClass detailBlock:(NIActionBlock)action;\n- (void)attachToClass:(Class)aClass navigationBlock:(NIActionBlock)action;\n\n- (void)attachToClass:(Class)aClass tapSelector:(SEL)selector;\n- (void)attachToClass:(Class)aClass detailSelector:(SEL)selector;\n- (void)attachToClass:(Class)aClass navigationSelector:(SEL)selector;\n\n#pragma mark Object State\n\n- (BOOL)isObjectActionable:(id<NSObject>)object;\n- (NIActionType)attachedActionTypesForObject:(id<NSObject>)object;\n\n+ (id)objectFromKeyClass:(Class)keyClass map:(NSMutableDictionary *)map;\n\n@end\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Returns a block that pushes an instance of the controllerClass onto the navigation stack.\n *\n * Allocates an instance of the controller class and calls the init selector.\n *\n * The target property of the NIActions instance must be an instance of UIViewController\n * with an attached navigationController.\n *\n * @param controllerClass The class of controller to instantiate.\n */\nNIActionBlock NIPushControllerAction(Class controllerClass);\n\n#if defined __cplusplus\n}\n#endif\n\n/** The protocol for a data source that can be used with NIActions. */\n@protocol NIActionsDataSource <NSObject>\n\n/**\n * The object located at the given indexPath.\n *\n * @param indexPath The index path of the requested object.\n */\n- (id)objectAtIndexPath:(NSIndexPath *)indexPath;\n\n@end\n\n/** @name Creating Table View Actions */\n\n/**\n * Initializes a newly allocated table view actions object with the given controller.\n *\n * @attention This method is deprecated. Use the new method\n *            @link NIActions::initWithTarget: initWithTarget:@endlink.\n *\n * The controller is stored as a weak reference internally.\n *\n * @param controller The controller that will be used in action blocks.\n * @fn NIActions::initWithController:\n */\n\n/**\n * Initializes a newly allocated table view actions object with the given target.\n *\n * This is the designated initializer.\n *\n * The target is stored as a weak reference internally.\n *\n * @param target The target that will be provided to action blocks and on which selectors will\n *                    be performed.\n * @fn NIActions::initWithTarget:\n */\n\n/** @name Mapping Objects */\n\n/**\n * Attaches a tap action to the given object.\n *\n * A cell with an attached tap action will have its selectionStyle set to\n * @c tableViewCellSelectionStyle when the cell is displayed.\n *\n * The action will be executed when the object's corresponding cell is tapped. The object argument\n * of the block will be the object to which this action was attached. The target argument of the\n * block will be this receiver's @c target.\n *\n * Return NO if the tap action is used to present a modal view controller. This provides a visual\n * reminder to the user when the modal controller is dismissed as to which cell was tapped to invoke\n * the modal controller.\n *\n * The tap action will be invoked first, followed by the navigation action if one is attached.\n *\n * @param object The object to attach the action to. This object must be contained within\n *                    an NITableViewModel.\n * @param action The tap action block.\n * @returns The object that you attached this action to.\n * @fn NIActions::attachToObject:tapBlock:\n * @sa NIActions::attachToObject:tapSelector:\n */\n\n/**\n * Attaches a detail action to the given object.\n *\n * When a cell with a detail action is displayed, its accessoryType will be set to\n * UITableViewCellAccessoryDetailDisclosureButton.\n *\n * When a cell's detail button is tapped, the detail action block will be executed. The return\n * value of the block is ignored.\n *\n * @param object The object to attach the action to. This object must be contained within\n *                    an NITableViewModel.\n * @param action The detail action block.\n * @returns The object that you attached this action to.\n * @fn NIActions::attachToObject:detailBlock:\n */\n\n/**\n * Attaches a navigation action to the given object.\n *\n * When a cell with a navigation action is displayed, its accessoryType will be set to\n * UITableViewCellAccessoryDisclosureIndicator if there is no detail action, otherwise the\n * detail disclosure indicator takes precedence.\n *\n * When a cell with a navigation action is tapped the navigation block will be executed.\n *\n * If a tap action also exists for this object then the tap action will be executed first, followed\n * by the navigation action.\n *\n * @param object The object to attach the action to. This object must be contained within\n *                    an NITableViewModel.\n * @param action The navigation action block.\n * @returns The object that you attached this action to.\n * @fn NIActions::attachToObject:navigationBlock:\n */\n\n/**\n * Attaches a tap selector to the given object.\n *\n * The method signature for the selector is:\n @code\n - (BOOL)didTapObject:(id)object;\n @endcode\n *\n * A cell with an attached tap action will have its selectionStyle set to\n * @c tableViewCellSelectionStyle when the cell is displayed.\n *\n * The selector will be performed on the action object's target when a cell with a tap selector is\n * tapped, unless that selector does not exist on the @c target in which case nothing happens.\n *\n * If the selector invocation returns YES then the cell will be deselected immediately after the\n * invocation completes its execution. If NO is returned then the cell's selection will remain.\n *\n * Return NO if the tap action is used to present a modal view controller. This provides a visual\n * reminder to the user when the modal controller is dismissed as to which cell was tapped to invoke\n * the modal controller.\n *\n * The tap action will be invoked first, followed by the navigation action if one is attached.\n *\n * @param object The object to attach the selector to. This object must be contained within\n *                    an NITableViewModel.\n * @param selector The selector that will be invoked by this action.\n * @returns The object that you attached this action to.\n * @fn NIActions::attachToObject:tapSelector:\n * @sa NIActions::attachToObject:tapBlock:\n */\n\n/**\n * Attaches a detail selector to the given object.\n *\n * The method signature for the selector is:\n @code\n - (void)didTapObject:(id)object;\n @endcode\n *\n * A cell with an attached tap action will have its selectionStyle set to\n * @c tableViewCellSelectionStyle and its accessoryType set to\n * @c UITableViewCellAccessoryDetailDisclosureButton when the cell is displayed.\n *\n * The selector will be performed on the action object's target when a cell with a detail selector's\n * accessory indicator is tapped, unless that selector does not exist on the @c target in which\n * case nothing happens.\n *\n * @param object The object to attach the selector to. This object must be contained within\n *                    an NITableViewModel.\n * @param selector The selector that will be invoked by this action.\n * @returns The object that you attached this action to.\n * @fn NIActions::attachToObject:detailSelector:\n * @sa NIActions::attachToObject:detailBlock:\n */\n\n/**\n * Attaches a navigation selector to the given object.\n *\n * The method signature for the selector is:\n @code\n - (void)didTapObject:(id)object;\n @endcode\n *\n * A cell with an attached navigation action will have its selectionStyle set to\n * @c tableViewCellSelectionStyle and its accessoryType set to\n * @c UITableViewCellAccessoryDetailDisclosureButton, unless it also has an attached detail action,\n * in which case its accessoryType will be set to @c UITableViewCellAccessoryDisclosureIndicator\n * when the cell is displayed.\n *\n * The selector will be performed on the action object's target when a cell with a navigation\n * selector is tapped, unless that selector does not exist on the @c target in which case nothing\n * happens.\n *\n * @param object The object to attach the selector to. This object must be contained within\n *                    an NITableViewModel.\n * @param selector The selector that will be invoked by this action.\n * @returns The object that you attached this action to.\n * @fn NIActions::attachToObject:navigationSelector:\n * @sa NIActions::attachToObject:navigationBlock:\n */\n\n/** @name Mapping Classes */\n\n/**\n * Attaches a tap block to a class.\n *\n * This method behaves similarly to attachToObject:tapBlock: except it attaches a tap action to\n * all instances and subclassed instances of a given class.\n *\n * @param aClass The class to attach the action to.\n * @param action The tap action block.\n * @fn NIActions::attachToClass:tapBlock:\n */\n\n/**\n * Attaches a detail block to a class.\n *\n * This method behaves similarly to attachToObject:detailBlock: except it attaches a detail action\n * to all instances and subclassed instances of a given class.\n *\n * @param aClass The class to attach the action to.\n * @param action The detail action block.\n * @fn NIActions::attachToClass:detailBlock:\n */\n\n/**\n * Attaches a navigation block to a class.\n *\n * This method behaves similarly to attachToObject:navigationBlock: except it attaches a navigation\n * action to all instances and subclassed instances of a given class.\n *\n * @param aClass The class to attach the action to.\n * @param action The navigation action block.\n * @fn NIActions::attachToClass:navigationBlock:\n */\n\n/**\n * Attaches a tap selector to a class.\n *\n * This method behaves similarly to attachToObject:tapBlock: except it attaches a tap action to\n * all instances and subclassed instances of a given class.\n *\n * @param aClass The class to attach the action to.\n * @param selector The tap selector.\n * @fn NIActions::attachToClass:tapSelector:\n */\n\n/**\n * Attaches a detail selector to a class.\n *\n * This method behaves similarly to attachToObject:detailBlock: except it attaches a detail action\n * to all instances and subclassed instances of a given class.\n *\n * @param aClass The class to attach the action to.\n * @param selector The tap selector.\n * @fn NIActions::attachToClass:detailSelector:\n */\n\n/**\n * Attaches a navigation selector to a class.\n *\n * This method behaves similarly to attachToObject:navigationBlock: except it attaches a navigation\n * action to all instances and subclassed instances of a given class.\n *\n * @param aClass The class to attach the action to.\n * @param selector The tap selector.\n * @fn NIActions::attachToClass:navigationSelector:\n */\n\n/** @name Object State */\n\n/**\n * Returns whether or not the object has any actions attached to it.\n *\n * @fn NIActions::isObjectActionable:\n */\n\n/**\n * Returns a bitmask of flags indicating the types of actions attached to the provided object.\n *\n * @fn NIActions::attachedActionTypesForObject:\n */\n\n/**\n * Returns a mapped object from the given key class.\n *\n * If the key class is a subclass of any mapped key classes, the nearest ancestor class's mapped\n * object will be returned and keyClass will be added to the map for future accesses.\n *\n * @param keyClass The key class that will be used to find the mapping in map.\n * @param map A map of key classes to classes. May be modified if keyClass is a subclass of\n *                 any existing key classes.\n * @returns The mapped object if a match for keyClass was found in map. nil is returned\n *               otherwise.\n * @fn NIActions::objectFromKeyClass:map:\n */\n\n/**@}*/// End of Actions //////////////////////////////////////////////////////////////////////////\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIActions.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIActions.h\"\n#import \"NIActions+Subclassing.h\"\n\n#import <UIKit/UIKit.h>\n\n#import \"NIDebuggingTools.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NIActions ()\n\n@property (nonatomic, strong) NSMutableDictionary* objectToAction;\n@property (nonatomic, strong) NSMutableDictionary* classToAction;\n@property (nonatomic, strong) NSMutableSet* objectSet;\n\n@end\n\n@implementation NIActions\n\n- (id)initWithTarget:(id)target {\n  if ((self = [super init])) {\n    _target = target;\n\n    _objectToAction = [[NSMutableDictionary alloc] init];\n    _classToAction = [[NSMutableDictionary alloc] init];\n    _objectSet = [[NSMutableSet alloc] init];\n  }\n  return self;\n}\n\n- (id)init {\n  return [self initWithTarget:nil];\n}\n\n#pragma mark - Private\n\n- (id)keyForObject:(id<NSObject>)object {\n  return @(object.hash);\n}\n\n//\n// actionForObject: and actionForClass: are used when attaching actions to objects and classes and\n// will always return an NIObjectActions object. These methods should not be used for determining\n// whether an action is attached to a given object or class.\n//\n// actionForObjectOrClassOfObject: determines whether an action has been attached to an object\n// or class of object and then returns the NIObjectActions or nil if no actions have been attached.\n//\n\n// Retrieves an NIObjectActions object for the given object or creates one if it doesn't yet exist\n// so that actions may be attached.\n- (NIObjectActions *)actionForObject:(id<NSObject>)object {\n  id key = [self keyForObject:object];\n  NIObjectActions* action = [self.objectToAction objectForKey:key];\n  if (nil == action) {\n    action = [[NIObjectActions alloc] init];\n    [self.objectToAction setObject:action forKey:key];\n  }\n  return action;\n}\n\n// Retrieves an NIObjectActions object for the given class or creates one if it doesn't yet exist\n// so that actions may be attached.\n- (NIObjectActions *)actionForClass:(Class)class {\n  NIObjectActions* action = [self.classToAction objectForKey:class];\n  if (nil == action) {\n    action = [[NIObjectActions alloc] init];\n    [self.classToAction setObject:action forKey:(id<NSCopying>)class];\n  }\n  return action;\n}\n\n// Fetches any attached actions for a given object.\n- (NIObjectActions *)actionForObjectOrClassOfObject:(id<NSObject>)object {\n  id key = [self keyForObject:object];\n  NIObjectActions* action = [self.objectToAction objectForKey:key];\n  if (nil == action) {\n    action = [self.class objectFromKeyClass:object.class map:self.classToAction];\n  }\n  return action;\n}\n\n#pragma mark - Public\n\n- (id)attachToObject:(id<NSObject>)object tapBlock:(NIActionBlock)action {\n  [self.objectSet addObject:object];\n  [self actionForObject:object].tapAction = action;\n  return object;\n}\n\n- (id)attachToObject:(id<NSObject>)object detailBlock:(NIActionBlock)action {\n  [self.objectSet addObject:object];\n  [self actionForObject:object].detailAction = action;\n  return object;\n}\n\n- (id)attachToObject:(id<NSObject>)object navigationBlock:(NIActionBlock)action {\n  [self.objectSet addObject:object];\n  [self actionForObject:object].navigateAction = action;\n  return object;\n}\n\n- (id)attachToObject:(id<NSObject>)object tapSelector:(SEL)selector {\n  [self.objectSet addObject:object];\n  [self actionForObject:object].tapSelector = selector;\n  return object;\n}\n\n- (id)attachToObject:(id<NSObject>)object detailSelector:(SEL)selector {\n  [self.objectSet addObject:object];\n  [self actionForObject:object].detailSelector = selector;\n  return object;\n}\n\n- (id)attachToObject:(id<NSObject>)object navigationSelector:(SEL)selector {\n  [self.objectSet addObject:object];\n  [self actionForObject:object].navigateSelector = selector;\n  return object;\n}\n\n- (void)attachToClass:(Class)aClass tapBlock:(NIActionBlock)action {\n  [self actionForClass:aClass].tapAction = action;\n}\n\n- (void)attachToClass:(Class)aClass detailBlock:(NIActionBlock)action {\n  [self actionForClass:aClass].detailAction = action;\n}\n\n- (void)attachToClass:(Class)aClass navigationBlock:(NIActionBlock)action {\n  [self actionForClass:aClass].navigateAction = action;\n}\n\n- (void)attachToClass:(Class)aClass tapSelector:(SEL)selector {\n  [self actionForClass:aClass].tapSelector = selector;\n}\n\n- (void)attachToClass:(Class)aClass detailSelector:(SEL)selector {\n  [self actionForClass:aClass].detailSelector = selector;\n}\n\n- (void)attachToClass:(Class)aClass navigationSelector:(SEL)selector {\n  [self actionForClass:aClass].navigateSelector = selector;\n}\n\n- (BOOL)isObjectActionable:(id<NSObject>)object {\n  return NIActionTypeNone != [self attachedActionTypesForObject:object];\n}\n\n- (NIActionType)attachedActionTypesForObject:(id<NSObject>)object {\n  if (nil == object) {\n    return NIActionTypeNone;\n  }\n\n  NIObjectActions* actions = [self actionForObjectOrClassOfObject:object];\n  NIActionType attachedActionTypes = 0;\n  if (actions.tapAction || actions.tapSelector) {\n    attachedActionTypes |= NIActionTypeTap;\n  }\n  if (actions.detailAction || actions.detailSelector) {\n    attachedActionTypes |= NIActionTypeDetail;\n  }\n  if (actions.navigateAction || actions.navigateSelector) {\n    attachedActionTypes |= NIActionTypeNavigate;\n  }\n  return attachedActionTypes;\n}\n\n+ (id)objectFromKeyClass:(Class)keyClass map:(NSMutableDictionary *)map {\n  id object = [map objectForKey:keyClass];\n\n  if (nil == object) {\n    // No mapping found for this key class, but it may be a subclass of another object that does\n    // have a mapping, so let's see what we can find.\n    Class superClass = nil;\n    for (Class class in map.allKeys) {\n      // We want to find the lowest node in the class hierarchy so that we pick the lowest ancestor\n      // in the hierarchy tree.\n      if ([keyClass isSubclassOfClass:class]\n          && (nil == superClass || [class isSubclassOfClass:superClass])) {\n        superClass = class;\n      }\n    }\n\n    if (nil != superClass) {\n      object = [map objectForKey:superClass];\n\n      // Add this subclass to the map so that next time this result is instant.\n      [map setObject:object forKey:(id<NSCopying>)keyClass];\n    }\n  }\n\n  if (nil == object) {\n    // We couldn't find a mapping at all so let's add an empty mapping.\n    [map setObject:[NSNull class] forKey:(id<NSCopying>)keyClass];\n\n  } else if (object == [NSNull class]) {\n    // Don't return null mappings.\n    object = nil;\n  }\n\n  return object;\n}\n\n@end\n\n@implementation NIObjectActions\n@end\n\nNIActionBlock NIPushControllerAction(Class controllerClass) {\n  return [^(id object, id target, NSIndexPath* indexPath) {\n    // You must initialize the actions object with initWithTarget: and pass a valid\n    // controller.\n    NIDASSERT(nil != target);\n    NIDASSERT([target isKindOfClass:[UIViewController class]]);\n    UIViewController *controller = target;\n\n    if (nil != controller && [controller isKindOfClass:[UIViewController class]]) {\n      // No navigation controller to push this new controller; this controller\n      // is going to be lost.\n      NIDASSERT(nil != controller.navigationController);\n\n      UIViewController* controllerToPush = [[controllerClass alloc] init];\n      [controller.navigationController pushViewController:controllerToPush\n                                                 animated:YES];\n    }\n\n    return NO;\n  } copy];\n}\n"
  },
  {
    "path": "src/core/src/NIButtonUtilities.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nAPI_DEPRECATED_BEGIN(\n    \"Use a branded UIButton instead (http://go/material-ios-buttons)\",\n    ios(12, API_TO_BE_DEPRECATED))\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For manipulating UIButton objects.\n *\n * @ingroup NimbusCore\n * @defgroup Button-Utilities Button Utilities\n * @{\n *\n * The methods provided here make it possible to specify different properties for different button\n * states in a scalable way. For example, you can define a stylesheet class that has a number of\n * class methods that return the various properties for buttons.\n *\n@code\n@implementation Stylesheet\n\n+ (UIImage *)backgroundImageForButtonWithState:(UIControlState)state {\n  if (state & UIControlStateHighlighted) {\n    return [UIImage imageNamed:@\"button_highlighted\"];\n\n  } else if (state == UIControlStateNormal) {\n    return [UIImage imageNamed:@\"button\"];\n  }\n  return nil;\n}\n\n@end\n\n// The result of the implementation above will set the background images for the button's\n// highlighted and default states.\nNIApplyBackgroundImageSelectorToButton(@selector(backgroundImageForButtonWithState:),\n                                       [Stylesheet class],\n                                       button);\n@endcode\n */\n\n/**\n * Sets the images for a button's states.\n *\n * @param selector A selector of the form:\n *                      (UIImage *)imageWithControlState:(UIControlState)controlState\n * @param target The target upon which the selector will be invoked.\n * @param button The button object whose properties should be modified.\n */\nvoid NIApplyImageSelectorToButton(SEL selector, id target, UIButton* button);\n\n/**\n * Sets the background images for a button's states.\n *\n * @param selector A selector of the form:\n *                      (UIImage *)backgroundImageWithControlState:(UIControlState)controlState\n * @param target The target upon which the selector will be invoked.\n * @param button The button object whose properties should be modified.\n */\nvoid NIApplyBackgroundImageSelectorToButton(SEL selector, id target, UIButton* button);\n\n/**\n * Sets the title colors for a button's states.\n *\n * @param selector A selector of the form:\n *                      (UIColor *)colorWithControlState:(UIControlState)controlState\n * @param target The target upon which the selector will be invoked.\n * @param button The button object whose properties should be modified.\n */\nvoid NIApplyTitleColorSelectorToButton(SEL selector, id target, UIButton* button);\n\n/**@}*/// End of Button Utilities /////////////////////////////////////////////////////////////////\n\n#if defined __cplusplus\n}\n#endif\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIButtonUtilities.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIButtonUtilities.h\"\n\nvoid NIApplyImageSelectorToButton(SEL selector, id target, UIButton* button) {\n  typedef UIImage* (*ImageMethod)(id, SEL, UIControlState);\n  ImageMethod method = (ImageMethod)[target methodForSelector:selector];\n  UIImage* image = nil;\n\n  image = method(target, selector, UIControlStateNormal);\n  [button setImage:image forState:UIControlStateNormal];\n\n  image = method(target, selector, UIControlStateHighlighted);\n  [button setImage:image forState:UIControlStateHighlighted];\n\n  image = method(target, selector, UIControlStateDisabled);\n  [button setImage:image forState:UIControlStateDisabled];\n\n  image = method(target, selector, UIControlStateSelected);\n  [button setImage:image forState:UIControlStateSelected];\n\n  UIControlState selectedHighlightState = UIControlStateSelected | UIControlStateHighlighted;\n  image = method(target, selector, selectedHighlightState);\n  [button setImage:image forState:selectedHighlightState];\n}\n\nvoid NIApplyBackgroundImageSelectorToButton(SEL selector, id target, UIButton* button) {\n  typedef UIImage* (*ImageMethod)(id, SEL, UIControlState);\n  ImageMethod method = (ImageMethod)[target methodForSelector:selector];\n  UIImage* image = nil;\n\n  image = method(target, selector, UIControlStateNormal);\n  [button setBackgroundImage:image forState:UIControlStateNormal];\n\n  image = method(target, selector, UIControlStateHighlighted);\n  [button setBackgroundImage:image forState:UIControlStateHighlighted];\n\n  image = method(target, selector, UIControlStateDisabled);\n  [button setBackgroundImage:image forState:UIControlStateDisabled];\n\n  image = method(target, selector, UIControlStateSelected);\n  [button setBackgroundImage:image forState:UIControlStateSelected];\n\n  UIControlState selectedHighlightState = UIControlStateSelected | UIControlStateHighlighted;\n  image = method(target, selector, selectedHighlightState);\n  [button setBackgroundImage:image forState:selectedHighlightState];\n}\n\nvoid NIApplyTitleColorSelectorToButton(SEL selector, id target, UIButton* button) {\n  typedef UIColor* (*ColorMethod)(id, SEL, UIControlState);\n  ColorMethod method = (ColorMethod)[target methodForSelector:selector];\n  UIColor* color = nil;\n\n  color = method(target, selector, UIControlStateNormal);\n  [button setTitleColor:color forState:UIControlStateNormal];\n\n  color = method(target, selector, UIControlStateHighlighted);\n  [button setTitleColor:color forState:UIControlStateHighlighted];\n\n  color = method(target, selector, UIControlStateDisabled);\n  [button setTitleColor:color forState:UIControlStateDisabled];\n\n  color = method(target, selector, UIControlStateSelected);\n  [button setTitleColor:color forState:UIControlStateSelected];\n\n  UIControlState selectedHighlightState = UIControlStateSelected | UIControlStateHighlighted;\n  color = method(target, selector, selectedHighlightState);\n  [button setTitleColor:color forState:selectedHighlightState];\n}\n"
  },
  {
    "path": "src/core/src/NICommonMetrics.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPreprocessorMacros.h\"\n\nAPI_DEPRECATED_BEGIN(\"Use equivalent UIKit APIs instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For common system metrics.\n *\n * If you work with system metrics in any way it can be a pain in the ass to figure out what the\n * exact metrics are. Figuring out how long it takes the status bar to animate is not something you\n * should be spending your time on. The metrics in this file are provided as a means of unifying a\n * number of system metrics for use in your applications.\n *\n * <h2>What Qualifies as a Common Metric</h2>\n *\n * Common metrics are system components, such as the dimensions of a toolbar in\n * a particular orientation or the duration of a standard animation. This is\n * not the place to put feature-specific metrics, such as the height of a photo scrubber\n * view.\n *\n * <h2>Examples</h2>\n *\n * <h3>Positioning a Toolbar</h3>\n *\n * The following example updates the position and height of a toolbar when the device\n * orientation is changing. This ensures that, in landscape mode on the iPhone, the toolbar\n * is slightly shorter to accomodate the smaller height of the screen.\n *\n * @code\n * - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation\n *                                          duration:(NSTimeInterval)duration {\n *   [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n *\n *   CGRect toolbarFrame = self.toolbar.frame;\n *   toolbarFrame.size.height = NIToolbarHeightForOrientation(toInterfaceOrientation);\n *   toolbarFrame.origin.y = self.view.bounds.size.height - toolbarFrame.size.height;\n *   self.toolbar.frame = toolbarFrame;\n * }\n * @endcode\n *\n * @ingroup NimbusCore\n * @defgroup Common-Metrics Common Metrics\n * @{\n */\n\n/**\n * The recommended number of points for a minimum tappable area.\n *\n * Value: 44\n */\nCGFloat NIMinimumTapDimension(void)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * Fetch the height of a toolbar in a given orientation.\n *\n * On the iPhone:\n * - Portrait: 44\n * - Landscape: 33\n *\n * On the iPad: always 44\n */\nCGFloat NIToolbarHeightForOrientation(UIInterfaceOrientation orientation)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * The animation curve used when changing the status bar's visibility.\n *\n * This is the curve of the animation used by\n * <code>-[[UIApplication sharedApplication] setStatusBarHidden:withAnimation:].</code>\n *\n * Value: UIViewAnimationCurveEaseIn\n */\nUIViewAnimationCurve NIStatusBarAnimationCurve(void)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * The animation duration used when changing the status bar's visibility.\n *\n * This is the duration of the animation used by\n * <code>-[[UIApplication sharedApplication] setStatusBarHidden:withAnimation:].</code>\n *\n * Value: 0.3 seconds\n */\nNSTimeInterval NIStatusBarAnimationDuration(void)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * The animation curve used when the status bar's bounds change (when a call is received,\n * for example).\n *\n * Value: UIViewAnimationCurveEaseInOut\n */\nUIViewAnimationCurve NIStatusBarBoundsChangeAnimationCurve(void)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * The animation duration used when the status bar's bounds change (when a call is received,\n * for example).\n *\n * Value: 0.35 seconds\n */\nNSTimeInterval NIStatusBarBoundsChangeAnimationDuration(void)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * Get the status bar's current height.\n *\n * If the status bar is hidden this will return 0.\n *\n * This is generally 20 when the status bar is its normal height.\n */\nCGFloat NIStatusBarHeight(void) NI_EXTENSION_UNAVAILABLE_IOS(\"\")\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * The animation duration when the device is rotating to a new orientation.\n *\n * Value: 0.4 seconds if the device is being rotated 90 degrees.\n *        0.8 seconds if the device is being rotated 180 degrees.\n *\n * @param isFlippingUpsideDown YES if the device is being flipped upside down.\n */\nNSTimeInterval NIDeviceRotationDuration(BOOL isFlippingUpsideDown)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * The padding around a standard cell in a table view.\n *\n * Value: 10 pixels on all sides.\n */\nUIEdgeInsets NICellContentPadding(void)\n    API_UNAVAILABLE(tvos, watchos);\n\n#if defined __cplusplus\n}\n#endif\n\n/**@}*/// End of Common Metrics ///////////////////////////////////////////////////////////////////\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NICommonMetrics.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICommonMetrics.h\"\n\n#import \"NISDKAvailability.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nCGFloat NIMinimumTapDimension(void) {\n  return 44;\n}\n\nCGFloat NIToolbarHeightForOrientation(UIInterfaceOrientation orientation) {\n  return (NIIsPad()\n          ? 44\n          : (UIInterfaceOrientationIsPortrait(orientation)\n             ? 44\n             : 33));\n}\n\nUIViewAnimationCurve NIStatusBarAnimationCurve(void) {\n  return UIViewAnimationCurveEaseIn;\n}\n\nNSTimeInterval NIStatusBarAnimationDuration(void) {\n  return 0.3;\n}\n\nUIViewAnimationCurve NIStatusBarBoundsChangeAnimationCurve(void) {\n  return UIViewAnimationCurveEaseInOut;\n}\n\nNSTimeInterval NIStatusBarBoundsChangeAnimationDuration(void) {\n  return 0.35;\n}\n\nCGFloat NIStatusBarHeight(void) {\n  CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];\n\n  // We take advantage of the fact that the status bar will always be wider than it is tall\n  // in order to avoid having to check the status bar orientation.\n  CGFloat statusBarHeight = MIN(statusBarFrame.size.width, statusBarFrame.size.height);\n\n  return statusBarHeight;\n}\n\nNSTimeInterval NIDeviceRotationDuration(BOOL isFlippingUpsideDown) {\n  return isFlippingUpsideDown ? 0.8 : 0.4;\n}\n\nUIEdgeInsets NICellContentPadding(void) {\n  return UIEdgeInsetsMake(10, 10, 10, 10);\n}\n"
  },
  {
    "path": "src/core/src/NIDebuggingTools.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\nAPI_DEPRECATED_BEGIN(\"Use Foundation APIs instead.\", ios(12, API_TO_BE_DEPRECATED))\n/**\n * For inspecting code and writing to logs in debug builds.\n *\n * Nearly all of the following macros will only do anything if the DEBUG macro is defined.\n * The recommended way to enable the debug tools is to specify DEBUG in the \"Preprocessor Macros\"\n * field in your application's Debug target settings. Be careful not to set this for your release\n * or app store builds because this will enable code that may cause your app to be rejected.\n *\n *\n * <h2>Debug Assertions</h2>\n *\n * Debug assertions are a lightweight \"sanity check\". They won't crash the app, nor will they\n * be included in release builds. They <i>will</i> halt the app's execution when debugging so\n * that you can inspect the values that caused the failure.\n *\n * @code\n *  NIDASSERT(statement);\n * @endcode\n *\n * If <i>statement</i> is false, the statement will be written to the log and if a debugger is\n * attached, the app will break on the assertion line.\n *\n *\n * <h2>Debug Logging</h2>\n *\n * @code\n *  NIDPRINT(@\"formatted log text %d\", param1);\n * @endcode\n *\n * Print the given formatted text to the log.\n *\n * @code\n *  NIDPRINTMETHODNAME();\n * @endcode\n *\n * Print the current method name to the log.\n *\n * @code\n *  NIDCONDITIONLOG(statement, @\"formatted log text %d\", param1);\n * @endcode\n *\n * If statement is true, then the formatted text will be written to the log.\n *\n * @code\n *  NIDINFO/NIDWARNING/NIDERROR(@\"formatted log text %d\", param1);\n * @endcode\n *\n * Will only write the formatted text to the log if NIMaxLogLevel is greater than the respective\n * NID* method's log level. See below for log levels.\n *\n * The default maximum log level is NILOGLEVEL_WARNING.\n *\n * <h3>Turning up the log level while the app is running</h3>\n *\n * NIMaxLogLevel is declared a non-const extern so that you can modify it at runtime. This can\n * be helpful for turning logging on while the application is running.\n *\n * @code\n *  NIMaxLogLevel = NILOGLEVEL_INFO;\n * @endcode\n *\n * @ingroup NimbusCore\n * @defgroup Debugging-Tools Debugging Tools\n * @{\n */\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\n/**\n * Assertions that only fire when DEBUG is defined.\n *\n * An assertion is like a programmatic breakpoint. Use it for sanity checks to save headache while\n * writing your code.\n */\n#import <TargetConditionals.h>\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\nint NIIsInDebugger(void);\n\n#if defined __cplusplus\n}\n#endif\n\n#if TARGET_IPHONE_SIMULATOR\n#define NIDASSERT(xx) { if (!(xx)) { NIDPRINT(@\"NIDASSERT failed: %s\", #xx); \\\nif (NIDebugAssertionsShouldBreak && NIIsInDebugger()) { __builtin_debugtrap(); } } \\\n} ((void)0)\n#else\n#define NIDASSERT(xx) { if (!(xx)) { NIDPRINT(@\"NIDASSERT failed: %s\", #xx); \\\nif (NIDebugAssertionsShouldBreak && NIIsInDebugger()) { raise(SIGTRAP); } } \\\n} ((void)0)\n#endif // #if TARGET_IPHONE_SIMULATOR\n\n#else\n#define NIDASSERT(xx) ((void)0)\n#endif // #if defined(DEBUG) || defined(NI_DEBUG)\n\n\n#define NILOGLEVEL_INFO     5\n#define NILOGLEVEL_WARNING  3\n#define NILOGLEVEL_ERROR    1\n\n/**\n * The maximum log level to output for Nimbus debug logs.\n *\n * This value may be changed at run-time.\n *\n * The default value is NILOGLEVEL_WARNING.\n */\nextern NSInteger NIMaxLogLevel;\n\n/**\n * Whether or not debug assertions should halt program execution like a breakpoint when they fail.\n *\n * An example of when this is used is in unit tests, when failure cases are tested that will\n * fire debug assertions.\n *\n * The default value is YES.\n */\nextern BOOL NIDebugAssertionsShouldBreak;\n\n/**\n * Only writes to the log when DEBUG is defined.\n *\n * This log method will always write to the log, regardless of log levels. It is used by all\n * of the other logging methods in Nimbus' debugging library.\n */\n#if defined(DEBUG) || defined(NI_DEBUG)\n#define NIDPRINT(xx, ...)  NSLog(@\"%s(%d): \" xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)\n#else\n#define NIDPRINT(xx, ...)  ((void)0)\n#endif // #if defined(DEBUG) || defined(NI_DEBUG)\n\n/**\n * Write the containing method's name to the log using NIDPRINT.\n */\n#define NIDPRINTMETHODNAME() NIDPRINT(@\"%s\", __PRETTY_FUNCTION__)\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n/**\n * Only writes to the log if condition is satisified.\n *\n * This macro powers the level-based loggers. It can also be used for conditionally enabling\n * families of logs.\n */\n#define NIDCONDITIONLOG(condition, xx, ...) { if ((condition)) { NIDPRINT(xx, ##__VA_ARGS__); } \\\n} ((void)0)\n#else\n#define NIDCONDITIONLOG(condition, xx, ...) ((void)0)\n#endif // #if defined(DEBUG) || defined(NI_DEBUG)\n\n\n/**\n * Only writes to the log if NIMaxLogLevel >= NILOGLEVEL_ERROR.\n */\n#define NIDERROR(xx, ...)  NIDCONDITIONLOG((NILOGLEVEL_ERROR <= NIMaxLogLevel), xx, ##__VA_ARGS__)\n\n/**\n * Only writes to the log if NIMaxLogLevel >= NILOGLEVEL_WARNING.\n */\n#define NIDWARNING(xx, ...)  NIDCONDITIONLOG((NILOGLEVEL_WARNING <= NIMaxLogLevel), \\\nxx, ##__VA_ARGS__)\n\n/**\n * Only writes to the log if NIMaxLogLevel >= NILOGLEVEL_INFO.\n */\n#define NIDINFO(xx, ...)  NIDCONDITIONLOG((NILOGLEVEL_INFO <= NIMaxLogLevel), xx, ##__VA_ARGS__)\n\n/**@}*/// End of Debugging Tools //////////////////////////////////////////////////////////////////\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIDebuggingTools.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIDebuggingTools.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNSInteger NIMaxLogLevel = NILOGLEVEL_WARNING;\nBOOL NIDebugAssertionsShouldBreak = YES;\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\n#import <unistd.h>\n#import <sys/sysctl.h>\n\n// From: http://developer.apple.com/mac/library/qa/qa2004/qa1361.html\nint NIIsInDebugger(void) {\n  int                 mib[4];\n  struct kinfo_proc   info;\n  size_t              size;\n\n  // Initialize the flags so that, if sysctl fails for some bizarre\n  // reason, we get a predictable result.\n\n  info.kp_proc.p_flag = 0;\n\n  // Initialize mib, which tells sysctl the info we want, in this case\n  // we're looking for information about a specific process ID.\n\n  mib[0] = CTL_KERN;\n  mib[1] = KERN_PROC;\n  mib[2] = KERN_PROC_PID;\n  mib[3] = getpid();\n\n  // Call sysctl.\n\n  size = sizeof(info);\n  sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);\n\n  // We're being debugged if the P_TRACED flag is set.\n\n  return (info.kp_proc.p_flag & P_TRACED) != 0;\n}\n\n#endif // #if defined(DEBUG) || defined(NI_DEBUG)\n"
  },
  {
    "path": "src/core/src/NIDeviceOrientation.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPreprocessorMacros.h\"\n\nAPI_DEPRECATED_BEGIN(\"Use trait collections instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For dealing with device orientations.\n *\n * <h2>Examples</h2>\n *\n * <h3>Use NIIsSupportedOrientation to Enable Autorotation</h3>\n *\n * @code\n *  - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {\n *    return NIIsSupportedOrientation(toInterfaceOrientation);\n *  }\n * @endcode\n *\n * @ingroup NimbusCore\n * @defgroup Device-Orientation Device Orientation\n * @{\n */\n\n/**\n * For use in shouldAutorotateToInterfaceOrientation:\n *\n * On iPhone/iPod touch:\n *\n *      Returns YES if the orientation is portrait, landscape left, or landscape right.\n *      This helps to ignore upside down and flat orientations.\n *\n * On iPad:\n *\n *      Always returns YES.\n */\nBOOL NIIsSupportedOrientation(UIInterfaceOrientation orientation)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * Returns the application's current interface orientation.\n *\n * This is simply a convenience method for [UIApplication sharedApplication].statusBarOrientation.\n *\n * @returns The current interface orientation.\n */\nUIInterfaceOrientation NIInterfaceOrientation(void) NI_EXTENSION_UNAVAILABLE_IOS(\"\")\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * Returns YES if the device is a phone and the orientation is landscape.\n *\n * This is a useful check for phone landscape mode which often requires\n * additional logic to handle the smaller vertical real estate.\n *\n * @returns YES if the device is a phone and orientation is landscape.\n */\nBOOL NIIsLandscapePhoneOrientation(UIInterfaceOrientation orientation)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * Creates an affine transform for the given device orientation.\n *\n * This is useful for creating a transformation matrix for a view that has been added\n * directly to the window and doesn't automatically have its transformation modified.\n */\nCGAffineTransform NIRotateTransformForOrientation(UIInterfaceOrientation orientation)\n    API_UNAVAILABLE(tvos, watchos);\n\n#if defined __cplusplus\n}\n#endif\n\n/**@}*/// End of Device Orientation ///////////////////////////////////////////////////////////////\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIDeviceOrientation.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIDeviceOrientation.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n#import \"NIDebuggingTools.h\"\n#import \"NISDKAvailability.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nBOOL NIIsSupportedOrientation(UIInterfaceOrientation orientation) {\n  if (NIIsPad()) {\n    return YES;\n\n  } else {\n    switch (orientation) {\n      case UIInterfaceOrientationPortrait:\n      case UIInterfaceOrientationLandscapeLeft:\n      case UIInterfaceOrientationLandscapeRight:\n        return YES;\n      default:\n        return NO;\n    }\n  }\n}\n\nUIInterfaceOrientation NIInterfaceOrientation(void) {\n  UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation;\n\n  // This code used to use the Three20 navigator to find the currently visible view controller and\n  // fall back to checking its orientation if we didn't know the status bar's orientation.\n  // It's unclear when this was actually necessary, though, so this assertion is here to try\n  // to find that case. If this assertion fails then the repro case needs to be analyzed and\n  // this method made more robust to handle that case.\n  NIDASSERT(UIDeviceOrientationUnknown != orient);\n\n  return orient;\n}\n\nBOOL NIIsLandscapePhoneOrientation(UIInterfaceOrientation orientation) {\n  return NIIsPhone() && UIInterfaceOrientationIsLandscape(orientation);\n}\n\nCGAffineTransform NIRotateTransformForOrientation(UIInterfaceOrientation orientation) {\n  if (orientation == UIInterfaceOrientationLandscapeLeft) {\n    return CGAffineTransformMakeRotation((CGFloat)(M_PI * 1.5));\n\n  } else if (orientation == UIInterfaceOrientationLandscapeRight) {\n    return CGAffineTransformMakeRotation((CGFloat)(M_PI / 2.0));\n\n  } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {\n    return CGAffineTransformMakeRotation((CGFloat)(-M_PI));\n\n  } else {\n    return CGAffineTransformIdentity;\n  }\n}\n"
  },
  {
    "path": "src/core/src/NIError.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nAPI_DEPRECATED_BEGIN(\"Use NSError instead.\", ios(12, API_TO_BE_DEPRECATED))\n/**\n * For defining various error types used throughout the Nimbus framework.\n *\n * @ingroup NimbusCore\n * @defgroup Errors Errors\n * @{\n */\n\n/** The Nimbus error domain. */\nextern NSString* const NINimbusErrorDomain;\n\n/** The key used for images in the error's userInfo. */\nextern NSString* const NIImageErrorKey;\n\n/** NSError codes in NINimbusErrorDomain. */\ntypedef enum {\n  /** The image is too small to be used. */\n  NIImageTooSmall = 1,\n} NINimbusErrorDomainCode;\n\n\n/**@}*/// End of Errors ///////////////////////////////////////////////////////////////////////////\n\n/**\n * <h3>Example</h3>\n *\n * @code\n * error = [NSError errorWithDomain: NINimbusErrorDomain\n *                             code: NIImageTooSmall\n *                         userInfo: [NSDictionary dictionaryWithObject: image\n *                                                               forKey: NIImageErrorKey]];\n * @endcode\n *\n * @enum NINimbusErrorDomainCode\n */\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIError.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIError.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNSString* const NINimbusErrorDomain = @\"com.nimbus.error\";\nNSString* const NIImageErrorKey = @\"image\";\n"
  },
  {
    "path": "src/core/src/NIFoundationMethods.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPreprocessorMacros.h\"\n#import \"NISDKAvailability.h\"\n\nAPI_DEPRECATED_BEGIN(\"Use standard Foundation APIs instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For filling in gaps in Apple's Foundation framework.\n *\n * @ingroup NimbusCore\n * @defgroup Foundation-Methods Foundation Methods\n * @{\n *\n * Utility methods save time and headache. You've probably written dozens of your own. Nimbus\n * hopes to provide an ever-growing set of convenience methods that compliment the Foundation\n * framework's functionality.\n */\n\n#pragma mark - NSInvocation Methods\n\n/**\n * Construct an NSInvocation with an instance of an object and a selector\n *\n *  @return an NSInvocation that will call the given selector on the given target\n */\nNSInvocation* NIInvocationWithInstanceTarget(NSObject* target, SEL selector);\n\n/**\n * This method is deprecated. Please use NIInvocationWithInstanceTarget([object class], selector)\n * instead.\n */\nNSInvocation* NIInvocationWithClassTarget(Class targetClass, SEL selector) __NI_DEPRECATED_METHOD;\n\n#pragma mark - CGRect Methods\n\n/**\n * For manipulating CGRects.\n *\n * @defgroup CGRect-Methods CGRect Methods\n * @{\n *\n * These methods provide additional means of modifying the edges of CGRects beyond the basics\n * included in CoreGraphics.\n */\n\n/**\n * Modifies only the right and bottom edges of a CGRect.\n *\n * @return a CGRect with dx and dy subtracted from the width and height.\n *\n *      Example result: CGRectMake(x, y, w - dx, h - dy)\n */\nCGRect NIRectContract(CGRect rect, CGFloat dx, CGFloat dy);\n\n/**\n * Modifies only the right and bottom edges of a CGRect.\n *\n * @return a CGRect with dx and dy added to the width and height.\n *\n *      Example result: CGRectMake(x, y, w + dx, h + dy)\n */\nCGRect NIRectExpand(CGRect rect, CGFloat dx, CGFloat dy);\n\n/**\n * Modifies only the top and left edges of a CGRect.\n *\n * @return a CGRect whose origin has been offset by dx, dy, and whose size has been\n *              contracted by dx, dy.\n *\n *      Example result: CGRectMake(x + dx, y + dy, w - dx, h - dy)\n */\nCGRect NIRectShift(CGRect rect, CGFloat dx, CGFloat dy);\n\n/**\n * Inverse of UIEdgeInsetsInsetRect.\n *\n *      Example result: CGRectMake(x - left, y - top,\n *                                 w + left + right, h + top + bottom)\n */\nCGRect NIEdgeInsetsOutsetRect(CGRect rect, UIEdgeInsets outsets);\n\n/**\n * Returns the x position that will center size within containerSize.\n *\n *      Example result: floorf((containerSize.width - size.width) / 2.f)\n */\nCGFloat NICenterX(CGSize containerSize, CGSize size);\n\n/**\n * Returns the y position that will center size within containerSize.\n *\n *      Example result: floorf((containerSize.height - size.height) / 2.f)\n */\nCGFloat NICenterY(CGSize containerSize, CGSize size);\n\n/**\n * Returns a rect that will center viewToCenter within containerView.\n *\n * @return a CGPoint that will center viewToCenter within containerView.\n */\nCGRect NIFrameOfCenteredViewWithinView(UIView* viewToCenter, UIView* containerView);\n\n/**\n * Returns the size of the string with given UILabel properties.\n */\nCGSize NISizeOfStringWithLabelProperties(NSString *string, CGSize constrainedToSize, UIFont *font, NSLineBreakMode lineBreakMode, NSInteger numberOfLines)\n    API_UNAVAILABLE(tvos, watchos) NI_UNAVAILABLE_VISIONOS;\n\n/**@}*/\n\n\n#pragma mark - NSRange Methods\n\n/**\n * For manipulating NSRange.\n *\n * @defgroup NSRange-Methods NSRange Methods\n * @{\n */\n\n/**\n * Create an NSRange object from a CFRange object.\n *\n * @return an NSRange object with the same values as the CFRange object.\n *\n * @attention This has the potential to behave unexpectedly because it converts the\n *                 CFRange's long values to unsigned integers. Nimbus will fire off a debug\n *                 assertion at runtime if the value will be chopped or the sign will change.\n *                 Even though the assertion will fire, the method will still chop or change\n *                 the sign of the values so you should take care to fix this.\n */\nNSRange NIMakeNSRangeFromCFRange(CFRange range);\n\n/**@}*/\n\n\n#pragma mark - NSData Methods\n\n/**\n * For manipulating NSData.\n *\n * @defgroup NSData-Methods NSData Methods\n * @{\n */\n\n/**\n * Calculates an md5 hash of the data using CC_MD5.\n */\nNSString* NIMD5HashFromData(NSData* data);\n\n/**\n * Calculates a sha1 hash of the data using CC_SHA1.\n */\nNSString* NISHA1HashFromData(NSData* data);\n\n/**@}*/\n\n\n#pragma mark - NSString Methods\n\n/**\n * For manipulating NSStrings.\n *\n * @defgroup NSString-Methods NSString Methods\n * @{\n */\n\n/**\n * Calculates an md5 hash of the string using CC_MD5.\n *\n * Treats the string as UTF8.\n */\nNSString* NIMD5HashFromString(NSString* string);\n\n/**\n * Calculates a sha1 hash of the string using CC_SHA1.\n *\n * Treats the string as UTF8.\n */\nNSString* NISHA1HashFromString(NSString* string);\n\n/**\n * Returns a Boolean value indicating whether the string is a NSString object that contains only\n * whitespace and newlines.\n */\nBOOL NIIsStringWithWhitespaceAndNewlines(NSString* string);\n\n/**\n * Compares two strings expressing software versions.\n *\n * The comparison is (except for the development version provisions noted below) lexicographic\n * string comparison. So as long as the strings being compared use consistent version formats,\n * a variety of schemes are supported. For example \"3.02\" < \"3.03\" and \"3.0.2\" < \"3.0.3\". If you\n * mix such schemes, like trying to compare \"3.02\" and \"3.0.3\", the result may not be what you\n * expect.\n *\n * Development versions are also supported by adding an \"a\" character and more version info after\n * it. For example \"3.0a1\" or \"3.01a4\". The way these are handled is as follows: if the parts\n * before the \"a\" are different, the parts after the \"a\" are ignored. If the parts before the \"a\"\n * are identical, the result of the comparison is the result of NUMERICALLY comparing the parts\n * after the \"a\". If the part after the \"a\" is empty, it is treated as if it were \"0\". If one\n * string has an \"a\" and the other does not (e.g. \"3.0\" and \"3.0a1\") the one without the \"a\"\n * is newer.\n *\n * Examples (?? means undefined):\n * @htmlonly\n * <pre>\n *   \"3.0\" = \"3.0\"\n *   \"3.0a2\" = \"3.0a2\"\n *   \"3.0\" > \"2.5\"\n *   \"3.1\" > \"3.0\"\n *   \"3.0a1\" < \"3.0\"\n *   \"3.0a1\" < \"3.0a4\"\n *   \"3.0a2\" < \"3.0a19\"  <-- numeric, not lexicographic\n *   \"3.0a\" < \"3.0a1\"\n *   \"3.02\" < \"3.03\"\n *   \"3.0.2\" < \"3.0.3\"\n *   \"3.00\" ?? \"3.0\"\n *   \"3.02\" ?? \"3.0.3\"\n *   \"3.02\" ?? \"3.0.2\"\n * </pre>\n * @endhtmlonly\n */\nNSComparisonResult NICompareVersionStrings(NSString* string1, NSString* string2);\n\n/**\n * Parses a URL query string into a dictionary where the values are arrays.\n *\n * A query string is one that looks like &param1=value1&param2=value2...\n *\n * The resulting NSDictionary will contain keys for each parameter name present in the query.\n * The value for each key will be an NSArray which may be empty if the key is simply present\n * in the query. Otherwise each object in the array with be an NSString corresponding to a value\n * in the query for that parameter.\n */\nNSDictionary* NIQueryDictionaryFromString(NSString* string);\n\n/**\n * Deprecated method. Use NIQueryDictionaryFromString instead.\n */\nNSDictionary* NIQueryDictionaryFromStringUsingEncoding(NSString* string, NSStringEncoding encoding) __NI_DEPRECATED_METHOD; // Use NIQueryDictionaryFromString instead.\n\n/**\n * Returns a string that has been escaped for use as a URL parameter.\n */\nNSString* NIStringByAddingPercentEscapesForURLParameterString(NSString* parameter);\n\n/**\n * Appends a dictionary of query parameters to a string, adding the ? character if necessary.\n */\nNSString* NIStringByAddingQueryDictionaryToString(NSString* string, NSDictionary* query);\n\n/**@}*/\n\n\n#pragma mark - CGFloat Methods\n\n/**\n * For manipulating CGFloat.\n *\n * @defgroup CGFloat-Methods CGFloat Methods\n * @{\n *\n * These methods provide math functions on CGFloats. They could easily be replaced with <tgmath.h>\n * but that is currently (Xcode 5.0) incompatible with CLANG_ENABLE_MODULES (on by default for\n * many projects/targets). We'll use CG_INLINE because this really should be completely inline.\n */\n\n#if CGFLOAT_IS_DOUBLE\n  #define NI_CGFLOAT_EPSILON DBL_EPSILON\n#else\n  #define NI_CGFLOAT_EPSILON FLT_EPSILON\n#endif\n\n/**\n * fabs()/fabsf() sized for CGFloat\n */\nCG_INLINE CGFloat NICGFloatAbs(CGFloat x) {\n#if CGFLOAT_IS_DOUBLE\n  return (CGFloat)fabs(x);\n#else\n  return (CGFloat)fabsf(x);\n#endif\n}\n\n/**\n * floor()/floorf() sized for CGFloat\n */\nCG_INLINE CGFloat NICGFloatFloor(CGFloat x) {\n#if CGFLOAT_IS_DOUBLE\n  return (CGFloat)floor(x);\n#else\n  return (CGFloat)floorf(x);\n#endif\n}\n\n/**\n * ceil()/ceilf() sized for CGFloat\n */\nCG_INLINE CGFloat NICGFloatCeil(CGFloat x) {\n#if CGFLOAT_IS_DOUBLE\n  return (CGFloat)ceil(x);\n#else\n  return (CGFloat)ceilf(x);\n#endif\n}\n\n/**\n * round()/roundf() sized for CGFloat\n */\nCG_INLINE CGFloat NICGFloatRound(CGFloat x) {\n#if CGFLOAT_IS_DOUBLE\n  return (CGFloat)round(x);\n#else\n  return (CGFloat)roundf(x);\n#endif\n}\n\n/**\n * sqrt()/sqrtf() sized for CGFloat\n */\nCG_INLINE CGFloat NICGFloatSqRt(CGFloat x) {\n#if CGFLOAT_IS_DOUBLE\n  return (CGFloat)sqrt(x);\n#else\n  return (CGFloat)sqrtf(x);\n#endif\n}\n\n/**\n * copysign()/copysignf() sized for CGFloat\n */\nCG_INLINE CGFloat NICGFloatCopySign(CGFloat x, CGFloat y) {\n#if CGFLOAT_IS_DOUBLE\n  return (CGFloat)copysign(x, y);\n#else\n  return (CGFloat)copysignf(x, y);\n#endif\n}\n\n/**\n * pow()/powf() sized for CGFloat\n */\nCG_INLINE CGFloat NICGFloatPow(CGFloat x, CGFloat y) {\n#if CGFLOAT_IS_DOUBLE\n  return (CGFloat)pow(x, y);\n#else\n  return (CGFloat)powf(x, y);\n#endif\n}\n\n/**\n * cos()/cosf() sized for CGFloat\n */\nCG_INLINE CGFloat NICGFloatCos(CGFloat x) {\n#if CGFLOAT_IS_DOUBLE\n  return (CGFloat)cos(x);\n#else\n  return (CGFloat)cosf(x);\n#endif\n}\n\n/**@}*/\n\n#pragma mark - General Purpose Methods\n\n/**\n * For general purpose foundation type manipulation.\n *\n * @defgroup General-Purpose-Methods General Purpose Methods\n * @{\n */\n\n/**\n * Deprecated method. Use NIBoundf instead.\n */\nCGFloat boundf(CGFloat value, CGFloat min, CGFloat max) __NI_DEPRECATED_METHOD; // Use NIBoundf instead. MAINTENANCE: Remove by Feb 28, 2014.\n\n/**\n * Bounds a given value within the min and max values.\n *\n * If max < min then value will be min.\n *\n * @returns min <= result <= max\n */\nCGFloat NIBoundf(CGFloat value, CGFloat min, CGFloat max);\n\n/**\n * Bounds a given value within the min and max values.\n *\n * If max < min then value will be min.\n *\n * @returns min <= result <= max\n */\nNSInteger NIBoundi(NSInteger value, NSInteger min, NSInteger max);\n\n/**@}*/\n\n#if defined __cplusplus\n}\n#endif\n\n/**@}*/// End of Foundation Methods ///////////////////////////////////////////////////////////////\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIFoundationMethods.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIFoundationMethods.h\"\n\n#import \"NIDebuggingTools.h\"\n#import <CommonCrypto/CommonDigest.h>\n#import <objc/runtime.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n#pragma mark - NSInvocation\n\nNSInvocation* NIInvocationWithInstanceTarget(NSObject *targetObject, SEL selector) {\n  NSMethodSignature* sig = [targetObject methodSignatureForSelector:selector];\n  NSInvocation* inv = [NSInvocation invocationWithMethodSignature:sig];\n  [inv setTarget:targetObject];\n  [inv setSelector:selector];\n  return inv;\n}\n\n// Deprecated. Please delete on the next minor version upgrade.\nNSInvocation* NIInvocationWithClassTarget(Class targetClass, SEL selector) {\n  return NIInvocationWithInstanceTarget((NSObject *)targetClass, selector);\n}\n\n#pragma mark - CGRect\n\nCGRect NIRectContract(CGRect rect, CGFloat dx, CGFloat dy) {\n  return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width - dx, rect.size.height - dy);\n}\n\nCGRect NIRectExpand(CGRect rect, CGFloat dx, CGFloat dy) {\n  return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width + dx, rect.size.height + dy);\n}\n\nCGRect NIRectShift(CGRect rect, CGFloat dx, CGFloat dy) {\n  return CGRectOffset(NIRectContract(rect, dx, dy), dx, dy);\n}\n\nCGRect NIEdgeInsetsOutsetRect(CGRect rect, UIEdgeInsets outsets) {\n  return CGRectMake(rect.origin.x - outsets.left,\n                    rect.origin.y - outsets.top,\n                    rect.size.width + outsets.left + outsets.right,\n                    rect.size.height + outsets.top + outsets.bottom);\n}\n\nCGFloat NICenterX(CGSize containerSize, CGSize size) {\n  return NICGFloatFloor((containerSize.width - size.width) / 2.f);\n}\n\nCGFloat NICenterY(CGSize containerSize, CGSize size) {\n  return NICGFloatFloor((containerSize.height - size.height) / 2.f);\n}\n\nCGRect NIFrameOfCenteredViewWithinView(UIView* viewToCenter, UIView* containerView) {\n  CGPoint origin;\n  CGSize containerViewSize = containerView.bounds.size;\n  CGSize viewSize = viewToCenter.frame.size;\n  origin.x = NICenterX(containerViewSize, viewSize);\n  origin.y = NICenterY(containerViewSize, viewSize);\n  return CGRectMake(origin.x, origin.y, viewSize.width, viewSize.height);\n}\n\nCGSize NISizeOfStringWithLabelProperties(NSString *string, CGSize constrainedToSize, UIFont *font, NSLineBreakMode lineBreakMode, NSInteger numberOfLines) {\n  if (string.length == 0) {\n    return CGSizeZero;\n  }\n\n  CGFloat lineHeight = font.lineHeight;\n  CGSize size = CGSizeZero;\n\n  if (numberOfLines == 1) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n    size = [string sizeWithFont:font forWidth:constrainedToSize.width lineBreakMode:lineBreakMode];\n#pragma clang diagnostic pop\n  } else {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n    size = [string sizeWithFont:font constrainedToSize:constrainedToSize lineBreakMode:lineBreakMode];\n#pragma clang diagnostic pop\n    if (numberOfLines > 0) {\n      size.height = MIN(size.height, numberOfLines * lineHeight);\n    }\n  }\n\n  return size;\n}\n\n#pragma mark - NSRange\n\nNSRange NIMakeNSRangeFromCFRange(CFRange range) {\n  // CFRange stores its values in signed longs, but we're about to copy the values into\n  // unsigned integers, let's check whether we're about to lose any information.\n  NIDASSERT(range.location >= 0 && range.location <= NSIntegerMax);\n  NIDASSERT(range.length >= 0 && range.length <= NSIntegerMax);\n  return NSMakeRange(range.location, range.length);\n}\n\n#pragma mark - NSData\n\nNSString* NIMD5HashFromData(NSData* data) {\n  unsigned char result[CC_MD5_DIGEST_LENGTH];\n  bzero(result, sizeof(result));\n  CC_MD5_CTX md5Context;\n  CC_MD5_Init(&md5Context);\n  size_t bytesHashed = 0;\n  while (bytesHashed < [data length]) {\n    CC_LONG updateSize = 1024 * 1024;\n    if (([data length] - bytesHashed) < (size_t)updateSize) {\n      updateSize = (CC_LONG)([data length] - bytesHashed);\n    }\n    CC_MD5_Update(&md5Context, (char *)[data bytes] + bytesHashed, updateSize);\n    bytesHashed += updateSize;\n  }\n  CC_MD5_Final(result, &md5Context);\n\n  return [NSString stringWithFormat:\n          @\"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\",\n          result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],\n          result[8], result[9], result[10], result[11], result[12], result[13], result[14],\n          result[15]\n          ];\n}\n\nNSString* NISHA1HashFromData(NSData* data) {\n  unsigned char result[CC_SHA1_DIGEST_LENGTH];\n  bzero(result, sizeof(result));\n  CC_SHA1_CTX sha1Context;\n  CC_SHA1_Init(&sha1Context);\n  size_t bytesHashed = 0;\n  while (bytesHashed < [data length]) {\n    CC_LONG updateSize = 1024 * 1024;\n    if (([data length] - bytesHashed) < (size_t)updateSize) {\n      updateSize = (CC_LONG)([data length] - bytesHashed);\n    }\n    CC_SHA1_Update(&sha1Context, (char *)[data bytes] + bytesHashed, updateSize);\n    bytesHashed += updateSize;\n  }\n  CC_SHA1_Final(result, &sha1Context);\n\n  return [NSString stringWithFormat:\n          @\"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\",\n          result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],\n          result[8], result[9], result[10], result[11], result[12], result[13], result[14],\n          result[15], result[16], result[17], result[18], result[19]\n          ];\n}\n\n#pragma mark - NSString\n\nNSString* NIMD5HashFromString(NSString* string) {\n  return NIMD5HashFromData([string dataUsingEncoding:NSUTF8StringEncoding]);\n}\n\nNSString* NISHA1HashFromString(NSString* string) {\n  return NISHA1HashFromData([string dataUsingEncoding:NSUTF8StringEncoding]);\n}\n\nBOOL NIIsStringWithWhitespaceAndNewlines(NSString* string) {\n  NSCharacterSet* notWhitespaceAndNewlines = [[NSCharacterSet whitespaceAndNewlineCharacterSet] invertedSet];\n  return [string isKindOfClass:[NSString class]] && [string rangeOfCharacterFromSet:notWhitespaceAndNewlines].length == 0;\n}\n\nNSComparisonResult NICompareVersionStrings(NSString* string1, NSString* string2) {\n  NSArray *oneComponents = [string1 componentsSeparatedByString:@\"a\"];\n  NSArray *twoComponents = [string2 componentsSeparatedByString:@\"a\"];\n\n  // The parts before the \"a\"\n  NSString *oneMain = [oneComponents objectAtIndex:0];\n  NSString *twoMain = [twoComponents objectAtIndex:0];\n\n  // If main parts are different, return that result, regardless of alpha part\n  NSComparisonResult mainDiff;\n  if ((mainDiff = [oneMain compare:twoMain]) != NSOrderedSame) {\n    return mainDiff;\n  }\n\n  // At this point the main parts are the same; just deal with alpha stuff\n  // If one has an alpha part and the other doesn't, the one without is newer\n  if ([oneComponents count] < [twoComponents count]) {\n    return NSOrderedDescending;\n\n  } else if ([oneComponents count] > [twoComponents count]) {\n    return NSOrderedAscending;\n\n  } else if ([oneComponents count] == 1) {\n    // Neither has an alpha part, and we know the main parts are the same\n    return NSOrderedSame;\n  }\n\n  // At this point the main parts are the same and both have alpha parts. Compare the alpha parts\n  // numerically. If it's not a valid number (including empty string) it's treated as zero.\n  NSNumber *oneAlpha = [NSNumber numberWithInt:[[oneComponents objectAtIndex:1] intValue]];\n  NSNumber *twoAlpha = [NSNumber numberWithInt:[[twoComponents objectAtIndex:1] intValue]];\n  return [oneAlpha compare:twoAlpha];\n}\n\n\nNSDictionary* NIQueryDictionaryFromString(NSString* string) {\n  NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@\"&;\"];\n  NSMutableDictionary* pairs = [NSMutableDictionary dictionary];\n  NSScanner* scanner = [[NSScanner alloc] initWithString:string];\n\n  while (![scanner isAtEnd]) {\n    NSString* pairString = nil;\n    [scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString];\n    [scanner scanCharactersFromSet:delimiterSet intoString:NULL];\n\n    NSArray* kvPair = [pairString componentsSeparatedByString:@\"=\"];\n    if (kvPair.count == 1 || kvPair.count == 2) {\n      NSString* key = [kvPair[0] stringByRemovingPercentEncoding];\n\n      NSMutableArray* values = pairs[key];\n      if (nil == values) {\n        values = [NSMutableArray array];\n        pairs[key] = values;\n      }\n\n      if (kvPair.count == 1) {\n        [values addObject:[NSNull null]];\n\n      } else if (kvPair.count == 2) {\n        NSString* value = [kvPair[1] stringByRemovingPercentEncoding];\n        [values addObject:value];\n      }\n    }\n  }\n  return [pairs copy];\n}\n\nNSDictionary* NIQueryDictionaryFromStringUsingEncoding(NSString* string, NSStringEncoding encoding) {\n  NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@\"&;\"];\n  NSMutableDictionary* pairs = [NSMutableDictionary dictionary];\n  NSScanner* scanner = [[NSScanner alloc] initWithString:string];\n\n  while (![scanner isAtEnd]) {\n    NSString* pairString = nil;\n    [scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString];\n    [scanner scanCharactersFromSet:delimiterSet intoString:NULL];\n\n    NSArray* kvPair = [pairString componentsSeparatedByString:@\"=\"];\n    if (kvPair.count == 1 || kvPair.count == 2) {\n      NSString* key = [kvPair[0] stringByReplacingPercentEscapesUsingEncoding:encoding];\n\n      NSMutableArray* values = pairs[key];\n      if (nil == values) {\n        values = [NSMutableArray array];\n        pairs[key] = values;\n      }\n\n      if (kvPair.count == 1) {\n        [values addObject:[NSNull null]];\n\n      } else if (kvPair.count == 2) {\n        NSString* value = [kvPair[1] stringByReplacingPercentEscapesUsingEncoding:encoding];\n        [values addObject:value];\n      }\n    }\n  }\n  return [pairs copy];\n}\n\nNSString* NIStringByAddingPercentEscapesForURLParameterString(NSString* parameter) {\n  CFStringRef buffer = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,\n                                                               (__bridge CFStringRef)parameter,\n                                                               NULL,\n                                                               (__bridge CFStringRef)@\"!*'();:@&=+$,/?%#[]\",\n                                                               kCFStringEncodingUTF8);\n\n  NSString* result = [NSString stringWithString:(__bridge NSString *)buffer];\n  CFRelease(buffer);\n  return result;\n}\n\nNSString* NIStringByAddingQueryDictionaryToString(NSString* string, NSDictionary* query) {\n  NSMutableArray* pairs = [NSMutableArray array];\n  for (NSString* key in [query keyEnumerator]) {\n    NSString* value = NIStringByAddingPercentEscapesForURLParameterString([query objectForKey:key]);\n    NSString* pair = [NSString stringWithFormat:@\"%@=%@\", key, value];\n    [pairs addObject:pair];\n  }\n\n  NSString* params = [pairs componentsJoinedByString:@\"&\"];\n  if ([string rangeOfString:@\"?\"].location == NSNotFound) {\n    return [string stringByAppendingFormat:@\"?%@\", params];\n\n  } else {\n    return [string stringByAppendingFormat:@\"&%@\", params];\n  }\n}\n\n#pragma mark - General Purpose\n\n// Deprecated.\nCGFloat boundf(CGFloat value, CGFloat min, CGFloat max) {\n  return NIBoundf(value, min, max);\n}\n\nCGFloat NIBoundf(CGFloat value, CGFloat min, CGFloat max) {\n  if (max < min) {\n    max = min;\n  }\n  CGFloat bounded = value;\n  if (bounded > max) {\n    bounded = max;\n  }\n  if (bounded < min) {\n    bounded = min;\n  }\n  return bounded;\n}\n\nNSInteger NIBoundi(NSInteger value, NSInteger min, NSInteger max) {\n  if (max < min) {\n    max = min;\n  }\n  NSInteger bounded = value;\n  if (bounded > max) {\n    bounded = max;\n  }\n  if (bounded < min) {\n    bounded = min;\n  }\n  return bounded;\n}\n"
  },
  {
    "path": "src/core/src/NIImageUtilities.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nAPI_DEPRECATED_BEGIN(\"Use UIImage APIs instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For manipulating UIImage objects.\n *\n * @ingroup NimbusCore\n * @defgroup Image-Utilities Image Utilities\n * @{\n */\n\n/**\n * Returns an image that is stretchable from the center.\n *\n * A common use of this method is to create an image that has rounded corners for a button\n * and then assign a stretchable version of that image to a UIButton.\n *\n * This stretches the middle vertical and horizontal line of pixels, so use care when\n * stretching images that have gradients. For example, an image with a vertical gradient\n * can be stretched horizontally, but will look odd if stretched vertically.\n */\nUIImage* NIStretchableImageFromImage(UIImage* image)\n    API_UNAVAILABLE(tvos, watchos);\n\n/**@}*/// End of Image Utilities //////////////////////////////////////////////////////////////////\n\n#if defined __cplusplus\n}\n#endif\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIImageUtilities.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIImageUtilities.h\"\n\nUIImage* NIStretchableImageFromImage(UIImage* image) {\n  const CGSize size = image.size;\n  NSInteger midX = (NSInteger)(size.width / 2.f);\n  NSInteger midY = (NSInteger)(size.height / 2.f);\n  return [image stretchableImageWithLeftCapWidth:midX topCapHeight:midY];\n}\n"
  },
  {
    "path": "src/core/src/NIInMemoryCache.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"NIPreprocessorMacros.h\"\n\nAPI_DEPRECATED_BEGIN(\"Use NSCache instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n/**\n * For storing and accessing objects in memory.\n *\n * The base class, NIMemoryCache, is a generic object store that may be used for anything that\n * requires support for expiration.\n *\n * @ingroup NimbusCore\n * @defgroup In-Memory-Caches In-Memory Caches\n * @{\n */\n\n/**\n * An in-memory cache for storing objects with expiration support.\n *\n * The Nimbus in-memory object cache allows you to store objects in memory with an expiration\n * date attached. Objects with expiration dates drop out of the cache when they have expired.\n */\n@interface NIMemoryCache : NSObject\n\n// Designated initializer.\n- (id)initWithCapacity:(NSUInteger)capacity;\n\n- (NSUInteger)count;\n\n- (void)storeObject:(id)object withName:(NSString *)name;\n- (void)storeObject:(id)object withName:(NSString *)name expiresAfter:(NSDate *)expirationDate;\n\n- (void)removeObjectWithName:(NSString *)name;\n- (void)removeAllObjectsWithPrefix:(NSString *)prefix;\n- (void)removeAllObjects;\n\n- (id)objectWithName:(NSString *)name;\n- (BOOL)containsObjectWithName:(NSString *)name;\n- (NSDate *)dateOfLastAccessWithName:(NSString *)name;\n\n- (NSString *)nameOfLeastRecentlyUsedObject;\n- (NSString *)nameOfMostRecentlyUsedObject;\n\n- (void)reduceMemoryUsage;\n\n// Subclassing\n\n- (BOOL)shouldSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject;\n- (void)didSetObject:(id)object withName:(NSString *)name;\n- (void)willRemoveObject:(id)object withName:(NSString *)name;\n\n// Deprecated method. Use shouldSetObject:withName:previousObject: instead.\n- (BOOL)willSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject __NI_DEPRECATED_METHOD;\n\n@end\n\n/**\n * An in-memory cache for storing images with caps on the total number of pixels.\n *\n * When reduceMemoryUsage is called, the least recently used images are removed from the cache\n * until the numberOfPixels is below maxNumberOfPixelsUnderStress.\n *\n * When an image is added to the cache that causes the memory usage to pass the max, the\n * least recently used images are removed from the cache until the numberOfPixels is below\n * maxNumberOfPixels.\n *\n * By default the image memory cache has no limit to its pixel count. You must explicitly\n * set this value in your application.\n *\n * @attention If the cache is too small to fit the newly added image, then all images\n *                 will end up being removed including the one being added.\n *\n * @see Nimbus::imageMemoryCache\n * @see Nimbus::setImageMemoryCache:\n */\n@interface NIImageMemoryCache : NIMemoryCache\n\n@property (nonatomic, readonly) unsigned long long numberOfPixels;\n\n@property (nonatomic)           unsigned long long maxNumberOfPixels;             // Default: 0 (unlimited)\n@property (nonatomic)           unsigned long long maxNumberOfPixelsUnderStress;  // Default: 0 (unlimited)\n\n@end\n\n/**@}*/// End of In-Memory Cache //////////////////////////////////////////////////////////////////\n\n/** @name Creating an In-Memory Cache */\n\n/**\n * Initializes a newly allocated cache with the given capacity.\n *\n * @returns An in-memory cache initialized with the given capacity.\n * @fn NIMemoryCache::initWithCapacity:\n */\n\n/** @name Storing Objects in the Cache */\n\n/**\n * Stores an object in the cache.\n *\n * The object will be stored without an expiration date. The object will stay in the cache until\n * it's bumped out due to the cache's memory limit.\n *\n * @param object  The object being stored in the cache.\n * @param name    The name used as a key to store this object.\n * @fn NIMemoryCache::storeObject:withName:\n */\n\n/**\n * Stores an object in the cache with an expiration date.\n *\n * If an object is stored with an expiration date that has already passed then the object will\n * not be stored in the cache and any existing object will be removed. The rationale behind this\n * is that the object would be removed from the cache the next time it was accessed anyway.\n *\n * @param object          The object being stored in the cache.\n * @param name            The name used as a key to store this object.\n * @param expirationDate  A date after which this object is no longer valid in the cache.\n * @fn NIMemoryCache::storeObject:withName:expiresAfter:\n */\n\n/** @name Removing Objects from the Cache */\n\n/**\n * Removes an object from the cache with the given name.\n *\n * @param name The name used as a key to store this object.\n * @fn NIMemoryCache::removeObjectWithName:\n */\n\n/**\n * Removes all objects from the cache with a given prefix.\n *\n * This method requires a scan of the cache entries.\n *\n * @param prefix Any object name that has this prefix will be removed from the cache.\n * @fn NIMemoryCache::removeAllObjectsWithPrefix:\n */\n\n/**\n * Removes all objects from the cache, regardless of expiration dates.\n *\n * This will completely clear out the cache and all objects in the cache will be released.\n *\n * @fn NIMemoryCache::removeAllObjects\n */\n\n/** @name Accessing Objects in the Cache */\n\n/**\n * Retrieves an object from the cache.\n *\n * If the object has expired then the object will be removed from the cache and nil will be\n * returned.\n *\n * @returns The object stored in the cache. The object is retained and autoreleased to\n *               ensure that it survives this run loop if you then remove it from the cache.\n * @fn NIMemoryCache::objectWithName:\n */\n\n/**\n * Returns a Boolean value that indicates whether an object with the given name is present\n * in the cache.\n *\n * Does not update the access time of the object.\n *\n * If the object has expired then the object will be removed from the cache and NO will be\n * returned.\n *\n * @returns YES if an object with the given name is present in the cache and has not expired,\n *               otherwise NO.\n * @fn NIMemoryCache::containsObjectWithName:\n */\n\n/**\n * Returns the date that the object with the given name was last accessed.\n *\n * Does not update the access time of the object.\n *\n * If the object has expired then the object will be removed from the cache and nil will be\n * returned.\n *\n * @returns The last access date of the object if it exists and has not expired, nil\n *               otherwise.\n * @fn NIMemoryCache::dateOfLastAccessWithName:\n */\n\n/**\n * Retrieve the name of the object that was least recently used.\n *\n * This will not update the access time of the object.\n *\n * If the cache is empty, returns nil.\n *\n * @fn NIMemoryCache::nameOfLeastRecentlyUsedObject\n */\n\n/**\n * Retrieve the key with the most fresh access.\n *\n * This will not update the access time of the object.\n *\n * If the cache is empty, returns nil.\n *\n * @fn NIMemoryCache::nameOfMostRecentlyUsedObject\n */\n\n/** @name Reducing Memory Usage Explicitly */\n\n/**\n * Removes all expired objects from the cache.\n *\n * Subclasses may add additional functionality to this implementation.\n * Subclasses should call super in order to prune expired objects.\n *\n * This will be called when <code>UIApplicationDidReceiveMemoryWarningNotification</code>\n * is posted.\n *\n * @fn NIMemoryCache::reduceMemoryUsage\n */\n\n/** @name Querying an In-Memory Cache */\n\n/**\n * Returns the number of objects currently in the cache.\n *\n * @returns The number of objects currently in the cache.\n * @fn NIMemoryCache::count\n */\n\n/**\n * @name Subclassing\n *\n * The following methods are provided to aid in subclassing and are not meant to be\n * used externally.\n */\n\n/**\n * An object is about to be stored in the cache.\n *\n * @param object          The object that is about to be stored in the cache.\n * @param name            The cache name for the object.\n * @param previousObject  The object previously stored in the cache. This may be the\n *                             same as object.\n * @returns YES If object is allowed to be stored in the cache.\n * @fn NIMemoryCache::shouldSetObject:withName:previousObject:\n */\n\n/**\n * This method is deprecated. Please use shouldSetObject:withName:previousObject: instead.\n *\n * @fn NIMemoryCache::willSetObject:withName:previousObject:\n */\n\n/**\n * An object has been stored in the cache.\n *\n * @param object          The object that was stored in the cache.\n * @param name            The cache name for the object.\n * @fn NIMemoryCache::didSetObject:withName:\n */\n\n/**\n * An object is about to be removed from the cache.\n *\n * @param object  The object about to removed from the cache.\n * @param name    The cache name for the object about to be removed.\n * @fn NIMemoryCache::willRemoveObject:withName:\n */\n\n// NIImageMemoryCache\n\n/** @name Querying an In-Memory Image Cache */\n\n/**\n * Returns the total number of pixels being stored in the cache.\n *\n * @returns The total number of pixels being stored in the cache.\n * @fn NIImageMemoryCache::numberOfPixels\n */\n\n/** @name Setting the Maximum Number of Pixels */\n\n/**\n * The maximum number of pixels this cache may ever store.\n *\n * Defaults to 0, which is special cased to represent an unlimited number of pixels.\n *\n * @returns The maximum number of pixels this cache may ever store.\n * @fn NIImageMemoryCache::maxNumberOfPixels\n */\n\n/**\n * The maximum number of pixels this cache may store after a call to reduceMemoryUsage.\n *\n * Defaults to 0, which is special cased to represent an unlimited number of pixels.\n *\n * @returns The maximum number of pixels this cache may store after a call\n *               to reduceMemoryUsage.\n * @fn NIImageMemoryCache::maxNumberOfPixelsUnderStress\n */\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIInMemoryCache.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIInMemoryCache.h\"\n\n#import \"NIDebuggingTools.h\"\n#import \"NIPreprocessorMacros.h\"\n\n#import <UIKit/UIKit.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NIMemoryCache()\n// Mapping from a name (usually a URL) to an internal object.\n@property (nonatomic, strong) NSMutableDictionary* cacheMap;\n// A linked list of least recently used cache objects. Most recently used is the tail.\n@property (nonatomic, strong) NSMutableOrderedSet* lruCacheObjects;\n@end\n\n/**\n * @brief A single cache item's information.\n *\n * Used in expiration calculations and for storing the actual cache object.\n */\n@interface NIMemoryCacheInfo : NSObject\n\n/**\n * @brief The name used to store this object in the cache.\n */\n@property (nonatomic, copy) NSString* name;\n\n/**\n * @brief The object stored in the cache.\n */\n@property (nonatomic, strong) id object;\n\n/**\n * @brief The date after which the image is no longer valid and should be removed from the cache.\n */\n@property (nonatomic, strong) NSDate* expirationDate;\n\n/**\n * @brief The last time this image was accessed.\n *\n * This property is updated every time the image is fetched from or stored into the cache. It\n * is used when the memory peak has been reached as a fast means of removing least-recently-used\n * images. When the memory limit is reached, we sort the cache based on the last access times and\n * then prune images until we're under the memory limit again.\n */\n@property (nonatomic, strong) NSDate* lastAccessTime;\n\n/**\n * @brief Determine whether this cache entry has past its expiration date.\n *\n * @returns YES if an expiration date has been specified and the expiration date has been passed.\n *          NO in all other cases. Notably if there is no expiration date then this object will\n *          never expire.\n */\n- (BOOL)hasExpired;\n\n@end\n\n@implementation NIMemoryCache\n\n- (void)dealloc {\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (id)init {\n  return [self initWithCapacity:0];\n}\n\n- (id)initWithCapacity:(NSUInteger)capacity {\n  if ((self = [super init])) {\n    _cacheMap = [[NSMutableDictionary alloc] initWithCapacity:capacity];\n    _lruCacheObjects = [NSMutableOrderedSet orderedSet];\n\n    // Automatically reduce memory usage when we get a memory warning.\n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(reduceMemoryUsage)\n                                                 name:UIApplicationDidReceiveMemoryWarningNotification\n                                               object:nil];\n  }\n  return self;\n}\n\n- (NSString *)description {\n  return [NSString stringWithFormat:\n          @\"<%@\"\n          @\" lruObjects: %@\"\n          @\" cache map: %@\"\n          @\">\",\n          [super description],\n          self.lruCacheObjects,\n          self.cacheMap];\n}\n\n#pragma mark - Internal\n\n- (void)updateAccessTimeForInfo:(NIMemoryCacheInfo *)info {\n  @synchronized(self) {\n    NIDASSERT(nil != info);\n    if (nil == info) {\n      return; // COV_NF_LINE\n    }\n    info.lastAccessTime = [NSDate date];\n\n    [self.lruCacheObjects removeObject:info];\n    [self.lruCacheObjects addObject:info];\n  }\n}\n\n- (NIMemoryCacheInfo *)cacheInfoForName:(NSString *)name {\n  NIMemoryCacheInfo* info;\n  @synchronized(self) {\n    info = self.cacheMap[name];\n  }\n  return info;\n}\n\n- (void)setCacheInfo:(NIMemoryCacheInfo *)info forName:(NSString *)name {\n  @synchronized(self) {\n    NIDASSERT(nil != name);\n    if (nil == name) {\n      return;\n    }\n\n    // Storing in the cache counts as an access of the object, so we update the access time.\n    [self updateAccessTimeForInfo:info];\n\n    id previousObject = [self cacheInfoForName:name].object;\n    if ([self shouldSetObject:info.object withName:name previousObject:previousObject]) {\n      self.cacheMap[name] = info;\n      [self didSetObject:info.object withName:name];\n    }\n  }\n}\n\n- (void)removeCacheInfoForName:(NSString *)name {\n  @synchronized(self) {\n    NIDASSERT(nil != name);\n    if (nil == name) {\n      return;\n    }\n\n    NIMemoryCacheInfo* cacheInfo = [self cacheInfoForName:name];\n    [self willRemoveObject:cacheInfo.object withName:name];\n\n    [self.lruCacheObjects removeObject:cacheInfo];\n    [self.cacheMap removeObjectForKey:name];\n  }\n}\n\n#pragma mark - Subclassing\n\n// Deprecated method.\n- (BOOL)willSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject {\n  return [self shouldSetObject:object withName:name previousObject:previousObject];\n}\n\n- (BOOL)shouldSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject {\n  // Allow anything to be stored.\n  return YES;\n}\n\n- (void)didSetObject:(id)object withName:(NSString *)name {\n  // No-op\n}\n\n- (void)willRemoveObject:(id)object withName:(NSString *)name {\n  // No-op\n}\n\n#pragma mark - Public\n\n- (void)storeObject:(id)object withName:(NSString *)name {\n  @synchronized(self) {\n    [self storeObject:object withName:name expiresAfter:nil];\n  }\n}\n\n- (void)storeObject:(id)object withName:(NSString *)name expiresAfter:(NSDate *)expirationDate {\n  @synchronized(self) {\n    // Don't store nil objects in the cache.\n    if (nil == object) {\n      return;\n    }\n\n    if (nil != expirationDate && [[NSDate date] timeIntervalSinceDate:expirationDate] >= 0) {\n      // The object being stored is already expired so remove the object from the cache altogether.\n      [self removeObjectWithName:name];\n\n      // We're done here.\n      return;\n    }\n\n    NIMemoryCacheInfo* info = [self cacheInfoForName:name];\n\n    // Create a new cache entry.\n    if (nil == info) {\n      info = [[NIMemoryCacheInfo alloc] init];\n      info.name = name;\n    }\n\n    // Store the object in the cache item.\n    info.object = object;\n\n    // Override any existing expiration date.\n    info.expirationDate = expirationDate;\n\n    // Commit the changes to the cache.\n    [self setCacheInfo:info forName:name];\n  }\n}\n\n- (id)objectWithName:(NSString *)name {\n  @synchronized(self) {\n    NIMemoryCacheInfo* info = [self cacheInfoForName:name];\n\n    id object = nil;\n\n    if (nil != info) {\n      if ([info hasExpired]) {\n        [self removeObjectWithName:name];\n\n      } else {\n        // Update the access time whenever we fetch an object from the cache.\n        [self updateAccessTimeForInfo:info];\n\n        object = info.object;\n      }\n    }\n\n    return object;\n  }\n}\n\n- (BOOL)containsObjectWithName:(NSString *)name {\n  @synchronized(self) {\n    NIMemoryCacheInfo* info = [self cacheInfoForName:name];\n\n    if ([info hasExpired]) {\n      [self removeObjectWithName:name];\n      return NO;\n    }\n\n    return (nil != info);\n  }\n}\n\n- (NSDate *)dateOfLastAccessWithName:(NSString *)name {\n  @synchronized(self) {\n    NIMemoryCacheInfo* info = [self cacheInfoForName:name];\n\n    if ([info hasExpired]) {\n      [self removeObjectWithName:name];\n      return nil;\n    }\n\n    return [info lastAccessTime];\n  }\n}\n\n- (NSString *)nameOfLeastRecentlyUsedObject {\n  @synchronized(self) {\n    NIMemoryCacheInfo* info = [self.lruCacheObjects firstObject];\n\n    if ([info hasExpired]) {\n      [self removeObjectWithName:info.name];\n      return nil;\n    }\n\n    return info.name;\n  }\n}\n\n- (NSString *)nameOfMostRecentlyUsedObject {\n  @synchronized(self) {\n    NIMemoryCacheInfo* info = [self.lruCacheObjects lastObject];\n\n    if ([info hasExpired]) {\n      [self removeObjectWithName:info.name];\n      return nil;\n    }\n\n    return info.name;\n  }\n}\n\n- (void)removeObjectWithName:(NSString *)name {\n  @synchronized(self) {\n    [self removeCacheInfoForName:name];\n  }\n}\n\n- (void)removeAllObjectsWithPrefix:(NSString *)prefix {\n  @synchronized(self) {\n    // Assertions fire if you try to modify the object you're iterating over, so we make a copy.\n    for (NSString* name in [self.cacheMap copy]) {\n      if ([name hasPrefix:prefix]) {\n        [self removeObjectWithName:name];\n      }\n    }\n  }\n}\n\n- (void)removeAllObjects {\n  @synchronized(self) {\n    [self.cacheMap removeAllObjects];\n    [self.lruCacheObjects removeAllObjects];\n  }\n}\n\n- (void)reduceMemoryUsage {\n  @synchronized(self) {\n    // Assertions fire if you try to modify the object you're iterating over, so we make a copy.\n    for (id name in [self.cacheMap copy]) {\n      NIMemoryCacheInfo* info = [self cacheInfoForName:name];\n\n      if ([info hasExpired]) {\n        [self removeCacheInfoForName:name];\n      }\n    }\n  }\n}\n\n- (NSUInteger)count {\n  @synchronized(self) {\n    return self.cacheMap.count;\n  }\n}\n\n@end\n\n@implementation NIMemoryCacheInfo\n\n- (BOOL)hasExpired {\n  return (nil != _expirationDate\n          && [[NSDate date] timeIntervalSinceDate:_expirationDate] >= 0);\n}\n\n- (NSString *)description {\n  return [NSString stringWithFormat:\n          @\"<%@\"\n          @\" name: %@\"\n          @\" object: %@\"\n          @\" expiration date: %@\"\n          @\" last access time: %@\"\n          @\">\",\n          [super description],\n          self.name,\n          self.object,\n          self.expirationDate,\n          self.lastAccessTime];\n}\n\n@end\n\n@interface NIImageMemoryCache()\n@property (nonatomic, assign) unsigned long long numberOfPixels;\n@end\n\n@implementation NIImageMemoryCache\n\n- (unsigned long long)numberOfPixelsUsedByImage:(UIImage *)image {\n  @synchronized(self) {\n    if (nil == image) {\n      return 0;\n    }\n\n    return (unsigned long long)(image.size.width * image.size.height * [image scale] * [image scale]);\n  }\n}\n\n- (void)removeAllObjects {\n  @synchronized(self) {\n    [super removeAllObjects];\n\n    self.numberOfPixels = 0;\n  }\n}\n\n- (void)reduceMemoryUsage {\n  @synchronized(self) {\n    // Remove all expired images first.\n    [super reduceMemoryUsage];\n\n    if (self.maxNumberOfPixelsUnderStress > 0) {\n      // Remove the least recently used images by iterating over the linked list.\n      while (self.numberOfPixels > self.maxNumberOfPixelsUnderStress) {\n        NIMemoryCacheInfo* info = [self.lruCacheObjects firstObject];\n        [self removeCacheInfoForName:info.name];\n      }\n    }\n  }\n}\n\n- (BOOL)shouldSetObject:(id)object withName:(NSString *)name previousObject:(id)previousObject {\n  @synchronized(self) {\n    NIDASSERT(nil == object || [object isKindOfClass:[UIImage class]]);\n    if (![object isKindOfClass:[UIImage class]]) {\n      return NO;\n    }\n\n    _numberOfPixels -= [self numberOfPixelsUsedByImage:previousObject];\n    _numberOfPixels += [self numberOfPixelsUsedByImage:object];\n\n    return YES;\n  }\n}\n\n- (void)didSetObject:(id)object withName:(NSString *)name {\n  @synchronized(self) {\n    // Reduce the cache size after the object has been set in case the cache size is smaller\n    // than the object that's being added and we need to remove this object right away.\n    if (self.maxNumberOfPixels > 0) {\n      // Remove least recently used images until we satisfy our memory constraints.\n      while (self.numberOfPixels > self.maxNumberOfPixels) {\n        NIMemoryCacheInfo* info = [self.lruCacheObjects firstObject];\n        [self removeCacheInfoForName:info.name];\n      }\n    }\n  }\n}\n\n- (void)willRemoveObject:(id)object withName:(NSString *)name {\n  @synchronized(self) {\n    NIDASSERT(nil == object || [object isKindOfClass:[UIImage class]]);\n    if (nil == object || ![object isKindOfClass:[UIImage class]]) {\n      return;\n    }\n\n    self.numberOfPixels -= [self numberOfPixelsUsedByImage:object];\n  }\n}\n\n@end\n\n"
  },
  {
    "path": "src/core/src/NINetworkActivity.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 July 2, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"NIPreprocessorMacros.h\"\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For showing network activity in the device's status bar.\n *\n * @ingroup NimbusCore\n * @defgroup Network-Activity Network Activity\n * @{\n *\n * Two methods for keeping track of all active network tasks. These methods are threadsafe\n * and act as a simple counter. When the counter is positive, the network activity indicator\n * is displayed.\n */\n\n/**\n * Increment the number of active network tasks.\n *\n * The status bar activity indicator will be spinning while there are active tasks.\n *\n * This method is threadsafe.\n */\nvoid NINetworkActivityTaskDidStart(void) NI_EXTENSION_UNAVAILABLE_IOS(\"\")\n    API_UNAVAILABLE(tvos, watchos);\n\n/**\n * Decrement the number of active network tasks.\n *\n * The status bar activity indicator will be spinning while there are active tasks.\n *\n * This method is threadsafe.\n */\nvoid NINetworkActivityTaskDidFinish(void) API_UNAVAILABLE(tvos, watchos);\n\n/**\n * @name For Debugging Only\n * @{\n *\n * Methods that will only do anything interesting if the DEBUG preprocessor macro is defined.\n */\n\n/**\n * Enable network activity debugging.\n *\n * @attention This won't do anything unless the DEBUG preprocessor macro is defined.\n *\n * The Nimbus network activity methods will only work correctly if they are the only methods to\n * touch networkActivityIndicatorVisible. If you are using another library that touches\n * networkActivityIndicatorVisible then the network activity indicator might not accurately\n * represent its state.\n *\n * When enabled, the networkActivityIndicatorVisible method on UIApplication will be swizzled\n * with a debugging method that checks the global network task count and verifies that state\n * is maintained correctly. If it is found that networkActivityIndicatorVisible is being accessed\n * directly, then an assertion will be fired.\n *\n * If debugging was previously enabled, this does nothing.\n */\nvoid NIEnableNetworkActivityDebugging(void) API_UNAVAILABLE(tvos, watchos);\n\n/**\n * Disable network activity debugging.\n *\n * @attention This won't do anything unless the DEBUG preprocessor macro is defined.\n *\n * When disabled, the networkActivityIndicatorVisible will be restored if this was previously\n * enabled, otherwise this method does nothing.\n *\n * If debugging wasn't previously enabled, this does nothing.\n */\nvoid NIDisableNetworkActivityDebugging(void) API_UNAVAILABLE(tvos, watchos);\n\n/**@}*/// End of For Debugging Only\n\n#if defined __cplusplus\n}\n#endif\n\n/**@}*/// End of Network Activity /////////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "src/core/src/NINetworkActivity.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NINetworkActivity.h\"\n\n#import \"NIDebuggingTools.h\"\n#import \"NIPreprocessorMacros.h\"\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n#import \"NIRuntimeClassModifications.h\"\n#endif\n\n#import <pthread.h>\n#import <UIKit/UIKit.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic int              gNetworkTaskCount = 0;\nstatic pthread_mutex_t  gMutex = PTHREAD_MUTEX_INITIALIZER;\nstatic const NSTimeInterval kDelayBeforeDisablingActivity = 0.1;\nstatic NSTimer* gScheduledDelayTimer = nil;\n\nAPI_UNAVAILABLE(tvos, watchos)\n@interface NINetworkActivity : NSObject\n@end\n\n\n@implementation NINetworkActivity\n\n\n// Called after a certain amount of time has passed since all network activity has stopped.\n// By delaying the turnoff of the network activity we avoid \"flickering\" effects when network\n// activity is starting and stopping rapidly.\n+ (void)disableNetworkActivity NI_EXTENSION_UNAVAILABLE_IOS(\"\") {\n  pthread_mutex_lock(&gMutex);\n  if (nil != gScheduledDelayTimer) {\n    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;\n    gScheduledDelayTimer = nil;\n  }\n  pthread_mutex_unlock(&gMutex);\n}\n\n@end\n\n\nvoid NINetworkActivityTaskDidStart(void) {\n  pthread_mutex_lock(&gMutex);\n\n  BOOL enableNetworkActivityIndicator = (0 == gNetworkTaskCount);\n\n  ++gNetworkTaskCount;\n  [gScheduledDelayTimer invalidate];\n  gScheduledDelayTimer = nil;\n\n  if (enableNetworkActivityIndicator) {\n    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;\n  }\n\n  pthread_mutex_unlock(&gMutex);\n}\n\nvoid NINetworkActivityTaskDidFinish(void) {\n  pthread_mutex_lock(&gMutex);\n\n  --gNetworkTaskCount;\n  // If this asserts, you don't have enough stop requests to match your start requests.\n  NIDASSERT(gNetworkTaskCount >= 0);\n  gNetworkTaskCount = MAX(0, gNetworkTaskCount);\n\n  if (gNetworkTaskCount == 0) {\n    [gScheduledDelayTimer invalidate];\n    gScheduledDelayTimer = nil;\n\n    // Ensure that the timer is scheduled on the main loop, otherwise it will die when the thread\n    // dies.\n    dispatch_async(dispatch_get_main_queue(), ^{\n      pthread_mutex_lock(&gMutex);\n      gScheduledDelayTimer = [NSTimer scheduledTimerWithTimeInterval:kDelayBeforeDisablingActivity\n                                                              target:[NINetworkActivity class]\n                                                            selector:@selector(disableNetworkActivity)\n                                                            userInfo:nil\n                                                             repeats:NO];\n      pthread_mutex_unlock(&gMutex);\n    });\n  }\n\n  pthread_mutex_unlock(&gMutex);\n}\n\n#pragma mark - Network Activity Debugging\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\nstatic BOOL gNetworkActivityDebuggingEnabled = NO;\n\nvoid NISwizzleMethodsForNetworkActivityDebugging(void);\n\n@implementation UIApplication (NimbusNetworkActivityDebugging)\n\n\n- (void)nimbusDebugSetNetworkActivityIndicatorVisible:(BOOL)visible {\n  // This method will only be used when swizzled, so this will actually call\n  // setNetworkActivityIndicatorVisible:\n  [self nimbusDebugSetNetworkActivityIndicatorVisible:visible];\n\n  // Sanity check that this method isn't being called directly when debugging isn't enabled.\n  NIDASSERT(gNetworkActivityDebuggingEnabled);\n\n  // If either of the following assertions fail then you should look at the call stack to\n  // determine what code is erroneously calling setNetworkActivityIndicatorVisible: directly.\n  if (visible) {\n    // The only time we should be enabling the network activity indicator is when the task\n    // count is one.\n    NIDASSERT(1 == gNetworkTaskCount);\n\n  } else {\n    // The only time we should be disabling the network activity indicator is when the task\n    // count is zero.\n    NIDASSERT(0 == gNetworkTaskCount);\n  }\n}\n\n@end\n\n\nvoid NISwizzleMethodsForNetworkActivityDebugging(void) {\n  NISwapInstanceMethods([UIApplication class],\n                        @selector(setNetworkActivityIndicatorVisible:),\n                        @selector(nimbusDebugSetNetworkActivityIndicatorVisible:));\n}\n\nvoid NIEnableNetworkActivityDebugging(void) {\n  if (!gNetworkActivityDebuggingEnabled) {\n    gNetworkActivityDebuggingEnabled = YES;\n    NISwizzleMethodsForNetworkActivityDebugging();\n  }\n}\n\nvoid NIDisableNetworkActivityDebugging(void) {\n  if (gNetworkActivityDebuggingEnabled) {\n    gNetworkActivityDebuggingEnabled = NO;\n    NISwizzleMethodsForNetworkActivityDebugging();\n  }\n}\n\n#else // #ifndef DEBUG\n\n\nvoid NIEnableNetworkActivityDebugging(void) {\n  // No-op\n}\n\nvoid NIDisableNetworkActivityDebugging(void) {\n  // No-op\n}\n\n#endif // #if defined(DEBUG) || defined(NI_DEBUG)\n"
  },
  {
    "path": "src/core/src/NINonEmptyCollectionTesting.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\nAPI_DEPRECATED_BEGIN(\"Use standard Foundation APIs instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For testing whether a collection is of a certain type and is non-empty.\n *\n * @ingroup NimbusCore\n * @defgroup Non-Empty-Collection-Testing Non-Empty Collection Testing\n * @{\n *\n * Simply calling -count on an object may not yield the expected results when enumerating it if\n * certain assumptions are also made about the object's type. For example, if a JSON response\n * returns a dictionary when you expected an array, casting the result to an NSArray and\n * calling count will yield a positive value, but objectAtIndex: will crash the application.\n * These methods provide a safer check for non-emptiness of collections.\n */\n\n/**\n * Tests if an object is a non-nil array which is not empty.\n */\nBOOL NIIsArrayWithObjects(id object);\n\n/**\n * Tests if an object is a non-nil set which is not empty.\n */\nBOOL NIIsSetWithObjects(id object);\n\n/**\n * Tests if an object is a non-nil string which is not empty.\n */\nBOOL NIIsStringWithAnyText(id object);\n\n#if defined __cplusplus\n}\n#endif\n\n/**@}*/// End of Non-Empty Collection Testing /////////////////////////////////////////////////////\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NINonEmptyCollectionTesting.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NINonEmptyCollectionTesting.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nBOOL NIIsArrayWithObjects(id object) {\n  return [object isKindOfClass:[NSArray class]] && [(NSArray*)object count] > 0;\n}\n\nBOOL NIIsSetWithObjects(id object) {\n  return [object isKindOfClass:[NSSet class]] && [(NSSet*)object count] > 0;\n}\n\nBOOL NIIsStringWithAnyText(id object) {\n  return [object isKindOfClass:[NSString class]] && [(NSString*)object length] > 0;\n}\n"
  },
  {
    "path": "src/core/src/NINonRetainingCollections.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For collections that don't retain their objects.\n *\n * @ingroup NimbusCore\n * @defgroup Non-Retaining-Collections Non-Retaining Collections\n * @{\n *\n * Non-retaining collections have historically been used when we needed more than one delegate\n * in an object. However, NSNotificationCenter is a much better solution for n > 1 delegates.\n * Using a non-retaining collection is dangerous, so if you must use one, use it with extreme care.\n * The danger primarily lies in the fact that by all appearances the collection should still\n * operate like a regular collection, so this might lead to a lot of developer error if the\n * developer assumes that the collection does, in fact, retain the object.\n */\n\n/**\n * Creates a mutable array which does not retain references to the objects it contains.\n *\n * Typically used with arrays of delegates.\n */\nNSMutableArray* NICreateNonRetainingMutableArray(void);\n\n/**\n * Creates a mutable dictionary which does not retain references to the values it contains.\n *\n * Typically used with dictionaries of delegates.\n */\nNSMutableDictionary* NICreateNonRetainingMutableDictionary(void);\n\n/**\n * Creates a mutable set which does not retain references to the values it contains.\n *\n * Typically used with sets of delegates.\n */\nNSMutableSet* NICreateNonRetainingMutableSet(void);\n\n#if defined __cplusplus\n}\n#endif\n\n/**@}*/// End of Non-Retaining Collections ////////////////////////////////////////////////////////\n"
  },
  {
    "path": "src/core/src/NINonRetainingCollections.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 9, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NINonRetainingCollections.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNSMutableArray* NICreateNonRetainingMutableArray(void) {\n  return (__bridge_transfer NSMutableArray *)CFArrayCreateMutable(nil, 0, nil);\n}\n\nNSMutableDictionary* NICreateNonRetainingMutableDictionary(void) {\n  return (__bridge_transfer NSMutableDictionary *)CFDictionaryCreateMutable(nil, 0, nil, nil);\n}\n\nNSMutableSet* NICreateNonRetainingMutableSet(void) {\n  return (__bridge_transfer NSMutableSet *)CFSetCreateMutable(nil, 0, nil);\n}\n\n"
  },
  {
    "path": "src/core/src/NIOperations+Subclassing.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n#import \"NIOperations.h\"\n\nAPI_DEPRECATED_BEGIN(\"Use NSOperation instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n@interface NIOperation()\n@property (strong) NSError* lastError;\n@end\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIOperations.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPreprocessorMacros.h\" /* for weak */\n\nAPI_DEPRECATED_BEGIN(\"Use NSOperation instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n@class NIOperation;\n\ntypedef void (^NIOperationBlock)(NIOperation* operation);\ntypedef void (^NIOperationDidFailBlock)(NIOperation* operation, NSError* error);\n\n/**\n * For writing code that runs concurrently.\n *\n * @ingroup NimbusCore\n * @defgroup Operations Operations\n *\n * This collection of NSOperation implementations is meant to provide a set of common\n * operations that might be used in an application to offload complex processing to a separate\n * thread.\n */\n\n@protocol NIOperationDelegate;\n\n/**\n * A base implementation of an NSOperation that supports traditional delegation and blocks.\n *\n * <h2>Subclassing</h2>\n *\n * A subclass should call the operationDid* methods to notify the delegate on the main thread\n * of changes in the operation's state. Calling these methods will notify the delegate and the\n * blocks if provided.\n *\n * @ingroup Operations\n */\n@interface NIOperation : NSOperation\n\n@property (weak) id<NIOperationDelegate> delegate;\n@property (readonly, strong) NSError* lastError;\n@property (assign) NSInteger tag;\n\n@property (copy) NIOperationBlock didStartBlock;\n@property (copy) NIOperationBlock didFinishBlock;\n@property (copy) NIOperationDidFailBlock didFailWithErrorBlock;\n@property (copy) NIOperationBlock willFinishBlock;\n\n- (void)didStart;\n- (void)didFinish;\n- (void)didFailWithError:(NSError *)error;\n- (void)willFinish;\n\n@end\n\n/**\n * The delegate protocol for an NIOperation.\n *\n * @ingroup Operations\n */\n@protocol NIOperationDelegate <NSObject>\n@optional\n\n/** @name [NIOperationDelegate] State Changes */\n\n/** The operation has started executing. */\n- (void)nimbusOperationDidStart:(NIOperation *)operation;\n\n/**\n * The operation is about to complete successfully.\n *\n * This will not be called if the operation fails.\n *\n * This will be called from within the operation's runloop and must be thread safe.\n */\n- (void)nimbusOperationWillFinish:(NIOperation *)operation;\n\n/**\n * The operation has completed successfully.\n *\n * This will not be called if the operation fails.\n */\n- (void)nimbusOperationDidFinish:(NIOperation *)operation;\n\n/**\n * The operation failed in some way and has completed.\n *\n * operationDidFinish: will not be called.\n */\n- (void)nimbusOperationDidFail:(NIOperation *)operation withError:(NSError *)error;\n\n@end\n\n\n// NIOperation\n\n/** @name Delegation */\n\n/**\n * The delegate through which changes are notified for this operation.\n *\n * All delegate methods are performed on the main thread.\n *\n * @fn NIOperation::delegate\n */\n\n\n/** @name Post-Operation Properties */\n\n/**\n * The error last passed to the didFailWithError notification.\n *\n * @fn NIOperation::lastError\n */\n\n\n/** @name Identification */\n\n/**\n * A simple tagging mechanism for identifying operations.\n *\n * @fn NIOperation::tag\n */\n\n\n/** @name Blocks */\n\n/**\n * The operation has started executing.\n *\n * Performed on the main thread.\n *\n * @fn NIOperation::didStartBlock\n */\n\n/**\n * The operation has completed successfully.\n *\n * This will not be called if the operation fails.\n *\n * Performed on the main thread.\n *\n * @fn NIOperation::didFinishBlock\n */\n\n/**\n * The operation failed in some way and has completed.\n *\n * didFinishBlock will not be executed.\n *\n * Performed on the main thread.\n *\n * @fn NIOperation::didFailWithErrorBlock\n */\n\n/**\n * The operation is about to complete successfully.\n *\n * This will not be called if the operation fails.\n *\n * Performed in the operation's thread.\n *\n * @fn NIOperation::willFinishBlock\n */\n\n\n/**\n * @name Subclassing\n *\n * The following methods are provided to aid in subclassing and are not meant to be\n * used externally.\n */\n\n/**\n * On the main thread, notify the delegate that the operation has begun.\n *\n * @fn NIOperation::didStart\n */\n\n/**\n * On the main thread, notify the delegate that the operation has finished.\n *\n * @fn NIOperation::didFinish\n */\n\n/**\n * On the main thread, notify the delegate that the operation has failed.\n *\n * @fn NIOperation::didFailWithError:\n */\n\n/**\n * In the operation's thread, notify the delegate that the operation will finish successfully.\n *\n * @fn NIOperation::willFinish\n */\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIOperations.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIOperations.h\"\n\n#import \"NIDebuggingTools.h\"\n#import \"NIPreprocessorMacros.h\"\n#import \"NIOperations+Subclassing.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NIOperation\n\n- (void)dealloc {\n  // For an unknown reason these block objects are not released when the NIOperation is deallocated\n  // with ARC enabled.\n  _didStartBlock = nil;\n  _didFinishBlock = nil;\n  _didFailWithErrorBlock = nil;\n  _willFinishBlock = nil;\n}\n\n#pragma mark - Initiate delegate notification from the NSOperation\n\n- (void)didStart {\n\t[self performSelectorOnMainThread:@selector(onMainThreadOperationDidStart)\n                         withObject:nil\n                      waitUntilDone:[NSThread isMainThread]];\n}\n\n- (void)didFinish {\n\t[self performSelectorOnMainThread:@selector(onMainThreadOperationDidFinish)\n                         withObject:nil\n                      waitUntilDone:[NSThread isMainThread]];\n}\n\n- (void)didFailWithError:(NSError *)error {\n  self.lastError = error;\n\n\t[self performSelectorOnMainThread:@selector(onMainThreadOperationDidFailWithError:)\n                         withObject:error\n                      waitUntilDone:[NSThread isMainThread]];\n}\n\n- (void)willFinish {\n  if ([self.delegate respondsToSelector:@selector(nimbusOperationWillFinish:)]) {\n    [self.delegate nimbusOperationWillFinish:self];\n  }\n\n  if (nil != self.willFinishBlock) {\n    self.willFinishBlock(self);\n  }\n}\n\n#pragma mark - Main Thread\n\n- (void)onMainThreadOperationDidStart {\n  // This method should only be called on the main thread.\n  NIDASSERT([NSThread isMainThread]);\n\n  if ([self.delegate respondsToSelector:@selector(nimbusOperationDidStart:)]) {\n    [self.delegate nimbusOperationDidStart:self];\n  }\n\n  if (nil != self.didStartBlock) {\n    self.didStartBlock(self);\n  }\n}\n\n- (void)onMainThreadOperationDidFinish {\n  // This method should only be called on the main thread.\n  NIDASSERT([NSThread isMainThread]);\n\n  if ([self.delegate respondsToSelector:@selector(nimbusOperationDidFinish:)]) {\n    [self.delegate nimbusOperationDidFinish:self];\n  }\n\n  if (nil != self.didFinishBlock) {\n    self.didFinishBlock(self);\n  }\n}\n\n- (void)onMainThreadOperationDidFailWithError:(NSError *)error {\n  // This method should only be called on the main thread.\n  NIDASSERT([NSThread isMainThread]);\n\n  if ([self.delegate respondsToSelector:@selector(nimbusOperationDidFail:withError:)]) {\n    [self.delegate nimbusOperationDidFail:self withError:error];\n  }\n\n  if (nil != self.didFailWithErrorBlock) {\n    self.didFailWithErrorBlock(self, error);\n  }\n}\n\n@end\n"
  },
  {
    "path": "src/core/src/NIPaths.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\nAPI_DEPRECATED_BEGIN(\"Use standard Foundation APIs instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For creating standard system paths.\n *\n * @ingroup NimbusCore\n * @defgroup Paths Paths\n * @{\n */\n\n/**\n * Create a path with the given bundle and the relative path appended.\n *\n * @param bundle        The bundle to append relativePath to. If nil, [NSBundle mainBundle]\n *                           will be used.\n * @param relativePath  The relative path to append to the bundle's path.\n *\n * @returns The bundle path concatenated with the given relative path.\n */\nNSString* NIPathForBundleResource(NSBundle* bundle, NSString* relativePath);\n\n/**\n * Create a path with the documents directory and the relative path appended.\n *\n * @returns The documents path concatenated with the given relative path.\n */\nNSString* NIPathForDocumentsResource(NSString* relativePath);\n\n/**\n * Create a path with the Library directory and the relative path appended.\n *\n * @returns The Library path concatenated with the given relative path.\n */\nNSString* NIPathForLibraryResource(NSString* relativePath);\n\n/**\n * Create a path with the caches directory and the relative path appended.\n *\n * @returns The caches path concatenated with the given relative path.\n */\nNSString* NIPathForCachesResource(NSString* relativePath);\n\n#if defined __cplusplus\n}\n#endif\n\n/**@}*/// End of Paths ////////////////////////////////////////////////////////////////////////////\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIPaths.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPaths.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNSString* NIPathForBundleResource(NSBundle* bundle, NSString* relativePath) {\n  NSString* resourcePath = [(nil == bundle ? [NSBundle mainBundle] : bundle) resourcePath];\n  return [resourcePath stringByAppendingPathComponent:relativePath];\n}\n\nNSString* NIPathForDocumentsResource(NSString* relativePath) {\n  static NSString* documentsPath = nil;\n  if (nil == documentsPath) {\n    NSArray* dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,\n                                                        NSUserDomainMask,\n                                                        YES);\n    documentsPath = [dirs objectAtIndex:0];\n  }\n  return [documentsPath stringByAppendingPathComponent:relativePath];\n}\n\nNSString* NIPathForLibraryResource(NSString* relativePath) {\n  static NSString* libraryPath = nil;\n  if (nil == libraryPath) {\n    NSArray* dirs = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,\n                                                        NSUserDomainMask,\n                                                        YES);\n    libraryPath = [dirs objectAtIndex:0];\n  }\n  return [libraryPath stringByAppendingPathComponent:relativePath];\n}\n\nNSString* NIPathForCachesResource(NSString* relativePath) {\n  static NSString* cachesPath = nil;\n  if (nil == cachesPath) {\n    NSArray* dirs = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,\n                                                        NSUserDomainMask,\n                                                        YES);\n    cachesPath = [dirs objectAtIndex:0];\n  }\n  return [cachesPath stringByAppendingPathComponent:relativePath];\n}\n"
  },
  {
    "path": "src/core/src/NIPreprocessorMacros.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n\n#pragma mark - Preprocessor Macros\n\n/**\n * Preprocessor macros are added to Nimbus with care. Macros hide functionality and are difficult\n * to debug, so most macros found in Nimbus are one-liners or compiler utilities.\n *\n * <h2>Creating Byte- and Hex-based Colors</h2>\n * \n * Nimbus provides the RGBCOLOR and RGBACOLOR macros for easily creating UIColor objects\n * with byte and hex values.\n * \n * <h3>Examples</h3>\n * \n@code\nUIColor* color = RGBCOLOR(255, 128, 64); // Fully opaque orange\nUIColor* color = RGBACOLOR(255, 128, 64, 0.5); // Orange with 50% transparency\nUIColor* color = RGBCOLOR(0xFF, 0x7A, 0x64); // Hexadecimal color\n@endcode\n * \n * <h3>Why it exists</h3>\n * \n * There is no easy way to create UIColor objects using 0 - 255 range values or hexadecimal. This\n * leads to code like this being written:\n * \n@code\nUIColor* color = [UIColor colorWithRed:128.f/255.0f green:64.f/255.0f blue:32.f/255.0f alpha:1]\n@endcode\n *\n * <h2>Avoid requiring the -all_load and -force_load flags</h2>\n * \n * Categories can introduce the need for the -all_load and -force_load because of the fact that\n * the application will not load these categories on startup without them. This is due to the way\n * Xcode deals with .m files that only contain categories: it doesn't load them without the\n * -all_load or -force_load flag specified.\n * \n * There is, however, a way to force Xcode into loading the category .m file. If you provide an\n * empty class implementation in the .m file then your app will pick up the category\n * implementation.\n * \n * Example in plain UIKit:\n * \n@code\n@interface BogusClass\n@end\n@implementation BogusClass\n@end\n\n@implementation UIViewController (MyCustomCategory)\n...\n@end\n@endcode\n * \n * NI_FIX_CATEGORY_BUG is a Nimbus macro that you include in your category `.m` file to save you\n * the trouble of having to write a bogus class for every category. Just be sure that the name you\n * provide to the macro is unique across your project or you will encounter duplicate symbol errors\n * when linking.\n * \n@code\nNI_FIX_CATEGORY_BUG(UIViewController_MyCustomCategory);\n\n@implementation UIViewController (MyCustomCategory)\n...\n@end\n@endcode\n * \n * @ingroup NimbusCore\n * @defgroup Preprocessor-Macros Preprocessor Macros\n * @{\n */\n\n/**\n * Mark a method or property as deprecated to the compiler.\n *\n * Any use of a deprecated method or property will flag a warning when compiling.\n *\n * Borrowed from Apple's AvailabiltyInternal.h header.\n *\n * @htmlonly\n * <pre>\n *   __AVAILABILITY_INTERNAL_DEPRECATED         __attribute__((deprecated))\n * </pre>\n * @endhtmlonly\n */\n#define __NI_DEPRECATED_METHOD __attribute__((deprecated))\n\n/**\n * Mark APIs as unavailable in app extensions.\n *\n * Use of unavailable methods, classes, or functions produces a compile error when built as part\n * of an app extension target. If the method, class or function using the unavailable API has also\n * been marked as unavailable in app extensions, the error will be suppressed.\n */\n#ifdef NS_EXTENSION_UNAVAILABLE_IOS\n#define NI_EXTENSION_UNAVAILABLE_IOS(msg) NS_EXTENSION_UNAVAILABLE_IOS(msg)\n#else\n#define NI_EXTENSION_UNAVAILABLE_IOS(msg)\n#endif\n\n/**\n * Force a category to be loaded when an app starts up.\n *\n * Add this macro before each category implementation, so we don't have to use\n * -all_load or -force_load to load object files from static libraries that only contain\n * categories and no classes.\n * See http://developer.apple.com/library/mac/#qa/qa2006/qa1490.html for more info.\n */\n#define NI_FIX_CATEGORY_BUG(name) @interface NI_FIX_CATEGORY_BUG_##name : NSObject @end \\\n@implementation NI_FIX_CATEGORY_BUG_##name @end\n\n/**\n * Creates an opaque UIColor object from a byte-value color definition.\n */\n#define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1]\n\n/**\n * Creates a UIColor object from a byte-value color definition and alpha transparency.\n */\n#define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:(a)]\n\n/**@}*/// End of Preprocessor Macros //////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "src/core/src/NIRuntimeClassModifications.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\nAPI_DEPRECATED_BEGIN(\"Avoid swizzling unless absolutely needed.\", ios(12, API_TO_BE_DEPRECATED))\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * For modifying class implementations at runtime.\n *\n * @ingroup NimbusCore\n * @defgroup Runtime-Class-Modifications Runtime Class Modifications\n * @{\n *\n * @attention Please use caution when modifying class implementations at runtime.\n *                 Apple is prone to rejecting apps for gratuitous use of method swapping.\n *                 In particular, avoid swapping any NSObject methods such as dealloc, init,\n *                 and retain/release on UIKit classes.\n *\n * See example: @link ExampleRuntimeDebugging.m Runtime Debugging with Method Swizzling@endlink\n */\n\n/**\n * Swap two class instance method implementations.\n *\n * Use this method when you would like to replace an existing method implementation in a class\n * with your own implementation at runtime. In practice this is often used to replace the\n * implementations of UIKit classes where subclassing isn't an adequate solution.\n *\n * This will only work for methods declared with a -.\n *\n * After calling this method, any calls to originalSel will actually call newSel and vice versa.\n *\n * Uses method_exchangeImplementations to accomplish this.\n */\nvoid NISwapInstanceMethods(Class cls, SEL originalSel, SEL newSel);\n\n/**\n * Swap two class method implementations.\n *\n * Use this method when you would like to replace an existing method implementation in a class\n * with your own implementation at runtime. In practice this is often used to replace the\n * implementations of UIKit classes where subclassing isn't an adequate solution.\n *\n * This will only work for methods declared with a +.\n *\n * After calling this method, any calls to originalSel will actually call newSel and vice versa.\n *\n * Uses method_exchangeImplementations to accomplish this.\n */\nvoid NISwapClassMethods(Class cls, SEL originalSel, SEL newSel);\n\n#if defined __cplusplus\n}\n#endif\n\n/**@}*/// End of Runtime Class Modifications //////////////////////////////////////////////////////\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIRuntimeClassModifications.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIRuntimeClassModifications.h\"\n\n#import <objc/runtime.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nvoid NISwapInstanceMethods(Class cls, SEL originalSel, SEL newSel) {\n  Method originalMethod = class_getInstanceMethod(cls, originalSel);\n  Method newMethod = class_getInstanceMethod(cls, newSel);\n  method_exchangeImplementations(originalMethod, newMethod);\n}\n\nvoid NISwapClassMethods(Class cls, SEL originalSel, SEL newSel) {\n  Method originalMethod = class_getClassMethod(cls, originalSel);\n  Method newMethod = class_getClassMethod(cls, newSel);\n  method_exchangeImplementations(originalMethod, newMethod);\n}\n"
  },
  {
    "path": "src/core/src/NISDKAvailability.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Availability.h>\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPreprocessorMacros.h\"\n\nAPI_DEPRECATED_BEGIN(\"Use standard Foundation APIs instead.\", ios(12, API_TO_BE_DEPRECATED))\n\n/**\n * For checking SDK feature availibility.\n *\n * @ingroup NimbusCore\n * @defgroup SDK-Availability SDK Availability\n * @{\n *\n * NIIOS macros are defined in parallel to their __IPHONE_ counterparts as a consistently-defined\n * means of checking __IPHONE_OS_VERSION_MAX_ALLOWED.\n *\n * For example:\n *\n * @htmlonly\n * <pre>\n *     #if __IPHONE_OS_VERSION_MAX_ALLOWED >= NIIOS_3_2\n *       // This code will only compile on versions >= iOS 3.2\n *     #endif\n * </pre>\n * @endhtmlonly\n */\n\n/**\n * Released on July 11, 2008\n */\n#define NIIOS_2_0     20000\n\n/**\n * Released on September 9, 2008\n */\n#define NIIOS_2_1     20100\n\n/**\n * Released on November 21, 2008\n */\n#define NIIOS_2_2     20200\n\n/**\n * Released on June 17, 2009\n */\n#define NIIOS_3_0     30000\n\n/**\n * Released on September 9, 2009\n */\n#define NIIOS_3_1     30100\n\n/**\n * Released on April 3, 2010\n */\n#define NIIOS_3_2     30200\n\n/**\n * Released on June 21, 2010\n */\n#define NIIOS_4_0     40000\n\n/**\n * Released on September 8, 2010\n */\n#define NIIOS_4_1     40100\n\n/**\n * Released on November 22, 2010\n */\n#define NIIOS_4_2     40200\n\n/**\n * Released on March 9, 2011\n */\n#define NIIOS_4_3     40300\n\n/**\n * Released on October 12, 2011.\n */\n#define NIIOS_5_0     50000\n\n/**\n * Released on March 7, 2012.\n */\n#define NIIOS_5_1     50100\n\n/**\n * Released on September 19, 2012.\n */\n#define NIIOS_6_0     60000\n\n/**\n * Released on January 28, 2013.\n */\n#define NIIOS_6_1     60100\n\n/**\n * Released on September 18, 2013\n */\n#define NIIOS_7_0     70000\n\n#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_0\n#define kCFCoreFoundationVersionNumber_iPhoneOS_2_0 478.23\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_1\n#define kCFCoreFoundationVersionNumber_iPhoneOS_2_1 478.26\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_2\n#define kCFCoreFoundationVersionNumber_iPhoneOS_2_2 478.29\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_0\n#define kCFCoreFoundationVersionNumber_iPhoneOS_3_0 478.47\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_1\n#define kCFCoreFoundationVersionNumber_iPhoneOS_3_1 478.52\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_2\n#define kCFCoreFoundationVersionNumber_iPhoneOS_3_2 478.61\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iOS_4_0\n#define kCFCoreFoundationVersionNumber_iOS_4_0 550.32\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iOS_4_1\n#define kCFCoreFoundationVersionNumber_iOS_4_1 550.38\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iOS_4_2\n#define kCFCoreFoundationVersionNumber_iOS_4_2 550.52\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iOS_4_3\n#define kCFCoreFoundationVersionNumber_iOS_4_3 550.52\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iOS_5_0\n#define kCFCoreFoundationVersionNumber_iOS_5_0 675.00\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iOS_5_1\n#define kCFCoreFoundationVersionNumber_iOS_5_1 690.10\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iOS_6_0\n#define kCFCoreFoundationVersionNumber_iOS_6_0 793.00\n#endif\n\n#ifndef kCFCoreFoundationVersionNumber_iOS_6_1\n#define kCFCoreFoundationVersionNumber_iOS_6_1 793.00\n#endif\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/**\n  On SDKs that support visionOS, this attribute will mark the annotated API as\n  unavailable.\n\n  This annotation can be stacked with an existing API_UNAVAILABLE macro if needed, e.g.:\n\n  ```\n  NI_UNAVAILABLE_VISIONOS API_UNAVAILABLE(macos)\n  ```\n*/\n#ifdef __API_UNAVAILABLE_PLATFORM_visionos\n#define NI_UNAVAILABLE_VISIONOS API_UNAVAILABLE(visionos)\n#else\n#define NI_UNAVAILABLE_VISIONOS\n#endif\n\n/**\n * Checks whether the device the app is currently running on is an iPad or not.\n *\n * @returns YES if the device is an iPad.\n */\nBOOL NIIsPad(void) NI_UNAVAILABLE_VISIONOS;\n\n/**\n * Checks whether the device the app is currently running on is an\n * iPhone/iPod touch or not.\n *\n * @returns YES if the device is an iPhone or iPod touch.\n */\nBOOL NIIsPhone(void) NI_UNAVAILABLE_VISIONOS;\n\n/**\n * Checks whether the device supports tint colors on all UIViews.\n *\n * @returns YES if all UIView instances on the device respond to tintColor.\n */\nBOOL NIIsTintColorGloballySupported(void);\n\n/**\n * Checks whether the device's OS version is at least the given version number.\n *\n * Useful for runtime checks of the device's version number.\n *\n * @param versionNumber  Any value of kCFCoreFoundationVersionNumber.\n *\n * @attention Apple recommends using respondsToSelector where possible to check for\n *                 feature support. Use this method as a last resort.\n */\nBOOL NIDeviceOSVersionIsAtLeast(double versionNumber);\n\n/**\n * Fetch the screen's scale.\n */\nCGFloat NIScreenScale(void) NI_UNAVAILABLE_VISIONOS;\n\n/**\n * Returns YES if the screen is a retina display, NO otherwise.\n */\nBOOL NIIsRetina(void) NI_UNAVAILABLE_VISIONOS;\n\n/**\n * This method is now deprecated. Use [UIPopoverController class] instead.\n *\n * MAINTENANCE: Remove by Feb 28, 2014.\n */\nClass NIUIPopoverControllerClass(void) __NI_DEPRECATED_METHOD;\n\n/**\n * This method is now deprecated. Use [UITapGestureRecognizer class] instead.\n *\n * MAINTENANCE: Remove by Feb 28, 2014.\n */\nClass NIUITapGestureRecognizerClass(void) __NI_DEPRECATED_METHOD;\n\n#if defined(__cplusplus)\n} // extern \"C\"\n#endif\n\n#pragma mark Building with Old SDKs\n\n// Define methods that were introduced in iOS 7.0.\n#if __IPHONE_OS_VERSION_MAX_ALLOWED < NIIOS_7_0\n\n@interface UIViewController (Nimbus7SDKAvailability)\n\n@property (nonatomic, assign) UIRectEdge edgesForExtendedLayout;\n- (void)setNeedsStatusBarAppearanceUpdate;\n\n@end\n\n#endif\n\n\n/**@}*/// End of SDK Availability /////////////////////////////////////////////////////////////////\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NISDKAvailability.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NISDKAvailability.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n#if __IPHONE_OS_VERSION_MAX_ALLOWED < NIIOS_6_0\nconst UIImageResizingMode UIImageResizingModeStretch = -1;\n#endif\n\nBOOL NIIsPad(void) {\n  static NSInteger isPad = -1;\n  if (isPad < 0) {\n    isPad = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) ? 1 : 0;\n  }\n  return isPad > 0;\n}\n\nBOOL NIIsPhone(void) {\n  static NSInteger isPhone = -1;\n  if (isPhone < 0) {\n    isPhone = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) ? 1 : 0;\n  }\n  return isPhone > 0;\n}\n\nBOOL NIIsTintColorGloballySupported(void) {\n  static NSInteger isTintColorGloballySupported = -1;\n  if (isTintColorGloballySupported < 0) {\n    UIView* view = [[UIView alloc] init];\n    isTintColorGloballySupported = [view respondsToSelector:@selector(tintColor)];\n  }\n  return isTintColorGloballySupported > 0;\n}\n\nBOOL NIDeviceOSVersionIsAtLeast(double versionNumber) {\n  return kCFCoreFoundationVersionNumber >= versionNumber;\n}\n\nCGFloat NIScreenScale(void) {\n  return [[UIScreen mainScreen] scale];\n}\n\nBOOL NIIsRetina(void) {\n  return NIScreenScale() > 1.f;\n}\n\nClass NIUIPopoverControllerClass(void) {\n  return [UIPopoverController class];\n}\n\nClass NIUITapGestureRecognizerClass(void) {\n  return [UITapGestureRecognizer class];\n}\n"
  },
  {
    "path": "src/core/src/NISnapshotRotation.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nAPI_DEPRECATED_BEGIN(\"This feature is no longer applicable and should be removed from usage.\",\n                     ios(12, API_TO_BE_DEPRECATED))\n/**\n * An object designed to easily implement snapshot rotation.\n *\n * Snapshot rotation involves taking two screenshots of a UIView: the \"before\" and the \"after\"\n * state of the rotation. These two images are then cross-faded during the rotation, creating an\n * animation that minimizes visual artifacts that would otherwise be noticed when rotation occurs.\n *\n * This feature will only function on iOS 6.0 and higher. On older iOS versions the view will rotate\n * just as it always has.\n *\n * This functionality has been adopted from WWDC 2012 session 240 \"Polishing Your Interface\n * Rotations\".\n *\n * @ingroup NimbusCore\n * @defgroup Snapshot-Rotation Snapshot Rotation\n * @{\n */\n\n@protocol NISnapshotRotationDelegate;\n\n/**\n * The NISnapshotRotation class provides support for implementing snapshot-based rotations on views.\n *\n * You must call this object's rotation methods from your controller in order for the rotation\n * object to implement the rotation animations correctly.\n */\nAPI_UNAVAILABLE(tvos, watchos)\n@interface NISnapshotRotation : NSObject\n\n// Designated initializer.\n- (id)initWithDelegate:(id<NISnapshotRotationDelegate>)delegate;\n\n@property (nonatomic, weak) id<NISnapshotRotationDelegate> delegate;\n\n@property (nonatomic, readonly, assign) CGRect frameBeforeRotation;\n@property (nonatomic, readonly, assign) CGRect frameAfterRotation;\n\n- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;\n- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;\n\n@end\n\n/**\n * The NITableViewSnapshotRotation class implements the fixedInsetsForSnapshotRotation: delegate\n * method and forwards all other delegate methods along.\n *\n * If you are rotating a UITableView you can instantiate a NITableViewSnapshotRotation object and\n * use it just like you would a snapshot rotation object. The NITableViewSnapshotRotation class\n * intercepts the fixedInsetsForSnapshotRotation: method and returns insets that map to the\n * dimensions of the content view for the first visible cell in the table view.\n *\n * The assigned delegate only needs to implement containerViewForSnapshotRotation: and\n * rotatingViewForSnapshotRotation:.\n */\nAPI_UNAVAILABLE(tvos, watchos)\n@interface NITableViewSnapshotRotation : NISnapshotRotation\n@end\n\n/**\n * The methods declared by the NISnapshotRotation protocol allow the adopting delegate to respond to\n * messages from the NISnapshotRotation class and thus implement snapshot rotations.\n */\nAPI_UNAVAILABLE(tvos, watchos)\n@protocol NISnapshotRotationDelegate <NSObject>\n@required\n\n/** @name Accessing Rotation Views */\n\n/**\n * Tells the delegate to return the container view of the rotating view.\n *\n * This is often the controller's self.view. This view must not be the same as the rotatingView and\n * rotatingView must be in the subview tree of containerView.\n *\n *        @sa NISnapshotRotation::rotatingViewForSnapshotRotation:\n */\n- (UIView *)containerViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation;\n\n/**\n * Tells the delegate to return the rotating view.\n *\n * The rotating view is the view that will be snapshotted during the rotation.\n *\n * This view must not be the same as the containerView and must be in the subview tree of\n * containerView.\n *\n *        @sa NISnapshotRotation::containerViewForSnapshotRotation:\n */\n- (UIView *)rotatingViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation;\n\n@optional\n\n/** @name Configuring Fixed Insets */\n\n/**\n * Asks the delegate to return the insets of the rotating view that should be fixed during rotation.\n *\n * This method will only be called on iOS 6.0 and higher.\n *\n * The returned insets will denote which parts of the snapshotted images will not stretch during\n * the rotation animation.\n */\n- (UIEdgeInsets)fixedInsetsForSnapshotRotation:(NISnapshotRotation *)snapshotRotation;\n\n@end\n\n#if defined __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Returns an opaque UIImage snapshot of the given view.\n *\n * This method takes into account the offset of scrollable views and captures whatever is currently\n * in the frame of the view.\n *\n * @param view A snapshot will be taken of this view.\n * @returns A UIImage with the snapshot of @c view.\n */\nUIImage* NISnapshotOfView(UIView* view);\n\n/**\n * Returns a UIImageView with an image snapshot of the given view.\n *\n * The frame of the returned view is set to match the frame of @c view.\n *\n * @param view A snapshot will be taken of this view.\n * @returns A UIImageView with the snapshot of @c view and matching frame.\n */\nUIImageView* NISnapshotViewOfView(UIView* view);\n\n/**\n * Returns a UIImage snapshot of the given view with transparency.\n *\n * This method takes into account the offset of scrollable views and captures whatever is currently\n * in the frame of the view.\n *\n * @param view A snapshot will be taken of this view.\n * @returns A UIImage with the snapshot of @c view.\n */\nUIImage* NISnapshotOfViewWithTransparency(UIView* view);\n\n/**\n * Returns a UIImageView with an image snapshot with transparency of the given view.\n *\n * The frame of the returned view is set to match the frame of @c view.\n *\n * @param view A snapshot will be taken of this view.\n * @returns A UIImageView with the snapshot of @c view and matching frame.\n */\nUIImageView* NISnapshotViewOfViewWithTransparency(UIView* view);\n\n#if defined __cplusplus\n}\n#endif\n\n/**\n * @}\n */\n\n/** @name Creating a Snapshot Rotation Object */\n\n/**\n * Initializes a newly allocated rotation object with a given delegate.\n *\n * @param delegate A delegate that implements the NISnapshotRotation protocol.\n * @returns A NISnapshotRotation object initialized with @c delegate.\n * @fn NISnapshotRotation::initWithDelegate:\n */\n\n/** @name Accessing the Delegate */\n\n/**\n * The delegate of the snapshot rotation object.\n *\n * The delegate must adopt the NISnapshotRotation protocol. The NISnapshotRotation class, which does\n * not retain the delegate, invokes each protocol method the delegate implements.\n *\n * @fn NISnapshotRotation::delegate\n */\n\n/** @name Implementing UIViewController Autorotation */\n\n/**\n * Prepares the animation for a rotation by taking a snapshot of the rotatingView in its current\n * state.\n *\n * This method must be called from your UIViewController implementation.\n *\n * @fn NISnapshotRotation::willRotateToInterfaceOrientation:duration:\n */\n\n/**\n * Crossfades between the initial and final snapshots.\n *\n * This method must be called from your UIViewController implementation.\n *\n * @fn NISnapshotRotation::willAnimateRotationToInterfaceOrientation:duration:\n */\n\n/**\n * Finalizes the rotation animation by removing the snapshot views from the container view.\n *\n * This method must be called from your UIViewController implementation.\n *\n * @fn NISnapshotRotation::didRotateFromInterfaceOrientation:\n */\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NISnapshotRotation.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// This code was originally found in Apple's WWDC Session 240 on\n// \"Polishing Your Interface Rotations\" and has been repurposed into a reusable class.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NISnapshotRotation.h\"\n\n#import \"NIDebuggingTools.h\"\n#import \"NISDKAvailability.h\"\n#import <QuartzCore/QuartzCore.h>\n#import <objc/runtime.h>\n\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n#error \"Nimbus Snapshot Rotation requires iOS 6 or higher.\"\n#endif\n\nUIImage* NISnapshotOfViewWithTransparencyOption(UIView* view, BOOL transparency);\n\nUIImage* NISnapshotOfViewWithTransparencyOption(UIView* view, BOOL transparency) {\n  // Passing 0 as the last argument ensures that the image context will match the current device's\n  // scaling mode.\n  UIGraphicsBeginImageContextWithOptions(view.bounds.size, !transparency, 0);\n\n  CGContextRef cx = UIGraphicsGetCurrentContext();\n\n  // Views that can scroll do so by modifying their bounds. We want to capture the part of the view\n  // that is currently in the frame, so we offset by the bounds of the view accordingly.\n  CGContextTranslateCTM(cx, -view.bounds.origin.x, -view.bounds.origin.y);\n\n  BOOL didDraw = NO;\n#if __IPHONE_OS_VERSION_MAX_ALLOWED >= NIIOS_7_0\n  if ([view respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {\n    didDraw = [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];\n  }\n#endif\n  if (!didDraw) {\n    [view.layer renderInContext:cx];\n  }\n\n  UIImage* image = UIGraphicsGetImageFromCurrentImageContext();\n  UIGraphicsEndImageContext();\n\n  return image;\n}\n\nUIImage* NISnapshotOfView(UIView* view) {\n  return NISnapshotOfViewWithTransparencyOption(view, NO);\n}\n\nUIImageView* NISnapshotViewOfView(UIView* view) {\n  UIImage* image = NISnapshotOfView(view);\n\n  UIImageView* snapshotView = [[UIImageView alloc] initWithImage:image];\n  snapshotView.frame = view.frame;\n\n  return snapshotView;\n}\n\nUIImage* NISnapshotOfViewWithTransparency(UIView* view) {\n  return NISnapshotOfViewWithTransparencyOption(view, YES);\n}\n\nUIImageView* NISnapshotViewOfViewWithTransparency(UIView* view) {\n  UIImage* image = NISnapshotOfViewWithTransparency(view);\n\n  UIImageView* snapshotView = [[UIImageView alloc] initWithImage:image];\n  snapshotView.frame = view.frame;\n  \n  return snapshotView;\n}\n\n@interface NISnapshotRotation()\n@property (nonatomic, assign) BOOL isSupportedOS;\n@property (nonatomic, assign) CGRect frameBeforeRotation;\n@property (nonatomic, assign) CGRect frameAfterRotation;\n\n@property (nonatomic, strong) UIImageView* snapshotViewBeforeRotation;\n@property (nonatomic, strong) UIImageView* snapshotViewAfterRotation;\n@end\n\n@implementation NISnapshotRotation\n\n- (id)initWithDelegate:(id<NISnapshotRotationDelegate>)delegate {\n  if ((self = [super init])) {\n    _delegate = delegate;\n\n    // Check whether this feature is supported or not.\n    UIImage* image = [[UIImage alloc] init];\n    _isSupportedOS = [image respondsToSelector:@selector(resizableImageWithCapInsets:resizingMode:)];\n  }\n  return self;\n}\n\n- (id)init {\n  return [self initWithDelegate:nil];\n}\n\n- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  if (!self.isSupportedOS) {\n    return;\n  }\n\n  UIView* containerView = [self.delegate containerViewForSnapshotRotation:self];\n  UIView* rotationView = [self.delegate rotatingViewForSnapshotRotation:self];\n\n  // The container view must not be the same as the rotation view.\n  NIDASSERT(containerView != rotationView);\n  if (containerView == rotationView) {\n    return;\n  }\n\n  self.frameBeforeRotation = rotationView.frame;\n  self.snapshotViewBeforeRotation = NISnapshotViewOfViewWithTransparency(rotationView);\n  [containerView insertSubview:self.snapshotViewBeforeRotation aboveSubview:rotationView];\n}\n\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  if (!self.isSupportedOS) {\n    return;\n  }\n\n  UIView* containerView = [self.delegate containerViewForSnapshotRotation:self];\n  UIView* rotationView = [self.delegate rotatingViewForSnapshotRotation:self];\n\n  // The container view must not be the same as the rotation view.\n  NIDASSERT(containerView != rotationView);\n  if (containerView == rotationView) {\n    return;\n  }\n\n  self.frameAfterRotation = rotationView.frame;\n  \n  [UIView setAnimationsEnabled:NO];\n  \n  self.snapshotViewAfterRotation = NISnapshotViewOfViewWithTransparency(rotationView);\n  // Set the new frame while maintaining the old frame's height.\n  self.snapshotViewAfterRotation.frame = CGRectMake(self.frameBeforeRotation.origin.x,\n                                                    self.frameBeforeRotation.origin.y,\n                                                    self.frameBeforeRotation.size.width,\n                                                    self.snapshotViewAfterRotation.frame.size.height);\n  \n  UIImage* imageBeforeRotation = self.snapshotViewBeforeRotation.image;\n  UIImage* imageAfterRotation = self.snapshotViewAfterRotation.image;\n\n  if ([self.delegate respondsToSelector:@selector(fixedInsetsForSnapshotRotation:)]) {\n    UIEdgeInsets fixedInsets = [self.delegate fixedInsetsForSnapshotRotation:self];\n\n    imageBeforeRotation = [imageBeforeRotation resizableImageWithCapInsets:fixedInsets resizingMode:UIImageResizingModeStretch];\n    imageAfterRotation = [imageAfterRotation resizableImageWithCapInsets:fixedInsets resizingMode:UIImageResizingModeStretch];\n  }\n\n  self.snapshotViewBeforeRotation.image = imageBeforeRotation;\n  self.snapshotViewAfterRotation.image = imageAfterRotation;\n\n  [UIView setAnimationsEnabled:YES];\n\n  if (imageAfterRotation.size.height < imageBeforeRotation.size.height) {\n    self.snapshotViewAfterRotation.alpha = 0;\n\n    [containerView insertSubview:self.snapshotViewAfterRotation aboveSubview:self.snapshotViewBeforeRotation];\n\n    self.snapshotViewAfterRotation.alpha = 1;\n\n  } else {\n    [containerView insertSubview:self.snapshotViewAfterRotation belowSubview:self.snapshotViewBeforeRotation];\n    self.snapshotViewBeforeRotation.alpha = 0;\n  }\n\n  self.snapshotViewAfterRotation.frame = self.frameAfterRotation;\n  self.snapshotViewBeforeRotation.frame = CGRectMake(self.frameAfterRotation.origin.x,\n                                                     self.frameAfterRotation.origin.y,\n                                                     self.frameAfterRotation.size.width,\n                                                     self.snapshotViewBeforeRotation.frame.size.height);\n\n  rotationView.hidden = YES;\n}\n\n- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {\n  if (!self.isSupportedOS) {\n    return;\n  }\n\n  UIView* containerView = [self.delegate containerViewForSnapshotRotation:self];\n  UIView* rotationView = [self.delegate rotatingViewForSnapshotRotation:self];\n\n  // The container view must not be the same as the rotation view.\n  NIDASSERT(containerView != rotationView);\n  if (containerView == rotationView) {\n    return;\n  }\n\n  [self.snapshotViewBeforeRotation removeFromSuperview];\n  [self.snapshotViewAfterRotation removeFromSuperview];\n  self.snapshotViewBeforeRotation = nil;\n  self.snapshotViewAfterRotation = nil;\n\n  rotationView.hidden = NO;\n}\n\n@end\n\n@interface NITableViewSnapshotRotation() <NISnapshotRotationDelegate>\n@property (nonatomic, weak) id<NISnapshotRotationDelegate> forwardingDelegate;\n@end\n\n@implementation NITableViewSnapshotRotation\n\n- (void)setDelegate:(id<NISnapshotRotationDelegate>)delegate {\n  if (delegate == self) {\n    [super setDelegate:delegate];\n\n  } else {\n    self.forwardingDelegate = delegate;\n  }\n}\n\n- (id)init {\n  if ((self = [super init])) {\n    self.delegate = self;\n  }\n  return self;\n}\n\n#pragma mark - Forward Invocations\n\n- (BOOL)shouldForwardSelectorToDelegate:(SEL)selector {\n  struct objc_method_description description;\n  // Only forward the selector if it's part of the protocol.\n  description = protocol_getMethodDescription(@protocol(NISnapshotRotationDelegate), selector, NO, YES);\n\n  BOOL isSelectorInProtocol = (description.name != NULL && description.types != NULL);\n  return (isSelectorInProtocol && [self.forwardingDelegate respondsToSelector:selector]);\n}\n\n- (BOOL)respondsToSelector:(SEL)selector {\n  if ([super respondsToSelector:selector] == YES) {\n    return YES;\n    \n  } else {\n    return [self shouldForwardSelectorToDelegate:selector];\n  }\n}\n\n- (id)forwardingTargetForSelector:(SEL)selector {\n  if ([self shouldForwardSelectorToDelegate:selector]) {\n    return self.forwardingDelegate;\n\n  } else {\n    return nil;\n  }\n}\n\n#pragma mark - NISnapshotRotation\n\n- (UIView *)containerViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation {\n  return [self.forwardingDelegate containerViewForSnapshotRotation:snapshotRotation];\n}\n\n- (UIView *)rotatingViewForSnapshotRotation:(NISnapshotRotation *)snapshotRotation {\n  return [self.forwardingDelegate rotatingViewForSnapshotRotation:snapshotRotation];\n}\n\n- (UIEdgeInsets)fixedInsetsForSnapshotRotation:(NISnapshotRotation *)snapshotRotation {\n  UIEdgeInsets insets = UIEdgeInsetsZero;\n\n  // Find the right edge of the content view in the coordinate space of the UITableView.\n  UIView* rotatingView = [self.forwardingDelegate rotatingViewForSnapshotRotation:snapshotRotation];\n  NIDASSERT([rotatingView isKindOfClass:[UITableView class]]);\n  if ([rotatingView isKindOfClass:[UITableView class]]) {\n    UITableView* tableView = (UITableView *)rotatingView;\n\n    NSArray* visibleCells = tableView.visibleCells;\n    if (visibleCells.count > 0) {\n      UIView* contentView = [[visibleCells objectAtIndex:0] contentView];\n      CGFloat contentViewRightEdge = [tableView convertPoint:CGPointMake(contentView.bounds.size.width, 0) fromView:contentView].x;\n\n      CGFloat fixedRightWidth = tableView.bounds.size.width - contentViewRightEdge;\n      CGFloat fixedLeftWidth = MIN(snapshotRotation.frameAfterRotation.size.width, snapshotRotation.frameBeforeRotation.size.width) - fixedRightWidth - 1;\n      insets = UIEdgeInsetsMake(0, fixedLeftWidth, 0, fixedRightWidth);\n    }\n  }\n  return insets;\n}\n\n@end\n"
  },
  {
    "path": "src/core/src/NIState.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n@class NIImageMemoryCache;\n\n/**\n * For modifying Nimbus state information.\n *\n * @ingroup NimbusCore\n * @defgroup Core-State State\n * @{\n *\n * The Nimbus core provides a common layer of features used by nearly all of the libraries in\n * the Nimbus ecosystem. Here you will find methods for accessing and setting the global image\n * cache amongst other things.\n */\n\n/**\n * The Nimbus state interface.\n *\n * @ingroup Core-State\n */\n@interface Nimbus : NSObject\n\n#pragma mark Accessing Global State /** @name Accessing Global State */\n\n/**\n * Access the global image memory cache.\n *\n * If a cache hasn't been assigned via Nimbus::setGlobalImageMemoryCache: then one will be created\n * automatically.\n *\n * @remarks The default image cache has no upper limit on its memory consumption. It is\n *               up to you to specify an upper limit in your application.\n */\n+ (NIImageMemoryCache *)imageMemoryCache;\n\n/**\n * Access the global network operation queue.\n *\n * The global network operation queue exists to be used for asynchronous network requests if\n * you choose. By defining a global operation queue in the core of Nimbus, we can ensure that\n * all libraries that depend on core will use the same network operation queue unless configured\n * otherwise.\n *\n * If an operation queue hasn't been assigned via Nimbus::setGlobalNetworkOperationQueue: then\n * one will be created automatically with the default iOS settings.\n */\n+ (NSOperationQueue *)networkOperationQueue;\n\n#pragma mark Modifying Global State /** @name Modifying Global State */\n\n/**\n * Set the global image memory cache.\n *\n * The cache will be retained and the old cache released.\n */\n+ (void)setImageMemoryCache:(NIImageMemoryCache *)imageMemoryCache;\n\n/**\n * Set the global network operation queue.\n *\n * The queue will be retained and the old queue released.\n */\n+ (void)setNetworkOperationQueue:(NSOperationQueue *)queue;\n\n@end\n\n/**@}*/// End of State ////////////////////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "src/core/src/NIState.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIState.h\"\n\n#import \"NIInMemoryCache.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic NIImageMemoryCache* sNimbusGlobalMemoryCache = nil;\nstatic NSOperationQueue* sNimbusGlobalOperationQueue = nil;\n\n@implementation Nimbus\n\n+ (void)setImageMemoryCache:(NIImageMemoryCache *)imageMemoryCache {\n  if (sNimbusGlobalMemoryCache != imageMemoryCache) {\n    sNimbusGlobalMemoryCache = nil;\n    sNimbusGlobalMemoryCache = imageMemoryCache;\n  }\n}\n\n+ (NIImageMemoryCache *)imageMemoryCache {\n  if (nil == sNimbusGlobalMemoryCache) {\n    sNimbusGlobalMemoryCache = [[NIImageMemoryCache alloc] init];\n  }\n  return sNimbusGlobalMemoryCache;\n}\n\n+ (void)setNetworkOperationQueue:(NSOperationQueue *)queue {\n  if (sNimbusGlobalOperationQueue != queue) {\n    sNimbusGlobalOperationQueue = nil;\n    sNimbusGlobalOperationQueue = queue;\n  }\n}\n\n+ (NSOperationQueue *)networkOperationQueue {\n  if (nil == sNimbusGlobalOperationQueue) {\n    sNimbusGlobalOperationQueue = [[NSOperationQueue alloc] init];\n  }\n  return sNimbusGlobalOperationQueue;\n}\n\n@end\n"
  },
  {
    "path": "src/core/src/NIViewRecycler.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nAPI_DEPRECATED_BEGIN(\"Use standard UITableView or UICollectionView APIs instead.\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n/**\n * For recycling views in scroll views.\n *\n * @ingroup NimbusCore\n * @defgroup Core-View-Recycling View Recyling\n * @{\n *\n * View recycling is an important aspect of iOS memory management and performance when building\n * scroll views. UITableView uses view recycling via the table cell dequeue mechanism.\n * NIViewRecycler implements this recycling functionality, allowing you to implement recycling\n * mechanisms in your own views and controllers.\n *\n *\n * <h2>Example Use</h2>\n *\n * Imagine building a UITableView. We'll assume that a viewRecycler object exists in the view.\n *\n * Views are usually recycled once they are no longer on screen, so within a did scroll event\n * we might have code like the following:\n *\n@code\nfor (UIView<NIRecyclableView>* view in visibleViews) {\n  if (![self isVisible:view]) {\n    [viewRecycler recycleView:view];\n    [view removeFromSuperview];\n  }\n}\n@endcode\n *\n * This will take the views that are no longer visible and add them to the recycler. At a later\n * point in that same didScroll code we will check if there are any new views that are visible.\n * This is when we try to dequeue a recycled view from the recycler.\n *\n@code\nUIView<NIRecyclableView>* view = [viewRecycler dequeueReusableViewWithIdentifier:reuseIdentifier];\nif (nil == view) {\n  // Allocate a new view that conforms to the NIRecyclableView protocol.\n  view = [[[...]] autorelease];\n}\n[self addSubview:view];\n@endcode\n *\n */\n\n@protocol NIRecyclableView;\n\n/**\n * An object for efficiently reusing views by recycling and dequeuing them from a pool of views.\n *\n * This sort of object is likely what UITableView and NIPagingScrollView use to recycle their views.\n */\n@interface NIViewRecycler : NSObject\n\n- (UIView<NIRecyclableView> *)dequeueReusableViewWithIdentifier:(NSString *)reuseIdentifier;\n\n- (void)recycleView:(UIView<NIRecyclableView> *)view;\n\n- (void)removeAllViews;\n\n@end\n\n/**\n * The NIRecyclableView protocol defines a set of optional methods that a view may implement to\n * handle being added to a NIViewRecycler.\n */\n@protocol NIRecyclableView <NSObject>\n\n@optional\n\n/**\n * The identifier used to categorize views into buckets for reuse.\n *\n * Views will be reused when a new view is requested with a matching identifier.\n *\n * If the reuseIdentifier is nil then the class name will be used.\n */\n@property (nonatomic, copy) NSString* reuseIdentifier;\n\n/**\n * Called immediately after the view has been dequeued from the recycled view pool.\n */\n- (void)prepareForReuse;\n\n@end\n\n/**\n * A simple implementation of the NIRecyclableView protocol as a UIView.\n *\n * This class can be used as a base class for building recyclable views if specific reuse\n * identifiers are necessary, e.g. when the same class might have different implementations\n * depending on the reuse identifier.\n *\n * Assuming functionality is consistent for a given class it is simpler not to have a\n * reuseIdentifier, making the view recycler use the class name as the reuseIdentifier. In this case\n * subclassing this class is overkill.\n */\n@interface NIRecyclableView : UIView <NIRecyclableView>\n\n// Designated initializer.\n- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier;\n\n@property (nonatomic, copy) NSString* reuseIdentifier;\n\n@end\n\n/**@}*/ // End of View Recyling\n\n/**\n * Dequeues a reusable view from the recycled views pool if one exists, otherwise returns nil.\n *\n * @fn NIViewRecycler::dequeueReusableViewWithIdentifier:\n * @param reuseIdentifier  Often the name of the class of view you wish to fetch.\n */\n\n/**\n * Adds a given view to the recycled views pool.\n *\n * @fn NIViewRecycler::recycleView:\n * @param view   The view to recycle. The reuse identifier will be retrieved from the view\n *                    via the NIRecyclableView protocol.\n */\n\n/**\n * Removes all of the views from the recycled views pool.\n *\n * @fn NIViewRecycler::removeAllViews\n */\n\n/**\n * Initializes a newly allocated view with the given reuse identifier.\n *\n * This is the designated initializer.\n *\n * @fn NIRecyclableView::initWithReuseIdentifier:\n * @param reuseIdentifier  The identifier that will be used to group this view in the view\n *                              recycler.\n */\n\n/**\n * This view's reuse identifier.\n *\n * Used by NIViewRecycler to pool this view into a group of similar recycled views.\n *\n * @fn NIRecyclableView::reuseIdentifier\n */\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/core/src/NIViewRecycler.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIViewRecycler.h\"\n\n#import \"NIDebuggingTools.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NIViewRecycler()\n@property (nonatomic, strong) NSMutableDictionary* reuseIdentifiersToRecycledViews;\n@end\n\n@implementation NIViewRecycler\n\n- (void)dealloc {\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (id)init {\n  if ((self = [super init])) {\n    _reuseIdentifiersToRecycledViews = [[NSMutableDictionary alloc] init];\n\n    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];\n    [nc addObserver:self\n           selector:@selector(reduceMemoryUsage)\n               name:UIApplicationDidReceiveMemoryWarningNotification\n             object:nil];\n  }\n  return self;\n}\n\n#pragma mark - Memory Warnings\n\n- (void)reduceMemoryUsage {\n  [self removeAllViews];\n}\n\n#pragma mark - Public\n\n- (UIView<NIRecyclableView> *)dequeueReusableViewWithIdentifier:(NSString *)reuseIdentifier {\n  NSMutableArray* views = [_reuseIdentifiersToRecycledViews objectForKey:reuseIdentifier];\n  UIView<NIRecyclableView>* view = [views lastObject];\n  if (nil != view) {\n    [views removeLastObject];\n    if ([view respondsToSelector:@selector(prepareForReuse)]) {\n      [view prepareForReuse];\n    }\n  }\n  return view;\n}\n\n- (void)recycleView:(UIView<NIRecyclableView> *)view {\n  NIDASSERT([view isKindOfClass:[UIView class]]);\n\n  NSString* reuseIdentifier = nil;\n  if ([view respondsToSelector:@selector(reuseIdentifier)]) {\n    reuseIdentifier = [view reuseIdentifier];;\n  }\n  if (nil == reuseIdentifier) {\n    reuseIdentifier = NSStringFromClass([view class]);\n  }\n\n  NIDASSERT(nil != reuseIdentifier);\n  if (nil == reuseIdentifier) {\n    return;\n  }\n\n  NSMutableArray* views = [_reuseIdentifiersToRecycledViews objectForKey:reuseIdentifier];\n  if (nil == views) {\n    views = [[NSMutableArray alloc] init];\n    [_reuseIdentifiersToRecycledViews setObject:views forKey:reuseIdentifier];\n  }\n  [views addObject:view];\n}\n\n- (void)removeAllViews {\n  [_reuseIdentifiersToRecycledViews removeAllObjects];\n}\n\n@end\n\n@implementation NIRecyclableView\n\n- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithFrame:CGRectZero])) {\n    _reuseIdentifier = reuseIdentifier;\n  }\n  return self;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  return [self initWithReuseIdentifier:nil];\n}\n\n@end\n"
  },
  {
    "path": "src/core/src/NimbusCore+Additions.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// All category documentation is found in the source files due to limitations of Doxygen.\n// Look for the documentation in the Classes tab of the documentation.\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NimbusCore.h\"\n\n// Additions\n#import \"UIResponder+NimbusCore.h\"\n"
  },
  {
    "path": "src/core/src/NimbusCore.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * @defgroup NimbusCore Nimbus Core\n *\n * <div id=\"github\" feature=\"core\"></div>\n *\n * Nimbus' Core defines the foundation upon which all other Nimbus features are built.\n * Within the core you will find common elements used to build iOS applications\n * including in-memory caches, path manipulation, and SDK availability. These features form\n * the foundation upon which all other Nimbus libraries are built.\n *\n * <h2>How Features are Added to the Core</h2>\n *\n * As a general rule of thumb, if something is used between multiple independent libraries or\n * applications with little variation, it likely qualifies to be added to the Core.\n *\n * <h3>Exceptions</h3>\n *\n * Standalone user interface components are <i>rarely</i> acceptable features to add to the Core.\n * For example: photo viewers, pull to refresh, launchers, attributed labels.\n *\n * Nimbus is not UIKit: we don't have the privilege of being an assumed cost on every iOS\n * device. Developers must carefully weigh whether it is worth adding a Nimbus feature - along\n * with its dependencies - over building the feature themselves or using another library. This\n * means that an incredible amount of care must be placed into deciding what gets added to the\n * Core.\n *\n * <h2>How Features are Removed from the Core</h2>\n *\n * It is inevitable that certain aspects of the Core will grow and develop over time. If a\n * feature gets to the point where the value of being a separate library is greater than the\n * overhead of managing such a library, then the feature should be considered for removal\n * from the Core.\n *\n * Great care must be taken to ensure that Nimbus doesn't become a framework composed of\n * hundreds of miniscule libraries.\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIActions.h\"  // IWYU pragma: export\n#import \"NIButtonUtilities.h\"  // IWYU pragma: export\n#import \"NICommonMetrics.h\"  // IWYU pragma: export\n#import \"NIDebuggingTools.h\"  // IWYU pragma: export\n#import \"NIDeviceOrientation.h\"  // IWYU pragma: export\n#import \"NIError.h\"  // IWYU pragma: export\n#import \"NIFoundationMethods.h\"  // IWYU pragma: export\n#import \"NIImageUtilities.h\"  // IWYU pragma: export\n#import \"NIInMemoryCache.h\"  // IWYU pragma: export\n#import \"NINetworkActivity.h\"  // IWYU pragma: export\n#import \"NINonEmptyCollectionTesting.h\"  // IWYU pragma: export\n#import \"NINonRetainingCollections.h\"  // IWYU pragma: export\n#import \"NIPaths.h\"  // IWYU pragma: export\n#import \"NIPreprocessorMacros.h\"  // IWYU pragma: export\n#import \"NIRuntimeClassModifications.h\"  // IWYU pragma: export\n#import \"NISDKAvailability.h\"  // IWYU pragma: export\n#import \"NISnapshotRotation.h\"  // IWYU pragma: export\n#import \"NIState.h\"  // IWYU pragma: export\n#import \"NIViewRecycler.h\"  // IWYU pragma: export\n"
  },
  {
    "path": "src/core/src/UIResponder+NimbusCore.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// +currentFirstResponder originally written by Jakob Egger, adapted by Jeff Verkoeyen.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n// Documentation for these additions is found in the .m file.\n@interface UIResponder (NimbusCore)\n\n+ (instancetype)nimbus_currentFirstResponder;\n\n@end\n"
  },
  {
    "path": "src/core/src/UIResponder+NimbusCore.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// +currentFirstResponder originally written by Jakob Egger, adapted by Jeff Verkoeyen.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UIResponder+NimbusCore.h\"\n\n#import \"NIPreprocessorMacros.h\"\n\n// Adapted from http://stackoverflow.com/questions/5029267/is-there-any-way-of-asking-an-ios-view-which-of-its-children-has-first-responder/14135456#14135456\n\nstatic __weak id sCurrentFirstResponder = nil;\n\nNI_FIX_CATEGORY_BUG(UIResponderNimbusCore)\n/**\n * For working with UIResponders.\n */\n@implementation UIResponder (NimbusCore)\n\n/**\n * Returns the current first responder by sending an action from the UIApplication.\n *\n * The implementation was adapted from http://stackoverflow.com/questions/5029267/is-there-any-way-of-asking-an-ios-view-which-of-its-children-has-first-responder/14135456#14135456\n */\n+ (instancetype)nimbus_currentFirstResponder {\n  sCurrentFirstResponder = nil;\n  [[UIApplication sharedApplication] sendAction:@selector(nimbus_findFirstResponder:)\n                                             to:nil from:nil forEvent:nil];\n  return sCurrentFirstResponder;\n}\n\n- (void)nimbus_findFirstResponder:(id)sender {\n  sCurrentFirstResponder = self;\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NICommonMetricsTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCore.h\"\n\n@interface NICommonMetricsTests : XCTestCase\n@end\n\n\n@implementation NICommonMetricsTests\n\n- (void)testMetrics {\n  // TODO (Jan 25, 2012): Test iPad logic as well.\n  //STAssertEquals(NIToolbarHeightForOrientation(UIInterfaceOrientationPortrait), 44.f, @\"Should match.\");\n  XCTAssertEqual(NIToolbarHeightForOrientation(UIInterfaceOrientationLandscapeLeft), 33.f, @\"Should match.\");\n  XCTAssertEqual(NIStatusBarAnimationCurve(), UIViewAnimationCurveEaseIn, @\"Should match.\");\n  XCTAssertEqual(NIStatusBarAnimationDuration(), 0.3, @\"Should match.\");\n  XCTAssertEqual(NIStatusBarBoundsChangeAnimationCurve(), UIViewAnimationCurveEaseInOut, @\"Should match.\");\n  XCTAssertEqual(NIStatusBarBoundsChangeAnimationDuration(), 0.35, @\"Should match.\");\n\n  // TODO (Jan 25, 2012): Override the status bar functionality so that we can test the height code.\n  //STAssertEquals(NIStatusBarHeight(), 0.f, @\"Should match.\");\n\n  XCTAssertEqual(NIDeviceRotationDuration(YES), 0.8, @\"Should match.\");\n  XCTAssertEqual(NIDeviceRotationDuration(NO), 0.4, @\"Should match.\");\n  XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(NICellContentPadding(), UIEdgeInsetsMake(10, 10, 10, 10)),\n                @\"Should match.\");\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NICoreAdditionTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCore+Additions.h\"\n\n@interface NimbusCoreAdditionTests : XCTestCase {\n}\n\n@end\n\n\n@implementation NimbusCoreAdditionTests\n\n#pragma mark - NSString Additions\n\n- (void)testNSString_queryContents {\n  NSDictionary* query;\n\n  query = NIQueryDictionaryFromString(@\"\");\n  XCTAssertTrue([query count] == 0, @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q\");\n  XCTAssertTrue([query[@\"q\"] isEqual:@[[NSNull null]]],\n                @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=\");\n  XCTAssertTrue([query[@\"q\"] isEqual:@[@\"\"]],\n                @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=three20\");\n  XCTAssertTrue([query[@\"q\"] isEqual:@[@\"three20\"]],\n                @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=three20%20github\");\n  XCTAssertTrue([query[@\"q\"] isEqual:@[@\"three20 github\"]],\n                @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=three20&hl=en\");\n  XCTAssertTrue([query[@\"q\"] isEqual:@[@\"three20\"]],\n                @\"Query: %@\", query);\n  XCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                 @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=three20&hl=\");\n  XCTAssertTrue([query[@\"q\"] isEqual:@[@\"three20\"]],\n                @\"Query: %@\", query);\n  XCTAssertTrue([query[@\"hl\"] isEqual:@[@\"\"]],\n                @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=&&hl=\");\n  XCTAssertTrue([query[@\"q\"] isEqual:@[@\"\"]],\n                @\"Query: %@\", query);\n  XCTAssertTrue([query[@\"hl\"] isEqual:@[@\"\"]],\n                @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=three20=repo&hl=en\");\n  XCTAssertNil(query[@\"q\"], @\"Query: %@\", query);\n  XCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"&&\");\n  XCTAssertTrue([query count] == 0, @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=foo&q=three20\");\n  NSArray* qArr = @[@\"foo\", @\"three20\"];\n  XCTAssertTrue([query[@\"q\"] isEqual:qArr], @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=foo&q=three20&hl=en\");\n  qArr = @[@\"foo\", @\"three20\"];\n  XCTAssertTrue([query[@\"q\"] isEqual:qArr], @\"Query: %@\", query);\n  XCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q=foo&q=three20&hl=en&g\");\n  qArr = @[@\"foo\", @\"three20\"];\n  XCTAssertTrue([query[@\"q\"] isEqual:qArr], @\"Query: %@\", query);\n  XCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                @\"Query: %@\", query);\n  XCTAssertTrue([query[@\"g\"] isEqual:@[[NSNull null]]],\n                @\"Query: %@\", query);\n\n  query = NIQueryDictionaryFromString(@\"q&q=three20&hl=en&g\");\n  qArr = @[[NSNull null], @\"three20\"];\n  XCTAssertTrue([query[@\"q\"] isEqual:qArr], @\"Query: %@\", query);\n  XCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                @\"Query: %@\", query);\n}\n\n- (void)testNSString_queryContentsUsingEncoding {\n\tNSDictionary* query;\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"\", NSUTF8StringEncoding);\n\tXCTAssertTrue([query count] == 0, @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q\", NSUTF8StringEncoding);\n\tXCTAssertTrue([query[@\"q\"] isEqual:@[[NSNull null]]],\n                @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=\", NSUTF8StringEncoding);\n\tXCTAssertTrue([query[@\"q\"] isEqual:@[@\"\"]],\n                @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=three20\", NSUTF8StringEncoding);\n\tXCTAssertTrue([query[@\"q\"] isEqual:@[@\"three20\"]],\n                @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=three20%20github\", NSUTF8StringEncoding);\n\tXCTAssertTrue([query[@\"q\"] isEqual:@[@\"three20 github\"]],\n                @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=three20&hl=en\", NSUTF8StringEncoding);\n\tXCTAssertTrue([query[@\"q\"] isEqual:@[@\"three20\"]],\n                @\"Query: %@\", query);\n\tXCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                 @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=three20&hl=\", NSUTF8StringEncoding);\n\tXCTAssertTrue([query[@\"q\"] isEqual:@[@\"three20\"]],\n                @\"Query: %@\", query);\n\tXCTAssertTrue([query[@\"hl\"] isEqual:@[@\"\"]],\n                @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=&&hl=\", NSUTF8StringEncoding);\n\tXCTAssertTrue([query[@\"q\"] isEqual:@[@\"\"]],\n                @\"Query: %@\", query);\n\tXCTAssertTrue([query[@\"hl\"] isEqual:@[@\"\"]],\n                @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=three20=repo&hl=en\", NSUTF8StringEncoding);\n\tXCTAssertNil(query[@\"q\"], @\"Query: %@\", query);\n\tXCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"&&\", NSUTF8StringEncoding);\n\tXCTAssertTrue([query count] == 0, @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=foo&q=three20\", NSUTF8StringEncoding);\n\tNSArray* qArr = @[@\"foo\", @\"three20\"];\n\tXCTAssertTrue([query[@\"q\"] isEqual:qArr], @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=foo&q=three20&hl=en\", NSUTF8StringEncoding);\n\tqArr = @[@\"foo\", @\"three20\"];\n\tXCTAssertTrue([query[@\"q\"] isEqual:qArr], @\"Query: %@\", query);\n\tXCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q=foo&q=three20&hl=en&g\", NSUTF8StringEncoding);\n\tqArr = @[@\"foo\", @\"three20\"];\n\tXCTAssertTrue([query[@\"q\"] isEqual:qArr], @\"Query: %@\", query);\n\tXCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                @\"Query: %@\", query);\n\tXCTAssertTrue([query[@\"g\"] isEqual:@[[NSNull null]]],\n                @\"Query: %@\", query);\n\n\tquery = NIQueryDictionaryFromStringUsingEncoding(@\"q&q=three20&hl=en&g\", NSUTF8StringEncoding);\n\tqArr = @[[NSNull null], @\"three20\"];\n\tXCTAssertTrue([query[@\"q\"] isEqual:qArr], @\"Query: %@\", query);\n\tXCTAssertTrue([query[@\"hl\"] isEqual:@[@\"en\"]],\n                @\"Query: %@\", query);\n}\n\n- (void)testNSString_stringByAddingQueryDictionary {\n  NSString* baseUrl = @\"http://google.com/search\";\n  XCTAssertTrue([NIStringByAddingQueryDictionaryToString(baseUrl, nil) isEqualToString:\n                [baseUrl stringByAppendingString:@\"?\"]], @\"Empty dictionary fail.\");\n\n  XCTAssertTrue([NIStringByAddingQueryDictionaryToString(baseUrl, @{}) isEqualToString:\n                [baseUrl stringByAppendingString:@\"?\"]], @\"Empty dictionary fail.\");\n\n  XCTAssertTrue([NIStringByAddingQueryDictionaryToString(baseUrl, @{@\"q\":@\"three20\"}) isEqualToString:\n                [baseUrl stringByAppendingString:@\"?q=three20\"]], @\"Single parameter fail.\");\n\n  NSDictionary* query = @{@\"q\": @\"three20\",\n                          @\"hl\": @\"en\"};\n  NSString* baseUrlWithQuery = NIStringByAddingQueryDictionaryToString(baseUrl, query);\n  XCTAssertTrue([baseUrlWithQuery isEqualToString:[baseUrl\n                                                  stringByAppendingString:@\"?hl=en&q=three20\"]]\n                || [baseUrlWithQuery isEqualToString:[baseUrl\n                                                     stringByAppendingString:@\"?q=three20&hl=en\"]],\n                @\"Additional query parameters not correct. %@\",\n                NIStringByAddingQueryDictionaryToString(baseUrl, query));\n}\n\n- (void)testNSString_versionStringCompare {\n  XCTAssertTrue(NICompareVersionStrings(@\"3.0\", @\"3.0\")      == NSOrderedSame, @\"same version\");\n  XCTAssertTrue(NICompareVersionStrings(@\"3.0a2\", @\"3.0a2\")  == NSOrderedSame, @\"same version alpha\");\n  XCTAssertTrue(NICompareVersionStrings(@\"3.0\", @\"2.5\")      == NSOrderedDescending, @\"major no alpha\");\n  XCTAssertTrue(NICompareVersionStrings(@\"3.1\", @\"3.0\")      == NSOrderedDescending, @\"minor no alpha\");\n  XCTAssertTrue(NICompareVersionStrings(@\"3.0a1\", @\"3.0\")    == NSOrderedAscending, @\"alpha-no alpha\");\n  XCTAssertTrue(NICompareVersionStrings(@\"3.0a1\", @\"3.0a4\")  == NSOrderedAscending, @\"alpha diff\");\n  XCTAssertTrue(NICompareVersionStrings(@\"3.0a2\", @\"3.0a19\") == NSOrderedAscending, @\"numeric alpha\");\n  XCTAssertTrue(NICompareVersionStrings(@\"3.0a\", @\"3.0a1\")   == NSOrderedAscending, @\"empty alpha\");\n  XCTAssertTrue(NICompareVersionStrings(@\"3.02\", @\"3.03\")    == NSOrderedAscending, @\"point diff\");\n  XCTAssertTrue(NICompareVersionStrings(@\"3.0.2\", @\"3.0.3\")  == NSOrderedAscending, @\"point diff\");\n}\n\n- (void)testNSString_md5Hash {\n  XCTAssertTrue([NIMD5HashFromString(@\"nimbus\") isEqualToString:@\"0e78d66f33c484a3c3b36d69bd3114cf\"],\n                @\"MD5 hashes don't match.\");\n}\n\n- (void)testNSString_sha1Hash {\n  XCTAssertTrue([NISHA1HashFromString(@\"nimbus\") isEqualToString:@\"c1b42d95fd18ad8a56d4fd7bbb4105952620d857\"],\n                @\"SHA1 hashes don't match.\");\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NIDataStructureTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 9, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <SenTestingKit/SenTestingKit.h>\n\n#import \"NimbusCore.h\"\n\n@interface NIDataStructureTests : SenTestCase {\n}\n\n@end\n\n\n@implementation NIDataStructureTests\n\n\n#pragma mark - Linked List\n\n\n- (void)testEmptyLinkedList {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  STAssertEquals([ll count], (NSUInteger)0, @\"Initial linked list should be empty.\");\n  STAssertNil(ll.firstObject, @\"Initial linked list should not have a head object.\");\n  STAssertNil(ll.lastObject, @\"Initial linked list should not have a tail object.\");\n\n  ll = [NILinkedList linkedList];\n\n  STAssertEquals([ll count], (NSUInteger)0, @\"Initial linked list should be empty.\");\n  STAssertNil(ll.firstObject, @\"Initial linked list should not have a head object.\");\n  STAssertNil(ll.lastObject, @\"Initial linked list should not have a tail object.\");\n}\n\n- (void)testLinkedListDescription {\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  NSArray* array = [NSArray arrayWithObjects:object1, object2, object3, nil];\n\n  NILinkedList* ll = [[NILinkedList alloc] initWithArray:array];\n\n  STAssertTrue([[ll description] isEqualToString:[array description]], @\"Should be equal.\");\n}\n\n- (void)testLinkedListWithArray {\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  NSArray* array = [NSArray arrayWithObjects:object1, object2, object3, nil];\n  \n  NILinkedList* ll = [[NILinkedList alloc] initWithArray:array];\n  \n  STAssertEquals([ll count], (NSUInteger)3, @\"Should have 3 objects.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head object should be object1.\");\n  STAssertEquals(ll.lastObject, object3, @\"Tail object should be object3.\");\n\n  ll = [NILinkedList linkedListWithArray:array];\n  \n  STAssertEquals([ll count], (NSUInteger)3, @\"Should have 3 objects.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head object should be object1.\");\n  STAssertEquals(ll.lastObject, object3, @\"Tail object should be object3.\");\n}\n\n- (void)testLinkedListAddNilItem {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  NIDebugAssertionsShouldBreak = NO;\n  [ll addObject:nil];\n  NIDebugAssertionsShouldBreak = YES;\n  STAssertEquals(ll.count, (NSUInteger)0, @\"There should be no objects.\");\n}\n\n- (void)testLinkedListAddSingleItem {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  NSArray* object = [NSArray array];\n  [ll addObject:object];\n  STAssertEquals(ll.count, (NSUInteger)1, @\"There should be exactly one object.\");\n  STAssertEquals(ll.firstObject, object, @\"Head should be the object.\");\n  STAssertEquals(ll.lastObject, object, @\"Tail should be the object.\");\n}\n\n- (void)testLinkedListAddTwoItems {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  STAssertEquals(ll.count, (NSUInteger)2, @\"There should be exactly two objects.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll.lastObject, object2, @\"Tail should be the second object.\");\n}\n\n- (void)testLinkedListAddThreeItems {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n  STAssertEquals(ll.count, (NSUInteger)3, @\"There should be exactly three objects.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll.lastObject, object3, @\"Tail should be the third object.\");\n}\n\n- (void)testLinkedListAddArrayOfItems {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n  \n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObjectsFromArray:[NSArray arrayWithObjects:object1, object2, object3, nil]];\n  STAssertEquals(ll.count, (NSUInteger)3, @\"There should be exactly three objects.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll.lastObject, object3, @\"Tail should be the third object.\");\n}\n\n- (void)testLinkedListCount {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n  \n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  STAssertEquals(ll.count, (NSUInteger)0, @\"There should be exactly zero objects.\");\n  [ll addObject:object1];\n  STAssertEquals(ll.count, (NSUInteger)1, @\"There should be exactly one object.\");\n  [ll addObject:object2];\n  STAssertEquals(ll.count, (NSUInteger)2, @\"There should be exactly two objects.\");\n  [ll addObject:object3];\n  STAssertEquals(ll.count, (NSUInteger)3, @\"There should be exactly three objects.\");\n}\n\n- (void)testLinkedListAllObjects {\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  NSArray* array = [NSArray arrayWithObjects:object1, object2, object3, nil];\n  \n  NILinkedList* ll = [NILinkedList linkedListWithArray:array];\n  \n  array = [ll allObjects];\n\n  STAssertEquals([array count], (NSUInteger)3, @\"There should be 3 objects in the array.\");\n  STAssertEquals([array objectAtIndex:0], object1, @\"The first object should be object1.\");\n  STAssertEquals([array objectAtIndex:1], object2, @\"The second object should be object2.\");\n  STAssertEquals([array objectAtIndex:2], object3, @\"The third object should be object3.\");\n\n  // Test empty case.\n  array = [NSArray array];\n  \n  ll = [NILinkedList linkedListWithArray:array];\n\n  array = [ll allObjects];\n\n  STAssertEquals([array count], (NSUInteger)0, @\"There should be no objects in the array.\");\n\n  // Test nil case.\n  ll = [NILinkedList linkedListWithArray:nil];\n  \n  array = [ll allObjects];\n  \n  STAssertEquals([array count], (NSUInteger)0, @\"There should be no objects in the array.\");\n}\n\n- (void)testLinkedListContainsObject {\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  NSArray* array = [NSArray arrayWithObjects:object1, object2, nil];\n  \n  NILinkedList* ll = [NILinkedList linkedListWithArray:array];\n  \n  STAssertTrue([ll containsObject:object1], @\"The linked list should contain object1.\");\n  STAssertTrue([ll containsObject:object2], @\"The linked list should contain object2.\");\n  STAssertFalse([ll containsObject:object3], @\"The linked list should not contain object3.\");\n  STAssertFalse([ll containsObject:nil], @\"Checking for the nil object should never be true.\");\n}\n\n- (void)testLinkedListObjectAtLocation {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  NILinkedListLocation* location = [ll addObject:object2];\n  [ll addObject:object3];\n  STAssertEquals([ll objectAtLocation:location], object2,\n                 @\"The location should point to the second object.\");\n}\n\n- (void)testLinkedListRemoveFirstObject {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n  [ll removeFirstObject];\n  STAssertEquals(ll.count, (NSUInteger)2, @\"There should be exactly two objects.\");\n  STAssertEquals(ll.firstObject, object2, @\"Head should be the second object.\");\n  STAssertEquals(ll.lastObject, object3, @\"Tail should be the third object.\");\n\n  [ll removeFirstObject];\n  STAssertEquals(ll.count, (NSUInteger)1, @\"There should be exactly one object.\");\n  STAssertEqualObjects(ll.firstObject, object3, @\"Head should be the third object.\");\n  STAssertEqualObjects(ll.lastObject, object3, @\"Tail should be the third object.\");\n\n  [ll removeFirstObject];\n  STAssertEquals(ll.count, (NSUInteger)0, @\"There should be exactly zero objects.\");\n  STAssertNil(ll.firstObject, @\"Head should be nil.\");\n  STAssertNil(ll.lastObject, @\"Tail should be nil.\");\n}\n\n- (void)testLinkedListRemoveLastObject {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n  [ll removeLastObject];\n  STAssertEquals(ll.count, (NSUInteger)2, @\"There should be exactly two objects.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll.lastObject, object2, @\"Tail should be the second object.\");\n\n  [ll removeLastObject];\n  STAssertEquals(ll.count, (NSUInteger)1, @\"There should be exactly one object.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll.lastObject, object1, @\"Tail should be the first object.\");\n\n  [ll removeLastObject];\n  STAssertEquals(ll.count, (NSUInteger)0, @\"There should be exactly zero objects.\");\n  STAssertNil(ll.firstObject, @\"Head should be nil.\");\n  STAssertNil(ll.lastObject, @\"Tail should be nil.\");\n}\n\n- (void)testLinkedListRemoveAllObjects {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n  [ll removeAllObjects];\n\n  STAssertEquals(ll.count, (NSUInteger)0, @\"There should be exactly zero objects.\");\n  STAssertNil(ll.firstObject, @\"Head should be nil.\");\n  STAssertNil(ll.lastObject, @\"Tail should be nil.\");\n}\n\n- (void)testLinkedListRemoveTooManyObjects {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n  [ll removeAllObjects];\n\n  [ll removeLastObject];\n\n  STAssertEquals(ll.count, (NSUInteger)0, @\"There should be exactly zero objects.\");\n  STAssertNil(ll.firstObject, @\"Head should be nil.\");\n  STAssertNil(ll.lastObject, @\"Tail should be nil.\");\n\n  [ll removeFirstObject];\n\n  STAssertEquals(ll.count, (NSUInteger)0, @\"There should be exactly zero objects.\");\n  STAssertNil(ll.firstObject, @\"Head should be nil.\");\n  STAssertNil(ll.lastObject, @\"Tail should be nil.\");\n\n  [ll removeAllObjects];\n\n  STAssertEquals(ll.count, (NSUInteger)0, @\"There should be exactly zero objects.\");\n  STAssertNil(ll.firstObject, @\"Head should be nil.\");\n  STAssertNil(ll.lastObject, @\"Tail should be nil.\");\n}\n\n- (void)testLinkedListLocationOfObject {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  NILinkedListLocation* location = [ll addObject:object2];\n  [ll addObject:object3];\n  STAssertTrue([location isEqual:[ll locationOfObject:object2]], @\"The locations should match up\");\n}\n\n- (void)testLinkedListRemoveObject {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n  [ll removeObject:object2];\n\n  STAssertEquals(ll.count, (NSUInteger)2, @\"There should be exactly two objects.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll.lastObject, object3, @\"Tail should be the third object.\");\n\n  // Test removing an object that has already been removed.\n  [ll removeObject:object2];\n\n  STAssertEquals(ll.count, (NSUInteger)2, @\"There should be exactly two objects.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll.lastObject, object3, @\"Tail should be the third object.\");\n\n  // Test removing the tail.\n  [ll removeObject:object3];\n\n  STAssertEquals(ll.count, (NSUInteger)1, @\"There should be exactly one object.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll.lastObject, object1, @\"Tail should be the first object.\");\n}\n\n- (void)testLinkedListRemoveObjectAtLocation {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n  [ll removeObjectAtLocation:[ll locationOfObject:object2]];\n\n  STAssertEquals(ll.count, (NSUInteger)2, @\"There should be exactly two objects.\");\n  STAssertEquals(ll.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll.lastObject, object3, @\"Tail should be the third object.\");\n}\n\n- (void)testLinkedListIteration {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n\n  NSInteger ix = 0;\n  for (id object in ll) {\n    if (ix == 0) {\n      STAssertEquals(object, object1, @\"The first object should be object1.\");\n\n    } else if (ix == 1) {\n      STAssertEquals(object, object2, @\"The second object should be object2.\");\n\n    } else if (ix == 2) {\n      STAssertEquals(object, object3, @\"The third object should be object3.\");\n    }\n    ++ix;\n  }\n}\n\n- (void)testLinkedListEnumeration {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n\n  NSEnumerator* enumerator = [ll objectEnumerator];\n  STAssertEquals([enumerator nextObject], object1, @\"The first object should be object1.\");\n  STAssertEquals([enumerator nextObject], object2, @\"The first object should be object2.\");\n  STAssertEquals([enumerator nextObject], object3, @\"The first object should be object3.\");\n  STAssertNil([enumerator nextObject], @\"The final object should be nil.\");\n}\n\n- (void)testLinkedListCopying {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n\n  NILinkedList* ll2 = [ll copy];\n  STAssertEquals(ll2.count, (NSUInteger)3, @\"There should be exactly three objects.\");\n  STAssertEquals(ll2.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll2.lastObject, object3, @\"Tail should be the third object.\");\n}\n\n- (void)testLinkedListCoding {\n  NILinkedList* ll = [[NILinkedList alloc] init];\n\n  id object1 = [NSArray array];\n  id object2 = [NSDictionary dictionary];\n  id object3 = [NSSet set];\n  [ll addObject:object1];\n  [ll addObject:object2];\n  [ll addObject:object3];\n\n  NSData* data = [NSKeyedArchiver archivedDataWithRootObject:ll];\n  NILinkedList* ll2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];\n\n  STAssertEquals(ll2.count, (NSUInteger )3, @\"There should be exactly three objects.\");\n  STAssertEquals(ll2.firstObject, object1, @\"Head should be the first object.\");\n  STAssertEquals(ll2.lastObject, object3, @\"Tail should be the third object.\");\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NIFoundationMethodsTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 9, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NIFoundationMethods.h\"\n\n@interface NIFoundationMethodsTests : XCTestCase {\n}\n\n@end\n\n@implementation NIFoundationMethodsTests\n\n\n#pragma mark - CGRect Methods\n\n\n- (void)testCGRectMethods {\n  CGRect rect = CGRectMake(0, 0, 100, 100);\n\n  XCTAssertTrue(CGRectEqualToRect(CGRectMake(0, 0, 90, 90),\n                                 NIRectContract(rect, 10, 10)),\n                @\"Contracting a rect should only modify the right and bottom edges.\");\n\n  XCTAssertTrue(CGRectEqualToRect(CGRectMake(10, 10, 90, 90),\n                                 NIRectShift(rect, 10, 10)),\n                @\"Shifting a rect should only modify the left and top edges.\");\n}\n\n- (void)testCGRectCenterWithin {\n  UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];\n  UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];\n  \n  CGRect centeredFrame = NIFrameOfCenteredViewWithinView(subview, containerView);\n  \n  XCTAssertTrue(CGRectEqualToRect(centeredFrame, CGRectMake(45, 45, 10, 10)), @\"Rect should be centered.\");\n}\n\n\n#pragma mark - NSRange Methods\n\n\n- (void)testNSRangeMethods {\n  CFRange cfRange = CFRangeMake(0, 10);\n  NSRange nsRange = NIMakeNSRangeFromCFRange(cfRange);\n\n  XCTAssertEqual(nsRange.location, (NSUInteger)cfRange.location,\n                 @\"The two locations should be equal.\");\n\n  XCTAssertEqual(nsRange.length, (NSUInteger)cfRange.length,\n                 @\"The two lengths should be equal.\");\n}\n\n#pragma mark - NSData Methods\n\n\n- (void)testNSDataHashing {\n  const char* bytes = \"nimbus\";\n  NSData* data = [[NSData alloc] initWithBytes:bytes length:strlen(bytes)];\n  \n  XCTAssertTrue([NIMD5HashFromData(data) isEqualToString:@\"0e78d66f33c484a3c3b36d69bd3114cf\"],\n                @\"MD5 hashes don't match.\");\n  XCTAssertTrue([NISHA1HashFromData(data) isEqualToString:@\"c1b42d95fd18ad8a56d4fd7bbb4105952620d857\"],\n                @\"SHA1 hashes don't match.\");\n}\n\n#pragma mark - NSString Methods\n\n\n- (void)testNIIsStringWithWhitespaceAndNewlines {\n  XCTAssertTrue(NIIsStringWithWhitespaceAndNewlines(@\"\"), @\"Empty string should be whitespace and newlines.\");\n  XCTAssertTrue(NIIsStringWithWhitespaceAndNewlines(@\" \"), @\"Space should be whitespace and newlines.\");\n  XCTAssertTrue(NIIsStringWithWhitespaceAndNewlines(@\"    \\n\\r\"), @\"Whitespace and newlines should be whitespace and newlines.\");\n  XCTAssertFalse(NIIsStringWithWhitespaceAndNewlines(nil), @\"nil is not a string\");\n  XCTAssertFalse(NIIsStringWithWhitespaceAndNewlines(@\"cat\"), @\"Words are not whitespace and newlines\");\n\n  for (unsigned short unicode = 0x000A; unicode <= 0x000D; ++unicode) {\n    NSString* str = [NSString stringWithFormat:@\"%C\", unicode];\n    XCTAssertTrue(NIIsStringWithWhitespaceAndNewlines(str),\n                  @\"Unicode string #%X should be whitespace.\", unicode);\n  }\n\n  NSString* str = [NSString stringWithFormat:@\"%C\", (unsigned short)0x0085];\n  XCTAssertTrue(NIIsStringWithWhitespaceAndNewlines(str), @\"Unicode string should be whitespace.\");\n  \n  XCTAssertTrue(NIIsStringWithWhitespaceAndNewlines(@\" \\t\\r\\n\"), @\"Empty string should be whitespace.\");\n  \n  XCTAssertTrue(!NIIsStringWithWhitespaceAndNewlines(@\"a\"), @\"Text should not be whitespace.\");\n  XCTAssertTrue(!NIIsStringWithWhitespaceAndNewlines(@\" \\r\\n\\ta\\r\\n \"), @\"Text should not be whitespace.\");\n}\n\n#pragma mark - General Purpose Methods\n\n\n- (void)testNIBoundf {\n  XCTAssertEqual(NIBoundf(1, 0, 2), 1.f, @\"Should be equal.\");\n  XCTAssertEqual(NIBoundf(20, 0, 2), 2.f, @\"Should be equal.\");\n  XCTAssertEqual(NIBoundf(-500, 0, 2), 0.f, @\"Should be equal.\");\n  XCTAssertEqual(NIBoundf(5234, 0, -500), 0.f, @\"Should be equal.\");\n}\n\n- (void)testNIBoundi {\n  XCTAssertEqual(NIBoundi(1, 0, 2), 1, @\"Should be equal.\");\n  XCTAssertEqual(NIBoundi(20, 0, 2), 2, @\"Should be equal.\");\n  XCTAssertEqual(NIBoundi(-500, 0, 2), 0, @\"Should be equal.\");\n  XCTAssertEqual(NIBoundi(5234, 0, -500), 0, @\"Should be equal.\");\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NIMemoryCacheTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import <UIKit/UIKit.h>\n\n#import \"NIDebuggingTools.h\"\n#import \"NIInMemoryCache.h\"\n#import \"NSDate+UnitTesting.h\"\n\n@interface NIMemoryCacheTests : XCTestCase {\n}\n\n@end\n\n@implementation NIMemoryCacheTests\n\n\n#pragma mark - In-Memory Cache\n\n\n- (void)testInitialization {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty after initialization.\");\n}\n\n- (void)testSingleObjectNoExpiration {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1 withName:@\"obj1\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object in it.\");\n  XCTAssertEqual([cache objectWithName:@\"obj1\"], cacheObject1, @\"Cache object should be equal.\");\n}\n\n- (void)testMultipleObjectsNoExpiration {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1 withName:@\"obj1\"];\n\n  id cacheObject2 = [NSArray array];\n  [cache storeObject: cacheObject2 withName: @\"obj2\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)2, @\"Cache should have two objects in it.\");\n  XCTAssertEqual([cache objectWithName:@\"obj1\"], cacheObject1, @\"Cache object should be equal.\");\n  XCTAssertEqual([cache objectWithName:@\"obj2\"], cacheObject2, @\"Cache object should be equal.\");\n}\n\n- (void)testRemovingSingleObject {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1 withName:@\"obj1\"];\n\n  [cache removeObjectWithName:@\"obj1\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty.\");\n}\n\n- (void)testRemovingCachePrefixes {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1 withName:@\"obj1\"];\n  id cacheObject1Prefix = [NSArray array];\n  [cache storeObject:cacheObject1Prefix withName:@\"obj1_details\"];\n  id cacheObject2 = [NSArray array];\n  [cache storeObject:cacheObject2 withName:@\"obj2\"];\n\n  [cache removeAllObjectsWithPrefix:@\"obj1\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n}\n\n- (void)testRemovingAllObjects {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1 withName:@\"obj1\"];\n\n  id cacheObject2 = [NSArray array];\n  [cache storeObject:cacheObject2 withName:@\"obj2\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)2, @\"Cache should have two objects in it.\");\n  [cache removeAllObjects];\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should now be empty.\");\n}\n\n- (void)testSingleObjectWithFutureExpiration {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:1]];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object in it.\");\n}\n\n- (void)testMultipleObjectsWithFutureExpiration {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:1]];\n\n  id cacheObject2 = [NSArray array];\n  [cache storeObject: cacheObject2\n            withName: @\"obj2\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:100]];\n\n  XCTAssertEqual([cache count], (NSUInteger)2, @\"Cache should have two objects in it.\");\n}\n\n- (void)testSingleObjectWithPastExpiration {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:-1]];\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty.\");\n}\n\n- (void)testMultipleObjectsWithPastExpiration {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:-1]];\n\n  id cacheObject2 = [NSArray array];\n  [cache storeObject: cacheObject2\n            withName: @\"obj2\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:-100]];\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty.\");\n}\n\n- (void)testSingleObjectWithExpiredUpdate {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"];\n\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:-1]];\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty.\");\n}\n\n- (void)testSingleObjectWithNonExpiredUpdate {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"];\n\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:1]];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one item.\");\n}\n\n- (void)testSingleObjectWithExpiration {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:1]];\n\n  [NSDate setFakeDate:[NSDate dateWithTimeIntervalSinceNow:2]];\n\n  // This makes [NSDate date] call our fakeDate implementation, which allows us to fake the\n  // current time so that we don't have to pause the tests while we wait for the object to\n  // expire.\n  [NSDate swizzleMethodsForUnitTesting];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n\n  // Accessing an expired object removes it from the cache entirely.\n  XCTAssertNil([cache objectWithName:@\"obj1\"], @\"Object should have expired.\");\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty.\");\n\n  // Reset the class implementations when we're done with them.\n  [NSDate swizzleMethodsForUnitTesting];\n}\n\n- (void)testAccessExpiredObjectWithContains {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1\n            withName:@\"obj1\"\n        expiresAfter:[NSDate dateWithTimeIntervalSinceNow:1]];\n\n  [NSDate setFakeDate:[NSDate dateWithTimeIntervalSinceNow:2]];\n\n  // This makes [NSDate date] call our fakeDate implementation, which allows us to fake the\n  // current time so that we don't have to pause the tests while we wait for the object to\n  // expire.\n  [NSDate swizzleMethodsForUnitTesting];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n\n  // Accessing an expired object removes it from the cache entirely.\n  XCTAssertFalse([cache containsObjectWithName:@\"obj1\"], @\"Object should have expired.\");\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty.\");\n\n  // Reset the class implementations when we're done with them.\n  [NSDate swizzleMethodsForUnitTesting];\n}\n\n- (void)testAccessExpiredObjectWithDate {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1\n            withName:@\"obj1\"\n        expiresAfter:[NSDate dateWithTimeIntervalSinceNow:1]];\n\n  [NSDate setFakeDate:[NSDate dateWithTimeIntervalSinceNow:2]];\n\n  // This makes [NSDate date] call our fakeDate implementation, which allows us to fake the\n  // current time so that we don't have to pause the tests while we wait for the object to\n  // expire.\n  [NSDate swizzleMethodsForUnitTesting];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n\n  // Accessing an expired object removes it from the cache entirely.\n  XCTAssertNil([cache dateOfLastAccessWithName:@\"obj1\"], @\"Object should have expired.\");\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty.\");\n\n  // Reset the class implementations when we're done with them.\n  [NSDate swizzleMethodsForUnitTesting];\n}\n\n- (void)testAccessExpiredObjectWithNameOfLeastRecentlyUsedObject {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1\n            withName:@\"obj1\"\n        expiresAfter:[NSDate dateWithTimeIntervalSinceNow:1]];\n\n  [NSDate setFakeDate:[NSDate dateWithTimeIntervalSinceNow:2]];\n\n  // This makes [NSDate date] call our fakeDate implementation, which allows us to fake the\n  // current time so that we don't have to pause the tests while we wait for the object to\n  // expire.\n  [NSDate swizzleMethodsForUnitTesting];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n\n  // Accessing an expired object removes it from the cache entirely.\n  XCTAssertNil([cache nameOfLeastRecentlyUsedObject], @\"Object should have expired.\");\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty.\");\n\n  // Reset the class implementations when we're done with them.\n  [NSDate swizzleMethodsForUnitTesting];\n}\n\n- (void)testAccessExpiredObjectWithNameOfMostRecentlyUsedObject {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1\n            withName:@\"obj1\"\n        expiresAfter:[NSDate dateWithTimeIntervalSinceNow:1]];\n\n  [NSDate setFakeDate:[NSDate dateWithTimeIntervalSinceNow:2]];\n\n  // This makes [NSDate date] call our fakeDate implementation, which allows us to fake the\n  // current time so that we don't have to pause the tests while we wait for the object to\n  // expire.\n  [NSDate swizzleMethodsForUnitTesting];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n\n  // Accessing an expired object removes it from the cache entirely.\n  XCTAssertNil([cache nameOfMostRecentlyUsedObject], @\"Object should have expired.\");\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should be empty.\");\n\n  // Reset the class implementations when we're done with them.\n  [NSDate swizzleMethodsForUnitTesting];\n}\n\n- (void)testHasObject {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1 withName:@\"obj1\"];\n\n  XCTAssertTrue([cache containsObjectWithName:@\"obj1\"], @\"obj1 should exist in the cache.\");\n\n  XCTAssertFalse([cache containsObjectWithName:@\"obj2\"], @\"obj2 should not exist in the cache.\");\n}\n\n- (void)testAccessTimeModifications {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject:cacheObject1 withName:@\"obj1\"];\n\n  NSDate* lastAccessTime = [cache dateOfLastAccessWithName:@\"obj1\"];\n\n  // Does not update the access time.\n  [cache containsObjectWithName:@\"obj1\"];\n\n  XCTAssertEqual(lastAccessTime, [cache dateOfLastAccessWithName:@\"obj1\"],\n                 @\"Access time should not have been modified.\");\n\n  // Does update the access time.\n  [cache objectWithName:@\"obj1\"];\n\n  XCTAssertFalse([lastAccessTime isEqualToDate:[cache dateOfLastAccessWithName:@\"obj1\"]],\n                 @\"Access time should have been modified.\");\n}\n\n- (void)testLeastAndMostRecentlyUsedObjects {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  XCTAssertNil([cache nameOfLeastRecentlyUsedObject],\n               @\"There should not be a least-recently-used object.\");\n  XCTAssertNil([cache nameOfMostRecentlyUsedObject],\n               @\"There should not be a most-recently-used object.\");\n\n  id cacheObject1 = [NSArray array];\n  id cacheObject2 = [NSDictionary dictionary];\n  id cacheObject3 = [NSSet set];\n  [cache storeObject:cacheObject1 withName:@\"obj1\"];\n  [cache storeObject:cacheObject2 withName:@\"obj2\"];\n  [cache storeObject:cacheObject3 withName:@\"obj3\"];\n\n  XCTAssertEqual(@\"obj1\", [cache nameOfLeastRecentlyUsedObject],\n                 @\"The least recently used object should be object 1.\");\n  XCTAssertEqual(@\"obj3\", [cache nameOfMostRecentlyUsedObject],\n                 @\"The most recently used object should be object 3.\");\n\n  // Make object 1 the most-recently-accessed\n  [cache objectWithName:@\"obj1\"];\n\n  XCTAssertEqual(@\"obj2\", [cache nameOfLeastRecentlyUsedObject],\n                 @\"The least recently used object should be object 2.\");\n  XCTAssertEqual(@\"obj1\", [cache nameOfMostRecentlyUsedObject],\n                 @\"The most recently used object should be object 1.\");\n}\n\n- (void)testReduceMemoryUsage {\n  NIMemoryCache* cache = [[NIMemoryCache alloc] init];\n\n  id cacheObject1 = [NSArray array];\n  [cache storeObject: cacheObject1\n            withName: @\"obj1\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:1]];\n\n  id cacheObject2 = [NSDictionary dictionary];\n  [cache storeObject: cacheObject2\n            withName: @\"obj2\"\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:10]];\n\n  [NSDate setFakeDate:[NSDate dateWithTimeIntervalSinceNow:2]];\n\n  // This makes [NSDate date] call our fakeDate implementation, which allows us to fake the\n  // current time so that we don't have to pause the tests while we wait for the object to\n  // expire.\n  [NSDate swizzleMethodsForUnitTesting];\n\n  XCTAssertEqual([cache count], (NSUInteger)2, @\"Cache should have two objects.\");\n\n  [cache reduceMemoryUsage];\n\n  XCTAssertNil([cache objectWithName:@\"obj1\"], @\"Object 1 should have expired.\");\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object left.\");\n\n  XCTAssertNotNil([cache objectWithName:@\"obj2\"], @\"Object 2 should still be around.\");\n\n  // Reset the class implementations when we're done with them.\n  [NSDate swizzleMethodsForUnitTesting];\n}\n\n#pragma mark - Image In-Memory Cache\n\n\n// Create an image of a given size. The contents are undefined.\n- (UIImage *)emptyImageWithSize:(CGSize)size {\n  UIGraphicsBeginImageContext(size);\n  UIImage* image = UIGraphicsGetImageFromCurrentImageContext();\n  UIGraphicsEndImageContext();\n\n  return image;\n}\n\n- (void)testImageCacheStoreNonImage {\n  NIImageMemoryCache* cache = [[NIImageMemoryCache alloc] init];\n\n  NIDebugAssertionsShouldBreak = NO;\n  [cache storeObject:[NSArray array] withName:@\"obj1\"];\n  NIDebugAssertionsShouldBreak = YES;\n\n  XCTAssertEqual(cache.count, (NSUInteger)0, @\"Cache should be empty.\");\n}\n\n- (void)testImageCacheNoLimit {\n  NIImageMemoryCache* cache = [[NIImageMemoryCache alloc] init];\n\n  UIImage* img1 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n  UIImage* img2 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n  [cache storeObject:img1 withName:@\"obj1\"];\n  [cache storeObject:img2 withName:@\"obj2\"];\n\n  XCTAssertEqual(cache.count, (NSUInteger)2, @\"Cache should have two objects.\");\n  XCTAssertNotNil([cache objectWithName:@\"obj1\"], @\"Image 1 should still be around.\");\n  XCTAssertNotNil([cache objectWithName:@\"obj2\"], @\"Image 2 should still be around.\");\n}\n\n- (void)testImageCacheRemoveAllObjects {\n  NIImageMemoryCache* cache = [[NIImageMemoryCache alloc] init];\n\n  UIImage* img1 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n  UIImage* img2 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n  [cache storeObject:img1 withName:@\"obj1\"];\n  [cache storeObject:img2 withName:@\"obj2\"];\n\n  XCTAssertEqual(cache.count, (NSUInteger)2, @\"Cache should have two objects in it.\");\n  [cache removeAllObjects];\n  XCTAssertEqual(cache.count, (NSUInteger)0, @\"Cache should now be empty.\");\n  XCTAssertEqual(cache.numberOfPixels, (unsigned long long)0, @\"Cache should have zero pixels.\");\n}\n\n- (void)testImageCacheNils {\n  // Disable NIDASSERTs from breaking the program execution.\n  NIDebugAssertionsShouldBreak = NO;\n  \n  NIImageMemoryCache* cache = [[NIImageMemoryCache alloc] init];\n\n  [cache storeObject: nil\n            withName: @\"obj1\"];\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"No objects should have been stored in the cache.\");\n\n  [cache storeObject: nil\n            withName: nil];\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"No objects should have been stored in the cache.\");\n\n  [cache storeObject: [NSDictionary dictionary]\n            withName: nil];\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"No objects should have been stored in the cache.\");\n\n  [cache storeObject: [NSDictionary dictionary]\n            withName: nil\n        expiresAfter: nil];\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"No objects should have been stored in the cache.\");\n\n  [cache storeObject: [NSDictionary dictionary]\n            withName: nil\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:1]];\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"No objects should have been stored in the cache.\");\n\n  [cache storeObject: nil\n            withName: @\"obj1\"\n        expiresAfter: nil];\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"No objects should have been stored in the cache.\");\n\n  [cache storeObject: nil\n            withName: nil\n        expiresAfter: [NSDate dateWithTimeIntervalSinceNow:1]];\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"No objects should have been stored in the cache.\");\n\n  [cache storeObject: nil\n            withName: nil\n        expiresAfter: nil];\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"No objects should have been stored in the cache.\");\n\n  XCTAssertNil([cache objectWithName:nil], @\"The result should be nil\");\n  [cache removeObjectWithName:nil];\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"No objects should have been stored in the cache.\");\n  \n  NIDebugAssertionsShouldBreak = YES;\n}\n\n- (void)testImageCacheStoreTooMuch {\n  NIImageMemoryCache* cache = [[NIImageMemoryCache alloc] init];\n\n  static const NSUInteger numberOfPixelsInOneImage = 100 * 100;\n  cache.maxNumberOfPixels = numberOfPixelsInOneImage;\n\n  UIImage* img1 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n  UIImage* img2 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n\n  [cache storeObject: img1\n            withName: @\"obj1\"];\n\n  // This second image will push out the first image.\n  [cache storeObject: img2\n            withName: @\"obj2\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n  XCTAssertNil([cache objectWithName:@\"obj1\"], @\"Image 1 should not still be around.\");\n  XCTAssertNotNil([cache objectWithName:@\"obj2\"], @\"Image 2 should still be around.\");\n}\n\n- (void)testImageCacheReduceMemoryUsage {\n  NIImageMemoryCache* cache = [[NIImageMemoryCache alloc] init];\n\n  static const NSUInteger numberOfPixelsInOneImage = 100 * 100;\n  cache.maxNumberOfPixels = numberOfPixelsInOneImage * 2;\n  cache.maxNumberOfPixelsUnderStress = numberOfPixelsInOneImage;\n\n  UIImage* img1 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n  UIImage* img2 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n\n  [cache storeObject: img1\n            withName: @\"obj1\"];\n\n  [cache storeObject: img2\n            withName: @\"obj2\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)2, @\"Cache should have two objects.\");\n\n  // Our \"low memory\" cache size will only fit one image. The first image should be the one\n  // removed.\n  [cache reduceMemoryUsage];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n  XCTAssertNil([cache objectWithName:@\"obj1\"], @\"Image 1 should not still be around.\");\n  XCTAssertNotNil([cache objectWithName:@\"obj2\"], @\"Image 2 should still be around.\");\n}\n\n- (void)testImageCacheReduceMemoryUsageWithAccess {\n  NIImageMemoryCache* cache = [[NIImageMemoryCache alloc] init];\n\n  static const NSUInteger numberOfPixelsInOneImage = 100 * 100;\n  cache.maxNumberOfPixels = numberOfPixelsInOneImage * 2;\n  cache.maxNumberOfPixelsUnderStress = numberOfPixelsInOneImage;\n\n  UIImage* img1 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n  UIImage* img2 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n\n  [cache storeObject: img1\n            withName: @\"obj1\"];\n\n  [cache storeObject: img2\n            withName: @\"obj2\"];\n\n  // Update the access time for img1.\n  [cache objectWithName:@\"obj1\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)2, @\"Cache should have two objects.\");\n\n  // Our \"low memory\" cache size will only fit one image.\n  [cache reduceMemoryUsage];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n  XCTAssertNotNil([cache objectWithName:@\"obj1\"], @\"Image 1 should still be around.\");\n  XCTAssertNil([cache objectWithName:@\"obj2\"], @\"Image 2 should not still be around.\");\n}\n\n- (void)testImageCacheReduceMemoryUsageWithThrashingAccess {\n  NIImageMemoryCache* cache = [[NIImageMemoryCache alloc] init];\n\n  static const NSUInteger numberOfPixelsInOneImage = 100 * 100;\n  cache.maxNumberOfPixels = numberOfPixelsInOneImage * 2;\n  cache.maxNumberOfPixelsUnderStress = numberOfPixelsInOneImage;\n\n  UIImage* img1 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n  UIImage* img2 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n\n  [cache storeObject: img1\n            withName: @\"obj1\"];\n\n  [cache storeObject: img2\n            withName: @\"obj2\"];\n\n  for (NSInteger ix = 0; ix < 10; ++ix) {\n    [cache objectWithName:@\"obj1\"];\n    [cache objectWithName:@\"obj2\"];\n  }\n\n  XCTAssertEqual([cache count], (NSUInteger)2, @\"Cache should have two objects.\");\n\n  // Our \"low memory\" cache size will only fit one image.\n  [cache reduceMemoryUsage];\n\n  XCTAssertEqual([cache count], (NSUInteger)1, @\"Cache should have one object.\");\n  XCTAssertNil([cache objectWithName:@\"obj1\"], @\"Image 1 should not still be around.\");\n  XCTAssertNotNil([cache objectWithName:@\"obj2\"], @\"Image 2 should still be around.\");\n}\n\n- (void)testImageCacheStoringWithTinyLimit {\n  NIImageMemoryCache* cache = [[NIImageMemoryCache alloc] init];\n\n  cache.maxNumberOfPixels = 1;\n\n  UIImage* img1 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n  UIImage* img2 = [self emptyImageWithSize:CGSizeMake(100, 100)];\n\n  [cache storeObject: img1\n            withName: @\"obj1\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should have zero objects.\");\n\n  [cache storeObject: img2\n            withName: @\"obj2\"];\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should have zero objects.\");\n\n  [cache reduceMemoryUsage];\n\n  XCTAssertEqual([cache count], (NSUInteger)0, @\"Cache should have zero objects.\");\n\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NINetworkActivityTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n#import <UIKit/UIKit.h>\n\n#import \"NINetworkActivity.h\"\n\n@interface NINetworkActivityTests : XCTestCase\n@end\n\n\n@implementation NINetworkActivityTests\n\n\n- (void)testNetworkActivity {\n  XCTAssertFalse([UIApplication sharedApplication].networkActivityIndicatorVisible,\n                 @\"Activity indicator should be hidden.\");\n\n  // TODO (Jan 26, 2012): Swizzle out the networkActivityIndicatorVisible method so that we can\n  // test when it gets changed.\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NINonEmptyCollectionTestingTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 9, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NINonEmptyCollectionTesting.h\"\n\n\n#pragma mark - Unit Test Documentation\n\n/**\n * @fn NIIsArrayWithObjects(id)\n *\n * - [test] nil.\n * - [test] Empty array.\n * - [test] Non-array.\n * - [test] Array with any objects.\n */\n\n/**\n * @fn NIIsSetWithObjects(id)\n *\n * - [test] nil.\n * - [test] Empty set.\n * - [test] Non-set.\n * - [test] Set with any objects.\n */\n\n/**\n * @fn NIIsStringWithAnyText(id)\n *\n * - [test] nil.\n * - [test] Newly-allocated string.\n * - [test] @\"\"\n * - [test] Non-string.\n * - [test] String with any text.\n */\n\n@interface NINonEmptyCollectionTestingTests : XCTestCase {\n}\n\n@end\n\n\n@implementation NINonEmptyCollectionTestingTests\n\n\n#pragma mark - Non-Empty Collection Testing\n\n\n- (void)testIsArrayWithObjects {\n  XCTAssertTrue(!NIIsArrayWithObjects(nil), @\"nil should not be an array with items.\");\n\n  NSMutableArray* array = [[NSMutableArray alloc] init];\n\n  XCTAssertTrue(!NIIsArrayWithObjects(array), @\"This array should not have any items.\");\n\n  NSDictionary* dictionary = [[NSDictionary alloc] init];\n  XCTAssertTrue(!NIIsArrayWithObjects(dictionary), @\"This is not an array.\");\n\n  [array addObject:dictionary];\n  XCTAssertTrue(NIIsArrayWithObjects(array), @\"This array should have items.\");\n}\n\n- (void)testIsSetWithObjects {\n  XCTAssertTrue(!NIIsSetWithObjects(nil), @\"nil should not be a set with items.\");\n\n  NSMutableSet* set = [[NSMutableSet alloc] init];\n\n  XCTAssertTrue(!NIIsSetWithObjects(set), @\"This set should not have any items.\");\n\n  NSDictionary* dictionary = [[NSDictionary alloc] init];\n  XCTAssertTrue(!NIIsSetWithObjects(dictionary), @\"This is not an set.\");\n\n  [set addObject:dictionary];\n  XCTAssertTrue(NIIsSetWithObjects(set), @\"This set should have items.\");\n}\n\n- (void)testIsStringWithAnyText {\n  XCTAssertTrue(!NIIsStringWithAnyText(nil), @\"nil should not be a string with any text.\");\n\n  NSString* string = [[NSString alloc] init];\n\n  XCTAssertTrue(!NIIsStringWithAnyText(string), @\"This should be an empty string.\");\n\n  NSDictionary* dictionary = [[NSDictionary alloc] init];\n  XCTAssertTrue(!NIIsStringWithAnyText(dictionary), @\"This is not a string.\");\n\n  XCTAssertTrue(!NIIsStringWithAnyText(@\"\"), @\"This should be an empty string.\");\n  XCTAssertTrue(NIIsStringWithAnyText(@\"three20\"), @\"This should be a string with text.\");\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NINonRetainingCollectionsTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 9, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NIPreprocessorMacros.h\"\n#import \"NINonRetainingCollections.h\"\n\n@interface NINonRetainingCollectionsTests : XCTestCase {\n}\n\n@end\n\n\n@implementation NINonRetainingCollectionsTests\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NIRuntimeClassModificationsTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NIPreprocessorMacros.h\"\n#import \"NIRuntimeClassModifications.h\"\n\n#pragma mark - Unit Test Documentation\n\n/**\n * @fn NISwapInstanceMethods(Class, SEL, SEL)\n *\n * - [test] Swap two instance methods on a class.\n */\n\n/**\n * @fn NISwapClassMethods(Class, SEL, SEL)\n *\n * - [test] Swap two static methods on a class.\n */\n\nstatic NSInteger sClassValue = 0;\n\n@interface NIRuntimeClassModificationsTests : XCTestCase {\n@private\n  NSInteger _value;\n}\n\n- (void)setValueToOne;\n- (void)setValueToTwo;\n\n+ (void)setValueToThree;\n+ (void)setValueToFour;\n\n@end\n\n\n@implementation NIRuntimeClassModificationsTests\n\n\n- (void)testSwapInstanceMethods {\n  _value = 0;\n\n  [self setValueToOne];\n  XCTAssertEqual(_value, (NSInteger)1, @\"value should be 1\");\n\n  [self setValueToTwo];\n  XCTAssertEqual(_value, (NSInteger)2, @\"value should be 2\");\n\n  NISwapInstanceMethods([NIRuntimeClassModificationsTests class],\n                        @selector(setValueToOne), @selector(setValueToTwo));\n\n  [self setValueToOne];\n  XCTAssertEqual(_value, (NSInteger)2, @\"value should be 2\");\n\n  [self setValueToTwo];\n  XCTAssertEqual(_value, (NSInteger)1, @\"value should be 1\");\n}\n\n- (void)testSwapClassMethods {\n  sClassValue = 0;\n\n  [[self class] setValueToThree];\n  XCTAssertEqual(sClassValue, (NSInteger)3, @\"value should be 3\");\n\n  [[self class] setValueToFour];\n  XCTAssertEqual(sClassValue, (NSInteger)4, @\"value should be 4\");\n\n  NISwapClassMethods([NIRuntimeClassModificationsTests class],\n                     @selector(setValueToThree), @selector(setValueToFour));\n\n  [[self class] setValueToThree];\n  XCTAssertEqual(sClassValue, (NSInteger)4, @\"value should be 4\");\n\n  [[self class] setValueToFour];\n  XCTAssertEqual(sClassValue, (NSInteger)3, @\"value should be 3\");\n}\n\n#pragma mark - Class Methods\n\n\n- (void)setValueToOne {\n  _value = 1;\n}\n\n- (void)setValueToTwo {\n  _value = 2;\n}\n\n+ (void)setValueToThree {\n  sClassValue = 3;\n}\n\n+ (void)setValueToFour {\n  sClassValue = 4;\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NIStateTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIState.h\"\n#import \"NIInMemoryCache.h\"\n\n@interface NIStateTests : XCTestCase\n@end\n\n\n@implementation NIStateTests\n\n\n- (void)testSingletonAccess {\n  XCTAssertNotNil([Nimbus imageMemoryCache], @\"Singleton object should be created automatically.\");\n  XCTAssertNotNil([Nimbus networkOperationQueue], @\"Singleton object should be created automatically.\");\n}\n\n- (void)testSingletonSetting {\n  NIImageMemoryCache *cache = [[NIImageMemoryCache alloc] init];\n  [Nimbus setImageMemoryCache:cache];\n  XCTAssertEqual([Nimbus imageMemoryCache], cache, @\"Singleton object should have been set.\");\n\n  NSOperationQueue *queue = [[NSOperationQueue alloc] init];\n  [Nimbus setNetworkOperationQueue:queue];\n  XCTAssertEqual([Nimbus networkOperationQueue], queue, @\"Singleton object should have been set.\");\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NIViewRecyclerTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 9, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCore.h\"\n\n@interface RecyclableView : UIView <NIRecyclableView> {\n@private\n  NSString* _reuseIdentifier;\n  BOOL _didReuse;\n}\n@property (nonatomic, copy) NSString* reuseIdentifier;\n@property (nonatomic, assign) BOOL didReuse;\n@end\n\n@interface NIViewRecyclerTests : XCTestCase\n@end\n\n@implementation NIViewRecyclerTests\n\n\n- (void)testNils {\n  NIViewRecycler* recycler = [[NIViewRecycler alloc] init];\n  XCTAssertNil([recycler dequeueReusableViewWithIdentifier:nil], @\"Should be nil.\");\n  NIDebugAssertionsShouldBreak = NO;\n  [recycler recycleView:nil];\n  NIDebugAssertionsShouldBreak = YES;\n\n  XCTAssertNil([recycler dequeueReusableViewWithIdentifier:nil], @\"Should be nil.\");\n}\n\n- (void)testNoReuseIdentifierRecycling {\n  NIViewRecycler* recycler = [[NIViewRecycler alloc] init];\n  NSString* reuseIdentifier = NSStringFromClass([RecyclableView class]);\n  {\n    RecyclableView* view = [[RecyclableView alloc] init];\n    [recycler recycleView:view];\n    XCTAssertFalse(view.didReuse, @\"Should not have reused this view yet.\");\n  }\n  {\n    RecyclableView* view = (RecyclableView*)[recycler dequeueReusableViewWithIdentifier:reuseIdentifier];\n    XCTAssertTrue(view.didReuse, @\"Should have reused this view.\");\n  }\n  \n  XCTAssertNil([recycler dequeueReusableViewWithIdentifier:reuseIdentifier], @\"Should be no views left.\");\n}\n\n- (void)testRecycling {\n  NIViewRecycler* recycler = [[NIViewRecycler alloc] init];\n  NSString* reuseIdentifier = NSStringFromClass([RecyclableView class]);\n  {\n    RecyclableView* view = [[RecyclableView alloc] init];\n    view.reuseIdentifier = reuseIdentifier;\n    [recycler recycleView:view];\n    XCTAssertFalse(view.didReuse, @\"Should not have reused this view yet.\");\n  }\n  {\n    RecyclableView* view = (RecyclableView*)[recycler dequeueReusableViewWithIdentifier:reuseIdentifier];\n    XCTAssertTrue(view.didReuse, @\"Should have reused this view.\");\n  }\n\n  XCTAssertNil([recycler dequeueReusableViewWithIdentifier:reuseIdentifier], @\"Should be no views left.\");\n}\n\n- (void)testComplexRecycling {\n  NIViewRecycler* recycler = [[NIViewRecycler alloc] init];\n  {\n    RecyclableView* view = [[RecyclableView alloc] init];\n    view.reuseIdentifier = @\"1\";\n    [recycler recycleView:view];\n  }\n  {\n    RecyclableView* view = [[RecyclableView alloc] init];\n    view.reuseIdentifier = @\"2\";\n    [recycler recycleView:view];\n  }\n\n  {\n    RecyclableView* view = (RecyclableView*)[recycler dequeueReusableViewWithIdentifier:@\"1\"];\n    XCTAssertTrue(view.didReuse, @\"Should have reused this view.\");\n    XCTAssertTrue([view.reuseIdentifier isEqualToString:@\"1\"], @\"Reuse identifier should be 1.\");\n\n    XCTAssertNil([recycler dequeueReusableViewWithIdentifier:@\"1\"], @\"Should be no '1' views left.\");\n  }\n\n  {\n    RecyclableView* view = (RecyclableView*)[recycler dequeueReusableViewWithIdentifier:@\"2\"];\n    XCTAssertTrue(view.didReuse, @\"Should have reused this view.\");\n    XCTAssertTrue([view.reuseIdentifier isEqualToString:@\"2\"], @\"Reuse identifier should be 2.\");\n    \n    XCTAssertNil([recycler dequeueReusableViewWithIdentifier:@\"2\"], @\"Should be no '2' views left.\");\n  }\n}\n\n- (void)testMemoryWarning {\n  NIViewRecycler* recycler = [[NIViewRecycler alloc] init];\n  NSString* reuseIdentifier = NSStringFromClass([RecyclableView class]);\n  {\n    RecyclableView* view = [[RecyclableView alloc] init];\n    view.reuseIdentifier = reuseIdentifier;\n    [recycler recycleView:view];\n  }\n  [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidReceiveMemoryWarningNotification\n                                                      object:nil\n                                                    userInfo:nil];\n  XCTAssertNil([recycler dequeueReusableViewWithIdentifier:reuseIdentifier], @\"Should be no views left.\");\n}\n\n- (void)testRemoveAllViews {\n  NIViewRecycler* recycler = [[NIViewRecycler alloc] init];\n  NSString* reuseIdentifier = NSStringFromClass([RecyclableView class]);\n  {\n    RecyclableView* view = [[RecyclableView alloc] init];\n    view.reuseIdentifier = reuseIdentifier;\n    [recycler recycleView:view];\n  }\n  [recycler removeAllViews];\n  XCTAssertNil([recycler dequeueReusableViewWithIdentifier:reuseIdentifier], @\"Should be no views left.\");\n}\n\n@end\n\n\n@implementation RecyclableView\n\n\n\n- (void)prepareForReuse {\n  _didReuse = YES;\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NSDate+UnitTesting.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n@interface NSDate (NIUnitTesting)\n\n/**\n * @brief Swizzle any methods used for unit testing.\n *\n * Required for certain unit test methods to work.\n *\n * Call this method again to undo the swizzling.\n */\n+ (void)swizzleMethodsForUnitTesting;\n\n/**\n * @brief Set the fake date to be used.\n *\n * This should be called before swizzling, otherwise you'll end up using the previous fake date\n * to create the new fake date causing unexpected results.\n *\n * Example use:\n *\n * @htmlonly\n * <pre>\n * [NSDate setFakeDate:[NSDate dateWithTimeIntervalSinceNow:2]];\n * [NSDate swizzleMethodsForUnitTesting];\n * // All calls to [NSDate date] will now return the fake date.\n * [NSDate swizzleMethodsForUnitTesting];\n * // All calls to [NSDate date] will again return the system's current date.\n * </pre>\n * @endhtmlonly\n */\n+ (void)setFakeDate:(NSDate *)date;\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NSDate+UnitTesting.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NSDate+UnitTesting.h\"\n\n#import \"NimbusCore.h\"\n\nstatic NSDate* sFakeDate = nil;\n\n\n@implementation NSDate (NIUnitTesting)\n\n\n+ (void)swizzleMethodsForUnitTesting {\n  NISwapClassMethods([NSDate class], @selector(date), @selector(fakeDate));\n}\n\n+ (NSDate *)fakeDate {\n  if (nil == sFakeDate) {\n    // This method is meant to be swizzled, so calling fakeDate will actually call the swizzlee.\n    return [self fakeDate];\n\n  } else {\n    return sFakeDate;\n  }\n}\n\n+ (void)setFakeDate:(NSDate *)date {\n  sFakeDate = date;\n}\n\n@end\n"
  },
  {
    "path": "src/core/unittests/NimbusCoreTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/css/chameleon/README.mdown",
    "content": "Chameleon - Real-Time CSS Styling for iOS Applications\n======================================================\n\n## Getting Started\n\nChameleon uses Node.js. Check out Node.js somewhere on your system and build/install it.\n\n    git clone https://github.com/joyent/node.git\n    cd node\n    ./configure\n    make\n    sudo make install\n\nNode.js comes packaged with it's own dependency management tool called npm. Within the chameleon\ndirectory install chameleon's dependencies by running `npm install`\n\n    cd nimbus/src/css/chameleon/\n    npm install\n\nStart the server from within the chameleon directory.\n\n    cd nimbus/src/css/chameleon/\n    node chameleon.js --watch /path/to/watch/directory\n\nTest it by hitting localhost:8888/watch and modifying a file within the watch directory.\nThe request should complete immediately after you modify the file.\n\n\n## Notes about the Chameleon server\n\nThe Chameleon server is currently designed for single-watcher situations only. Do not deploy\nit on a production machine with expectations of hundreds of devices being able to update in\nany sensible way.\n\nPerhaps someday it may be worth making the server scale better if someone so desires. Until\nthat day we will likely leave the Chameleon server as is.\n"
  },
  {
    "path": "src/css/chameleon/chameleon.js",
    "content": "//\n// Copyright 2011 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// Parses the command line into properties on argv. --watch <value> becomes argv.watch = <value>\nvar argv = require('optimist').argv;\nvar path = require('path');\n// The chameleon server.\nvar server = require(\"./server\");\n\n// Only accept strings.\nif (typeof argv.watch != 'string') {\n  console.log(\"Usage:\\n  node chameleon.js --watch <path to watch changes in> --bonjour <service_identifier>\");\n  return;\n}\n\n// Verify that the watch path exists.\nif (!path.existsSync(argv.watch)) { // it's interesting that methods are assumed asynchronous by default.\n  console.log(\"Unable to find path: \"+argv.watch);\n  return;\n}\n\nconsole.log(\"Starting chameleon...\");\nconsole.log(\"  Watching \"+argv.watch);\n\nserver.start(argv.watch,argv.bonjour);\n"
  },
  {
    "path": "src/css/chameleon/package.json",
    "content": "{\n  \"name\": \"chameleon\",\n  \"version\": \"0.0.1\",\n  \"engines\": {\n    \"node\": \"0.6.x\",\n    \"npm\":  \"1.1.x\"\n  },\n  \"dependencies\": {\n    \"optimist\": \"0.3.4\",\n    \"mdns\": \"1.1.0\"\n  }\n}"
  },
  {
    "path": "src/css/chameleon/server.js",
    "content": "//\n// Copyright 2011 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\nvar http = require(\"http\");\nvar url = require(\"url\");\nvar path = require('path');\nvar fs = require('fs');\nvar mdns = null;\n\nvar changeSet = {};\nvar activeWatcher = null;\n\nvar port = 8888;\nvar watchInterval = 500; // 500 ms makes it effectively instant.\n\n/**\n * Starts the Chameleon HTTP server and file watcher on the given path.\n */\nfunction start(watchPath,bonjour) {\n\n    if (bonjour) {\n\tmdns = require('mdns');\n    }\n    /**\n     * Load a file from disk and pipe it down.\n     */\n    function onServeFile(request, response, pathname) {\n        var localFile = path.join(watchPath, pathname);\n\n        if (!path.existsSync(localFile)) {\n            response.writeHead(404);\n            response.end();\n            return;\n        }\n\n        fs.readFile(localFile, function (error, content) {\n            if (error) {\n                response.writeHead(500);\n                response.end();\n            } else if (path.extname(localFile).toLowerCase() == \".strings\") {\n                response.writeHead(200, { 'Content-Type':'text/plain' });\n                response.end(content, 'utf-8');\n            } else if (path.extname(localFile).toLowerCase() == \".json\") {\n                response.writeHead(200, { 'Content-Type':'application/json' });\n                response.end(content, 'utf-8');\n            } else {\n                response.writeHead(200, { 'Content-Type':'text/css' });\n                response.end(content, 'utf-8');\n            }\n        });\n    }\n\n    /**\n     * A new HTTP request has been started that wants to know what files have changed.\n     * If files have changed since the last time a watch request was made then the changed\n     * files will be returned immediately.\n     * Otherwise the consume method will be stowed away until a file does change.\n     */\n    function onWatch(request, response) {\n\tconsole.log(\"Client connected from\", request.connection.remoteAddress);\n        var sendResponse = function () {\n            response.writeHead(200, { 'Content-Type':'text/plain' });\n            var changed = [];\n            for (var key in changeSet) {\n                changed.push(key);\n            }\n            response.write(changed.join(\"\\n\"), 'utf-8');\n            response.end(\"\", 'utf-8');\n            changeSet = {};\n        };\n\n        var anyKeys = false;\n        for (var key in changeSet) {\n            // Ensure that we're only checking keys for the changeSet and nothing that was inherited.\n            if (changeSet.hasOwnProperty(key)) {\n                anyKeys = true;\n                break;\n            }\n        }\n\n        if (!anyKeys) {\n            activeWatcher = sendResponse;\n        } else {\n            // Consume all of the changes immediately.\n            sendResponse();\n        }\n    }\n\n    /**\n     * The general purpose entry-point for HTTP requests.\n     */\n    function onRequest(request, response) {\n        var pathname = url.parse(request.url).pathname;\n\n        if (pathname == \"/watch\") {\n            onWatch(request, response);\n\n        } else {\n            onServeFile(request, response, pathname);\n        }\n    }\n\n    /**\n     * Starts watching changes on the given file. shortName is effectively just the relative\n     * path to watchDir.\n     */\n    function watchFileAtPath(path, shortName) {\n        fs.watchFile(path, { persistent:true, interval:watchInterval }, function (curr, prev) {\n            if (curr.mtime.getTime() != prev.mtime.getTime()) {\n                changeSet[shortName] = true;\n\n                if (null != activeWatcher) {\n                    activeWatcher();\n                    activeWatcher = null;\n                }\n            }\n        });\n    }\n\n    // W00t to chjj for saving me time on this one.\n    // http://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search\n    var walk = function (dir, done) {\n        var results = [];\n        fs.readdir(dir, function (err, list) {\n            if (err) return done(err);\n            (function next(i) {\n                var file = list[i];\n                if (!file) return done(null, results);\n                file = path.join(dir, file);\n                fs.stat(file, function (err, stat) {\n                    if (stat && stat.isDirectory()) {\n                        walk(file, function (err, res) {\n                            results = results.concat(res);\n                            next(++i);\n                        });\n                    } else {\n                        results.push(file);\n                        next(++i);\n                    }\n                });\n            })(0);\n        });\n    };\n\n    // Watch all of the files in the watch path recursively.\n    walk(watchPath, function (err, results) {\n        if (err) throw err;\n        for (var i = 0; i < results.length; ++i) {\n            var fullPath = results[i];\n            var shortName = fullPath.substr(watchPath.length);\n\n            // Only watch css files.\n            if (path.extname(shortName).toLowerCase() == '.css') {\n                console.log(\"Watching\", fullPath);\n                watchFileAtPath(fullPath, shortName);\n            }\n            // And strings files\n            else if (path.extname(shortName).toLowerCase() == '.strings') {\n                console.log(\"Watching\", fullPath);\n                watchFileAtPath(fullPath, shortName);\n            }\n            // And json files\n            else if (path.extname(shortName).toLowerCase() == \".json\") {\n                console.log(\"Watching\", fullPath);\n                watchFileAtPath(fullPath, shortName);\n            }\n        }\n    });\n\n    http.createServer(onRequest).listen(port);\n    console.log(\"  Server: http://localhost:\" + port + \"/\");\n\n    if (bonjour) {\n\tvar ad = mdns.createAdvertisement(mdns.tcp(bonjour), port);\n\tad.start();\n    }\n}\n\n// This allows us to call server.start from the chameleon.js file.\nexports.start = start;\n"
  },
  {
    "path": "src/css/deps",
    "content": "core\ntextfield\n\n[Frameworks]\nAFNetworking\nFoundation.framework\nUIKit.framework\nQuartzCore.framework\n"
  },
  {
    "path": "src/css/grammar/CSSTokenizerPrefix",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Autogenerated by flex using the Nimbus CSS grammar\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// Turn off the clang analyzer for flex generated code as it reports several false positives.\n#ifndef __clang_analyzer__\n\n#include \"CssTokens.h\"\n"
  },
  {
    "path": "src/css/grammar/CSSTokenizerSuffix",
    "content": "#endif  // __clang_analyzer__\n"
  },
  {
    "path": "src/css/grammar/CSSTokens.cpp",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nconst char* cssnames[] = {\n  \"STRING\",\n  \"IDENT\",\n  \"HASH\",\n  \"EMS\",\n  \"EXS\",\n  \"LENGTH\",\n  \"ANGLE\",\n  \"TIME\",\n  \"FREQ\",\n  \"DIMEN\",\n  \"PERCENTAGE\",\n  \"NUMBER\",\n  \"URI\",\n  \"FUNCTION\",\n  \"UNICODERANGE\",\n  \"CSSIMPORT\",\n  \"UNKNOWN\",\n};\n"
  },
  {
    "path": "src/css/grammar/CSSTokens.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#include <stdio.h>\n\ntypedef enum {\n  CSSFIRST_TOKEN = 0x100,\n  CSSSTRING = CSSFIRST_TOKEN,\n  CSSIDENT,\n  CSSHASH,\n  CSSEMS,\n  CSSEXS,\n  CSSLENGTH,\n  CSSANGLE,\n  CSSTIME,\n  CSSFREQ,\n  CSSDIMEN,\n  CSSPERCENTAGE,\n  CSSNUMBER,\n  CSSURI,\n  CSSFUNCTION,\n  CSSUNICODERANGE,\n  CSSIMPORT,\n  CSSUNKNOWN,\n  CSSMEDIA\n} CssParserCodes;\n\nextern const char* cssnames[];\n\n#ifndef YY_TYPEDEF_YY_SCANNER_T\n#define YY_TYPEDEF_YY_SCANNER_T\ntypedef void* yyscan_t;\n#endif\n\nextern FILE *cssin;\n\nint csslex(void);\nint cssConsume(char* text, int token);\nint cssget_lineno(void);\n"
  },
  {
    "path": "src/css/grammar/css.grammar",
    "content": "%option case-insensitive\n%option noinput\n\nh         [0-9a-f]\nnonascii  [\\200-\\377]\nunicode   \\\\{h}{1,6}[ \\t\\r\\n\\f]?\nescape    {unicode}|\\\\[ -~\\200-\\377]\nnmstart   [a-z]|{nonascii}|{escape}\nnmchar    [a-z0-9-]|{nonascii}|{escape}\nstring1   \\\"([\\t !#$%&(-~]|\\\\{nl}|\\'|{nonascii}|{escape})*\\\"\nstring2   \\'([\\t !#$%&(-~]|\\\\{nl}|\\\"|{nonascii}|{escape})*\\'\n\nident     [-]?{nmstart}{nmchar}*\nname      {nmchar}+\nnum       [-]?[0-9]+|[-]?[0-9]*\".\"[0-9]+\nstring    {string1}|{string2}\nurl       ([!#$%&*-~]|{nonascii}|{escape})*\nw         [ \\t\\r\\n\\f]*\nnl        \\n|\\r\\n|\\r|\\f\nrange     \\?{1,6}|{h}(\\?{0,5}|{h}(\\?{0,4}|{h}(\\?{0,3}|{h}(\\?{0,2}|{h}(\\??|{h})))))\n\n%%\n\n[ \\t\\r\\n\\f]+\n\n\\/\\*[^*]*\\*+([^/][^*]*\\*+)*\\/   /* ignore comments */\n\n\"<!--\"\n\"-->\"\n\"~=\"\n\"|=\"\n\n{string}                              {cssConsume(yytext, CSSSTRING);}\n\n(\\.|#)?{ident}(\\.{ident})*(:{ident})? {cssConsume(yytext, CSSIDENT);}\n\n\"#\"{name}                             {cssConsume(yytext, CSSHASH);}\n\n\"@import\"                       {cssConsume(yytext, CSSIMPORT);}\n\"@page\"\n\"@media\"                        {cssConsume(yytext, CSSMEDIA);}\n\"@font-face\"\n\"@charset\"\n\"@namespace\"\n\n\"!{w}important\"\n\n{num}em                         {cssConsume(yytext, CSSEMS);}\n{num}ex                         {cssConsume(yytext, CSSEXS);}\n{num}px                         {cssConsume(yytext, CSSLENGTH);}\n{num}cm                         {cssConsume(yytext, CSSLENGTH);}\n{num}mm                         {cssConsume(yytext, CSSLENGTH);}\n{num}in                         {cssConsume(yytext, CSSLENGTH);}\n{num}pt                         {cssConsume(yytext, CSSLENGTH);}\n{num}pc                         {cssConsume(yytext, CSSLENGTH);}\n{num}deg                        {cssConsume(yytext, CSSANGLE);}\n{num}rad                        {cssConsume(yytext, CSSANGLE);}\n{num}grad                       {cssConsume(yytext, CSSANGLE);}\n{num}ms                         {cssConsume(yytext, CSSTIME);}\n{num}s                          {cssConsume(yytext, CSSTIME);}\n{num}Hz                         {cssConsume(yytext, CSSFREQ);}\n{num}kHz                        {cssConsume(yytext, CSSFREQ);}\n{num}{ident}                    {cssConsume(yytext, CSSDIMEN);}\n{num}%                          {cssConsume(yytext, CSSPERCENTAGE);}\n{num}                           {cssConsume(yytext, CSSNUMBER);}\n\n\"url(\"{w}{string}{w}\")\"         {cssConsume(yytext, CSSURI);}\n\"url(\"{w}{url}{w}\")\"            {cssConsume(yytext, CSSURI);}\n{ident}\"(\"                      {cssConsume(yytext, CSSFUNCTION);}\n\nU\\+{range}                      {cssConsume(yytext, CSSUNICODERANGE);}\nU\\+{h}{1,6}-{h}{1,6}            {cssConsume(yytext, CSSUNICODERANGE);}\n\n.                               {cssConsume(yytext, CSSUNKNOWN);}\n\n%%\n\nint csswrap(void){return 1;}\n"
  },
  {
    "path": "src/css/grammar/generate",
    "content": "#!/bin/bash\n#\n# Build a CSS grammar for Nimbus using flex.\n# http://flex.sourceforge.net/\n#\n# Written by Jeff Verkoeyen for the Nimbus project.\n# http://jverkoey.github.com/nimbus/\n\nflex --prefix=css --nounput css.grammar\n\ncat CSSTokenizerPrefix lex.css.c CSSTokenizerSuffix > CSSTokenizer.m\n\nrm lex.css.c\n\nmv CSSTokenizer.m ../src/CSSTokenizer.m\ncp CSSTokens.cpp ../src/CSSTokens.m\ncp CSSTokens.h ../src/CSSTokens.h\n"
  },
  {
    "path": "src/css/src/CSSTokenizer.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Autogenerated by flex using the Nimbus CSS grammar\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// Turn off the clang analyzer for flex generated code as it reports several false positives.\n#ifndef __clang_analyzer__\n\n#include \"CssTokens.h\"\n\n#line 3 \"lex.css.c\"\n\n#define  YY_INT_ALIGNED short int\n\n/* A lexical scanner generated by flex */\n\n#define yy_create_buffer css_create_buffer\n#define yy_delete_buffer css_delete_buffer\n#define yy_flex_debug css_flex_debug\n#define yy_init_buffer css_init_buffer\n#define yy_flush_buffer css_flush_buffer\n#define yy_load_buffer_state css_load_buffer_state\n#define yy_switch_to_buffer css_switch_to_buffer\n#define yyin cssin\n#define yyleng cssleng\n#define yylex csslex\n#define yylineno csslineno\n#define yyout cssout\n#define yyrestart cssrestart\n#define yytext csstext\n#define yywrap csswrap\n#define yyalloc cssalloc\n#define yyrealloc cssrealloc\n#define yyfree cssfree\n\n#define FLEX_SCANNER\n#define YY_FLEX_MAJOR_VERSION 2\n#define YY_FLEX_MINOR_VERSION 5\n#define YY_FLEX_SUBMINOR_VERSION 35\n#if YY_FLEX_SUBMINOR_VERSION > 0\n#define FLEX_BETA\n#endif\n\n/* First, we deal with  platform-specific or compiler-specific issues. */\n\n/* begin standard C headers. */\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <stdlib.h>\n\n/* end standard C headers. */\n\n/* flex integer type definitions */\n\n#ifndef FLEXINT_H\n#define FLEXINT_H\n\n/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */\n\n#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n\n/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,\n * if you want the limit (max/min) macros for int types. \n */\n#ifndef __STDC_LIMIT_MACROS\n#define __STDC_LIMIT_MACROS 1\n#endif\n\n#include <inttypes.h>\ntypedef int8_t flex_int8_t;\ntypedef uint8_t flex_uint8_t;\ntypedef int16_t flex_int16_t;\ntypedef uint16_t flex_uint16_t;\ntypedef int32_t flex_int32_t;\ntypedef uint32_t flex_uint32_t;\ntypedef uint64_t flex_uint64_t;\n#else\ntypedef signed char flex_int8_t;\ntypedef short int flex_int16_t;\ntypedef int flex_int32_t;\ntypedef unsigned char flex_uint8_t; \ntypedef unsigned short int flex_uint16_t;\ntypedef unsigned int flex_uint32_t;\n#endif /* ! C99 */\n\n/* Limits of integral types. */\n#ifndef INT8_MIN\n#define INT8_MIN               (-128)\n#endif\n#ifndef INT16_MIN\n#define INT16_MIN              (-32767-1)\n#endif\n#ifndef INT32_MIN\n#define INT32_MIN              (-2147483647-1)\n#endif\n#ifndef INT8_MAX\n#define INT8_MAX               (127)\n#endif\n#ifndef INT16_MAX\n#define INT16_MAX              (32767)\n#endif\n#ifndef INT32_MAX\n#define INT32_MAX              (2147483647)\n#endif\n#ifndef UINT8_MAX\n#define UINT8_MAX              (255U)\n#endif\n#ifndef UINT16_MAX\n#define UINT16_MAX             (65535U)\n#endif\n#ifndef UINT32_MAX\n#define UINT32_MAX             (4294967295U)\n#endif\n\n#endif /* ! FLEXINT_H */\n\n#ifdef __cplusplus\n\n/* The \"const\" storage-class-modifier is valid. */\n#define YY_USE_CONST\n\n#else\t/* ! __cplusplus */\n\n/* C99 requires __STDC__ to be defined as 1. */\n#if defined (__STDC__)\n\n#define YY_USE_CONST\n\n#endif\t/* defined (__STDC__) */\n#endif\t/* ! __cplusplus */\n\n#ifdef YY_USE_CONST\n#define yyconst const\n#else\n#define yyconst\n#endif\n\n/* Returned upon end-of-file. */\n#define YY_NULL 0\n\n/* Promotes a possibly negative, possibly signed char to an unsigned\n * integer for use as an array index.  If the signed char is negative,\n * we want to instead treat it as an 8-bit unsigned char, hence the\n * double cast.\n */\n#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)\n\n/* Enter a start condition.  This macro really ought to take a parameter,\n * but we do it the disgusting crufty way forced on us by the ()-less\n * definition of BEGIN.\n */\n#define BEGIN (yy_start) = 1 + 2 *\n\n/* Translate the current start state into a value that can be later handed\n * to BEGIN to return to the state.  The YYSTATE alias is for lex\n * compatibility.\n */\n#define YY_START (((yy_start) - 1) / 2)\n#define YYSTATE YY_START\n\n/* Action number for EOF rule of a given start state. */\n#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)\n\n/* Special action meaning \"start processing a new file\". */\n#define YY_NEW_FILE cssrestart(cssin  )\n\n#define YY_END_OF_BUFFER_CHAR 0\n\n/* Size of default input buffer. */\n#ifndef YY_BUF_SIZE\n#define YY_BUF_SIZE 16384\n#endif\n\n/* The state buf must be large enough to hold one state per character in the main buffer.\n */\n#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))\n\n#ifndef YY_TYPEDEF_YY_BUFFER_STATE\n#define YY_TYPEDEF_YY_BUFFER_STATE\ntypedef struct yy_buffer_state *YY_BUFFER_STATE;\n#endif\n\n#ifndef YY_TYPEDEF_YY_SIZE_T\n#define YY_TYPEDEF_YY_SIZE_T\ntypedef size_t yy_size_t;\n#endif\n\nextern yy_size_t cssleng;\n\nextern FILE *cssin, *cssout;\n\n#define EOB_ACT_CONTINUE_SCAN 0\n#define EOB_ACT_END_OF_FILE 1\n#define EOB_ACT_LAST_MATCH 2\n\n    #define YY_LESS_LINENO(n)\n    \n/* Return all but the first \"n\" matched characters back to the input stream. */\n#define yyless(n) \\\n\tdo \\\n\t\t{ \\\n\t\t/* Undo effects of setting up csstext. */ \\\n        int yyless_macro_arg = (n); \\\n        YY_LESS_LINENO(yyless_macro_arg);\\\n\t\t*yy_cp = (yy_hold_char); \\\n\t\tYY_RESTORE_YY_MORE_OFFSET \\\n\t\t(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \\\n\t\tYY_DO_BEFORE_ACTION; /* set up csstext again */ \\\n\t\t} \\\n\twhile ( 0 )\n\n#define unput(c) yyunput( c, (yytext_ptr)  )\n\n#ifndef YY_STRUCT_YY_BUFFER_STATE\n#define YY_STRUCT_YY_BUFFER_STATE\nstruct yy_buffer_state\n\t{\n\tFILE *yy_input_file;\n\n\tchar *yy_ch_buf;\t\t/* input buffer */\n\tchar *yy_buf_pos;\t\t/* current position in input buffer */\n\n\t/* Size of input buffer in bytes, not including room for EOB\n\t * characters.\n\t */\n\tyy_size_t yy_buf_size;\n\n\t/* Number of characters read into yy_ch_buf, not including EOB\n\t * characters.\n\t */\n\tyy_size_t yy_n_chars;\n\n\t/* Whether we \"own\" the buffer - i.e., we know we created it,\n\t * and can realloc() it to grow it, and should free() it to\n\t * delete it.\n\t */\n\tint yy_is_our_buffer;\n\n\t/* Whether this is an \"interactive\" input source; if so, and\n\t * if we're using stdio for input, then we want to use getc()\n\t * instead of fread(), to make sure we stop fetching input after\n\t * each newline.\n\t */\n\tint yy_is_interactive;\n\n\t/* Whether we're considered to be at the beginning of a line.\n\t * If so, '^' rules will be active on the next match, otherwise\n\t * not.\n\t */\n\tint yy_at_bol;\n\n    int yy_bs_lineno; /**< The line count. */\n    int yy_bs_column; /**< The column count. */\n    \n\t/* Whether to try to fill the input buffer when we reach the\n\t * end of it.\n\t */\n\tint yy_fill_buffer;\n\n\tint yy_buffer_status;\n\n#define YY_BUFFER_NEW 0\n#define YY_BUFFER_NORMAL 1\n\t/* When an EOF's been seen but there's still some text to process\n\t * then we mark the buffer as YY_EOF_PENDING, to indicate that we\n\t * shouldn't try reading from the input source any more.  We might\n\t * still have a bunch of tokens to match, though, because of\n\t * possible backing-up.\n\t *\n\t * When we actually see the EOF, we change the status to \"new\"\n\t * (via cssrestart()), so that the user can continue scanning by\n\t * just pointing cssin at a new input file.\n\t */\n#define YY_BUFFER_EOF_PENDING 2\n\n\t};\n#endif /* !YY_STRUCT_YY_BUFFER_STATE */\n\n/* Stack of input buffers. */\nstatic size_t yy_buffer_stack_top = 0; /**< index of top of stack. */\nstatic size_t yy_buffer_stack_max = 0; /**< capacity of stack. */\nstatic YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */\n\n/* We provide macros for accessing buffer states in case in the\n * future we want to put the buffer states in a more general\n * \"scanner state\".\n *\n * Returns the top of the stack, or NULL.\n */\n#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \\\n                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \\\n                          : NULL)\n\n/* Same as previous macro, but useful when we know that the buffer stack is not\n * NULL or when we need an lvalue. For internal use only.\n */\n#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]\n\n/* yy_hold_char holds the character lost when csstext is formed. */\nstatic char yy_hold_char;\nstatic yy_size_t yy_n_chars;\t\t/* number of characters read into yy_ch_buf */\nyy_size_t cssleng;\n\n/* Points to current character in buffer. */\nstatic char *yy_c_buf_p = (char *) 0;\nstatic int yy_init = 0;\t\t/* whether we need to initialize */\nstatic int yy_start = 0;\t/* start state number */\n\n/* Flag which is used to allow csswrap()'s to do buffer switches\n * instead of setting up a fresh cssin.  A bit of a hack ...\n */\nstatic int yy_did_buffer_switch_on_eof;\n\nvoid cssrestart (FILE *input_file  );\nvoid css_switch_to_buffer (YY_BUFFER_STATE new_buffer  );\nYY_BUFFER_STATE css_create_buffer (FILE *file,int size  );\nvoid css_delete_buffer (YY_BUFFER_STATE b  );\nvoid css_flush_buffer (YY_BUFFER_STATE b  );\nvoid csspush_buffer_state (YY_BUFFER_STATE new_buffer  );\nvoid csspop_buffer_state (void );\n\nstatic void cssensure_buffer_stack (void );\nstatic void css_load_buffer_state (void );\nstatic void css_init_buffer (YY_BUFFER_STATE b,FILE *file  );\n\n#define YY_FLUSH_BUFFER css_flush_buffer(YY_CURRENT_BUFFER )\n\nYY_BUFFER_STATE css_scan_buffer (char *base,yy_size_t size  );\nYY_BUFFER_STATE css_scan_string (yyconst char *yy_str  );\nYY_BUFFER_STATE css_scan_bytes (yyconst char *bytes,yy_size_t len  );\n\nvoid *cssalloc (yy_size_t  );\nvoid *cssrealloc (void *,yy_size_t  );\nvoid cssfree (void *  );\n\n#define yy_new_buffer css_create_buffer\n\n#define yy_set_interactive(is_interactive) \\\n\t{ \\\n\tif ( ! YY_CURRENT_BUFFER ){ \\\n        cssensure_buffer_stack (); \\\n\t\tYY_CURRENT_BUFFER_LVALUE =    \\\n            css_create_buffer(cssin,YY_BUF_SIZE ); \\\n\t} \\\n\tYY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \\\n\t}\n\n#define yy_set_bol(at_bol) \\\n\t{ \\\n\tif ( ! YY_CURRENT_BUFFER ){\\\n        cssensure_buffer_stack (); \\\n\t\tYY_CURRENT_BUFFER_LVALUE =    \\\n            css_create_buffer(cssin,YY_BUF_SIZE ); \\\n\t} \\\n\tYY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \\\n\t}\n\n#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)\n\n/* Begin user sect3 */\n\ntypedef unsigned char YY_CHAR;\n\nFILE *cssin = (FILE *) 0, *cssout = (FILE *) 0;\n\ntypedef int yy_state_type;\n\nextern int csslineno;\n\nint csslineno = 1;\n\nextern char *csstext;\n#define yytext_ptr csstext\n\nstatic yy_state_type yy_get_previous_state (void );\nstatic yy_state_type yy_try_NUL_trans (yy_state_type current_state  );\nstatic int yy_get_next_buffer (void );\nstatic void yy_fatal_error (yyconst char msg[]  );\n\n/* Done after the current pattern has been matched and before the\n * corresponding action - sets up csstext.\n */\n#define YY_DO_BEFORE_ACTION \\\n\t(yytext_ptr) = yy_bp; \\\n\tcssleng = (yy_size_t) (yy_cp - yy_bp); \\\n\t(yy_hold_char) = *yy_cp; \\\n\t*yy_cp = '\\0'; \\\n\t(yy_c_buf_p) = yy_cp;\n\n#define YY_NUM_RULES 41\n#define YY_END_OF_BUFFER 42\n/* This struct is not used in this scanner,\n   but its presence is necessary. */\nstruct yy_trans_info\n\t{\n\tflex_int32_t yy_verify;\n\tflex_int32_t yy_nxt;\n\t};\nstatic yyconst flex_int16_t yy_accept[370] =\n    {   0,\n        0,    0,   42,   40,    1,    1,   40,   40,   40,   40,\n       40,   40,   40,   34,   40,   40,    8,    8,   40,   40,\n       40,    1,    0,    0,    7,    0,    9,    9,    8,    0,\n        0,    0,    0,    0,   34,    8,    0,    0,   34,    8,\n        0,    0,   33,    0,   32,   32,   32,   32,   32,   32,\n       32,   32,   32,   32,   32,   29,    0,    0,    0,    0,\n        0,    0,    0,    0,   37,    8,    0,    0,    0,    0,\n        8,    8,    8,    6,    5,    0,    0,    0,    7,    0,\n        0,    0,    8,    0,    8,    8,    0,    0,    7,    0,\n        0,    4,    8,    0,    8,    8,    0,    0,   32,    0,\n\n       20,   32,   17,   18,   32,   30,   22,   32,   21,   28,\n       24,   23,   19,   32,   32,   32,    0,    0,    0,    0,\n        0,    0,    0,    0,    8,    0,    0,    8,    0,    8,\n        8,   38,   38,    8,    8,    0,    0,    0,    9,    9,\n        8,    8,    8,    0,    0,    8,    8,    8,    0,    0,\n        2,   32,   32,   25,   32,   31,   26,   32,    3,    0,\n        0,    0,    0,    0,    0,    8,    0,    8,    8,    8,\n        0,    8,    8,    8,    0,   38,   38,   38,   37,    8,\n        0,    0,    9,    8,    8,    0,    8,    8,    0,    0,\n        0,    0,    2,   32,   27,   32,    0,    0,    0,    0,\n\n        0,   11,    8,    8,    8,    8,    8,    8,    8,   39,\n       38,   38,   38,   38,    0,    0,    0,    0,   36,    0,\n        8,    0,    0,    9,    8,    8,    0,    8,    8,    0,\n       32,   32,    0,    0,    0,   12,    0,    8,    8,    8,\n        8,    8,   39,   38,   38,   38,   38,   38,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,   36,    0,    0,\n        8,    0,    0,    9,    8,    8,    0,    8,    8,   32,\n       32,    0,    0,   10,    0,    8,    8,    8,    8,    8,\n       39,   38,   38,   38,   38,   38,   38,    0,   35,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        8,    0,    0,    9,    8,    8,    0,    8,    8,   32,\n       32,   14,    0,    0,    8,    8,    8,    8,    8,   39,\n       38,   38,   38,   38,   38,   38,   38,    0,   35,    0,\n        0,    0,   35,    0,    0,    0,    0,    9,    8,    8,\n       32,    0,    0,    8,    8,    8,    8,   39,    0,    0,\n        0,    0,   13,   15,    8,    8,   39,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,   16,    0\n    } ;\n\nstatic yyconst flex_int32_t yy_ec[256] =\n    {   0,\n        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,\n        1,    4,    5,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    6,    7,    8,    9,   10,   11,   10,   12,   13,\n       14,   15,   16,   10,   17,   18,   19,   20,   20,   20,\n       20,   20,   20,   20,   20,   20,   20,   21,   10,   22,\n       23,   24,   25,   26,   27,   28,   29,   30,   31,   32,\n       33,   34,   35,   36,   37,   38,   39,   40,   41,   42,\n       36,   43,   44,   45,   46,   36,   47,   48,   36,   49,\n       10,   50,   10,   10,   10,   10,   51,   28,   52,   53,\n\n       54,   55,   56,   57,   58,   36,   59,   60,   61,   62,\n       63,   64,   36,   65,   66,   67,   68,   36,   69,   70,\n       36,   71,   72,   73,   74,   75,    1,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76\n    } ;\n\nstatic yyconst flex_int32_t yy_meta[77] =\n    {   0,\n        1,    2,    3,    4,    4,    5,    6,    7,    6,    6,\n        6,    7,    8,    6,    6,    6,    9,   10,    6,   11,\n       12,    6,    6,    6,   13,    6,   14,   14,   14,   14,\n       14,   14,   15,   15,   15,   15,   15,   15,   15,   15,\n       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,\n       14,   14,   14,   14,   14,   15,   15,   15,   15,   15,\n       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,\n       15,    6,    6,    6,    6,   15\n    } ;\n\nstatic yyconst flex_int16_t yy_base[448] =\n    {   0,\n        0,    0,  882, 6624,   75,   80,  803,   79,   71,   77,\n       75,   80,  858,  120,  865,  168,   83,  188,  234,  831,\n      830,  103,   43,   86, 6624,  288,   82,  802,   92,  324,\n       91,  378,  827,  830,    0,  198,  414,   94,   97,  174,\n      450,  834, 6624,  798,  797,   84,   85,  186,  162,  144,\n      178,  164,  207,  230,  233,  796,  486,  828,   86,   83,\n      174,  168,   71,  190, 6624,  224,  222,  226,  522,  819,\n      285,  231,  576, 6624, 6624,  762,  296,  259,  261,  630,\n      684,  720,  284,  756,  307,  810,  298,  221,  282,  864,\n      918, 6624,  308,  954,  309, 1008,  820,  318,  784, 1044,\n\n      783,  314,  782,  779,  322,  777,  776,  313,  774,  773,\n      772,  771,  770,  335,  769, 1098,  801,  228,  274,  325,\n      338,  332,  336,  344,  397, 1134,  767,  756, 1170,  398,\n     1224,  101,  780,  399, 1278,  339,  262, 1332,  753, 1386,\n      403, 1440, 1494,  310, 1548,  404, 1602, 1656,  787,  380,\n     6624,  750, 1710,  744,  373,  743,  740, 1764, 6624,  370,\n      369,  396,  369,  407,  408,  434, 1800,  439, 1854,  732,\n     1890,  682, 1944, 1980,    0,  233,  705,  675,  517, 2034,\n      411, 2088, 2142, 2178, 2232, 2286, 2322, 2358,  683,  381,\n      638,  456,  636, 2394, 2448, 2502,  407,  630,  420,  280,\n\n      420, 6624,  474, 2556, 2610,  591, 2664, 2718, 2754,    0,\n      296,  612,  567,  511,  640,  691,  316,  390, 6624, 2808,\n     2862,  432, 2916, 2970, 3024, 3078, 3132, 3186, 3240,  468,\n     3276, 3312,  445,  456,  445, 6624,  466, 3348, 3384, 3420,\n     3456, 3492,    0,  509,  472,  468,  466,  376,  541,  448,\n      554, 3546,  482, 3600,  704,  717,  754,  775, 3654, 3708,\n     3762,  507, 3816, 3870, 3924, 3978, 4032, 4086, 4140, 4194,\n     4248,  516,  482, 6624,  535, 4284, 4320, 4356, 4392, 4428,\n        0,  510,  325,  270,  252,  177,  103,  596, 6624,  561,\n      450,  875, 4482, 4536,  516,  606,  929, 4590, 4644, 4698,\n\n     4734,  520,  617, 4788, 4842,  853,  667, 4896,  906, 4932,\n     4986, 6624,  536,  543, 5040, 5094, 5130, 5166,  610,    0,\n      102, 6624, 6624, 6624, 6624, 6624, 6624,  949,  616,  641,\n     5202, 1018,  652,  741, 5238, 5292,  526, 5328,  998, 1087,\n      672,  586,  670, 5364, 5400, 5436, 5472,    0, 5508, 5544,\n     5580,  612, 6624, 6624,  723,  759, 6624, 5616, 5652, 5688,\n      693, 5724, 5760, 1107,  725,  793, 1082, 6624, 6624, 5814,\n     5821, 5835, 5842, 5849, 5857, 5868, 5882, 5889, 5896, 5907,\n     5921, 5928, 5939, 5954,  372, 5961, 5972, 5979, 5986, 5997,\n     6002, 6012, 6023, 6034, 6049, 6060, 6067, 6078,  576, 6085,\n\n     6096, 6103, 6116, 6123, 6137, 6152, 6167, 6178, 6189,  496,\n     6196, 6209, 6223, 6237, 6252, 6267,  573, 6274, 6287, 6301,\n     6315, 6329, 6343, 6357, 6371, 6385, 6399, 6414,  654, 6421,\n     6434, 6448, 6462, 6476, 6490, 6504, 6518, 6532, 6546,  731,\n     6553, 6566, 6580, 6594, 6608,  732,  755\n    } ;\n\nstatic yyconst flex_int16_t yy_def[448] =\n    {   0,\n      369,    1,  369,  369,  369,  369,  369,  370,  371,  372,\n      373,  374,  369,  369,  369,  369,  375,  375,  376,  369,\n      369,  369,  369,  370,  369,  377,  371,  378,  379,  380,\n      372,  381,  369,  369,   14,  375,  376,  374,   14,  382,\n      383,  384,  369,  385,  386,  386,  386,  386,  386,  386,\n      386,  386,  386,  386,  386,  386,  387,  369,  369,  369,\n      369,  369,  369,  369,  369,  375,  388,  389,  390,  391,\n      375,  375,  375,  369,  369,  369,  370,  370,  370,  370,\n      377,  392,  379,  393,  379,  379,  372,  372,  372,  372,\n      381,  369,  382,  394,  382,  382,  384,  395,  386,  396,\n\n      386,  386,  386,  386,  386,  386,  386,  386,  386,  386,\n      386,  386,  386,  386,  386,  386,  369,  369,  369,  369,\n      369,  369,  369,  388,  397,  398,  399,  400,  401,  375,\n      375,  402,  369,  375,  131,  369,  403,  403,  404,  404,\n      379,  379,  142,  405,  405,  382,   96,  147,  406,  407,\n      369,  386,  116,  386,  386,  386,  386,  153,  369,  369,\n      369,  369,  369,  369,  369,  397,  408,  397,  397,  400,\n      409,  400,  400,  131,  410,  411,  369,  369,  412,  131,\n      369,  413,  414,  142,  142,  405,  147,  148,  406,  415,\n      406,  416,  406,  153,  153,  153,  369,  369,  369,  369,\n\n      369,  369,  397,  397,  204,  400,  400,  207,  131,  417,\n      418,  369,  369,  369,  419,  419,  420,  421,  369,  422,\n      131,  369,  423,  424,  425,  425,  426,  427,  427,  428,\n      153,  196,  369,  369,  369,  369,  369,  204,  205,  207,\n      208,  131,  429,  430,  369,  369,  369,  369,  369,  420,\n      369,  431,  421,  432,  433,  433,  433,  433,  433,  434,\n      131,  369,  435,  436,  437,  437,  438,  439,  439,  232,\n      270,  369,  369,  369,  369,  204,  239,  207,  241,  131,\n      440,  441,  369,  369,  369,  369,  369,  369,  369,  420,\n      420,  420,  420,  442,  443,  443,  443,  443,  444,  445,\n\n      261,  369,  435,  436,  266,  437,  438,  269,  439,  270,\n      270,  369,  369,  369,  277,  315,  207,  279,  301,  446,\n      369,  369,  369,  369,  369,  369,  369,  420,  420,  420,\n      293,  443,  443,  443,  298,  445,  369,  304,  437,  439,\n      311,  369,  369,  315,  316,  317,  318,  447,  293,  298,\n      336,  369,  369,  369,  345,  347,  369,  293,  298,  336,\n      369,  293,  298,  445,  369,  420,  443,  369,    0,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369\n    } ;\n\nstatic yyconst flex_int16_t yy_nxt[6701] =\n    {   0,\n        4,    5,    6,    5,    5,    5,    7,    8,    9,    4,\n        4,   10,    4,    4,    4,    4,   11,   12,   13,   14,\n        4,   15,    4,    4,    4,   16,   17,   17,   17,   17,\n       17,   17,   17,   17,   17,   17,   17,   17,   17,   17,\n       17,   17,   17,   17,   17,   18,   17,   17,   17,   19,\n       17,   17,   17,   17,   17,   17,   17,   17,   17,   17,\n       17,   17,   17,   17,   17,   17,   17,   18,   17,   17,\n       17,    4,   20,    4,   21,   17,   22,   22,   22,   22,\n       22,   22,   22,   22,   22,   22,   25,   27,   25,   76,\n       28,   33,   34,   25,   35,   65,   38,  122,   28,   39,\n\n       67,   28,   25,   68,   22,   22,   22,   22,   22,   67,\n      369,   76,   68,  369,  369,  102,   39,  175,  175,  118,\n       30,  122,  101,  119,   37,  177,   32,  327,   26,   41,\n       43,   30,   69,  100,  100,   26,   44,   34,  102,   35,\n       32,   84,  118,   41,  101,  119,   45,   45,   46,   47,\n       48,   45,   49,   50,   51,   45,   52,   45,   53,   45,\n       45,   54,   55,   56,   45,   45,   45,   45,   45,   57,\n       45,   46,   47,   48,   45,   49,   50,   51,   52,   45,\n       53,   45,   45,   54,   55,   56,   45,   45,   45,   45,\n       45,   67,  106,  100,   68,   45,   59,  108,  121,   60,\n\n       65,  326,   61,   70,  105,   67,   62,   63,   68,   64,\n       65,  100,  120,  100,  106,   67,  123,  107,   68,   59,\n      108,  121,   60,   94,  103,   61,  105,  100,   62,   63,\n       71,   64,   25,  104,  120,  100,   65,   69,  124,  107,\n      123,   67,  127,   65,   68,  109,  103,   69,   67,  175,\n      110,   68,   71,   73,  160,  104,  100,  212,  111,  114,\n       73,   73,   73,   73,   73,   73,   25,  109,   25,   25,\n       32,  126,  110,   69,  112,  129,  325,  113,  160,  100,\n       69,  111,  100,  114,   73,   73,   73,   73,   73,   24,\n       24,   24,   77,   25,  324,   79,  112,   65,   24,  113,\n\n       31,   67,   67,   25,   68,   68,  236,   80,   26,   25,\n       26,   26,  175,  161,   80,   80,   80,   80,   80,   80,\n      245,   25,  134,  251,   67,   67,   67,   68,   68,   68,\n      236,   32,  150,   84,   69,  161,  151,   81,   80,   80,\n       80,   80,   80,   86,  134,   26,  154,   32,  155,  323,\n       86,   86,   86,   86,   86,   86,   84,   94,   94,   32,\n      369,  156,  100,  100,  157,  252,  162,  163,  165,  154,\n      164,  100,  155,  181,   86,   86,   86,   86,   86,   31,\n       31,   31,   87,  156,  100,   45,   45,  157,  162,   89,\n      163,  165,  164,  126,  192,  230,  181,   90,  193,  151,\n\n      287,  251,  195,  200,   90,   90,   90,   90,   90,   90,\n       65,  179,  197,  198,   67,   67,   67,   68,   68,   68,\n       67,   67,  100,   68,   68,  195,  200,   91,   90,   90,\n       90,   90,   90,   73,  197,  198,  199,  201,  202,  254,\n       73,   73,   73,   73,   73,   73,  167,   69,   69,  222,\n      233,   67,   84,   94,   68,  251,   67,  251,  199,   68,\n      201,  202,  235,  237,   73,   73,   73,   73,   73,   96,\n      192,  222,  233,  262,  193,  272,   96,   96,   96,   96,\n       96,   96,  230,  167,  235,  237,  193,  273,  167,  274,\n      286,   67,  285,  251,   68,  262,  284,  252,  272,  252,\n\n       96,   96,   96,   96,   96,  116,  210,  275,  313,  210,\n      273,  274,  116,  116,  116,  116,  116,  116,  215,  215,\n      215,  215,  215,  167,  217,  175,  175,  251,  218,  275,\n      219,  254,  313,  283,  322,  248,  116,  116,  116,  116,\n      116,  131,  249,  249,  249,  249,  249,  302,  131,  131,\n      131,  131,  131,  131,  219,  288,  288,  288,  288,  288,\n      312,  314,  337,  250,  342,  254,  220,  289,  251,  302,\n      352,  343,  131,  131,  131,  131,  131,   72,   72,   72,\n       72,   72,  312,  243,  337,  314,  243,  342,   65,  128,\n      128,  247,  352,   67,  343,  135,   68,  288,  288,  288,\n\n      288,  288,  135,  135,  135,  135,  135,  135,  369,  289,\n      252,  130,  130,  130,  130,  130,  353,  251,   78,  137,\n      137,  137,   78,  251,   25,   69,  135,  135,  135,  135,\n      135,   78,  137,  137,  137,   78,  246,   25,  361,  353,\n      171,  215,  215,  215,  215,  215,  234,  217,  251,  138,\n      190,  218,  190,  219,  369,  254,  138,  138,  138,  138,\n      138,  138,  361,  251,  281,  252,   26,  281,   88,  144,\n      144,  144,   88,  152,  152,  152,  152,  152,   25,   26,\n      138,  138,  138,  138,  138,   24,   24,   24,   77,  220,\n      252,   79,  249,  249,  249,  249,  249,  190,  369,  214,\n\n      354,  254,  369,   80,  219,  249,  249,  249,  249,  249,\n       80,   80,   80,   80,   80,   80,   32,  219,  249,  249,\n      249,  249,  249,  354,  203,  203,  203,  203,  203,  213,\n      219,  171,  365,   81,   80,   80,   80,   80,   80,  140,\n      220,  320,  348,  369,  320,  348,  140,  140,  140,  140,\n      140,  140,  251,  220,  365,  249,  249,  249,  249,  249,\n      206,  206,  206,  206,  206,  357,  220,  219,  357,  368,\n      140,  140,  140,  140,  140,  142,  249,  249,  249,  249,\n      249,  171,  142,  142,  142,  142,  142,  142,  219,  100,\n      254,  368,  100,  100,  291,  330,  330,  330,  291,  100,\n\n      251,  190,   82,  220,  178,  171,  142,  142,  142,  142,\n      142,   85,   85,   85,   85,   85,  129,  159,  100,  100,\n      100,  100,  100,  100,  220,  100,  100,   67,  100,  143,\n       68,  100,  100,  100,   98,  136,  143,  143,  143,  143,\n      143,  143,  252,  133,  117,  100,  100,   57,   98,   39,\n       92,   82,   75,   74,   85,   85,   85,   85,   85,   84,\n      143,  143,  143,  143,  143,   88,  144,  144,  144,   88,\n       67,   58,   42,   68,   23,   25,  328,  288,  288,  288,\n      328,  369,  251,  145,  369,  369,  369,  369,  329,  369,\n      145,  145,  145,  145,  145,  145,  369,  369,  369,  369,\n\n      369,  369,   84,  369,  369,  369,  369,   95,   95,   95,\n       95,   95,  369,   32,  145,  145,  145,  145,  145,   31,\n       31,   31,   87,   67,  252,  369,   68,  369,  369,   89,\n      332,  288,  288,  288,  332,  369,  369,   90,  369,  369,\n      251,  369,  333,  369,   90,   90,   90,   90,   90,   90,\n      328,  288,  288,  288,  328,   94,  251,  369,  369,  369,\n      369,  369,  329,  369,  369,  369,  369,   91,   90,   90,\n       90,   90,   90,  147,  369,  369,  369,  369,  254,  369,\n      147,  147,  147,  147,  147,  147,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  252,  141,\n\n      141,  141,  141,  141,  147,  147,  147,  147,  147,   95,\n       95,   95,   95,   95,  369,   67,  369,  369,   68,  332,\n      288,  288,  288,  332,  369,   67,  369,  148,   68,  251,\n      369,  333,  369,  369,  148,  148,  148,  148,  148,  148,\n      369,  369,  369,  369,  369,  369,  369,   84,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   94,  148,  148,\n      148,  148,  148,  153,  369,  369,  369,  254,  369,  369,\n      153,  153,  153,  153,  153,  153,  369,  369,  369,  369,\n      369,  369,  369,  296,  334,  334,  334,  296,  146,  146,\n      146,  146,  146,  251,  153,  153,  153,  153,  153,  115,\n\n      115,  115,  115,  115,   67,  369,  369,   68,  255,  255,\n      255,  255,  255,  369,  369,  369,  369,  158,  369,  369,\n      219,  369,  369,  369,  158,  158,  158,  158,  158,  158,\n      369,  254,  369,  369,  369,  369,   94,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  100,  158,  158,\n      158,  158,  158,  169,  369,  369,  220,  369,  369,  369,\n      169,  169,  169,  169,  169,  169,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  169,  169,  169,  169,  169,  173,\n      369,  369,  369,  369,  369,  369,  173,  173,  173,  173,\n\n      173,  173,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      173,  173,  173,  173,  173,  130,  130,  130,  130,  130,\n      369,  369,  369,  369,  369,  369,   65,  369,  369,  369,\n      369,   67,  369,  174,   68,  369,  369,  369,  369,  369,\n      174,  174,  174,  174,  174,  174,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,   69,  174,  174,  174,  174,  174,   72,\n       72,   72,   72,   72,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  180,  369,  369,\n\n      369,  369,  369,  369,  180,  180,  180,  180,  180,  180,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  180,  180,\n      180,  180,  180,   78,  137,  137,  137,   78,  369,   25,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  182,  369,  369,  369,  369,  369,  369,  182,  182,\n      182,  182,  182,  182,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,   26,  182,  182,  182,  182,  182,  139,  139,  139,\n      139,  139,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  183,  369,  369,  369,  369,\n      369,  369,  183,  183,  183,  183,  183,  183,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,   82,  183,  183,  183,  183,\n      183,  141,  141,  141,  141,  141,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   67,  369,  184,\n       68,  369,  369,  369,  369,  369,  184,  184,  184,  184,\n      184,  184,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,   84,\n      184,  184,  184,  184,  184,   85,   85,   85,   85,   85,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  185,  369,  369,  369,  369,  369,  369,\n      185,  185,  185,  185,  185,  185,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  185,  185,  185,  185,  185,   88,\n      144,  144,  144,   88,  369,  369,  369,  369,  369,   25,\n      369,  369,  369,  369,  369,  369,  369,  186,  369,  369,\n      369,  369,  369,  369,  186,  186,  186,  186,  186,  186,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   32,  186,  186,\n\n      186,  186,  186,  146,  146,  146,  146,  146,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  187,  369,  369,  369,  369,  369,  369,  187,  187,\n      187,  187,  187,  187,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  187,  187,  187,  187,  187,   95,   95,   95,\n       95,   95,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  188,  369,  369,  369,  369,\n      369,  369,  188,  188,  188,  188,  188,  188,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  188,  188,  188,  188,\n      188,  152,  152,  152,  152,  152,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  194,\n      369,  369,  369,  369,  369,  369,  194,  194,  194,  194,\n      194,  194,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      194,  194,  194,  194,  194,  115,  115,  115,  115,  115,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  196,  369,  369,  369,  369,  369,  369,\n      196,  196,  196,  196,  196,  196,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  196,  196,  196,  196,  196,  204,\n      369,  369,  369,  369,  369,  369,  204,  204,  204,  204,\n      204,  204,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      204,  204,  204,  204,  204,  168,  168,  168,  168,  168,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,   67,  369,  205,   68,  369,  369,  369,  369,  369,\n      205,  205,  205,  205,  205,  205,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  167,  205,  205,  205,  205,  205,  207,\n      369,  369,  369,  369,  369,  369,  207,  207,  207,  207,\n      207,  207,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      207,  207,  207,  207,  207,  172,  172,  172,  172,  172,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  208,  369,  369,  369,  369,  369,  369,\n      208,  208,  208,  208,  208,  208,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  171,  208,  208,  208,  208,  208,  209,\n\n      369,  369,  369,  369,  369,  369,  209,  209,  209,  209,\n      209,  209,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      209,  209,  209,  209,  209,   72,   72,   72,   72,   72,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  221,  369,  369,  369,  369,  369,  369,\n      221,  221,  221,  221,  221,  221,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  221,  221,  221,  221,  221,   78,\n      137,  137,  137,   78,  369,   25,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  223,  369,  369,\n      369,  369,  369,  369,  223,  223,  223,  223,  223,  223,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   26,  223,  223,\n      223,  223,  223,  139,  139,  139,  139,  139,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  224,  369,  369,  369,  369,  369,  369,  224,  224,\n      224,  224,  224,  224,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,   82,  224,  224,  224,  224,  224,  225,  369,  369,\n\n      369,  369,  369,  369,  225,  225,  225,  225,  225,  225,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  225,  225,\n      225,  225,  225,   85,   85,   85,   85,   85,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  226,  369,  369,  369,  369,  369,  369,  226,  226,\n      226,  226,  226,  226,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  226,  226,  226,  226,  226,   88,  144,  144,\n      144,   88,  369,  369,  369,  369,  369,   25,  369,  369,\n\n      369,  369,  369,  369,  369,  227,  369,  369,  369,  369,\n      369,  369,  227,  227,  227,  227,  227,  227,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,   32,  227,  227,  227,  227,\n      227,  228,  369,  369,  369,  369,  369,  369,  228,  228,\n      228,  228,  228,  228,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  228,  228,  228,  228,  228,  229,  369,  369,\n      369,  369,  369,  369,  229,  229,  229,  229,  229,  229,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  229,  229,\n      229,  229,  229,  231,  369,  369,  369,  369,  369,  369,\n      231,  231,  231,  231,  231,  231,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  231,  231,  231,  231,  231,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   99,  369,  369,\n      369,  369,  369,  369,   99,   99,   99,   99,   99,   99,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,   99,   99,\n\n       99,   99,   99,  115,  115,  115,  115,  115,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  232,  369,  369,  369,  369,  369,  369,  232,  232,\n      232,  232,  232,  232,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  232,  232,  232,  232,  232,  203,  203,  203,\n      203,  203,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,   67,  369,  238,   68,  369,  369,  369,\n      369,  369,  238,  238,  238,  238,  238,  238,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  167,  238,  238,  238,  238,\n      238,  168,  168,  168,  168,  168,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  239,\n      369,  369,  369,  369,  369,  369,  239,  239,  239,  239,\n      239,  239,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      239,  239,  239,  239,  239,  206,  206,  206,  206,  206,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  240,  369,  369,  369,  369,  369,  369,\n      240,  240,  240,  240,  240,  240,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  171,  240,  240,  240,  240,  240,  172,\n      172,  172,  172,  172,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  241,  369,  369,\n      369,  369,  369,  369,  241,  241,  241,  241,  241,  241,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  241,  241,\n      241,  241,  241,  242,  369,  369,  369,  369,  369,  369,\n      242,  242,  242,  242,  242,  242,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  242,  242,  242,  242,  242,  249,\n      249,  249,  249,  255,  369,  257,  369,  369,  369,  257,\n      257,  258,  369,  369,  369,  369,  369,  259,  369,  369,\n      369,  369,  369,  369,  259,  259,  259,  259,  259,  259,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  260,  259,  259,\n      259,  259,  259,   72,   72,   72,   72,   72,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  261,  369,  369,  369,  369,  369,  369,  261,  261,\n      261,  261,  261,  261,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  261,  261,  261,  261,  261,   78,  137,  137,\n      137,   78,  369,   25,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  263,  369,  369,  369,  369,\n      369,  369,  263,  263,  263,  263,  263,  263,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,   26,  263,  263,  263,  263,\n      263,  139,  139,  139,  139,  139,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  264,\n      369,  369,  369,  369,  369,  369,  264,  264,  264,  264,\n\n      264,  264,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,   82,\n      264,  264,  264,  264,  264,  141,  141,  141,  141,  141,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,   67,  369,  265,   68,  369,  369,  369,  369,  369,\n      265,  265,  265,  265,  265,  265,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,   84,  265,  265,  265,  265,  265,   85,\n       85,   85,   85,   85,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,   67,  369,  266,   68,  369,\n\n      369,  369,  369,  369,  266,  266,  266,  266,  266,  266,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   84,  266,  266,\n      266,  266,  266,   88,  144,  144,  144,   88,  369,  369,\n      369,  369,  369,   25,  369,  369,  369,  369,  369,  369,\n      369,  267,  369,  369,  369,  369,  369,  369,  267,  267,\n      267,  267,  267,  267,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,   32,  267,  267,  267,  267,  267,  146,  146,  146,\n      146,  146,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,   67,  369,  268,   68,  369,  369,  369,\n      369,  369,  268,  268,  268,  268,  268,  268,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,   94,  268,  268,  268,  268,\n      268,   95,   95,   95,   95,   95,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   67,  369,  269,\n       68,  369,  369,  369,  369,  369,  269,  269,  269,  269,\n      269,  269,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,   94,\n      269,  269,  269,  269,  269,  270,  369,  369,  369,  369,\n\n      369,  369,  270,  270,  270,  270,  270,  270,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  270,  270,  270,  270,\n      270,  271,  369,  369,  369,  369,  369,  369,  271,  271,\n      271,  271,  271,  271,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  271,  271,  271,  271,  271,  276,  369,  369,\n      369,  369,  369,  369,  276,  276,  276,  276,  276,  276,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  276,  276,\n\n      276,  276,  276,  277,  369,  369,  369,  369,  369,  369,\n      277,  277,  277,  277,  277,  277,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  277,  277,  277,  277,  277,  278,\n      369,  369,  369,  369,  369,  369,  278,  278,  278,  278,\n      278,  278,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      278,  278,  278,  278,  278,  279,  369,  369,  369,  369,\n      369,  369,  279,  279,  279,  279,  279,  279,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  279,  279,  279,  279,\n      279,  280,  369,  369,  369,  369,  369,  369,  280,  280,\n      280,  280,  280,  280,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  280,  280,  280,  280,  280,  250,  250,  250,\n      290,  369,  369,  292,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  293,  369,  369,  369,  369,\n      369,  369,  293,  293,  293,  293,  293,  293,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  294,  293,  293,  293,  293,\n\n      293,  253,  253,  253,  295,  369,  369,  369,  369,  369,\n      369,  297,  369,  369,  369,  369,  369,  369,  369,  298,\n      369,  369,  369,  369,  369,  369,  298,  298,  298,  298,\n      298,  298,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  299,\n      298,  298,  298,  298,  298,  255,  255,  255,  255,  255,\n      369,  369,  369,  369,  369,  369,  369,  219,  369,  369,\n      369,  369,  369,  300,  369,  369,  369,  369,  369,  369,\n      300,  300,  300,  300,  300,  300,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  220,  300,  300,  300,  300,  300,  249,\n      249,  249,  249,  255,  369,  257,  369,  369,  369,  257,\n      257,  258,  369,  369,  369,  369,  369,  259,  369,  369,\n      369,  369,  369,  369,  259,  259,  259,  259,  259,  259,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  260,  259,  259,\n      259,  259,  259,   72,   72,   72,   72,   72,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  301,  369,  369,  369,  369,  369,  369,  301,  301,\n      301,  301,  301,  301,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  301,  301,  301,  301,  301,   78,  137,  137,\n      137,   78,  369,   25,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  303,  369,  369,  369,  369,\n      369,  369,  303,  303,  303,  303,  303,  303,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,   26,  303,  303,  303,  303,\n      303,  139,  139,  139,  139,  139,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  304,\n      369,  369,  369,  369,  369,  369,  304,  304,  304,  304,\n\n      304,  304,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,   82,\n      304,  304,  304,  304,  304,  141,  141,  141,  141,  141,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,   67,  369,  305,   68,  369,  369,  369,  369,  369,\n      305,  305,  305,  305,  305,  305,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,   84,  305,  305,  305,  305,  305,   85,\n       85,   85,   85,   85,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,   67,  369,  306,   68,  369,\n\n      369,  369,  369,  369,  306,  306,  306,  306,  306,  306,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   84,  306,  306,\n      306,  306,  306,   88,  144,  144,  144,   88,  369,  369,\n      369,  369,  369,   25,  369,  369,  369,  369,  369,  369,\n      369,  307,  369,  369,  369,  369,  369,  369,  307,  307,\n      307,  307,  307,  307,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,   32,  307,  307,  307,  307,  307,  146,  146,  146,\n      146,  146,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,   67,  369,  308,   68,  369,  369,  369,\n      369,  369,  308,  308,  308,  308,  308,  308,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,   94,  308,  308,  308,  308,\n      308,   95,   95,   95,   95,   95,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   67,  369,  309,\n       68,  369,  369,  369,  369,  369,  309,  309,  309,  309,\n      309,  309,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,   94,\n      309,  309,  309,  309,  309,  152,  152,  152,  152,  152,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  310,  369,  369,  369,  369,  369,  369,\n      310,  310,  310,  310,  310,  310,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  310,  310,  310,  310,  310,  115,\n      115,  115,  115,  115,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  311,  369,  369,\n      369,  369,  369,  369,  311,  311,  311,  311,  311,  311,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  311,  311,\n\n      311,  311,  311,  315,  369,  369,  369,  369,  369,  369,\n      315,  315,  315,  315,  315,  315,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  315,  315,  315,  315,  315,  316,\n      369,  369,  369,  369,  369,  369,  316,  316,  316,  316,\n      316,  316,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      316,  316,  316,  316,  316,  317,  369,  369,  369,  369,\n      369,  369,  317,  317,  317,  317,  317,  317,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  317,  317,  317,  317,\n      317,  318,  369,  369,  369,  369,  369,  369,  318,  318,\n      318,  318,  318,  318,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  318,  318,  318,  318,  318,  319,  369,  369,\n      369,  369,  369,  369,  319,  319,  319,  319,  319,  319,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  319,  319,\n      319,  319,  319,  291,  330,  330,  330,  291,  369,  251,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  331,  369,  369,  369,  369,  369,  369,  331,  331,\n      331,  331,  331,  331,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  252,  331,  331,  331,  331,  331,  250,  250,  250,\n      290,  369,  369,  292,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  293,  369,  369,  369,  369,\n      369,  369,  293,  293,  293,  293,  293,  293,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  294,  293,  293,  293,  293,\n      293,  296,  334,  334,  334,  296,  369,  369,  369,  369,\n\n      369,  251,  369,  369,  369,  369,  369,  369,  369,  335,\n      369,  369,  369,  369,  369,  369,  335,  335,  335,  335,\n      335,  335,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  254,\n      335,  335,  335,  335,  335,  253,  253,  253,  295,  369,\n      369,  369,  369,  369,  369,  297,  369,  369,  369,  369,\n      369,  369,  369,  298,  369,  369,  369,  369,  369,  369,\n      298,  298,  298,  298,  298,  298,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  299,  298,  298,  298,  298,  298,  255,\n\n      255,  255,  255,  255,  369,  369,  369,  369,  369,  369,\n      369,  219,  369,  369,  369,  369,  369,  336,  369,  369,\n      369,  369,  369,  369,  336,  336,  336,  336,  336,  336,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  220,  336,  336,\n      336,  336,  336,   66,  369,  369,  369,  369,  369,  369,\n       66,   66,   66,   66,   66,   66,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,   66,   66,   66,   66,   66,  139,\n      139,  139,  139,  139,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  338,  369,  369,\n      369,  369,  369,  369,  338,  338,  338,  338,  338,  338,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,   82,  338,  338,\n      338,  338,  338,  141,  141,  141,  141,  141,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  339,  369,  369,  369,  369,  369,  369,  339,  339,\n      339,  339,  339,  339,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  339,  339,  339,  339,  339,  146,  146,  146,\n\n      146,  146,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  340,  369,  369,  369,  369,\n      369,  369,  340,  340,  340,  340,  340,  340,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  340,  340,  340,  340,\n      340,  341,  369,  369,  369,  369,  369,  369,  341,  341,\n      341,  341,  341,  341,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  341,  341,  341,  341,  341,  115,  115,  115,\n      115,  115,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,   99,  369,  369,  369,  369,\n      369,  369,   99,   99,   99,   99,   99,   99,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,   99,   99,   99,   99,\n       99,  203,  203,  203,  203,  203,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  344,\n      369,  369,  369,  369,  369,  369,  344,  344,  344,  344,\n      344,  344,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      344,  344,  344,  344,  344,  168,  168,  168,  168,  168,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  345,  369,  369,  369,  369,  369,  369,\n      345,  345,  345,  345,  345,  345,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  345,  345,  345,  345,  345,  346,\n      369,  369,  369,  369,  369,  369,  346,  346,  346,  346,\n      346,  346,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      346,  346,  346,  346,  346,  347,  369,  369,  369,  369,\n      369,  369,  347,  347,  347,  347,  347,  347,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  347,  347,  347,  347,\n      347,  349,  369,  369,  369,  369,  369,  369,  349,  349,\n      349,  349,  349,  349,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  349,  349,  349,  349,  349,  350,  369,  369,\n      369,  369,  369,  369,  350,  350,  350,  350,  350,  350,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  350,  350,\n      350,  350,  350,  255,  255,  255,  255,  255,  369,  369,\n\n      369,  369,  369,  369,  369,  219,  369,  369,  369,  369,\n      369,  351,  369,  369,  369,  369,  369,  369,  351,  351,\n      351,  351,  351,  351,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  220,  351,  351,  351,  351,  351,   28,  369,  369,\n      369,  369,  369,  369,   28,   28,   28,   28,   28,   28,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,   28,   28,\n       28,   28,   28,  355,  369,  369,  369,  369,  369,  369,\n      355,  355,  355,  355,  355,  355,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  355,  355,  355,  355,  355,  166,\n      369,  369,  369,  369,  369,  369,  166,  166,  166,  166,\n      166,  166,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      166,  166,  166,  166,  166,  356,  369,  369,  369,  369,\n      369,  369,  356,  356,  356,  356,  356,  356,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  356,  356,  356,  356,\n      356,  170,  369,  369,  369,  369,  369,  369,  170,  170,\n\n      170,  170,  170,  170,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  170,  170,  170,  170,  170,  358,  369,  369,\n      369,  369,  369,  369,  358,  358,  358,  358,  358,  358,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  358,  358,\n      358,  358,  358,  359,  369,  369,  369,  369,  369,  369,\n      359,  359,  359,  359,  359,  359,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  359,  359,  359,  359,  359,  360,\n\n      369,  369,  369,  369,  369,  369,  360,  360,  360,  360,\n      360,  360,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      360,  360,  360,  360,  360,  362,  369,  369,  369,  369,\n      369,  369,  362,  362,  362,  362,  362,  362,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  362,  362,  362,  362,\n      362,  363,  369,  369,  369,  369,  369,  369,  363,  363,\n      363,  363,  363,  363,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  363,  363,  363,  363,  363,  364,  369,  369,\n      369,  369,  369,  369,  364,  364,  364,  364,  364,  364,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  364,  364,\n      364,  364,  364,  366,  369,  369,  369,  369,  369,  369,\n      366,  366,  366,  366,  366,  366,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  366,  366,  366,  366,  366,  367,\n      369,  369,  369,  369,  369,  369,  367,  367,  367,  367,\n      367,  367,  369,  369,  369,  369,  369,  369,  369,  369,\n\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      367,  367,  367,  367,  367,   24,  369,  369,   24,   24,\n       24,   24,   24,   24,   24,   24,   24,   24,   24,   29,\n      369,   29,  369,  369,   29,   29,   31,  369,  369,   31,\n       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,\n       36,   36,   36,  369,  369,   36,   36,   40,  369,   40,\n      369,  369,   40,   40,   66,   66,   66,   66,   66,  369,\n       66,   66,   72,   72,   72,   72,   72,   72,   72,   72,\n       72,   72,   72,   78,   78,   78,   78,   78,   78,   78,\n       78,   78,   78,   78,   78,   78,   78,   28,  369,   28,\n\n      369,  369,   28,   28,   83,   83,   83,   83,  369,   83,\n       83,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   88,   88,   88,   88,   88,   88,   88,   88,\n       88,   88,   88,   88,   88,   88,   93,   93,   93,   93,\n      369,   93,   93,   95,   95,   95,   95,   95,   95,   95,\n       95,   95,   95,   95,   97,   97,   97,   97,   97,   97,\n       97,   97,   97,   97,   97,   97,   97,   97,   97,   99,\n      369,   99,  369,  369,   99,   99,  115,  115,  115,  115,\n      115,  115,  115,  115,  115,  115,  115,  125,  369,  369,\n      369,  369,  125,  125,  128,  369,  369,  369,  369,  128,\n\n      128,  130,  130,  130,  130,  130,  130,  130,  130,  130,\n      130,  130,  132,  369,  132,  132,  139,  139,  139,  139,\n      139,  139,  139,  139,  139,  139,  139,  141,  141,  141,\n      141,  141,  141,  141,  141,  141,  141,  141,  146,  146,\n      146,  146,  146,  146,  146,  146,  146,  146,  146,  149,\n      149,  149,  149,  149,  149,  149,  149,  149,  149,  149,\n      149,  149,  149,  149,  152,  152,  152,  152,  152,  152,\n      152,  152,  152,  152,  152,  166,  166,  166,  166,  369,\n      166,  166,  168,  168,  168,  168,  168,  168,  168,  168,\n      168,  168,  168,  170,  369,  170,  369,  369,  170,  170,\n\n      172,  172,  172,  172,  172,  172,  172,  172,  172,  172,\n      172,  176,  369,  176,  369,  176,  176,   24,  369,  369,\n       24,   24,   24,   24,   24,   24,   24,   24,   24,   24,\n       24,   28,  369,   28,  369,  369,   28,   28,   31,  369,\n      369,   31,   31,   31,   31,   31,   31,   31,   31,   31,\n       31,   31,  189,  189,  189,  189,  189,  189,  189,  189,\n      189,  189,  189,  189,  189,  189,  189,  191,  191,  191,\n      191,  191,  191,  191,  191,  191,  191,  191,  191,  191,\n      191,  191,  203,  203,  203,  203,  203,  203,  203,  203,\n      203,  203,  203,  206,  206,  206,  206,  206,  206,  206,\n\n      206,  206,  206,  206,  211,  369,  211,  369,  211,  211,\n      216,  216,  216,  216,  216,  216,  369,  216,  216,  216,\n      216,  216,  216,  216,   24,   24,   24,   24,   24,   24,\n       24,   24,   24,   24,   24,   24,   24,   24,   28,   28,\n       28,   28,  369,  369,  369,   28,  369,   28,  369,  369,\n       28,   28,  149,  149,  149,  149,  149,  149,  149,  149,\n      149,  149,  149,  149,  149,  149,  149,  191,  191,  191,\n      191,  191,  191,  191,  191,  191,  191,  191,  191,  191,\n      191,  191,  244,  369,  244,  369,  244,  244,  216,  216,\n      216,  216,  216,  216,  369,  216,  216,  216,  216,  216,\n\n      216,  216,  250,  369,  369,  250,  250,  250,  250,  250,\n      250,  250,  250,  250,  250,  250,  253,  369,  369,  253,\n      253,  253,  253,  253,  253,  253,  253,  253,  253,  253,\n      256,  256,  256,  256,  256,  256,  256,  256,  256,  256,\n      256,  256,  256,  256,   24,   24,   24,   24,   24,   24,\n       24,   24,   24,   24,   24,   24,   24,   24,   28,   28,\n       28,   28,  369,  369,  369,   28,  369,   28,  369,  369,\n       28,   28,   83,   83,   83,   83,  369,  369,  369,   83,\n       83,   83,   83,  369,   83,   83,   31,   31,   31,   31,\n       31,   31,   31,   31,   31,   31,   31,   31,   31,   31,\n\n       93,   93,   93,   93,  369,  369,  369,   93,   93,   93,\n       93,  369,   93,   93,  191,  191,  191,  191,  191,  191,\n      191,  191,  191,  191,  191,  191,  191,  191,  191,  282,\n      369,  282,  369,  282,  282,  291,  291,  291,  291,  291,\n      291,  291,  291,  291,  291,  291,  291,  291,  291,  296,\n      296,  296,  296,  296,  296,  296,  296,  296,  296,  296,\n      296,  296,  296,  216,  216,  216,  216,  216,  369,  369,\n      216,  216,  216,  216,  216,  216,  216,  256,  256,  256,\n      256,  256,  256,  256,  256,  256,  256,  256,  256,  256,\n      256,   24,   24,   24,   24,   24,   24,   24,   24,   24,\n\n       24,   24,   24,   24,   24,   28,   28,   28,   28,  369,\n      369,  369,   28,  369,   28,  369,  369,   28,   28,   83,\n       83,   83,   83,  369,  369,  369,   83,   83,   83,   83,\n      369,   83,   83,   31,   31,   31,   31,   31,   31,   31,\n       31,   31,   31,   31,   31,   31,   31,   93,   93,   93,\n       93,  369,  369,  369,   93,   93,   93,   93,  369,   93,\n       93,  321,  369,  321,  369,  321,  321,  291,  291,  291,\n      291,  291,  291,  291,  291,  291,  291,  291,  291,  291,\n      291,  253,  253,  369,  253,  253,  253,  253,  253,  253,\n      253,  253,  253,  253,  253,  296,  296,  296,  296,  296,\n\n      296,  296,  296,  296,  296,  296,  296,  296,  296,  216,\n      216,  216,  216,  216,  369,  369,  216,  216,  216,  216,\n      216,  216,  216,    3,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369\n\n    } ;\n\nstatic yyconst flex_int16_t yy_chk[6701] =\n    {   0,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    5,    5,    5,    5,\n        5,    6,    6,    6,    6,    6,    8,    9,   10,   23,\n        9,   11,   11,   24,   11,   17,   12,   63,   27,   12,\n\n       17,   27,   31,   17,   22,   22,   22,   22,   22,   29,\n       38,   23,   29,   38,   39,   47,   39,  132,  321,   59,\n        9,   63,   46,   60,   11,  132,   10,  287,    8,   12,\n       14,   27,   17,   46,   47,   24,   14,   14,   47,   14,\n       31,   29,   59,   38,   46,   60,   14,   14,   14,   14,\n       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,\n       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,\n       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,\n       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,\n       14,   40,   50,   50,   40,   14,   16,   52,   62,   16,\n\n       18,  286,   16,   18,   49,   18,   16,   16,   18,   16,\n       36,   49,   61,   52,   50,   36,   64,   51,   36,   16,\n       52,   62,   16,   40,   48,   16,   49,   51,   16,   16,\n       18,   16,   88,   48,   61,   48,   66,   18,   67,   51,\n       64,   66,   68,   72,   66,   53,   48,   36,   72,  176,\n       53,   72,   18,   19,  118,   48,   53,  176,   54,   55,\n       19,   19,   19,   19,   19,   19,   78,   53,   79,  137,\n       88,   67,   53,   66,   54,   68,  285,   54,  118,   54,\n       72,   54,   55,   55,   19,   19,   19,   19,   19,   26,\n       26,   26,   26,   89,  284,   26,   54,   71,   77,   54,\n\n       87,   83,   71,   77,   83,   71,  200,   26,   78,   87,\n       79,  137,  211,  119,   26,   26,   26,   26,   26,   26,\n      211,  144,   71,  217,   85,   93,   95,   85,   93,   95,\n      200,   89,   98,   83,   71,  119,   98,   26,   26,   26,\n       26,   26,   26,   30,   71,   77,  102,   87,  105,  283,\n       30,   30,   30,   30,   30,   30,   85,   93,   95,  144,\n      124,  108,  108,  102,  114,  217,  120,  121,  123,  102,\n      122,  105,  105,  136,   30,   30,   30,   30,   30,   32,\n       32,   32,   32,  108,  114,  385,  385,  114,  120,   32,\n      121,  123,  122,  124,  150,  190,  136,   32,  150,  190,\n\n      248,  218,  155,  163,   32,   32,   32,   32,   32,   32,\n      130,  134,  160,  161,  125,  130,  134,  125,  130,  134,\n      141,  146,  155,  141,  146,  155,  163,   32,   32,   32,\n       32,   32,   32,   37,  160,  161,  162,  164,  165,  218,\n       37,   37,   37,   37,   37,   37,  125,  130,  134,  181,\n      197,  166,  141,  146,  166,  250,  168,  291,  162,  168,\n      164,  165,  199,  201,   37,   37,   37,   37,   37,   41,\n      192,  181,  197,  222,  192,  233,   41,   41,   41,   41,\n       41,   41,  230,  166,  199,  201,  230,  234,  168,  235,\n      247,  203,  246,  253,  203,  222,  245,  250,  233,  291,\n\n       41,   41,   41,   41,   41,   57,  410,  237,  273,  410,\n      234,  235,   57,   57,   57,   57,   57,   57,  179,  179,\n      179,  179,  179,  203,  179,  244,  282,  295,  179,  237,\n      179,  253,  273,  244,  282,  214,   57,   57,   57,   57,\n       57,   69,  249,  249,  249,  249,  249,  262,   69,   69,\n       69,   69,   69,   69,  249,  251,  251,  251,  251,  251,\n      272,  275,  302,  290,  313,  295,  179,  251,  290,  262,\n      337,  314,   69,   69,   69,   69,   69,   73,   73,   73,\n       73,   73,  272,  417,  302,  275,  417,  313,   73,  399,\n      399,  213,  337,   73,  314,   73,   73,  288,  288,  288,\n\n      288,  288,   73,   73,   73,   73,   73,   73,  296,  288,\n      290,  319,  319,  319,  319,  319,  342,  296,  303,  303,\n      303,  303,  303,  329,  303,   73,   73,   73,   73,   73,\n       73,   80,   80,   80,   80,   80,  212,   80,  352,  342,\n      206,  215,  215,  215,  215,  215,  198,  215,  330,   80,\n      193,  215,  191,  215,  333,  296,   80,   80,   80,   80,\n       80,   80,  352,  333,  429,  329,  303,  429,  307,  307,\n      307,  307,  307,  341,  341,  341,  341,  341,  307,   80,\n       80,   80,   80,   80,   80,   81,   81,   81,   81,  215,\n      330,   81,  216,  216,  216,  216,  216,  189,  216,  178,\n\n      343,  333,  216,   81,  216,  255,  255,  255,  255,  255,\n       81,   81,   81,   81,   81,   81,  307,  255,  256,  256,\n      256,  256,  256,  343,  355,  355,  355,  355,  355,  177,\n      256,  172,  361,   81,   81,   81,   81,   81,   81,   82,\n      216,  440,  446,  334,  440,  446,   82,   82,   82,   82,\n       82,   82,  334,  255,  361,  257,  257,  257,  257,  257,\n      356,  356,  356,  356,  356,  447,  256,  257,  447,  365,\n       82,   82,   82,   82,   82,   84,  258,  258,  258,  258,\n      258,  170,   84,   84,   84,   84,   84,   84,  258,  157,\n      334,  365,  156,  154,  366,  366,  366,  366,  366,  152,\n\n      366,  149,  139,  257,  133,  128,   84,   84,   84,   84,\n       84,   86,   86,   86,   86,   86,  127,  117,  115,  113,\n      112,  111,  110,  109,  258,  107,  106,   86,  104,   86,\n       86,  103,  101,   99,   97,   76,   86,   86,   86,   86,\n       86,   86,  366,   70,   58,   56,   45,   44,   42,   34,\n       33,   28,   21,   20,  306,  306,  306,  306,  306,   86,\n       86,   86,   86,   86,   86,   90,   90,   90,   90,   90,\n      306,   15,   13,  306,    7,   90,  292,  292,  292,  292,\n      292,    3,  292,   90,    0,    0,    0,    0,  292,    0,\n       90,   90,   90,   90,   90,   90,    0,    0,    0,    0,\n\n        0,    0,  306,    0,    0,    0,    0,  309,  309,  309,\n      309,  309,    0,   90,   90,   90,   90,   90,   90,   91,\n       91,   91,   91,  309,  292,    0,  309,    0,    0,   91,\n      297,  297,  297,  297,  297,    0,    0,   91,    0,    0,\n      297,    0,  297,    0,   91,   91,   91,   91,   91,   91,\n      328,  328,  328,  328,  328,  309,  328,    0,    0,    0,\n        0,    0,  328,    0,    0,    0,    0,   91,   91,   91,\n       91,   91,   91,   94,    0,    0,    0,    0,  297,    0,\n       94,   94,   94,   94,   94,   94,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  328,  339,\n\n      339,  339,  339,  339,   94,   94,   94,   94,   94,   96,\n       96,   96,   96,   96,    0,  339,    0,    0,  339,  332,\n      332,  332,  332,  332,    0,   96,    0,   96,   96,  332,\n        0,  332,    0,    0,   96,   96,   96,   96,   96,   96,\n        0,    0,    0,    0,    0,    0,    0,  339,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,   96,   96,   96,\n       96,   96,   96,  100,    0,    0,    0,  332,    0,    0,\n      100,  100,  100,  100,  100,  100,    0,    0,    0,    0,\n        0,    0,    0,  367,  367,  367,  367,  367,  340,  340,\n      340,  340,  340,  367,  100,  100,  100,  100,  100,  116,\n\n      116,  116,  116,  116,  340,    0,    0,  340,  364,  364,\n      364,  364,  364,    0,    0,    0,    0,  116,    0,    0,\n      364,    0,    0,    0,  116,  116,  116,  116,  116,  116,\n        0,  367,    0,    0,    0,    0,  340,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  116,  116,  116,\n      116,  116,  116,  126,    0,    0,  364,    0,    0,    0,\n      126,  126,  126,  126,  126,  126,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  126,  126,  126,  126,  126,  129,\n        0,    0,    0,    0,    0,    0,  129,  129,  129,  129,\n\n      129,  129,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      129,  129,  129,  129,  129,  131,  131,  131,  131,  131,\n        0,    0,    0,    0,    0,    0,  131,    0,    0,    0,\n        0,  131,    0,  131,  131,    0,    0,    0,    0,    0,\n      131,  131,  131,  131,  131,  131,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  131,  131,  131,  131,  131,  131,  135,\n      135,  135,  135,  135,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  135,    0,    0,\n\n        0,    0,    0,    0,  135,  135,  135,  135,  135,  135,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  135,  135,\n      135,  135,  135,  138,  138,  138,  138,  138,    0,  138,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  138,    0,    0,    0,    0,    0,    0,  138,  138,\n      138,  138,  138,  138,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  138,  138,  138,  138,  138,  138,  140,  140,  140,\n      140,  140,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,  140,    0,    0,    0,    0,\n        0,    0,  140,  140,  140,  140,  140,  140,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  140,  140,  140,  140,  140,\n      140,  142,  142,  142,  142,  142,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  142,    0,  142,\n      142,    0,    0,    0,    0,    0,  142,  142,  142,  142,\n      142,  142,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  142,\n      142,  142,  142,  142,  142,  143,  143,  143,  143,  143,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  143,    0,    0,    0,    0,    0,    0,\n      143,  143,  143,  143,  143,  143,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  143,  143,  143,  143,  143,  145,\n      145,  145,  145,  145,    0,    0,    0,    0,    0,  145,\n        0,    0,    0,    0,    0,    0,    0,  145,    0,    0,\n        0,    0,    0,    0,  145,  145,  145,  145,  145,  145,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  145,  145,  145,\n\n      145,  145,  145,  147,  147,  147,  147,  147,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  147,    0,    0,    0,    0,    0,    0,  147,  147,\n      147,  147,  147,  147,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  147,  147,  147,  147,  147,  148,  148,  148,\n      148,  148,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  148,    0,    0,    0,    0,\n        0,    0,  148,  148,  148,  148,  148,  148,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,  148,  148,  148,  148,\n      148,  153,  153,  153,  153,  153,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  153,\n        0,    0,    0,    0,    0,    0,  153,  153,  153,  153,\n      153,  153,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      153,  153,  153,  153,  153,  158,  158,  158,  158,  158,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  158,    0,    0,    0,    0,    0,    0,\n      158,  158,  158,  158,  158,  158,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  158,  158,  158,  158,  158,  167,\n        0,    0,    0,    0,    0,    0,  167,  167,  167,  167,\n      167,  167,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      167,  167,  167,  167,  167,  169,  169,  169,  169,  169,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  169,    0,  169,  169,    0,    0,    0,    0,    0,\n      169,  169,  169,  169,  169,  169,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,  169,  169,  169,  169,  169,  169,  171,\n        0,    0,    0,    0,    0,    0,  171,  171,  171,  171,\n      171,  171,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      171,  171,  171,  171,  171,  173,  173,  173,  173,  173,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  173,    0,    0,    0,    0,    0,    0,\n      173,  173,  173,  173,  173,  173,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  173,  173,  173,  173,  173,  173,  174,\n\n        0,    0,    0,    0,    0,    0,  174,  174,  174,  174,\n      174,  174,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      174,  174,  174,  174,  174,  180,  180,  180,  180,  180,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  180,    0,    0,    0,    0,    0,    0,\n      180,  180,  180,  180,  180,  180,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  180,  180,  180,  180,  180,  182,\n      182,  182,  182,  182,    0,  182,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,  182,    0,    0,\n        0,    0,    0,    0,  182,  182,  182,  182,  182,  182,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  182,  182,  182,\n      182,  182,  182,  183,  183,  183,  183,  183,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  183,    0,    0,    0,    0,    0,    0,  183,  183,\n      183,  183,  183,  183,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  183,  183,  183,  183,  183,  183,  184,    0,    0,\n\n        0,    0,    0,    0,  184,  184,  184,  184,  184,  184,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  184,  184,\n      184,  184,  184,  185,  185,  185,  185,  185,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  185,    0,    0,    0,    0,    0,    0,  185,  185,\n      185,  185,  185,  185,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  185,  185,  185,  185,  185,  186,  186,  186,\n      186,  186,    0,    0,    0,    0,    0,  186,    0,    0,\n\n        0,    0,    0,    0,    0,  186,    0,    0,    0,    0,\n        0,    0,  186,  186,  186,  186,  186,  186,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  186,  186,  186,  186,  186,\n      186,  187,    0,    0,    0,    0,    0,    0,  187,  187,\n      187,  187,  187,  187,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  187,  187,  187,  187,  187,  188,    0,    0,\n        0,    0,    0,    0,  188,  188,  188,  188,  188,  188,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,  188,  188,\n      188,  188,  188,  194,    0,    0,    0,    0,    0,    0,\n      194,  194,  194,  194,  194,  194,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  194,  194,  194,  194,  194,  195,\n      195,  195,  195,  195,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  195,    0,    0,\n        0,    0,    0,    0,  195,  195,  195,  195,  195,  195,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  195,  195,\n\n      195,  195,  195,  196,  196,  196,  196,  196,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  196,    0,    0,    0,    0,    0,    0,  196,  196,\n      196,  196,  196,  196,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  196,  196,  196,  196,  196,  204,  204,  204,\n      204,  204,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  204,    0,  204,  204,    0,    0,    0,\n        0,    0,  204,  204,  204,  204,  204,  204,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,  204,  204,  204,  204,  204,\n      204,  205,  205,  205,  205,  205,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  205,\n        0,    0,    0,    0,    0,    0,  205,  205,  205,  205,\n      205,  205,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      205,  205,  205,  205,  205,  207,  207,  207,  207,  207,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  207,    0,    0,    0,    0,    0,    0,\n      207,  207,  207,  207,  207,  207,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  207,  207,  207,  207,  207,  207,  208,\n      208,  208,  208,  208,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  208,    0,    0,\n        0,    0,    0,    0,  208,  208,  208,  208,  208,  208,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  208,  208,\n      208,  208,  208,  209,    0,    0,    0,    0,    0,    0,\n      209,  209,  209,  209,  209,  209,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,  209,  209,  209,  209,  209,  220,\n      220,  220,  220,  220,    0,  220,    0,    0,    0,  220,\n      220,  220,    0,    0,    0,    0,    0,  220,    0,    0,\n        0,    0,    0,    0,  220,  220,  220,  220,  220,  220,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  220,  220,  220,\n      220,  220,  220,  221,  221,  221,  221,  221,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  221,    0,    0,    0,    0,    0,    0,  221,  221,\n      221,  221,  221,  221,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  221,  221,  221,  221,  221,  223,  223,  223,\n      223,  223,    0,  223,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  223,    0,    0,    0,    0,\n        0,    0,  223,  223,  223,  223,  223,  223,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  223,  223,  223,  223,  223,\n      223,  224,  224,  224,  224,  224,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  224,\n        0,    0,    0,    0,    0,    0,  224,  224,  224,  224,\n\n      224,  224,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  224,\n      224,  224,  224,  224,  224,  225,  225,  225,  225,  225,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  225,    0,  225,  225,    0,    0,    0,    0,    0,\n      225,  225,  225,  225,  225,  225,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  225,  225,  225,  225,  225,  225,  226,\n      226,  226,  226,  226,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  226,    0,  226,  226,    0,\n\n        0,    0,    0,    0,  226,  226,  226,  226,  226,  226,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  226,  226,  226,\n      226,  226,  226,  227,  227,  227,  227,  227,    0,    0,\n        0,    0,    0,  227,    0,    0,    0,    0,    0,    0,\n        0,  227,    0,    0,    0,    0,    0,    0,  227,  227,\n      227,  227,  227,  227,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  227,  227,  227,  227,  227,  227,  228,  228,  228,\n      228,  228,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,  228,    0,  228,  228,    0,    0,    0,\n        0,    0,  228,  228,  228,  228,  228,  228,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  228,  228,  228,  228,  228,\n      228,  229,  229,  229,  229,  229,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  229,    0,  229,\n      229,    0,    0,    0,    0,    0,  229,  229,  229,  229,\n      229,  229,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  229,\n      229,  229,  229,  229,  229,  231,    0,    0,    0,    0,\n\n        0,    0,  231,  231,  231,  231,  231,  231,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  231,  231,  231,  231,\n      231,  232,    0,    0,    0,    0,    0,    0,  232,  232,\n      232,  232,  232,  232,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  232,  232,  232,  232,  232,  238,    0,    0,\n        0,    0,    0,    0,  238,  238,  238,  238,  238,  238,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  238,  238,\n\n      238,  238,  238,  239,    0,    0,    0,    0,    0,    0,\n      239,  239,  239,  239,  239,  239,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  239,  239,  239,  239,  239,  240,\n        0,    0,    0,    0,    0,    0,  240,  240,  240,  240,\n      240,  240,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      240,  240,  240,  240,  240,  241,    0,    0,    0,    0,\n        0,    0,  241,  241,  241,  241,  241,  241,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,  241,  241,  241,  241,\n      241,  242,    0,    0,    0,    0,    0,    0,  242,  242,\n      242,  242,  242,  242,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  242,  242,  242,  242,  242,  252,  252,  252,\n      252,    0,    0,  252,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  252,    0,    0,    0,    0,\n        0,    0,  252,  252,  252,  252,  252,  252,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  252,  252,  252,  252,  252,\n\n      252,  254,  254,  254,  254,    0,    0,    0,    0,    0,\n        0,  254,    0,    0,    0,    0,    0,    0,    0,  254,\n        0,    0,    0,    0,    0,    0,  254,  254,  254,  254,\n      254,  254,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  254,\n      254,  254,  254,  254,  254,  259,  259,  259,  259,  259,\n        0,    0,    0,    0,    0,    0,    0,  259,    0,    0,\n        0,    0,    0,  259,    0,    0,    0,    0,    0,    0,\n      259,  259,  259,  259,  259,  259,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,  259,  259,  259,  259,  259,  259,  260,\n      260,  260,  260,  260,    0,  260,    0,    0,    0,  260,\n      260,  260,    0,    0,    0,    0,    0,  260,    0,    0,\n        0,    0,    0,    0,  260,  260,  260,  260,  260,  260,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  260,  260,  260,\n      260,  260,  260,  261,  261,  261,  261,  261,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  261,    0,    0,    0,    0,    0,    0,  261,  261,\n      261,  261,  261,  261,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  261,  261,  261,  261,  261,  263,  263,  263,\n      263,  263,    0,  263,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  263,    0,    0,    0,    0,\n        0,    0,  263,  263,  263,  263,  263,  263,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  263,  263,  263,  263,  263,\n      263,  264,  264,  264,  264,  264,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  264,\n        0,    0,    0,    0,    0,    0,  264,  264,  264,  264,\n\n      264,  264,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  264,\n      264,  264,  264,  264,  264,  265,  265,  265,  265,  265,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  265,    0,  265,  265,    0,    0,    0,    0,    0,\n      265,  265,  265,  265,  265,  265,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  265,  265,  265,  265,  265,  265,  266,\n      266,  266,  266,  266,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  266,    0,  266,  266,    0,\n\n        0,    0,    0,    0,  266,  266,  266,  266,  266,  266,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  266,  266,  266,\n      266,  266,  266,  267,  267,  267,  267,  267,    0,    0,\n        0,    0,    0,  267,    0,    0,    0,    0,    0,    0,\n        0,  267,    0,    0,    0,    0,    0,    0,  267,  267,\n      267,  267,  267,  267,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  267,  267,  267,  267,  267,  267,  268,  268,  268,\n      268,  268,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,  268,    0,  268,  268,    0,    0,    0,\n        0,    0,  268,  268,  268,  268,  268,  268,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  268,  268,  268,  268,  268,\n      268,  269,  269,  269,  269,  269,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  269,    0,  269,\n      269,    0,    0,    0,    0,    0,  269,  269,  269,  269,\n      269,  269,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  269,\n      269,  269,  269,  269,  269,  270,  270,  270,  270,  270,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  270,    0,    0,    0,    0,    0,    0,\n      270,  270,  270,  270,  270,  270,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  270,  270,  270,  270,  270,  271,\n      271,  271,  271,  271,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  271,    0,    0,\n        0,    0,    0,    0,  271,  271,  271,  271,  271,  271,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  271,  271,\n\n      271,  271,  271,  276,    0,    0,    0,    0,    0,    0,\n      276,  276,  276,  276,  276,  276,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  276,  276,  276,  276,  276,  277,\n        0,    0,    0,    0,    0,    0,  277,  277,  277,  277,\n      277,  277,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      277,  277,  277,  277,  277,  278,    0,    0,    0,    0,\n        0,    0,  278,  278,  278,  278,  278,  278,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,  278,  278,  278,  278,\n      278,  279,    0,    0,    0,    0,    0,    0,  279,  279,\n      279,  279,  279,  279,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  279,  279,  279,  279,  279,  280,    0,    0,\n        0,    0,    0,    0,  280,  280,  280,  280,  280,  280,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  280,  280,\n      280,  280,  280,  293,  293,  293,  293,  293,    0,  293,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,  293,    0,    0,    0,    0,    0,    0,  293,  293,\n      293,  293,  293,  293,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  293,  293,  293,  293,  293,  293,  294,  294,  294,\n      294,    0,    0,  294,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  294,    0,    0,    0,    0,\n        0,    0,  294,  294,  294,  294,  294,  294,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  294,  294,  294,  294,  294,\n      294,  298,  298,  298,  298,  298,    0,    0,    0,    0,\n\n        0,  298,    0,    0,    0,    0,    0,    0,    0,  298,\n        0,    0,    0,    0,    0,    0,  298,  298,  298,  298,\n      298,  298,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  298,\n      298,  298,  298,  298,  298,  299,  299,  299,  299,    0,\n        0,    0,    0,    0,    0,  299,    0,    0,    0,    0,\n        0,    0,    0,  299,    0,    0,    0,    0,    0,    0,\n      299,  299,  299,  299,  299,  299,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  299,  299,  299,  299,  299,  299,  300,\n\n      300,  300,  300,  300,    0,    0,    0,    0,    0,    0,\n        0,  300,    0,    0,    0,    0,    0,  300,    0,    0,\n        0,    0,    0,    0,  300,  300,  300,  300,  300,  300,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  300,  300,  300,\n      300,  300,  300,  301,    0,    0,    0,    0,    0,    0,\n      301,  301,  301,  301,  301,  301,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  301,  301,  301,  301,  301,  304,\n      304,  304,  304,  304,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,  304,    0,    0,\n        0,    0,    0,    0,  304,  304,  304,  304,  304,  304,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  304,  304,  304,\n      304,  304,  304,  305,  305,  305,  305,  305,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  305,    0,    0,    0,    0,    0,    0,  305,  305,\n      305,  305,  305,  305,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  305,  305,  305,  305,  305,  308,  308,  308,\n\n      308,  308,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  308,    0,    0,    0,    0,\n        0,    0,  308,  308,  308,  308,  308,  308,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  308,  308,  308,  308,\n      308,  310,    0,    0,    0,    0,    0,    0,  310,  310,\n      310,  310,  310,  310,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  310,  310,  310,  310,  310,  311,  311,  311,\n      311,  311,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,  311,    0,    0,    0,    0,\n        0,    0,  311,  311,  311,  311,  311,  311,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  311,  311,  311,  311,\n      311,  315,  315,  315,  315,  315,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  315,\n        0,    0,    0,    0,    0,    0,  315,  315,  315,  315,\n      315,  315,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      315,  315,  315,  315,  315,  316,  316,  316,  316,  316,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  316,    0,    0,    0,    0,    0,    0,\n      316,  316,  316,  316,  316,  316,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  316,  316,  316,  316,  316,  317,\n        0,    0,    0,    0,    0,    0,  317,  317,  317,  317,\n      317,  317,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      317,  317,  317,  317,  317,  318,    0,    0,    0,    0,\n        0,    0,  318,  318,  318,  318,  318,  318,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  318,  318,  318,  318,\n      318,  331,    0,    0,    0,    0,    0,    0,  331,  331,\n      331,  331,  331,  331,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  331,  331,  331,  331,  331,  335,    0,    0,\n        0,    0,    0,    0,  335,  335,  335,  335,  335,  335,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  335,  335,\n      335,  335,  335,  336,  336,  336,  336,  336,    0,    0,\n\n        0,    0,    0,    0,    0,  336,    0,    0,    0,    0,\n        0,  336,    0,    0,    0,    0,    0,    0,  336,  336,\n      336,  336,  336,  336,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  336,  336,  336,  336,  336,  336,  338,    0,    0,\n        0,    0,    0,    0,  338,  338,  338,  338,  338,  338,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  338,  338,\n      338,  338,  338,  344,    0,    0,    0,    0,    0,    0,\n      344,  344,  344,  344,  344,  344,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  344,  344,  344,  344,  344,  345,\n        0,    0,    0,    0,    0,    0,  345,  345,  345,  345,\n      345,  345,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      345,  345,  345,  345,  345,  346,    0,    0,    0,    0,\n        0,    0,  346,  346,  346,  346,  346,  346,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  346,  346,  346,  346,\n      346,  347,    0,    0,    0,    0,    0,    0,  347,  347,\n\n      347,  347,  347,  347,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  347,  347,  347,  347,  347,  349,    0,    0,\n        0,    0,    0,    0,  349,  349,  349,  349,  349,  349,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  349,  349,\n      349,  349,  349,  350,    0,    0,    0,    0,    0,    0,\n      350,  350,  350,  350,  350,  350,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  350,  350,  350,  350,  350,  351,\n\n        0,    0,    0,    0,    0,    0,  351,  351,  351,  351,\n      351,  351,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      351,  351,  351,  351,  351,  358,    0,    0,    0,    0,\n        0,    0,  358,  358,  358,  358,  358,  358,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  358,  358,  358,  358,\n      358,  359,    0,    0,    0,    0,    0,    0,  359,  359,\n      359,  359,  359,  359,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,  359,  359,  359,  359,  359,  360,    0,    0,\n        0,    0,    0,    0,  360,  360,  360,  360,  360,  360,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  360,  360,\n      360,  360,  360,  362,    0,    0,    0,    0,    0,    0,\n      362,  362,  362,  362,  362,  362,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  362,  362,  362,  362,  362,  363,\n        0,    0,    0,    0,    0,    0,  363,  363,  363,  363,\n      363,  363,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      363,  363,  363,  363,  363,  370,    0,    0,  370,  370,\n      370,  370,  370,  370,  370,  370,  370,  370,  370,  371,\n        0,  371,    0,    0,  371,  371,  372,    0,    0,  372,\n      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,\n      373,  373,  373,    0,    0,  373,  373,  374,    0,  374,\n        0,    0,  374,  374,  375,  375,  375,  375,  375,    0,\n      375,  375,  376,  376,  376,  376,  376,  376,  376,  376,\n      376,  376,  376,  377,  377,  377,  377,  377,  377,  377,\n      377,  377,  377,  377,  377,  377,  377,  378,    0,  378,\n\n        0,    0,  378,  378,  379,  379,  379,  379,    0,  379,\n      379,  380,  380,  380,  380,  380,  380,  380,  380,  380,\n      380,  380,  381,  381,  381,  381,  381,  381,  381,  381,\n      381,  381,  381,  381,  381,  381,  382,  382,  382,  382,\n        0,  382,  382,  383,  383,  383,  383,  383,  383,  383,\n      383,  383,  383,  383,  384,  384,  384,  384,  384,  384,\n      384,  384,  384,  384,  384,  384,  384,  384,  384,  386,\n        0,  386,    0,    0,  386,  386,  387,  387,  387,  387,\n      387,  387,  387,  387,  387,  387,  387,  388,    0,    0,\n        0,    0,  388,  388,  389,    0,    0,    0,    0,  389,\n\n      389,  390,  390,  390,  390,  390,  390,  390,  390,  390,\n      390,  390,  391,    0,  391,  391,  392,  392,  392,  392,\n      392,  392,  392,  392,  392,  392,  392,  393,  393,  393,\n      393,  393,  393,  393,  393,  393,  393,  393,  394,  394,\n      394,  394,  394,  394,  394,  394,  394,  394,  394,  395,\n      395,  395,  395,  395,  395,  395,  395,  395,  395,  395,\n      395,  395,  395,  395,  396,  396,  396,  396,  396,  396,\n      396,  396,  396,  396,  396,  397,  397,  397,  397,    0,\n      397,  397,  398,  398,  398,  398,  398,  398,  398,  398,\n      398,  398,  398,  400,    0,  400,    0,    0,  400,  400,\n\n      401,  401,  401,  401,  401,  401,  401,  401,  401,  401,\n      401,  402,    0,  402,    0,  402,  402,  403,    0,    0,\n      403,  403,  403,  403,  403,  403,  403,  403,  403,  403,\n      403,  404,    0,  404,    0,    0,  404,  404,  405,    0,\n        0,  405,  405,  405,  405,  405,  405,  405,  405,  405,\n      405,  405,  406,  406,  406,  406,  406,  406,  406,  406,\n      406,  406,  406,  406,  406,  406,  406,  407,  407,  407,\n      407,  407,  407,  407,  407,  407,  407,  407,  407,  407,\n      407,  407,  408,  408,  408,  408,  408,  408,  408,  408,\n      408,  408,  408,  409,  409,  409,  409,  409,  409,  409,\n\n      409,  409,  409,  409,  411,    0,  411,    0,  411,  411,\n      412,  412,  412,  412,  412,  412,    0,  412,  412,  412,\n      412,  412,  412,  412,  413,  413,  413,  413,  413,  413,\n      413,  413,  413,  413,  413,  413,  413,  413,  414,  414,\n      414,  414,    0,    0,    0,  414,    0,  414,    0,    0,\n      414,  414,  415,  415,  415,  415,  415,  415,  415,  415,\n      415,  415,  415,  415,  415,  415,  415,  416,  416,  416,\n      416,  416,  416,  416,  416,  416,  416,  416,  416,  416,\n      416,  416,  418,    0,  418,    0,  418,  418,  419,  419,\n      419,  419,  419,  419,    0,  419,  419,  419,  419,  419,\n\n      419,  419,  420,    0,    0,  420,  420,  420,  420,  420,\n      420,  420,  420,  420,  420,  420,  421,    0,    0,  421,\n      421,  421,  421,  421,  421,  421,  421,  421,  421,  421,\n      422,  422,  422,  422,  422,  422,  422,  422,  422,  422,\n      422,  422,  422,  422,  423,  423,  423,  423,  423,  423,\n      423,  423,  423,  423,  423,  423,  423,  423,  424,  424,\n      424,  424,    0,    0,    0,  424,    0,  424,    0,    0,\n      424,  424,  425,  425,  425,  425,    0,    0,    0,  425,\n      425,  425,  425,    0,  425,  425,  426,  426,  426,  426,\n      426,  426,  426,  426,  426,  426,  426,  426,  426,  426,\n\n      427,  427,  427,  427,    0,    0,    0,  427,  427,  427,\n      427,    0,  427,  427,  428,  428,  428,  428,  428,  428,\n      428,  428,  428,  428,  428,  428,  428,  428,  428,  430,\n        0,  430,    0,  430,  430,  431,  431,  431,  431,  431,\n      431,  431,  431,  431,  431,  431,  431,  431,  431,  432,\n      432,  432,  432,  432,  432,  432,  432,  432,  432,  432,\n      432,  432,  432,  433,  433,  433,  433,  433,    0,    0,\n      433,  433,  433,  433,  433,  433,  433,  434,  434,  434,\n      434,  434,  434,  434,  434,  434,  434,  434,  434,  434,\n      434,  435,  435,  435,  435,  435,  435,  435,  435,  435,\n\n      435,  435,  435,  435,  435,  436,  436,  436,  436,    0,\n        0,    0,  436,    0,  436,    0,    0,  436,  436,  437,\n      437,  437,  437,    0,    0,    0,  437,  437,  437,  437,\n        0,  437,  437,  438,  438,  438,  438,  438,  438,  438,\n      438,  438,  438,  438,  438,  438,  438,  439,  439,  439,\n      439,    0,    0,    0,  439,  439,  439,  439,    0,  439,\n      439,  441,    0,  441,    0,  441,  441,  442,  442,  442,\n      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,\n      442,  443,  443,    0,  443,  443,  443,  443,  443,  443,\n      443,  443,  443,  443,  443,  444,  444,  444,  444,  444,\n\n      444,  444,  444,  444,  444,  444,  444,  444,  444,  445,\n      445,  445,  445,  445,    0,    0,  445,  445,  445,  445,\n      445,  445,  445,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,\n      369,  369,  369,  369,  369,  369,  369,  369,  369,  369\n\n    } ;\n\nstatic yy_state_type yy_last_accepting_state;\nstatic char *yy_last_accepting_cpos;\n\nextern int css_flex_debug;\nint css_flex_debug = 0;\n\n/* The intent behind this definition is that it'll catch\n * any uses of REJECT which flex missed.\n */\n#define REJECT reject_used_but_not_detected\n#define yymore() yymore_used_but_not_detected\n#define YY_MORE_ADJ 0\n#define YY_RESTORE_YY_MORE_OFFSET\nchar *csstext;\n#line 1 \"css.grammar\"\n#define YY_NO_INPUT 1\n#line 2084 \"lex.css.c\"\n\n#define INITIAL 0\n\n#ifndef YY_NO_UNISTD_H\n/* Special case for \"unistd.h\", since it is non-ANSI. We include it way\n * down here because we want the user's section 1 to have been scanned first.\n * The user has a chance to override it with an option.\n */\n#include <unistd.h>\n#endif\n\n#ifndef YY_EXTRA_TYPE\n#define YY_EXTRA_TYPE void *\n#endif\n\nstatic int yy_init_globals (void );\n\n/* Accessor methods to globals.\n   These are made visible to non-reentrant scanners for convenience. */\n\nint csslex_destroy (void );\n\nint cssget_debug (void );\n\nvoid cssset_debug (int debug_flag  );\n\nYY_EXTRA_TYPE cssget_extra (void );\n\nvoid cssset_extra (YY_EXTRA_TYPE user_defined  );\n\nFILE *cssget_in (void );\n\nvoid cssset_in  (FILE * in_str  );\n\nFILE *cssget_out (void );\n\nvoid cssset_out  (FILE * out_str  );\n\nyy_size_t cssget_leng (void );\n\nchar *cssget_text (void );\n\nint cssget_lineno (void );\n\nvoid cssset_lineno (int line_number  );\n\n/* Macros after this point can all be overridden by user definitions in\n * section 1.\n */\n\n#ifndef YY_SKIP_YYWRAP\n#ifdef __cplusplus\nextern \"C\" int csswrap (void );\n#else\nextern int csswrap (void );\n#endif\n#endif\n\n#ifndef yytext_ptr\nstatic void yy_flex_strncpy (char *,yyconst char *,int );\n#endif\n\n#ifdef YY_NEED_STRLEN\nstatic int yy_flex_strlen (yyconst char * );\n#endif\n\n#ifndef YY_NO_INPUT\n\n#ifdef __cplusplus\nstatic int yyinput (void );\n#else\nstatic int input (void );\n#endif\n\n#endif\n\n/* Amount of stuff to slurp up with each read. */\n#ifndef YY_READ_BUF_SIZE\n#define YY_READ_BUF_SIZE 8192\n#endif\n\n/* Copy whatever the last rule matched to the standard output. */\n#ifndef ECHO\n/* This used to be an fputs(), but since the string might contain NUL's,\n * we now use fwrite().\n */\n#define ECHO fwrite( csstext, cssleng, 1, cssout )\n#endif\n\n/* Gets input and stuffs it into \"buf\".  number of characters read, or YY_NULL,\n * is returned in \"result\".\n */\n#ifndef YY_INPUT\n#define YY_INPUT(buf,result,max_size) \\\n\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\\n\t\t{ \\\n\t\tint c = '*'; \\\n\t\tyy_size_t n; \\\n\t\tfor ( n = 0; n < max_size && \\\n\t\t\t     (c = getc( cssin )) != EOF && c != '\\n'; ++n ) \\\n\t\t\tbuf[n] = (char) c; \\\n\t\tif ( c == '\\n' ) \\\n\t\t\tbuf[n++] = (char) c; \\\n\t\tif ( c == EOF && ferror( cssin ) ) \\\n\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\\n\t\tresult = n; \\\n\t\t} \\\n\telse \\\n\t\t{ \\\n\t\terrno=0; \\\n\t\twhile ( (result = fread(buf, 1, max_size, cssin))==0 && ferror(cssin)) \\\n\t\t\t{ \\\n\t\t\tif( errno != EINTR) \\\n\t\t\t\t{ \\\n\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\\n\t\t\t\tbreak; \\\n\t\t\t\t} \\\n\t\t\terrno=0; \\\n\t\t\tclearerr(cssin); \\\n\t\t\t} \\\n\t\t}\\\n\\\n\n#endif\n\n/* No semi-colon after return; correct usage is to write \"yyterminate();\" -\n * we don't want an extra ';' after the \"return\" because that will cause\n * some compilers to complain about unreachable statements.\n */\n#ifndef yyterminate\n#define yyterminate() return YY_NULL\n#endif\n\n/* Number of entries by which start-condition stack grows. */\n#ifndef YY_START_STACK_INCR\n#define YY_START_STACK_INCR 25\n#endif\n\n/* Report a fatal error. */\n#ifndef YY_FATAL_ERROR\n#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )\n#endif\n\n/* end tables serialization structures and prototypes */\n\n/* Default declaration of generated scanner - a define so the user can\n * easily add parameters.\n */\n#ifndef YY_DECL\n#define YY_DECL_IS_OURS 1\n\nextern int csslex (void);\n\n#define YY_DECL int csslex (void)\n#endif /* !YY_DECL */\n\n/* Code executed at the beginning of each rule, after csstext and cssleng\n * have been set up.\n */\n#ifndef YY_USER_ACTION\n#define YY_USER_ACTION\n#endif\n\n/* Code executed at the end of each rule. */\n#ifndef YY_BREAK\n#define YY_BREAK break;\n#endif\n\n#define YY_RULE_SETUP \\\n\tYY_USER_ACTION\n\n/** The main scanner function which does all the work.\n */\nYY_DECL\n{\n\tregister yy_state_type yy_current_state;\n\tregister char *yy_cp, *yy_bp;\n\tregister int yy_act;\n    \n#line 22 \"css.grammar\"\n\n\n#line 2267 \"lex.css.c\"\n\n\tif ( !(yy_init) )\n\t\t{\n\t\t(yy_init) = 1;\n\n#ifdef YY_USER_INIT\n\t\tYY_USER_INIT;\n#endif\n\n\t\tif ( ! (yy_start) )\n\t\t\t(yy_start) = 1;\t/* first start state */\n\n\t\tif ( ! cssin )\n\t\t\tcssin = stdin;\n\n\t\tif ( ! cssout )\n\t\t\tcssout = stdout;\n\n\t\tif ( ! YY_CURRENT_BUFFER ) {\n\t\t\tcssensure_buffer_stack ();\n\t\t\tYY_CURRENT_BUFFER_LVALUE =\n\t\t\t\tcss_create_buffer(cssin,YY_BUF_SIZE );\n\t\t}\n\n\t\tcss_load_buffer_state( );\n\t\t}\n\n\twhile ( 1 )\t\t/* loops until end-of-file is reached */\n\t\t{\n\t\tyy_cp = (yy_c_buf_p);\n\n\t\t/* Support of csstext. */\n\t\t*yy_cp = (yy_hold_char);\n\n\t\t/* yy_bp points to the position in yy_ch_buf of the start of\n\t\t * the current run.\n\t\t */\n\t\tyy_bp = yy_cp;\n\n\t\tyy_current_state = (yy_start);\nyy_match:\n\t\tdo\n\t\t\t{\n\t\t\tregister YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];\n\t\t\tif ( yy_accept[yy_current_state] )\n\t\t\t\t{\n\t\t\t\t(yy_last_accepting_state) = yy_current_state;\n\t\t\t\t(yy_last_accepting_cpos) = yy_cp;\n\t\t\t\t}\n\t\t\twhile ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\n\t\t\t\t{\n\t\t\t\tyy_current_state = (int) yy_def[yy_current_state];\n\t\t\t\tif ( yy_current_state >= 370 )\n\t\t\t\t\tyy_c = yy_meta[(unsigned int) yy_c];\n\t\t\t\t}\n\t\t\tyy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];\n\t\t\t++yy_cp;\n\t\t\t}\n\t\twhile ( yy_base[yy_current_state] != 6624 );\n\nyy_find_action:\n\t\tyy_act = yy_accept[yy_current_state];\n\t\tif ( yy_act == 0 )\n\t\t\t{ /* have to back up */\n\t\t\tyy_cp = (yy_last_accepting_cpos);\n\t\t\tyy_current_state = (yy_last_accepting_state);\n\t\t\tyy_act = yy_accept[yy_current_state];\n\t\t\t}\n\n\t\tYY_DO_BEFORE_ACTION;\n\ndo_action:\t/* This label is used only to access EOF actions. */\n\n\t\tswitch ( yy_act )\n\t{ /* beginning of action switch */\n\t\t\tcase 0: /* must back up */\n\t\t\t/* undo the effects of YY_DO_BEFORE_ACTION */\n\t\t\t*yy_cp = (yy_hold_char);\n\t\t\tyy_cp = (yy_last_accepting_cpos);\n\t\t\tyy_current_state = (yy_last_accepting_state);\n\t\t\tgoto yy_find_action;\n\ncase 1:\n/* rule 1 can match eol */\nYY_RULE_SETUP\n#line 24 \"css.grammar\"\n\n\tYY_BREAK\ncase 2:\n/* rule 2 can match eol */\nYY_RULE_SETUP\n#line 26 \"css.grammar\"\n/* ignore comments */\n\tYY_BREAK\ncase 3:\nYY_RULE_SETUP\n#line 28 \"css.grammar\"\n\n\tYY_BREAK\ncase 4:\nYY_RULE_SETUP\n#line 29 \"css.grammar\"\n\n\tYY_BREAK\ncase 5:\nYY_RULE_SETUP\n#line 30 \"css.grammar\"\n\n\tYY_BREAK\ncase 6:\nYY_RULE_SETUP\n#line 31 \"css.grammar\"\n\n\tYY_BREAK\ncase 7:\n/* rule 7 can match eol */\nYY_RULE_SETUP\n#line 33 \"css.grammar\"\n{cssConsume(csstext, CSSSTRING);}\n\tYY_BREAK\ncase 8:\n/* rule 8 can match eol */\nYY_RULE_SETUP\n#line 35 \"css.grammar\"\n{cssConsume(csstext, CSSIDENT);}\n\tYY_BREAK\ncase 9:\n/* rule 9 can match eol */\nYY_RULE_SETUP\n#line 37 \"css.grammar\"\n{cssConsume(csstext, CSSHASH);}\n\tYY_BREAK\ncase 10:\nYY_RULE_SETUP\n#line 39 \"css.grammar\"\n{cssConsume(csstext, CSSIMPORT);}\n\tYY_BREAK\ncase 11:\nYY_RULE_SETUP\n#line 40 \"css.grammar\"\n\n\tYY_BREAK\ncase 12:\nYY_RULE_SETUP\n#line 41 \"css.grammar\"\n{cssConsume(csstext, CSSMEDIA);}\n\tYY_BREAK\ncase 13:\nYY_RULE_SETUP\n#line 42 \"css.grammar\"\n\n\tYY_BREAK\ncase 14:\nYY_RULE_SETUP\n#line 43 \"css.grammar\"\n\n\tYY_BREAK\ncase 15:\nYY_RULE_SETUP\n#line 44 \"css.grammar\"\n\n\tYY_BREAK\ncase 16:\nYY_RULE_SETUP\n#line 46 \"css.grammar\"\n\n\tYY_BREAK\ncase 17:\nYY_RULE_SETUP\n#line 48 \"css.grammar\"\n{cssConsume(csstext, CSSEMS);}\n\tYY_BREAK\ncase 18:\nYY_RULE_SETUP\n#line 49 \"css.grammar\"\n{cssConsume(csstext, CSSEXS);}\n\tYY_BREAK\ncase 19:\nYY_RULE_SETUP\n#line 50 \"css.grammar\"\n{cssConsume(csstext, CSSLENGTH);}\n\tYY_BREAK\ncase 20:\nYY_RULE_SETUP\n#line 51 \"css.grammar\"\n{cssConsume(csstext, CSSLENGTH);}\n\tYY_BREAK\ncase 21:\nYY_RULE_SETUP\n#line 52 \"css.grammar\"\n{cssConsume(csstext, CSSLENGTH);}\n\tYY_BREAK\ncase 22:\nYY_RULE_SETUP\n#line 53 \"css.grammar\"\n{cssConsume(csstext, CSSLENGTH);}\n\tYY_BREAK\ncase 23:\nYY_RULE_SETUP\n#line 54 \"css.grammar\"\n{cssConsume(csstext, CSSLENGTH);}\n\tYY_BREAK\ncase 24:\nYY_RULE_SETUP\n#line 55 \"css.grammar\"\n{cssConsume(csstext, CSSLENGTH);}\n\tYY_BREAK\ncase 25:\nYY_RULE_SETUP\n#line 56 \"css.grammar\"\n{cssConsume(csstext, CSSANGLE);}\n\tYY_BREAK\ncase 26:\nYY_RULE_SETUP\n#line 57 \"css.grammar\"\n{cssConsume(csstext, CSSANGLE);}\n\tYY_BREAK\ncase 27:\nYY_RULE_SETUP\n#line 58 \"css.grammar\"\n{cssConsume(csstext, CSSANGLE);}\n\tYY_BREAK\ncase 28:\nYY_RULE_SETUP\n#line 59 \"css.grammar\"\n{cssConsume(csstext, CSSTIME);}\n\tYY_BREAK\ncase 29:\nYY_RULE_SETUP\n#line 60 \"css.grammar\"\n{cssConsume(csstext, CSSTIME);}\n\tYY_BREAK\ncase 30:\nYY_RULE_SETUP\n#line 61 \"css.grammar\"\n{cssConsume(csstext, CSSFREQ);}\n\tYY_BREAK\ncase 31:\nYY_RULE_SETUP\n#line 62 \"css.grammar\"\n{cssConsume(csstext, CSSFREQ);}\n\tYY_BREAK\ncase 32:\n/* rule 32 can match eol */\nYY_RULE_SETUP\n#line 63 \"css.grammar\"\n{cssConsume(csstext, CSSDIMEN);}\n\tYY_BREAK\ncase 33:\nYY_RULE_SETUP\n#line 64 \"css.grammar\"\n{cssConsume(csstext, CSSPERCENTAGE);}\n\tYY_BREAK\ncase 34:\nYY_RULE_SETUP\n#line 65 \"css.grammar\"\n{cssConsume(csstext, CSSNUMBER);}\n\tYY_BREAK\ncase 35:\n/* rule 35 can match eol */\nYY_RULE_SETUP\n#line 67 \"css.grammar\"\n{cssConsume(csstext, CSSURI);}\n\tYY_BREAK\ncase 36:\n/* rule 36 can match eol */\nYY_RULE_SETUP\n#line 68 \"css.grammar\"\n{cssConsume(csstext, CSSURI);}\n\tYY_BREAK\ncase 37:\n/* rule 37 can match eol */\nYY_RULE_SETUP\n#line 69 \"css.grammar\"\n{cssConsume(csstext, CSSFUNCTION);}\n\tYY_BREAK\ncase 38:\nYY_RULE_SETUP\n#line 71 \"css.grammar\"\n{cssConsume(csstext, CSSUNICODERANGE);}\n\tYY_BREAK\ncase 39:\nYY_RULE_SETUP\n#line 72 \"css.grammar\"\n{cssConsume(csstext, CSSUNICODERANGE);}\n\tYY_BREAK\ncase 40:\nYY_RULE_SETUP\n#line 74 \"css.grammar\"\n{cssConsume(csstext, CSSUNKNOWN);}\n\tYY_BREAK\ncase 41:\nYY_RULE_SETUP\n#line 76 \"css.grammar\"\nECHO;\n\tYY_BREAK\n#line 2564 \"lex.css.c\"\ncase YY_STATE_EOF(INITIAL):\n\tyyterminate();\n\n\tcase YY_END_OF_BUFFER:\n\t\t{\n\t\t/* Amount of text matched not including the EOB char. */\n\t\tint yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;\n\n\t\t/* Undo the effects of YY_DO_BEFORE_ACTION. */\n\t\t*yy_cp = (yy_hold_char);\n\t\tYY_RESTORE_YY_MORE_OFFSET\n\n\t\tif ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )\n\t\t\t{\n\t\t\t/* We're scanning a new file or input source.  It's\n\t\t\t * possible that this happened because the user\n\t\t\t * just pointed cssin at a new source and called\n\t\t\t * csslex().  If so, then we have to assure\n\t\t\t * consistency between YY_CURRENT_BUFFER and our\n\t\t\t * globals.  Here is the right place to do so, because\n\t\t\t * this is the first action (other than possibly a\n\t\t\t * back-up) that will match for the new input source.\n\t\t\t */\n\t\t\t(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_input_file = cssin;\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;\n\t\t\t}\n\n\t\t/* Note that here we test for yy_c_buf_p \"<=\" to the position\n\t\t * of the first EOB in the buffer, since yy_c_buf_p will\n\t\t * already have been incremented past the NUL character\n\t\t * (since all states make transitions on EOB to the\n\t\t * end-of-buffer state).  Contrast this with the test\n\t\t * in input().\n\t\t */\n\t\tif ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )\n\t\t\t{ /* This was really a NUL. */\n\t\t\tyy_state_type yy_next_state;\n\n\t\t\t(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;\n\n\t\t\tyy_current_state = yy_get_previous_state(  );\n\n\t\t\t/* Okay, we're now positioned to make the NUL\n\t\t\t * transition.  We couldn't have\n\t\t\t * yy_get_previous_state() go ahead and do it\n\t\t\t * for us because it doesn't know how to deal\n\t\t\t * with the possibility of jamming (and we don't\n\t\t\t * want to build jamming into it because then it\n\t\t\t * will run more slowly).\n\t\t\t */\n\n\t\t\tyy_next_state = yy_try_NUL_trans( yy_current_state );\n\n\t\t\tyy_bp = (yytext_ptr) + YY_MORE_ADJ;\n\n\t\t\tif ( yy_next_state )\n\t\t\t\t{\n\t\t\t\t/* Consume the NUL. */\n\t\t\t\tyy_cp = ++(yy_c_buf_p);\n\t\t\t\tyy_current_state = yy_next_state;\n\t\t\t\tgoto yy_match;\n\t\t\t\t}\n\n\t\t\telse\n\t\t\t\t{\n\t\t\t\tyy_cp = (yy_c_buf_p);\n\t\t\t\tgoto yy_find_action;\n\t\t\t\t}\n\t\t\t}\n\n\t\telse switch ( yy_get_next_buffer(  ) )\n\t\t\t{\n\t\t\tcase EOB_ACT_END_OF_FILE:\n\t\t\t\t{\n\t\t\t\t(yy_did_buffer_switch_on_eof) = 0;\n\n\t\t\t\tif ( csswrap( ) )\n\t\t\t\t\t{\n\t\t\t\t\t/* Note: because we've taken care in\n\t\t\t\t\t * yy_get_next_buffer() to have set up\n\t\t\t\t\t * csstext, we can now set up\n\t\t\t\t\t * yy_c_buf_p so that if some total\n\t\t\t\t\t * hoser (like flex itself) wants to\n\t\t\t\t\t * call the scanner after we return the\n\t\t\t\t\t * YY_NULL, it'll still work - another\n\t\t\t\t\t * YY_NULL will get returned.\n\t\t\t\t\t */\n\t\t\t\t\t(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;\n\n\t\t\t\t\tyy_act = YY_STATE_EOF(YY_START);\n\t\t\t\t\tgoto do_action;\n\t\t\t\t\t}\n\n\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\tif ( ! (yy_did_buffer_switch_on_eof) )\n\t\t\t\t\t\tYY_NEW_FILE;\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\tcase EOB_ACT_CONTINUE_SCAN:\n\t\t\t\t(yy_c_buf_p) =\n\t\t\t\t\t(yytext_ptr) + yy_amount_of_matched_text;\n\n\t\t\t\tyy_current_state = yy_get_previous_state(  );\n\n\t\t\t\tyy_cp = (yy_c_buf_p);\n\t\t\t\tyy_bp = (yytext_ptr) + YY_MORE_ADJ;\n\t\t\t\tgoto yy_match;\n\n\t\t\tcase EOB_ACT_LAST_MATCH:\n\t\t\t\t(yy_c_buf_p) =\n\t\t\t\t&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];\n\n\t\t\t\tyy_current_state = yy_get_previous_state(  );\n\n\t\t\t\tyy_cp = (yy_c_buf_p);\n\t\t\t\tyy_bp = (yytext_ptr) + YY_MORE_ADJ;\n\t\t\t\tgoto yy_find_action;\n\t\t\t}\n\t\tbreak;\n\t\t}\n\n\tdefault:\n\t\tYY_FATAL_ERROR(\n\t\t\t\"fatal flex scanner internal error--no action found\" );\n\t} /* end of action switch */\n\t\t} /* end of scanning one token */\n} /* end of csslex */\n\n/* yy_get_next_buffer - try to read in a new buffer\n *\n * Returns a code representing an action:\n *\tEOB_ACT_LAST_MATCH -\n *\tEOB_ACT_CONTINUE_SCAN - continue scanning from current position\n *\tEOB_ACT_END_OF_FILE - end of file\n */\nstatic int yy_get_next_buffer (void)\n{\n    \tregister char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;\n\tregister char *source = (yytext_ptr);\n\tregister int number_to_move, i;\n\tint ret_val;\n\n\tif ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )\n\t\tYY_FATAL_ERROR(\n\t\t\"fatal flex scanner internal error--end of buffer missed\" );\n\n\tif ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )\n\t\t{ /* Don't try to fill the buffer, so this is an EOF. */\n\t\tif ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )\n\t\t\t{\n\t\t\t/* We matched a single character, the EOB, so\n\t\t\t * treat this as a final EOF.\n\t\t\t */\n\t\t\treturn EOB_ACT_END_OF_FILE;\n\t\t\t}\n\n\t\telse\n\t\t\t{\n\t\t\t/* We matched some text prior to the EOB, first\n\t\t\t * process it.\n\t\t\t */\n\t\t\treturn EOB_ACT_LAST_MATCH;\n\t\t\t}\n\t\t}\n\n\t/* Try to read more data. */\n\n\t/* First move last chars to start of buffer. */\n\tnumber_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;\n\n\tfor ( i = 0; i < number_to_move; ++i )\n\t\t*(dest++) = *(source++);\n\n\tif ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )\n\t\t/* don't do the read, it's not guaranteed to return an EOF,\n\t\t * just force an EOF\n\t\t */\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;\n\n\telse\n\t\t{\n\t\t\tyy_size_t num_to_read =\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;\n\n\t\twhile ( num_to_read <= 0 )\n\t\t\t{ /* Not enough room in the buffer - grow it. */\n\n\t\t\t/* just a shorter name for the current buffer */\n\t\t\tYY_BUFFER_STATE b = YY_CURRENT_BUFFER;\n\n\t\t\tint yy_c_buf_p_offset =\n\t\t\t\t(int) ((yy_c_buf_p) - b->yy_ch_buf);\n\n\t\t\tif ( b->yy_is_our_buffer )\n\t\t\t\t{\n\t\t\t\tyy_size_t new_size = b->yy_buf_size * 2;\n\n\t\t\t\tif ( new_size <= 0 )\n\t\t\t\t\tb->yy_buf_size += b->yy_buf_size / 8;\n\t\t\t\telse\n\t\t\t\t\tb->yy_buf_size *= 2;\n\n\t\t\t\tb->yy_ch_buf = (char *)\n\t\t\t\t\t/* Include room in for 2 EOB chars. */\n\t\t\t\t\tcssrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );\n\t\t\t\t}\n\t\t\telse\n\t\t\t\t/* Can't grow it, we don't own it. */\n\t\t\t\tb->yy_ch_buf = 0;\n\n\t\t\tif ( ! b->yy_ch_buf )\n\t\t\t\tYY_FATAL_ERROR(\n\t\t\t\t\"fatal error - scanner input buffer overflow\" );\n\n\t\t\t(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];\n\n\t\t\tnum_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -\n\t\t\t\t\t\tnumber_to_move - 1;\n\n\t\t\t}\n\n\t\tif ( num_to_read > YY_READ_BUF_SIZE )\n\t\t\tnum_to_read = YY_READ_BUF_SIZE;\n\n\t\t/* Read in more data. */\n\t\tYY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),\n\t\t\t(yy_n_chars), num_to_read );\n\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);\n\t\t}\n\n\tif ( (yy_n_chars) == 0 )\n\t\t{\n\t\tif ( number_to_move == YY_MORE_ADJ )\n\t\t\t{\n\t\t\tret_val = EOB_ACT_END_OF_FILE;\n\t\t\tcssrestart(cssin  );\n\t\t\t}\n\n\t\telse\n\t\t\t{\n\t\t\tret_val = EOB_ACT_LAST_MATCH;\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_buffer_status =\n\t\t\t\tYY_BUFFER_EOF_PENDING;\n\t\t\t}\n\t\t}\n\n\telse\n\t\tret_val = EOB_ACT_CONTINUE_SCAN;\n\n\tif ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {\n\t\t/* Extend the array by 50%, plus the number we really need. */\n\t\tyy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cssrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );\n\t\tif ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )\n\t\t\tYY_FATAL_ERROR( \"out of dynamic memory in yy_get_next_buffer()\" );\n\t}\n\n\t(yy_n_chars) += number_to_move;\n\tYY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;\n\tYY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;\n\n\t(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];\n\n\treturn ret_val;\n}\n\n/* yy_get_previous_state - get the state just before the EOB char was reached */\n\n    static yy_state_type yy_get_previous_state (void)\n{\n\tregister yy_state_type yy_current_state;\n\tregister char *yy_cp;\n    \n\tyy_current_state = (yy_start);\n\n\tfor ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )\n\t\t{\n\t\tregister YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);\n\t\tif ( yy_accept[yy_current_state] )\n\t\t\t{\n\t\t\t(yy_last_accepting_state) = yy_current_state;\n\t\t\t(yy_last_accepting_cpos) = yy_cp;\n\t\t\t}\n\t\twhile ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\n\t\t\t{\n\t\t\tyy_current_state = (int) yy_def[yy_current_state];\n\t\t\tif ( yy_current_state >= 370 )\n\t\t\t\tyy_c = yy_meta[(unsigned int) yy_c];\n\t\t\t}\n\t\tyy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];\n\t\t}\n\n\treturn yy_current_state;\n}\n\n/* yy_try_NUL_trans - try to make a transition on the NUL character\n *\n * synopsis\n *\tnext_state = yy_try_NUL_trans( current_state );\n */\n    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )\n{\n\tregister int yy_is_jam;\n    \tregister char *yy_cp = (yy_c_buf_p);\n\n\tregister YY_CHAR yy_c = 1;\n\tif ( yy_accept[yy_current_state] )\n\t\t{\n\t\t(yy_last_accepting_state) = yy_current_state;\n\t\t(yy_last_accepting_cpos) = yy_cp;\n\t\t}\n\twhile ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\n\t\t{\n\t\tyy_current_state = (int) yy_def[yy_current_state];\n\t\tif ( yy_current_state >= 370 )\n\t\t\tyy_c = yy_meta[(unsigned int) yy_c];\n\t\t}\n\tyy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];\n\tyy_is_jam = (yy_current_state == 369);\n\n\treturn yy_is_jam ? 0 : yy_current_state;\n}\n\n#ifndef YY_NO_INPUT\n#ifdef __cplusplus\n    static int yyinput (void)\n#else\n    static int input  (void)\n#endif\n\n{\n\tint c;\n    \n\t*(yy_c_buf_p) = (yy_hold_char);\n\n\tif ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )\n\t\t{\n\t\t/* yy_c_buf_p now points to the character we want to return.\n\t\t * If this occurs *before* the EOB characters, then it's a\n\t\t * valid NUL; if not, then we've hit the end of the buffer.\n\t\t */\n\t\tif ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )\n\t\t\t/* This was really a NUL. */\n\t\t\t*(yy_c_buf_p) = '\\0';\n\n\t\telse\n\t\t\t{ /* need more input */\n\t\t\tyy_size_t offset = (yy_c_buf_p) - (yytext_ptr);\n\t\t\t++(yy_c_buf_p);\n\n\t\t\tswitch ( yy_get_next_buffer(  ) )\n\t\t\t\t{\n\t\t\t\tcase EOB_ACT_LAST_MATCH:\n\t\t\t\t\t/* This happens because yy_g_n_b()\n\t\t\t\t\t * sees that we've accumulated a\n\t\t\t\t\t * token and flags that we need to\n\t\t\t\t\t * try matching the token before\n\t\t\t\t\t * proceeding.  But for input(),\n\t\t\t\t\t * there's no matching to consider.\n\t\t\t\t\t * So convert the EOB_ACT_LAST_MATCH\n\t\t\t\t\t * to EOB_ACT_END_OF_FILE.\n\t\t\t\t\t */\n\n\t\t\t\t\t/* Reset buffer status. */\n\t\t\t\t\tcssrestart(cssin );\n\n\t\t\t\t\t/*FALLTHROUGH*/\n\n\t\t\t\tcase EOB_ACT_END_OF_FILE:\n\t\t\t\t\t{\n\t\t\t\t\tif ( csswrap( ) )\n\t\t\t\t\t\treturn 0;\n\n\t\t\t\t\tif ( ! (yy_did_buffer_switch_on_eof) )\n\t\t\t\t\t\tYY_NEW_FILE;\n#ifdef __cplusplus\n\t\t\t\t\treturn yyinput();\n#else\n\t\t\t\t\treturn input();\n#endif\n\t\t\t\t\t}\n\n\t\t\t\tcase EOB_ACT_CONTINUE_SCAN:\n\t\t\t\t\t(yy_c_buf_p) = (yytext_ptr) + offset;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tc = *(unsigned char *) (yy_c_buf_p);\t/* cast for 8-bit char's */\n\t*(yy_c_buf_p) = '\\0';\t/* preserve csstext */\n\t(yy_hold_char) = *++(yy_c_buf_p);\n\n\treturn c;\n}\n#endif\t/* ifndef YY_NO_INPUT */\n\n/** Immediately switch to a different input stream.\n * @param input_file A readable stream.\n * \n * @note This function does not reset the start condition to @c INITIAL .\n */\n    void cssrestart  (FILE * input_file )\n{\n    \n\tif ( ! YY_CURRENT_BUFFER ){\n        cssensure_buffer_stack ();\n\t\tYY_CURRENT_BUFFER_LVALUE =\n            css_create_buffer(cssin,YY_BUF_SIZE );\n\t}\n\n\tcss_init_buffer(YY_CURRENT_BUFFER,input_file );\n\tcss_load_buffer_state( );\n}\n\n/** Switch to a different input buffer.\n * @param new_buffer The new input buffer.\n * \n */\n    void css_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )\n{\n    \n\t/* TODO. We should be able to replace this entire function body\n\t * with\n\t *\t\tcsspop_buffer_state();\n\t *\t\tcsspush_buffer_state(new_buffer);\n     */\n\tcssensure_buffer_stack ();\n\tif ( YY_CURRENT_BUFFER == new_buffer )\n\t\treturn;\n\n\tif ( YY_CURRENT_BUFFER )\n\t\t{\n\t\t/* Flush out information for old buffer. */\n\t\t*(yy_c_buf_p) = (yy_hold_char);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);\n\t\t}\n\n\tYY_CURRENT_BUFFER_LVALUE = new_buffer;\n\tcss_load_buffer_state( );\n\n\t/* We don't actually know whether we did this switch during\n\t * EOF (csswrap()) processing, but the only time this flag\n\t * is looked at is after csswrap() is called, so it's safe\n\t * to go ahead and always set it.\n\t */\n\t(yy_did_buffer_switch_on_eof) = 1;\n}\n\nstatic void css_load_buffer_state  (void)\n{\n    \t(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;\n\t(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;\n\tcssin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;\n\t(yy_hold_char) = *(yy_c_buf_p);\n}\n\n/** Allocate and initialize an input buffer state.\n * @param file A readable stream.\n * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.\n * \n * @return the allocated buffer state.\n */\n    YY_BUFFER_STATE css_create_buffer  (FILE * file, int  size )\n{\n\tYY_BUFFER_STATE b;\n    \n\tb = (YY_BUFFER_STATE) cssalloc(sizeof( struct yy_buffer_state )  );\n\tif ( ! b )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in css_create_buffer()\" );\n\n\tb->yy_buf_size = size;\n\n\t/* yy_ch_buf has to be 2 characters longer than the size given because\n\t * we need to put in 2 end-of-buffer characters.\n\t */\n\tb->yy_ch_buf = (char *) cssalloc(b->yy_buf_size + 2  );\n\tif ( ! b->yy_ch_buf )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in css_create_buffer()\" );\n\n\tb->yy_is_our_buffer = 1;\n\n\tcss_init_buffer(b,file );\n\n\treturn b;\n}\n\n/** Destroy the buffer.\n * @param b a buffer created with css_create_buffer()\n * \n */\n    void css_delete_buffer (YY_BUFFER_STATE  b )\n{\n    \n\tif ( ! b )\n\t\treturn;\n\n\tif ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */\n\t\tYY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;\n\n\tif ( b->yy_is_our_buffer )\n\t\tcssfree((void *) b->yy_ch_buf  );\n\n\tcssfree((void *) b  );\n}\n\n#ifndef __cplusplus\nextern int isatty (int );\n#endif /* __cplusplus */\n    \n/* Initializes or reinitializes a buffer.\n * This function is sometimes called more than once on the same buffer,\n * such as during a cssrestart() or at EOF.\n */\n    static void css_init_buffer  (YY_BUFFER_STATE  b, FILE * file )\n\n{\n\tint oerrno = errno;\n    \n\tcss_flush_buffer(b );\n\n\tb->yy_input_file = file;\n\tb->yy_fill_buffer = 1;\n\n    /* If b is the current buffer, then css_init_buffer was _probably_\n     * called from cssrestart() or through yy_get_next_buffer.\n     * In that case, we don't want to reset the lineno or column.\n     */\n    if (b != YY_CURRENT_BUFFER){\n        b->yy_bs_lineno = 1;\n        b->yy_bs_column = 0;\n    }\n\n        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;\n    \n\terrno = oerrno;\n}\n\n/** Discard all buffered characters. On the next scan, YY_INPUT will be called.\n * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.\n * \n */\n    void css_flush_buffer (YY_BUFFER_STATE  b )\n{\n    \tif ( ! b )\n\t\treturn;\n\n\tb->yy_n_chars = 0;\n\n\t/* We always need two end-of-buffer characters.  The first causes\n\t * a transition to the end-of-buffer state.  The second causes\n\t * a jam in that state.\n\t */\n\tb->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;\n\tb->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;\n\n\tb->yy_buf_pos = &b->yy_ch_buf[0];\n\n\tb->yy_at_bol = 1;\n\tb->yy_buffer_status = YY_BUFFER_NEW;\n\n\tif ( b == YY_CURRENT_BUFFER )\n\t\tcss_load_buffer_state( );\n}\n\n/** Pushes the new state onto the stack. The new state becomes\n *  the current state. This function will allocate the stack\n *  if necessary.\n *  @param new_buffer The new state.\n *  \n */\nvoid csspush_buffer_state (YY_BUFFER_STATE new_buffer )\n{\n    \tif (new_buffer == NULL)\n\t\treturn;\n\n\tcssensure_buffer_stack();\n\n\t/* This block is copied from css_switch_to_buffer. */\n\tif ( YY_CURRENT_BUFFER )\n\t\t{\n\t\t/* Flush out information for old buffer. */\n\t\t*(yy_c_buf_p) = (yy_hold_char);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);\n\t\t}\n\n\t/* Only push if top exists. Otherwise, replace top. */\n\tif (YY_CURRENT_BUFFER)\n\t\t(yy_buffer_stack_top)++;\n\tYY_CURRENT_BUFFER_LVALUE = new_buffer;\n\n\t/* copied from css_switch_to_buffer. */\n\tcss_load_buffer_state( );\n\t(yy_did_buffer_switch_on_eof) = 1;\n}\n\n/** Removes and deletes the top of the stack, if present.\n *  The next element becomes the new top.\n *  \n */\nvoid csspop_buffer_state (void)\n{\n    \tif (!YY_CURRENT_BUFFER)\n\t\treturn;\n\n\tcss_delete_buffer(YY_CURRENT_BUFFER );\n\tYY_CURRENT_BUFFER_LVALUE = NULL;\n\tif ((yy_buffer_stack_top) > 0)\n\t\t--(yy_buffer_stack_top);\n\n\tif (YY_CURRENT_BUFFER) {\n\t\tcss_load_buffer_state( );\n\t\t(yy_did_buffer_switch_on_eof) = 1;\n\t}\n}\n\n/* Allocates the stack if it does not exist.\n *  Guarantees space for at least one push.\n */\nstatic void cssensure_buffer_stack (void)\n{\n\tyy_size_t num_to_alloc;\n    \n\tif (!(yy_buffer_stack)) {\n\n\t\t/* First allocation is just for 2 elements, since we don't know if this\n\t\t * scanner will even need a stack. We use 2 instead of 1 to avoid an\n\t\t * immediate realloc on the next call.\n         */\n\t\tnum_to_alloc = 1;\n\t\t(yy_buffer_stack) = (struct yy_buffer_state**)cssalloc\n\t\t\t\t\t\t\t\t(num_to_alloc * sizeof(struct yy_buffer_state*)\n\t\t\t\t\t\t\t\t);\n\t\tif ( ! (yy_buffer_stack) )\n\t\t\tYY_FATAL_ERROR( \"out of dynamic memory in cssensure_buffer_stack()\" );\n\t\t\t\t\t\t\t\t  \n\t\tmemset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));\n\t\t\t\t\n\t\t(yy_buffer_stack_max) = num_to_alloc;\n\t\t(yy_buffer_stack_top) = 0;\n\t\treturn;\n\t}\n\n\tif ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){\n\n\t\t/* Increase the buffer to prepare for a possible push. */\n\t\tint grow_size = 8 /* arbitrary grow size */;\n\n\t\tnum_to_alloc = (yy_buffer_stack_max) + grow_size;\n\t\t(yy_buffer_stack) = (struct yy_buffer_state**)cssrealloc\n\t\t\t\t\t\t\t\t((yy_buffer_stack),\n\t\t\t\t\t\t\t\tnum_to_alloc * sizeof(struct yy_buffer_state*)\n\t\t\t\t\t\t\t\t);\n\t\tif ( ! (yy_buffer_stack) )\n\t\t\tYY_FATAL_ERROR( \"out of dynamic memory in cssensure_buffer_stack()\" );\n\n\t\t/* zero only the new slots.*/\n\t\tmemset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));\n\t\t(yy_buffer_stack_max) = num_to_alloc;\n\t}\n}\n\n/** Setup the input buffer state to scan directly from a user-specified character buffer.\n * @param base the character buffer\n * @param size the size in bytes of the character buffer\n * \n * @return the newly allocated buffer state object. \n */\nYY_BUFFER_STATE css_scan_buffer  (char * base, yy_size_t  size )\n{\n\tYY_BUFFER_STATE b;\n    \n\tif ( size < 2 ||\n\t     base[size-2] != YY_END_OF_BUFFER_CHAR ||\n\t     base[size-1] != YY_END_OF_BUFFER_CHAR )\n\t\t/* They forgot to leave room for the EOB's. */\n\t\treturn 0;\n\n\tb = (YY_BUFFER_STATE) cssalloc(sizeof( struct yy_buffer_state )  );\n\tif ( ! b )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in css_scan_buffer()\" );\n\n\tb->yy_buf_size = size - 2;\t/* \"- 2\" to take care of EOB's */\n\tb->yy_buf_pos = b->yy_ch_buf = base;\n\tb->yy_is_our_buffer = 0;\n\tb->yy_input_file = 0;\n\tb->yy_n_chars = b->yy_buf_size;\n\tb->yy_is_interactive = 0;\n\tb->yy_at_bol = 1;\n\tb->yy_fill_buffer = 0;\n\tb->yy_buffer_status = YY_BUFFER_NEW;\n\n\tcss_switch_to_buffer(b  );\n\n\treturn b;\n}\n\n/** Setup the input buffer state to scan a string. The next call to csslex() will\n * scan from a @e copy of @a str.\n * @param yystr a NUL-terminated string to scan\n * \n * @return the newly allocated buffer state object.\n * @note If you want to scan bytes that may contain NUL values, then use\n *       css_scan_bytes() instead.\n */\nYY_BUFFER_STATE css_scan_string (yyconst char * yystr )\n{\n    \n\treturn css_scan_bytes(yystr,strlen(yystr) );\n}\n\n/** Setup the input buffer state to scan the given bytes. The next call to csslex() will\n * scan from a @e copy of @a bytes.\n * @param bytes the byte buffer to scan\n * @param len the number of bytes in the buffer pointed to by @a bytes.\n * \n * @return the newly allocated buffer state object.\n */\nYY_BUFFER_STATE css_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )\n{\n\tYY_BUFFER_STATE b;\n\tchar *buf;\n\tyy_size_t n, i;\n    \n\t/* Get memory for full buffer, including space for trailing EOB's. */\n\tn = _yybytes_len + 2;\n\tbuf = (char *) cssalloc(n  );\n\tif ( ! buf )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in css_scan_bytes()\" );\n\n\tfor ( i = 0; i < _yybytes_len; ++i )\n\t\tbuf[i] = yybytes[i];\n\n\tbuf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;\n\n\tb = css_scan_buffer(buf,n );\n\tif ( ! b )\n\t\tYY_FATAL_ERROR( \"bad buffer in css_scan_bytes()\" );\n\n\t/* It's okay to grow etc. this buffer, and we should throw it\n\t * away when we're done.\n\t */\n\tb->yy_is_our_buffer = 1;\n\n\treturn b;\n}\n\n#ifndef YY_EXIT_FAILURE\n#define YY_EXIT_FAILURE 2\n#endif\n\nstatic void yy_fatal_error (yyconst char* msg )\n{\n    \t(void) fprintf( stderr, \"%s\\n\", msg );\n\texit( YY_EXIT_FAILURE );\n}\n\n/* Redefine yyless() so it works in section 3 code. */\n\n#undef yyless\n#define yyless(n) \\\n\tdo \\\n\t\t{ \\\n\t\t/* Undo effects of setting up csstext. */ \\\n        int yyless_macro_arg = (n); \\\n        YY_LESS_LINENO(yyless_macro_arg);\\\n\t\tcsstext[cssleng] = (yy_hold_char); \\\n\t\t(yy_c_buf_p) = csstext + yyless_macro_arg; \\\n\t\t(yy_hold_char) = *(yy_c_buf_p); \\\n\t\t*(yy_c_buf_p) = '\\0'; \\\n\t\tcssleng = yyless_macro_arg; \\\n\t\t} \\\n\twhile ( 0 )\n\n/* Accessor  methods (get/set functions) to struct members. */\n\n/** Get the current line number.\n * \n */\nint cssget_lineno  (void)\n{\n        \n    return csslineno;\n}\n\n/** Get the input stream.\n * \n */\nFILE *cssget_in  (void)\n{\n        return cssin;\n}\n\n/** Get the output stream.\n * \n */\nFILE *cssget_out  (void)\n{\n        return cssout;\n}\n\n/** Get the length of the current token.\n * \n */\nyy_size_t cssget_leng  (void)\n{\n        return cssleng;\n}\n\n/** Get the current token.\n * \n */\n\nchar *cssget_text  (void)\n{\n        return csstext;\n}\n\n/** Set the current line number.\n * @param line_number\n * \n */\nvoid cssset_lineno (int  line_number )\n{\n    \n    csslineno = line_number;\n}\n\n/** Set the input stream. This does not discard the current\n * input buffer.\n * @param in_str A readable stream.\n * \n * @see css_switch_to_buffer\n */\nvoid cssset_in (FILE *  in_str )\n{\n        cssin = in_str ;\n}\n\nvoid cssset_out (FILE *  out_str )\n{\n        cssout = out_str ;\n}\n\nint cssget_debug  (void)\n{\n        return css_flex_debug;\n}\n\nvoid cssset_debug (int  bdebug )\n{\n        css_flex_debug = bdebug ;\n}\n\nstatic int yy_init_globals (void)\n{\n        /* Initialization is the same as for the non-reentrant scanner.\n     * This function is called from csslex_destroy(), so don't allocate here.\n     */\n\n    (yy_buffer_stack) = 0;\n    (yy_buffer_stack_top) = 0;\n    (yy_buffer_stack_max) = 0;\n    (yy_c_buf_p) = (char *) 0;\n    (yy_init) = 0;\n    (yy_start) = 0;\n\n/* Defined in main.c */\n#ifdef YY_STDINIT\n    cssin = stdin;\n    cssout = stdout;\n#else\n    cssin = (FILE *) 0;\n    cssout = (FILE *) 0;\n#endif\n\n    /* For future reference: Set errno on error, since we are called by\n     * csslex_init()\n     */\n    return 0;\n}\n\n/* csslex_destroy is for both reentrant and non-reentrant scanners. */\nint csslex_destroy  (void)\n{\n    \n    /* Pop the buffer stack, destroying each element. */\n\twhile(YY_CURRENT_BUFFER){\n\t\tcss_delete_buffer(YY_CURRENT_BUFFER  );\n\t\tYY_CURRENT_BUFFER_LVALUE = NULL;\n\t\tcsspop_buffer_state();\n\t}\n\n\t/* Destroy the stack itself. */\n\tcssfree((yy_buffer_stack) );\n\t(yy_buffer_stack) = NULL;\n\n    /* Reset the globals. This is important in a non-reentrant scanner so the next time\n     * csslex() is called, initialization will occur. */\n    yy_init_globals( );\n\n    return 0;\n}\n\n/*\n * Internal utility routines.\n */\n\n#ifndef yytext_ptr\nstatic void yy_flex_strncpy (char* s1, yyconst char * s2, int n )\n{\n\tregister int i;\n\tfor ( i = 0; i < n; ++i )\n\t\ts1[i] = s2[i];\n}\n#endif\n\n#ifdef YY_NEED_STRLEN\nstatic int yy_flex_strlen (yyconst char * s )\n{\n\tregister int n;\n\tfor ( n = 0; s[n]; ++n )\n\t\t;\n\n\treturn n;\n}\n#endif\n\nvoid *cssalloc (yy_size_t  size )\n{\n\treturn (void *) malloc( size );\n}\n\nvoid *cssrealloc  (void * ptr, yy_size_t  size )\n{\n\t/* The cast to (char *) in the following accommodates both\n\t * implementations that use char* generic pointers, and those\n\t * that use void* generic pointers.  It works with the latter\n\t * because both ANSI C and C++ allow castless assignment from\n\t * any pointer type to void*, and deal with argument conversions\n\t * as though doing an assignment.\n\t */\n\treturn (void *) realloc( (char *) ptr, size );\n}\n\nvoid cssfree (void * ptr )\n{\n\tfree( (char *) ptr );\t/* see cssrealloc() for (char *) cast */\n}\n\n#define YYTABLES_NAME \"yytables\"\n\n#line 76 \"css.grammar\"\n\n\n\nint csswrap(void){return 1;}\n\n#endif  // __clang_analyzer__\n"
  },
  {
    "path": "src/css/src/CSSTokens.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#include <stdio.h>\n\ntypedef enum {\n  CSSFIRST_TOKEN = 0x100,\n  CSSSTRING = CSSFIRST_TOKEN,\n  CSSIDENT,\n  CSSHASH,\n  CSSEMS,\n  CSSEXS,\n  CSSLENGTH,\n  CSSANGLE,\n  CSSTIME,\n  CSSFREQ,\n  CSSDIMEN,\n  CSSPERCENTAGE,\n  CSSNUMBER,\n  CSSURI,\n  CSSFUNCTION,\n  CSSUNICODERANGE,\n  CSSIMPORT,\n  CSSUNKNOWN,\n  CSSMEDIA\n} CssParserCodes;\n\nextern const char* cssnames[];\n\n#ifndef YY_TYPEDEF_YY_SCANNER_T\n#define YY_TYPEDEF_YY_SCANNER_T\ntypedef void* yyscan_t;\n#endif\n\nextern FILE *cssin;\n\nint csslex(void);\nint cssConsume(char* text, int token);\nint cssget_lineno(void);\n"
  },
  {
    "path": "src/css/src/CSSTokens.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nconst char* cssnames[] = {\n  \"STRING\",\n  \"IDENT\",\n  \"HASH\",\n  \"EMS\",\n  \"EXS\",\n  \"LENGTH\",\n  \"ANGLE\",\n  \"TIME\",\n  \"FREQ\",\n  \"DIMEN\",\n  \"PERCENTAGE\",\n  \"NUMBER\",\n  \"URI\",\n  \"FUNCTION\",\n  \"UNICODERANGE\",\n  \"CSSIMPORT\",\n  \"UNKNOWN\",\n};\n"
  },
  {
    "path": "src/css/src/NICSSParser.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\nextern NSString* const kPropertyOrderKey;\nextern NSString* const kDependenciesSelectorKey;\n\n@protocol NICSSParserDelegate;\n\n/**\n * An Objective-C wrapper for the flex CSS parser.\n *\n * @ingroup NimbusCSS\n *\n * Generates a dictionary of raw CSS rules from a given CSS file.\n *\n * It is recommended that you do NOT use this object directly. Use NIStylesheet instead.\n *\n * Terminology note: CSS selectors are referred to as \"scopes\" to avoid confusion with\n * Objective-C selectors.\n *\n * This object is not thread-safe.\n */\n@interface NICSSParser : NSObject {\n@private\n  // CSS state\n  NSMutableDictionary* _mutatingRuleset;\n  NSMutableDictionary* _rulesets;\n  NSMutableArray* _mutatingScope;\n  NSMutableArray* _scopesForActiveRuleset;\n  NSString* _currentPropertyName;\n  NSMutableArray* _importedFilenames;\n  BOOL droppingCurrentRules;\n\n  union {\n    struct {\n      int InsideRuleset : 1; // Within `ruleset {...}`\n      int InsideProperty : 1; // Defining a `property: ...`\n      int InsideFunction : 1; // Within a `function(...)`\n      int InsideMedia : 1; // within `@media {}`\n      int ReadingMedia : 1; // got @media start, waiting for rules and a brace\n    } Flags;\n    int _data;\n  } _state;\n\n  // Parser state\n  NSString* _lastTokenText;\n  int _lastToken;\n\n  // Result state\n  BOOL _didFailToParse;\n}\n\n- (NSDictionary *)dictionaryForPath:(NSString *)path\n                         pathPrefix:(NSString *)pathPrefix\n                           delegate:(id<NICSSParserDelegate>)delegate;\n\n- (NSDictionary *)dictionaryForPath:(NSString *)path pathPrefix:(NSString *)rootPath;\n- (NSDictionary *)dictionaryForPath:(NSString *)path;\n\n@property (nonatomic, readonly, assign) BOOL didFailToParse;\n\n@end\n\n/**\n * The delegate protocol for NICSSParser.\n */\n@protocol NICSSParserDelegate <NSObject>\n@required\n\n/**\n * The implementor may use this method to change the filename that will be used to load\n * the CSS file from disk.\n *\n * If nil is returned then the given filename will be used.\n *\n * Example:\n * This is used by the Chameleon observer to hash filenames with md5, effectively flattening\n * the path structure so that the files can be accessed without creating subdirectories.\n */\n- (NSString *)cssParser:(NICSSParser *)parser pathFromPath:(NSString *)path;\n\n@end\n\n/**\n * Reads a CSS file from a given path and returns a dictionary of raw CSS rule sets.\n *\n * If a pathPrefix is provided then all paths will be prefixed with this value.\n *\n * For example, if a path prefix of \"/bundle/css\" is given and a CSS file has the\n * statement \"@import url('user/profile.css')\", the loaded file will be\n * \"/bundle/css/user/profile.css\".\n *\n * @fn NICSSParser::dictionaryForPath:pathPrefix:delegate:\n * @param path         The path of the file to be read.\n * @param pathPrefix   [optional] A prefix path that will be prepended to the given path\n *                          as well as any imported files.\n * @param delegate     [optional] A delegate that can reprocess paths.\n * @returns A dictionary mapping CSS scopes to dictionaries of property names to values.\n */\n\n/**\n * @fn NICSSParser::dictionaryForPath:pathPrefix:\n * @sa NICSSParser::dictionaryForPath:pathPrefix:delegate:\n */\n\n/**\n * @fn NICSSParser::dictionaryForPath:\n * @sa NICSSParser::dictionaryForPath:pathPrefix:delegate:\n */\n\n/**\n * Will be YES after retrieving a dictionary if the parser failed to parse the file in any way.\n *\n * @fn NICSSParser::didFailToParse\n */\n"
  },
  {
    "path": "src/css/src/NICSSParser.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICSSParser.h\"\n\n#import \"CSSTokens.h\"\n#import \"NimbusCore.h\"\n\n#import <pthread.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic pthread_mutex_t gMutex = PTHREAD_MUTEX_INITIALIZER;\nNSString* const kPropertyOrderKey = @\"__kRuleSetOrder__\";\nNSString* const kDependenciesSelectorKey = @\"__kDependencies__\";\n\n// Damn you, flex. Due to the nature of flex we can only have one active parser at any given time.\nNICSSParser* gActiveParser = nil;\n\nint cssConsume(char* text, int token);\n@interface NICSSParser()\n- (void)consumeToken:(int)token text:(char*)text;\n@end\n\n// The entry point of the flex css parser.\n// Flex is inherently designed to operate as a singleton.\nint cssConsume(char* text, int token) {\n  [gActiveParser consumeToken:token text:text];\n  return 0;\n}\n\n@implementation NICSSParser\n\n\n\n- (void)shutdown {\n  _rulesets = nil;\n  _scopesForActiveRuleset = nil;\n  _mutatingScope = nil;\n  _mutatingRuleset = nil;\n  _currentPropertyName = nil;\n  _importedFilenames = nil;\n  _lastTokenText = nil;\n}\n\n- (void)setFailFlag {\n  if (!self.didFailToParse) {\n    _didFailToParse = YES;\n\n    [self shutdown];\n  }\n}\n\n- (void)commitCurrentSelector {\n  [_scopesForActiveRuleset addObject:[_mutatingScope componentsJoinedByString:@\" \"]];\n  [_mutatingScope removeAllObjects];\n}\n\n- (void)consumeToken:(int)token text:(char*)text {\n  if (_didFailToParse) {\n    return;\n  }\n\n  NSString* textAsString = [[NSString alloc] initWithCString:text encoding:NSUTF8StringEncoding];\n  NSString* lowercaseTextAsString = [textAsString lowercaseString];\n\n  switch (token) {\n    case CSSMEDIA: // @media { }\n      if (_state.Flags.InsideMedia || _state.Flags.ReadingMedia) {\n        [self setFailFlag];\n      }\n      _state.Flags.ReadingMedia = YES;\n      droppingCurrentRules = YES; // at least one must match to undo this\n      break;\n    case CSSHASH: // #{name}\n    case CSSIDENT: { // {ident}(:{ident})?\n\n      if (_state.Flags.ReadingMedia) {\n        if (!droppingCurrentRules) {\n          // No point in running these checks if we've already decided\n          break;\n        } else if ([textAsString caseInsensitiveCompare:@\"ipad\"] == NSOrderedSame) {\n          if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { droppingCurrentRules = NO; }\n          break;\n        } else if ([textAsString caseInsensitiveCompare:@\"iphone\"] == NSOrderedSame) {\n          if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) { droppingCurrentRules = NO; }\n          break;\n        } else if ([textAsString caseInsensitiveCompare:@\"retina\"] == NSOrderedSame) {\n          if ([UIScreen mainScreen].scale != 1.0) { droppingCurrentRules = NO; }\n          break;\n        } else if ([textAsString caseInsensitiveCompare:@\"nonretina\"] == NSOrderedSame) {\n          if ([UIScreen mainScreen].scale == 1.0) { droppingCurrentRules = NO; }\n          break;\n        } else if ([textAsString caseInsensitiveCompare:@\"ipad-retina\"] == NSOrderedSame) {\n          if ([UIScreen mainScreen].scale != 1.0 && [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { droppingCurrentRules = NO; }\n          break;\n        } else if ([textAsString caseInsensitiveCompare:@\"ipad-nonretina\"] == NSOrderedSame) {\n          if ([UIScreen mainScreen].scale == 1.0 && [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { droppingCurrentRules = NO; }\n          break;\n        } else if ([textAsString caseInsensitiveCompare:@\"iphone-retina\"] == NSOrderedSame) {\n          if ([UIScreen mainScreen].scale != 1.0 && [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) { droppingCurrentRules = NO; }\n          break;\n        } else if ([textAsString caseInsensitiveCompare:@\"iphone-nonretina\"] == NSOrderedSame) {\n          if ([UIScreen mainScreen].scale == 1.0 && [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) { droppingCurrentRules = NO; }\n          break;\n        }\n      }\n      else if (_state.Flags.InsideRuleset) {\n        NIDASSERT(nil != _mutatingRuleset);\n        if (nil == _mutatingRuleset) {\n          [self setFailFlag];\n        }\n\n        // Treat CSSIDENT as a new property if we're not already defining one.\n        if (CSSIDENT == token && !_state.Flags.InsideProperty) {\n          // Properties are case insensitive.\n          _currentPropertyName = lowercaseTextAsString;\n          \n          NSMutableArray* ruleSetOrder = [_mutatingRuleset objectForKey:kPropertyOrderKey];\n          [ruleSetOrder addObject:_currentPropertyName];\n\n          // Clear any existing values for the given property.\n          NSMutableArray* values = [[NSMutableArray alloc] init];\n          [_mutatingRuleset setObject:values forKey:_currentPropertyName];\n\n        } else {\n          // This is a value for the active property; add it.\n          NIDASSERT(nil != _currentPropertyName);\n\n          if (nil != _currentPropertyName) {\n            NSMutableArray* values = [_mutatingRuleset objectForKey:_currentPropertyName];\n            [values addObject:lowercaseTextAsString];\n\n          } else {\n            [self setFailFlag];\n          }\n        }\n\n      } else { // if not inside a rule set...\n        [_mutatingScope addObject:textAsString];\n\n        // Ensure that we're not modifying a property.\n        _currentPropertyName = nil;\n      }\n      break;\n    }\n\n    case CSSFUNCTION: {\n      // Functions can only exist within properties.\n      if (_state.Flags.InsideProperty) {\n        _state.Flags.InsideFunction = YES;\n\n        NIDASSERT(nil != _currentPropertyName);\n        if (nil != _currentPropertyName) {\n          NSMutableArray* values = [_mutatingRuleset objectForKey:_currentPropertyName];\n          [values addObject:lowercaseTextAsString];\n\n        } else {\n          [self setFailFlag];\n        }\n      }\n      break;\n    }\n\n    case CSSSTRING:\n    case CSSEMS:\n    case CSSEXS:\n    case CSSLENGTH:\n    case CSSANGLE:\n    case CSSTIME:\n    case CSSFREQ:\n    case CSSDIMEN:\n    case CSSPERCENTAGE:\n    case CSSNUMBER:\n    case CSSURI: {\n      if (_lastToken == CSSIMPORT && token == CSSURI) {\n        NSInteger prefixLength = @\"url(\\\"\".length;\n        NSString* filename = [textAsString substringWithRange:NSMakeRange(prefixLength,\n                                                                          textAsString.length\n                                                                          - prefixLength - 2)];\n        [_importedFilenames addObject:filename];\n\n      } else {\n        NIDASSERT(nil != _currentPropertyName);\n\n        if (nil != _currentPropertyName) {\n          NSMutableArray* values = [_mutatingRuleset objectForKey:_currentPropertyName];\n          [values addObject:textAsString];\n\n        } else {\n          [self setFailFlag];\n        }\n      }\n      break;\n    }\n\n    // Parse individual characters.\n    case CSSUNKNOWN: {\n      switch (text[0]) {\n\n        // Commit the current selector and start a new one.\n        case ',': {\n          if (_state.Flags.ReadingMedia) {\n            // Ignore, more media coming\n          } else if (!_state.Flags.InsideRuleset) {\n            [self commitCurrentSelector];\n          }\n          break;\n        }\n\n        // Start a new rule set.\n        case '{': {\n          if (_state.Flags.ReadingMedia) {\n            _state.Flags.InsideMedia = YES;\n            _state.Flags.ReadingMedia = NO;\n            break;\n          }\n          NIDASSERT(nil != _mutatingScope);\n          if ([_mutatingScope count] > 0\n              && !_state.Flags.InsideRuleset && !_state.Flags.InsideFunction) {\n            [self commitCurrentSelector];\n\n            _state.Flags.InsideRuleset = YES;\n            _state.Flags.InsideFunction = NO;\n\n            _mutatingRuleset = [[NSMutableDictionary alloc] init];\n            [_mutatingRuleset setObject:[NSMutableArray array] forKey:kPropertyOrderKey];\n\n          } else {\n            [self setFailFlag];\n          }\n          break;\n        }\n\n        // Commit an existing rule set.\n        case '}': {\n          \n          if (_state.Flags.InsideMedia && !_mutatingRuleset) {\n            // End of a media tag\n            _state.Flags.InsideMedia = NO;\n            droppingCurrentRules = NO;\n          } else {\n            if (!droppingCurrentRules) {\n              for (NSString* name in _scopesForActiveRuleset) {\n                NSMutableDictionary* existingProperties = [_rulesets objectForKey:name];\n                \n                if (nil == existingProperties) {\n                  NSMutableDictionary* ruleSet = [_mutatingRuleset mutableCopy];\n                  [_rulesets setObject:ruleSet forKey:name];\n                  \n                } else {\n                  // Properties already exist, so overwrite them.\n                  // Merge the orders.\n                  {\n                    NSMutableArray* order = [existingProperties objectForKey:kPropertyOrderKey];\n                    [order addObjectsFromArray:[_mutatingRuleset objectForKey:kPropertyOrderKey]];\n                    [_mutatingRuleset setObject:order forKey:kPropertyOrderKey];\n                  }\n                  \n                  for (NSString* key in _mutatingRuleset) {\n                    [existingProperties setObject:[_mutatingRuleset objectForKey:key] forKey:key];\n                  }\n                  // Add the order of the new properties.\n                  NSMutableArray* order = [existingProperties objectForKey:kPropertyOrderKey];\n                  [order addObjectsFromArray:[_mutatingRuleset objectForKey:kPropertyOrderKey]];\n                }\n              }\n            }\n            \n          _mutatingRuleset = nil;\n          [_scopesForActiveRuleset removeAllObjects];\n          _state.Flags.InsideRuleset = NO;\n          _state.Flags.InsideProperty = NO;\n          _state.Flags.InsideFunction = NO;\n          }\n          break;\n        }\n\n        case ':': {\n          // Defining a property value.\n          if (_state.Flags.InsideRuleset) {\n            _state.Flags.InsideProperty = YES;\n          }\n          break;\n        }\n\n        case ')': {\n          if (_state.Flags.InsideFunction && nil != _currentPropertyName) {\n            NSMutableArray* values = [_mutatingRuleset objectForKey:_currentPropertyName];\n            [values addObject:lowercaseTextAsString];\n          }\n          _state.Flags.InsideFunction = NO;\n          break;\n        }\n\n        case ';': {\n          // Committing a property value.\n          if (_state.Flags.InsideRuleset) {\n            _state.Flags.InsideProperty = NO;\n          }\n          break;\n        }\n      }\n      break;\n    }\n  }\n\n  _lastTokenText = textAsString;\n  _lastToken = token;\n}\n\n- (void)setup {\n  [self shutdown];\n\n  _rulesets = [[NSMutableDictionary alloc] init];\n  _scopesForActiveRuleset = [[NSMutableArray alloc] init];\n  _mutatingScope = [[NSMutableArray alloc] init];\n  _importedFilenames = [[NSMutableArray alloc] init];\n}\n\n- (void)parseFileAtPath:(NSString *)path {\n  // flex is not thread-safe so we force it to be by creating a single-access lock here.\n  pthread_mutex_lock(&gMutex); {\n    cssin = fopen([path UTF8String], \"r\");\n    gActiveParser = self;\n    csslex();\n    fclose(cssin);\n  }\n  pthread_mutex_unlock(&gMutex);\n}\n\n- (NSDictionary *)mergeCompositeRulesets:(NSMutableArray *)compositeRulesets dependencyFilenames:(NSSet *)dependencyFilenames {\n  NIDASSERT([compositeRulesets count] > 0);\n  if ([compositeRulesets count] == 0) {\n    return nil;\n  }\n\n  NSDictionary* result = nil;\n\n  if ([compositeRulesets count] == 1) {\n    if ([dependencyFilenames count] > 0) {\n      [[compositeRulesets objectAtIndex:0] setObject:dependencyFilenames\n                                              forKey:kDependenciesSelectorKey];\n    }\n    result = [[compositeRulesets objectAtIndex:0] copy];\n\n  } else {\n    NSMutableDictionary* mergedResult = [compositeRulesets lastObject];\n    [compositeRulesets removeLastObject];\n\n    // Merge all of the rulesets into one.\n    for (NSDictionary* ruleSet in [compositeRulesets reverseObjectEnumerator]) {\n      for (NSString* scope in ruleSet) {\n        if (![mergedResult objectForKey:scope]) {\n          // New scope means we can just add it.\n          [mergedResult setObject:[ruleSet objectForKey:scope] forKey:scope];\n\n        } else {\n          // Existing scope means we need to overwrite existing properties.\n          NSMutableDictionary* mergedScopeProperties = [mergedResult objectForKey:scope];\n          NSMutableDictionary* properties = [ruleSet objectForKey:scope];\n\n          for (NSString* propertyName in properties) {\n\n            if (!(nil != [mergedScopeProperties objectForKey:propertyName]\n                  && [propertyName isEqualToString:kPropertyOrderKey])) {\n              // Overwrite the existing property's value.\n              [mergedScopeProperties setObject:[properties objectForKey:propertyName]\n                                        forKey:propertyName];\n\n            } else {\n              // Append the property order.\n              NSMutableArray *order = [mergedScopeProperties objectForKey:kPropertyOrderKey];\n              [order addObjectsFromArray:[properties objectForKey:kPropertyOrderKey]];\n            }\n          }\n        }\n      }\n    }\n    \n    if ([dependencyFilenames count] > 0) {\n      [mergedResult setObject:dependencyFilenames forKey:kDependenciesSelectorKey];\n    }\n    result = [mergedResult copy];\n  }\n\n  return result;\n}\n\n#pragma mark - Public\n\n\n- (NSDictionary *)dictionaryForPath:(NSString *)path {\n  return [self dictionaryForPath:path pathPrefix:nil delegate:nil];\n}\n\n- (NSDictionary *)dictionaryForPath:(NSString *)path pathPrefix:(NSString *)pathPrefix {\n  return [self dictionaryForPath:path pathPrefix:pathPrefix delegate:nil];\n}\n\n- (NSDictionary *)dictionaryForPath:(NSString *)aPath\n                         pathPrefix:(NSString *)pathPrefix\n                           delegate:(id<NICSSParserDelegate>)delegate {\n  // Bail out early if there was no path given.\n  if ([aPath length] == 0) {\n    _didFailToParse = YES;\n    return nil;\n  }\n\n  _didFailToParse = NO;\n\n  NSMutableArray* compositeRulesets = [[NSMutableArray alloc] init];\n\n  // Maintain a set of filenames that we've looked at for two reasons:\n  // 1) To avoid visiting the same CSS file twice.\n  // 2) To collect a list of dependencies for this stylesheet.\n  NSMutableSet* processedFilenames = [[NSMutableSet alloc] init];\n\n  // Imported CSS files will be added to the queue.\n  NSMutableOrderedSet* filenameQueue = [NSMutableOrderedSet orderedSet];\n  [filenameQueue addObject:aPath];\n\n  while ([filenameQueue count] > 0) {\n    // Om nom nom\n    NSString* path = [filenameQueue firstObject];\n    [filenameQueue removeObjectAtIndex:0];\n\n    // Skip files that we've already processed in order to avoid infinite loops.\n    if ([processedFilenames containsObject:path]) {\n      continue;\n    }\n    [processedFilenames addObject:path];\n\n    // Allow the delegate to rename the file.\n    if ([delegate respondsToSelector:@selector(cssParser:pathFromPath:)]) {\n      NSString* reprocessedFilename = [delegate cssParser:self pathFromPath:path];\n      if (nil != reprocessedFilename) {\n        path = reprocessedFilename;\n      }\n    }\n\n    // Add the prefix, if it exists.\n    if (pathPrefix.length > 0) {\n      path = [pathPrefix stringByAppendingPathComponent:path];\n    }\n\n    // Verify that the file exists.\n    if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {\n      [self shutdown];\n      return nil;\n    }\n\n    [self setup];\n    [self parseFileAtPath:path];\n    if (self.didFailToParse) {\n      break;\n    }\n\n    [filenameQueue addObjectsFromArray:_importedFilenames];\n    [_importedFilenames removeAllObjects];\n\n    [compositeRulesets addObject:_rulesets];\n    [self shutdown];\n  }\n\n  NSDictionary* result = nil;\n\n  if (!self.didFailToParse) {\n    // processedFilenames will be the set of dependencies, so remove the initial path.\n    [processedFilenames removeObject:aPath];\n\n    result = [self mergeCompositeRulesets:compositeRulesets\n                      dependencyFilenames:processedFilenames];\n\n  }\n\n  [self shutdown];\n\n  return result;\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/NICSSRuleset.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n/**\n * Currently, for size units we only support pixels (resolution independent)\n * and percentage (of superview)\n */\ntypedef enum {\n\tCSS_PIXEL_UNIT,\n\tCSS_PERCENTAGE_UNIT,\n  CSS_AUTO_UNIT\n} NICSSUnitType;\n\n/**\n * Width, height, top, left, right, bottom can be expressed in various units.\n */\ntypedef struct {\n\tNICSSUnitType type;\n\tCGFloat value;\n} NICSSUnit;\n\ntypedef enum {\n  NICSSButtonAdjustNone = 0,\n  NICSSButtonAdjustHighlighted = 1,\n  NICSSButtonAdjustDisabled = 2\n} NICSSButtonAdjust;\n\n/**\n * A simple translator from raw CSS rulesets to Objective-C values.\n *\n * @ingroup NimbusCSS\n *\n * Objective-C values are created on-demand and cached. These ruleset objects are cached\n * by NIStylesheet for a given CSS scope. When a memory warning is received, all ruleset objects\n * are removed from every stylesheet.\n */\n@interface NICSSRuleset : NSObject {\n@private\n  NSMutableDictionary* _ruleset;\n  \n  UIColor* _textColor;\n  UIColor* _highlightedTextColor;\n  NSTextAlignment _textAlignment;\n  UIFont* _font;\n  UIColor* _textShadowColor;\n  CGSize _textShadowOffset;\n  NSLineBreakMode _lineBreakMode;\n  NSInteger _numberOfLines;\n  CGFloat _minimumFontSize;\n  BOOL _adjustsFontSize;\n  UIBaselineAdjustment _baselineAdjustment;\n  CGFloat _opacity;\n  UIColor* _backgroundColor;\n  NSString* _backgroundImage;\n  UIEdgeInsets _backgroundStretchInsets;\n  NSString* _image;\n  CGFloat _borderRadius;\n  UIColor *_borderColor;\n  CGFloat _borderWidth;\n  UIColor *_tintColor;\n  UIActivityIndicatorViewStyle _activityIndicatorStyle;\n  UIViewAutoresizing _autoresizing;\n  UITableViewCellSeparatorStyle _tableViewCellSeparatorStyle;\n  UIScrollViewIndicatorStyle _scrollViewIndicatorStyle;\n  NSTextAlignment _frameHorizontalAlign;\n  UIViewContentMode _frameVerticalAlign;\n  UIControlContentVerticalAlignment _verticalAlign;\n  UIControlContentHorizontalAlignment _horizontalAlign;\n  BOOL _visible;\n  NICSSButtonAdjust _buttonAdjust;\n  UIEdgeInsets _titleInsets;\n  UIEdgeInsets _contentInsets;\n  UIEdgeInsets _imageInsets;\n  NSString *_textKey;\n  NSString* _relativeToId;\n  NICSSUnit _marginTop;\n  NICSSUnit _marginLeft;\n  NICSSUnit _marginRight;\n  NICSSUnit _marginBottom;\n  NICSSUnit _width;\n  NICSSUnit _height;\n  NICSSUnit _top;\n  NICSSUnit _bottom;\n  NICSSUnit _left;\n  NICSSUnit _right;\n  NICSSUnit _minHeight;\n  NICSSUnit _minWidth;\n  NICSSUnit _maxHeight;\n  NICSSUnit _maxWidth;\n  \n  union {\n    struct {\n      int TextColor : 1;\n      int HighlightedTextColor: 1;\n      int TextAlignment : 1;\n      int Font : 1;\n      int TextShadowColor : 1;\n      int TextShadowOffset : 1;\n      int LineBreakMode : 1;\n      int NumberOfLines : 1;\n      int MinimumFontSize : 1;\n      int AdjustsFontSize : 1;\n      int BaselineAdjustment : 1;\n      int Opacity : 1;\n      int BackgroundColor : 1;\n      int BackgroundImage: 1;\n      int BackgroundStretchInsets: 1;\n      //16\n      int Image: 1;\n      int BorderRadius : 1;\n      int BorderColor : 1;\n      int BorderWidth : 1;\n      int TintColor : 1;\n      int ActivityIndicatorStyle : 1;\n      int Autoresizing : 1;\n      int TableViewCellSeparatorStyle : 1;\n      int ScrollViewIndicatorStyle : 1;\n      int VerticalAlign: 1;\n      int HorizontalAlign: 1;\n      int Width : 1;\n      int Height : 1;\n      int Top : 1;\n      int Bottom : 1;\n      int Left : 1;\n      // 32\n      int Right : 1;\n      int FrameHorizontalAlign: 1;\n      int FrameVerticalAlign: 1;\n      int Visible: 1;\n      int TitleInsets: 1;\n      int ContentInsets: 1;\n      int ImageInsets: 1;\n      int RelativeToId: 1;\n      int MarginTop: 1;\n      int MarginLeft: 1;\n      int MarginRight: 1;\n      int MarginBottom: 1;\n      int MinWidth: 1;\n      int MinHeight: 1;\n      int MaxWidth: 1;\n      int MaxHeight: 1;\n      // 48\n      int TextKey: 1;\n      int ButtonAdjust: 1;\n      int HorizontalPadding: 1;\n      int VerticalPadding: 1;\n    } cached;\n    int64_t _data;\n  } _is;\n}\n\n- (void)addEntriesFromDictionary:(NSDictionary *)dictionary;\n- (id)cssRuleForKey: (NSString*)key;\n\n- (BOOL)hasTextColor;\n- (UIColor *)textColor; // color\n\n- (BOOL)hasHighlightedTextColor;\n- (UIColor *)highlightedTextColor;\n\n- (BOOL)hasTextAlignment;\n- (NSTextAlignment)textAlignment; // text-align\n\n- (BOOL)hasFont;\n- (UIFont *)font; // font, font-family, font-size, font-style, font-weight\n\n- (BOOL)hasTextShadowColor;\n- (UIColor *)textShadowColor; // text-shadow\n\n- (BOOL)hasTextShadowOffset;\n- (CGSize)textShadowOffset; // text-shadow\n\n- (BOOL)hasLineBreakMode;\n- (NSLineBreakMode)lineBreakMode; // -ios-line-break-mode\n\n- (BOOL)hasNumberOfLines;\n- (NSInteger)numberOfLines; // -ios-number-of-lines\n\n- (BOOL)hasMinimumFontSize;\n- (CGFloat)minimumFontSize; // -ios-minimum-font-size\n\n- (BOOL)hasAdjustsFontSize;\n- (BOOL)adjustsFontSize; // -ios-adjusts-font-size\n\n- (BOOL)hasBaselineAdjustment;\n- (UIBaselineAdjustment)baselineAdjustment; // -ios-baseline-adjustment\n\n- (BOOL)hasOpacity;\n- (CGFloat)opacity; // opacity\n\n- (BOOL)hasBackgroundColor;\n- (UIColor *)backgroundColor; // background-color\n\n- (BOOL)hasBackgroundImage;\n- (NSString*)backgroundImage; // background-image\n\n- (BOOL)hasBackgroundStretchInsets;\n- (UIEdgeInsets)backgroundStretchInsets; // -mobile-background-stretch\n\n- (BOOL)hasImage;\n- (NSString*)image; // -mobile-image\n\n- (BOOL)hasBorderRadius;\n- (CGFloat)borderRadius; // border-radius\n\n- (BOOL)hasBorderColor;\n- (UIColor *)borderColor; // border, border-color\n\n- (BOOL)hasBorderWidth;\n- (CGFloat)borderWidth; // border, border-width\n\n- (BOOL)hasWidth;\n- (NICSSUnit)width; // width\n\n- (BOOL)hasHeight;\n- (NICSSUnit)height; // height\n\n- (BOOL)hasTop;\n- (NICSSUnit)top; // top\n\n- (BOOL)hasBottom;\n- (NICSSUnit)bottom; // bottom\n\n- (BOOL)hasLeft;\n- (NICSSUnit)left; // left\n\n- (BOOL)hasRight;\n- (NICSSUnit)right; // right\n\n- (BOOL)hasMinWidth;\n- (NICSSUnit)minWidth; // min-width\n\n- (BOOL)hasMinHeight;\n- (NICSSUnit)minHeight; // min-height\n\n- (BOOL)hasMaxWidth;\n- (NICSSUnit)maxWidth; // max-width\n\n- (BOOL)hasMaxHeight;\n- (NICSSUnit)maxHeight; // max-height\n\n- (BOOL)hasVerticalAlign;\n- (UIControlContentVerticalAlignment)verticalAlign; // -mobile-content-valign\n\n- (BOOL)hasHorizontalAlign;\n- (UIControlContentHorizontalAlignment)horizontalAlign; // -mobile-content-halign\n\n- (BOOL)hasFrameHorizontalAlign;\n- (NSTextAlignment)frameHorizontalAlign; // -mobile-halign\n\n- (BOOL)hasFrameVerticalAlign;\n- (UIViewContentMode)frameVerticalAlign; // -mobile-valign\n\n- (BOOL)hasTintColor;\n- (UIColor *)tintColor; // -ios-tint-color\n\n- (BOOL)hasActivityIndicatorStyle;\n- (UIActivityIndicatorViewStyle)activityIndicatorStyle; // -ios-activity-indicator-style\n\n- (BOOL)hasAutoresizing;\n- (UIViewAutoresizing)autoresizing; // -ios-autoresizing\n\n- (BOOL)hasTableViewCellSeparatorStyle;\n- (UITableViewCellSeparatorStyle)tableViewCellSeparatorStyle; // -ios-table-view-cell-separator-style\n\n- (BOOL)hasScrollViewIndicatorStyle;\n- (UIScrollViewIndicatorStyle)scrollViewIndicatorStyle; // -ios-scroll-view-indicator-style\n\n- (BOOL)hasVisible;\n- (BOOL)visible; // visibility\n\n- (BOOL)hasButtonAdjust;\n- (NICSSButtonAdjust)buttonAdjust; // -ios-button-adjust\n\n- (BOOL)hasTitleInsets;\n- (UIEdgeInsets)titleInsets; // -mobile-title-insets\n\n- (BOOL)hasContentInsets;\n- (UIEdgeInsets)contentInsets; // -mobile-content-insets\n\n- (BOOL)hasImageInsets;\n- (UIEdgeInsets)imageInsets; // -mobile-image-insets\n\n- (BOOL)hasRelativeToId;\n- (NSString*)relativeToId; // -mobile-relative\n\n- (BOOL)hasMarginTop;\n- (NICSSUnit)marginTop; // margin-top\n\n- (BOOL)hasMarginBottom;\n- (NICSSUnit)marginBottom; // margin-bottom\n\n- (BOOL)hasMarginLeft;\n- (NICSSUnit)marginLeft; // margin-left\n\n- (BOOL)hasMarginRight;\n- (NICSSUnit)marginRight; // margin-bottom\n\n- (BOOL)hasTextKey;\n- (NSString*)textKey; // -mobile-text-key\n\n- (BOOL) hasHorizontalPadding;\n- (NICSSUnit) horizontalPadding; // padding or -mobile-hPadding\n\n- (BOOL) hasVerticalPadding;\n- (NICSSUnit) verticalPadding; // padding or -mobile-vPadding\n@end\n\n/**\n * Adds a raw CSS ruleset to this ruleset object.\n *\n * @fn NICSSRuleset::addEntriesFromDictionary:\n */\n\n/**\n * Returns YES if the ruleset has a 'color' property.\n *\n * @fn NICSSRuleset::hasTextColor\n */\n\n/**\n * Returns the text color.\n *\n * @fn NICSSRuleset::textColor\n */\n\n/**\n * Returns YES if the ruleset has a 'text-align' property.\n *\n * @fn NICSSRuleset::hasTextAlignment\n */\n\n/**\n * Returns the text alignment.\n *\n * @fn NICSSRuleset::textAlignment\n */\n\n/**\n * Returns YES if the ruleset has a value for any of the following properties:\n * font, font-family, font-size, font-style, font-weight.\n *\n * Note: You can't specify bold or italic with a font-family due to the way fonts are\n * constructed. You also can't specify a font that is both bold and italic. In order to do\n * either of these things you must specify the font-family that corresponds to the bold or italic\n * version of your font.\n *\n * @fn NICSSRuleset::hasFont\n */\n\n/**\n * Returns the font.\n *\n * @fn NICSSRuleset::font\n */\n\n/**\n * Returns YES if the ruleset has a 'text-shadow' property.\n *\n * @fn NICSSRuleset::hasTextShadowColor\n */\n\n/**\n * Returns the text shadow color.\n *\n * @fn NICSSRuleset::textShadowColor\n */\n\n/**\n * Returns YES if the ruleset has a 'text-shadow' property.\n *\n * @fn NICSSRuleset::hasTextShadowOffset\n */\n\n/**\n * Returns the text shadow offset.\n *\n * @fn NICSSRuleset::textShadowOffset\n */\n\n/**\n * Returns YES if the ruleset has an '-ios-line-break-mode' property.\n *\n * @fn NICSSRuleset::hasLineBreakMode\n */\n\n/**\n * Returns the line break mode.\n *\n * @fn NICSSRuleset::lineBreakMode\n */\n\n/**\n * Returns YES if the ruleset has an '-ios-number-of-lines' property.\n *\n * @fn NICSSRuleset::hasNumberOfLines\n */\n\n/**\n * Returns the number of lines.\n *\n * @fn NICSSRuleset::numberOfLines\n */\n\n/**\n * Returns YES if the ruleset has an '-ios-minimum-font-size' property.\n *\n * @fn NICSSRuleset::hasMinimumFontSize\n */\n\n/**\n * Returns the minimum font size.\n *\n * @fn NICSSRuleset::minimumFontSize\n */\n\n/**\n * Returns YES if the ruleset has an '-ios-adjusts-font-size' property.\n *\n * @fn NICSSRuleset::hasAdjustsFontSize\n */\n\n/**\n * Returns the adjustsFontSize value.\n *\n * @fn NICSSRuleset::adjustsFontSize\n */\n\n/**\n * Returns YES if the ruleset has an '-ios-baseline-adjustment' property.\n *\n * @fn NICSSRuleset::hasBaselineAdjustment\n */\n\n/**\n * Returns the baseline adjustment.\n *\n * @fn NICSSRuleset::baselineAdjustment\n */\n\n/**\n * Returns YES if the ruleset has an 'opacity' property.\n *\n * @fn NICSSRuleset::hasOpacity\n */\n\n/**\n * Returns the opacity.\n *\n * @fn NICSSRuleset::opacity\n */\n\n/**\n * Returns YES if the ruleset has a 'background-color' property.\n *\n * @fn NICSSRuleset::hasBackgroundColor\n */\n\n/**\n * Returns the background color.\n *\n * @fn NICSSRuleset::backgroundColor\n */\n\n/**\n * Returns YES if the ruleset has a 'border-radius' property.\n *\n * @fn NICSSRuleset::hasBorderRadius\n */\n\n/**\n * Returns the border radius.\n *\n * @fn NICSSRuleset::borderRadius\n */\n\n/**\n * Returns YES if the ruleset has a 'border' or 'border-color' property.\n *\n * @fn NICSSRuleset::hasBorderColor\n */\n\n/**\n * Returns the border color.\n *\n * @fn NICSSRuleset::borderColor\n */\n\n/**\n * Returns YES if the ruleset has a 'border' or 'border-width' property.\n *\n * @fn NICSSRuleset::hasBorderWidth\n */\n\n/**\n * Returns the border width.\n *\n * @fn NICSSRuleset::borderWidth\n */\n\n/**\n * Returns YES if the ruleset has an '-ios-tint-color' property.\n *\n * @fn NICSSRuleset::hasTintColor\n */\n\n/**\n * Returns the tint color.\n *\n * @fn NICSSRuleset::tintColor\n */\n\n/**\n * Returns YES if the ruleset has a 'width' property.\n *\n * @fn NICSSRuleset::hasWidth\n */\n\n/**\n * Returns the width.\n *\n * @fn NICSSRuleset::width\n */\n\n/**\n * When relativeToId is set, a view will be positioned using margin-* directives relative to the view\n * identified by relativeToId. You can use id notation, e.g. #MyButton, or a few selectors:\n * .next, .prev, .first and .last which find the obviously named siblings. Note that the mechanics or\n * margin are not the same as CSS, which is of course a flow layout. So you cannot, for example,\n * combine margin-top and margin-bottom as only margin-top will be executed.\n *\n * Relative positioning also requires that you're careful about the order in which you register views\n * in the engine (for now), since we will evaluate the rules immediately. TODO add some simple dependency\n * management to make sure we've run the right views first.\n *\n * @fn NICSSRuleset::relativeToId\n */\n\n/**\n * In combination with relativeToId, the margin fields control how a view is positioned relative to another.\n * margin-top: 0 means the top of this view will be aligned to the bottom of the view identified by relativeToId.\n * A positive number will move this further down, and a negative number further up. A *percentage* will operate\n * off the height of relativeToId and modify the position relative to margin-top:0. So -100% means \"align top\".\n * A value of auto means we will align the center y of relativeToId with the center y of this view.\n *\n * @fn NICSSRuleset::margin-top\n */\n\n/**\n * In combination with relativeToId, the margin fields control how a view is positioned relative to another.\n * margin-bottom: 0 means the bottom of this view will be aligned to the bottom of the view identified by relativeToId.\n * A positive number will move this further down, and a negative number further up. A *percentage* will operate\n * off the height of relativeToId and modify the position relative to margin-bottom:0. So -100% means line up the bottom\n * of this view with the top of relativeToId.\n * A value of auto means we will align the center y of relativeToId with the center y of this view.\n *\n * @fn NICSSRuleset::margin-bottom\n */\n\n/**\n * In combination with relativeToId, the margin fields control how a view is positioned relative to another.\n * margin-left: 0 means the left of this view will be aligned to the right of the view identified by relativeToId.\n * A positive number will move this further right, and a negative number further left. A *percentage* will operate\n * off the width of relativeToId and modify the position relative to margin-left:0. So -100% means line up the left\n * of this view with the left of relativeToId.\n * A value of auto means we will align the center x of relativeToId with the center x of this view.\n *\n * @fn NICSSRuleset::margin-left\n */\n\n/**\n * In combination with relativeToId, the margin fields control how a view is positioned relative to another.\n * margin-right: 0 means the right of this view will be aligned to the right of the view identified by relativeToId.\n * A positive number will move this further right, and a negative number further left. A *percentage* will operate\n * off the width of relativeToId and modify the position relative to margin-left:0. So -100% means line up the right\n * of this view with the left of relativeToId.\n * A value of auto means we will align the center x of relativeToId with the center x of this view.\n *\n * @fn NICSSRuleset::margin-right\n */\n\n/**\n * Return the rule values for a particular key, such as margin-top or width. Exposing this allows you, among\n * other things, use the CSS to hold variable information that has an effect on the layout of the views that\n * cannot be expressed as a style - such as padding.\n *\n * @fn NICSSRuleset::cssRuleForKey\n */\n\n/**\n * For views that support sizeToFit, padding will add a value to the computed size\n *\n * @fn NICSSRuleset::horizontalPadding\n */\n\n/**\n * For views that support sizeToFit, padding will add a value to the computed size\n *\n * @fn NICSSRuleset::verticalPadding\n */\n"
  },
  {
    "path": "src/css/src/NICSSRuleset.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICSSRuleset.h\"\n\n#import \"NICSSParser.h\"\n#import \"NimbusCore.h\"\n\n// TODO selected/highlighted states for buttons\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic NSString* const kTextColorKey = @\"color\";\nstatic NSString* const kHighlightedTextColorKey = @\"-ios-highlighted-color\";\nstatic NSString* const kTextAlignmentKey = @\"text-align\";\nstatic NSString* const kFontKey = @\"font\";\nstatic NSString* const kFontSizeKey = @\"font-size\";\nstatic NSString* const kFontStyleKey = @\"font-style\";\nstatic NSString* const kFontWeightKey = @\"font-weight\";\nstatic NSString* const kFontFamilyKey = @\"font-family\";\nstatic NSString* const kTextShadowKey = @\"text-shadow\";\nstatic NSString* const kLineBreakModeKey = @\"-ios-line-break-mode\";\nstatic NSString* const kNumberOfLinesKey = @\"-ios-number-of-lines\";\nstatic NSString* const kMinimumFontSizeKey = @\"-ios-minimum-font-size\";\nstatic NSString* const kAdjustsFontSizeKey = @\"-ios-adjusts-font-size\";\nstatic NSString* const kBaselineAdjustmentKey = @\"-ios-baseline-adjustment\";\nstatic NSString* const kOpacityKey = @\"opacity\";\nstatic NSString* const kBackgroundColorKey = @\"background-color\";\nstatic NSString* const kBorderRadiusKey = @\"border-radius\";\nstatic NSString* const kBorderKey = @\"border\";\nstatic NSString* const kBorderColorKey = @\"border-color\";\nstatic NSString* const kBorderWidthKey = @\"border-width\";\nstatic NSString* const kTintColorKey = @\"-ios-tint-color\";\nstatic NSString* const kActivityIndicatorStyleKey = @\"-ios-activity-indicator-style\";\nstatic NSString* const kAutoresizingKey = @\"-ios-autoresizing\";\nstatic NSString* const kTableViewCellSeparatorStyleKey = @\"-ios-table-view-cell-separator-style\";\nstatic NSString* const kScrollViewIndicatorStyleKey = @\"-ios-scroll-view-indicator-style\";\nstatic NSString* const kPaddingKey = @\"padding\";\nstatic NSString* const kHPaddingKey = @\"-mobile-hpadding\";\nstatic NSString* const kVPaddingKey = @\"-mobile-vpadding\";\n\n// This color table is generated on-demand and is released when a memory warning is encountered.\nstatic NSDictionary* sColorTable = nil;\n\n@interface NICSSRuleset()\n// Instantiates the color table if it does not already exist.\n+ (NSDictionary *)colorTable;\n+ (UIColor *)colorFromCssValues:(NSArray *)cssValues numberOfConsumedTokens:(NSInteger *)pNumberOfConsumedTokens;\n+ (NSTextAlignment)textAlignmentFromCssValues:(NSArray *)cssValues;\n@end\n\n\n// Maintain sanity with a preprocessor macro for the common cases\n#define RULE_ELEMENT(name,Name,cssKey,type,converter) \\\nstatic NSString* const k ## Name ## Key = cssKey; \\\n-(BOOL)has ## Name { \\\nreturn nil != [_ruleset objectForKey: k ## Name ## Key]; \\\n} \\\n-(type)name { \\\nNIDASSERT([self has ## Name]); \\\nif (!_is.cached.Name) { \\\n_##name = [[self class] converter:[_ruleset objectForKey:k##Name##Key]]; \\\n_is.cached.Name = YES; \\\n} \\\nreturn _##name; \\\n}\n\n@implementation NICSSRuleset\n\n\n- (void)dealloc {\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (id)init {\n  if ((self = [super init])) {\n    _ruleset = [[NSMutableDictionary alloc] init];\n\n    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];\n    [nc addObserver: self\n           selector: @selector(didReceiveMemoryWarning:)\n               name: UIApplicationDidReceiveMemoryWarningNotification\n             object: nil];\n  }\n  return self;\n}\n\n#pragma mark - Public\n\n\n- (void)addEntriesFromDictionary:(NSDictionary *)dictionary {\n  NSMutableArray* order = [_ruleset objectForKey:kPropertyOrderKey];\n  [_ruleset addEntriesFromDictionary:dictionary];\n\n  if (nil != order) {\n    [order addObjectsFromArray:[dictionary objectForKey:kPropertyOrderKey]];\n    [_ruleset setObject:order forKey:kPropertyOrderKey];\n  }\n}\n\n-(id)cssRuleForKey:(NSString *)key\n{\n    return [_ruleset objectForKey:key];\n}\n\n- (BOOL)hasTextColor {\n  return nil != [_ruleset objectForKey:kTextColorKey];\n}\n\n- (UIColor *)textColor {\n  NIDASSERT([self hasTextColor]);\n  if (!_is.cached.TextColor) {\n    _textColor = [[self class] colorFromCssValues:[_ruleset objectForKey:kTextColorKey]\n                           numberOfConsumedTokens:nil];\n    _is.cached.TextColor = YES;\n  }\n  return _textColor;\n}\n\n- (BOOL)hasHighlightedTextColor {\n    return nil != [_ruleset objectForKey:kHighlightedTextColorKey];\n}\n\n- (UIColor *)highlightedTextColor {\n  NIDASSERT([self hasHighlightedTextColor]);\n  if (!_is.cached.HighlightedTextColor) {\n    _highlightedTextColor = [[self class] colorFromCssValues:[_ruleset objectForKey:kHighlightedTextColorKey]\n                                      numberOfConsumedTokens:nil];\n    _is.cached.HighlightedTextColor = YES;\n  }\n  return _highlightedTextColor;\n}\n\n- (BOOL)hasTextAlignment {\n  return nil != [_ruleset objectForKey:kTextAlignmentKey];\n}\n\n- (NSTextAlignment)textAlignment {\n  NIDASSERT([self hasTextAlignment]);\n  if (!_is.cached.TextAlignment) {\n    _textAlignment = [[self class] textAlignmentFromCssValues:[_ruleset objectForKey:kTextAlignmentKey]];\n    _is.cached.TextAlignment = YES;\n  }\n  return _textAlignment;\n}\n\n-(BOOL)hasHorizontalPadding {\n  return nil != [_ruleset objectForKey:kPaddingKey] || nil != [_ruleset objectForKey:kHPaddingKey];\n}\n\n-(NICSSUnit)horizontalPadding {\n  NIDASSERT([self hasHorizontalPadding]);\n  NSArray *css = [_ruleset objectForKey:kHPaddingKey];\n  if (css && css.count > 0) {\n    return [NICSSRuleset unitFromCssValues:css];\n  }\n  css = [_ruleset objectForKey:kPaddingKey];\n  if (css && css.count > 1) {\n    return [NICSSRuleset unitFromCssValues:css offset:1];\n  }\n  if (css && css.count == 1) {\n    return [NICSSRuleset unitFromCssValues:css];\n  } else {\n    NICSSUnit unit;\n    NIDASSERT([css count] > 0);\n    unit.type = CSS_PIXEL_UNIT;\n    unit.value = 0;\n    return unit;\n  }\n}\n\n-(BOOL)hasVerticalPadding {\n  return nil != [_ruleset objectForKey:kPaddingKey] || nil != [_ruleset objectForKey:kVPaddingKey];\n}\n\n-(NICSSUnit)verticalPadding {\n  NIDASSERT([self hasVerticalPadding]);\n  NSArray *css = [_ruleset objectForKey:kVPaddingKey];\n  if (css && css.count > 0) {\n    return [NICSSRuleset unitFromCssValues:css];\n  }\n  css = [_ruleset objectForKey:kPaddingKey];\n  if (css && css.count > 0) {\n    return [NICSSRuleset unitFromCssValues:css];\n  } else {\n    NICSSUnit unit;\n    NIDASSERT([css count] > 0);\n    unit.type = CSS_PIXEL_UNIT;\n    unit.value = 0;\n    return unit;\n  }\n}\n\n- (BOOL)hasFont {\n  return (nil != [_ruleset objectForKey:kFontKey]\n          || nil != [_ruleset objectForKey:kFontSizeKey]\n          || nil != [_ruleset objectForKey:kFontWeightKey]\n          || nil != [_ruleset objectForKey:kFontStyleKey]\n          || nil != [_ruleset objectForKey:kFontFamilyKey]);\n}\n\n- (UIFont *)font {\n  NIDASSERT([self hasFont]);\n  \n  if (_is.cached.Font) {\n    return _font;\n  }\n\n  NSString* fontName = nil;\n  CGFloat fontSize = [UIFont systemFontSize];\n  BOOL fontIsBold = NO;\n  BOOL fontIsItalic = NO;\n  \n  NSArray* values = [_ruleset objectForKey:kFontWeightKey];\n  if (nil != values) {\n    NIDASSERT([values count] == 1);\n    fontIsBold = [[values objectAtIndex:0] isEqualToString:@\"bold\"];\n  }\n  \n  values = [_ruleset objectForKey:kFontStyleKey];\n  if (nil != values) {\n    NIDASSERT([values count] == 1);\n    fontIsItalic = [[values objectAtIndex:0] isEqualToString:@\"italic\"];\n  }\n\n  // There are two ways to set font size and family: font and font-size/font-family.\n  // Newer definitions of these values should overwrite previous definitions so we must\n  // respect ordering here.\n  BOOL hasSetFontName = NO;\n  BOOL hasSetFontSize = NO;\n\n  NSArray* order = [_ruleset objectForKey:kPropertyOrderKey];\n  for (NSString* name in [order reverseObjectEnumerator]) {\n    if (!hasSetFontName && [name isEqualToString:kFontFamilyKey]) {\n      values = [_ruleset objectForKey:name];\n      NIDASSERT([values count] == 1); if ([values count] < 1) { continue; }\n      fontName = [[values objectAtIndex:0] stringByTrimmingCharactersInSet:\n                  [NSCharacterSet characterSetWithCharactersInString:@\"\\\"\"]];\n      hasSetFontName = YES;\n\n    } else if (!hasSetFontSize && [name isEqualToString:kFontSizeKey]) {\n      values = [_ruleset objectForKey:name];\n      NIDASSERT([values count] == 1); if ([values count] < 1) { continue; }\n      NSString* value = [values objectAtIndex:0];\n      if ([value isEqualToString:@\"default\"]) {\n        fontSize = [UIFont systemFontSize];\n\n      } else {\n        fontSize = [value floatValue];\n      }\n      hasSetFontSize = YES;\n\n    } else if (!hasSetFontSize && !hasSetFontName && [name isEqualToString:kFontKey]) {\n      values = [_ruleset objectForKey:name];\n      NIDASSERT([values count] <= 2); if ([values count] < 1) { continue; }\n\n      if ([values count] >= 1) {\n        // Font size\n        fontSize = [[values objectAtIndex:0] floatValue];\n        hasSetFontSize = YES;\n      }\n      if ([values count] >= 2) {\n        // Font name\n        fontName = [[values objectAtIndex:1] stringByTrimmingCharactersInSet:\n                    [NSCharacterSet characterSetWithCharactersInString:@\"\\\"\"]];\n        hasSetFontName = YES;\n      }\n    }\n\n    if (hasSetFontName && hasSetFontSize) {\n      // Once we've set all values then we can ignore any previous values.\n      break;\n    }\n  }\n  \n  UIFont* font = nil;\n  if (hasSetFontName) {\n    // If you wish to set the weight and style for a non-standard font family then you will need\n    // to set the font family to the given style manually.\n    NIDASSERT(!fontIsItalic && !fontIsBold);\n    font = [UIFont fontWithName:fontName size:fontSize];\n\n  } else if (fontIsItalic && fontIsBold) {\n    // There is no easy way to create a bold italic font using the exposed UIFont methods.\n    // Please consider using the exact font name instead. E.g. font-name: Helvetica-BoldObliquei\n    NIDASSERT(!(fontIsItalic && fontIsBold));\n    font = [UIFont systemFontOfSize:fontSize];\n\n  } else if (fontIsItalic) {\n    font = [UIFont italicSystemFontOfSize:fontSize];\n\n  } else if (fontIsBold) {\n    font = [UIFont boldSystemFontOfSize:fontSize];\n\n  } else {\n    font = [UIFont systemFontOfSize:fontSize];\n  }\n\n  _font = font;\n  _is.cached.Font = YES;\n\n  return font;\n}\n\n- (BOOL)hasTextShadowColor {\n  return nil != [_ruleset objectForKey:kTextShadowKey];\n}\n\n- (UIColor *)textShadowColor {\n  NIDASSERT([self hasTextShadowColor]);\n  if (!_is.cached.TextShadowColor) {\n    NSArray* values = [_ruleset objectForKey:kTextShadowKey];\n    _textShadowColor = [[self class] colorFromCssValues:values numberOfConsumedTokens:nil];\n    _is.cached.TextShadowColor = YES;\n  }\n  return _textShadowColor;\n}\n\n- (BOOL)hasTextShadowOffset {\n  return nil != [_ruleset objectForKey:kTextShadowKey];\n}\n\n- (CGSize)textShadowOffset {\n  NIDASSERT([self hasTextShadowOffset]);\n  if (!_is.cached.TextShadowOffset) {\n    NSArray* values = [_ruleset objectForKey:kTextShadowKey];\n    NSInteger skipTokens = 0;\n    [[self class] colorFromCssValues:values numberOfConsumedTokens:&skipTokens];\n\n    _textShadowOffset = CGSizeZero;\n    if ([values count] - skipTokens >= 1) {\n      _textShadowOffset.width = [[values objectAtIndex:skipTokens] floatValue];\n    }\n    if ([values count] - skipTokens >= 2) {\n      _textShadowOffset.height = [[values objectAtIndex:skipTokens + 1] floatValue];\n    }\n    _is.cached.TextShadowOffset = YES;\n  }\n  return _textShadowOffset;\n}\n\n- (BOOL)hasLineBreakMode {\n  return nil != [_ruleset objectForKey:kLineBreakModeKey];\n}\n\n- (NSLineBreakMode)lineBreakMode {\n  NIDASSERT([self hasLineBreakMode]);\n  if (!_is.cached.LineBreakMode) {\n    NSArray* values = [_ruleset objectForKey:kLineBreakModeKey];\n    NIDASSERT([values count] == 1);\n    NSString* value = [values objectAtIndex:0];\n    if ([value isEqualToString:@\"wrap\"]) {\n      _lineBreakMode = NSLineBreakByWordWrapping;\n    } else if ([value isEqualToString:@\"character-wrap\"]) {\n      _lineBreakMode = NSLineBreakByCharWrapping;\n    } else if ([value isEqualToString:@\"clip\"]) {\n      _lineBreakMode = NSLineBreakByClipping;\n    } else if ([value isEqualToString:@\"head-truncate\"]) {\n      _lineBreakMode = NSLineBreakByTruncatingHead;\n    } else if ([value isEqualToString:@\"tail-truncate\"]) {\n      _lineBreakMode = NSLineBreakByTruncatingTail;\n    } else if ([value isEqualToString:@\"middle-truncate\"]) {\n      _lineBreakMode = NSLineBreakByTruncatingMiddle;\n    } else {\n      _lineBreakMode = NSLineBreakByWordWrapping;\n    }\n    _is.cached.LineBreakMode = YES;\n  }\n  return _lineBreakMode;\n}\n\n- (BOOL)hasNumberOfLines {\n  return nil != [_ruleset objectForKey:kNumberOfLinesKey];\n}\n\n- (NSInteger)numberOfLines {\n  NIDASSERT([self hasNumberOfLines]);\n  if (!_is.cached.NumberOfLines) {\n    NSArray* values = [_ruleset objectForKey:kNumberOfLinesKey];\n    NIDASSERT([values count] == 1);\n    _numberOfLines = [[values objectAtIndex:0] intValue];\n    _is.cached.NumberOfLines = YES;\n  }\n  return _numberOfLines;\n}\n\n- (BOOL)hasMinimumFontSize {\n  return nil != [_ruleset objectForKey:kMinimumFontSizeKey];\n}\n\n- (CGFloat)minimumFontSize {\n  NIDASSERT([self hasMinimumFontSize]);\n  if (!_is.cached.MinimumFontSize) {\n    NSArray* values = [_ruleset objectForKey:kMinimumFontSizeKey];\n    NIDASSERT([values count] == 1);\n    _minimumFontSize = [[values objectAtIndex:0] floatValue];\n    _is.cached.MinimumFontSize = YES;\n  }\n  return _minimumFontSize;\n}\n\n- (BOOL)hasAdjustsFontSize {\n  return nil != [_ruleset objectForKey:kAdjustsFontSizeKey];\n}\n\n- (BOOL)adjustsFontSize {\n  NIDASSERT([self hasAdjustsFontSize]);\n  if (!_is.cached.AdjustsFontSize) {\n    NSArray* values = [_ruleset objectForKey:kAdjustsFontSizeKey];\n    NIDASSERT([values count] == 1);\n    _adjustsFontSize = [[values objectAtIndex:0] boolValue];\n    _is.cached.AdjustsFontSize = YES;\n  }\n  return _adjustsFontSize;\n}\n\n- (BOOL)hasBaselineAdjustment {\n  return nil != [_ruleset objectForKey:kBaselineAdjustmentKey];\n}\n\n- (UIBaselineAdjustment)baselineAdjustment {\n  NIDASSERT([self hasBaselineAdjustment]);\n  if (!_is.cached.BaselineAdjustment) {\n    NSArray* values = [_ruleset objectForKey:kBaselineAdjustmentKey];\n    NIDASSERT([values count] == 1);\n    NSString* value = [values objectAtIndex:0];\n    if ([value isEqualToString:@\"align-baselines\"]) {\n      _baselineAdjustment = UIBaselineAdjustmentAlignBaselines;\n    } else if ([value isEqualToString:@\"align-centers\"]) {\n      _baselineAdjustment = UIBaselineAdjustmentAlignCenters;\n    } else {\n      _baselineAdjustment = UIBaselineAdjustmentNone;\n    }\n    _is.cached.BaselineAdjustment = YES;\n  }\n  return _baselineAdjustment;\n}\n\n- (BOOL)hasOpacity {\n  return nil != [_ruleset objectForKey:kOpacityKey];\n}\n\n- (CGFloat)opacity {\n  NIDASSERT([self hasOpacity]);\n  if (!_is.cached.Opacity) {\n    NSArray* values = [_ruleset objectForKey:kOpacityKey];\n    NIDASSERT([values count] == 1);\n    _opacity = [[values objectAtIndex:0] floatValue];\n    _is.cached.Opacity = YES;\n  }\n  return _opacity;\n}\n\n- (BOOL)hasBackgroundColor {\n  return nil != [_ruleset objectForKey:kBackgroundColorKey];\n}\n\n- (UIColor *)backgroundColor {\n  NIDASSERT([self hasBackgroundColor]);\n  if (!_is.cached.BackgroundColor) {\n    _backgroundColor = [[self class] colorFromCssValues:[_ruleset objectForKey:kBackgroundColorKey]\n                                 numberOfConsumedTokens:nil];\n    _is.cached.BackgroundColor = YES;\n  }\n  return _backgroundColor;\n}\n\n- (BOOL)hasBorderRadius {\n  return nil != [_ruleset objectForKey:kBorderRadiusKey];\n}\n\n- (CGFloat)borderRadius {\n  NIDASSERT([self hasBorderRadius]);\n  if (!_is.cached.BorderRadius) {\n    NSArray* values = [_ruleset objectForKey:kBorderRadiusKey];\n    NIDASSERT([values count] == 1);\n    _borderRadius = [[values objectAtIndex:0] floatValue];\n    _is.cached.BorderRadius = YES;\n  }\n  return _borderRadius;\n}\n\n- (BOOL)hasBorderColor {\n  return (nil != [_ruleset objectForKey:kBorderColorKey]\n          || nil != [_ruleset objectForKey:kBorderKey]);\n}\n\n- (void)cacheBorderValues {\n  _borderWidth = 0;\n  _borderColor = nil;\n\n  NSArray* values = nil;\n\n  // There are two ways to set border color and width: border and border-color/border-width.\n  // Newer definitions of these values should overwrite previous definitions so we must\n  // respect ordering here.\n  BOOL hasSetBorderColor = NO;\n  BOOL hasSetBorderWidth = NO;\n\n  NSArray* order = [_ruleset objectForKey:kPropertyOrderKey];\n  for (NSString* name in [order reverseObjectEnumerator]) {\n    if (!hasSetBorderColor && [name isEqualToString:kBorderColorKey]) {\n      values = [_ruleset objectForKey:name];\n      _borderColor = [[self class] colorFromCssValues:values\n                               numberOfConsumedTokens:nil];\n      hasSetBorderColor = YES;\n\n    } else if (!hasSetBorderWidth && [name isEqualToString:kBorderWidthKey]) {\n      values = [_ruleset objectForKey:name];\n      NIDASSERT([values count] == 1); if ([values count] < 1) { continue; }\n      _borderWidth = [[values objectAtIndex:0] floatValue];\n      hasSetBorderWidth = YES;\n\n    } else if (!hasSetBorderColor && !hasSetBorderWidth && [name isEqualToString:kBorderKey]) {\n      values = [_ruleset objectForKey:name];\n\n      if ([values count] >= 1) {\n        // Border width\n        _borderWidth = [[values objectAtIndex:0] floatValue];\n        hasSetBorderWidth = YES;\n      }\n      if ([values count] >= 3) {\n        // Border color\n        _borderColor = [[self class] colorFromCssValues:[values subarrayWithRange:NSMakeRange(2, [values count] - 2)]\n                                 numberOfConsumedTokens:nil];\n        hasSetBorderColor = YES;\n      }\n    }\n    \n    if (hasSetBorderColor && hasSetBorderWidth) {\n      // Once we've set all values then we can ignore any previous values.\n      break;\n    }\n  }\n  \n  _is.cached.BorderColor = hasSetBorderColor;\n  _is.cached.BorderWidth = hasSetBorderWidth;\n}\n\n- (UIColor *)borderColor {\n  NIDASSERT([self hasBorderColor]);\n\n  [self cacheBorderValues];\n  return _borderColor;\n}\n\n- (BOOL)hasBorderWidth {\n  return (nil != [_ruleset objectForKey:kBorderWidthKey]\n          || nil != [_ruleset objectForKey:kBorderKey]);\n}\n\n- (CGFloat)borderWidth {\n  NIDASSERT([self hasBorderWidth]);\n\n  [self cacheBorderValues];\n  return _borderWidth;\n}\n\nRULE_ELEMENT(width,Width,@\"width\",NICSSUnit,unitFromCssValues)\nRULE_ELEMENT(height,Height,@\"height\",NICSSUnit,unitFromCssValues)\nRULE_ELEMENT(top,Top,@\"top\",NICSSUnit,unitFromCssValues)\nRULE_ELEMENT(bottom,Bottom,@\"bottom\",NICSSUnit,unitFromCssValues)\nRULE_ELEMENT(right,Right,@\"right\",NICSSUnit,unitFromCssValues)\nRULE_ELEMENT(left,Left,@\"left\",NICSSUnit,unitFromCssValues)\nRULE_ELEMENT(minWidth, MinWidth, @\"min-width\", NICSSUnit, unitFromCssValues)\nRULE_ELEMENT(minHeight, MinHeight, @\"min-height\", NICSSUnit, unitFromCssValues)\nRULE_ELEMENT(maxWidth, MaxWidth, @\"max-width\", NICSSUnit, unitFromCssValues)\nRULE_ELEMENT(maxHeight, MaxHeight, @\"max-height\", NICSSUnit, unitFromCssValues)\nRULE_ELEMENT(frameHorizontalAlign,FrameHorizontalAlign,@\"-mobile-halign\",NSTextAlignment,textAlignmentFromCssValues)\nRULE_ELEMENT(frameVerticalAlign,FrameVerticalAlign,@\"-mobile-valign\",UIViewContentMode,verticalAlignFromCssValues)\nRULE_ELEMENT(backgroundStretchInsets,BackgroundStretchInsets,@\"-mobile-background-stretch\",UIEdgeInsets,edgeInsetsFromCssValues)\nRULE_ELEMENT(backgroundImage,BackgroundImage,@\"background-image\", NSString*,imageStringFromCssValues)\nRULE_ELEMENT(image, Image, @\"-mobile-image\", NSString*, imageStringFromCssValues)\nRULE_ELEMENT(visible, Visible, @\"visibility\", BOOL, visibilityFromCssValues)\nRULE_ELEMENT(titleInsets, TitleInsets, @\"-mobile-title-insets\", UIEdgeInsets, edgeInsetsFromCssValues)\nRULE_ELEMENT(contentInsets, ContentInsets, @\"-mobile-content-insets\", UIEdgeInsets, edgeInsetsFromCssValues)\nRULE_ELEMENT(imageInsets, ImageInsets, @\"-mobile-image-insets\", UIEdgeInsets, edgeInsetsFromCssValues)\nRULE_ELEMENT(relativeToId, RelativeToId, @\"-mobile-relative\", NSString*, stringFromCssValue)\nRULE_ELEMENT(marginTop, MarginTop, @\"margin-top\", NICSSUnit, unitFromCssValues)\nRULE_ELEMENT(marginBottom, MarginBottom, @\"margin-bottom\", NICSSUnit, unitFromCssValues)\nRULE_ELEMENT(marginLeft, MarginLeft, @\"margin-left\", NICSSUnit, unitFromCssValues)\nRULE_ELEMENT(marginRight, MarginRight, @\"margin-right\", NICSSUnit, unitFromCssValues)\nRULE_ELEMENT(textKey, TextKey, @\"-mobile-text-key\", NSString*, stringFromCssValue)\nRULE_ELEMENT(buttonAdjust, ButtonAdjust, @\"-ios-button-adjust\", NICSSButtonAdjust, buttonAdjustFromCssValue)\nRULE_ELEMENT(verticalAlign, VerticalAlign, @\"-mobile-content-valign\", UIControlContentVerticalAlignment, controlVerticalAlignFromCssValues)\nRULE_ELEMENT(horizontalAlign, HorizontalAlign, @\"-mobile-content-halign\", UIControlContentHorizontalAlignment, controlHorizontalAlignFromCssValues)\n\n- (BOOL)hasTintColor {\n  return nil != [_ruleset objectForKey:kTintColorKey];\n}\n\n- (UIColor *)tintColor {\n  NIDASSERT([self hasTintColor]);\n  if (!_is.cached.TintColor) {\n    _tintColor = [[self class] colorFromCssValues:[_ruleset objectForKey:kTintColorKey]\n                           numberOfConsumedTokens:nil];\n    _is.cached.TintColor = YES;\n  }\n  return _tintColor;\n}\n\n- (BOOL)hasActivityIndicatorStyle {\n  return nil != [_ruleset objectForKey:kActivityIndicatorStyleKey];\n}\n\n- (UIActivityIndicatorViewStyle)activityIndicatorStyle {\n  NIDASSERT([self hasActivityIndicatorStyle]);\n  if (!_is.cached.ActivityIndicatorStyle) {\n    NSArray* values = [_ruleset objectForKey:kActivityIndicatorStyleKey];\n    NIDASSERT([values count] == 1);\n    NSString* value = [values objectAtIndex:0];\n    if ([value isEqualToString:@\"white\"]) {\n      _activityIndicatorStyle = UIActivityIndicatorViewStyleWhite;\n    } else if ([value isEqualToString:@\"gray\"]) {\n      _activityIndicatorStyle = UIActivityIndicatorViewStyleGray;\n    } else {\n      _activityIndicatorStyle = UIActivityIndicatorViewStyleWhiteLarge;\n    }\n    _is.cached.ActivityIndicatorStyle = YES;\n  }\n  return _activityIndicatorStyle;\n}\n\n- (BOOL)hasAutoresizing {\n  return nil != [_ruleset objectForKey:kAutoresizingKey];\n}\n\n- (UIViewAutoresizing)autoresizing {\n  NIDASSERT([self hasAutoresizing]);\n  if (!_is.cached.Autoresizing) {\n    NSArray* values = [_ruleset objectForKey:kAutoresizingKey];\n    UIViewAutoresizing autoresizing = UIViewAutoresizingNone;\n    for (NSString* value in values) {\n      if ([value isEqualToString:@\"left\"]) {\n        autoresizing |= UIViewAutoresizingFlexibleLeftMargin;\n      } else if ([value isEqualToString:@\"top\"]) {\n        autoresizing |= UIViewAutoresizingFlexibleTopMargin;\n      } else if ([value isEqualToString:@\"right\"]) {\n        autoresizing |= UIViewAutoresizingFlexibleRightMargin;\n      } else if ([value isEqualToString:@\"bottom\"]) {\n        autoresizing |= UIViewAutoresizingFlexibleBottomMargin;\n      } else if ([value isEqualToString:@\"width\"]) {\n        autoresizing |= UIViewAutoresizingFlexibleWidth;\n      } else if ([value isEqualToString:@\"height\"]) {\n        autoresizing |= UIViewAutoresizingFlexibleHeight;\n      } else if ([value isEqualToString:@\"all\"]) {\n        autoresizing |=\n            (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth\n             | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin\n             | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin);\n      } else if ([value isEqualToString:@\"margins\"]) {\n        autoresizing |=\n            (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin\n             | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin);\n      } else if ([value isEqualToString:@\"dimensions\"]) {\n        autoresizing |= UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;\n      }\n    }\n    _autoresizing = autoresizing;\n    _is.cached.Autoresizing = YES;\n  }\n  return _autoresizing;\n}\n\n- (BOOL)hasTableViewCellSeparatorStyle {\n  return nil != [_ruleset objectForKey:kTableViewCellSeparatorStyleKey];\n}\n\n- (UITableViewCellSeparatorStyle)tableViewCellSeparatorStyle {\n  NIDASSERT([self hasTableViewCellSeparatorStyle]);\n  if (!_is.cached.TableViewCellSeparatorStyle) {\n    NSArray* values = [_ruleset objectForKey:kTableViewCellSeparatorStyleKey];\n    NIDASSERT([values count] == 1);\n    NSString* value = [values objectAtIndex:0];\n    UITableViewCellSeparatorStyle style = UITableViewCellSeparatorStyleSingleLine;\n    if ([value isEqualToString:@\"none\"]) {\n      style = UITableViewCellSeparatorStyleNone;\n    } else if ([value isEqualToString:@\"single-line-etched\"]) {\n      style = UITableViewCellSeparatorStyleSingleLineEtched;\n    }\n    _tableViewCellSeparatorStyle = style;\n    _is.cached.TableViewCellSeparatorStyle = YES;\n  }\n  return _tableViewCellSeparatorStyle;\n}\n\n- (BOOL)hasScrollViewIndicatorStyle {\n  return nil != [_ruleset objectForKey:kScrollViewIndicatorStyleKey];\n}\n\n- (UIScrollViewIndicatorStyle)scrollViewIndicatorStyle {\n  NIDASSERT([self hasScrollViewIndicatorStyle]);\n  if (!_is.cached.ScrollViewIndicatorStyle) {\n    NSArray* values = [_ruleset objectForKey:kScrollViewIndicatorStyleKey];\n    NIDASSERT([values count] == 1);\n    NSString* value = [values objectAtIndex:0];\n    UIScrollViewIndicatorStyle style = UIScrollViewIndicatorStyleDefault;\n    if ([value isEqualToString:@\"black\"]) {\n      style = UIScrollViewIndicatorStyleBlack;\n    } else if ([value isEqualToString:@\"white\"]) {\n      style = UIScrollViewIndicatorStyleWhite;\n    }\n    _scrollViewIndicatorStyle = style;\n    _is.cached.ScrollViewIndicatorStyle = YES;\n  }\n  return _scrollViewIndicatorStyle;\n}\n\n#pragma mark - NSNotifications\n\n\n\n- (void)reduceMemory {\n  sColorTable = nil;\n\n  _textColor = nil;\n  _font = nil;\n  _textShadowColor = nil;\n  _backgroundColor = nil;\n  _borderColor = nil;\n  _tintColor = nil;\n\n  memset(&_is, 0, sizeof(_is));\n}\n\n- (void)didReceiveMemoryWarning:(void*)object {\n  [self reduceMemory];\n}\n\n#pragma mark - Color Tables\n\n\n+ (NSDictionary *)colorTable {\n  if (nil == sColorTable) {\n    // This color table was generated from http://www.w3.org/TR/css3-color/\n    //\n    // The output was sorted,\n    // > pbpaste | sort | pbcopy\n    //\n    // reformatted using a regex,\n    // ^(.+)\\t(.+)\\t(.+) => RGBCOLOR($3), @\"$1\",\n    //\n    // and then uniq'd\n    // > pbpaste | uniq | pbcopy\n    NSMutableDictionary* colorTable =\n    [[NSMutableDictionary alloc] initWithObjectsAndKeys:\n     RGBCOLOR(240,248,255), @\"aliceblue\",\n     RGBCOLOR(250,235,215), @\"antiquewhite\",\n     RGBCOLOR(0,255,255), @\"aqua\",\n     RGBCOLOR(127,255,212), @\"aquamarine\",\n     RGBCOLOR(240,255,255), @\"azure\",\n     RGBCOLOR(245,245,220), @\"beige\",\n     RGBCOLOR(255,228,196), @\"bisque\",\n     RGBCOLOR(0,0,0), @\"black\",\n     RGBCOLOR(255,235,205), @\"blanchedalmond\",\n     RGBCOLOR(0,0,255), @\"blue\",\n     RGBCOLOR(138,43,226), @\"blueviolet\",\n     RGBCOLOR(165,42,42), @\"brown\",\n     RGBCOLOR(222,184,135), @\"burlywood\",\n     RGBCOLOR(95,158,160), @\"cadetblue\",\n     RGBCOLOR(127,255,0), @\"chartreuse\",\n     RGBCOLOR(210,105,30), @\"chocolate\",\n     RGBCOLOR(255,127,80), @\"coral\",\n     RGBCOLOR(100,149,237), @\"cornflowerblue\",\n     RGBCOLOR(255,248,220), @\"cornsilk\",\n     RGBCOLOR(220,20,60), @\"crimson\",\n     RGBCOLOR(0,255,255), @\"cyan\",\n     RGBCOLOR(0,0,139), @\"darkblue\",\n     RGBCOLOR(0,139,139), @\"darkcyan\",\n     RGBCOLOR(184,134,11), @\"darkgoldenrod\",\n     RGBCOLOR(169,169,169), @\"darkgray\",\n     RGBCOLOR(0,100,0), @\"darkgreen\",\n     RGBCOLOR(169,169,169), @\"darkgrey\",\n     RGBCOLOR(189,183,107), @\"darkkhaki\",\n     RGBCOLOR(139,0,139), @\"darkmagenta\",\n     RGBCOLOR(85,107,47), @\"darkolivegreen\",\n     RGBCOLOR(255,140,0), @\"darkorange\",\n     RGBCOLOR(153,50,204), @\"darkorchid\",\n     RGBCOLOR(139,0,0), @\"darkred\",\n     RGBCOLOR(233,150,122), @\"darksalmon\",\n     RGBCOLOR(143,188,143), @\"darkseagreen\",\n     RGBCOLOR(72,61,139), @\"darkslateblue\",\n     RGBCOLOR(47,79,79), @\"darkslategray\",\n     RGBCOLOR(47,79,79), @\"darkslategrey\",\n     RGBCOLOR(0,206,209), @\"darkturquoise\",\n     RGBCOLOR(148,0,211), @\"darkviolet\",\n     RGBCOLOR(255,20,147), @\"deeppink\",\n     RGBCOLOR(0,191,255), @\"deepskyblue\",\n     RGBCOLOR(105,105,105), @\"dimgray\",\n     RGBCOLOR(105,105,105), @\"dimgrey\",\n     RGBCOLOR(30,144,255), @\"dodgerblue\",\n     RGBCOLOR(178,34,34), @\"firebrick\",\n     RGBCOLOR(255,250,240), @\"floralwhite\",\n     RGBCOLOR(34,139,34), @\"forestgreen\",\n     RGBCOLOR(255,0,255), @\"fuchsia\",\n     RGBCOLOR(220,220,220), @\"gainsboro\",\n     RGBCOLOR(248,248,255), @\"ghostwhite\",\n     RGBCOLOR(255,215,0), @\"gold\",\n     RGBCOLOR(218,165,32), @\"goldenrod\",\n     RGBCOLOR(128,128,128), @\"gray\",\n     RGBCOLOR(0,128,0), @\"green\",\n     RGBCOLOR(173,255,47), @\"greenyellow\",\n     RGBCOLOR(128,128,128), @\"grey\",\n     RGBCOLOR(240,255,240), @\"honeydew\",\n     RGBCOLOR(255,105,180), @\"hotpink\",\n     RGBCOLOR(205,92,92), @\"indianred\",\n     RGBCOLOR(75,0,130), @\"indigo\",\n     RGBCOLOR(255,255,240), @\"ivory\",\n     RGBCOLOR(240,230,140), @\"khaki\",\n     RGBCOLOR(230,230,250), @\"lavender\",\n     RGBCOLOR(255,240,245), @\"lavenderblush\",\n     RGBCOLOR(124,252,0), @\"lawngreen\",\n     RGBCOLOR(255,250,205), @\"lemonchiffon\",\n     RGBCOLOR(173,216,230), @\"lightblue\",\n     RGBCOLOR(240,128,128), @\"lightcoral\",\n     RGBCOLOR(224,255,255), @\"lightcyan\",\n     RGBCOLOR(250,250,210), @\"lightgoldenrodyellow\",\n     RGBCOLOR(211,211,211), @\"lightgray\",\n     RGBCOLOR(144,238,144), @\"lightgreen\",\n     RGBCOLOR(211,211,211), @\"lightgrey\",\n     RGBCOLOR(255,182,193), @\"lightpink\",\n     RGBCOLOR(255,160,122), @\"lightsalmon\",\n     RGBCOLOR(32,178,170), @\"lightseagreen\",\n     RGBCOLOR(135,206,250), @\"lightskyblue\",\n     RGBCOLOR(119,136,153), @\"lightslategray\",\n     RGBCOLOR(119,136,153), @\"lightslategrey\",\n     RGBCOLOR(176,196,222), @\"lightsteelblue\",\n     RGBCOLOR(255,255,224), @\"lightyellow\",\n     RGBCOLOR(0,255,0), @\"lime\",\n     RGBCOLOR(50,205,50), @\"limegreen\",\n     RGBCOLOR(250,240,230), @\"linen\",\n     RGBCOLOR(255,0,255), @\"magenta\",\n     RGBCOLOR(128,0,0), @\"maroon\",\n     RGBCOLOR(102,205,170), @\"mediumaquamarine\",\n     RGBCOLOR(0,0,205), @\"mediumblue\",\n     RGBCOLOR(186,85,211), @\"mediumorchid\",\n     RGBCOLOR(147,112,219), @\"mediumpurple\",\n     RGBCOLOR(60,179,113), @\"mediumseagreen\",\n     RGBCOLOR(123,104,238), @\"mediumslateblue\",\n     RGBCOLOR(0,250,154), @\"mediumspringgreen\",\n     RGBCOLOR(72,209,204), @\"mediumturquoise\",\n     RGBCOLOR(199,21,133), @\"mediumvioletred\",\n     RGBCOLOR(25,25,112), @\"midnightblue\",\n     RGBCOLOR(245,255,250), @\"mintcream\",\n     RGBCOLOR(255,228,225), @\"mistyrose\",\n     RGBCOLOR(255,228,181), @\"moccasin\",\n     RGBCOLOR(255,222,173), @\"navajowhite\",\n     RGBCOLOR(0,0,128), @\"navy\",\n     RGBCOLOR(253,245,230), @\"oldlace\",\n     RGBCOLOR(128,128,0), @\"olive\",\n     RGBCOLOR(107,142,35), @\"olivedrab\",\n     RGBCOLOR(255,165,0), @\"orange\",\n     RGBCOLOR(255,69,0), @\"orangered\",\n     RGBCOLOR(218,112,214), @\"orchid\",\n     RGBCOLOR(238,232,170), @\"palegoldenrod\",\n     RGBCOLOR(152,251,152), @\"palegreen\",\n     RGBCOLOR(175,238,238), @\"paleturquoise\",\n     RGBCOLOR(219,112,147), @\"palevioletred\",\n     RGBCOLOR(255,239,213), @\"papayawhip\",\n     RGBCOLOR(255,218,185), @\"peachpuff\",\n     RGBCOLOR(205,133,63), @\"peru\",\n     RGBCOLOR(255,192,203), @\"pink\",\n     RGBCOLOR(221,160,221), @\"plum\",\n     RGBCOLOR(176,224,230), @\"powderblue\",\n     RGBCOLOR(128,0,128), @\"purple\",\n     RGBCOLOR(255,0,0), @\"red\",\n     RGBCOLOR(188,143,143), @\"rosybrown\",\n     RGBCOLOR(65,105,225), @\"royalblue\",\n     RGBCOLOR(139,69,19), @\"saddlebrown\",\n     RGBCOLOR(250,128,114), @\"salmon\",\n     RGBCOLOR(244,164,96), @\"sandybrown\",\n     RGBCOLOR(46,139,87), @\"seagreen\",\n     RGBCOLOR(255,245,238), @\"seashell\",\n     RGBCOLOR(160,82,45), @\"sienna\",\n     RGBCOLOR(192,192,192), @\"silver\",\n     RGBCOLOR(135,206,235), @\"skyblue\",\n     RGBCOLOR(106,90,205), @\"slateblue\",\n     RGBCOLOR(112,128,144), @\"slategray\",\n     RGBCOLOR(112,128,144), @\"slategrey\",\n     RGBCOLOR(255,250,250), @\"snow\",\n     RGBCOLOR(0,255,127), @\"springgreen\",\n     RGBCOLOR(70,130,180), @\"steelblue\",\n     RGBCOLOR(210,180,140), @\"tan\",\n     RGBCOLOR(0,128,128), @\"teal\",\n     RGBCOLOR(216,191,216), @\"thistle\",\n     RGBCOLOR(255,99,71), @\"tomato\",\n     RGBCOLOR(64,224,208), @\"turquoise\",\n     RGBCOLOR(238,130,238), @\"violet\",\n     RGBCOLOR(245,222,179), @\"wheat\",\n     RGBCOLOR(255,255,255), @\"white\",\n     RGBCOLOR(245,245,245), @\"whitesmoke\",\n     RGBCOLOR(255,255,0), @\"yellow\",\n     RGBCOLOR(154,205,50), @\"yellowgreen\",\n     \n     // System colors\n     [UIColor lightTextColor],                @\"lightTextColor\",\n     [UIColor darkTextColor],                 @\"darkTextColor\",\n     [UIColor groupTableViewBackgroundColor], @\"groupTableViewBackgroundColor\",\n     [UIColor viewFlipsideBackgroundColor],   @\"viewFlipsideBackgroundColor\",\n     nil];\n    \n    if ([UIColor respondsToSelector:@selector(scrollViewTexturedBackgroundColor)]) {\n      // 3.2 and up\n      UIColor* color = [UIColor scrollViewTexturedBackgroundColor];\n      if (nil != color) {\n        [colorTable setObject:color\n                       forKey:@\"scrollViewTexturedBackgroundColor\"];\n      }\n    }\n    \n    if ([UIColor respondsToSelector:@selector(underPageBackgroundColor)]) {\n      // 5.0 and up\n      UIColor* color = [UIColor underPageBackgroundColor];\n      if (nil != color) {\n        [colorTable setObject:color\n                       forKey:@\"underPageBackgroundColor\"];\n      }\n    }\n\n    // Replace the web colors with their system color equivalents.\n    [colorTable setObject:[UIColor blackColor] forKey:@\"black\"];\n    [colorTable setObject:[UIColor darkGrayColor] forKey:@\"darkGray\"];\n    [colorTable setObject:[UIColor lightGrayColor] forKey:@\"lightGray\"];\n    [colorTable setObject:[UIColor whiteColor] forKey:@\"white\"];\n    [colorTable setObject:[UIColor grayColor] forKey:@\"gray\"];\n    [colorTable setObject:[UIColor redColor] forKey:@\"red\"];\n    [colorTable setObject:[UIColor greenColor] forKey:@\"green\"];\n    [colorTable setObject:[UIColor blueColor] forKey:@\"blue\"];\n    [colorTable setObject:[UIColor cyanColor] forKey:@\"cyan\"];\n    [colorTable setObject:[UIColor yellowColor] forKey:@\"yellow\"];\n    [colorTable setObject:[UIColor magentaColor] forKey:@\"magenta\"];\n    [colorTable setObject:[UIColor orangeColor] forKey:@\"orange\"];\n    [colorTable setObject:[UIColor purpleColor] forKey:@\"purple\"];\n    [colorTable setObject:[UIColor brownColor] forKey:@\"brown\"];\n    [colorTable setObject:[UIColor clearColor] forKey:@\"clear\"];\n\n    sColorTable = [colorTable copy];\n  }\n  return sColorTable;\n}\n\n+ (NICSSUnit)unitFromCssValues:(NSArray*)cssValues {\n  return [self unitFromCssValues:cssValues offset: 0];\n}\n\n+ (NICSSUnit)unitFromCssValues:(NSArray*)cssValues offset: (int) offset {\n  NICSSUnit returnUnits;\n  NSString *unitValue = [cssValues objectAtIndex:offset];\n\tif ([unitValue caseInsensitiveCompare:@\"auto\"] == NSOrderedSame) {\n    returnUnits.type = CSS_AUTO_UNIT;\n    returnUnits.value = 0;\n  } else if ([unitValue hasSuffix:@\"%\"]) {\n    returnUnits.type = CSS_PERCENTAGE_UNIT;\n    NSDecimalNumber *nv = [NSDecimalNumber decimalNumberWithString: [unitValue substringToIndex:unitValue.length-1]];\n    returnUnits.value = [nv decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithMantissa:1 exponent:2 isNegative:NO]].floatValue;\n  } else if ([unitValue hasSuffix:@\"px\"]) {\n    returnUnits.type = CSS_PIXEL_UNIT;\n    returnUnits.value = [NSDecimalNumber decimalNumberWithString: [unitValue substringToIndex:unitValue.length-1]].floatValue;\n  } else if ([unitValue isEqualToString:@\"0\"]) {\n    returnUnits.type = CSS_PIXEL_UNIT;\n    returnUnits.value = 0;\n  } else {\n    NIDERROR(@\"Unknown unit: %@\", unitValue);\n  }\n  return returnUnits;\n}\n\n+(UIViewContentMode) verticalAlignFromCssValues:(NSArray*)cssValues\n{\n  NSString *unitValue = [cssValues objectAtIndex:0];\n\tif ([unitValue caseInsensitiveCompare:@\"middle\"] == NSOrderedSame) {\n    return UIViewContentModeCenter;\n  } else if ([unitValue caseInsensitiveCompare:@\"top\"] == NSOrderedSame) {\n    return UIViewContentModeTop;\n  }  else if ([unitValue caseInsensitiveCompare:@\"bottom\"] == NSOrderedSame) {\n    return UIViewContentModeBottom;\n  } else {\n    NIDERROR(@\"Unknown vertical alignment: %@\", unitValue);\n    return UIViewContentModeCenter;\n  }\n}\n\n+(UIControlContentVerticalAlignment) controlVerticalAlignFromCssValues:(NSArray*)cssValues\n{\n  NSString *unitValue = [cssValues objectAtIndex:0];\n\tif ([unitValue caseInsensitiveCompare:@\"middle\"] == NSOrderedSame) {\n    return UIControlContentVerticalAlignmentCenter;\n  } else if ([unitValue caseInsensitiveCompare:@\"top\"] == NSOrderedSame) {\n    return UIControlContentVerticalAlignmentTop;\n  }  else if ([unitValue caseInsensitiveCompare:@\"bottom\"] == NSOrderedSame) {\n    return UIControlContentVerticalAlignmentBottom;\n  } else if ([unitValue caseInsensitiveCompare:@\"fill\"] == NSOrderedSame) {\n    return UIControlContentVerticalAlignmentFill;\n  } else {\n    NIDERROR(@\"Unknown content vertical alignment: %@\", unitValue);\n    return UIControlContentVerticalAlignmentCenter;\n  }\n}\n\n+(UIControlContentHorizontalAlignment) controlHorizontalAlignFromCssValues:(NSArray*)cssValues\n{\n  NSString *unitValue = [cssValues objectAtIndex:0];\n\tif ([unitValue caseInsensitiveCompare:@\"center\"] == NSOrderedSame) {\n    return UIControlContentHorizontalAlignmentCenter;\n  } else if ([unitValue caseInsensitiveCompare:@\"left\"] == NSOrderedSame) {\n    return UIControlContentHorizontalAlignmentLeft;\n  }  else if ([unitValue caseInsensitiveCompare:@\"right\"] == NSOrderedSame) {\n    return UIControlContentHorizontalAlignmentRight;\n  } else if ([unitValue caseInsensitiveCompare:@\"fill\"] == NSOrderedSame) {\n    return UIControlContentHorizontalAlignmentFill;\n  } else {\n    NIDERROR(@\"Unknown content horizontal alignment: %@\", unitValue);\n    return UIControlContentHorizontalAlignmentCenter;\n  }\n}\n\n+ (UIColor *)colorFromCssValues:(NSArray *)cssValues numberOfConsumedTokens:(NSInteger *)pNumberOfConsumedTokens {\n  NSInteger bogus = 0;\n  if (nil == pNumberOfConsumedTokens) {\n    pNumberOfConsumedTokens = &bogus;\n  }\n  UIColor* color = nil;\n\n  if ([cssValues count] >= 6 && [[cssValues objectAtIndex:0] isEqualToString:@\"rgba(\"]) {\n    // rgba( x x x x )\n    color = RGBACOLOR([[cssValues objectAtIndex:1] floatValue],\n                      [[cssValues objectAtIndex:2] floatValue],\n                      [[cssValues objectAtIndex:3] floatValue],\n                      [[cssValues objectAtIndex:4] floatValue]);\n    *pNumberOfConsumedTokens = 6;\n\n  } else if ([cssValues count] >= 5 && [[cssValues objectAtIndex:0] isEqualToString:@\"rgb(\"]) {\n    // rgb( x x x )\n    color = RGBCOLOR([[cssValues objectAtIndex:1] floatValue],\n                     [[cssValues objectAtIndex:2] floatValue],\n                     [[cssValues objectAtIndex:3] floatValue]);\n    *pNumberOfConsumedTokens = 5;\n    \n  } else if ([cssValues count] == 1 && [[cssValues objectAtIndex:0] hasPrefix:@\"url(\"]) {\n      NSString *image = [cssValues objectAtIndex:0];\n      image = [image substringWithRange:NSMakeRange(4, image.length - 5)];\n      image = [image stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@\" '\\\"\"]];\n      color = [UIColor colorWithPatternImage:[UIImage imageNamed:image]];\n  } else if ([cssValues count] >= 1) {\n    NSString* cssString = [cssValues objectAtIndex:0];\n\n    if ([cssString characterAtIndex:0] == '#') {\n      unsigned long colorValue = 0;\n\n      // #FFF\n      if ([cssString length] == 4) {\n        colorValue = strtol([cssString UTF8String] + 1, nil, 16);\n        colorValue = ((colorValue & 0xF00) << 12) | ((colorValue & 0xF00) << 8)\n        | ((colorValue & 0xF0) << 8) | ((colorValue & 0xF0) << 4)\n        | ((colorValue & 0xF) << 4) | (colorValue & 0xF);\n\n      // #FFFFFF\n      } else if ([cssString length] == 7) {\n        colorValue = strtol([cssString UTF8String] + 1, nil, 16);\n      }\n\n      color = RGBCOLOR(((colorValue & 0xFF0000) >> 16),\n                       ((colorValue & 0xFF00) >> 8),\n                       (colorValue & 0xFF));\n    } else if ([cssString caseInsensitiveCompare:@\"none\"] == NSOrderedSame) {\n      // Special case to \"undo\" a color that was set by some other rule\n      color = nil;\n    } else {\n      color = [[self colorTable] objectForKey:cssString];\n    }\n\n    *pNumberOfConsumedTokens = 1;\n  }\n  return color;\n}\n\n+(BOOL)visibilityFromCssValues: (NSArray*) values\n{\n  NSString *v = [values objectAtIndex:0];\n  if ([v caseInsensitiveCompare:@\"hidden\"] == NSOrderedSame) {\n    return NO;\n  }\n  return YES;\n}\n\n+(NSString*)imageStringFromCssValues:(NSArray*) cssValues\n{\n  NSString *bg = [cssValues objectAtIndex:0];\n  if ([bg hasPrefix:@\"url(\"]) {\n    bg = [bg substringWithRange: NSMakeRange(4, bg.length - 5)];\n  }\n  if ([bg characterAtIndex:0] == '\\'' || [bg characterAtIndex:0] == '\"') {\n    bg = [bg substringWithRange:NSMakeRange(1, bg.length-2)];\n  }\n  return bg;\n}\n\n+(NSString*)stringFromCssValue:(NSArray*) cssValues\n{\n  NSString *s = [cssValues objectAtIndex:0];\n  if ([s characterAtIndex:0] == '\\\"') {\n    s = [s substringWithRange:NSMakeRange(1, s.length-2)];\n  }\n  return s;\n}\n\n+(UIEdgeInsets)edgeInsetsFromCssValues: (NSArray*) cssValues\n{\n  // top, left, bottom, right\n  NSString *top = [cssValues objectAtIndex:0], *left, *right, *bottom;\n  if (cssValues.count > 1) {\n    left = [cssValues objectAtIndex:1];\n    if (cssValues.count > 2) {\n      bottom = [cssValues objectAtIndex:2];\n      if (cssValues.count > 3) {\n        right = [cssValues objectAtIndex:3];\n      }\n    } else {\n      bottom = top;\n      right = left;\n    }\n  } else {\n    left = right = bottom = top;\n  }\n  return UIEdgeInsetsMake(\n                          [NSDecimalNumber decimalNumberWithString:top].floatValue,\n                          [NSDecimalNumber decimalNumberWithString:left].floatValue,\n                          [NSDecimalNumber decimalNumberWithString:bottom].floatValue,\n                          [NSDecimalNumber decimalNumberWithString:right].floatValue\n                          );\n}\n\n+(CGFloat)pixelsFromCssValue: (NSArray*) cssValues\n{\n  return [[cssValues objectAtIndex:0] floatValue];\n}\n\n+(NICSSButtonAdjust)buttonAdjustFromCssValue: (NSArray*) cssValues\n{\n  NICSSButtonAdjust a = NICSSButtonAdjustNone;\n  for (NSString* token in cssValues) {\n    if ([token caseInsensitiveCompare:@\"highlighted\"] == NSOrderedSame) {\n      a |= NICSSButtonAdjustHighlighted;\n    } else if ([token caseInsensitiveCompare:@\"disabled\"] == NSOrderedSame) {\n      a |= NICSSButtonAdjustDisabled;\n    }\n  }\n  return a;\n}\n\n+ (NSTextAlignment)textAlignmentFromCssValues:(NSArray *)cssValues {\n  NIDASSERT([cssValues count] == 1);\n  if ([cssValues count] < 1) {\n    return NSTextAlignmentLeft;\n  }\n\n  NSString* value = [cssValues objectAtIndex:0];\n\n  NSTextAlignment textAlignment = NSTextAlignmentLeft;\n  \n  if ([value isEqualToString:@\"center\"]) {\n    textAlignment = NSTextAlignmentCenter;\n  } else if ([value isEqualToString:@\"right\"]) {\n    textAlignment = NSTextAlignmentRight;\n  } else if ([value isEqualToString:@\"left\"]) {\n    textAlignment = NSTextAlignmentLeft;\n  } else {\n    NIDERROR(@\"Unknown horizontal alignment %@\", value);\n  }\n\n  return textAlignment;\n}\n\n-(NSString *)description\n{\n    return [_ruleset description];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/NIChameleonObserver.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"NimbusCore.h\"\n#import \"NIOperations.h\"\n#import \"NICSSParser.h\"\n\n@class NIStylesheet;\n@class NIStylesheetCache;\n\nextern NSString* const NIJSONDidChangeNotification;\nextern NSString* const NIJSONDidChangeFilePathKey;\nextern NSString* const NIJSONDidChangeNameKey;\n\n/**\n * An observer for the Chameleon server.\n *\n * @ingroup NimbusCSS\n *\n * This observer connects to a Chameleon server and waits for changes in stylesheets. Once\n * a stylesheet change has been detected, the new stylesheet is retrieved from the server\n * and a notification is fired via NIStylesheetDidChangeNotification after the stylesheet\n * has been reloaded.\n *\n * Thanks to the use of NIOperations, the stylesheet loading and processing is accomplished\n * on a separate thread. This means that the UI will only be notified of stylesheet changes\n * once the request thread has successfully loaded and processed the changed stylesheet.\n */\n@interface NIChameleonObserver : NSObject <NIOperationDelegate, NICSSParserDelegate> {\n@private\n  NIStylesheetCache* _stylesheetCache;\n  NSMutableArray* _stylesheetPaths;\n  NSString* _host;\n  NSInteger _retryCount;\n}\n\n// Designated initializer.\n- (id)initWithStylesheetCache:(NIStylesheetCache *)stylesheetCache host:(NSString *)host;\n\n- (NIStylesheet *)stylesheetForPath:(NSString *)path;\n\n- (void)watchSkinChanges;\n\n- (void)enableBonjourDiscovery: (NSString*) serviceName;\n\n@end\n\n/**\n * Initializes a newly allocated Chameleon observer with a given stylesheet cache and host.\n *\n * @fn NIChameleonObserver::initWithStylesheetCache:host:\n */\n\n/**\n * Returns a loaded stylesheet from the given path.\n *\n * @fn NIChameleonObserver::stylesheetForPath:\n */\n\n/**\n * Begins listening to the Chameleon server for changes.\n *\n * When changes are detected the Chameleon observer downloads the new CSS files, reloads them,\n * and then fires the appropriate notifications.\n *\n * @fn NIChameleonObserver::watchSkinChanges\n */\n\n/**\n * Browses Bonjour for services with the given name (e.g. your username) and sets the host\n * automatically.\n *\n * @fn NIChameleonObserver::enableBonjourDiscovery:\n */\n"
  },
  {
    "path": "src/css/src/NIChameleonObserver.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIChameleonObserver.h\"\n\n#import \"NIStylesheet.h\"\n#import \"NIStylesheetCache.h\"\n#import \"NIUserInterfaceString.h\"\n#import \"NimbusCore+Additions.h\"\n#import \"AFNetworking.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic NSString* const kWatchFilenameKey = @\"___watch___\";\nstatic const NSTimeInterval kTimeoutInterval = 1000;\nstatic const NSTimeInterval kRetryInterval = 10000;\nstatic const NSInteger kMaxNumberOfRetries = 3;\n\nNSString* const NIJSONDidChangeNotification = @\"NIJSONDidChangeNotification\";\nNSString* const NIJSONDidChangeFilePathKey = @\"NIJSONPathKey\";\nNSString* const NIJSONDidChangeNameKey = @\"NIJSONNameKey\";\n\n@interface NIChameleonObserver() <\n    NSNetServiceBrowserDelegate,\n    NSNetServiceDelegate\n>\n- (NSString *)pathFromPath:(NSString *)path;\n@property (nonatomic,strong) NSNetServiceBrowser *netBrowser;\n@property (nonatomic,strong) NSNetService *netService;\n@property (nonatomic,strong) AFHTTPSessionManager *httpSessionManager;\n@end\n\n@implementation NIChameleonObserver\n\n\n- (void)dealloc {\n  [self.httpSessionManager invalidateSessionCancelingTasks:YES];\n}\n\n- (id)initWithStylesheetCache:(NIStylesheetCache *)stylesheetCache host:(NSString *)host {\n  if ((self = [super init])) {\n    // You must provide a stylesheet cache.\n    NIDASSERT(nil != stylesheetCache);\n    _stylesheetCache = stylesheetCache;\n    _stylesheetPaths = [[NSMutableArray alloc] init];\n    _httpSessionManager = [AFHTTPSessionManager manager];\n\n    if ([host hasSuffix:@\"/\"]) {\n      _host = [host copy];\n\n    } else if (host) {\n      _host = [[host stringByAppendingString:@\"/\"] copy];\n    }\n\n    NSFileManager* fm = [NSFileManager defaultManager];\n    NSDirectoryEnumerator* de = [fm enumeratorAtPath:_stylesheetCache.pathPrefix];\n\n    NSString* filename;\n    while ((filename = [de nextObject])) {\n      BOOL isFolder = NO;\n      NSString* path = [_stylesheetCache.pathPrefix stringByAppendingPathComponent:filename];\n      if ([fm fileExistsAtPath:path isDirectory:&isFolder]\n          && !isFolder\n          && [[filename pathExtension] isEqualToString:@\"css\"]) {\n        [_stylesheetPaths addObject:filename];\n        NSString* cachePath = NIPathForDocumentsResource([self pathFromPath:filename]);\n        NSError* error = nil;\n        [fm removeItemAtPath:cachePath error:&error];\n        error = nil;\n        [fm copyItemAtPath:path toPath:cachePath error:&error];\n        NIDASSERT(nil == error);\n      }\n    }\n  }\n  return self;\n}\n\n- (void)downloadStylesheetWithFilename:(NSString *)path {\n  NSURL* url = [NSURL URLWithString:[_host stringByAppendingString:path]];\n\n  [self.httpSessionManager GET:url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {\n    NSMutableArray* changedStylesheets = [NSMutableArray array];\n    NSArray* pathParts = [url.absoluteString pathComponents];\n    NSString* resultPath = [[pathParts subarrayWithRange:NSMakeRange(2, [pathParts count] - 2)]\n                            componentsJoinedByString:@\"/\"];\n    NSString* rootPath = NIPathForDocumentsResource(nil);\n    NSString* hashedPath = [self pathFromPath:resultPath];\n    NSString* diskPath = [rootPath stringByAppendingPathComponent:hashedPath];\n    [responseObject writeToFile:diskPath atomically:YES];\n\n    NIStylesheet* stylesheet = [_stylesheetCache stylesheetWithPath:resultPath loadFromDisk:NO];\n    if ([stylesheet loadFromPath:resultPath pathPrefix:rootPath delegate:self]) {\n      [changedStylesheets addObject:stylesheet];\n    }\n\n    for (NSString* iteratingPath in _stylesheetPaths) {\n      stylesheet = [_stylesheetCache stylesheetWithPath:iteratingPath loadFromDisk:NO];\n      if ([stylesheet.dependencies containsObject:resultPath]) {\n        // This stylesheet has the changed stylesheet as a dependency so let's refresh it.\n        if ([stylesheet loadFromPath:iteratingPath pathPrefix:rootPath delegate:self]) {\n          [changedStylesheets addObject:stylesheet];\n        }\n      }\n    }\n\n    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];\n    for (NIStylesheet* changedStylesheet in changedStylesheets) {\n      [nc postNotificationName:NIStylesheetDidChangeNotification\n                        object:changedStylesheet\n                      userInfo:nil];\n    }\n  } failure:nil];\n}\n\n- (void)downloadStringsWithFilename:(NSString *)path {\n  NSURL* url = [NSURL URLWithString:[_host stringByAppendingString:path]];\n\n  [self.httpSessionManager GET:url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {\n    NSArray* pathParts = [url.absoluteString pathComponents];\n    NSString* resultPath = [[pathParts subarrayWithRange:NSMakeRange(2, [pathParts count] - 2)]\n                            componentsJoinedByString:@\"/\"];\n    NSString* rootPath = NIPathForDocumentsResource(nil);\n    NSString* hashedPath = [self pathFromPath:resultPath];\n    NSString* diskPath = [rootPath stringByAppendingPathComponent:hashedPath];\n    [responseObject writeToFile:diskPath atomically:YES];\n    \n    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];\n    [nc postNotificationName:NIStringsDidChangeNotification object:nil userInfo:@{\n        NIStringsDidChangeFilePathKey: diskPath\n     }];\n  } failure:nil];\n}\n\n- (void)downloadJSONWithFilename:(NSString *)path {\n  NSURL* url = [NSURL URLWithString:[_host stringByAppendingString:path]];\n\n  [self.httpSessionManager GET:url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {\n    NSArray* pathParts = [url.absoluteString pathComponents];\n    NSString* resultPath = [[pathParts subarrayWithRange:NSMakeRange(2, [pathParts count] - 2)]\n                            componentsJoinedByString:@\"/\"];\n    NSString* rootPath = NIPathForDocumentsResource(nil);\n    NSString* hashedPath = [self pathFromPath:resultPath];\n    NSString* diskPath = [rootPath stringByAppendingPathComponent:hashedPath];\n    [responseObject writeToFile:diskPath atomically:YES];\n\n    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];\n    [nc postNotificationName:NIJSONDidChangeNotification object:nil\n                    userInfo:@{NIJSONDidChangeFilePathKey: diskPath,\n                               NIJSONDidChangeNameKey: path}];\n  } failure:nil];\n}\n\n- (NSString *)pathFromPath:(NSString *)path {\n  return NIMD5HashFromString(path);\n}\n\n#pragma mark - NICSSParserDelegate\n\n\n- (NSString *)cssParser:(NICSSParser *)parser pathFromPath:(NSString *)path {\n  return [self pathFromPath:path];\n}\n\n#pragma mark - Public\n\n\n- (NIStylesheet *)stylesheetForPath:(NSString *)path {\n  return [_stylesheetCache stylesheetWithPath:path];\n}\n\n- (void)watchSkinChanges {\n  NSURL* url = [NSURL URLWithString:[_host stringByAppendingString:@\"watch\"]];\n  NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];\n  request.timeoutInterval = kTimeoutInterval;\n\n  [self.httpSessionManager GET:url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {\n    NSString* stringData = [[NSString alloc] initWithData:responseObject\n                                                 encoding:NSUTF8StringEncoding];\n\n    NSArray* files = [stringData componentsSeparatedByString:@\"\\n\"];\n    for (NSString* filename in files) {\n      if ([[filename lowercaseString] hasSuffix:@\".strings\"]) {\n        [self downloadStringsWithFilename: filename];\n      } else if ([[filename lowercaseString] hasSuffix:@\".json\"]) {\n        [self downloadJSONWithFilename:filename];\n      } else {\n        [self downloadStylesheetWithFilename:filename];\n      }\n    }\n\n    // Immediately start watching for more skin changes.\n    _retryCount = 0;\n    [self watchSkinChanges];\n  } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {\n    if (_retryCount < kMaxNumberOfRetries) {\n      ++_retryCount;\n\n      dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kRetryInterval * NSEC_PER_MSEC));\n      dispatch_after(popTime, dispatch_get_main_queue(), ^(void){\n        [self watchSkinChanges];\n      });\n    }\n  }];\n}\n\n-(void)enableBonjourDiscovery:(NSString *)serviceName\n{\n    self.netBrowser = [[NSNetServiceBrowser alloc] init];\n    self.netBrowser.delegate = self;\n    [self.netBrowser searchForServicesOfType:[NSString stringWithFormat:@\"_%@._tcp\", serviceName] inDomain:@\"\"];\n}\n\n-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing\n{\n    [self.netBrowser stop];\n    self.netBrowser = nil;\n\n    self.netService = aNetService;\n    aNetService.delegate = self;\n    [aNetService resolveWithTimeout:15.0];\n}\n\n-(void)netServiceDidResolveAddress:(NSNetService *)sender\n{\n    _host = [NSString stringWithFormat:@\"http://%@:%zd/\", [sender hostName], [sender port]];\n    self.netService = nil;\n    [self watchSkinChanges];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/NIDOM.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n@class NIStylesheet;\n\n/**\n * A light-weight DOM-like object to which you attach views and stylesheets.\n *\n * @ingroup NimbusCSS\n *\n * To be clear: this is not an HTML DOM, but its intent is the same. NIDOM is designed\n * to simplify the view <=> stylesheet relationship. Add a view to the DOM and it will\n * automatically apply any applicable styles from the attached stylesheet. If the stylesheet\n * changes you can refresh the DOM and all registered views will be updated accordingly.\n *\n * Because NimbusCSS supports positioning and sizing using percentages and relative units,\n * the order of view registration is important. Generally, you should register superviews\n * first, so that any size calculations on their children can occur after their own\n * size has been determined. It's not feasible (or at least advisable) to try and\n * untangle these dependencies automatically.\n *\n * <h2>Example Use</h2>\n *\n * NIDOM is most useful when you create a single NIDOM per view controller.\n *\n@code\nNIStylesheet* stylesheet = [stylesheetCache stylesheetWithPath:@\"root/root.css\"];\n// Create a NIDOM object in your view controller.\n_dom = [[NIDOM alloc] initWithStylesheet:stylesheet];\n@endcode\n *\n * You then register views in the DOM during loadView or viewDidLoad.\n *\n@code\n// Registers a view by itself such that only \"UILabel\" rulesets will apply.\n[_dom registerView:_label];\n\n// Register a view with a specific CSS class. Any rulesets with the \".background\" scope will\n// apply to this view.\n[_dom registerView:self.view withCSSClass:@\"background\"];\n@endcode\n *\n * Once the view controller unloads its view you must unregister all of the views from your DOM.\n *\n@code\n- (void)viewDidUnload {\n  [_dom unregisterAllViews];\n}\n@endcode\n */\n@interface NIDOM : NSObject\n\n// Designated initializer.\n\n- (id)initWithStylesheet:(NIStylesheet *)stylesheet;\n\n+ (id)domWithStylesheet:(NIStylesheet *)stylesheet;\n+ (id)domWithStylesheetWithPathPrefix:(NSString *)pathPrefix paths:(NSString *)path, ...;\n\n+ (id)domWithStylesheet:(NIStylesheet *)stylesheet andParentStyles: (NIStylesheet*) parentStyles;\n\n- (void)registerView:(UIView *)view;\n- (void)registerView:(UIView *)view withCSSClass:(NSString *)cssClass;\n- (void)registerView:(UIView *)view withCSSClass:(NSString *)cssClass andId: (NSString*) viewId;\n\n- (void)addCssClass: (NSString *) cssClass toView: (UIView*) view;\n- (void)removeCssClass: (NSString*) cssClass fromView: (UIView*) view;\n\n- (void)unregisterView:(UIView *)view;\n- (void)unregisterAllViews;\n- (void)refresh;\n- (void)refreshView: (UIView*) view;\n\n-(UIView*)viewById: (NSString*) viewId;\n\n-(NSString*)descriptionForView: (UIView*) view withName: (NSString*) viewName;\n-(NSString*)descriptionForAllViews;\n\n@property (nonatomic,unsafe_unretained) id target;\n@end\n\n/** @name Creating NIDOMs */\n\n/**\n * Initializes a newly allocated DOM with the given stylesheet.\n *\n * @fn NIDOM::initWithStylesheet:\n */\n\n/**\n * Returns an autoreleased DOM initialized with the given stylesheet.\n *\n * @fn NIDOM::domWithStylesheet:\n */\n\n/**\n * Returns an autoreleased DOM initialized with a nil-terminated list of file paths.\n *\n * @fn NIDOM::domWithStylesheetWithPathPrefix:paths:\n */\n\n/**\n * Returns an autoreleased DOM initialized with the given stylesheet and a \"parent\" stylesheet\n * that runs first. Doing this rather than compositing stylesheets can save memory and improve\n * performance in the common case where you have a set of global styles and a bunch of view\n * or view controller specific style sheets.\n *\n * @fn NIDOM::domWithStylesheet:andParentStyles:\n */\n\n/** @name Registering Views */\n\n/**\n * Registers the given view with the DOM.\n *\n * The view's class will be used as the CSS selector when applying styles from the stylesheet.\n *\n * @fn NIDOM::registerView:\n */\n\n/**\n * Registers the given view with the DOM.\n *\n * The view's class as well as the given CSS class string will be used as the CSS selectors\n * when applying styles from the stylesheet.\n *\n * @fn NIDOM::registerView:withCSSClass:\n */\n\n/**\n * Removes the given view from from the DOM.\n *\n * Once a view has been removed from the DOM it will not be restyled when the DOM is refreshed.\n *\n * @fn NIDOM::unregisterView:\n */\n\n/**\n * Removes all views from from the DOM.\n *\n * @fn NIDOM::unregisterAllViews\n */\n\n\n/** @name Re-Applying All Styles */\n\n/**\n * Reapplies the stylesheet to all views. Since there may be positioning involved,\n * you may need to reapply if layout or sizes change.\n *\n * @fn NIDOM::refresh\n */\n\n/**\n * Reapplies the stylesheet to a single view. Since there may be positioning involved,\n * you may need to reapply if layout or sizes change.\n *\n * @fn NIDOM::refreshView:\n */\n\n/**\n * Removes the association of a view with a CSS class. Note that this doesn't\n * \"undo\" the styles that the CSS class generated, it just stops applying them\n * in the future.\n *\n * @fn NIDOM::removeCssClass:fromView:\n */\n\n/**\n * Create an association of a view with a CSS class and apply relevant styles\n * immediately.\n *\n * @fn NIDOM::addCssClass:toView:\n */\n\n/** @name Dynamic View Construction */\n\n/**\n * Using the [UIView buildSubviews:inDOM:] extension allows you to build view\n * hierarchies from JSON (or anything able to convert to NSDictionary/NSArray\n * of simple types) documents, mostly for prototyping. Those documents can\n * specify selectors, and those selectors need a target. This target property\n * will be the target for all selectors in a given DOM. Truth is it only matters\n * during buildSubviews, so in theory you could set and reset it across multiple\n * build calls if you wanted to.\n *\n * @fn NIDOM::target\n */\n\n/** @name Debugging */\n\n/**\n * Describe what would be done to view given the existing registrations for it. In other words, you\n * must call one of the register view variants first before asking for a description. The current\n * implementations return actual objective-c code, using viewName as the target. This allows you to\n * theoretically replace the CSS infrastructure with generated code, if you choose to. More importantly,\n * it allows you to debug what's happening with view styling.\n *\n * @fn NIDOM::descriptionForView:withName:\n */\n\n/**\n * Call descriptionForView for all registered views, in the order they would be applied during refresh\n *\n * @fn NIDOM::descriptionForAllViews\n */\n\n\n@protocol NIDOMView <NSObject>\n- (NSArray *)pseudoClasses;\n@end\n\n/** @name Pseudo Classes */\n\n/**\n * Documentation needed here.\n *\n * @fn NIDOMView::pseudoClasses:\n */\n\n"
  },
  {
    "path": "src/css/src/NIDOM.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIDOM.h\"\n\n#import \"NIStylesheet.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NIDOM ()\n@property (nonatomic,strong) NIStylesheet* stylesheet;\n@property (nonatomic,strong) NSMutableArray* registeredViews;\n@property (nonatomic,strong) NSMutableDictionary* viewToSelectorsMap;\n@property (nonatomic,strong) NSMutableDictionary* idToViewMap;\n@property (nonatomic,strong) NIDOM *parent;\n@end\n\n@implementation NIDOM\n\n\n+ (id)domWithStylesheet:(NIStylesheet *)stylesheet {\n  return [[self alloc] initWithStylesheet:stylesheet];\n}\n\n+ (id)domWithStylesheetWithPathPrefix:(NSString *)pathPrefix paths:(NSString *)path, ... {\n  va_list ap;\n  va_start(ap, path);\n  \n  NIStylesheet* compositeStylesheet = [[NIStylesheet alloc] init];\n  \n  while (nil != path) {\n    NIDASSERT([path isKindOfClass:[NSString class]]);\n    \n    if ([path isKindOfClass:[NSString class]]) {\n      NIStylesheet* stylesheet = [[NIStylesheet alloc] init];\n      if ([stylesheet loadFromPath:path pathPrefix:pathPrefix]) {\n        [compositeStylesheet addStylesheet:stylesheet];\n      }\n    }\n    path = va_arg(ap, NSString*);\n  }\n  va_end(ap);\n  \n  return [[self alloc] initWithStylesheet:compositeStylesheet];\n}\n\n+(id)domWithStylesheet:(NIStylesheet *)stylesheet andParentStyles:(NIStylesheet *)parentStyles\n{\n  NIDOM *dom = [[self alloc] initWithStylesheet:stylesheet];\n  if (parentStyles) {\n    dom.parent = [NIDOM domWithStylesheet:parentStyles andParentStyles:nil];\n  }\n  return dom;\n}\n\n- (id)initWithStylesheet:(NIStylesheet *)stylesheet {\n  if ((self = [super init])) {\n    _stylesheet = stylesheet;\n    _registeredViews = [[NSMutableArray alloc] init];\n    _viewToSelectorsMap = [[NSMutableDictionary alloc] init];\n  }\n  return self;\n}\n\n#pragma mark - Styling Views\n\n\n- (void)refreshStyleForView:(UIView *)view withSelectorName:(NSString *)selectorName {\n  if (self.parent) {\n    [self.parent.stylesheet applyStyleToView:view withClassName:selectorName inDOM:self];\n  }\n  [_stylesheet applyStyleToView:view withClassName:selectorName inDOM:self];\n}\n\n#pragma mark - Public\n\n\n- (id)keyForView:(UIView *)view {\n  return [NSNumber numberWithLong:(long)view];\n}\n\n- (void)registerSelector:(NSString *)selector withView:(UIView *)view {\n  id key = [self keyForView:view];\n  NSMutableArray* selectors = [_viewToSelectorsMap objectForKey:key];\n  if (nil == selectors) {\n    selectors = [[NSMutableArray alloc] init];\n    [_viewToSelectorsMap setObject:selectors forKey:key];\n  }\n  [selectors addObject:selector];\n}\n\n- (void)registerView:(UIView *)view {\n  if (self.parent) {\n    [self.parent registerView:view];\n  }\n  NSString* selector = NSStringFromClass([view class]);\n  [self registerSelector:selector withView:view];\n  \n  NSArray *pseudos = nil;\n  if ([view respondsToSelector:@selector(pseudoClasses)]) {\n    pseudos = (NSArray*) [view performSelector:@selector(pseudoClasses)];\n    if (pseudos) {\n      for (NSString *ps in pseudos) {\n        [self registerSelector:[selector stringByAppendingString:ps] withView:view];\n      }\n    }\n  }\n  \n  [_registeredViews addObject:view];\n  [self refreshStyleForView:view withSelectorName:selector];\n  if (pseudos) {\n    for (NSString *ps in pseudos) {\n      [self refreshStyleForView:view withSelectorName:[selector stringByAppendingString:ps]];\n    }\n  }\n}\n\n- (void)registerView:(UIView *)view withCSSClass:(NSString *)cssClass andId:(NSString *)viewId\n{\n  // These are basically the least specific selectors (by our simple rules), so this needs to get registered first\n  [self registerView:view withCSSClass:cssClass];\n\n  NSArray *pseudos = nil;\n  if (viewId) {\n    if (![viewId hasPrefix:@\"#\"]) { viewId = [@\"#\" stringByAppendingString:viewId]; }\n    if (self.parent) {\n      [self.parent registerSelector:viewId withView:view];\n    }\n    [self registerSelector:viewId withView:view];\n    \n    if ([view respondsToSelector:@selector(pseudoClasses)]) {\n      pseudos = (NSArray*) [view performSelector:@selector(pseudoClasses)];\n      if (pseudos) {\n        for (NSString *ps in pseudos) {\n          if (self.parent) {\n            [self.parent registerSelector:[viewId stringByAppendingString:ps] withView:view];\n          }\n          [self registerSelector:[viewId stringByAppendingString:ps] withView:view];\n        }\n      }\n    }\n\n    if (!_idToViewMap) {\n      _idToViewMap = [[NSMutableDictionary alloc] init];\n    }\n    [_idToViewMap setObject:view forKey:viewId];\n    // Run the id selectors last so they take precedence\n    [self refreshStyleForView:view withSelectorName:viewId];\n    if (pseudos) {\n      for (NSString *ps in pseudos) {\n        [self refreshStyleForView:view withSelectorName:[viewId stringByAppendingString:ps]];\n      }\n    }\n  }\n}\n\n- (void)registerView:(UIView *)view withCSSClass:(NSString *)cssClass registerMainView: (BOOL) registerMainView\n{\n  if (registerMainView) {\n    if (self.parent) {\n      [self.parent registerView:view withCSSClass:cssClass registerMainView:NO];\n    }\n    [self registerView:view];\n  }\n  \n  if (cssClass) {\n    [self addCssClass:cssClass toView:view];\n  }\n}\n\n- (void)registerView:(UIView *)view withCSSClass:(NSString *)cssClass {\n  [self registerView:view withCSSClass:cssClass registerMainView:YES];\n}\n\n-(void)addCssClass:(NSString *)cssClass toView:(UIView *)view\n{\n  NSString* selector = [@\".\" stringByAppendingString:cssClass];\n  [self registerSelector:selector withView:view];\n  \n  // This registers both the UIKit class name and the css class name for this view\n  // Now, we also want to register the 'state based' selectors. Fun.\n  NSArray *pseudos = nil;\n  if ([view respondsToSelector:@selector(pseudoClasses)]) {\n    pseudos = (NSArray*) [view performSelector:@selector(pseudoClasses)];\n    if (pseudos) {\n      for (NSString *ps in pseudos) {\n        [self registerSelector:[selector stringByAppendingString:ps] withView:view];\n      }\n    }\n  }\n  \n  [self refreshStyleForView:view withSelectorName:selector];\n  if (pseudos) {\n    for (NSString *ps in pseudos) {\n      [self refreshStyleForView:view withSelectorName:[selector stringByAppendingString:ps]];\n    }\n  }\n}\n\n-(void)removeCssClass:(NSString *)cssClass fromView:(UIView *)view {\n  NSString* selector = [@\".\" stringByAppendingString:cssClass];\n  NSString* pseudoBase = [selector stringByAppendingString:@\":\"];\n  NSMutableArray *selectors = [_viewToSelectorsMap objectForKey:[self keyForView:view]];\n  if (selectors) {\n    // Iterate over the selectors finding the id selector (if any) so we can\n    // also remove it from the id map\n    for (NSUInteger i = selectors.count; i >= 1; i--) {\n      NSString *s = [selectors objectAtIndex:i - 1];\n      if ([s isEqualToString:selector] && [s hasPrefix:pseudoBase]) {\n        [selectors removeObjectAtIndex:i - 1];\n      }\n    }\n  }\n}\n\n- (void)unregisterView:(UIView *)view {\n  [_registeredViews removeObject:view];\n  NSArray *selectors = [_viewToSelectorsMap objectForKey:[self keyForView:view]];\n  if (selectors) {\n    // Iterate over the selectors finding the id selector (if any) so we can\n    // also remove it from the id map\n    for (NSString *s in selectors) {\n      if ([s characterAtIndex:0] == '#') {\n        [_idToViewMap removeObjectForKey:s];\n      }\n    }\n  }\n  [_viewToSelectorsMap removeObjectForKey:[self keyForView:view]];\n}\n\n- (void)unregisterAllViews {\n  [_registeredViews removeAllObjects];\n  [_viewToSelectorsMap removeAllObjects];\n  [_idToViewMap removeAllObjects];\n}\n\n- (void)refresh {\n  for (UIView* view in _registeredViews) {\n    for (NSString* selector in [_viewToSelectorsMap objectForKey:[self keyForView:view]]) {\n      [self refreshStyleForView:view withSelectorName:selector];\n    }\n  }\n}\n\n- (void)refreshView:(UIView *)view {\n    for (NSString* selector in [_viewToSelectorsMap objectForKey:[self keyForView:view]]) {\n        [self refreshStyleForView:view withSelectorName:selector];\n    }\n}\n\n-(UIView *)viewById:(NSString *)viewId\n{\n  if (![viewId hasPrefix:@\"#\"]) { viewId = [@\"#\" stringByAppendingString:viewId]; }\n  return [_idToViewMap objectForKey:viewId];\n}\n\n-(NSString *)descriptionForView:(UIView *)view withName:(NSString *)viewName\n{\n  NSMutableString *description = [[NSMutableString alloc] init];\n  BOOL appendedStyleInfo = NO;\n  \n  for (NSString *selector in [_viewToSelectorsMap objectForKey:[self keyForView:view]]) {\n    BOOL appendedSelectorInfo = NO;\n    NSString *additional = nil;\n    if (self.parent) {\n      additional = [self.parent.stylesheet descriptionForView: view withClassName: selector inDOM:self andViewName: viewName];\n      if (additional && additional.length) {\n        if (!appendedStyleInfo) { appendedStyleInfo = YES; [description appendFormat:@\"// Styles for %@\\n\", viewName]; }\n        if (!appendedSelectorInfo) { appendedSelectorInfo = YES; [description appendFormat:@\"// Selector %@\\n\", selector]; }\n        [description appendString:additional];\n      }\n    }\n    additional = [_stylesheet descriptionForView:view withClassName: selector inDOM:self andViewName: viewName];\n    if (additional && additional.length) {\n      if (!appendedStyleInfo) { appendedStyleInfo = YES; [description appendFormat:@\"// Styles for %@\\n\", viewName]; }\n      if (!appendedSelectorInfo) { [description appendFormat:@\"// Selector %@\\n\", selector]; }\n      [description appendString:additional];\n    }\n  }\n  return description;\n}\n\n-(NSString *)descriptionForAllViews {\n  NSMutableString *description = [[NSMutableString alloc] init];\n  int viewCount = 0;\n  for (UIView *view in _registeredViews) {\n    [description appendString:@\"\\n///////////////////////////////////////////////////////////////////////////////////////////////////\\n\"];\n    viewCount++;\n    // This is a little hokey - because we don't get individual view names we have to come up with some.\n    __block NSString *vid = nil;\n    [[_viewToSelectorsMap objectForKey:[self keyForView:view]] enumerateObjectsUsingBlock:^(NSString *selector, NSUInteger idx, BOOL *stop) {\n      if ([selector hasPrefix:@\"#\"]) {\n        vid = [selector substringFromIndex:1];\n        *stop = YES;\n      }\n    }];\n    if (vid) {\n      [description appendFormat:@\"UIView *%@_%d = [dom viewById: @\\\"#%@\\\"];\\n\", [view class], viewCount, vid];\n    }\n    [description appendString:[self descriptionForView:view withName:[NSString stringWithFormat:@\"%@_%d\", [view class], viewCount]]];\n  }\n  return description;\n}\n@end\n"
  },
  {
    "path": "src/css/src/NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n@class NICSSRuleset;\n@class NIDOM;\n\n/**\n * The protocol used by the NIStylesheet to apply NICSSRuleSets to views.\n *\n * @ingroup NimbusCSS\n *\n * If you implement this protocol in a category it is recommended that you implement the\n * logic as a separate method and call that method from applyStyleWithRuleSet: so as to allow\n * subclasses to call super implementations. See UILabel+NIStyleable.h/m for an example.\n */\n@protocol NIStyleable <NSObject>\n@required\n\n/**\n * Please implement applyStyleWithRuleSet:inDOM: instead to support relative positioning. The deprecated\n * warning will only catch calls to super rather than implementors, but not sure what else to do.\n */\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet DEPRECATED_ATTRIBUTE;\n\n/**\n * The given ruleset should be applied to the view. The ruleset represents a composite of all\n * rulesets in the applicable stylesheet.\n */\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n@optional\n/**\n * Tells the CSS engine a set of pseudo classes that apply to views of this class.\n * In the case of UIButton, for example, this includes :selected, :highlighted, and :disabled.\n * In CSS, you specify these with selectors like UIButton:active. If you implement this you need to respond\n * to applyStyleWithRuleSet:forPseudoClass:\n *\n * Make sure to include the leading colon.\n */\n- (NSArray*) pseudoClasses;\n\n/**\n * Applies the given rule set to this view but for a pseudo class. Thus it only supports the subset of\n * properties that can be set on states of the view. (e.g. UIButton textColor or background)\n */\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet forPseudoClass: (NSString*) pseudo inDOM: (NIDOM*) dom;\n\n/**\n * Return a string describing what would be done with the view. The current implementations return actual\n * Objective-C using the view name as the message target. The intent is to allow developers to debug\n * the logic, but also to be able to strip out the CSS infrastructure if desired and replace it with manual code.\n */\n- (NSString*) descriptionWithRuleSet: (NICSSRuleset*) ruleSet forPseudoClass: (NSString*) pseudo inDOM: (NIDOM*) dom withViewName: (NSString*) name;\n\n@end\n"
  },
  {
    "path": "src/css/src/NIStylesheet.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n@protocol NICSSParserDelegate;\n@class NICSSRuleset;\n@class NIDOM;\n\n/**\n * The notification key for when a stylesheet has changed.\n *\n * @ingroup NimbusCSS\n *\n * This notification will be sent with the stylesheet as the object. Listeners should add\n * themselves using the stylesheet object that they are interested in.\n *\n * The NSNotification userInfo object will be nil.\n */\nextern NSString* const NIStylesheetDidChangeNotification;\n\n/**\n * Loads and caches information regarding a specific stylesheet.\n *\n * @ingroup NimbusCSS\n *\n * Use this object to load and parse a CSS stylesheet from disk and then apply the stylesheet\n * to views. Rulesets are cached on demand and cleared when a memory warning is received.\n *\n * Stylesheets can be merged using the addStylesheet: method.\n *\n * Cached rulesets are released when a memory warning is received.\n */\n@interface NIStylesheet : NSObject {\n@private\n  NSDictionary* _rawRulesets;\n  NSMutableDictionary* _ruleSets;\n  NSDictionary* _significantScopeToScopes;\n}\n\n@property (nonatomic, readonly, copy) NSSet* dependencies;\n\n- (BOOL)loadFromPath:(NSString *)path\n          pathPrefix:(NSString *)pathPrefix\n            delegate:(id<NICSSParserDelegate>)delegate;\n- (BOOL)loadFromPath:(NSString *)path pathPrefix:(NSString *)path;\n- (BOOL)loadFromPath:(NSString *)path;\n\n- (void)addStylesheet:(NIStylesheet *)stylesheet;\n\n- (void)applyStyleToView:(UIView *)view withClassName:(NSString *)className inDOM: (NIDOM*)dom;\n\n- (NSString*)descriptionForView:(UIView *)view withClassName:(NSString *)className inDOM: (NIDOM*)dom andViewName: (NSString*) viewName;\n\n- (NICSSRuleset *)rulesetForClassName:(NSString *)className;\n\n/**\n * The class to create for rule sets. Default is NICSSRuleset\n */\n+(Class)rulesetClass;\n/**\n * Set the class created to hold rule sets. Default is NICSSRuleset\n */\n+(void)setRulesetClass: (Class) rulesetClass;\n\n@end\n\n\n/** @name Properties */\n\n/**\n * A set of NSString filenames for the @htmlonly@imports@endhtmlonly in this stylesheet.\n *\n * @fn NIStylesheet::dependencies\n */\n\n\n/** @name Loading Stylesheets */\n\n/**\n * Loads and parses a CSS file from disk.\n *\n * @fn NIStylesheet::loadFromPath:pathPrefix:delegate:\n * @param path         The path of the file to be read.\n * @param pathPrefix   [optional] A prefix path that will be prepended to the given path\n *                          as well as any imported files.\n * @param delegate     [optional] A delegate that can reprocess paths.\n * @returns YES if the CSS file was successfully loaded and parsed, NO otherwise.\n */\n\n/**\n * @fn NIStylesheet::loadFromPath:pathPrefix:\n * @sa NIStylesheet::loadFromPath:pathPrefix:delegate:\n */\n\n/**\n * @fn NIStylesheet::loadFromPath:\n * @sa NIStylesheet::loadFromPath:pathPrefix:delegate:\n */\n\n/** @name Compositing Stylesheets */\n\n/**\n * Merge another stylesheet with this one.\n *\n * All property values in the given stylesheet will overwrite values in this stylesheet.\n * Non-overlapping values will not be modified.\n *\n * @fn NIStylesheet::addStylesheet:\n */\n\n\n/** @name Applying Stylesheets to Views */\n\n/**\n * Apply any rulesets that match the className to the given view.\n *\n * @fn NIStylesheet::applyStyleToView:withClassName:\n * @param view       The view for which styles should be applied.\n * @param className  Either the view's class as a string using NSStringFromClass([view class]);\n *                        or a CSS class selector such as \".myClassSelector\".\n * @param dom        The DOM responsible for applying this style\n */\n\n/**\n * Returns an autoreleased ruleset for the given class name.\n *\n * @fn NIStylesheet::rulesetForClassName:\n * @param className  Either the view's class as a string using NSStringFromClass([view class]);\n *                        or a CSS class selector such as \".myClassSelector\".\n */\n\n/** @name Debugging */\n\n/**\n * Build a string describing the rules that would be applied to the view given a css class name in a DOM.\n * Current implementations output Objective-C code that use viewName as the target.\n *\n * @fn NIStylesheet::descriptionForView:withClassName:inDOM:andViewName:\n */\n"
  },
  {
    "path": "src/css/src/NIStylesheet.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIStylesheet.h\"\n\n#import \"NICSSParser.h\"\n#import \"NICSSRuleset.h\"\n#import \"NIStyleable.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNSString* const NIStylesheetDidChangeNotification = @\"NIStylesheetDidChangeNotification\";\nstatic Class _rulesetClass;\n\n@interface NIStylesheet()\n@property (nonatomic, readonly, copy) NSDictionary* rawRulesets;\n@property (nonatomic, readonly, copy) NSDictionary* significantScopeToScopes;\n@end\n\n@implementation NIStylesheet\n\n\n\n- (void)dealloc {\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (id)init {\n  if ((self = [super init])) {\n    _ruleSets = [[NSMutableDictionary alloc] init];\n\n    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];\n    [nc addObserver: self\n           selector: @selector(didReceiveMemoryWarning:)\n               name: UIApplicationDidReceiveMemoryWarningNotification\n             object: nil];\n  }\n\n  return self;\n}\n\n#pragma mark - Rule Sets\n\n\n// Builds a map of significant scopes to full scopes.\n//\n// For example, consider the following rulesets:\n//\n// .root UIButton {\n// }\n// .apple UIButton {\n// }\n// UIButton UIView {\n// }\n// UIView {\n// }\n//\n// The generated scope map will look like:\n//\n// UIButton => (.root UIButton, .apple UIButton)\n// UIView => (UIButton UIView, UIView)\n//\n- (void)rebuildSignificantScopeToScopes {\n  NSMutableDictionary* significantScopeToScopes =\n  [[NSMutableDictionary alloc] initWithCapacity:[_rawRulesets count]];\n\n  for (NSString* scope in _rawRulesets) {\n    NSArray* parts = [scope componentsSeparatedByString:@\" \"];\n    NSString* mostSignificantScopePart = [parts lastObject];\n\n    // TODO (jverkoey Oct 6, 2011): We should respect CSS specificity. Right now this will\n    // give higher precedance to newer styles. Instead, we should prefer styles that have more\n    // selectors.\n    NSMutableArray* scopes = [significantScopeToScopes objectForKey:mostSignificantScopePart];\n    if (nil == scopes) {\n      scopes = [[NSMutableArray alloc] initWithObjects:scope, nil];\n      [significantScopeToScopes setObject:scopes forKey:mostSignificantScopePart];\n      \n    } else {\n      [scopes addObject:scope];\n    }\n  }\n\n  _significantScopeToScopes = [significantScopeToScopes copy];\n}\n\n- (void)ruleSetsDidChange {\n  [self rebuildSignificantScopeToScopes];\n}\n\n#pragma mark - NSNotifications\n\n\n- (void)reduceMemory {\n  _ruleSets = [[NSMutableDictionary alloc] init];\n}\n\n- (void)didReceiveMemoryWarning:(void*)object {\n  [self reduceMemory];\n}\n\n#pragma mark - Public\n\n\n- (BOOL)loadFromPath:(NSString *)path {\n  return [self loadFromPath:path pathPrefix:nil delegate:nil];\n}\n\n- (BOOL)loadFromPath:(NSString *)path pathPrefix:(NSString *)pathPrefix {\n  return [self loadFromPath:path pathPrefix:pathPrefix delegate:nil];\n}\n\n- (BOOL)loadFromPath:(NSString *)path\n          pathPrefix:(NSString *)pathPrefix\n            delegate:(id<NICSSParserDelegate>)delegate {\n  BOOL loadDidSucceed = NO;\n\n  @synchronized(self) {\n    _rawRulesets = nil;\n    _significantScopeToScopes = nil;\n\n    _ruleSets = [[NSMutableDictionary alloc] init];\n\n    NICSSParser* parser = [[NICSSParser alloc] init];\n\n    NSDictionary* results = [parser dictionaryForPath:path\n                                           pathPrefix:pathPrefix\n                                             delegate:delegate];\n    if (nil != results && ![parser didFailToParse]) {\n      _rawRulesets = results;\n      loadDidSucceed = YES;\n    }\n\n    if (loadDidSucceed) {\n      [self ruleSetsDidChange];\n    }\n  }\n\n  return loadDidSucceed;\n}\n\n- (void)addStylesheet:(NIStylesheet *)stylesheet {\n  NIDASSERT(nil != stylesheet);\n  if (nil == stylesheet) {\n    return;\n  }\n\n  @synchronized(self) {\n    NSMutableDictionary* compositeRuleSets = [self.rawRulesets mutableCopy];\n\n    BOOL ruleSetsDidChange = NO;\n\n    for (NSString* selector in stylesheet.rawRulesets) {\n      NSDictionary* incomingRuleSet   = [stylesheet.rawRulesets objectForKey:selector];\n      NSDictionary* existingRuleSet = [self.rawRulesets objectForKey:selector];\n\n      // Don't bother adding empty rulesets.\n      if ([incomingRuleSet count] > 0) {\n        ruleSetsDidChange = YES;\n\n        if (nil == existingRuleSet) {\n          // There is no rule set of this selector - simply add the new one.\n          [compositeRuleSets setObject:incomingRuleSet forKey:selector];\n          continue;\n        }\n\n        NSMutableDictionary* compositeRuleSet = [existingRuleSet mutableCopy];\n        // Add the incoming rule set entries, overwriting any existing ones.\n        [compositeRuleSet addEntriesFromDictionary:incomingRuleSet];\n\n        [compositeRuleSets setObject:compositeRuleSet forKey:selector];\n      }\n    }\n\n    _rawRulesets = [compositeRuleSets copy];\n\n    if (ruleSetsDidChange) {\n      [self ruleSetsDidChange];\n    }\n  }\n}\n\n- (NSString*)descriptionForView:(UIView *)view withClassName:(NSString *)className inDOM:(NIDOM *)dom andViewName:(NSString *)viewName {\n  NSMutableString *description = [[NSMutableString alloc] init];\n  NICSSRuleset *ruleset = [self rulesetForClassName:className];\n  if (nil != ruleset) {\n    NSRange r = [className rangeOfString:@\":\"];\n    if ([view respondsToSelector:@selector(descriptionWithRuleSet:forPseudoClass:inDOM:withViewName:)]) {\n      if (r.location != NSNotFound) {\n        [description appendString:[(id<NIStyleable>)view descriptionWithRuleSet:ruleset forPseudoClass:[className substringFromIndex:r.location+1] inDOM:dom withViewName:viewName]];\n      } else {\n        [description appendString:[(id<NIStyleable>)view descriptionWithRuleSet:ruleset forPseudoClass:nil inDOM:dom withViewName:viewName]];\n      }\n    } else {\n      [description appendFormat:@\"// Description not supported for %@ with selector %@\\n\", view, className];\n    }\n  }\n  return description;\n}\n\n#pragma mark Applying Styles to Views\n\n\n- (void)applyRuleSet:(NICSSRuleset *)ruleSet toView:(UIView *)view inDOM: (NIDOM*)dom {\n  if ([view respondsToSelector:@selector(applyStyleWithRuleSet:inDOM:)]) {\n    [(id<NIStyleable>)view applyStyleWithRuleSet:ruleSet inDOM:dom];\n  }\n  if ([view respondsToSelector:@selector(applyStyleWithRuleSet:)]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n    [(id<NIStyleable>)view applyStyleWithRuleSet:ruleSet];\n#pragma clang diagnostic pop\n  }\n}\n\n- (void)applyStyleToView:(UIView *)view withClassName:(NSString *)className inDOM:(NIDOM *)dom {\n  NICSSRuleset *ruleset = [self rulesetForClassName:className];\n  if (nil != ruleset) {\n    NSRange r = [className rangeOfString:@\":\"];\n    if (r.location != NSNotFound && [view respondsToSelector:@selector(applyStyleWithRuleSet:forPseudoClass:inDOM:)]) {\n      [(id<NIStyleable>)view applyStyleWithRuleSet:ruleset forPseudoClass: [className substringFromIndex:r.location+1] inDOM:dom];\n    } else {\n      [self applyRuleSet:ruleset toView:view inDOM:dom];\n    }\n  }\n}\n\n- (NICSSRuleset*) addSelectors: (NSArray*) selectors toRuleset: (NICSSRuleset*) ruleSet forClassName: (NSString*) className\n{\n  if ([selectors count] > 0) {\n    // Gather all of the rule sets for this view into a composite rule set.\n    ruleSet = ruleSet ?: [_ruleSets objectForKey:className];\n    \n    if (nil == ruleSet) {\n      ruleSet = [[[NIStylesheet rulesetClass] alloc] init];\n      \n      // Composite the rule sets into one.\n      for (NSString* selector in selectors) {\n        [ruleSet addEntriesFromDictionary:[_rawRulesets objectForKey:selector]];\n      }\n      \n      NIDASSERT(nil != _ruleSets);\n      [_ruleSets setObject:ruleSet forKey:className];\n    }\n  }\n  \n  return ruleSet;\n}\n\n- (NICSSRuleset *)rulesetForClassName:(NSString *)className {\n  NSArray* selectors = [_significantScopeToScopes objectForKey:className];\n  return [self addSelectors:selectors toRuleset:nil forClassName:className];\n}\n\n- (NSSet *)dependencies {\n  return [_rawRulesets objectForKey:kDependenciesSelectorKey];\n}\n\n+(Class)rulesetClass\n{\n  return _rulesetClass ?: [NICSSRuleset class];\n}\n\n+(void)setRulesetClass:(Class)rulesetClass\n{\n  _rulesetClass = rulesetClass;\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/NIStylesheetCache.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n@class NIStylesheet;\n\n/**\n * A simple in-memory cache for stylesheets.\n *\n * @ingroup NimbusCSS\n *\n * It is recommended that you use this object to store stylesheets in a centralized location.\n * Ideally you would have one stylesheet cache throughout the lifetime of your application.\n *\n *\n * <h2>Using a stylesheet cache with Chameleon</h2>\n *\n * A stylesheet cache must be used with the Chameleon observer so that changes can be sent\n * for a given stylesheet. This is because changes are sent using the stylesheet object as\n * the notification object, so a listener must register notifications with the stylesheet as\n * the object.\n *\n@code\nNIStylesheet* stylesheet = [stylesheetCache stylesheetWithPath:@\"common.css\"];\nNSNotificationCenter* nc = [NSNotificationCenter defaultCenter];\n[nc addObserver:self\n       selector:@selector(stylesheetDidChange)\n           name:NIStylesheetDidChangeNotification\n         object:stylesheet];\n@endcode\n */\n@interface NIStylesheetCache : NSObject {\n@private\n  NSMutableDictionary* _pathToStylesheet;\n  NSString* _pathPrefix;\n}\n\n@property (nonatomic, readonly, copy) NSString* pathPrefix;\n\n// Designated initializer.\n- (id)initWithPathPrefix:(NSString *)pathPrefix;\n\n- (NIStylesheet *)stylesheetWithPath:(NSString *)path loadFromDisk:(BOOL)loadFromDisk;\n- (NIStylesheet *)stylesheetWithPath:(NSString *)path;\n\n@end\n\n/**\n * The path prefix that will be used to load stylesheets.\n *\n * @fn NIStylesheetCache::pathPrefix\n */\n\n/**\n * Initializes a newly allocated stylesheet cache with a given path prefix.\n *\n * @fn NIStylesheetCache::initWithPathPrefix:\n */\n\n/**\n * Fetches a stylesheet from the in-memory cache if it exists or loads the stylesheet from disk if\n * loadFromDisk is YES.\n *\n * @fn NIStylesheetCache::stylesheetWithPath:loadFromDisk:\n */\n\n/**\n * Fetches a stylesheet from the in-memory cache if it exists or loads the stylesheet from disk.\n *\n * Short form for calling [cache stylesheetWithPath:path loadFromDisk:YES]\n *\n * @fn NIStylesheetCache::stylesheetWithPath:\n */\n"
  },
  {
    "path": "src/css/src/NIStylesheetCache.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIStylesheetCache.h\"\n\n#import \"NIStylesheet.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NIStylesheetCache\n\n\n\n- (id)initWithPathPrefix:(NSString *)pathPrefix {\n  if ((self = [super init])) {\n    _pathToStylesheet = [[NSMutableDictionary alloc] init];\n    _pathPrefix = [pathPrefix copy];\n  }\n  return self;\n}\n\n- (id)init {\n  // This method should not be called directly.\n  NIDASSERT(NO);\n  return [self initWithPathPrefix:nil];\n}\n\n- (NIStylesheet *)stylesheetWithPath:(NSString *)path loadFromDisk:(BOOL)loadFromDisk {\n  NIStylesheet* stylesheet = [_pathToStylesheet objectForKey:path];\n\n  if (nil == stylesheet) {\n    stylesheet = [[NIStylesheet alloc] init];\n    if (loadFromDisk) {\n      BOOL didSucceed = [stylesheet loadFromPath:path\n                                      pathPrefix:_pathPrefix];\n\n      if (didSucceed) {\n        [_pathToStylesheet setObject:stylesheet forKey:path];\n\n      } else {\n        [_pathToStylesheet removeObjectForKey:path];\n        stylesheet = nil;\n      }\n\n    } else {\n      [_pathToStylesheet setObject:stylesheet forKey:path];\n    }\n  }\n  \n  return stylesheet;\n}\n\n- (NIStylesheet *)stylesheetWithPath:(NSString *)path {\n  return [self stylesheetWithPath:path loadFromDisk:YES];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/NITextField+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally written by Max Metral\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NITextField.h\"\n\n@class NICSSRuleset;\n@class NIDOM;\n\n@interface NITextField (NIStyleable)\n\n/**\n * Applies the given rule set to this text field.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyNITextFieldStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n/**\n * Applies the given rule set to this label.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable. Since some of the view\n * styles (e.g. positioning) may rely on some label elements (like text), this is called\n * before the view styling is done.\n */\n- (void)applyNITextFieldStyleBeforeViewWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n/**\n * Applies the given rule set to this text field but for a pseudo class. Thus it only supports the subset of\n * properties that can be set on states of the button. (There's no fancy stuff that applies the styles\n * manually on state transitions.\n *\n * Since UIView doesn't have psuedo's, we don't need the specific version for UIButton like we do with\n * applyButtonStyleWithRuleSet.\n */\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet forPseudoClass: (NSString*) pseudo inDOM: (NIDOM*) dom;\n\n\n@end\n"
  },
  {
    "path": "src/css/src/NITextField+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally written by Max Metral\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NITextField+NIStyleable.h\"\n#import \"UITextField+NIStyleable.h\"\n#import \"UIView+NIStyleable.h\"\n\n#import \"NIDOM.h\"\n#import \"NICSSRuleset.h\"\n#import \"NIUserInterfaceString.h\"\n#import \"NIPreprocessorMacros.h\"\n\nNI_FIX_CATEGORY_BUG(NITextField_NIStyleable)\n\n@implementation NITextField (NIStyleable)\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n    [self applyNITextFieldStyleBeforeViewWithRuleSet:ruleSet inDOM:dom];\n    [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n    [self applyNITextFieldStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n-(void)applyStyleWithRuleSet:(NICSSRuleset*)ruleSet forPseudoClass:(NSString *)pseudo inDOM:(NIDOM*)dom\n{\n    if (ruleSet.hasFont) {\n        self.placeholderFont = ruleSet.font;\n    }\n    if (ruleSet.hasTextColor) {\n        self.placeholderTextColor = ruleSet.textColor;\n    }\n    if (ruleSet.hasTextKey) {\n        NIUserInterfaceString *nis = [[NIUserInterfaceString alloc] initWithKey:ruleSet.textKey];\n        [nis attach:self withSelector:@selector(setPlaceholder:)];\n    }\n}\n\n-(void)applyNITextFieldStyleBeforeViewWithRuleSet:(NICSSRuleset*)ruleSet inDOM:(NIDOM*)dom\n{\n    [self applyTextFieldStyleBeforeViewWithRuleSet:ruleSet inDOM:dom];\n    if (ruleSet.hasTitleInsets) {\n        self.textInsets = ruleSet.titleInsets;\n    }\n}\n\n-(void)applyNITextFieldStyleWithRuleSet:(NICSSRuleset*)ruleSet inDOM:(NIDOM*)dom\n{\n    [self applyTextFieldStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/NIUserInterfaceString.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally written by Max Metral\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n/**\n * The notification key for when a strings file has changed.\n *\n * @ingroup NimbusCSS\n *\n * This notification will be sent globally at the moment.\n *\n * The NSNotification userInfo object will contain the local disk path of the strings file.\n */\nextern NSString* const NIStringsDidChangeNotification;\nextern NSString* const NIStringsDidChangeFilePathKey;\n\n/**\n * A very thin derivative of NSString that will track what user interface\n * elements it has been assigned to and watch for updates via Chameleon\n */\n@class NIUserInterfaceString;\n\n/**\n * A simple NSLocalizedString like macro to make it easier to use NIUserInterfaceStrings\n */\n#define NILocalizedStringWithDefault(key,default) [[NIUserInterfaceString alloc] initWithKey: key defaultValue: default]\n#define NILocalizedStringWithKey(key) [[NIUserInterfaceString alloc] initWithKey: key];\n\n@protocol NIUserInterfaceStringResolver\n@required\n/**\n * The default resolver will just call NSLocalizedString, but also watch the notification center\n * for incoming updates from Chameleon\n */\n-(NSString*)stringForKey: (NSString*) key withDefaultValue: (NSString*) value;\n/**\n * Determine whether string change tracking is enabled or not. Since there\n * is some overhead to this, the default behavior is to return YES\n * if DEBUG is defined, and NO otherwise.\n */\n-(BOOL)isChangeTrackingEnabled;\n@end\n\n/**\n * A very thin derivative of NSString that will track what user interface\n * elements it has been assigned to and watch for updates via Chameleon\n */\n@interface NIUserInterfaceString : NSObject\n@property (nonatomic,strong) NSString *string;\n@property (nonatomic,strong) NSString *originalKey;\n\n/**\n * The global resolver for strings by key\n */\n+(id<NIUserInterfaceStringResolver>)stringResolver;\n/**\n * Set the global resolver for strings by key\n */\n+(void)setStringResolver:(id<NIUserInterfaceStringResolver>)stringResolver;\n\n/**\n * Create a string with the given key using the resolver.\n */\n-(id)initWithKey: (NSString*) key;\n\n/**\n* Create a string with the given key using the resolver and a default value if\n* not found.\n*/\n-(id)initWithKey: (NSString*) key defaultValue: (NSString*) value;\n\n/**\n * Attach a string to a user interface element. Any changes to the string will\n * be sent to the view until the view is dealloced or the string is detached.\n * This method uses setText if available, else setTitle or asserts.\n */\n-(void)attach: (UIView*) view;\n\n/**\n * Attach a string to an element via a selector. The selector must take\n * one argument.\n */\n-(void)attach: (id) element withSelector: (SEL) selector;\n\n/**\n * Attach a string to a user interface element that supports control states.\n * Any changes to the string will be sent to the view until the view is \n * dealloced or the string is detached.\n */\n-(void)attach: (UIView*) view withSelector: (SEL) selector forControlState: (UIControlState) state;\n\n/**\n * Detach a string from a user interface element. This does not \"unset\"\n * the string value itself but it essentially stops tracking changes\n * and frees internal structures.\n */\n-(void)detach: (UIView*) view;\n\n/**\n * Attach a string to an element via a selector. The selector must take\n * one argument.\n */\n-(void)detach: (id) element withSelector: (SEL) selector;\n\n/**\n * Attach a string to an element via a selector. The selector must take\n * one argument.\n */\n-(void)detach: (UIView*) element withSelector: (SEL) selector forControlState: (UIControlState) state;\n\n@end\n"
  },
  {
    "path": "src/css/src/NIUserInterfaceString.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIUserInterfaceString.h\"\n#import \"NIDebuggingTools.h\"\n#import <objc/runtime.h>\n\nstatic NSMutableDictionary*               sStringToViewMap;\nstatic char                               sBaseStringAssocationKey;\nstatic id<NIUserInterfaceStringResolver>  sResolver;\n\nNSString* const NIStringsDidChangeNotification = @\"NIStringsDidChangeNotification\";\nNSString* const NIStringsDidChangeFilePathKey = @\"NIStringsPathKey\";\n\n////////////////////////////////////////////////////////////////////////////////\n/**\n * Information about an attachment\n */\n@interface NIUserInterfaceStringAttachment : NSObject\n@property (unsafe_unretained,nonatomic) id element;\n@property (assign) SEL setter;\n@property (assign) UIControlState controlState;\n@property (assign) BOOL setterIsWithControlState;\n-(void)attach: (NSString*) value;\n@end\n\n////////////////////////////////////////////////////////////////////////////////\n/**\n * This class exists solely to be attached to objects that strings have been\n * attached to so that we can easily detach them on dealloc\n */\n@interface NIUserInterfaceStringDeallocTracker : NSObject\n+(void)attachString: (NIUserInterfaceString*) string withInfo: (NIUserInterfaceStringAttachment*) attachment;\n@property (strong, nonatomic) NIUserInterfaceStringAttachment *attachment;\n@property (strong, nonatomic) NIUserInterfaceString *string;\n@end\n\n////////////////////////////////////////////////////////////////////////////////\n@interface NIUserInterfaceStringResolverDefault : NSObject <\nNIUserInterfaceStringResolver\n>\n// The path of a file that was loaded from Chameleon that should be checked first\n// before the built in bundle\n@property (nonatomic,strong) NSDictionary *overrides;\n// For dev/debug purposes, if we read \"/* SHOW KEYS */\" at the front of the file, we'll\n// just return all keys in the UI\n@property (nonatomic,assign) BOOL returnKeys;\n@end\n\n////////////////////////////////////////////////////////////////////////////////\n@implementation NIUserInterfaceString\n\n+(void)setStringResolver:(id<NIUserInterfaceStringResolver>)stringResolver\n{\n  sResolver = stringResolver;\n}\n\n+(id<NIUserInterfaceStringResolver>)stringResolver\n{\n  return sResolver ?: (sResolver = [[NIUserInterfaceStringResolverDefault alloc] init]);\n}\n\n-(NSMutableDictionary*) viewMap\n{\n  static dispatch_once_t onceToken;\n  dispatch_once(&onceToken, ^{\n    sStringToViewMap = [[NSMutableDictionary alloc] init];\n  });\n  return sStringToViewMap;\n}\n\n////////////////////////////////////////////////////////////////////////////////\n-(id)initWithKey:(NSString *)key\n{\n  return [self initWithKey:key defaultValue:nil];\n}\n\n-(id)initWithKey:(NSString *)key defaultValue: (NSString*) value\n{\n  NSString *v =[[NIUserInterfaceString stringResolver] stringForKey:key withDefaultValue:value];\n  if (!v) { return nil; }\n  \n  self = [super init];\n  if (self) {\n    _string = v;\n    _originalKey = key;\n  }\n  return self;\n}\n\n////////////////////////////////////////////////////////////////////////////////\n-(void)attach:(UIView *)view\n{\n  if ([view respondsToSelector:@selector(setText:)]) {\n    // UILabel\n    [self attach: view withSelector:@selector(setText:)];\n  } else if ([view respondsToSelector:@selector(setTitle:forState:)]) {\n    [self attach:view withSelector:@selector(setTitle:forState:) withControlState:UIControlStateNormal hasControlState:YES];\n  } else if ([view respondsToSelector:@selector(setTitle:)]) {\n    [self attach: view withSelector:@selector(setTitle:)];\n  } else {\n    NIDASSERT([view respondsToSelector:@selector(setText:)] || [view respondsToSelector:@selector(setTitle:)]);\n  }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n-(void)attach:(id)element withSelector:(SEL)selector\n{\n  [self attach:element withSelector:selector withControlState:UIControlStateNormal hasControlState:NO];\n}\n\n////////////////////////////////////////////////////////////////////////////////\n-(void)attach:(UIView *)view withSelector:(SEL)selector forControlState:(UIControlState)state\n{\n  [self attach:view withSelector:selector withControlState:state hasControlState:YES];\n}\n\n////////////////////////////////////////////////////////////////////////////////\n-(void)attach:(id)element withSelector:(SEL)selector withControlState: (UIControlState) state hasControlState: (BOOL) hasControlState\n{\n  NIUserInterfaceStringAttachment *attachment = [[NIUserInterfaceStringAttachment alloc] init];\n  attachment.element = element;\n  attachment.controlState = state;\n  attachment.setterIsWithControlState = hasControlState;\n  attachment.setter = selector;\n  \n  // If we're keeping track of attachments, set all that up. Else just call the selector\n  if ([[NIUserInterfaceString stringResolver] isChangeTrackingEnabled]) {\n    NSMutableDictionary *viewMap =  self.viewMap;\n    @synchronized (viewMap) {\n      // Call this first, because if there's an existing association, it will detach it in dealloc\n      [NIUserInterfaceStringDeallocTracker attachString:self withInfo:attachment];\n      id existing = [viewMap objectForKey:_originalKey];\n      if (!existing) {\n        // Simple, no map exists, make one\n        [viewMap setObject:attachment forKey:_originalKey];\n      } else if ([existing isKindOfClass: [NIUserInterfaceStringAttachment class]]) {\n        // An attachment exists, convert it to a list\n        NSMutableArray *list = [[NSMutableArray alloc] initWithCapacity:2];\n        [list addObject:existing];\n        [list addObject:attachment];\n        [viewMap setObject:list forKey:_originalKey];\n      } else {\n        // NSMutableArray*\n        NSMutableArray *a = (NSMutableArray*) existing;\n        [a addObject: attachment];\n      }\n    }\n  }\n  [attachment attach: _string];\n}\n\n////////////////////////////////////////////////////////////////////////////////\n-(void)detach:(UIView *)view\n{\n  if ([view respondsToSelector:@selector(setText:)]) {\n    // UILabel\n    [self detach: view withSelector:@selector(setText:) withControlState:UIControlStateNormal hasControlState:NO];\n  } else if ([view respondsToSelector:@selector(setTitle:)]) {\n    [self detach: view withSelector:@selector(setTitle:) withControlState:UIControlStateNormal hasControlState:NO];\n  } else {\n    NIDASSERT([view respondsToSelector:@selector(setText:)] || [view respondsToSelector:@selector(setTitle:)]);\n  }\n  \n}\n\n-(void)detach:(id)element withSelector:(SEL)selector\n{\n  [self detach:element withSelector:selector withControlState:UIControlStateNormal hasControlState:NO];\n}\n\n-(void)detach:(UIView *)element withSelector:(SEL)selector forControlState:(UIControlState)state\n{\n  [self detach:element withSelector:selector withControlState:state hasControlState:YES];\n}\n\n-(void)detach:(id)element withSelector:(SEL)selector withControlState: (UIControlState) state hasControlState: (BOOL) hasControlState\n{\n  NSMutableDictionary *viewMap = self.viewMap;\n  @synchronized (viewMap) {\n    \n  }\n}\n\n@end\n\n////////////////////////////////////////////////////////////////////////////////\n@implementation NIUserInterfaceStringResolverDefault\n\n-(id)init\n{\n  self = [super init];\n  if (self) {\n    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stringsDidChange:) name:NIStringsDidChangeNotification object:nil];\n  }\n  return self;\n}\n\n-(void)dealloc\n{\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n-(void)stringsDidChange: (NSNotification*) notification\n{\n  NSString *path = [notification.userInfo objectForKey:NIStringsDidChangeFilePathKey];\n  NSString *content = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];\n\n  if ([content hasPrefix:@\"/* SHOW KEYS */\"]) {\n    self.returnKeys = YES;\n  } else {\n    self.returnKeys = NO;\n  }\n  self.overrides = [[NSDictionary alloc] initWithContentsOfFile:path];\n  if (sStringToViewMap && self.overrides.count > 0) {\n    @synchronized (sStringToViewMap) {\n      [sStringToViewMap enumerateKeysAndObjectsUsingBlock:^(NSString* key, id obj, BOOL *stop) {\n        NSString *o = self.returnKeys ? key : [self.overrides objectForKey:key];\n        if (o) {\n          if ([obj isKindOfClass:[NIUserInterfaceStringAttachment class]]) {\n            [((NIUserInterfaceStringAttachment*)obj) attach: o];\n          } else {\n            NSArray *attachments = (NSArray*) obj;\n            for (NIUserInterfaceStringAttachment *a in attachments) {\n              [a attach:o];\n            }\n          }\n        }\n      }];\n    }\n  }\n}\n\n-(NSString *)stringForKey:(NSString *)key withDefaultValue:(NSString *)value\n{\n  if (self.returnKeys) {\n    return key; // TODO should we maybe return \n  }\n  if (self.overrides) {\n    NSString *overridden = [self.overrides objectForKey:key];\n    if (overridden) {\n      return overridden;\n    }\n  }\n  return NSLocalizedStringWithDefaultValue(key, nil, [NSBundle mainBundle], value, nil);\n}\n\n-(BOOL)isChangeTrackingEnabled\n{\n#ifdef DEBUG\n  return YES;\n#else\n  return NO;\n#endif\n}\n@end\n\n////////////////////////////////////////////////////////////////////////////////\n@implementation NIUserInterfaceStringAttachment\n-(void)attach: (NSString*) value\n{\n  if (self.setterIsWithControlState) {\n    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[_element methodSignatureForSelector:_setter]];\n    [inv setSelector:_setter];\n    [inv setTarget:_element];\n    [inv setArgument:&value atIndex:2]; //this is the string to set (0 and 1 are self and message respectively)\n    [inv setArgument:&_controlState atIndex:3];\n    [inv invoke];\n  } else {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n    [_element performSelector:_setter withObject:value];\n#pragma clang diagnostic pop\n  }\n}\n@end\n\n////////////////////////////////////////////////////////////////////////////////\n@implementation NIUserInterfaceStringDeallocTracker\n+(void)attachString:(NIUserInterfaceString *)string withInfo:(NIUserInterfaceStringAttachment *)attachment\n{\n  NIUserInterfaceStringDeallocTracker *tracker = [[NIUserInterfaceStringDeallocTracker alloc] init];\n  tracker.attachment = attachment;\n  tracker.string = string;\n  char* key = &sBaseStringAssocationKey;\n  if (attachment.setterIsWithControlState) {\n    key += attachment.controlState;\n  }\n  objc_setAssociatedObject(attachment.element, key, tracker, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n-(void)dealloc\n{\n  [self.string detach:self.attachment.element withSelector:self.attachment.setter withControlState:self.attachment.controlState hasControlState:self.attachment.setterIsWithControlState];\n}\n@end\n"
  },
  {
    "path": "src/css/src/NimbusCSS.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n/**\n * @defgroup NimbusCSS Nimbus CSS\n * @{\n *\n * <div id=\"github\" feature=\"css\"></div>\n *\n * Nimbus CSS allows you to use cascading stylesheets to theme your native iOS application.\n * Stylesheets provide a number of advantages over Interface Builder and native code.\n *\n * - Diffing CSS files is much easier than diffing Interface Builder's xibs.\n * - CSS allows you to define cascading styles. Change one line and an entire class of views\n *   throughout your application will change.\n * - CSS can be downloaded and swapped out post-App Store submission if you want to make any\n *   minor stylistic changes in production.\n * - On that same note, CSS stylesheets can be swapped at runtime allowing you to easily change\n *   the application's UI when the app state changes. A good example of this is the Rdio app\n *   when you go into offline mode and the app's online components gray out.\n * - Chameleon - modify CSS files and watch the changes affect your app in real time.\n *\n * <h2>How to Create a Stylesheet</h2>\n *\n * Start by creating a .css file. Add it to your project, ensuring that you include it in\n * the copy resources phase. Place all of your CSS files in a subdirectory and add the folder\n * to your project by creating a folder reference. Creating a folder reference will ensure\n * that your subdirectories are maintained when the CSS files are copied to the device.\n *\n * You can then load the stylesheet:\n *\n@code\n// In this example all of the app's css files are in a \"css\" folder. The \"css\" folder would be\n// dragged into the Xcode project with the \"Create folder reference\" option selected.\nNSString* pathPrefix = NIPathForBundleResource(nil, @\"css\");\nNIStylesheet* stylesheet = [[[NIStylesheet alloc] init] autorelease];\nif ([stylesheet loadFromPath:\"common.css\"\n                  pathPrefix:pathPrefix]) {\n  // Successfully loaded <bundlePath>/css/common.css\n}\n@endcode\n *\n *\n * <h2>Recommended Procedure for Storing Stylesheets</h2>\n *\n * Use a global NIStylesheetCache object to store your stylesheets in memory. Parsing a stylesheet\n * is fast but care should be taken to avoid loading a stylesheet more often than necessary.\n * By no means should you be allocating new stylesheets in tight loops.\n * Using a global NIStylesheetCache will make it easy to ensure that your stylesheets are\n * cached in memory and easily accessible.\n *\n * Another advantage to using a global NIStylesheetCache is that it allows you to easily use\n * Chameleon. Chameleon will post notifications on the stylesheet objects\n * registered in the NIStylesheetCache. Because the observer and you will use the same cache,\n * you can register for notifications on the same stylesheet objects.\n *\n * The above example would look like this if you used a stylesheet cache:\n *\n@code\n// In your app initialization code, create a global stylesheet cache:\nNSString* pathPrefix = NIPathForBundleResource(nil, @\"resources/css\");\n_stylesheetCache = [[NIStylesheetCache alloc] initWithPathPrefix:pathPrefix];\n@endcode\n *\n@code\n// Elsewhere in your app, when you need access to any stylesheet:\nNIStylesheetCache* stylesheetCache =\n  [(AppDelegate *)[UIApplication sharedApplication].delegate stylesheetCache];\nNIStylesheet* stylesheet = [stylesheetCache stylesheetWithPath:@\"common.css\"];\n@endcode\n *\n * Reduce the dependencies on your application delegate by defining a global method somewhere:\n *\n@code\nNIStylesheetCache* StylesheetCache(void);\n@endcode\n *\n@code\n#import \"AppDelegate.h\"\n\nNIStylesheetCache* StylesheetCache(void) {\n  return [(AppDelegate *)[UIApplication sharedApplication].delegate stylesheetCache];\n}\n@endcode\n *\n *\n * <h2>Using a Stylesheet</h2>\n *\n * The easiest way to apply a stylesheet to a set of views is by using a NIDOM object. Once\n * you attach a stylesheet to an NIDOM object, the stylesheet will be applied to any views you\n * attach to the NIDOM object.\n *\n *\n * <h2>Linking to Other Stylesheets</h2>\n *\n * You can link to one stylesheet from another using @htmlonly @import url('url')@endhtmlonly\n * in the .css file.\n *\n * For example, let's say you have a common CSS file, common.css, and a CSS file for a specific\n * view controller, profile.css. You can import common.css in profile.css by adding the following\n * line:\n *\n * @htmlonly @import url('common.css')@endhtmlonly\n *\n * Files are imported relative to the pathPrefix given to NIStylesheet.\n *\n * <h3>CSS Import Ordering Gotcha</h3>\n *\n * One might expect that placing an @htmlonly @import@endhtmlonly in the middle of a CSS\n * file would import the file at that exact location. This is not currently the case,\n * i.e. the parser does not insert the imported CSS where the @htmlonly @import@endhtmlonly\n * is. Instead, all of the CSS within the imported stylesheet will be processed before\n * the importer's CSS.\n *\n * For example, even if @htmlonly @import url('common.css')@endhtmlonly is placed at\n * the bottom of the profile.css file, common.css will be processed first, followed by profile.css.\n *\n * This is a known limitation and will ideally be fixed in a later release.\n *\n * Relative ordering of @htmlonly @imports@endhtmlonly is respected.\n *\n *\n * <h2>Supported CSS Properties</h2>\n *\n@code\n\nUIView {\n  border: <dimension> <ignored> <color> {view.layer.borderWidth view.layer.borderColor}\n  border-color: <color>       {view.layer.borderColor}\n  border-width: <dimension>   {view.layer.borderWidth}\n  background-color: <color|image_name>   {view.backgroundColor}\n  border-radius: <dimension>  {view.layer.cornerRadius}\n  opacity: xx.xx              {view.alpha}\n  -ios-autoresizing: [left|top|right|bottom|width|height|all|margins|dimensions]    {view.autoresizingMask}\n  visibility: [hidden|visible] {view.hidden}\n  width: [x%,xpx,auto]          {view.frameWidth}\n  height: [x%,xpx,auto]         {view.frameHeight}\n  padding: <vertical unit> <horizontal unit> {used in auto height and width calculations}\n  -mobile-hpadding: <horizontal unit>   {used in auto width}\n  -mobile-vpadding: <vertical unit>     {used in auto height}\n  max-width: [x%,xpx]           {view.frameWidth}\n  max-height: [x%,xps]          {view.frameHeight}\n  min-width: [x%,xpx]           {view.frameWidth}\n  min-height: [x%,xps]          {view.frameHeight}\n  top: [x%,xpx]                 {view.frameMinY}\n  left: [x%,xpx]                {view.frameMinX}\n  bottom: [x%,xpx]              {view.frameMaxY}\n  right: [x%,xpx]               {view.frameMaxX}\n  -mobile-halign: [left|right|center]   {view.frameX}\n  -mobile-valign: [top|bottom|middle]   {view.frameY}\n  -mobile-relative: [#id|.prev|.next|.first|.last]  {controls the position of the view relative to another view}\n  margin-top: [x%,xpx,auto]     {distance from view.frameMinY to relative.frameMaxY - % is relative to size of relative element, px is absolute, auto aligns the vertical centers}\n margin-bottom: [x%,xpx,auto]     {distance from view.frameMaxY to relative.frameMinY - % is relative to size of relative element, px is absolute, auto aligns the vertical centers}\n margin-left: [x%,xpx,auto]     {distance from view.frameMinX to relative.frameMaxX - % is relative to size of relative element, px is absolute, auto aligns the horizontal centers}\n margin-right: [x%,xpx,auto]     {distance from view.frameMaxX to relative.frameMinX - % is relative to size of relative element, px is absolute, auto aligns the horizontal centers}\n}\n\nUILabel {\n  color: <color>                  {label.textColor}\n\n  font: <font-size> <font-name>   {label.font}\n  font-size: <font-size>          {label.font}\n  font-family: <font-name>        {label.font}\n\n  Can not be used in conjunction with font/font-family properties. Use the italic/bold font\n  name instead.\n  font-style: [italic|normal]     {label.font}\n  font-weight: [bold|normal]      {label.font}\n\n  text-align: [left|right|center] {label.textAlignment}\n\n  text-shadow: <color> <x-offset> <y-offset> {label.shadowColor label.shadowOffset}\n\n  -ios-highlighted-color: <color>      {label.highlightedTextColor}\n  -ios-line-break-mode: [wrap|character-wrap|clip|head-truncate|tail-truncate|middle-truncate] [label.lineBreakMode]\n  -ios-number-of-lines: xx             {label.numberOfLines}\n  -ios-minimum-font-size: <font-size>  {label.minimumFontSize}\n  -ios-adjusts-font-size: [true|false] {label.adjustsFontSizeToFitWidth}\n  -ios-baseline-adjustment: [align-baselines|align-centers|none] {label.baselineAdjustment}\n  -mobile-text-key: \"Key Name\"          {attaches a localized string (or the key name if not found) to this label}\n}\n\nUIButton {\n  -mobile-title-insets\n  -mobile-content-insets\n  -mobile-image-insets\n  font: <font-size> <font-name>   {button.font}\n \n  Buttons also support pseudo selectors: :selected,:highlighted,:disabled with the following rules:\n  color: <color>        {[button titleColorForState:]}\n  text-shadow: <color>  {[button titleShadowColorForState:]}\n  -mobile-image: url(image_name)\n  -mobile-text-key: \"Key Name\"          {attaches a localized string (or the key name if not found) to this button}\n  background-image: url(image_name)\n  -mobile-background-stretch: top left bottom right\n  -ios-button-adjust\n}\n\nUINavigationBar {\n  -ios-tint-color: <color>  {navBar.tintColor}\n}\n \n UISearchBar {\n -ios-tint-color: <color>  {searchBar.tintColor}\n }\n \n UIToolbar {\n -ios-tint-color: <color>  {toolbar.tintColor}\n }\n@endcode\n *\n *\n * <h2>Chameleon</h2>\n *\n * Chameleon is a web server that serves changes to CSS files in real time.\n *\n * You start Chameleon from the command line using node.js and tell it to watch a specific\n * directory of CSS files for changes. This should ideally be the directory that contains\n * all of your project's CSS files.\n *\n * Note: ensure that when you add the css directory to your project that it is added as a folder\n * reference. This will ensure that the complete folder hierarchy is maintained when the files\n * are copied to the device.\n *\n * To learn more about how to start up a Chameleon server, view the README file within\n * nimbus/src/css/chameleon/. This README will walk you through the necessary steps to build\n * and install node.js.\n *\n * Once you've started the Chameleon server, you simply create a Chameleon observer in your\n * application, give it access to your global stylesheet cache, and then tell it to start\n * watching Chameleon for skin changes. This logic is summed up below:\n@code\n_chameleonObserver = [[NIChameleonObserver alloc] initWithStylesheetCache:_stylesheetCache\n                                                                     host:host];\n[_chameleonObserver watchSkinChanges];\n@endcode\n *\n * You then simply register for NIStylesheetDidChangeNotification notifications on the stylesheets\n * that you are interested in. You will get a notification when the stylesheet has been modified,\n * at which point if you're using NIDOM you can tell the NIDOM object to refresh itself;\n * this will reapply the stylesheet to all of its attached views.\n */\n\n/**@}*/\n\n#import \"NICSSRuleSet.h\"\n#import \"NICSSParser.h\"\n#import \"NIDOM.h\"\n#import \"NIStyleable.h\"\n#import \"NIStylesheet.h\"\n#import \"NIStylesheetCache.h\"\n#import \"NIChameleonObserver.h\"\n\n// Styleable UIKit views\n#import \"UIButton+NIStyleable.h\"\n#import \"UILabel+NIStyleable.h\"\n#import \"UINavigationBar+NIStyleable.h\"\n#import \"UISearchBar+NIStyleable.h\"\n#import \"UIToolbar+NIStyleable.h\"\n#import \"UIView+NIStyleable.h\"\n\n// Dependencies\n#import \"NimbusCore.h\"\n"
  },
  {
    "path": "src/css/src/UIActivityIndicatorView+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NICSSRuleset;\n@class NIDOM;\n\n@interface UIActivityIndicatorView (NIStyleable)\n\n/**\n * Applies the given rule set to this acitivity indicator view.\n * Use applyActivityIndicatorStyleWithRuleSet:inDOM: instead.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyActivityIndicatorStyleWithRuleSet:(NICSSRuleset *)ruleSet DEPRECATED_ATTRIBUTE;\n\n/**\n * Applies the given rule set to this acitivity indicator view.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyActivityIndicatorStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM*) dom;\n\n@end\n"
  },
  {
    "path": "src/css/src/UIActivityIndicatorView+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UIActivityIndicatorView+NIStyleable.h\"\n\n#import \"UIView+NIStyleable.h\"\n#import \"NICSSRuleset.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNI_FIX_CATEGORY_BUG(UIActivityIndicatorView_NIStyleable)\n\n@implementation UIActivityIndicatorView (NIStyleable)\n\n\n- (void)applyActivityIndicatorStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyActivityIndicatorStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n- (void)applyActivityIndicatorStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  if ([ruleSet hasActivityIndicatorStyle]) { [self setActivityIndicatorViewStyle:ruleSet.activityIndicatorStyle]; } else { [self setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge]; }\n  if ([ruleSet hasTextColor]) { [self setColor:ruleSet.textColor]; }\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n  [self applyActivityIndicatorStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/UIButton+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NICSSRuleset;\n@class NIDOM;\n\n@interface UIButton (NIStyleable)\n\n/**\n * Applies the given rule set to this button. Call applyButtonStyleWithRuleSet:inDOM:\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyButtonStyleWithRuleSet:(NICSSRuleset *)ruleSet DEPRECATED_ATTRIBUTE;\n\n/**\n * Applies the given rule set to this button.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyButtonStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n/**\n * Applies the given rule set to this label.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable. Since some of the view\n * styles (e.g. positioning) may rely on some label elements (like text), this is called\n * before the view styling is done.\n */\n- (void)applyButtonStyleBeforeViewWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n/**\n * Tells the CSS engine a set of pseudo classes that apply to views of this class.\n * In the case of UIButton, this includes :selected, :highlighted, and :disabled.\n * In CSS, you specify these with selectors like UIButton:active. If you implement this you need to respond\n * to applyStyleWithRuleSet:forPseudoClass:inDOM:\n *\n * Make sure to include the leading colon.\n */\n- (NSArray*) pseudoClasses;\n\n/**\n * Applies the given rule set to this button but for a pseudo class. Thus it only supports the subset of\n * properties that can be set on states of the button. (There's no fancy stuff that applies the styles\n * manually on state transitions.\n *\n * Since UIView doesn't have psuedo's, we don't need the specific version for UIButton like we do with\n * applyButtonStyleWithRuleSet.\n */\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet forPseudoClass: (NSString*) pseudo inDOM: (NIDOM*) dom;\n\n@end\n"
  },
  {
    "path": "src/css/src/UIButton+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UIButton+NIStyleable.h\"\n\n#import \"UIView+NIStyleable.h\"\n#import \"NICSSRuleset.h\"\n#import \"NimbusCore.h\"\n#import \"NIUserInterfaceString.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNI_FIX_CATEGORY_BUG(UIButton_NIStyleable)\n\n@implementation UIButton (NIStyleable)\n\n- (void)applyButtonStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyButtonStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n-(void)applyButtonStyleBeforeViewWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom\n{\n  if (ruleSet.hasFont) {\n    self.titleLabel.font = ruleSet.font;\n  }\n  if (ruleSet.hasTextKey) {\n    NIUserInterfaceString *nis = [[NIUserInterfaceString alloc] initWithKey:ruleSet.textKey];\n    [nis attach:self withSelector:@selector(setTitle:forState:) forControlState:UIControlStateNormal];\n  }\n}\n\n- (void)applyButtonStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  if ([ruleSet hasTextColor]) {\n    // If you want to reset this color, set none as the color\n    [self setTitleColor:ruleSet.textColor forState:UIControlStateNormal];\n  }\n  if ([ruleSet hasTextShadowColor]) {\n    // If you want to reset this color, set none as the color\n    [self setTitleShadowColor:ruleSet.textShadowColor forState:UIControlStateNormal];\n  }\n  if (ruleSet.hasImage) {\n    [self setImage:[UIImage imageNamed:ruleSet.image] forState:UIControlStateNormal];\n  }\n  if (ruleSet.hasBackgroundImage) {\n    UIImage *backImage = [UIImage imageNamed:ruleSet.backgroundImage];\n    if (ruleSet.hasBackgroundStretchInsets) {\n      backImage = [backImage resizableImageWithCapInsets:ruleSet.backgroundStretchInsets];\n    }\n    [self setBackgroundImage:backImage forState:UIControlStateNormal];\n  }\n  if ([ruleSet hasTextShadowOffset]) {\n    self.titleLabel.shadowOffset = ruleSet.textShadowOffset;\n  }\n  if ([ruleSet hasTitleInsets]) { self.titleEdgeInsets = ruleSet.titleInsets; }\n  if ([ruleSet hasContentInsets]) { self.contentEdgeInsets = ruleSet.contentInsets; }\n  if ([ruleSet hasImageInsets]) { self.imageEdgeInsets = ruleSet.imageInsets; }\n  if ([ruleSet hasButtonAdjust]) {\n    self.adjustsImageWhenDisabled = ((ruleSet.buttonAdjust & NICSSButtonAdjustDisabled) != 0);\n    self.adjustsImageWhenHighlighted = ((ruleSet.buttonAdjust & NICSSButtonAdjustHighlighted) != 0);\n  }\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  [self applyButtonStyleBeforeViewWithRuleSet:ruleSet inDOM:dom];\n  [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n  [self applyButtonStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n-(void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet forPseudoClass:(NSString *)pseudo inDOM:(NIDOM *)dom\n{\n  UIControlState state = UIControlStateNormal;\n  if ([pseudo caseInsensitiveCompare:@\"selected\"] == NSOrderedSame) {\n    state = UIControlStateSelected;\n  } else if ([pseudo caseInsensitiveCompare:@\"highlighted\"] == NSOrderedSame) {\n    state = UIControlStateHighlighted;\n  } else if ([pseudo caseInsensitiveCompare:@\"disabled\"] == NSOrderedSame) {\n    state = UIControlStateDisabled;\n  }\n  if (ruleSet.hasTextKey) {\n      NIUserInterfaceString *nis = [[NIUserInterfaceString alloc] initWithKey:ruleSet.textKey];\n      [nis attach:self withSelector:@selector(setTitle:forState:) forControlState:state];\n  }\n  if (ruleSet.hasTextColor) {\n    [self setTitleColor:ruleSet.textColor forState:state];\n  }\n  if (ruleSet.hasTextShadowColor) {\n    [self setTitleShadowColor:ruleSet.textShadowColor forState:state];\n  }\n  if (ruleSet.hasImage) {\n    [self setImage:[UIImage imageNamed:ruleSet.image] forState:state];\n  }\n  if (ruleSet.hasBackgroundImage) {\n    UIImage *backImage = [UIImage imageNamed:ruleSet.backgroundImage];\n    if (ruleSet.hasBackgroundStretchInsets) {\n      backImage = [backImage resizableImageWithCapInsets:ruleSet.backgroundStretchInsets];\n    }\n    [self setBackgroundImage:backImage forState:state];\n  }\n}\n\n-(NSArray *)pseudoClasses\n{\n  static dispatch_once_t onceToken;\n  static NSArray *buttonPseudos;\n  dispatch_once(&onceToken, ^{\n    buttonPseudos = @[@\":selected\", @\":highlighted\", @\":disabled\"];\n  });\n  return buttonPseudos;\n}\n@end\n"
  },
  {
    "path": "src/css/src/UILabel+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NICSSRuleset;\n@class NIDOM;\n\n@interface UILabel (NIStyleable)\n\n/**\n * Applies the given rule set to this label.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyLabelStyleWithRuleSet:(NICSSRuleset *)ruleSet DEPRECATED_ATTRIBUTE;\n\n/**\n * Applies the given rule set to this label.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyLabelStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n/**\n * Applies the given rule set to this label.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable. Since some of the view\n * styles (e.g. positioning) may rely on some label elements (like text), this is called\n * before the view styling is done.\n */\n- (void)applyLabelStyleBeforeViewWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n@end\n"
  },
  {
    "path": "src/css/src/UILabel+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UILabel+NIStyleable.h\"\n\n#import \"UIView+NIStyleable.h\"\n#import \"NICSSRuleset.h\"\n#import \"NimbusCore.h\"\n#import \"NIUserInterfaceString.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNI_FIX_CATEGORY_BUG(UILabel_NIStyleable)\n\n@implementation UILabel (NIStyleable)\n\n\n- (void)applyLabelStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyLabelStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n- (void)applyLabelStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  if ([ruleSet hasTextColor]) { self.textColor = ruleSet.textColor; }\n  if ([ruleSet hasHighlightedTextColor]) { self.highlightedTextColor = ruleSet.highlightedTextColor; }\n  if ([ruleSet hasTextAlignment]) { self.textAlignment = ruleSet.textAlignment; }\n  if ([ruleSet hasFont]) { self.font = ruleSet.font; }\n  if ([ruleSet hasTextShadowColor]) { self.shadowColor = ruleSet.textShadowColor; }\n  if ([ruleSet hasTextShadowOffset]) { self.shadowOffset = ruleSet.textShadowOffset; }\n  if ([ruleSet hasLineBreakMode]) { self.lineBreakMode = ruleSet.lineBreakMode; }\n  if ([ruleSet hasNumberOfLines]) { self.numberOfLines = ruleSet.numberOfLines; }\n  if ([ruleSet hasMinimumFontSize]) { self.minimumFontSize = ruleSet.minimumFontSize; }\n  if ([ruleSet hasAdjustsFontSize]) { self.adjustsFontSizeToFitWidth = ruleSet.adjustsFontSize; }\n  if ([ruleSet hasBaselineAdjustment]) { self.baselineAdjustment = ruleSet.baselineAdjustment; }\n}\n\n-(void)applyLabelStyleBeforeViewWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom\n{\n  if (ruleSet.hasTextKey) {\n    NIUserInterfaceString *nis = [[NIUserInterfaceString alloc] initWithKey:ruleSet.textKey];\n    [nis attach:self withSelector:@selector(setText:)];\n  }\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  [self applyLabelStyleBeforeViewWithRuleSet:ruleSet inDOM:dom];\n  [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n  [self applyLabelStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/UINavigationBar+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NICSSRuleset;\n@class NIDOM;\n\n@interface UINavigationBar (NIStyleable)\n\n/**\n * Applies the given rule set to this navigation bar. Use applyNavigationBarStyleWithRuleSet:inDOM: instead\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyNavigationBarStyleWithRuleSet:(NICSSRuleset *)ruleSet DEPRECATED_ATTRIBUTE;\n\n/**\n * Applies the given rule set to this navigation bar.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyNavigationBarStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n@end\n"
  },
  {
    "path": "src/css/src/UINavigationBar+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UINavigationBar+NIStyleable.h\"\n\n#import \"UIView+NIStyleable.h\"\n#import \"NICSSRuleset.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNI_FIX_CATEGORY_BUG(UINavigationBar_NIStyleable)\n\n@implementation UINavigationBar (NIStyleable)\n\n- (void)applyNavigationBarStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyNavigationBarStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n- (void)applyNavigationBarStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  if ([ruleSet hasTintColor]) { self.tintColor = ruleSet.tintColor; }\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n  [self applyNavigationBarStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/UIScrollView+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NIDOM;\n@class NICSSRuleset;\n\n@interface UIScrollView (NIStyleable)\n\n/**\n * Applies the given rule set to this scroll view.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyScrollViewStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM*) dom;\n\n@end\n"
  },
  {
    "path": "src/css/src/UIScrollView+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UIScrollView+NIStyleable.h\"\n\n#import \"UIView+NIStyleable.h\"\n#import \"NICSSRuleset.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNI_FIX_CATEGORY_BUG(UIScrollView_NIStyleable)\n\n@implementation UIScrollView (NIStyleable)\n\n\n- (void)applyScrollViewStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM*) dom {\n  if ([ruleSet hasScrollViewIndicatorStyle]) { self.indicatorStyle = ruleSet.scrollViewIndicatorStyle; }\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n    [self applyViewStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n- (void)applyViewStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  [super applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n  [self applyScrollViewStyleWithRuleSet:ruleSet inDOM: dom];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/UISearchBar+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NIDOM;\n@class NICSSRuleset;\n\n@interface UISearchBar (NIStyleable)\n\n/**\n * Applies the given rule set to this search bar.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applySearchBarStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM*) dom;\n\n@end\n\n"
  },
  {
    "path": "src/css/src/UISearchBar+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UISearchBar+NIStyleable.h\"\n\n#import \"UIView+NIStyleable.h\"\n#import \"NICSSRuleset.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNI_FIX_CATEGORY_BUG(UISearchBar_NIStyleable)\n\n@implementation UISearchBar (NIStyleable)\n\n\n- (void)applySearchBarStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM*) dom {\n  if ([ruleSet hasTintColor]) { self.tintColor = ruleSet.tintColor; }\n}\n\n-(void)applyViewStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n    [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n    [self applySearchBarStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/UITableView+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NIDOM;\n@class NICSSRuleset;\n\n@interface UITableView (NIStyleable)\n\n/**\n * Applies the given rule set to this table view.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyTableViewStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n@end\n"
  },
  {
    "path": "src/css/src/UITableView+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UITableView+NIStyleable.h\"\n\n#import \"UIView+NIStyleable.h\"\n#import \"UIScrollView+NIStyleable.h\"\n#import \"NICSSRuleset.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNI_FIX_CATEGORY_BUG(UITableView_NIStyleable)\n\n@implementation UITableView (NIStyleable)\n\n\n- (void)applyTableViewStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom {\n  if ([ruleSet hasTableViewCellSeparatorStyle]) { self.separatorStyle = ruleSet.tableViewCellSeparatorStyle; }\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyStyleWithRuleSet:ruleSet inDOM: nil];\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n  [self applyScrollViewStyleWithRuleSet:ruleSet inDOM:dom];\n  [self applyTableViewStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/UITextField+NIStyleable.h",
    "content": "//\n//  UITextField+NIStyleable.h\n//  Nimbus\n//\n//  Created by Metral, Max on 2/22/13.\n//  Copyright (c) 2013 Jeff Verkoeyen. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NICSSRuleset;\n@class NIDOM;\n\n@interface UITextField (NIStyleable)\n\n/**\n * Applies the given rule set to this text field.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyTextFieldStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n/**\n * Applies the given rule set to this label.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable. Since some of the view\n * styles (e.g. positioning) may rely on some label elements (like text), this is called\n * before the view styling is done.\n */\n- (void)applyTextFieldStyleBeforeViewWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n/**\n * Tells the CSS engine a set of pseudo classes that apply to views of this class.\n * In the case of UITextField, this is :empty.\n * In CSS, you specify these with selectors like UITextField:empty.\n *\n * Make sure to include the leading colon.\n */\n- (NSArray*) pseudoClasses;\n\n/**\n * Applies the given rule set to this text field but for a pseudo class. Thus it only supports the subset of\n * properties that can be set on states of the button. (There's no fancy stuff that applies the styles\n * manually on state transitions.\n *\n * Since UIView doesn't have psuedo's, we don't need the specific version for UITextField like we do with\n * applyTextFieldStyleWithRuleSet.\n */\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet forPseudoClass: (NSString*) pseudo inDOM: (NIDOM*) dom;\n\n@end\n"
  },
  {
    "path": "src/css/src/UITextField+NIStyleable.m",
    "content": "//\n//  UITextField+NIStyleable.m\n//  Nimbus\n//\n//  Created by Metral, Max on 2/22/13.\n//  Copyright (c) 2013 Jeff Verkoeyen. All rights reserved.\n//\n\n#import \"UITextField+NIStyleable.h\"\n#import \"UIView+NIStyleable.h\"\n\n#import \"NICSSRuleset.h\"\n#import \"NIUserInterfaceString.h\"\n#import \"NIPreprocessorMacros.h\"\n\n@class NIDOM;\n\nNI_FIX_CATEGORY_BUG(UITextField_NIStyleable)\n\n@implementation UITextField (NIStyleable)\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom\n{\n    [self applyTextFieldStyleBeforeViewWithRuleSet:ruleSet inDOM:dom];\n    [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n    [self applyTextFieldStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n-(void)applyStyleWithRuleSet:(NICSSRuleset*)ruleSet forPseudoClass:(NSString *)pseudo inDOM:(NIDOM*)dom\n{\n    if (ruleSet.hasTextKey) {\n        NIUserInterfaceString *nis = [[NIUserInterfaceString alloc] initWithKey:ruleSet.textKey];\n        [nis attach:self withSelector:@selector(setPlaceholder:)];\n    }\n}\n\n-(void)applyTextFieldStyleBeforeViewWithRuleSet:(NICSSRuleset*)ruleSet inDOM:(NIDOM*)dom\n{\n    if (ruleSet.hasTextKey) {\n        NIUserInterfaceString *nis = [[NIUserInterfaceString alloc] initWithKey:ruleSet.textKey];\n        [nis attach:self withSelector:@selector(setTitle:forState:) forControlState:UIControlStateNormal];\n    }\n}\n\n-(void)applyTextFieldStyleWithRuleSet:(NICSSRuleset*)ruleSet inDOM:(NIDOM*)dom\n{\n    if ([ruleSet hasTextColor]) { self.textColor = ruleSet.textColor; }\n    if ([ruleSet hasTextAlignment]) { self.textAlignment = ruleSet.textAlignment; }\n    if ([ruleSet hasFont]) { self.font = ruleSet.font; }\n    if ([ruleSet hasMinimumFontSize]) { self.minimumFontSize = ruleSet.minimumFontSize; }\n    if ([ruleSet hasAdjustsFontSize]) { self.adjustsFontSizeToFitWidth = ruleSet.adjustsFontSize; }\n    if ([ruleSet hasVerticalAlign]) { self.contentVerticalAlignment = ruleSet.verticalAlign; }\n}\n\n-(NSArray *)pseudoClasses\n{\n    static dispatch_once_t onceToken;\n    static NSArray *pseudos;\n    dispatch_once(&onceToken, ^{\n        pseudos = @[@\":empty\"];\n    });\n    return pseudos;\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/UIToolbar+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NIDOM;\n@class NICSSRuleset;\n\n@interface UIToolbar (NIStyleable)\n\n/**\n * Applies the given rule set to this toolbar.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyToolbarStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n@end\n"
  },
  {
    "path": "src/css/src/UIToolbar+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UIToolbar+NIStyleable.h\"\n\n#import \"UIView+NIStyleable.h\"\n#import \"NICSSRuleset.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNI_FIX_CATEGORY_BUG(UIToolbar_NIStyleable)\n\n@implementation UIToolbar (NIStyleable)\n\n\n- (void)applyToolbarStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom {\n  if ([ruleSet hasTintColor]) { self.tintColor = ruleSet.tintColor; }\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n  [self applyToolbarStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n@end\n"
  },
  {
    "path": "src/css/src/UIView+NIStyleable.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NICSSRuleset;\n@class NIDOM;\n\nextern NSString* const NICSSViewKey;\nextern NSString* const NICSSViewIdKey;\nextern NSString* const NICSSViewCssClassKey;\nextern NSString* const NICSSViewTextKey;\nextern NSString* const NICSSViewTagKey;\nextern NSString* const NICSSViewTargetSelectorKey;\nextern NSString* const NICSSViewSubviewsKey;\nextern NSString* const NICSSViewAccessibilityLabelKey;\nextern NSString* const NICSSViewBackgroundColorKey;\n\n@interface UIView (NIStyleable)\n\n/**\n * Applies the given rule set to this view. Call applyViewStyleWithRuleSet:inDOM: instead.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyViewStyleWithRuleSet:(NICSSRuleset *)ruleSet DEPRECATED_ATTRIBUTE;\n\n/**\n * Applies the given rule set to this view.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * applyStyleWithRuleSet: method from NIStyleable.\n */\n- (void)applyViewStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;\n\n/**\n * Describes the given rule set when applied to this view.\n *\n * This method is exposed primarily for subclasses to use when implementing the\n * descriptionWithRuleSetFor:forPseudoClass:inDOM:withViewName: method from NIStyleable.\n */\n- (NSString*) descriptionWithRuleSetForView: (NICSSRuleset*) ruleSet forPseudoClass: (NSString*) pseudo inDOM: (NIDOM*) dom withViewName: (NSString*) name;\n\n/**\n * Build a view hierarchy. The array is a list of view specs, where viewSpec is a loosely formatted\n * sequence delineated by UIViews. After a UIView, the type of the next object determines what is done\n * with it:\n *   UIView instance - following values will be applied to this UIView (other than Class, which \"starts anew\")\n *   Class - a UIView subclass that will be alloc'ed and init'ed\n *   NSString starting with a hash - view id (for style application)\n *   NSString starting with a dot - CSS Class (for style application) (you can do this multiple times per view)\n *   NSString - accessibility label for the view.\n *   NIUserInterfaceString - .text or .title(normal) on a button. Asserts otherwise\n *   NSNumber - tag\n *   NSInvocation - selector for TouchUpInside (e.g. on a UIButton)\n *   NSArray - passed to build on the active UIView and results added as subviews\n *   NSDictionary - if you're squeamish about this whole Javascript duck typing auto detecting fancyness\n *        you can pass a boring old dictionary with named values: \n *        NICSSViewKey, NICSSViewIdKey, NICSSViewCssClassKey, NICSSViewTextKey, NICSSViewTagKey, \n *        NICSSViewTargetSelectorKey, NICSSViewSubviewsKey, NICSSViewAccessibilityLabelKey\n *\n *   Example (including inline setting of self properties):\n *    [self.view buildSubviews: @[\n *       self.buttonContainer = UIView.alloc.init, @\"#LoginContainer\", @[\n *         self.myButton = UIButton.alloc.init, @\"#Login\", @\".primary\"\n *       ]\n *    ]];\n */\n- (NSArray*) buildSubviews: (NSArray*) viewSpecs inDOM: (NIDOM*) dom;\n\n/// View frame and bounds manipulation helpers\n@property (nonatomic) CGFloat frameWidth;\n@property (nonatomic) CGFloat frameHeight;\n@property (nonatomic) CGFloat frameMinX;\n@property (nonatomic) CGFloat frameMidX;\n@property (nonatomic) CGFloat frameMaxX;\n@property (nonatomic) CGFloat frameMinY;\n@property (nonatomic) CGFloat frameMidY;\n@property (nonatomic) CGFloat frameMaxY;\n\n@end\n"
  },
  {
    "path": "src/css/src/UIView+NIStyleable.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"UIView+NIStyleable.h\"\n\n#import \"NIDOM.h\"\n#import \"NICSSRuleset.h\"\n#import \"NimbusCore.h\"\n#import \"NIUserInterfaceString.h\"\n#import <QuartzCore/QuartzCore.h>\n#import <objc/runtime.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNSString* const NICSSViewKey = @\"view\";\nNSString* const NICSSViewIdKey = @\"id\";\nNSString* const NICSSViewCssClassKey = @\"cssClass\";\nNSString* const NICSSViewTextKey = @\"text\";\nNSString* const NICSSViewTagKey = @\"tag\";\nNSString* const NICSSViewTargetSelectorKey = @\"selector\";\nNSString* const NICSSViewSubviewsKey = @\"subviews\";\nNSString* const NICSSViewAccessibilityLabelKey = @\"label\";\nNSString* const NICSSViewBackgroundColorKey = @\"bg\";\n\n/**\n * Private class for storing info during view creation\n */\n@interface NIPrivateViewInfo : NSObject\n@property (nonatomic,strong) NSMutableArray *cssClasses;\n@property (nonatomic,strong) NSString *viewId;\n@property (nonatomic,strong) UIView *view;\n@end\n\n// We split this up because we want to add all the subviews to the DOM in the order they were created\n@interface UIView (NIStyleablePrivate)\n-(void)_buildSubviews:(NSArray *)viewSpecs inDOM:(NIDOM *)dom withViewArray: (NSMutableArray*) subviews;\n@end\n\nNI_FIX_CATEGORY_BUG(UIView_NIStyleable)\nNI_FIX_CATEGORY_BUG(UIView_NIStyleablePrivate)\n\nCGFloat NICSSUnitToPixels(NICSSUnit unit, CGFloat container);\n\n@implementation UIView (NIStyleable)\n\n- (void)applyViewStyleWithRuleSet:(NICSSRuleset *)ruleSet {\n  [self applyViewStyleWithRuleSet:ruleSet inDOM:nil];\n}\n\n-(NSString *)descriptionWithRuleSetForView:(NICSSRuleset *)ruleSet forPseudoClass:(NSString *)pseudo inDOM:(NIDOM *)dom withViewName:(NSString *)name\n{\n  return [self applyOrDescribe:NO ruleSet:ruleSet inDOM:dom withViewName:name];\n}\n\n-(NSString *)descriptionWithRuleSet:(NICSSRuleset *)ruleSet forPseudoClass:(NSString *)pseudo inDOM:(NIDOM *)dom withViewName:(NSString *)name\n{\n  return [self descriptionWithRuleSetForView:ruleSet forPseudoClass:pseudo inDOM:dom withViewName:name];\n}\n\n- (void)applyViewStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  [self applyOrDescribe:YES ruleSet:ruleSet inDOM:dom withViewName:nil];\n}\n\n- (NSString*)applyOrDescribe: (BOOL) apply ruleSet: (NICSSRuleset*) ruleSet inDOM: (NIDOM*)dom withViewName: (NSString*) name {\n  NSMutableString *desc = apply ? nil : [[NSMutableString alloc] init];\n  //      [desc appendFormat:@\"%@. = %f;\\n\"];\n  if ([ruleSet hasBackgroundColor]) {\n    if (apply) {\n      self.backgroundColor = ruleSet.backgroundColor;\n    } else {\n      CGFloat r,g,b,a;\n      [ruleSet.backgroundColor getRed:&r green:&g blue:&b alpha:&a];\n      [desc appendFormat:@\"%@.backgroundColor = [UIColor colorWithRed: %f green: %f blue: %f alpha: %f];\\n\", name, r, g, b, a];\n    }\n  }\n  if ([ruleSet hasOpacity]) {\n    if (apply) {\n      self.alpha = ruleSet.opacity;\n    } else {\n      [desc appendFormat:@\"%@.alpha = %f;\", name, ruleSet.opacity];\n    }\n  }\n  if ([ruleSet hasBorderRadius]) {\n    if (apply) {\n      self.layer.cornerRadius = ruleSet.borderRadius;\n    } else {\n      [desc appendFormat:@\"%@.layer.cornerRadius = %f;\\n\", name, ruleSet.borderRadius];\n    }\n  }\n  if ([ruleSet hasBorderWidth]) {\n    if (apply) {\n      self.layer.borderWidth = ruleSet.borderWidth;\n    } else {\n      [desc appendFormat:@\"%@.layer.borderWidth = %f;\\n\", name, ruleSet.borderWidth];\n    }\n  }\n  if ([ruleSet hasBorderColor]) {\n    if (apply) {\n      self.layer.borderColor = ruleSet.borderColor.CGColor;\n    } else {\n      CGFloat r,g,b,a;\n      [ruleSet.borderColor getRed:&r green:&g blue:&b alpha:&a];\n      [desc appendFormat:@\"%@.layer.borderColor = [UIColor colorWithRed: %f green: %f blue: %f alpha: %f].CGColor;\\n\", name, r, g, b, a];\n    }\n  }\n  if ([ruleSet hasAutoresizing]) {\n    if (apply) {\n      self.autoresizingMask = ruleSet.autoresizing;\n    } else {\n      [desc appendFormat:@\"%@.autoresizingMask = (UIViewAutoresizing) %zd;\\n\", name, ruleSet.autoresizing];\n    }\n  }\n  if ([ruleSet hasVisible]) {\n    if (apply) {\n      self.hidden = !ruleSet.visible;\n    } else {\n      [desc appendFormat:@\"%@.hidden = %@;\\n\", name, ruleSet.visible ? @\"NO\" : @\"YES\"];\n    }\n  }\n  \n    // View sizing\n    // Special case auto/auto height and width\n  if ([ruleSet hasWidth] && [ruleSet hasHeight] &&\n      ruleSet.width.type == CSS_AUTO_UNIT && ruleSet.height.type == CSS_AUTO_UNIT) {\n    if (apply) {\n      [self sizeToFit];\n    } else {\n      [desc appendFormat:@\"[%@ sizeToFit];\\n\", name];\n    }\n    if (ruleSet.hasVerticalPadding) {\n      NICSSUnit vPadding = ruleSet.verticalPadding;\n      switch (vPadding.type) {\n        case CSS_AUTO_UNIT:\n          break;\n        case CSS_PERCENTAGE_UNIT:\n          if (apply) {\n            self.frameHeight += (self.frameHeight * vPadding.value);\n          } else {\n            [desc appendFormat:@\"%@.frameHeight += (%@.frameHeight * %f);\", name, name, vPadding.value];\n          }\n          break;\n        case CSS_PIXEL_UNIT:\n          if (apply) {\n            self.frameHeight += vPadding.value;\n          } else {\n            [desc appendFormat:@\"%@.frameHeight += %f;\", name, vPadding.value];\n          }\n          break;\n      }\n    }\n    if (ruleSet.hasHorizontalPadding) {\n      NICSSUnit hPadding = ruleSet.horizontalPadding;\n      switch (hPadding.type) {\n        case CSS_AUTO_UNIT:\n          break;\n        case CSS_PERCENTAGE_UNIT:\n          if (apply) {\n            self.frameWidth += (self.frameWidth * hPadding.value);\n          } else {\n            [desc appendFormat:@\"%@.frameWidth += (%@.frameWidth * %f);\", name, name, hPadding.value];\n          }\n          break;\n        case CSS_PIXEL_UNIT:\n          if (apply) {\n            self.frameWidth += hPadding.value;\n          } else {\n            [desc appendFormat:@\"%@.frameWidth += %f;\", name, hPadding.value];\n          }\n          break;\n      }\n    }\n\n  } else {\n    if ([ruleSet hasWidth]) {\n      NICSSUnit u = ruleSet.width;\n      CGFloat startHeight = self.frameHeight;\n      switch (u.type) {\n        case CSS_AUTO_UNIT:\n          if (apply) {\n            [self sizeToFit]; // sizeToFit the width, but retain height. Behavior somewhat undefined...\n            self.frameHeight = startHeight;\n          } else {\n            [desc appendFormat:@\"[%@ sizeToFit];\\n%@.frameHeight = %f;\\n\", name, name, startHeight];\n          }\n          break;\n        case CSS_PERCENTAGE_UNIT:\n          if (apply) {\n            self.frameWidth = self.superview.bounds.size.width * u.value;\n          } else {\n            [desc appendFormat:@\"%@.frameWidth = %f;\\n\", name, self.superview.bounds.size.width * u.value];\n          }\n          break;\n        case CSS_PIXEL_UNIT:\n          // Because padding and margin are (a) complicated to implement and (b) not relevant in a non-flow layout,\n          // we use negative width values to mean \"the superview dimension - the value.\" It's a little hokey, but\n          // it's very useful. If someone wants to layer on padding primitives to deal with this in a more CSSy way,\n          // go for it.\n          if (u.value < 0) {\n            if (apply) {\n              self.frameWidth = self.superview.frameWidth + u.value;\n            } else {\n              [desc appendFormat:@\"%@.frameWidth = %f;\\n\", name, self.superview.frameWidth + u.value];\n            }\n          } else {\n            if (apply) {\n              self.frameWidth = u.value;\n            } else {\n              [desc appendFormat:@\"%@.frameWidth = %f;\\n\", name, u.value];\n            }\n          }\n          break;\n      }\n      if (ruleSet.hasHorizontalPadding) {\n        NICSSUnit hPadding = ruleSet.horizontalPadding;\n        switch (hPadding.type) {\n          case CSS_AUTO_UNIT:\n            break;\n          case CSS_PERCENTAGE_UNIT:\n            if (apply) {\n              self.frameWidth += (self.frameWidth * hPadding.value);\n            } else {\n              [desc appendFormat:@\"%@.frameWidth += (%@.frameWidth * %f);\", name, name, hPadding.value];\n            }\n            break;\n          case CSS_PIXEL_UNIT:\n            if (apply) {\n              self.frameWidth += hPadding.value;\n            } else {\n              [desc appendFormat:@\"%@.frameWidth += %f;\", name, hPadding.value];\n            }\n            break;\n        }\n      }\n    }\n    if ([ruleSet hasHeight]) {\n      NICSSUnit u = ruleSet.height;\n      CGFloat startWidth = self.frameWidth;\n      switch (u.type) {\n        case CSS_AUTO_UNIT:\n          if (apply) {\n            [self sizeToFit];\n            self.frameWidth = startWidth;\n          } else {\n            [desc appendFormat:@\"[%@ sizeToFit];\\n%@.frameWidth = %f;\\n\", name, name, startWidth];\n          }\n          break;\n        case CSS_PERCENTAGE_UNIT:\n          if (apply) {\n            self.frameHeight = self.superview.bounds.size.height * u.value;\n          } else {\n            [desc appendFormat:@\"%@.frameHeight = %f;\\n\", name, self.superview.bounds.size.height * u.value];\n          }\n          break;\n        case CSS_PIXEL_UNIT:\n          // Because padding and margin are (a) complicated to implement and (b) not relevant in a non-flow layout,\n          // we use negative width values to mean \"the superview dimension - the value.\" It's a little hokey, but\n          // it's very useful. If someone wants to layer on padding primitives to deal with this in a more CSSy way,\n          // go for it.\n          if (u.value < 0) {\n            if (apply) {\n              self.frameHeight = self.superview.frameHeight + u.value;\n            } else {\n              [desc appendFormat:@\"%@.frameHeight = %f;\\n\", name, self.superview.frameHeight + u.value];\n            }\n          } else {\n            if (apply) {\n              self.frameHeight = u.value;\n            } else {\n              [desc appendFormat:@\"%@.frameHeight = %f;\\n\", name, u.value];\n            }\n          }\n          break;\n      }\n      if (ruleSet.hasVerticalPadding) {\n        NICSSUnit vPadding = ruleSet.verticalPadding;\n        switch (vPadding.type) {\n          case CSS_AUTO_UNIT:\n            break;\n          case CSS_PERCENTAGE_UNIT:\n            if (apply) {\n              self.frameHeight += (self.frameHeight * vPadding.value);\n            } else {\n              [desc appendFormat:@\"%@.frameHeight += (%@.frameHeight * %f);\", name, name, vPadding.value];\n            }\n            break;\n          case CSS_PIXEL_UNIT:\n            if (apply) {\n              self.frameHeight += vPadding.value;\n            } else {\n              [desc appendFormat:@\"%@.frameHeight += %f;\", name, vPadding.value];\n            }\n            break;\n        }\n      }\n    }\n  }\n  \n    // Min/Max width/height enforcement\n    if ([ruleSet hasMaxWidth]) {\n    CGFloat max = NICSSUnitToPixels(ruleSet.maxWidth,self.frameWidth);\n    if (self.frameWidth > max) {\n      if (apply) { self.frameWidth = max; } else { [desc appendFormat:@\"%@.frameWidth = %f;\\n\", name, max]; }\n    }\n  }\n  if ([ruleSet hasMaxHeight]) {\n    CGFloat max = NICSSUnitToPixels(ruleSet.maxHeight,self.frameHeight);\n    if (self.frameHeight > max) {\n      if (apply) { self.frameHeight = max; } else { [desc appendFormat:@\"%@.frameHeight = %f;\\n\", name, max]; }\n    }\n  }\n  if ([ruleSet hasMinWidth]) {\n    CGFloat min = NICSSUnitToPixels(ruleSet.minWidth,self.frameWidth);\n    if (self.frameWidth < min) {\n      if (apply) { self.frameWidth = min; } else { [desc appendFormat:@\"%@.frameWidth = %f;\\n\", name, min]; }\n    }\n  }\n  if ([ruleSet hasMinHeight]) {\n    CGFloat min = NICSSUnitToPixels(ruleSet.minHeight,self.frameHeight);\n    if (self.frameHeight < min) {\n      if (apply) { self.frameHeight = min; } else { [desc appendFormat:@\"%@.frameHeight = %f;\\n\", name, min]; }\n    }\n  }\n  \n    // \"Absolute\" position in superview\n    if ([ruleSet hasTop]) {\n    NICSSUnit u = ruleSet.top;\n    switch (u.type) {\n      case CSS_PERCENTAGE_UNIT:\n        if (apply) {\n          self.frameMinY = self.superview.bounds.size.height * u.value;\n        } else {\n          [desc appendFormat:@\"%@.frameMinY = %f;\\n\", name, self.superview.bounds.size.height * u.value];\n        }\n        break;\n      case CSS_PIXEL_UNIT:\n        if (apply) {\n          self.frameMinY = u.value;\n        } else {\n          [desc appendFormat:@\"%@.frameMinY = %f;\\n\", name, u.value];\n        }\n        break;\n      default:\n        NIDASSERT(u.type == CSS_PERCENTAGE_UNIT || u.type == CSS_PIXEL_UNIT);\n        break;\n    }\n  }\n  if ([ruleSet hasLeft]) {\n    NICSSUnit u = ruleSet.left;\n    switch (u.type) {\n      case CSS_PERCENTAGE_UNIT:\n        if (apply) {\n          self.frameMinX = self.superview.bounds.size.width * u.value;\n        } else {\n          [desc appendFormat:@\"%@.frameMinX = %f;\\n\", name, self.superview.bounds.size.width * u.value];\n        }\n        break;\n      case CSS_PIXEL_UNIT:\n        if (apply) {\n          self.frameMinX = u.value;\n        } else {\n          [desc appendFormat:@\"%@.frameMinX = %f;\\n\", name, u.value];\n        }\n        break;\n      default:\n        NIDASSERT(u.type == CSS_PERCENTAGE_UNIT || u.type == CSS_PIXEL_UNIT);\n        break;\n    }\n  }\n  // TODO - should specifying both left/right or top/bottom set the width instead?\n  // TODO - how does left/right/top/bottom interact with relative positioning if at all?\n  if ([ruleSet hasRight]) {\n    NICSSUnit u = ruleSet.right;\n    switch (u.type) {\n      case CSS_PERCENTAGE_UNIT:\n        if (apply) {\n          self.frameMaxX = self.superview.bounds.size.width * u.value;\n        } else {\n          [desc appendFormat:@\"%@.frameMaxX = %f;\\n\", name, self.superview.bounds.size.width * u.value];\n        }\n        break;\n      case CSS_PIXEL_UNIT:\n        if (apply) {\n          self.frameMaxX = self.superview.bounds.size.width - u.value;\n        } else {\n          [desc appendFormat:@\"%@.frameMaxX = %f;\\n\", name, self.superview.bounds.size.width - u.value];\n        }\n        break;\n      default:\n        NIDASSERT(u.type == CSS_PERCENTAGE_UNIT || u.type == CSS_PIXEL_UNIT);\n        break;\n    }\n  }\n  if ([ruleSet hasBottom]) {\n    NICSSUnit u = ruleSet.bottom;\n    switch (u.type) {\n      case CSS_PERCENTAGE_UNIT:\n        if (apply) {\n          self.frameMaxY = self.superview.bounds.size.height * u.value;\n        } else {\n          [desc appendFormat:@\"%@.frameMaxY = %f;\\n\", name, self.superview.bounds.size.height * u.value];\n        }\n        break;\n      case CSS_PIXEL_UNIT:\n        if (apply) {\n          self.frameMaxY = self.superview.bounds.size.height - u.value;\n        } else {\n          [desc appendFormat:@\"%@.frameMaxY = %f;\\n\", name, self.superview.bounds.size.height - u.value];\n        }\n        break;\n      default:\n        NIDASSERT(u.type == CSS_PERCENTAGE_UNIT || u.type == CSS_PIXEL_UNIT);\n        break;\n    }\n  }\n  if ([ruleSet hasFrameHorizontalAlign]) {\n    switch (ruleSet.frameHorizontalAlign) {\n      case NSTextAlignmentCenter:\n        if (apply) {\n          self.frameMidX = self.superview.bounds.size.width / 2.0;\n        } else {\n          [desc appendFormat:@\"%@.frameMidX = %f;\\n\", name, self.superview.bounds.size.width / 2.0];\n        }\n        break;\n      case NSTextAlignmentLeft:\n        if (apply) {\n          self.frameMinX = 0;\n        } else {\n          [desc appendFormat:@\"%@.frameMinX = 0;\\n\", name];\n        }\n        break;\n      case NSTextAlignmentRight:\n        self.frameMaxX = self.superview.bounds.size.width;\n        break;\n      default:\n        NIDASSERT(NO);\n        break;\n    }\n  }\n  if ([ruleSet hasFrameVerticalAlign]) {\n    switch (ruleSet.frameVerticalAlign) {\n      case UIViewContentModeCenter:\n        if (apply) {\n          self.frameMidY = self.superview.bounds.size.height / 2.0;\n        } else {\n          [desc appendFormat:@\"%@.frameMidY = %f;\\n\", name, self.superview.bounds.size.height / 2.0];\n        }\n        break;\n      case UIViewContentModeTop:\n        if (apply) {\n          self.frameMinY = 0;\n        } else {\n          [desc appendFormat:@\"%@.frameMinY = 0;\\n\", name];\n        }\n        break;\n      case UIViewContentModeBottom:\n        if (apply) {\n          self.frameMaxY = self.superview.bounds.size.height;\n        } else {\n          [desc appendFormat:@\"%@.frameMaxY = %f;\\n\", name, self.superview.bounds.size.height];\n        }\n        break;\n      default:\n        NIDASSERT(NO);\n        break;\n    }\n  }\n  \n    // Relative positioning to other identified views\n    if (ruleSet.hasRelativeToId) {\n    NSString *viewSpec = ruleSet.relativeToId;\n    UIView* relative = nil;\n    if ([viewSpec characterAtIndex:0] == '.') {\n      if ([viewSpec caseInsensitiveCompare:@\".next\"] == NSOrderedSame) {\n        NSInteger ix = [self.superview.subviews indexOfObject:self];\n        if (++ix < self.superview.subviews.count) {\n          relative = [self.superview.subviews objectAtIndex:ix];\n        }\n      } else if ([viewSpec caseInsensitiveCompare:@\".prev\"] == NSOrderedSame) {\n        NSInteger ix = [self.superview.subviews indexOfObject:self];\n        if (ix > 0) {\n          relative = [self.superview.subviews objectAtIndex:ix-1];\n        }\n      } else if ([viewSpec caseInsensitiveCompare:@\".first\"] == NSOrderedSame) {\n        relative = [self.superview.subviews objectAtIndex:0];\n        if (relative == self) { relative = nil; }\n      } else if ([viewSpec caseInsensitiveCompare:@\".last\"] == NSOrderedSame) {\n        relative = [self.superview.subviews lastObject];\n        if (relative == self) { relative = nil; }\n      }\n    } else {\n      // For performance, I'm not going to try and fix up your bad selectors. Start with a # or it will fail.\n      relative = [dom viewById:ruleSet.relativeToId];\n    }\n    if (relative) {\n      CGPoint anchor;\n      \n      if (ruleSet.hasMarginTop) {\n        NICSSUnit top = ruleSet.marginTop;\n        switch (top.type) {\n          case CSS_AUTO_UNIT:\n            // Align y center\n            anchor = CGPointMake(0, relative.frameMidY);\n            if (self.superview != relative.superview) {\n              anchor = [self convertPoint:anchor fromView:relative.superview];\n            }\n            if (apply) {\n              self.frameMidY = anchor.y;\n            } else {\n              [desc appendFormat:@\"%@.frameMidY = %f;\\n\", name, anchor.y];\n            }\n            break;\n          case CSS_PERCENTAGE_UNIT:\n          case CSS_PIXEL_UNIT:\n            // relative.frameMaxY + relative.frameHeight * unit\n            anchor = CGPointMake(0, relative.frameMaxY);\n            if (self.superview != relative.superview) {\n              anchor = [self convertPoint:anchor fromView:relative.superview];\n            }\n            if (apply) {\n              self.frameMinY = anchor.y + NICSSUnitToPixels(top, relative.frameHeight);\n            } else {\n              [desc appendFormat:@\"%@.frameMinY = %f;\\n\", name, anchor.y + NICSSUnitToPixels(top, relative.frameHeight)];\n            }\n            break;\n        }\n      } else if (ruleSet.hasMarginBottom) {\n        NICSSUnit bottom = ruleSet.marginBottom;\n        switch (bottom.type) {\n          case CSS_AUTO_UNIT:\n            // Align y center\n            anchor = CGPointMake(0, relative.frameMidY);\n            if (self.superview != relative.superview) {\n              anchor = [self convertPoint:anchor fromView:relative.superview];\n            }\n            if (apply) {\n              self.frameMidY = anchor.y;\n            } else {\n              [desc appendFormat:@\"%@.frameMidY = %f;\\n\", name, anchor.y];\n            }\n            break;\n          case CSS_PERCENTAGE_UNIT:\n          case CSS_PIXEL_UNIT:\n            // relative.frameMinY - (relative.frameHeight * unit)\n            anchor = CGPointMake(0, relative.frameMinY);\n            if (self.superview != relative.superview) {\n              anchor = [self convertPoint:anchor fromView:relative.superview];\n            }\n            if (apply) {\n              self.frameMaxY = anchor.y - NICSSUnitToPixels(bottom, relative.frameHeight);\n            } else {\n              [desc appendFormat:@\"%@.frameMaxY = %f;\", name, anchor.y - NICSSUnitToPixels(bottom, relative.frameHeight)];\n            }\n            break;\n        }\n      }\n      \n      if (ruleSet.hasMarginLeft) {\n        NICSSUnit left = ruleSet.marginLeft;\n        switch (left.type) {\n          case CSS_AUTO_UNIT:\n            // Align x center\n            anchor = CGPointMake(relative.frameMidX, 0);\n            if (self.superview != relative.superview) {\n              anchor = [self convertPoint:anchor fromView:relative.superview];\n            }\n            if (apply) {\n              self.frameMidX = anchor.x;\n            } else {\n              [desc appendFormat:@\"%@.frameMidX = %f;\\n\", name, anchor.x];\n            }\n            break;\n          case CSS_PERCENTAGE_UNIT:\n          case CSS_PIXEL_UNIT:\n            // relative.frameMaxX + (relative.frameHeight * unit)\n            anchor = CGPointMake(relative.frameMaxX, 0);\n            if (self.superview != relative.superview) {\n              anchor = [self convertPoint:anchor fromView:relative.superview];\n            }\n            if (apply) {\n              self.frameMinX = anchor.x + NICSSUnitToPixels(left, relative.frameWidth);\n            } else {\n              [desc appendFormat:@\"%@.frameMinX = %f;\\n\", name, anchor.x + NICSSUnitToPixels(left, relative.frameWidth)];\n            }\n            break;\n        }\n      } else if (ruleSet.hasMarginRight) {\n        NICSSUnit right = ruleSet.marginRight;\n        switch (right.type) {\n          case CSS_AUTO_UNIT:\n            // Align x center\n            anchor = CGPointMake(relative.frameMidX, 0);\n            if (self.superview != relative.superview) {\n              anchor = [self convertPoint:anchor fromView:relative.superview];\n            }\n            if (apply) {\n              self.frameMidX = anchor.x;\n            } else {\n              [desc appendFormat:@\"%@.frameMidX = %f;\\n\", name, anchor.x];\n            }\n            break;\n          case CSS_PERCENTAGE_UNIT:\n          case CSS_PIXEL_UNIT:\n            // relative.frameMinX - (relative.frameHeight * unit)\n            anchor = CGPointMake(relative.frameMinX, 0);\n            if (self.superview != relative.superview) {\n              anchor = [self convertPoint:anchor fromView:relative.superview];\n            }\n            if (apply) {\n              self.frameMaxX = anchor.x - NICSSUnitToPixels(right, relative.frameWidth);\n            } else {\n              [desc appendFormat:@\"%@.frameMaxX = %f;\", name, anchor.x - NICSSUnitToPixels(right, relative.frameWidth)];\n              \n            }\n            break;\n        }\n      }\n    }\n  }\n  return desc;\n}\n\n-(NSArray *)buildSubviews:(NSArray *)viewSpecs inDOM:(NIDOM *)dom\n{\n  NSMutableArray *subviews = [[NSMutableArray alloc] init];\n  [self _buildSubviews:viewSpecs inDOM:dom withViewArray:subviews];\n  \n  for (NSUInteger ix = 0, ct = subviews.count; ix < ct; ix++) {\n    NIPrivateViewInfo *viewInfo = [subviews objectAtIndex:ix];\n    NSString *firstClass = [viewInfo.cssClasses count] ? [viewInfo.cssClasses objectAtIndex:0] : nil;\n    [dom registerView:viewInfo.view withCSSClass:firstClass andId:viewInfo.viewId];\n    if (viewInfo.viewId && dom.target) {\n      NSString *selectorName = [NSString stringWithFormat:@\"set%@%@:\", [[viewInfo.viewId substringWithRange:NSMakeRange(1, 1)] uppercaseString], [viewInfo.viewId substringFromIndex:2]];\n      SEL selector = NSSelectorFromString(selectorName);\n      if ([dom.target respondsToSelector:selector]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n        [dom.target performSelector:selector withObject:viewInfo.view];\n#pragma clang diagnostic pop\n      }\n    }\n    if (viewInfo.cssClasses.count > 1) {\n      for (NSUInteger i = 1, cct = viewInfo.cssClasses.count; i < cct; i++) {\n        [dom addCssClass:[viewInfo.cssClasses objectAtIndex:i] toView:viewInfo.view];\n      }\n    }\n    [subviews replaceObjectAtIndex:ix withObject:viewInfo.view];\n  }\n  return subviews;\n}\n\n- (void)applyStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM:(NIDOM *)dom {\n  [self applyViewStyleWithRuleSet:ruleSet inDOM:dom];\n}\n\n- (CGFloat)frameWidth\n{\n\treturn self.frame.size.width;\n}\n\n- (void)setFrameWidth:(CGFloat)frameWidth\n{\n\tCGRect frame = self.frame;\n\tframe.size.width = frameWidth;\n  \n\tself.frame = frame;\n}\n\n- (CGFloat)frameHeight\n{\n\treturn self.frame.size.height;\n}\n\n- (void)setFrameHeight:(CGFloat)frameHeight\n{\n\tCGRect frame = self.frame;\n\tframe.size.height = frameHeight;\n  \n\tself.frame = frame;\n}\n\n- (CGFloat)frameMinX\n{\n\treturn CGRectGetMinX(self.frame);\n}\n\n- (void)setFrameMinX:(CGFloat)frameMinX\n{\n\tCGRect frame = self.frame;\n\tframe.origin.x = frameMinX;\n  \n\tself.frame = frame;\n}\n\n- (CGFloat)frameMidX\n{\n\treturn CGRectGetMidX(self.frame);\n}\n\n- (void)setFrameMidX:(CGFloat)frameMidX\n{\n\tself.frameMinX = (frameMidX - (self.frameWidth / 2.0f));\n}\n\n- (CGFloat)frameMaxX\n{\n\treturn CGRectGetMaxX(self.frame);\n}\n\n- (void)setFrameMaxX:(CGFloat)frameMaxX\n{\n\tself.frameMinX = (frameMaxX - self.frameWidth);\n}\n\n- (CGFloat)frameMinY\n{\n\treturn CGRectGetMinY(self.frame);\n}\n\n- (void)setFrameMinY:(CGFloat)frameMinY\n{\n\tCGRect frame = self.frame;\n\tframe.origin.y = frameMinY;\n  \n\tself.frame = frame;\n}\n\n- (CGFloat)frameMidY\n{\n\treturn CGRectGetMidY(self.frame);\n}\n\n- (void)setFrameMidY:(CGFloat)frameMidY\n{\n\tself.frameMinY = (frameMidY - (self.frameHeight / 2.0f));\n}\n\n- (CGFloat)frameMaxY\n{\n\treturn CGRectGetMaxY(self.frame);\n}\n\n- (void)setFrameMaxY:(CGFloat)frameMaxY\n{\n\tself.frameMinY = (frameMaxY - self.frameHeight);\n}\n\n@end\n\nCGFloat NICSSUnitToPixels(NICSSUnit unit, CGFloat container)\n{\n  if (unit.type == CSS_PERCENTAGE_UNIT) {\n    return unit.value * container;\n  }\n  return unit.value;\n}\n\n@implementation UIView (NIStyleablePrivate)\n-(void)_buildSubviews:(NSArray *)viewSpecs inDOM:(NIDOM *)dom withViewArray:(NSMutableArray *)subviews\n{\n  NIPrivateViewInfo *active = nil;\n\tfor (id directive in viewSpecs) {\n    \n    if ([directive isKindOfClass:[NSDictionary class]]) {\n      // Process the key value pairs rather than trying to determine intent\n      // from the type\n      NSDictionary *kv = (NSDictionary*) directive;\n      if (!active) {\n        NSAssert([kv objectForKey:NICSSViewKey], @\"The first NSDictionary passed to build subviews must contain the NICSSViewKey\");\n      }\n      id directiveValue = [kv objectForKey:NICSSViewKey];\n      if (directiveValue) {\n#ifdef NI_DYNAMIC_VIEWS\n        // I have a dream that you can instantiate this whole thing from JSON.\n        // So the dictionary version endeavors to make NSString/NSNumber work for every directive\n        if ([directiveValue isKindOfClass:[NSString class]]) {\n          directiveValue = [[NSClassFromString(directiveValue) alloc] init];\n        }\n#endif\n        if ([directiveValue isKindOfClass:[UIView class]]) {\n          active = [[NIPrivateViewInfo alloc] init];\n          active.view = (UIView*) directiveValue;\n          [self addSubview:active.view];\n          [subviews addObject: active];\n        } else if (class_isMetaClass(object_getClass(directiveValue))) {\n          active = [[NIPrivateViewInfo alloc] init];\n          active.view = [[directive alloc] init];\n          NSAssert([active.view isKindOfClass:[UIView class]], @\"View must inherit from UIView. %@ does not.\", NSStringFromClass([active class]));\n          [self addSubview:active.view];\n          [subviews addObject: active];\n        } else {\n          NSAssert(NO, @\"NICSSViewKey directive does not identify a UIView or UIView class.\");\n        }\n      }\n      directiveValue = [kv objectForKey:NICSSViewIdKey];\n      if (directiveValue) {\n        NSAssert([directiveValue isKindOfClass:[NSString class]], @\"The value of NICSSViewIdKey must be an NSString*\");\n        if (![directiveValue hasPrefix:@\"#\"]) {\n          directiveValue = [@\"#\" stringByAppendingString:directiveValue];\n        }\n        active.viewId = directiveValue;\n      }\n      directiveValue = [kv objectForKey:NICSSViewCssClassKey];\n      if (directiveValue) {\n        NSAssert([directiveValue isKindOfClass:[NSString class]] || [directiveValue isKindOfClass:[NSArray class]], @\"The value of NICSSViewCssClassKey must be an NSString* or NSArray*\");\n        active.cssClasses = active.cssClasses ?: [[NSMutableArray alloc] init];\n        if ([directiveValue isKindOfClass:[NSString class]]) {\n          [active.cssClasses addObject:directiveValue];\n        } else {\n          [active.cssClasses addObjectsFromArray:directiveValue];\n        }\n      }\n      directiveValue = [kv objectForKey:NICSSViewTextKey];\n      if (directiveValue) {\n        NSAssert([directiveValue isKindOfClass:[NSString class]] || [directiveValue isKindOfClass:[NIUserInterfaceString class]], @\"The value of NICSSViewCssClassKey must be an NSString* or NIUserInterfaceString*\");\n        if ([directiveValue isKindOfClass:[NSString class]]) {\n          directiveValue = [[NIUserInterfaceString alloc] initWithKey:directiveValue defaultValue:directiveValue];\n        }\n        if ([directiveValue isKindOfClass:[NIUserInterfaceString class]]) {\n          [((NIUserInterfaceString*)directiveValue) attach:active.view];\n        }\n      }\n      directiveValue = [kv objectForKey:NICSSViewBackgroundColorKey];\n      if (directiveValue) {\n        NSAssert([directiveValue isKindOfClass:[UIColor class]] || [directiveValue isKindOfClass:[NSNumber class]], @\"The value of NICSSViewBackgroundColorKey must be NSNumber* or UIColor*\");\n        if ([directiveValue isKindOfClass:[NSNumber class]]) {\n          long rgbValue = [directiveValue longValue];\n          directiveValue = [UIColor colorWithRed:((float)((rgbValue & 0xFF000000) >> 24))/255.0 green:((float)((rgbValue & 0xFF0000) >> 16))/255.0 blue:((float)((rgbValue & 0xFF00) >> 8))/255.0 alpha:((float)(rgbValue & 0xFF))/255.0];\n        }\n        self.backgroundColor = directiveValue;\n      }\n      directiveValue = [kv objectForKey:NICSSViewTagKey];\n      if (directiveValue) {\n        NSAssert([directiveValue isKindOfClass:[NSNumber class]], @\"The value of NICSSViewTagKey must be an NSNumber*\");\n        active.view.tag = [directiveValue integerValue];\n      }\n      directiveValue = [kv objectForKey:NICSSViewTargetSelectorKey];\n      if (directiveValue) {\n        NSAssert([directiveValue isKindOfClass:[NSInvocation class]] || [directiveValue isKindOfClass:[NSString class]], @\"NICSSViewTargetSelectorKey must be an NSInvocation*, or an NSString* if you're adventurous and NI_DYNAMIC_VIEWS is defined.\");\n        \n#ifdef NI_DYNAMIC_VIEWS\n        // NSSelectorFromString has Apple rejection written all over it, even though it's documented. Since its intended\n        // use is primarily rapid development right now, use the #ifdef to turn it on.\n        if ([directiveValue isKindOfClass:[NSString class]]) {\n          // Let's make an invocation out of this puppy.\n          @try {\n            SEL selector = NSSelectorFromString(directiveValue);\n            directiveValue = NIInvocationWithInstanceTarget(dom.target, selector);\n          }\n          @catch (NSException *exception) {\n#ifdef DEBUG\n            NIDPRINT(@\"Unknown selector %@ specified on %@.\", directiveValue, dom.target);\n#endif\n          }\n        }\n#endif\n        \n        if ([directiveValue isKindOfClass:[NSInvocation class]]) {\n          NSInvocation *n = (NSInvocation*) directiveValue;\n          if ([active.view respondsToSelector:@selector(addTarget:action:forControlEvents:)]) {\n            [((id)active.view) addTarget:n.target action:n.selector forControlEvents:UIControlEventTouchUpInside];\n          } else {\n            NSString *error = [NSString stringWithFormat:@\"Cannot apply NSInvocation to class %@\", NSStringFromClass(active.class)];\n            NSAssert(NO, error);\n            #pragma unused (error)\n          }\n        }\n      }\n      directiveValue = [kv objectForKey:NICSSViewSubviewsKey];\n      if (directiveValue) {\n        NSAssert([directiveValue isKindOfClass: [NSArray class]], @\"NICSSViewSubviewsKey must be an NSArray*\");\n        [active.view _buildSubviews:directiveValue inDOM:dom withViewArray:subviews];\n      } else if (directiveValue)\n        directiveValue = [kv objectForKey:NICSSViewAccessibilityLabelKey];\n      if (directiveValue) {\n        NSAssert([directiveValue isKindOfClass:[NSString class]], @\"NICSSViewAccessibilityLabelKey must be an NSString*\");\n        active.view.accessibilityLabel = directiveValue;\n      }\n      continue;\n    }\n    \n    // This first element in a \"segment\" of the array must be a view or a class object that we will make into a view\n    // You can do things like UIView.alloc.init, UIView.class, [[UIView alloc] init]...\n    if ([directive isKindOfClass: [UIView class]]) {\n      active = [[NIPrivateViewInfo alloc] init];\n      active.view = (UIView*) directive;\n      [self addSubview:active.view];\n      [subviews addObject: active];\n      continue;\n    } else if (class_isMetaClass(object_getClass(directive))) {\n      active = [[NIPrivateViewInfo alloc] init];\n      active.view = [[directive alloc] init];\n      [self addSubview:active.view];\n      [subviews addObject: active];\n      continue;\n    } else if (!active) {\n      NSAssert(NO, @\"UIView::buildSubviews expected UIView or Class to start a directive.\");\n      continue;\n    }\n    \n    if ([directive isKindOfClass:[NIUserInterfaceString class]]) {\n      [((NIUserInterfaceString*)directive) attach:active.view];\n    } else if ([directive isKindOfClass:[NSString class]]) {\n      // Strings are either a cssClass or an accessibility label\n      NSString *d = (NSString*) directive;\n      if ([d hasPrefix:@\".\"]) {\n        active.cssClasses = active.cssClasses ?: [[NSMutableArray alloc] init];\n        [active.cssClasses addObject: [d substringFromIndex:1]];\n      } else if ([d hasPrefix:@\"#\"]) {\n        active.viewId = d;\n      } else {\n        active.view.accessibilityLabel = d;\n      }\n    } else if ([directive isKindOfClass:[NSNumber class]]) {\n      // NSNumber means tag\n      active.view.tag = [directive integerValue];\n    } else if ([directive isKindOfClass:[NSArray class]]) {\n      // NSArray means recursive call to build\n      [active.view _buildSubviews:directive inDOM:dom withViewArray:subviews];\n    } else if ([directive isKindOfClass:[UIColor class]]) {\n      active.view.backgroundColor = directive;\n    } else if ([directive isKindOfClass:[NSInvocation class]]) {\n      NSInvocation *n = (NSInvocation*) directive;\n      if ([active.view respondsToSelector:@selector(addTarget:action:forControlEvents:)]) {\n        [((id)active.view) addTarget: n.target action: n.selector forControlEvents: UIControlEventTouchUpInside];\n      } else {\n        NSString *error = [NSString stringWithFormat:@\"Cannot apply NSInvocation to class %@\", NSStringFromClass(active.class)];\n        NSAssert(NO, error);\n        #pragma unused (error)\n      }\n    } else {\n      NSAssert(NO, @\"Unknown directive in build specifier\");\n    }\n  }\n}\n@end\n\n@implementation NIPrivateViewInfo\n@end\n\n\n"
  },
  {
    "path": "src/css/unittests/NICSSParserTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCSS.h\"\n\n@interface NICSSParserTests : XCTestCase {\n@private\n  NSBundle* _unitTestBundle;\n}\n\n@end\n\n\n@implementation NICSSParserTests\n\n\n- (void)setUp {\n  _unitTestBundle = [NSBundle bundleWithIdentifier:@\"com.nimbus.css.unittests\"];\n  XCTAssertNotNil(_unitTestBundle, @\"Unable to find the bundle %@\", [NSBundle allBundles]);\n}\n\n- (void)tearDown {\n  _unitTestBundle = nil;\n}\n\n- (void)testFailures {\n  NICSSParser* parser = [[NICSSParser alloc] init];\n  \n  XCTAssertNil([parser dictionaryForPath:nil], @\"Parsing nil path should result in nil.\");\n  XCTAssertNil([parser dictionaryForPath:nil pathPrefix:nil], @\"Parsing nil path should result in nil.\");\n  XCTAssertNil([parser dictionaryForPath:nil pathPrefix:nil delegate:nil], @\"Parsing nil path should result in nil.\");\n  XCTAssertNil([parser dictionaryForPath:@\"\" pathPrefix:nil], @\"Parsing empty path should result in nil.\");\n  XCTAssertNil([parser dictionaryForPath:nil pathPrefix:@\"\"], @\"Parsing empty path should result in nil.\");\n  XCTAssertNil([parser dictionaryForPath:@\"nonexistent_file\" pathPrefix:@\"\"], @\"Parsing nonexistent file should result in nil.\");\n}\n\n- (void)testEmptyFile {\n  NICSSParser* parser = [[NICSSParser alloc] init];\n  \n  NSString* pathToFile = NIPathForBundleResource(_unitTestBundle, @\"empty.css\");\n\n  NSDictionary* rulesets = [parser dictionaryForPath:pathToFile];\n  XCTAssertEqual([rulesets count], (NSUInteger)0, @\"There should be no rule sets for an empty file.\");\n}\n\n- (void)testComments {\n  NICSSParser* parser = [[NICSSParser alloc] init];\n  \n  NSString* pathToFile = NIPathForBundleResource(_unitTestBundle, @\"comments.css\");\n  \n  NSDictionary* rulesets = [parser dictionaryForPath:pathToFile];\n  XCTAssertEqual([rulesets count], (NSUInteger)0, @\"There should be no rule sets.\");\n}\n\n- (void)testMalformed {\n  NICSSParser* parser = [[NICSSParser alloc] init];\n\n  NSString* pathToFile = NIPathForBundleResource(_unitTestBundle, @\"malformed.css\");\n\n  NSDictionary* rulesets = [parser dictionaryForPath:pathToFile];\n  XCTAssertNil(rulesets, @\"The file should have failed to process.\");\n  XCTAssertTrue(parser.didFailToParse, @\"The parser should have failed.\");\n}\n\n- (void)testEmptyRulesets {\n  NICSSParser* parser = [[NICSSParser alloc] init];\n\n  NSString* pathToFile = NIPathForBundleResource(_unitTestBundle, @\"empty-rulesets.css\");\n\n  NSDictionary* rulesets = [parser dictionaryForPath:pathToFile];\n  XCTAssertEqual([rulesets count], (NSUInteger)7, @\"There should be seven rule sets.\");\n  XCTAssertNotNil([rulesets objectForKey:@\"#topLevelView\"], @\"Key should exist.\");\n  XCTAssertNotNil([rulesets objectForKey:@\"#topLevelView UILabel\"], @\"Key should exist.\");\n  XCTAssertNotNil([rulesets objectForKey:@\"UIButton\"], @\"Key should exist.\");\n  XCTAssertNotNil([rulesets objectForKey:@\"UILabel\"], @\"Key should exist.\");\n  XCTAssertNotNil([rulesets objectForKey:@\"UINavigationBar ContainerView UILabel\"], @\"Key should exist.\");\n  XCTAssertNotNil([rulesets objectForKey:@\"UINavigationBar UILabel\"], @\"Key should exist.\");\n  XCTAssertNotNil([rulesets objectForKey:@\"UITextView\"], @\"Key should exist.\");\n\n  for (id key in rulesets) {\n    XCTAssertEqual([[rulesets objectForKey:key] count], (NSUInteger)1, @\"All rulesets should only have the rule set order.\");\n  }\n}\n\n- (void)testMediaRulesets {\n    NICSSParser* parser = [[NICSSParser alloc] init];\n    \n    NSString* pathToFile = NIPathForBundleResource(_unitTestBundle, @\"media-rulesets.css\");\n    \n    NSDictionary* rulesets = [parser dictionaryForPath:pathToFile];\n   // STAssertNotNil([rulesets objectForKey:@\"UIView\"], @\"@media tag with all known combinations didn't match one.\");\n    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {\n        if ([UIScreen mainScreen].scale == 1.0) {\n            XCTAssertNotNil([rulesets objectForKey:@\"UINavigationBar\"], @\"@media tag didn't match properly.\");\n            XCTAssertNotNil([rulesets objectForKey:@\"#UINavigationBar\"], @\"@media tag didn't match properly.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UITextField\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"UIButton\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UIButton\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UILabel\"], @\"@media tag shouldn't have matched.\");\n        } else {\n            XCTAssertNotNil([rulesets objectForKey:@\"UINavigationBar\"], @\"@media tag didn't match properly.\");\n            XCTAssertNotNil([rulesets objectForKey:@\"#UITextField\"], @\"@media tag didn't match properly.\");            \n            XCTAssertNil([rulesets objectForKey:@\"#UINavigationBar\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"UIButton\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UIButton\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UILabel\"], @\"@media tag shouldn't have matched.\");\n        }\n    } else {\n        if ([UIScreen mainScreen].scale == 1.0) {\n            XCTAssertNotNil([rulesets objectForKey:@\"UIButton\"], @\"@media tag didn't match properly.\");\n            XCTAssertNotNil([rulesets objectForKey:@\"#UIButton\"], @\"@media tag didn't match properly.\");\n            XCTAssertNil([rulesets objectForKey:@\"UINavigationBar\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UINavigationBar\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UITextField\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UILabel\"], @\"@media tag shouldn't have matched.\");\n        } else {\n            XCTAssertNotNil([rulesets objectForKey:@\"UIButton\"], @\"@media tag didn't match properly.\");\n            XCTAssertNotNil([rulesets objectForKey:@\"#UILabel\"], @\"@media tag didn't match properly.\");\n            XCTAssertNil([rulesets objectForKey:@\"UINavigationBar\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UINavigationBar\"], @\"@media tag shouldn't have matched.\");\n            XCTAssertNil([rulesets objectForKey:@\"#UITextField\"], @\"@media tag shouldn't have matched.\");\n        }\n    }\n}\n\n- (void)testRulesets {\n  NICSSParser* parser = [[NICSSParser alloc] init];\n\n  NSString* pathToFile = NIPathForBundleResource(_unitTestBundle, @\"rulesets.css\");\n\n  NSDictionary* rulesets = [parser dictionaryForPath:pathToFile];\n  XCTAssertEqual([rulesets count], (NSUInteger)4, @\"There should be four rule sets.\");\n\n  XCTAssertTrue([[[[rulesets objectForKey:@\".className\"] objectForKey:@\"background-color\"] objectAtIndex:0] isEqualToString:@\"orange\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UIButton\"] objectForKey:@\"color\"] objectAtIndex:0] isEqualToString:@\"red\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UIButton\"] objectForKey:@\"height\"] objectAtIndex:0] isEqualToString:@\"20px\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UIButton\"] objectForKey:@\"width\"] objectAtIndex:0] isEqualToString:@\"100%\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UIButton:hover\"] objectForKey:@\"color\"] objectAtIndex:0] isEqualToString:@\"blue\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UILabel\"] objectForKey:@\"font-size\"] objectAtIndex:0] isEqualToString:@\"23\"], @\"Value should match.\");\n}\n\n- (void)testRulesetOverrides {\n  NICSSParser* parser = [[NICSSParser alloc] init];\n\n  NSString* pathToFile = NIPathForBundleResource(_unitTestBundle, @\"rulesets-overrides.css\");\n\n  NSDictionary* rulesets = [parser dictionaryForPath:pathToFile];\n  XCTAssertEqual([rulesets count], (NSUInteger)3, @\"There should be three rule sets.\");\n\n  XCTAssertTrue([[[[rulesets objectForKey:@\".className\"] objectForKey:@\"background-color\"] objectAtIndex:0] isEqualToString:@\"green\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UIButton\"] objectForKey:@\"color\"] objectAtIndex:0] isEqualToString:@\"black\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UIButton\"] objectForKey:@\"height\"] objectAtIndex:0] isEqualToString:@\"20px\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UIButton\"] objectForKey:@\"width\"] objectAtIndex:0] isEqualToString:@\"100%\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UILabel\"] objectForKey:@\"font-size\"] objectAtIndex:0] isEqualToString:@\"50\"], @\"Value should match.\");\n}\n\n- (void)testImports {\n  NICSSParser* parser = [[NICSSParser alloc] init];\n\n  NSString* pathPrefix = NIPathForBundleResource(_unitTestBundle, nil);\n\n  NSDictionary* rulesets = [parser dictionaryForPath:@\"includer.css\" pathPrefix:pathPrefix];\n  XCTAssertEqual([rulesets count], (NSUInteger)2, @\"There should be two values.\");\n  NSSet* dependencies = [rulesets objectForKey:kDependenciesSelectorKey];\n  XCTAssertEqual(dependencies.count, (NSUInteger)1, @\"Should be exactly one dependency.\");\n  XCTAssertTrue([[dependencies anyObject] isEqualToString:@\"includee.css\"], @\"Should be equal.\");\n\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UIButton\"] objectForKey:@\"width\"] objectAtIndex:0] isEqualToString:@\"50%\"], @\"Value should match.\");\n  XCTAssertTrue([[[[rulesets objectForKey:@\"UIButton\"] objectForKey:@\"height\"] objectAtIndex:0] isEqualToString:@\"20px\"], @\"Value should match.\");\n}\n\n@end\n"
  },
  {
    "path": "src/css/unittests/NIStylesheetTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCSS.h\"\n\n@interface NIStylesheetTests : XCTestCase {\n@private\n  NSBundle* _unitTestBundle;\n}\n\n@end\n\n\n@implementation NIStylesheetTests\n\n\n- (void)setUp {\n  _unitTestBundle = [NSBundle bundleWithIdentifier:@\"com.nimbus.css.unittests\"];\n  XCTAssertNotNil(_unitTestBundle, @\"Unable to find the bundle %@\", [NSBundle allBundles]);\n}\n\n- (void)tearDown {\n  _unitTestBundle = nil;\n}\n\n- (void)testFailures {\n  NIStylesheet* stylesheet = [[NIStylesheet alloc] init];\n\n  XCTAssertFalse([stylesheet loadFromPath:nil], @\"Parsing nil path should fail.\");\n  XCTAssertFalse([stylesheet loadFromPath:nil pathPrefix:nil], @\"Parsing nil path should fail.\");\n  XCTAssertFalse([stylesheet loadFromPath:nil pathPrefix:nil delegate:nil], @\"Parsing nil path should fail.\");\n  XCTAssertFalse([stylesheet loadFromPath:@\"\"], @\"Parsing empty path should fail.\");\n  XCTAssertFalse([stylesheet loadFromPath:@\"nonexistent_file\"], @\"Parsing invalid file should fail.\");\n}\n\n- (void)assertColor:(UIColor *)color1 equalsColor:(UIColor *)color2 {\n  size_t nColors1 = CGColorGetNumberOfComponents(color1.CGColor);\n  size_t nColors2 = CGColorGetNumberOfComponents(color2.CGColor);\n  XCTAssertEqual(nColors1, nColors2, @\"Should have the same number of components.\");\n\n  const CGFloat* colors1 = CGColorGetComponents(color1.CGColor);\n  const CGFloat* colors2 = CGColorGetComponents(color2.CGColor);\n  for (NSInteger ix = 0; ix < nColors1; ++ix) {\n    XCTAssertEqualWithAccuracy(colors1[ix], colors2[ix], 0.0001, @\"Colors should match.\");\n  }\n}\n\n- (void)testApplyStyleToUILabel {\n  // Sadly nearly all of these tests don't work with SenTest. The error we get when we run these\n  // tests is:\n  // ERROR: System image table has not been initialized. Do not ask for images or set up UI before UIApplicationMain() has been called.\n  return;\n\n  NIStylesheet* stylesheet = [[NIStylesheet alloc] init];\n  NSString* pathToFile = NIPathForBundleResource(_unitTestBundle, @\"UILabel.css\");\n\n  XCTAssertTrue([stylesheet loadFromPath:pathToFile], @\"The stylesheet should have been parsed.\");\n\n  UILabel* label = [[UILabel alloc] initWithFrame:CGRectZero];\n  [stylesheet applyStyleToView:label withClassName:NSStringFromClass([label class]) inDOM:nil];\n\n  [self assertColor:label.textColor equalsColor:[UIColor redColor]];\n  [self assertColor:label.shadowColor equalsColor:[UIColor greenColor]];\n  XCTAssertEqual(label.textAlignment, NSTextAlignmentRight, @\"Alignment should match.\");\n  XCTAssertEqual(label.shadowOffset.width, 20.f, @\"Shadow offset should match.\");\n  XCTAssertEqual(label.shadowOffset.height, -30.f, @\"Shadow offset should match.\");\n  XCTAssertEqual(label.lineBreakMode, NSLineBreakByTruncatingTail, @\"Should match.\");\n  XCTAssertEqual(label.numberOfLines, 5, @\"Should match.\");\n  XCTAssertEqual(label.minimumFontSize, 5.f, @\"Should match.\");\n  XCTAssertTrue(label.adjustsFontSizeToFitWidth, @\"Should match.\");\n  XCTAssertEqual(label.baselineAdjustment, UIBaselineAdjustmentAlignCenters, @\"Should match.\");\n  XCTAssertEqual(label.alpha, 0.5f, @\"Should match.\");\n}\n\n@end\n"
  },
  {
    "path": "src/css/unittests/NimbusCSSTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/css/unittests/UILabel.css",
    "content": "/**\n * This file styles a UILabel view as much as it possibly can.\n */\n\n/** General UIView properties */\nUILabel {\n  background-color: red; /* tested */\n  border: 1px solid blue; /* tested */\n  border-color: orange; /* tested */\n  border-width: 5px; /* tested */\n  border-radius: 10px; /* tested */\n  opacity: 0.5; /* tested */\n}\n\n/** UILabel-specific */\nUILabel {\n  color: red; /* tested */\n  font: 13 Helvetica; /* tested */\n  font-style: italic; /* tested */\n  font-weight: bold; /* tested */\n  text-align: right; /* tested */\n  text-shadow: green 20 -30; /* tested */\n  -ios-line-break-mode: tail-truncate; /* tested */\n  -ios-number-of-lines: 5; /* tested */\n  -ios-minimum-font-size: 5; /* tested */\n  -ios-adjusts-font-size: true; /* tested */\n  -ios-baseline-adjustment: align-centers; /* tested */\n}\n\n/** For when the UILabel is in a UITableViewCell and is tapped. */\nUILabel:active {\n  color: blue;\n}\n"
  },
  {
    "path": "src/css/unittests/comments.css",
    "content": "/**\n * This is a comment!\n */\n\n/** Another comment. */\n"
  },
  {
    "path": "src/css/unittests/empty-rulesets.css",
    "content": "UIButton {\n}\n\nUINavigationBar UILabel {\n}\n\nUINavigationBar ContainerView UILabel {\n}\n\n#topLevelView UILabel {\n}\n\n#topLevelView {\n}\n\nUITextView,\nUILabel {\n}\n"
  },
  {
    "path": "src/css/unittests/empty.css",
    "content": ""
  },
  {
    "path": "src/css/unittests/includee.css",
    "content": "UIButton {\n  width: 100%;\n  height: 20px;\n}\n"
  },
  {
    "path": "src/css/unittests/includer.css",
    "content": "\n@import url('includee.css');\n\nUIButton {\n  width: 50%;\n}\n"
  },
  {
    "path": "src/css/unittests/malformed.css",
    "content": "UIButton {\n  width: 100%;\n  height: 20px;\n  {}\n}\n"
  },
  {
    "path": "src/css/unittests/media-rulesets.css",
    "content": "@media iPad-retina,iPad-nonretina,iPhone-retina,iPhone-nonretina {\nUIView {\n}\n}\n\n@media iPad\n{\nUIButton {\n}\n}\n\n@media iPhone\n{\nUINavigationBar {\n}\n}\n\n@media nonRetina {\nUILabel {\n}\n}\n\n@media retina {\nUITextField {\n}\n}\n\n@media iPad-nonRetina\n{\n#UIButton {\n}\n}\n\n@media iPhone-nonRetina\n{\n#UINavigationBar {\n}\n}\n\n@media iPad-retina {\n#UILabel {\n}\n}\n\n@media iPhone-retina {\n#UITextField {\n}\n}\n\n"
  },
  {
    "path": "src/css/unittests/rulesets-overrides.css",
    "content": "UIButton {\n  width: 100%;\n  height: 20px;\n}\n\nUIButton {\n  color: red;\n}\n\nUILabel {\n  font-size: 23;\n}\n\n.className {\n  background-COLOR: orange;\n}\n\nUIButton {\n  color: black;\n}\n\nUILabel {\n  font-size: 50;\n}\n\n.className {\n  background-color: green;\n}\n"
  },
  {
    "path": "src/css/unittests/rulesets.css",
    "content": "UIButton {\n  width: 100%;\n  height: 20px;\n}\n\nUIButton {\n  color: red;\n}\n\nUILabel {\n  font-size: 23;\n}\n\n.className {\n  background-COLOR: orange;\n}\n\nUIButton:hover {\n  color: blue;\n}\n"
  },
  {
    "path": "src/interapp/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\nCoreLocation.framework\n"
  },
  {
    "path": "src/interapp/src/NIInterapp.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <CoreLocation/CoreLocation.h>\n\n@class NIMailAppInvocation;\n\n/**\n * An interface for interacting with other apps installed on the device.\n *\n * @ingroup NimbusInterapp\n */\n@interface NIInterapp : NSObject\n\n#pragma mark Chrome vs Safari\n\n+ (void)setPreferGoogleChrome:(BOOL)preferGoogleChromeOverSafari;\n+ (BOOL)preferGoogleChrome;\n+ (BOOL)openPreferredBrowserWithURL:(NSURL *)url;\n\n#pragma mark Safari\n\n+ (BOOL)safariWithURL:(NSURL *)url;\n\n#pragma mark Google Chrome\n\n+ (BOOL)googleChromeIsInstalled;\n+ (BOOL)googleChromeWithURL:(NSURL *)url;\n+ (NSString *)googleChromeAppStoreId;\n\n#pragma mark Google Maps\n\n+ (BOOL)googleMapsIsInstalled;\n+ (BOOL)googleMaps;\n+ (NSString *)googleMapsAppStoreId;\n\n+ (BOOL)googleMapAtLocation:(CLLocationCoordinate2D)location;\n+ (BOOL)googleMapAtLocation:(CLLocationCoordinate2D)location title:(NSString *)title;\n+ (BOOL)googleMapDirectionsFromLocation:(CLLocationCoordinate2D)fromLocation toLocation:(CLLocationCoordinate2D)toLocation;\n\n// directionsMode can be nil. @\"driving\", @\"transit\", or @\"walking\".\n+ (BOOL)googleMapDirectionsFromLocation:(CLLocationCoordinate2D)fromLocation toLocation:(CLLocationCoordinate2D)toLocation withMode:(NSString*)directionsMode;\n+ (BOOL)googleMapDirectionsFromSourceAddress:(NSString *)srcAddr toDestAddress:(NSString *)destAddr withMode:(NSString *)directionsMode;\n\n// these just use the user's current location (even if your application doesn't have locations services on, the google maps site/app MIGHT\n+ (BOOL)googleMapDirectionsToDestAddress:(NSString *)destAddr withMode:(NSString *)directionsMode;\n+ (BOOL)googleMapDirectionsToLocation:(CLLocationCoordinate2D)toLocation withMode:(NSString *)directionsMode;\n\n+ (BOOL)googleMapWithQuery:(NSString *)query;\n\n#pragma mark Phone\n\n+ (BOOL)phone;\n+ (BOOL)phoneWithNumber:(NSString *)phoneNumber;\n\n#pragma mark SMS\n\n+ (BOOL)sms;\n+ (BOOL)smsWithNumber:(NSString *)phoneNumber;\n\n#pragma mark Mail\n\n+ (BOOL)mailWithInvocation:(NIMailAppInvocation *)invocation;\n\n#pragma mark YouTube\n\n+ (BOOL)youTubeWithVideoId:(NSString *)videoId;\n\n#pragma mark App Store\n\n+ (BOOL)appStoreWithAppId:(NSString *)appId;\n+ (BOOL)appStoreGiftWithAppId:(NSString *)appId;\n+ (BOOL)appStoreReviewWithAppId:(NSString *)appId;\n\n#pragma mark iBooks\n\n+ (BOOL)iBooksIsInstalled;\n+ (BOOL)iBooks;\n+ (NSString *)iBooksAppStoreId;\n\n#pragma mark Facebook\n\n+ (BOOL)facebookIsInstalled;\n+ (BOOL)facebook;\n+ (BOOL)facebookProfileWithId:(NSString *)profileId;\n+ (NSString *)facebookAppStoreId;\n\n#pragma mark Twitter\n\n+ (BOOL)twitterIsInstalled;\n+ (BOOL)twitter;\n+ (BOOL)twitterWithMessage:(NSString *)message;\n+ (BOOL)twitterProfileForUsername:(NSString *)username;\n+ (NSString *)twitterAppStoreId;\n\n#pragma mark Instagram\n\n+ (BOOL)instagramIsInstalled;\n+ (BOOL)instagram;\n+ (BOOL)instagramCamera;\n+ (BOOL)instagramProfileForUsername:(NSString *)username;\n+ (NSURL *)urlForInstagramImageAtFilePath:(NSString *)filePath error:(NSError **)error;\n+ (NSString *)instagramAppStoreId;\n\n#pragma mark Custom Application\n\n+ (BOOL)applicationIsInstalledWithScheme:(NSString *)applicationScheme;\n+ (BOOL)applicationWithScheme:(NSString *)applicationScheme;\n+ (BOOL)applicationWithScheme:(NSString *)applicationScheme andAppStoreId:(NSString *)appStoreId;\n+ (BOOL)applicationWithScheme:(NSString *)applicationScheme andPath:(NSString *)path;\n+ (BOOL)applicationWithScheme:(NSString *)applicationScheme appStoreId:(NSString *)appStoreId andPath:(NSString *)path;\n\n@end\n\n@interface NIMailAppInvocation : NSObject {\n@private\n  NSString* _recipient;\n  NSString* _cc;\n  NSString* _bcc;\n  NSString* _subject;\n  NSString* _body;\n}\n\n@property (nonatomic, copy) NSString* recipient;\n@property (nonatomic, copy) NSString* cc;\n@property (nonatomic, copy) NSString* bcc;\n@property (nonatomic, copy) NSString* subject;\n@property (nonatomic, copy) NSString* body;\n\n/**\n * Returns an autoreleased invocation object.\n */\n+ (id)invocation;\n\n@end\n\n/** @name Safari **/\n\n/**\n * Opens the given URL in Safari.\n *\n * @fn NIInterapp::safariWithURL:\n */\n\n\n/** @name Google Chrome **/\n\n/**\n * Returns YES if the Google Chrome application is installed.\n *\n * @fn NIInterapp::googleChromeIsInstalled\n */\n\n/**\n * Opens the given URL in Google Chrome if installed on the device.\n *\n * @fn NIINterapp::googleChromeWithURL:\n */\n\n/**\n * The Google Chrome App Store ID.\n *\n * @fn NIInterapp::googleChromeAppStoreId\n */\n\n\n/** @name Google Maps **/\n\n/**\n * Opens Google Maps at the given location.\n *\n * @fn NIInterapp::googleMapAtLocation:\n */\n\n/**\n * Opens Google Maps at the given location with a title.\n *\n * @fn NIInterapp::googleMapAtLocation:title:\n */\n\n/**\n * Opens Google Maps with directions from one location to another.\n *\n * @fn NIInterapp::googleMapDirectionsFromLocation:toLocation:\n */\n\n/**\n * Opens Google Maps with a generic query.\n *\n * @fn NIInterapp::googleMapWithQuery:\n */\n\n\n/** @name Phone **/\n\n/**\n * Opens the phone app.\n *\n * @fn NIInterapp::phone\n */\n\n/**\n * Make a phone call with the given number.\n *\n * @fn NIInterapp::phoneWithNumber:\n */\n\n\n/** @name SMS **/\n\n/**\n * Opens the phone app.\n *\n * @fn NIInterapp::sms\n */\n\n/**\n * Start texting the given number.\n *\n * @fn NIInterapp::smsWithNumber:\n */\n\n\n/** @name Mail **/\n\n/**\n * Opens mail with the given invocation properties.\n *\n * @fn NIInterapp::mailWithInvocation:\n */\n\n\n/** @name YouTube **/\n\n/**\n * Opens the YouTube video with the given video id.\n *\n * @fn NIInterapp::youTubeWithVideoId:\n */\n\n\n/** @name iBooks **/\n\n/**\n * Returns YES if the iBooks application is installed.\n *\n * @fn NIInterapp::iBooksIsInstalled\n */\n\n/**\n * Opens the iBooks application. If the iBooks application is not installed, will open the\n * App Store to the iBooks download page.\n *\n * @fn NIInterapp::iBooks\n */\n\n/**\n * The iBooks App Store ID.\n *\n * @fn NIInterapp::iBooksAppStoreId\n */\n\n\n/** @name Facebook **/\n\n/**\n * Returns YES if the Facebook application is installed.\n *\n * @fn NIInterapp::facebookIsInstalled\n */\n\n/**\n * Opens the Facebook application. If the Facebook application is not installed, will open the\n * App Store to the Facebook download page.\n *\n * @fn NIInterapp::facebook\n */\n\n/**\n * Opens the Facebook profile with the given id.\n *\n * @fn NIInterapp::facebookProfileWithId:\n */\n\n/**\n * The Facebook App Store ID.\n *\n * @fn NIInterapp::facebookAppStoreId\n */\n\n\n/** @name Twitter **/\n\n/**\n * Returns YES if the Twitter application is installed.\n *\n * @fn NIInterapp::twitterIsInstalled\n */\n\n/**\n * Opens the Twitter application. If the Twitter application is not installed, will open the\n * App Store to the Twitter download page.\n *\n * @fn NIInterapp::twitter\n */\n\n/**\n * Begins composing a message.\n *\n * @fn NIInterapp::twitterWithMessage:\n */\n\n/**\n * Opens the profile for the given username.\n *\n * @fn NIInterapp::twitterProfileForUsername:\n */\n\n/**\n * The Twitter App Store ID.\n *\n * @fn NIInterapp::twitterAppStoreId\n */\n\n\n/** @name Custom Application **/\n\n/**\n * Returns YES if the supplied application is installed.\n *\n * @fn NIInterapp::applicationIsInstalledWithScheme:\n */\n\n/**\n * Opens the supplied application.\n *\n * @fn NIInterapp::applicationWithScheme\n */\n\n/**\n * Opens the supplied application. If the supplied application is not installed, will open the\n * App Store to the specified ID download page.\n *\n * @fn NIInterapp::applicationWithScheme:andAppStoreId:\n */\n\n/**\n * Opens the supplied application.\n *\n * @fn NIInterapp::applicationWithScheme:andPath:\n */\n\n/**\n * Opens the supplied application, to the specified path. If the supplied application is not installed, will open the\n * App Store to the download page for the specified AppStoreId.\n *\n * @fn NIInterapp::applicationWithScheme:appStoreId:andPath:\n */\n\n/**\n * Opens the application with the supplied custom URL.\n *\n * @fn NIInterapp::applicationWithUrl:\n */\n\n\n/** @name Instagram **/\n// http://instagram.com/developer/iphone-hooks/\n\n/**\n * Returns YES if the Instagram application is installed.\n *\n * @fn NIInterapp::instagramIsInstalled\n */\n\n/**\n * Opens the Instagram application. If the Instagram application is not installed, will open the\n * App Store to the Instagram download page.\n *\n * @fn NIInterapp::instagram\n */\n\n/**\n * Opens the Instagram camera.\n *\n * @fn NIInterapp::instagramCamera\n */\n\n/**\n * Opens the profile for the given username.\n *\n * @fn NIInterapp::instagramProfileForUsername:\n */\n\n/**\n * Copies an image to a temporary path suitable for use with a UIDocumentInteractionController in\n * order to open the image in Instagram.\n *\n * The image at filePath must be at least 612x612 and preferably square. If the image\n * is smaller than 612x612 then this method will fail.\n *\n * @fn NIInterapp::urlForInstagramImageAtFilePath:error:\n */\n\n/**\n * The Instagram App Store ID.\n *\n * @fn NIInterapp::instagramAppStoreId\n */\n\n\n/** @name App Store **/\n\n/**\n * Opens the App Store page for the app with the given ID.\n *\n * @fn NIInterapp::appStoreWithAppId:\n */\n\n/**\n * Opens the \"Gift this app\" App Store page for the app with the given ID.\n *\n * @fn NIInterapp::appStoreGiftWithAppId:\n */\n\n/**\n * Opens the \"Write a review\" App Store page for the app with the given ID.\n *\n * @fn NIInterapp::appStoreReviewWithAppId:\n */\n"
  },
  {
    "path": "src/interapp/src/NIInterapp.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIInterapp.h\"\n\n#import \"NimbusCore+Additions.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n// TODO: Make this a user default.\nstatic BOOL sPreferGoogleChrome = NO;\n\n@implementation NIInterapp\n\n+ (NSString *)sanitizedPhoneNumberFromString:(NSString *)string {\n  if (nil == string) {\n    return nil;\n  }\n\n  NSCharacterSet* validCharacters = [NSCharacterSet characterSetWithCharactersInString:@\"1234567890-+\"];\n  return [[string componentsSeparatedByCharactersInSet:[validCharacters invertedSet]]\n          componentsJoinedByString:@\"\"];\n}\n\n#pragma mark Chrome vs Safari\n\n+ (void)setPreferGoogleChrome:(BOOL)preferGoogleChrome {\n  sPreferGoogleChrome = preferGoogleChrome;\n}\n\n+ (BOOL)preferGoogleChrome {\n  return sPreferGoogleChrome;\n}\n\n+ (BOOL)openPreferredBrowserWithURL:(NSURL *)url {\n  if (sPreferGoogleChrome && [NIInterapp googleChromeIsInstalled]) {\n    return [NIInterapp googleChromeWithURL:url];\n  } else {\n    return [NIInterapp safariWithURL:url];\n  }\n}\n\n#pragma mark - Safari\n\n+ (BOOL)safariWithURL:(NSURL *)url {\n  return [[UIApplication sharedApplication] openURL:url];\n}\n\n#pragma mark - Google Chrome\n\n/**\n * Based on https://developers.google.com/chrome/mobile/docs/ios-links\n */\n\nstatic NSString* const sGoogleChromeHttpScheme = @\"googlechrome:\";\nstatic NSString* const sGoogleChromeHttpsScheme = @\"googlechromes:\";\n\n+ (BOOL)googleChromeIsInstalled {\n  return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sGoogleChromeHttpScheme]];\n}\n\n+ (BOOL)googleChromeWithURL:(NSURL *)url {\n  NSString *chromeScheme = nil;\n  if ([url.scheme isEqualToString:@\"http\"]) {\n    chromeScheme = sGoogleChromeHttpScheme;\n  } else if ([url.scheme isEqualToString:@\"https\"]) {\n    chromeScheme = sGoogleChromeHttpsScheme;\n  }\n\n  if (chromeScheme) {\n    NSRange rangeForScheme = [[url absoluteString] rangeOfString:@\":\"];\n    NSString* urlNoScheme =  [[url absoluteString] substringFromIndex:rangeForScheme.location + 1];\n    NSString* chromeUrlString = [chromeScheme stringByAppendingString:urlNoScheme];\n    NSURL* chromeUrl = [NSURL URLWithString:chromeUrlString];\n\n    BOOL didOpen = [[UIApplication sharedApplication] openURL:chromeUrl];\n    if (!didOpen) {\n      didOpen = [self appStoreWithAppId:[self googleChromeAppStoreId]];\n    }\n\n    return didOpen;\n  }\n\n  return NO;\n}\n\n+ (NSString *)googleChromeAppStoreId {\n  return @\"535886823\";\n}\n\n#pragma mark - Google Maps\n\n/**\n * Source for URL information: http://mapki.com/wiki/Google_Map_Parameters\n */\n\nstatic NSString* const sGoogleMapsScheme = @\"comgooglemaps:\";\n\n+ (BOOL)googleMapsIsInstalled {\n  return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sGoogleMapsScheme]];\n}\n\n+ (BOOL)googleMaps {\n  BOOL didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:sGoogleMapsScheme]];\n  \n  if (!didOpen) {\n    didOpen = [self appStoreWithAppId:[self googleMapsAppStoreId]];\n  }\n  \n  return didOpen;\n}\n\n+ (NSString *)googleMapsAppStoreId {\n  return @\"585027354\";\n}\n\n+ (BOOL)openBestGoogleMapUrl:(NSString*)urlString{\n  if ([NIInterapp googleMapsIsInstalled]) {\n    NSURL* url = [NSURL URLWithString:[@\"comgooglemaps://\" stringByAppendingString:urlString]];\n    return [[UIApplication sharedApplication] openURL:url];\n  } else {\n    NSURL* url = [NSURL URLWithString:[@\"https://maps.google.com/maps\" stringByAppendingString:urlString]];\n    return [NIInterapp openPreferredBrowserWithURL:url];\n  }\n}\n\n+ (BOOL)googleMapAtLocation:(CLLocationCoordinate2D)location {\n  NSString* urlPath = [NSString stringWithFormat:@\"?q=%f,%f\", location.latitude, location.longitude];\n  return [NIInterapp openBestGoogleMapUrl:urlPath];\n}\n\n+ (BOOL)googleMapAtLocation:(CLLocationCoordinate2D)location title:(NSString *)title {\n  NSString* urlPath = [NSString stringWithFormat:@\"?q=%@@%f,%f\",\n                       NIStringByAddingPercentEscapesForURLParameterString(title),\n                       location.latitude, location.longitude];\n  return [NIInterapp openBestGoogleMapUrl:urlPath];\n\n}\n\n+ (BOOL)googleMapDirectionsFromLocation:(CLLocationCoordinate2D)fromLocation\n                             toLocation:(CLLocationCoordinate2D)toLocation {\n  return [NIInterapp googleMapDirectionsFromLocation:fromLocation toLocation:toLocation withMode:nil];\n}\n\n+ (BOOL)googleMapDirectionsFromLocation:(CLLocationCoordinate2D)fromLocation\n                             toLocation:(CLLocationCoordinate2D)toLocation\n                               withMode:(NSString *)directionsMode {\n  NSString* saddr = [NSString stringWithFormat:@\"%f,%f\", fromLocation.latitude, fromLocation.longitude];\n  NSString* daddr = [NSString stringWithFormat:@\"%f,%f\", toLocation.latitude, toLocation.longitude];\n\n  return [NIInterapp googleMapDirectionsFromSourceAddress:saddr toDestAddress:daddr withMode:directionsMode];\n}\n\n+ (BOOL)googleMapDirectionsToLocation:(CLLocationCoordinate2D)toLocation\n                             withMode:(NSString *)directionsMode {\n  NSString* daddr = [NSString stringWithFormat:@\"%f,%f\", toLocation.latitude, toLocation.longitude];\n  return [NIInterapp googleMapDirectionsFromSourceAddress:nil toDestAddress:daddr withMode:directionsMode];\n}\n\n+ (BOOL)googleMapDirectionsToDestAddress:(NSString *)destAddr withMode:(NSString *)directionsMode {\n  return [NIInterapp googleMapDirectionsFromSourceAddress:nil toDestAddress:destAddr withMode:directionsMode];\n}\n\n+ (BOOL)googleMapDirectionsFromSourceAddress:(NSString *)srcAddr\n                               toDestAddress:(NSString *)destAddr\n                                    withMode:(NSString *)directionsMode {\n  NSString* urlPath;\n  // source can be left blank  == get current users location\n  if (srcAddr.length > 0) {\n    urlPath = [NSString stringWithFormat:@\"?saddr=%@&daddr=%@\", srcAddr, destAddr];\n  } else {\n    urlPath = [NSString stringWithFormat:@\"?daddr=%@\", destAddr];\n  }\n  if (directionsMode.length > 0) {\n    urlPath = [NSString stringWithFormat:@\"%@&directionsmode=%@\", urlPath, directionsMode];\n  }\n  return [NIInterapp openBestGoogleMapUrl:urlPath];\n}\n\n+ (BOOL)googleMapWithQuery:(NSString *)query {\n  NSString* urlPath = [NSString stringWithFormat:@\"?q=%@\", NIStringByAddingPercentEscapesForURLParameterString(query)];\n  return [NIInterapp openBestGoogleMapUrl:urlPath];\n}\n\n#pragma mark - Phone\n\n+ (BOOL)phone {\n  return [self phoneWithNumber:nil];\n}\n\n+ (BOOL)phoneWithNumber:(NSString *)phoneNumber {\n  phoneNumber = [self sanitizedPhoneNumberFromString:phoneNumber];\n\n  if (nil == phoneNumber) {\n    phoneNumber = @\"\";\n  }\n\n  NSString* urlPath = [@\"tel:\" stringByAppendingString:phoneNumber];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n#pragma mark - Texting\n\n+ (BOOL)sms {\n  return [self smsWithNumber:nil];\n}\n\n+ (BOOL)smsWithNumber:(NSString *)phoneNumber {\n  phoneNumber = [self sanitizedPhoneNumberFromString:phoneNumber];\n\n  if (nil == phoneNumber) {\n    phoneNumber = @\"\";\n  }\n\n  NSString* urlPath = [@\"sms:\" stringByAppendingString:phoneNumber];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n#pragma mark - Mail\n\nstatic NSString* const sMailScheme = @\"mailto:\";\n\n+ (BOOL)mailWithInvocation:(NIMailAppInvocation *)invocation {\n  NSMutableDictionary* parameters = [NSMutableDictionary dictionary];\n\n  NSString* urlPath = sMailScheme;\n\n  if (NIIsStringWithAnyText(invocation.recipient)) {\n    urlPath = [urlPath stringByAppendingString:NIStringByAddingPercentEscapesForURLParameterString(invocation.recipient)];\n  }\n\n  if (NIIsStringWithAnyText(invocation.cc)) {\n    [parameters setObject:invocation.cc forKey:@\"cc\"];\n  }\n  if (NIIsStringWithAnyText(invocation.bcc)) {\n    [parameters setObject:invocation.bcc forKey:@\"bcc\"];\n  }\n  if (NIIsStringWithAnyText(invocation.subject)) {\n    [parameters setObject:invocation.subject forKey:@\"subject\"];\n  }\n  if (NIIsStringWithAnyText(invocation.body)) {\n    [parameters setObject:invocation.body forKey:@\"body\"];\n  }\n\n  urlPath = NIStringByAddingQueryDictionaryToString(urlPath, parameters);\n\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n#pragma mark - YouTube\n\n+ (BOOL)youTubeWithVideoId:(NSString *)videoId {\n  NSString* urlPath = [@\"http://www.youtube.com/watch?v=\" stringByAppendingString:videoId];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n#pragma mark - iBooks\n\nstatic NSString* const sIBooksScheme = @\"itms-books:\";\n\n+ (BOOL)iBooksIsInstalled {\n  return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sIBooksScheme]];\n}\n\n+ (BOOL)iBooks {\n  BOOL didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:sIBooksScheme]];\n\n  if (!didOpen) {\n    didOpen = [self appStoreWithAppId:[self iBooksAppStoreId]];\n  }\n\n  return didOpen;\n}\n\n+ (NSString *)iBooksAppStoreId {\n  return @\"364709193\";\n}\n\n#pragma mark - Facebook\n\nstatic NSString* const sFacebookScheme = @\"fb:\";\n\n+ (BOOL)facebookIsInstalled {\n  return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sFacebookScheme]];\n}\n\n+ (BOOL)facebook {\n  BOOL didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:sFacebookScheme]];\n\n  if (!didOpen) {\n    didOpen = [self appStoreWithAppId:[self facebookAppStoreId]];\n  }\n  \n  return didOpen;\n}\n\n+ (BOOL)facebookProfileWithId:(NSString *)profileId {\n  NSString* urlPath = [sFacebookScheme stringByAppendingFormat:@\"//profile/%@\", profileId];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n+ (NSString *)facebookAppStoreId {\n  return @\"284882215\";\n}\n\n#pragma mark - Twitter\n\nstatic NSString* const sTwitterScheme = @\"twitter:\";\n\n+ (BOOL)twitterIsInstalled {\n  return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sTwitterScheme]];\n}\n\n+ (BOOL)twitter {\n  BOOL didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:sTwitterScheme]];\n\n  if (!didOpen) {\n    didOpen = [self appStoreWithAppId:[self twitterAppStoreId]];\n  }\n  \n  return didOpen;\n}\n\n+ (BOOL)twitterWithMessage:(NSString *)message {\n  NSString* urlPath = [sTwitterScheme stringByAppendingFormat:@\"//post?message=%@\",\n                       NIStringByAddingPercentEscapesForURLParameterString(message)];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n+ (BOOL)twitterProfileForUsername:(NSString *)username {\n  NSString* urlPath = [sTwitterScheme stringByAppendingFormat:@\"//user?screen_name=%@\",\n                       NIStringByAddingPercentEscapesForURLParameterString(username)];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n+ (NSString *)twitterAppStoreId {\n  return @\"333903271\";\n}\n\n#pragma mark - Application\n\n+ (BOOL)applicationIsInstalledWithScheme:(NSString *)applicationScheme {\n    return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:applicationScheme]];\n}\n\n+ (BOOL)applicationWithScheme:(NSString *)applicationScheme {\n    return [self applicationWithScheme:applicationScheme\n                            appStoreId:nil\n                               andPath:nil];\n}\n\n+ (BOOL)applicationWithScheme:(NSString *)applicationScheme\n                andAppStoreId:(NSString *)appStoreId {\n    return [self applicationWithScheme:applicationScheme\n                            appStoreId:appStoreId\n                               andPath:nil];\n}\n\n+ (BOOL)applicationWithScheme:(NSString *)applicationScheme\n                      andPath:(NSString *)path {\n    return [self applicationWithScheme:applicationScheme\n                            appStoreId:nil\n                               andPath:path];\n}\n\n+ (BOOL)applicationWithScheme:(NSString *)applicationScheme\n                   appStoreId:(NSString *)appStoreId\n                      andPath:(NSString *)path {\n  BOOL didOpen = false;\n  NSString* urlPath = applicationScheme;\n\n  // Were we passed a path?\n  if (path != nil) {\n    // Generate the full application URL\n    urlPath = [urlPath stringByAppendingFormat:@\"%@\", path];\n  }\n\n  // Try to open the application URL\n  didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n\n  // Didn't open and we have an appStoreId\n  if (!didOpen && appStoreId != nil) {\n    // Open the app store instead\n    didOpen = [self appStoreWithAppId:appStoreId];\n  }\n\n  return didOpen;\n}\n\n#pragma mark - Instagram\n\nstatic NSString* const sInstagramScheme = @\"instagram:\";\n\n+ (BOOL)instagramIsInstalled {\n  return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:sInstagramScheme]];\n}\n\n+ (BOOL)instagram {\n  BOOL didOpen = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:sInstagramScheme]];\n\n  if (!didOpen) {\n    didOpen = [self appStoreWithAppId:[self instagramAppStoreId]];\n  }\n\n  return didOpen;\n}\n\n+ (BOOL)instagramCamera {\n  NSString* urlPath = [sInstagramScheme stringByAppendingString:@\"//camera\"];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n+ (BOOL)instagramProfileForUsername:(NSString *)username {\n  NSString* urlPath = [sInstagramScheme stringByAppendingFormat:@\"//user?username=%@\",\n                       NIStringByAddingPercentEscapesForURLParameterString(username)];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n+ (NSURL *)urlForInstagramImageAtFilePath:(NSString *)filePath error:(NSError **)error {\n  if (![self instagramIsInstalled]) {\n    return nil;\n  }\n\n  UIImage* image = [[UIImage alloc] initWithContentsOfFile:filePath];\n\n  // Unable to read the image.\n  if (nil == image) {\n    if (nil != error) {\n      *error = [NSError errorWithDomain: NSCocoaErrorDomain\n                                   code: NSFileReadUnknownError\n                               userInfo: [NSDictionary dictionaryWithObject: filePath\n                                                                     forKey: NSFilePathErrorKey]];\n    }\n    return nil;\n  }\n\n  // Instagram requires that images are at least 612x612 and preferably square.\n  if (image.size.width < 612\n      || image.size.height < 612) {\n    if (nil != error) {\n      *error = [NSError errorWithDomain: NINimbusErrorDomain\n                                   code: NIImageTooSmall\n                               userInfo: [NSDictionary dictionaryWithObject: image\n                                                                     forKey: NIImageErrorKey]];\n    }\n    return nil;\n  }\n\n  NSFileManager* fm = [NSFileManager defaultManager];\n  NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);\n\n  NIDASSERT(NIIsArrayWithObjects(paths));\n  if (!NIIsArrayWithObjects(paths)) {\n    return nil;\n  }\n\n  NSString* documentsPath = [paths objectAtIndex:0];\n  NSString* destinationPath = [documentsPath stringByAppendingPathComponent:\n                               [NSString stringWithFormat:@\"nimbus-instagram-image-%.0f.ig\",\n                                [NSDate timeIntervalSinceReferenceDate]]];\n\n  [fm copyItemAtPath: filePath\n              toPath: destinationPath\n               error: error];\n\n  NIDASSERT(nil == error || nil == *error);\n  if (nil == error || nil == *error) {\n    return [NSURL URLWithString:[@\"file:\" stringByAppendingString:destinationPath]];\n\n  } else {\n    return nil;\n  }\n}\n\n+ (NSString *)instagramAppStoreId {\n  return @\"389801252\";\n}\n\n#pragma mark - App Store\n\n+ (BOOL)appStoreWithAppId:(NSString *)appId {\n  NSString* urlPath = [@\"http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=\" stringByAppendingString:appId];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n+ (BOOL)appStoreGiftWithAppId:(NSString *)appId {\n  NSString* urlPath = [NSString stringWithFormat:@\"itms-appss://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/giftSongsWizard?gift=1&salableAdamId=%@&productType=C&pricingParameter=STDQ&mt=8&ign-mscache=1\", appId];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n+ (BOOL)appStoreReviewWithAppId:(NSString *)appId {\n  NSString* urlPath = [@\"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=\" stringByAppendingString:appId];\n  return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlPath]];\n}\n\n@end\n\n@implementation NIMailAppInvocation\n\n+ (id)invocation {\n  return [[[self class] alloc] init];\n}\n\n@end\n"
  },
  {
    "path": "src/interapp/src/NimbusInterapp.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n/**\n * @defgroup NimbusInterapp Nimbus Interapp\n *\n * <div id=\"github\" feature=\"interapp\"></div>\n *\n * Nimbus' inter-application communication feature for interacting with other applications\n * installed on the device.\n *\n * Applications may define schemes that make it possible to open them from your own application\n * using <code>[[UIApplication sharedApplication] openURL:]</code>. There is no way to\n * ask an application which URLs it implements, so Interapp strives to provide a growing\n * set of implementations for known application interfaces.\n *\n * <h2>Minimum Requirements</h2>\n *\n * Required frameworks:\n *\n * - Foundation.framework\n * - UIKit.framework\n * - CoreLocation.framework\n *\n * Minimum Operating System: <b>iOS 4.0</b>\n *\n * Source located in <code>src/interapp/src</code>\n *\n *\n * <h2>When to Use Interapp</h2>\n *\n * Interapp is particularly useful if you would like to reuse functionality provided by other\n * applications. For example, imagine building an app for a client that would optionally\n * support tweeting messages. Instead of building Oath into your application, you\n * can simply check to see whether the Twitter app is installed and then launch it with a\n * pre-populated message. If the app is not installed, Interapp also makes it easy to launch\n * the App Store directly to the page where the app can be downloaded.\n *\n * Choosing to use Interapp over building functionality into your application is a definite\n * tradeoff. Keeping the user within the context of your application may be worth the extra\n * effort to communicate with the API or implement the functionality yourself. In this case\n * you may find it useful to use Interapp as a quick means of prototyping the eventual\n * functionality.\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>Composing a Message in the Twitter App</h3>\n *\n * @code\n *  // Check whether the Twitter app is installed.\n *  if ([NIInterapp twitterIsInstalled]) {\n *    // Opens the Twitter app with the composer prepopulated with the following message.\n *    [NIInterapp twitterWithMessage:@\"Playing with the Nimbus Interapp feature!\"];\n *\n *  } else {\n *    // Optionally, we can open the App Store to the twitter page to download the app.\n *    [NIInterapp twitter];\n *  }\n * @endcode\n *\n *\n * <h3>Opening a Photo in Instagram</h3>\n *\n * @code\n *  NSString* filePath = ...;\n *  NSError* error = nil;\n *\n *  // Copies the image at filePath to a suitable location for being opened by Instagram.\n *  NSURL* fileUrl = [NIInterapp urlForInstagramImageAtFilePath:filePath error:&error];\n *\n *  // It's possible that copying the file might fail (if the image dimensions are\n *  // less than 612x612, for example).\n *  if (nil != fileUrl && nil == error) {\n *\n *    // Note: You must retain docController at some point here. Generally you would retain\n *    // a local copy of docController in your containing controller and then release the\n *    // docController as necessary.\n *    UIDocumentInteractionController* docController =\n *    [UIDocumentInteractionController interactionControllerWithURL:_fileUrl];\n *\n *    // Use the delegate methods to release the doc controller when the menu is dismissed.\n *    docController.delegate = self;\n *\n *    // Use any of the presentOpenIn* methods to present the menu from the correct location.\n *    [docController presentOpenInMenuFromRect: bounds\n *                                      inView: view\n *                                    animated: YES];\n *  }\n * @endcode\n */\n\n#import \"NimbusCore.h\"\n#import \"NIInterapp.h\"\n"
  },
  {
    "path": "src/interapp/unittests/NIInterappTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusInterapp.h\"\n\n@interface NIInterappTests : XCTestCase\n@end\n\n\n@implementation NIInterappTests\n\n\n- (void)testNothing {\n}\n\n@end\n"
  },
  {
    "path": "src/interapp/unittests/NimbusInterappTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/launcher/deps",
    "content": "core\npagingscrollview\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\nQuartzCore.framework"
  },
  {
    "path": "src/launcher/src/NILauncherButtonView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n#import \"NILauncherView.h\"\n#import \"NILauncherViewModel.h\"\n\n/**\n * A launcher button view that displays an image and and a label beneath it.\n *\n * This view shows the icon anchored to the top middle of the view and the label anchored to the\n * bottom middle. By default the label is a single line label with NSLineBreakByTruncatingTail.\n *\n * @image html NILauncherButtonExample1.png \"Example of an NILauncherButton\"\n *\n * @ingroup NimbusLauncher\n */\n@interface NILauncherButtonView : NIRecyclableView <NILauncherButtonView, NILauncherViewObjectView>\n\n@property (nonatomic, strong) UIButton* button;\n@property (nonatomic, copy) UILabel* label;\n\n@property (nonatomic, assign) UIEdgeInsets contentInset;\n\n@end\n\n/** @name Accessing Subviews */\n\n/**\n * The button view that should be used to display the launcher icon.\n *\n * @fn NILauncherButtonView::button\n */\n\n/**\n * The label view that should show the title of the launcher item.\n *\n * @fn NILauncherButtonView::label\n */\n\n/** @name Configuring Display Attributes */\n\n/**\n * The distance that the button and label are inset from the enclosing view.\n *\n * The unit of size is points. The default value is 5 points on all sides.\n *\n * @fn NILauncherButtonView::contentInset\n */\n"
  },
  {
    "path": "src/launcher/src/NILauncherButtonView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <QuartzCore/QuartzCore.h>\n#import \"NILauncherButtonView.h\"\n\n#import \"NILauncherViewObject.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n// The contentInset around the entire button on the top, left, bottom, and right sides.\nstatic const CGFloat kDefaultContentInset = 0;\n\n@implementation NILauncherButtonView\n\n\n\n- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithReuseIdentifier:reuseIdentifier])) {\n    _contentInset = UIEdgeInsetsMake(kDefaultContentInset, kDefaultContentInset, kDefaultContentInset, kDefaultContentInset);\n\n    _button = [UIButton buttonWithType:UIButtonTypeCustom];\n\n    _button.imageView.contentMode = UIViewContentModeCenter;\n\n    _label = [[UILabel alloc] init];\n    _label.backgroundColor = [UIColor clearColor];\n    _label.numberOfLines = 1;\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n    _label.textAlignment = UITextAlignmentCenter;\n    _label.lineBreakMode = NSLineBreakByTruncatingTail;\n#else\n    _label.textAlignment = NSTextAlignmentCenter;\n    _label.lineBreakMode = NSLineBreakByTruncatingTail;\n#endif\n    _label.font = [UIFont boldSystemFontOfSize:12];\n    _label.textColor = [UIColor whiteColor];\n\n    self.layer.rasterizationScale = NIScreenScale();\n    [self.layer setShouldRasterize:YES];\n\n    [self addSubview:_button];\n    [self addSubview:_label];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  CGRect contentBounds = UIEdgeInsetsInsetRect(self.bounds, self.contentInset);\n\n  self.label.frame = CGRectMake(CGRectGetMinX(contentBounds), CGRectGetMaxY(contentBounds) - self.label.font.lineHeight,\n                                CGRectGetWidth(contentBounds), self.label.font.lineHeight);\n  self.button.frame = NIRectContract(contentBounds, 0, self.label.bounds.size.height);\n}\n\n#pragma mark - NIRecyclableView\n\n\n- (void)prepareForReuse {\n  self.label.text = nil;\n  [self.button setImage:nil forState:UIControlStateNormal];\n}\n\n#pragma mark - NILauncherModelObjectView\n\n\n- (void)shouldUpdateViewWithObject:(NILauncherViewObject *)object {\n  self.label.text = object.title;\n  [self.button setImage:object.image forState:UIControlStateNormal];\n\n  [self setNeedsLayout];\n}\n\n@end\n"
  },
  {
    "path": "src/launcher/src/NILauncherPageView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n#import \"NimbusPagingScrollView.h\"\n\n/**\n * A single page in a launcher view.\n *\n * This is a recyclable page view that can be used with NIPagingScrollView.\n *\n * Each launcher page contains a set of views. The page lays out each of the views in a grid based\n * on the given display attributes.\n *\n * Views will be laid out from left to right and then from top to bottom.\n *\n * @ingroup NimbusLauncher\n */\n@interface NILauncherPageView : NIPagingScrollViewPage\n\n@property (nonatomic, strong) NIViewRecycler* viewRecycler;\n\n- (void)addRecyclableView:(UIView<NIRecyclableView> *)view;\n@property (nonatomic, readonly, strong) NSArray* recyclableViews;\n\n@property (nonatomic, assign) UIEdgeInsets contentInset;\n@property (nonatomic, assign) CGSize viewSize;\n@property (nonatomic, assign) CGSize viewMargins;\n\n@end\n\n/** @name Recyclable Views */\n\n/**\n * A shared view recycler for this page's recyclable views.\n *\n * When this page view is preparing for reuse it will add each of its button views to the recycler.\n * This recycler should be the same recycler used by all pages in the launcher view.\n *\n * @fn NILauncherPageView::viewRecycler\n */\n\n/**\n * Add a recyclable view to this page.\n *\n * @param view A recyclable view.\n * @fn NILauncherPageView::addRecyclableView:\n */\n\n/**\n * All of the recyclable views that have been added to this page.\n *\n * @returns An array of recyclable views in the same order in which they were added.\n * @fn NILauncherPageView::recyclableViews\n */\n\n/** @name Configuring Display Attributes */\n\n/**\n * The distance that the recyclable views are inset from the enclosing view.\n *\n * Use this property to add to the area around the content. The unit of size is points.\n * The default value is UIEdgeInsetsZero.\n *\n * @fn NILauncherPageView::contentInset\n */\n\n/**\n * The size of each recyclable view.\n *\n * The unit of size is points. The default value is CGSizeZero.\n *\n * @fn NILauncherPageView::viewSize\n */\n\n/**\n * The recommended horizontal and vertical distance between each recyclable view.\n *\n * This property is only a recommended value because the page view does its best to distribute the\n * views in a way that visually balances them.\n *\n * Width is the horizontal distance between each view. Height is the vertical distance between each\n * view. The unit of size is points. The default value is CGSizeZero.\n *\n * @fn NILauncherPageView::viewMargins\n */\n"
  },
  {
    "path": "src/launcher/src/NILauncherPageView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NILauncherPageView.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NILauncherPageView()\n@property (nonatomic, strong) NSMutableArray* mutableRecyclableViews;\n@end\n\n@implementation NILauncherPageView\n\n\n\n- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithReuseIdentifier:reuseIdentifier])) {\n    _mutableRecyclableViews = [NSMutableArray array];\n\n    // The view frames are calculated manually in layoutSubviews.\n    self.autoresizesSubviews = NO;\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  const CGFloat leftEdge = self.contentInset.left;\n  const CGFloat topEdge = self.contentInset.top;\n  const CGFloat rightEdge = self.bounds.size.width - self.contentInset.right;\n  const CGSize viewSize = self.viewSize;\n  const CGSize viewMargins = self.viewMargins;\n\n  CGFloat contentWidth = (self.bounds.size.width - self.contentInset.left - self.contentInset.right);\n  NSInteger numberOfColumns = floorf((contentWidth + viewMargins.width) / (viewSize.width + viewMargins.width));\n  CGFloat viewWidth = numberOfColumns * viewSize.width;\n  CGFloat distributedHorizontalMargin = floorf((contentWidth - viewWidth) / (CGFloat)(numberOfColumns + 1));\n  \n  const CGFloat horizontalDelta = viewSize.width + distributedHorizontalMargin;\n  const CGFloat verticalDelta = viewSize.height + viewMargins.height;\n\n  CGFloat x = leftEdge + distributedHorizontalMargin;\n  CGFloat y = topEdge;\n\n  for (UIView* view in self.mutableRecyclableViews) {\n    view.frame = CGRectMake(x, y, viewSize.width, viewSize.height);\n    x += horizontalDelta;\n    if (x + viewSize.width > rightEdge) {\n      x = leftEdge + distributedHorizontalMargin;\n      y += verticalDelta;\n    }\n  }\n}\n\n#pragma mark - NIRecyclableView\n\n\n- (void)prepareForReuse {\n  // You forgot to provide a view recycler.\n  NIDASSERT(nil != self.viewRecycler);\n\n  for (UIView<NIRecyclableView>* view in self.mutableRecyclableViews) {\n    [view removeFromSuperview];\n    [self.viewRecycler recycleView:view];\n  }\n  [self.mutableRecyclableViews removeAllObjects];\n}\n\n#pragma mark - Public\n\n\n- (void)addRecyclableView:(UIView<NIRecyclableView> *)view {\n  [self addSubview:view];\n  [self.mutableRecyclableViews addObject:view];\n\n  [self setNeedsLayout];\n}\n\n- (NSArray *)recyclableViews {\n  return [self.mutableRecyclableViews copy];\n}\n\n- (void)setContentInset:(UIEdgeInsets)contentInset {\n  _contentInset = contentInset;\n\n  [self setNeedsLayout];\n}\n\n- (void)setviewSize:(CGSize)viewSize {\n  _viewSize = viewSize;\n\n  [self setNeedsLayout];\n}\n\n- (void)setviewMargins:(CGSize)viewMargins {\n  _viewMargins = viewMargins;\n\n  [self setNeedsLayout];\n}\n\n@end\n"
  },
  {
    "path": "src/launcher/src/NILauncherView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NimbusCore.h\"\n\n@protocol NILauncherDelegate;\n@protocol NILauncherDataSource;\n@protocol NILauncherButtonView;\n\n/**\n * Calculate the given field dynamically given the view and button dimensions.\n */\nextern const NSInteger NILauncherViewGridBasedOnButtonSize;\n\n/**\n * A launcher view that simulates iOS' home screen launcher functionality.\n *\n * @ingroup NimbusLauncher\n */\n@interface NILauncherView : UIView\n\n@property (nonatomic, assign) NSInteger maxNumberOfButtonsPerPage; // Default: NSIntegerMax\n@property (nonatomic, assign) UIEdgeInsets contentInsetForPages; // Default: 10px on all sides\n@property (nonatomic, assign) CGSize buttonSize; // Default: 80x80\n@property (nonatomic, assign) NSInteger numberOfRows; // Default: NILauncherViewGridBasedOnButtonSize\n@property (nonatomic, assign) NSInteger numberOfColumns; // Default: NILauncherViewGridBasedOnButtonSize\n\n- (void)reloadData;\n@property (nonatomic, weak) id<NILauncherDelegate> delegate;\n@property (nonatomic, weak) id<NILauncherDataSource> dataSource;\n\n- (UIView<NILauncherButtonView> *)dequeueReusableViewWithIdentifier:(NSString *)identifier;\n\n- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;\n\n@end\n\n/**\n * The launcher data source used to populate the view.\n *\n * @ingroup NimbusLauncher\n */\n@protocol NILauncherDataSource <NSObject>\n@required\n\n/** @name Configuring a Launcher View */\n\n/**\n * Tells the receiver to return the number of rows in a given section of a table view (required).\n *\n * @param launcherView The launcher-view object requesting this information.\n * @param page The index locating a page in @c launcherView.\n * @returns The number of buttons in @c page.\n */\n- (NSInteger)launcherView:(NILauncherView *)launcherView numberOfButtonsInPage:(NSInteger)page;\n\n/**\n * Tells the receiver to return a button view for inserting into a particular location of a given\n * page in the launcher view (required).\n *\n * @param launcherView The launcher-view object requesting this information.\n * @param page The index locating a page in @c launcherView.\n * @param index The index locating a button in a page.\n * @returns A UIView that conforms to NILauncherButtonView that the launcher will display on\n                the given page. An assertion is raised if you return nil.\n */\n- (UIView<NILauncherButtonView> *)launcherView:(NILauncherView *)launcherView buttonViewForPage:(NSInteger)page atIndex:(NSInteger)index;\n\n@optional\n\n/**\n * Asks the receiver to return the number of pages in the launcher view.\n *\n * It is assumed that the launcher view has one page if this method is not implemented.\n *\n * @param launcherView The launcher-view object requesting this information.\n * @returns The number of pages in @c launcherView. The default value is 1.\n * @sa NILauncherDataSource::launcherView:numberOfButtonsInPage:\n */\n- (NSInteger)numberOfPagesInLauncherView:(NILauncherView *)launcherView;\n\n/**\n * Asks the receiver to return the number of rows of buttons each page can display in the\n * launcher view.\n *\n * This method will be called each time the frame of the launcher view changes. Notably, this will\n * be called when the launcher view has been rotated as a result of a device rotation.\n *\n * @param launcherView The launcher-view object requesting this information.\n * @returns The number of rows of buttons each page can display.\n * @sa NILauncherDataSource::numberOfColumnsPerPageInLauncherView:\n */\n- (NSInteger)numberOfRowsPerPageInLauncherView:(NILauncherView *)launcherView;\n\n/**\n * Asks the receiver to return the number of columns of buttons each page can display in the\n * launcher view.\n *\n * This method will be called each time the frame of the launcher view changes. Notably, this will\n * be called when the launcher view has been rotated as a result of a device rotation.\n *\n * @param launcherView The launcher-view object requesting this information.\n * @returns The number of columns of buttons each page can display.\n * @sa NILauncherDataSource::numberOfRowsPerPageInLauncherView:\n */\n- (NSInteger)numberOfColumnsPerPageInLauncherView:(NILauncherView *)launcherView;\n\n@end\n\n\n/**\n * The launcher delegate used to inform of state changes and user interactions.\n *\n * @ingroup NimbusLauncher\n */\n@protocol NILauncherDelegate <NSObject>\n@optional\n\n/** @name Managing Selections */\n\n/**\n * Informs the receiver that the specified item on the specified page has been selected.\n *\n * @param launcherView A launcher-view object informing the delegate about the new item\n *                          selection.\n * @param page A page index locating the selected item in @c launcher.\n * @param index An index locating the selected item in the given page.\n */\n- (void)launcherView:(NILauncherView *)launcherView didSelectItemOnPage:(NSInteger)page atIndex:(NSInteger)index;\n\n@end\n\n/**\n * The launcher delegate used to inform of state changes and user interactions.\n *\n * @ingroup NimbusLauncher\n */\n@protocol NILauncherButtonView <NIRecyclableView>\n@required\n\n/**\n * Requires the view to contain a button subview.\n */\n@property (nonatomic, strong) UIButton* button;\n\n@end\n\n/** @name Configuring a Launcher View */\n\n/**\n * The maximum number of buttons allowed on a given page.\n *\n * By default this value is NSIntegerMax.\n *\n * @fn NILauncherView::maxNumberOfButtonsPerPage\n */\n\n/**\n * The distance that each page view insets its contents.\n *\n * Use this property to add to the area around the content of each page. The unit of size is points.\n * The default value is 10 points on all sides.\n *\n * @fn NILauncherView::contentInsetForPages\n */\n\n/**\n * The size of each launcher button.\n *\n * @fn NILauncherView::buttonSize\n */\n\n/**\n * The number of rows to display on each page.\n *\n * @fn NILauncherView::numberOfRows\n */\n\n/**\n * The number of columns to display on each page.\n *\n * @fn NILauncherView::numberOfColumns\n */\n\n/**\n * Returns a reusable launcher button view object located by its identifier.\n *\n * @param identifier A string identifying the launcher button view object to be reused. By\n *                        default, a reusable view's identifier is its class name, but you can\n *                        change it to any arbitrary value.\n * @returns A UIView object with the associated identifier that conforms to the\n *               NILauncherButtonView protocol, or nil if no such object exists in the reusable-cell\n *               queue.\n * @fn NILauncherView::dequeueReusableViewWithIdentifier:\n */\n\n/** @name Managing the Delegate and the Data Source */\n\n/**\n * The object that acts as the delegate of the receiving launcher view.\n *\n * The delegate must adopt the NILauncherDelegate protocol. The delegate is not retained.\n *\n * @fn NILauncherView::delegate\n */\n\n/**\n * The object that acts as the data source of the receiving table view.\n *\n * The data source must adopt the NILauncherDataSource protocol. The data source is not retained.\n *\n * @fn NILauncherView::dataSource\n */\n\n/** @name Reloading the Table View */\n\n/**\n * Reloads the pages of the receiver.\n *\n * Call this method to reload all the data that is used to construct the launcher, including pages\n * and buttons. For efficiency, the launcher redisplays only those pages that are visible or nearly\n * visible.\n *\n * @fn NILauncherView::reloadData\n */\n\n/** @name Rotating the Launcher View */\n\n/**\n * Stores the current state of the launcher view in preparation for rotation.\n *\n * This must be called in conjunction with willAnimateRotationToInterfaceOrientation:duration:\n * in the methods by the same name from the view controller containing this view.\n *\n * @fn NILauncherView::willRotateToInterfaceOrientation:duration:\n */\n\n/**\n * Updates the frame of the launcher view while maintaining the current visible page's state.\n *\n * @fn NILauncherView::willAnimateRotationToInterfaceOrientation:duration:\n */\n"
  },
  {
    "path": "src/launcher/src/NILauncherView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 10, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NILauncherView.h\"\n\n#import \"NILauncherPageView.h\"\n#import \"NimbusPagingScrollView.h\"\n#import \"NIPagingScrollView+Subclassing.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic NSString* const kPageReuseIdentifier = @\"page\";\nconst NSInteger NILauncherViewGridBasedOnButtonSize = -1;\n\nstatic const CGFloat kDefaultButtonDimensions = 80;\nstatic const CGFloat kDefaultPadding = 10;\n\n\n@interface NILauncherView() <NIPagingScrollViewDataSource, NIPagingScrollViewDelegate>\n@property (nonatomic, strong) NIPagingScrollView* pagingScrollView;\n@property (nonatomic, strong) UIPageControl* pager;\n@property (nonatomic, assign) NSInteger numberOfPages;\n@property (nonatomic, strong) NIViewRecycler* viewRecycler;\n- (void)updateLayoutForPage:(NILauncherPageView *)page;\n@end\n\n\n@implementation NILauncherView\n\n\n\n- (void)_configureDefaults {\n  // We handle autoresizing ourselves.\n  [self setAutoresizesSubviews:NO];\n\n  _viewRecycler = [[NIViewRecycler alloc] init];\n\n  _buttonSize = CGSizeMake(kDefaultButtonDimensions, kDefaultButtonDimensions);\n  _numberOfColumns = NILauncherViewGridBasedOnButtonSize;\n  _numberOfRows = NILauncherViewGridBasedOnButtonSize;\n\n  _maxNumberOfButtonsPerPage = NSIntegerMax;\n  _contentInsetForPages = UIEdgeInsetsMake(kDefaultPadding, kDefaultPadding, kDefaultPadding, kDefaultPadding);\n\n  // The paging scroll view.\n  _pagingScrollView = [[NIPagingScrollView alloc] initWithFrame:self.bounds];\n  _pagingScrollView.dataSource = self;\n  _pagingScrollView.delegate = self;\n\n  [self addSubview:_pagingScrollView];\n\n  // The pager displayed below the paging scroll view.\n  _pager = [[UIPageControl alloc] init];\n  _pager.hidesForSinglePage = YES;\n\n  // So, this is weird. Apparently if you don't set a background color on the pager control\n  // then taps won't be handled anywhere but within the dot area. If you do set a background\n  // color, however, then taps outside of the dot area DO change the selected page.\n  //                                  \\(o.o)/\n  _pager.backgroundColor = [UIColor blackColor];\n\n  // Similarly for the scroll view anywhere there isn't a subview.\n  // We update these background colors when the launcher view's own background color is set.\n  _pagingScrollView.backgroundColor = [UIColor blackColor];\n\n  // Don't update the pager when the user taps until we've animated to the new page.\n  // This allows us to reset the page index forcefully if necessary without flickering the\n  // pager's current selection.\n  _pager.defersCurrentPageDisplay = YES;\n\n  // When the user taps the pager control it fires a UIControlEventValueChanged notification.\n  [_pager addTarget:self action:@selector(pagerDidChangePage:) forControlEvents:UIControlEventValueChanged];\n\n  [self addSubview:_pager];\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    [self _configureDefaults];\n  }\n  return self;\n}\n\n- (id)initWithCoder:(NSCoder *)aDecoder {\n  if ((self = [super initWithCoder:aDecoder])) {\n    [self _configureDefaults];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  [_pager sizeToFit];\n  _pagingScrollView.frame = NIRectContract(self.bounds, 0, _pager.frame.size.height);\n  _pager.frame = NIRectShift(self.bounds, 0, _pagingScrollView.frame.size.height);\n\n  for (NILauncherPageView* pageView in self.pagingScrollView.visiblePages) {\n    [self updateLayoutForPage:pageView];\n  }\n}\n\n- (void)setBackgroundColor:(UIColor *)backgroundColor {\n  [super setBackgroundColor:backgroundColor];\n\n  self.pagingScrollView.backgroundColor = backgroundColor;\n  self.pager.backgroundColor = backgroundColor;\n}\n\n- (void)calculateLayoutForFrame:(CGRect)frame\n               buttonDimensions:(CGSize *)pButtonDimensions\n                   numberOfRows:(NSInteger *)pNumberOfRows\n                numberOfColumns:(NSInteger *)pNumberOfColumns\n                  buttonMargins:(CGSize *)pButtonMargins {\n  NIDASSERT(nil != pButtonDimensions);\n  NIDASSERT(nil != pNumberOfRows);\n  NIDASSERT(nil != pNumberOfColumns);\n  NIDASSERT(nil != pButtonMargins);\n  if (nil == pButtonDimensions\n      || nil == pNumberOfRows\n      || nil == pNumberOfColumns\n      || nil == pButtonMargins) {\n    return;\n  }\n  CGFloat pageWidth = frame.size.width - self.contentInsetForPages.left - self.contentInsetForPages.right;\n  CGFloat pageHeight = frame.size.height - self.contentInsetForPages.top - self.contentInsetForPages.bottom;\n\n  CGSize buttonDimensions = self.buttonSize;\n  NSInteger numberOfColumns = self.numberOfColumns;\n  NSInteger numberOfRows = self.numberOfRows;\n\n  // Override point\n  if ([self.dataSource respondsToSelector:@selector(numberOfRowsPerPageInLauncherView:)]) {\n    numberOfRows = [self.dataSource numberOfRowsPerPageInLauncherView:self];\n  }\n  if ([self.dataSource respondsToSelector:@selector(numberOfColumnsPerPageInLauncherView:)]) {\n    numberOfColumns = [self.dataSource numberOfColumnsPerPageInLauncherView:self];\n  }\n\n  if (NILauncherViewGridBasedOnButtonSize == numberOfColumns) {\n    numberOfColumns = floorf(pageWidth / buttonDimensions.width);\n  }\n  if (NILauncherViewGridBasedOnButtonSize == numberOfRows) {\n    numberOfRows = floorf(pageHeight / buttonDimensions.height);\n  }\n  NIDASSERT(numberOfRows > 0);\n  NIDASSERT(numberOfColumns > 0);\n  numberOfRows = MAX(1, numberOfRows);\n  numberOfColumns = MAX(1, numberOfColumns);\n\n  CGFloat totalButtonWidth = numberOfColumns * buttonDimensions.width;\n  CGFloat buttonHorizontalSpacing = 0;\n  if (numberOfColumns > 1) {\n    buttonHorizontalSpacing = floorf((pageWidth - totalButtonWidth) / (numberOfColumns - 1));\n  }\n  CGFloat totalButtonHeight = numberOfRows * buttonDimensions.height;\n  CGFloat buttonVerticalSpacing = 0;\n  if (numberOfRows > 1) {\n    buttonVerticalSpacing = floorf((pageHeight - totalButtonHeight) / (numberOfRows - 1));\n  }\n\n  *pButtonDimensions = buttonDimensions;\n  *pNumberOfRows = numberOfRows;\n  *pNumberOfColumns = numberOfColumns;\n  pButtonMargins->width = buttonHorizontalSpacing;\n  pButtonMargins->height = buttonVerticalSpacing;\n}\n\n- (void)updateLayoutForPage:(NILauncherPageView *)page {\n  CGSize buttonDimensions = CGSizeZero;\n  NSInteger numberOfRows = 0;\n  NSInteger numberOfColumns = 0;\n  CGSize buttonMargins = CGSizeZero;\n  [self calculateLayoutForFrame:self.pagingScrollView.frame\n               buttonDimensions:&buttonDimensions\n                   numberOfRows:&numberOfRows\n                numberOfColumns:&numberOfColumns\n                  buttonMargins:&buttonMargins];\n  \n  page.contentInset = self.contentInsetForPages;\n  page.viewSize = buttonDimensions;\n  page.viewMargins = buttonMargins;\n}\n\n#pragma mark - UIPageControl Change Notifications\n\n\n- (void)pagerDidChangePage:(UIPageControl*)pager {\n  if ([self.pagingScrollView moveToPageAtIndex:pager.currentPage animated:YES]) {\n    // Once we've handled the page change notification, notify the pager that it's ok to update\n    // the page display.\n    [self.pager updateCurrentPageDisplay];\n  }\n}\n\n#pragma mark - Actions\n\n\n/**\n * Find a button in the pages and retrieve its page and index.\n *\n * @param[in] searchButton  The button you are looking for.\n * @param[out] pPage        The resulting page, if found.\n * @param[out] pIndex       The resulting index, if found.\n * @returns YES if the button was found. NO otherwise.\n */\n- (BOOL)pageAndIndexOfButton:(UIButton *)searchButton page:(NSInteger *)pPage index:(NSInteger *)pIndex {\n  NIDASSERT(nil != pPage);\n  NIDASSERT(nil != pIndex);\n  if (nil == pPage\n      || nil == pIndex) {\n    return NO;\n  }\n\n  for (NILauncherPageView* pageView in self.pagingScrollView.visiblePages) {\n    for (NSInteger buttonIndex = 0; buttonIndex < pageView.recyclableViews.count; ++buttonIndex) {\n      UIView<NILauncherButtonView>* buttonView = [pageView.recyclableViews objectAtIndex:buttonIndex];\n      if (buttonView.button == searchButton) {\n        *pPage = pageView.pageIndex;\n        *pIndex = buttonIndex;\n        return YES;\n      }\n    }\n  }\n\n  return NO;\n}\n\n- (void)didTapButton:(UIButton *)tappedButton {\n  NSInteger page = -1;\n  NSInteger buttonIndex = 0;\n  if ([self pageAndIndexOfButton:tappedButton\n                            page:&page\n                           index:&buttonIndex]) {\n\n    if ([self.delegate respondsToSelector:@selector(launcherView:didSelectItemOnPage:atIndex:)]) {\n      [self.delegate launcherView:self didSelectItemOnPage:page atIndex:buttonIndex];\n    }\n\n  } else {\n    // How exactly did we tap a button that wasn't a part of the launcher view?\n    NIDASSERT(NO);\n  }\n}\n\n#pragma mark - NIPagingScrollViewDataSource\n\n\n- (NSInteger)numberOfPagesInPagingScrollView:(NIPagingScrollView *)pagingScrollView {\n  return self.numberOfPages;\n}\n\n- (UIView<NIPagingScrollViewPage> *)pagingScrollView:(NIPagingScrollView *)pagingScrollView pageViewForIndex:(NSInteger)pageIndex {\n  NILauncherPageView* page = (NILauncherPageView *)[self.pagingScrollView dequeueReusablePageWithIdentifier:kPageReuseIdentifier];\n  if (nil == page) {\n    page = [[NILauncherPageView alloc] initWithReuseIdentifier:kPageReuseIdentifier];\n    page.viewRecycler = self.viewRecycler;\n  }\n\n  [self updateLayoutForPage:page];\n\n  NSInteger numberOfButtons = [self.dataSource launcherView:self numberOfButtonsInPage:pageIndex];\n  numberOfButtons = MIN(numberOfButtons, self.maxNumberOfButtonsPerPage);\n\n  for (NSInteger buttonIndex = 0 ; buttonIndex < numberOfButtons; ++buttonIndex) {\n    UIView<NILauncherButtonView>* buttonView = [self.dataSource launcherView:self buttonViewForPage:pageIndex atIndex:buttonIndex];\n    NSAssert(nil != buttonView, @\"A non-nil UIView must be returned.\");\n    [buttonView.button addTarget:self action:@selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside];\n    [page addRecyclableView:(UIView<NIRecyclableView> *)buttonView];\n  }\n\n  return page;\n}\n\n#pragma mark - NIPagingScrollViewDelegate\n\n\n- (void)pagingScrollViewDidChangePages:(NIPagingScrollView *)pagingScrollView {\n  self.pager.currentPage = pagingScrollView.centerPageIndex;\n}\n\n#pragma mark - Public\n\n\n- (void)reloadData {\n  if ([self.dataSource respondsToSelector:@selector(numberOfPagesInLauncherView:)]) {\n    _numberOfPages = [self.dataSource numberOfPagesInLauncherView:self];\n\n  } else {\n    _numberOfPages = 1;\n  }\n\n  self.pager.numberOfPages = _numberOfPages;\n  [self.pagingScrollView reloadData];\n  [self setNeedsLayout];\n}\n\n- (UIView<NILauncherButtonView> *)dequeueReusableViewWithIdentifier:(NSString *)identifier {\n  NIDASSERT(nil != identifier);\n  if (nil == identifier) {\n    return nil;\n  }\n  \n  return (UIView<NILauncherButtonView> *)[self.viewRecycler dequeueReusableViewWithIdentifier:identifier];\n}\n\n- (void)setcontentInsetForPages:(UIEdgeInsets)contentInsetForPages {\n  _contentInsetForPages = contentInsetForPages;\n\n  for (NILauncherPageView* pageView in self.pagingScrollView.visiblePages) {\n    pageView.contentInset = contentInsetForPages;\n  }\n}\n\n- (void)setButtonSize:(CGSize)buttonSize {\n  _buttonSize = buttonSize;\n\n  for (NILauncherPageView* pageView in self.pagingScrollView.visiblePages) {\n    pageView.viewSize = buttonSize;\n  }\n}\n\n- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  [self.pagingScrollView willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n}\n\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  [self.pagingScrollView willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n}\n\n@end\n"
  },
  {
    "path": "src/launcher/src/NILauncherViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NILauncherView.h\"\n\n/**\n * The NILauncherViewController class creates a controller object that manages a launcher view.\n * It implements the following behavior:\n *\n * - It creates an unconfigured NILauncherView object with the correct dimensions and autoresize\n *   mask. You can access this view through the launcherView property.\n * - NILauncherViewController sets the data source and the delegate of the launcher view to self.\n * - When the launcher view is about to appear the first time it’s loaded, the launcher-view\n *   controller reloads the launcher view’s data.\n *\n * @image html NILauncherViewControllerExample1.png \"Example of an NILauncherViewController.\"\n *\n * @ingroup NimbusLauncher\n */\n@interface NILauncherViewController : UIViewController <NILauncherDelegate, NILauncherDataSource>\n\n@property (nonatomic, strong) NILauncherView* launcherView;\n\n@end\n\n/** @name Accessing the Launcher View */\n\n/**\n * Returns the launcher view managed by the controller object.\n *\n * @fn NILauncherViewController::launcherView\n */\n"
  },
  {
    "path": "src/launcher/src/NILauncherViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NILauncherViewController.h\"\n#import \"NILauncherView.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NILauncherViewController()\n@property (nonatomic, assign) BOOL shouldReloadData;\n@end\n\n\n@implementation NILauncherViewController\n\n- (void)loadView {\n  [super loadView];\n\n  self.launcherView = [[NILauncherView alloc] initWithFrame:self.view.bounds];\n  self.launcherView.autoresizingMask =\n      (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  self.launcherView.dataSource = self;\n  self.launcherView.delegate = self;\n\n  self.view = self.launcherView;\n\n  self.shouldReloadData = YES;\n}\n\n- (void)viewWillAppear:(BOOL)animated {\n  [super viewWillAppear:animated];\n\n  if (self.view && self.shouldReloadData) {\n    [self.launcherView reloadData];\n    self.shouldReloadData = NO;\n  }\n}\n\n- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n\n  [self.launcherView willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n}\n\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {\n  [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n\n  [self.launcherView willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n}\n\n#pragma mark - NILauncherDataSource\n\n\n- (NSInteger)launcherView:(NILauncherView *)launcherView numberOfButtonsInPage:(NSInteger)page {\n  return 0;\n}\n\n- (UIView<NILauncherButtonView> *)launcherView:(NILauncherView *)launcherView buttonViewForPage:(NSInteger)page atIndex:(NSInteger)buttonIndex {\n  return nil;\n}\n\n@end\n"
  },
  {
    "path": "src/launcher/src/NILauncherViewModel.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NILauncherView.h\"\n\n@protocol NILauncherViewObject;\n@protocol NILauncherViewModelDelegate;\n\n/**\n * A launcher view model that complies to the NILauncherDataSource protocol.\n *\n * This model object allows you to keep all of your launcher view data together in one object.\n * It also conforms to the NSCoding protocol, allowing you to read and write your model to disk\n * so that you can store the state of your launcher.\n *\n * @ingroup NimbusLauncherModel\n */\n@interface NILauncherViewModel : NSObject <NILauncherDataSource, NSCoding>\n\n// Designated initializer.\n- (id)initWithArrayOfPages:(NSArray *)pages delegate:(id<NILauncherViewModelDelegate>)delegate;\n\n- (void)appendPage:(NSArray *)page;\n- (void)appendObject:(id<NILauncherViewObject>)object toPage:(NSInteger)pageIndex;\n\n- (id<NILauncherViewObject>)objectAtIndex:(NSInteger)index pageIndex:(NSInteger)pageIndex;\n\n@property (nonatomic, weak) id<NILauncherViewModelDelegate> delegate;\n\n@end\n\n/**\n * The delegate for NILauncherViewModel.\n *\n * This delegate allows you to configure the launcher button views before they are displayed.\n *\n * @ingroup NimbusLauncherModel\n */\n@protocol NILauncherViewModelDelegate <NSObject>\n@required\n\n/**\n * Tells the delegate to configure a button view in a given page.\n *\n * @param launcherViewModel The launcher-view model requesting this configuration.\n * @param buttonView The button view that should be configured.\n * @param launcherView The launcher-view object that will displaly this button view.\n * @param pageIndex The index of the page where this button view will be displayed.\n * @param buttonIndex The index of the button in the page.\n * @param object The object that will likely be used to configure this button view.\n */\n- (void)launcherViewModel:(NILauncherViewModel *)launcherViewModel\n      configureButtonView:(UIView<NILauncherButtonView> *)buttonView\n          forLauncherView:(NILauncherView *)launcherView\n                pageIndex:(NSInteger)pageIndex\n              buttonIndex:(NSInteger)buttonIndex\n                   object:(id<NILauncherViewObject>)object;\n\n@end\n\n/**\n * The minimal amount of information required to configure a button view.\n *\n * @ingroup NimbusLauncherModel\n */\n@protocol NILauncherViewObject <NSObject>\n@required\n\n/** @name Accessing the Object Attributes */\n\n/**\n * The title that will be displayed on the launcher view button.\n */\n@property (nonatomic, copy) NSString* title;\n\n/**\n * The image that will be displayed on the launcher view button.\n */\n@property (nonatomic, strong) UIImage* image;\n\n/**\n * The class of button view that should be used to display this object.\n *\n * This class must conform to the NILauncherButtonView protocol.\n */\n- (Class)buttonViewClass;\n\n@end\n\n/**\n * A protocol that a launcher button view can implement to allow itself to be configured.\n *\n * @ingroup NimbusLauncherModel\n */\n@protocol NILauncherViewObjectView <NSObject>\n@required\n\n/** @name Updating a Launcher Button View */\n\n/**\n * Informs the receiver that a new object should be used to configure the view.\n */\n- (void)shouldUpdateViewWithObject:(id)object;\n\n@end\n\n/** @name Creating Launcher View Models */\n\n/**\n * Initializes a newly allocated launcher view model with an array of pages and a given delegate.\n *\n * This is the designated initializer.\n *\n * @param pages An array of arrays of objects that conform to the NILauncherViewObject protocol.\n * @param delegate An object that conforms to the NILauncherViewModelDelegate protocol.\n * @returns An initialized launcher view model.\n * @fn NILauncherViewModel::initWithArrayOfPages:delegate:\n */\n\n/** @name Accessing Objects */\n\n/**\n * Appends a page of launcher view objects.\n *\n * @param page An array of launcher view objects to add.\n * @fn NILauncherViewModel::appendPage:\n */\n\n/**\n * Appends a launcher view object to a given page.\n *\n * @param object The object to add to the page.\n * @param pageIndex The index of the page to add this object to.\n * @fn NILauncherViewModel::appendObject:toPage:\n */\n\n/**\n * Returns the object at the given index in the page at the given page index.\n *\n * Throws an assertion if the object index or page index are out of bounds.\n *\n * @param index The index within the page of the object to return.\n * @param pageIndex The index of the page to retrieve the object from.\n * @returns An object from a specific page.\n * @fn NILauncherViewModel::objectAtIndex:pageIndex:\n */\n\n/** @name Managing the Delegate */\n\n/**\n * The delegate for this launcher view model.\n */\n"
  },
  {
    "path": "src/launcher/src/NILauncherViewModel.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NILauncherViewModel.h\"\n\n#import \"NILauncherView.h\"\n#import \"NILauncherViewObject.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NILauncherViewModel()\n@property (nonatomic, strong) NSMutableArray* pages;\n@end\n\n@implementation NILauncherViewModel\n\n\n\n- (id)initWithArrayOfPages:(NSArray *)pages delegate:(id<NILauncherViewModelDelegate>)delegate {\n  if ((self = [super init])) {\n    // Make the entire pages array mutable.\n    NSMutableArray* mutablePages = [NSMutableArray arrayWithCapacity:pages.count];\n    for (NSArray* subArray in pages) {\n      // You must add an array of arrays.\n      NIDASSERT([subArray isKindOfClass:[NSArray class]]);\n\n      [mutablePages addObject:[subArray mutableCopy]];\n    }\n    self.pages = mutablePages;\n\n    _delegate = delegate;\n  }\n  return self;\n}\n\n- (NSMutableArray *)_pageAtIndex:(NSInteger)pageIndex {\n  NIDASSERT(self.pages.count > pageIndex && pageIndex >= 0);\n  return [self.pages objectAtIndex:pageIndex];\n}\n\n- (void)appendPage:(NSArray *)page {\n  [self.pages addObject:[page mutableCopy]];\n}\n\n- (void)appendObject:(id<NILauncherViewObject>)object toPage:(NSInteger)pageIndex {\n  NSAssert(self.pages.count > pageIndex && pageIndex >= 0, @\"Page index is out of bounds.\");\n\n  [[self _pageAtIndex:pageIndex] addObject:object];\n}\n\n- (id<NILauncherViewObject>)objectAtIndex:(NSInteger)index pageIndex:(NSInteger)pageIndex {\n  NSAssert(self.pages.count > pageIndex && pageIndex >= 0, @\"Page index is out of bounds.\");\n\n  NSArray* objects = [self _pageAtIndex:pageIndex];\n  NSAssert(objects.count > index && index >= 0, @\"Index is out of bounds.\");\n\n  return [objects objectAtIndex:index];\n}\n\n#pragma mark NSCoding\n\n\n- (void)encodeWithCoder:(NSCoder *)coder {\n  NSUInteger numberOfPages = self.pages.count;\n  [coder encodeValueOfObjCType:@encode(NSUInteger) at:&numberOfPages];\n\n  for (NSArray* page in self.pages) {\n    NSUInteger numberOfObjects = page.count;\n    [coder encodeValueOfObjCType:@encode(NSUInteger) at:&numberOfObjects];\n\n    for (id object in page) {\n      // The object must conform to NSCoding in order to be encoded.\n      NIDASSERT([object conformsToProtocol:@protocol(NSCoding)]);\n      [coder encodeObject:object];\n    }\n  }\n}\n\n- (id)initWithCoder:(NSCoder *)decoder {\n  if ((self = [super init])) {\n    NSUInteger numberOfPages = 0;\n    [decoder decodeValueOfObjCType:@encode(NSUInteger) at:&numberOfPages];\n\n    NSMutableArray* pages = [NSMutableArray arrayWithCapacity:numberOfPages];\n    for (NSUInteger ixPage = 0; ixPage < numberOfPages; ++ixPage) {\n      NSUInteger numberOfObjects = 0;\n      [decoder decodeValueOfObjCType:@encode(NSUInteger) at:&numberOfObjects];\n\n      NSMutableArray* objects = [NSMutableArray arrayWithCapacity:numberOfObjects];\n      for (NSUInteger ixObject = 0; ixObject < numberOfObjects; ++ixObject) {\n        [objects addObject:[decoder decodeObject]];\n      }\n      [pages addObject:objects];\n    }\n\n    _pages = pages;\n  }\n  return self;\n}\n\n#pragma mark - NILauncherDataSource\n\n\n- (NSInteger)numberOfPagesInLauncherView:(NILauncherView *)launcherView {\n  return self.pages.count;\n}\n\n- (NSInteger)launcherView:(NILauncherView *)launcherView numberOfButtonsInPage:(NSInteger)page {\n  return [[self.pages objectAtIndex:page] count];\n}\n\n- (UIView<NILauncherButtonView> *)launcherView:(NILauncherView *)launcherView buttonViewForPage:(NSInteger)page atIndex:(NSInteger)index {\n  id<NILauncherViewObject> object = [self objectAtIndex:index pageIndex:page];\n\n  Class buttonViewClass = object.buttonViewClass;\n  // You must provide a button view class.\n  NIDASSERT(nil != buttonViewClass);\n\n  NSString* reuseIdentifier = NSStringFromClass(buttonViewClass);\n  UIView<NILauncherButtonView>* buttonView = [launcherView dequeueReusableViewWithIdentifier:reuseIdentifier];\n\n  if (nil == buttonView) {\n    buttonView = [[buttonViewClass alloc] initWithReuseIdentifier:reuseIdentifier];\n  }\n\n  // Give the button view a chance to update itself.\n  if ([buttonView respondsToSelector:@selector(shouldUpdateViewWithObject:)]) {\n    [buttonView performSelector:@selector(shouldUpdateViewWithObject:) withObject:object];\n  }\n\n  // Give the delegate a chance to customize this button.\n  [self.delegate launcherViewModel:self\n               configureButtonView:buttonView\n                   forLauncherView:launcherView\n                         pageIndex:page\n                       buttonIndex:index\n                            object:object];\n  \n  return buttonView;\n}\n\n@end\n"
  },
  {
    "path": "src/launcher/src/NILauncherViewObject.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NILauncherViewModel.h\"\n\n/**\n * An implementation of the NILauncherViewObject protocol.\n *\n * @ingroup NimbusLauncherModel\n */\n@interface NILauncherViewObject : NSObject <NILauncherViewObject, NSCoding>\n\n// Designated initializer.\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image;\n+ (id)objectWithTitle:(NSString *)title image:(UIImage *)image;\n\n@end\n\n/**\n * Initializes a newly allocated launcher view object with a given title and image.\n *\n * This is the designated initializer.\n *\n * @fn NILauncherViewObject::initWithTitle:image:\n */\n\n/**\n * Allocates and returns an autoreleased instance of a launcher view object.\n *\n * @fn NILauncherViewObject::objectWithTitle:image:\n */\n"
  },
  {
    "path": "src/launcher/src/NILauncherViewObject.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NILauncherViewObject.h\"\n#import \"NILauncherButtonView.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic NSString* const kTitleCodingKey = @\"title\";\nstatic NSString* const kImageCodingKey = @\"image\";\n\n@implementation NILauncherViewObject\n\n@synthesize title = _title;\n@synthesize image = _image;\n\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image {\n  if ((self = [super init])) {\n    _title = title;\n    _image = image;\n  }\n  return self;\n}\n\n+ (id)objectWithTitle:(NSString *)title image:(UIImage *)image {\n  return [[self alloc] initWithTitle:title image:image];\n}\n\n- (Class)buttonViewClass {\n  return [NILauncherButtonView class];\n}\n\n#pragma mark NSCoding\n\n\n- (void)encodeWithCoder:(NSCoder *)coder {\n  [coder encodeObject:self.title forKey:kTitleCodingKey];\n  [coder encodeObject:self.image forKey:kImageCodingKey];\n}\n\n- (id)initWithCoder:(NSCoder *)decoder {\n  if ((self = [super init])) {\n    _title = [decoder decodeObjectForKey:kTitleCodingKey];\n    _image = [decoder decodeObjectForKey:kImageCodingKey];\n  }\n  return self;\n}\n\n@end\n"
  },
  {
    "path": "src/launcher/src/NimbusLauncher.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * @defgroup NimbusLauncher Nimbus Launcher\n * @{\n *\n * <div id=\"github\" feature=\"launcher\"></div>\n *\n * A launcher view is best exemplified in Apple's home screen interface. It consists of a set\n * of pages that each contain a set of buttons that the user may tap to access a consistent,\n * focused aspect of the application or operating system. The user may swipe the screen to the\n * left or right or tap the pager control at the bottom of the screen to change pages.\n *\n * @image html NILauncherViewControllerExample1.png \"Example of an NILauncherViewController as seen in the BasicLauncher demo application.\"\n *\n * <h2>Minimum Requirements</h2>\n *\n * Required frameworks:\n *\n * - Foundation.framework\n * - UIKit.framework\n *\n * Minimum Operating System: <b>iOS 4.0</b>\n *\n * Source located in <code>src/launcher/src</code>\n */\n\n/**\n * @defgroup NimbusLauncherModel Nimbus Launcher Model\n *\n * The Nimbus Launcher provides a model object that can store all of the launcher data. This model\n * object works similarly to NITableViewModel.\n *\n * Presented below is an example of subclassing a NILauncherViewController and using a\n * NILauncherViewModel to supply the data source information.\n *\n@code\n@implementation CustomLauncherViewController()\n@property (nonatomic, retain) NILauncherViewModel* model;\n@end\n\n@interface CustomLauncherViewController\n\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    NSArray* contents =\n    [NSArray arrayWithObjects:\n     [NSArray arrayWithObjects:\n      [NILauncherViewObject objectWithTitle:@\"Nimbus\" image:image],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 2\" image:image],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 3\" image:image],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 5\" image:image],\n      [NILauncherViewObject objectWithTitle:@\"Nimbus 6\" image:image],\n      nil],\n     [NSArray arrayWithObjects:\n      [NILauncherViewObject objectWithTitle:@\"Page 2\" image:image],\n      nil],\n     [NSArray arrayWithObjects:\n      [NILauncherViewObject objectWithTitle:@\"Page 3\" image:image],\n      nil],\n     nil];\n\n    _model = [[NILauncherViewModel alloc] initWithArrayOfPages:contents delegate:nil];\n  }\n  return self;\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.launcherView.dataSource = self.model;\n}\n@end\n@endcode\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n// Dependencies\n#import \"NimbusCore.h\"\n#import \"NimbusPagingScrollView.h\"\n\n#import \"NILauncherButtonView.h\"\n#import \"NILauncherViewModel.h\"\n#import \"NILauncherViewObject.h\"\n#import \"NILauncherViewController.h\"\n#import \"NILauncherView.h\"\n\n/**@}*/\n"
  },
  {
    "path": "src/launcher/unittests/NILauncherViewTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusAttributedLabel.h\"\n\n@interface NILauncherViewTests : XCTestCase\n@end\n\n\n@implementation NILauncherViewTests\n\n\n- (void)testNothing {\n}\n\n@end\n"
  },
  {
    "path": "src/launcher/unittests/NimbusLauncherTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/models/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\n"
  },
  {
    "path": "src/models/src/NICellBackgrounds.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPreprocessorMacros.h\" /* for weak */\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n/**\n * The NIGroupedCellAppearance protocol provides support for each cell to adjust their appearance.\n *\n * @ingroup TableCellBackgrounds\n */\n@protocol NIGroupedCellAppearance <NSObject>\n\n@optional\n\n/**\n * Determines whether or not to draw a divider between cells. \n * \n * If the cell does not implement this method, a cell divider will be provided.\n */\n- (BOOL)drawsCellDivider;\n\n@end\n\n\n// Flags set on the cell's backgroundView's tag property.\ntypedef enum {\n  NIGroupedCellBackgroundFlagIsLast       = (1 << 0),\n  NIGroupedCellBackgroundFlagIsFirst      = (1 << 1),\n  NIGroupedCellBackgroundFlagInitialized  = (1 << 2),\n  NIGroupedCellBackgroundFlagNoDivider    = (1 << 3),\n} NIGroupedCellBackgroundFlag;\n\n/**\n * The NIGroupedCellBackground class provides support for generating grouped UITableView cell\n * backgrounds.\n *\n * @ingroup TableCellBackgrounds\n */\n@interface NIGroupedCellBackground : NSObject\n\n- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;\n\n- (UIImage *)imageForFirst:(BOOL)first last:(BOOL)last highlighted:(BOOL)highlighted; // Default: drawDivider: True\n- (UIImage *)imageForFirst:(BOOL)first last:(BOOL)last highlighted:(BOOL)highlighted drawDivider:(BOOL)drawDivider;\n\n- (id)cacheKeyForFirst:(BOOL)first last:(BOOL)last highlighted:(BOOL)highlighted drawDivider:(BOOL)drawDivider;\n- (NSInteger)backgroundTagForFirst:(BOOL)isFirst last:(BOOL)isLast drawDivider:(BOOL)drawDivider;\n\n@property (nonatomic, strong) UIColor* innerBackgroundColor; // Default: [UIColor whiteColor]\n@property (nonatomic, strong) NSMutableArray* highlightedInnerGradientColors; // Default: RGBCOLOR(53, 141, 245), RGBCOLOR(16, 93, 230)\n@property (nonatomic, assign) CGFloat shadowWidth; // Default: 4\n@property (nonatomic, assign) CGSize shadowOffset; // Default: CGSizeMake(0, 1)\n@property (nonatomic, strong) UIColor* shadowColor; // Default: RGBACOLOR(0, 0, 0, 0.3)\n@property (nonatomic, strong) UIColor* borderColor; // Default: RGBACOLOR(0, 0, 0, 0.07)\n@property (nonatomic, strong) UIColor* dividerColor; // Default: RGBCOLOR(230, 230, 230)\n@property (nonatomic, assign) CGFloat borderRadius; // Default: 5\n\n@end\n\n/**\n * Returns an image for use with the given cell configuration.\n *\n * The returned image is cached internally after the first request. Changing any of the display\n * properties will invalidate the cached images.\n *\n * @param first YES will round the top corners.\n * @param last  YES will round the bottom corners.\n * @param highlighed YES will fill the contents with the highlightedInnerGradientColors.\n * @returns A UIImage representing the given configuration.\n * @fn NIGroupedCellBackground::imageForFirst:last:highlighted:\n */\n\n/**\n * Returns an image for use with the given cell configuration.\n *\n * The returned image is cached internally after the first request. Changing any of the display\n * properties will invalidate the cached images.\n *\n *      @param first YES will round the top corners.\n *      @param last  YES will round the bottom corners.\n *      @param highlighed YES will fill the contents with the highlightedInnerGradientColors.\n *      @param drawDivider YES will draw a divider between this and the next cell if necessary.\n *      @returns A UIImage representing the given configuration.\n *      @fn NIGroupedCellBackground::imageForFirst:last:highlighted:drawDivider:\n */\n\n/**\n * Returns a cache key for the images returned by imageForFirst:last:highlighted:drawDivider:\n * Subclaseses that alter the behaviour of imageForFirst:last:highlighted:drawDivider: need to\n * override this method such that different images will have different cache keys. In particular,\n * this this will be necessary if the appearance of the image depends on anything other than the\n * arguments to the imageForFirst:last:highlighted:drawDivider: method.\n *\n *      @param first YES if the image is for the first row in a section\n *      @param last  YES if the image is for the last row in a section\n *      @param highlighted YES if the image is for a highlighted cell\n *      @param drawDivider YES if the image includes a divider\n *      @returns A cache key for an image that matches the given parameters.\n *      @fn NIGroupedCellBackground::cacheKeyForFirst:last:highlighted:drawDivider:\n */\n\n/**\n * Returns a tag for a cell's background image. This is used to prevent a cell's background\n * image from being set again when it already has the correct image. Similar to the cache key,\n * subclasses that alter the behaviour of imageForFirst:last:highlighted:drawDivider: need to\n * override this method, if the appearance of the image depends on anything other than the\n * arguments to the imageForFirst:last:highlighted:drawDivider: method.\n * Note that the highlighted state is irrelevant to the background tag.\n *\n *      @param first YES if the image is for the first row in a section\n *      @param last  YES if the image is for the last row in a section\n *      @param drawDivider YES if the image includes a divider\n *      @returns A tag for an image that matches the given parameters.\n *      @fn NIGroupedCellBackground::backgroundTagForFirst:last:drawDivider:\n*/\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/models/src/NICellBackgrounds.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICellBackgrounds.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic const CGFloat kBorderSize = 1;\nstatic const CGSize kCellImageSize = {44, 44};\n\n@interface NIGroupedCellBackground()\n@property (nonatomic, strong) NSMutableDictionary* cachedImages;\n@end\n\n\n@implementation NIGroupedCellBackground\n\n\n\n- (id)init {\n  if ((self = [super init])) {\n    _innerBackgroundColor = [UIColor whiteColor];\n    _highlightedInnerGradientColors = [NSMutableArray arrayWithObjects:\n                                       (id)RGBCOLOR(53, 141, 245).CGColor,\n                                       (id)RGBCOLOR(16, 93, 230).CGColor,\n                                       nil];\n    _shadowWidth = 4;\n    _shadowOffset = CGSizeMake(0, 1);\n    _shadowColor = RGBACOLOR(0, 0, 0, 0.3f);\n    _borderColor = RGBACOLOR(0, 0, 0, 0.07f);\n    _dividerColor = RGBCOLOR(230, 230, 230);\n    _borderRadius = 5;\n    _cachedImages = [NSMutableDictionary dictionary];\n  }\n  return self;\n}\n\n// We want to draw the borders and shadows on single retina-pixel boundaries if possible, but\n// we need to avoid doing this on non-retina devices because it'll look blurry.\n+ (CGFloat)minPixelOffset {\n  if (NIIsRetina()) {\n    return 0.5f;\n  } else {\n    return 1.f;\n  }\n}\n\n- (void)_applySinglePathToContext:(CGContextRef)c rect:(CGRect)rect {\n  CGFloat minPixelOffset = [[self class] minPixelOffset];\n  CGFloat minx = CGRectGetMinX(rect) + minPixelOffset;\n  CGFloat midx = CGRectGetMidX(rect) + minPixelOffset;\n  CGFloat maxx = CGRectGetMaxX(rect) - minPixelOffset;\n  CGFloat miny = CGRectGetMinY(rect) - minPixelOffset;\n  CGFloat midy = CGRectGetMidY(rect) - minPixelOffset;\n  CGFloat maxy = CGRectGetMaxY(rect) + minPixelOffset;\n\n  CGContextBeginPath(c);\n\n  CGContextMoveToPoint(c, minx, midy);\n  CGContextAddArcToPoint(c, minx, miny + 1, midx, miny + 1, self.borderRadius);\n  CGContextAddArcToPoint(c, maxx, miny + 1, maxx, midy, self.borderRadius);\n  CGContextAddLineToPoint(c, maxx, midy);\n  CGContextAddArcToPoint(c, maxx, maxy - 1, midx, maxy - 1, self.borderRadius);\n  CGContextAddArcToPoint(c, minx, maxy - 1, minx, midy, self.borderRadius);\n  CGContextAddLineToPoint(c, minx, midy);\n\n  CGContextClosePath(c);\n}\n\n- (void)_applyTopPathToContext:(CGContextRef)c rect:(CGRect)rect {\n  CGFloat minPixelOffset = [[self class] minPixelOffset];\n  CGFloat minx = CGRectGetMinX(rect) + minPixelOffset;\n  CGFloat midx = CGRectGetMidX(rect) + minPixelOffset;\n  CGFloat maxx = CGRectGetMaxX(rect) - minPixelOffset;\n  CGFloat miny = CGRectGetMinY(rect) - minPixelOffset;\n  CGFloat midy = CGRectGetMidY(rect) - minPixelOffset;\n  CGFloat maxy = CGRectGetMaxY(rect) + minPixelOffset;\n\n  CGContextBeginPath(c);\n\n  CGContextMoveToPoint(c, minx, maxy);\n  CGContextAddLineToPoint(c, minx, midy);\n  CGContextAddArcToPoint(c, minx, miny + 1, midx, miny + 1, self.borderRadius);\n  CGContextAddArcToPoint(c, maxx, miny + 1, maxx, midy, self.borderRadius);\n  CGContextAddLineToPoint(c, maxx, maxy);\n\n  CGContextClosePath(c);\n}\n\n- (void)_applyBottomPathToContext:(CGContextRef)c rect:(CGRect)rect {\n  CGFloat minPixelOffset = [[self class] minPixelOffset];\n  CGFloat minx = CGRectGetMinX(rect) + minPixelOffset;\n  CGFloat midx = CGRectGetMidX(rect) + minPixelOffset;\n  CGFloat maxx = CGRectGetMaxX(rect) - minPixelOffset;\n  CGFloat miny = CGRectGetMinY(rect) - minPixelOffset;\n  CGFloat midy = CGRectGetMidY(rect) - minPixelOffset;\n  CGFloat maxy = CGRectGetMaxY(rect) + minPixelOffset;\n\n  CGContextBeginPath(c);\n\n  CGContextMoveToPoint(c, maxx, miny);\n  CGContextAddLineToPoint(c, maxx, midy);\n  CGContextAddArcToPoint(c, maxx, maxy - 1, midx, maxy - 1, self.borderRadius);\n  CGContextAddArcToPoint(c, minx, maxy - 1, minx, midy, self.borderRadius);\n  CGContextAddLineToPoint(c, minx, miny);\n\n  CGContextClosePath(c);\n}\n\n- (void)_applyDividerPathToContext:(CGContextRef)c rect:(CGRect)rect {\n  CGFloat minPixelOffset = [[self class] minPixelOffset];\n  CGFloat minx = CGRectGetMinX(rect) + minPixelOffset;\n  CGFloat maxx = CGRectGetMaxX(rect) - minPixelOffset;\n  CGFloat maxy = CGRectGetMaxY(rect) + minPixelOffset;\n\n  CGContextBeginPath(c);\n\n  CGContextMoveToPoint(c, minx, maxy);\n  CGContextAddLineToPoint(c, maxx, maxy);\n\n  CGContextClosePath(c);\n}\n\n- (void)_applyLeftPathToContext:(CGContextRef)c rect:(CGRect)rect {\n  CGFloat minPixelOffset = [[self class] minPixelOffset];\n  CGFloat minx = CGRectGetMinX(rect) + minPixelOffset;\n  CGFloat miny = CGRectGetMinY(rect) - minPixelOffset;\n  CGFloat maxy = CGRectGetMaxY(rect) + minPixelOffset;\n\n  CGContextBeginPath(c);\n\n  CGContextMoveToPoint(c, minx, miny);\n  CGContextAddLineToPoint(c, minx, maxy);\n\n  CGContextClosePath(c);\n}\n\n- (void)_applyRightPathToContext:(CGContextRef)c rect:(CGRect)rect {\n  CGFloat minPixelOffset = [[self class] minPixelOffset];\n  CGFloat maxx = CGRectGetMaxX(rect) - minPixelOffset;\n  CGFloat miny = CGRectGetMinY(rect) - minPixelOffset;\n  CGFloat maxy = CGRectGetMaxY(rect) + minPixelOffset;\n\n  CGContextBeginPath(c);\n\n  CGContextMoveToPoint(c, maxx, miny);\n  CGContextAddLineToPoint(c, maxx, maxy);\n\n  CGContextClosePath(c);\n}\n\n- (void)_applyPathToContext:(CGContextRef)c rect:(CGRect)rect isFirst:(BOOL)isFirst isLast:(BOOL)isLast {\n  CGFloat minPixelOffset = [[self class] minPixelOffset];\n  CGFloat minx = CGRectGetMinX(rect) + minPixelOffset;\n  CGFloat midx = CGRectGetMidX(rect) + minPixelOffset;\n  CGFloat maxx = CGRectGetMaxX(rect) - minPixelOffset;\n  CGFloat miny = CGRectGetMinY(rect) - minPixelOffset;\n  CGFloat midy = CGRectGetMidY(rect) - minPixelOffset;\n  CGFloat maxy = CGRectGetMaxY(rect) + minPixelOffset;\n\n  CGContextBeginPath(c);\n\n  //\n  // x-> |\n  //\n  CGContextMoveToPoint(c, minx, midy);\n\n  if (isFirst) {\n    // arc\n    //    >/\n    //     |\n    //\n    CGContextAddArcToPoint(c, minx, miny + 1, midx, miny + 1, self.borderRadius);\n\n    //      ______   line and then arc\n    //     /      \\ <\n    //     |\n    //\n    CGContextAddArcToPoint(c, maxx, miny + 1, maxx, midy, self.borderRadius);\n\n  } else {\n    // line\n    //    >|\n    //     |\n    //\n    CGContextAddLineToPoint(c, minx, miny);\n\n    //      ______ <- line to here\n    //     |\n    //     |\n    //\n    CGContextAddLineToPoint(c, maxx, miny);\n  }\n\n  //     isSolid?\n  //        vv\n  //      ______\n  //     |      | -\n  //     |      | -\\< right edge line\n  //\n  CGContextAddLineToPoint(c, maxx, midy);\n\n  if (isLast) {\n    CGContextAddArcToPoint(c, maxx, maxy - 1, midx, maxy - 1, self.borderRadius);\n    CGContextAddArcToPoint(c, minx, maxy - 1, minx, midy, self.borderRadius);\n\n  } else {\n    //     |      |\n    //     |      |\n    //     -------- <- line to here\n    //\n    CGContextAddLineToPoint(c, maxx, maxy);\n\n    //     |      |\n    //     |      |\n    //     --------\n    //     ^ then to here\n    CGContextAddLineToPoint(c, minx, maxy);\n  }\n\n  // x-> |      |\n  //     |      |\n  //     --------\n  CGContextAddLineToPoint(c, minx, midy);\n\n  CGContextClosePath(c);\n}\n\n- (UIImage *)_imageForHighlight {\n  CGRect imageRect = CGRectMake(0, 0, 1, kCellImageSize.height);\n  UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0);\n\n  CGContextRef cx = UIGraphicsGetCurrentContext();\n\n  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();\n  CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)self.highlightedInnerGradientColors, nil);\n  CGColorSpaceRelease(colorSpace);\n  colorSpace = nil;\n\n  CGContextDrawLinearGradient(cx, gradient, CGPointZero, CGPointMake(imageRect.size.width, imageRect.size.height), 0);\n  CGGradientRelease(gradient);\n  gradient = nil;\n\n  UIImage* image = UIGraphicsGetImageFromCurrentImageContext();\n  UIGraphicsEndImageContext();\n\n  return image;\n}\n\n- (UIImage *)_imageForFirst:(BOOL)first last:(BOOL)last highlighted:(BOOL)highlighted drawDivider:(BOOL)drawDivider {\n  CGRect imageRect = CGRectMake(0, 0, kCellImageSize.width, kCellImageSize.height);\n  UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0);\n\n  CGContextRef cx = UIGraphicsGetCurrentContext();\n\n  // Create a transparent background.\n  CGContextClearRect(cx, imageRect);\n\n  if (highlighted) {\n    CGContextSetFillColorWithColor(cx, [UIColor colorWithPatternImage:self._imageForHighlight].CGColor);\n\n  } else {\n    CGContextSetFillColorWithColor(cx, self.innerBackgroundColor.CGColor);\n  }\n\n  CGRect contentFrame = CGRectInset(imageRect, self.shadowWidth, 0);\n  if (first) {\n    contentFrame = NIRectShift(contentFrame, 0, self.shadowWidth);\n  }\n  if (last) {\n    contentFrame = NIRectContract(contentFrame, 0, self.shadowWidth);\n  }\n  if (self.shadowWidth > 0 && !highlighted) {\n    // Draw the shadow\n    CGContextSaveGState(cx);\n    CGRect shadowFrame = contentFrame;\n\n    // We want the shadow to clip to the top and bottom edges of the image so that when two cells\n    // are next to each other their shadows line up perfectly.\n    if (!first) {\n      shadowFrame = NIRectShift(shadowFrame, 0, -self.borderRadius);\n    }\n    if (!last) {\n      shadowFrame = NIRectContract(shadowFrame, 0, -self.borderRadius);\n    }\n\n    [self _applyPathToContext:cx rect:shadowFrame isFirst:first isLast:last];\n\n    CGContextSetShadowWithColor(cx, self.shadowOffset, self.shadowWidth, self.shadowColor.CGColor);\n    CGContextDrawPath(cx, kCGPathFill);\n    CGContextRestoreGState(cx);\n  }\n\n  CGContextSaveGState(cx);\n  [self _applyPathToContext:cx rect:contentFrame isFirst:first isLast:last];\n  CGContextFillPath(cx);\n  CGContextRestoreGState(cx);\n\n  // We want the cell border to overlap the shadow and the content.\n  CGFloat minPixelOffset = [[self class] minPixelOffset];\n  CGRect borderFrame = CGRectInset(contentFrame, -minPixelOffset, -minPixelOffset);\n  if (!highlighted) {\n    // Draw the cell border.\n    CGContextSaveGState(cx);\n    CGContextSetLineWidth(cx, kBorderSize);\n    CGContextSetStrokeColorWithColor(cx, self.borderColor.CGColor);\n    if (first && last) {\n      [self _applySinglePathToContext:cx rect:borderFrame];\n      CGContextStrokePath(cx);\n\n    } else if (first) {\n      [self _applyTopPathToContext:cx rect:borderFrame];\n      CGContextStrokePath(cx);\n\n    } else if (last) {\n      [self _applyBottomPathToContext:cx rect:borderFrame];\n      CGContextStrokePath(cx);\n\n    } else {\n      [self _applyLeftPathToContext:cx rect:borderFrame];\n      CGContextStrokePath(cx);\n\n      [self _applyRightPathToContext:cx rect:borderFrame];\n      CGContextStrokePath(cx);\n    }\n    CGContextRestoreGState(cx);\n  }\n\n  // Draw the cell divider.\n  if (!last && drawDivider) {\n    CGContextSaveGState(cx);\n    CGContextSetLineWidth(cx, kBorderSize);\n    CGContextSetStrokeColorWithColor(cx, self.dividerColor.CGColor);\n    [self _applyDividerPathToContext:cx rect:NIRectContract(contentFrame, 0, 1)];\n    CGContextStrokePath(cx);\n    CGContextRestoreGState(cx);\n  }\n\n  UIImage* image = UIGraphicsGetImageFromCurrentImageContext();\n  UIGraphicsEndImageContext();\n\n  CGFloat capWidth = NICGFloatFloor(image.size.width / 2);\n  CGFloat capHeight = NICGFloatFloor(image.size.height / 2);\n  return [image resizableImageWithCapInsets:UIEdgeInsetsMake(capHeight, capWidth, capHeight, capWidth)];\n}\n\n- (id)cacheKeyForFirst:(BOOL)first last:(BOOL)last highlighted:(BOOL)highlighted drawDivider:(BOOL)drawDivider {\n  NSInteger flags = ((first ? 0x01 : 0)\n                     | (last ? 0x02 : 0)\n                     | (highlighted ? 0x04 : 0)\n                     | (drawDivider ? 0x08 : 0));\n  return [NSNumber numberWithInteger:flags];\n}\n\n- (void)_invalidateCache {\n  [self.cachedImages removeAllObjects];\n}\n\n#pragma mark - Public\n\n\n- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {\n  NSInteger numberOfRowsInSection = [tableView.dataSource tableView:tableView numberOfRowsInSection:indexPath.section];\n  BOOL isFirst = (0 == indexPath.row);\n  BOOL isLast = (indexPath.row == numberOfRowsInSection - 1);\n  BOOL drawDivider = YES;\n  if ([cell conformsToProtocol:@protocol(NIGroupedCellAppearance)]\n      && [cell respondsToSelector:@selector(drawsCellDivider)]) {\n    id<NIGroupedCellAppearance> groupedCell = (id<NIGroupedCellAppearance>)cell;\n    drawDivider = [groupedCell drawsCellDivider];\n  }\n  NSInteger backgroundTag = [self backgroundTagForFirst:isFirst last:isLast drawDivider:drawDivider];\n  if (cell.backgroundView.tag != backgroundTag) {\n    cell.backgroundView = [[UIImageView alloc] initWithImage:[self imageForFirst:isFirst\n                                                                            last:isLast\n                                                                     highlighted:NO\n                                                                     drawDivider:drawDivider]];\n    cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[self imageForFirst:isFirst\n                                                                                    last:isLast\n                                                                             highlighted:YES\n                                                                             drawDivider:drawDivider]];\n    cell.backgroundView.tag = backgroundTag;\n  }\n}\n\n- (NSInteger)backgroundTagForFirst:(BOOL)isFirst last:(BOOL)isLast drawDivider:(BOOL)drawDivider {\n  NSInteger tag = ((isFirst ? NIGroupedCellBackgroundFlagIsFirst : 0)\n                   | (isLast ? NIGroupedCellBackgroundFlagIsLast : 0)\n                   | NIGroupedCellBackgroundFlagInitialized\n                   | (drawDivider ? 0 : NIGroupedCellBackgroundFlagNoDivider));\n  return tag;\n}\n\n- (UIImage *)imageForFirst:(BOOL)first last:(BOOL)last highlighted:(BOOL)highlighted {\n  return [self imageForFirst:first last:last highlighted:highlighted drawDivider:YES];\n}\n\n- (UIImage *)imageForFirst:(BOOL)first last:(BOOL)last highlighted:(BOOL)highlighted drawDivider:(BOOL)drawDivider {\n  id cacheKey = [self cacheKeyForFirst:first last:last highlighted:highlighted drawDivider:drawDivider];\n  UIImage* image = [self.cachedImages objectForKey:cacheKey];\n  if (nil == image) {\n    image = [self _imageForFirst:first last:last highlighted:highlighted drawDivider:drawDivider];\n    [self.cachedImages setObject:image forKey:cacheKey];\n  }\n  return image;\n}\n\n- (void)setInnerBackgroundColor:(UIColor *)innerBackgroundColor {\n  if (_innerBackgroundColor != innerBackgroundColor) {\n    _innerBackgroundColor = innerBackgroundColor;\n    [self _invalidateCache];\n  }\n}\n\n- (void)setHighlightedInnerGradientColors:(NSMutableArray *)highlightedInnerGradientColors {\n  if (_highlightedInnerGradientColors != highlightedInnerGradientColors) {\n    _highlightedInnerGradientColors = highlightedInnerGradientColors;\n    [self _invalidateCache];\n  }\n}\n\n- (void)setShadowWidth:(CGFloat)shadowWidth {\n  if (_shadowWidth != shadowWidth) {\n    _shadowWidth = shadowWidth;\n    [self _invalidateCache];\n  }\n}\n\n- (void)setShadowColor:(UIColor *)shadowColor {\n  if (_shadowColor != shadowColor) {\n    _shadowColor = shadowColor;\n    [self _invalidateCache];\n  }\n}\n\n- (void)setBorderColor:(UIColor *)borderColor {\n  if (_borderColor != borderColor) {\n    _borderColor = borderColor;\n    [self _invalidateCache];\n  }\n}\n\n- (void)setDividerColor:(UIColor *)dividerColor {\n  if (_dividerColor != dividerColor) {\n    _dividerColor = dividerColor;\n    [self _invalidateCache];\n  }\n}\n\n@end\n"
  },
  {
    "path": "src/models/src/NICellCatalog.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICellFactory.h\"\n\ntypedef CGFloat (^NICellDrawRectBlock)(CGRect rect, id object, UITableViewCell* cell);\n\n/**\n * An object that will draw the contents of the cell using a provided block.\n *\n * @ingroup TableCellCatalog\n */\n@interface NIDrawRectBlockCellObject : NICellObject\n// Designated initializer.\n- (id)initWithBlock:(NICellDrawRectBlock)block object:(id)object;\n+ (id)objectWithBlock:(NICellDrawRectBlock)block object:(id)object;\n@property (nonatomic, copy) NICellDrawRectBlock block;\n@property (nonatomic, strong) id object;\n@end\n\n/**\n * An object for displaying a single-line title in a table view cell.\n *\n * This object maps by default to a NITextCell and displays the title with a\n * UITableViewCellStyleDefault cell. You can customize the cell class using the\n * NICellObject methods.\n *\n * @ingroup TableCellCatalog\n */\n@interface NITitleCellObject : NICellObject\n// Designated initializer.\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image;\n- (id)initWithTitle:(NSString *)title;\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image cellClass:(Class)cellClass userInfo:(id)userInfo;\n+ (id)objectWithTitle:(NSString *)title image:(UIImage *)image;\n+ (id)objectWithTitle:(NSString *)title;\n@property(nonatomic, copy) NSString *title;\n@property(nonatomic, strong) UIImage *image;\n@end\n\n/**\n * An object for displaying two lines of text in a table view cell.\n *\n * This object maps by default to a NITextCell and displays the title with a\n * UITableViewCellStyleSubtitle cell. You can customize the cell class using the\n * NICellObject methods.\n *\n * @ingroup TableCellCatalog\n */\n@interface NISubtitleCellObject : NITitleCellObject\n// Designated initializer.\n- (id)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle image:(UIImage *)image;\n- (id)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle;\n- (id)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle image:(UIImage *)image cellClass:(Class)cellClass userInfo:(id)userInfo;\n+ (id)objectWithTitle:(NSString *)title subtitle:(NSString *)subtitle image:(UIImage *)image;\n+ (id)objectWithTitle:(NSString *)title subtitle:(NSString *)subtitle;\n@property (nonatomic, copy) NSString* subtitle;\n@property (nonatomic, assign) UITableViewCellStyle cellStyle;\n@end\n\n/**\n * A general-purpose cell for displaying text.\n *\n * When given a NITitleCellObject, will set the textLabel's text with the title.\n * When given a NISubtitleCellObject, will also set the detailTextLabel's text with the subtitle.\n *\n * @ingroup TableCellCatalog\n */\n@interface NITextCell : UITableViewCell <NICell>\n@end\n\n/**\n * A cell that renders its contents using a block.\n *\n * @ingroup TableCellCatalog\n */\n@interface NIDrawRectBlockCell : UITableViewCell <NICell>\n@property (nonatomic, strong) UIView* blockView;\n@end\n\n/**\n * Initializes the NITitleCellObject with the given title, image, cellClass, and userInfo.\n *\n * This is the designated initializer. Use of this initializer allows for customization of the\n * associated cell class for this object.\n *\n * @fn NITitleCellObject::initWithTitle:image:cellClass:userInfo:\n */\n\n/**\n * Initializes the NITitleCellObject with NITextCell as the cell class and the given title text and\n * image.\n *\n * @fn NITitleCellObject::initWithTitle:image:\n */\n\n/**\n * Initializes the NITitleCellObject with NITextCell as the cell class and the given title text.\n *\n * @fn NITitleCellObject::initWithTitle:\n */\n\n/**\n * Convenience method for initWithTitle:image:.\n *\n * @fn NITitleCellObject::objectWithTitle:image:\n * @returns Autoreleased instance of NITitleCellObject.\n */\n\n/**\n * Convenience method for initWithTitle:.\n *\n * @fn NITitleCellObject::objectWithTitle:\n * @returns Autoreleased instance of NITitleCellObject.\n */\n\n/**\n * The text to be displayed in the cell.\n *\n * @fn NITitleCellObject::title\n */\n\n/**\n * Initializes the NISubtitleCellObject with the given title, subtitle, image, cellClass, and\n * userInfo.\n *\n * This is the designated initializer. Use of this initializer allows for customization of the\n * associated cell class for this object.\n *\n * @fn NISubtitleCellObject::initWithTitle:subtitle:image:cellClass:userInfo:\n */\n\n/**\n * Initializes the NICellObject with NITextCell as the cell class and the given title and subtitle\n * text.\n *\n * @fn NISubtitleCellObject::initWithTitle:subtitle:\n */\n\n/**\n * Convenience method for initWithTitle:subtitle:.\n *\n * @fn NISubtitleCellObject::objectWithTitle:subtitle:\n * @returns Autoreleased instance of NISubtitleCellObject.\n */\n\n/**\n * The text to be displayed in the subtitle portion of the cell.\n *\n * @fn NISubtitleCellObject::subtitle\n */\n\n/**\n * The type of UITableViewCell to instantiate.\n *\n * By default this is UITableViewCellStyleSubtitle.\n *\n * @fn NISubtitleCellObject::cellStyle\n */\n"
  },
  {
    "path": "src/models/src/NICellCatalog.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICellCatalog.h\"\n#import \"NICellFactory+Private.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NIDrawRectBlockCellObject\n\n\n\n- (id)initWithBlock:(NICellDrawRectBlock)block object:(id)object {\n  if ((self = [super initWithCellClass:[NIDrawRectBlockCell class]])) {\n    _block = block;\n    _object = object;\n  }\n  return self;\n}\n\n+ (id)objectWithBlock:(NICellDrawRectBlock)block object:(id)object {\n  return [[self alloc] initWithBlock:block object:object];\n}\n\n@end\n\n\n@implementation NITitleCellObject\n\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image cellClass:(Class)cellClass userInfo:(id)userInfo {\n  if ((self = [self initWithTitle:title image:image])) {\n    self.cellClass = cellClass;\n    self.userInfo = userInfo;\n  }\n  return self;\n}\n\n- (id)initWithCellClass:(Class)cellClass userInfo:(id)userInfo {\n  return [self initWithTitle:nil image:nil cellClass:cellClass userInfo:userInfo];\n}\n\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image {\n  if ((self = [super initWithCellClass:[NITextCell class] userInfo:nil])) {\n    _title = [title copy];\n    _image = image;\n  }\n  return self;\n}\n\n- (id)initWithTitle:(NSString *)title {\n  return [self initWithTitle:title image:nil];\n}\n\n- (id)init {\n  return [self initWithTitle:nil image:nil];\n}\n\n+ (id)objectWithTitle:(NSString *)title image:(UIImage *)image {\n  return [[self alloc] initWithTitle:title image:image];\n}\n\n+ (id)objectWithTitle:(NSString *)title {\n  return [[self alloc] initWithTitle:title image:nil];\n}\n\n@end\n\n\n@implementation NISubtitleCellObject\n\n- (id)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle image:(UIImage *)image cellClass:(Class)cellClass userInfo:(id)userInfo {\n  if ((self = [self initWithTitle:title subtitle:subtitle image:image])) {\n    self.cellClass = cellClass;\n    self.userInfo = userInfo;\n  }\n  return self;\n}\n\n- (id)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle image:(UIImage *)image {\n  if ((self = [super initWithTitle:title image:image])) {\n    _subtitle = [subtitle copy];\n    _cellStyle = UITableViewCellStyleSubtitle;\n  }\n  return self;\n}\n\n- (id)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle {\n  return [self initWithTitle:title subtitle:subtitle image:nil];\n}\n\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image {\n  return [self initWithTitle:title subtitle:nil image:image];\n}\n\n- (id)init {\n  return [self initWithTitle:nil subtitle:nil image:nil];\n}\n\n+ (id)objectWithTitle:(NSString *)title subtitle:(NSString *)subtitle image:(UIImage *)image {\n  return [[self alloc] initWithTitle:title subtitle:subtitle image:image];\n}\n\n+ (id)objectWithTitle:(NSString *)title subtitle:(NSString *)subtitle {\n  return [[self alloc] initWithTitle:title subtitle:subtitle image:nil];\n}\n\n@end\n\n\n@implementation NITextCell\n\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {\n    self.selectionStyle = UITableViewCellSelectionStyleNone;\n  }\n  return self;\n}\n\n- (void)prepareForReuse {\n  [super prepareForReuse];\n\n  self.imageView.image = nil;\n  self.textLabel.text = nil;\n  self.detailTextLabel.text = nil;\n}\n\n- (BOOL)shouldUpdateCellWithObject:(id)object {\n  if ([object isKindOfClass:[NITitleCellObject class]]) {\n    NITitleCellObject* titleObject = object;\n    self.textLabel.text = titleObject.title;\n    self.textLabel.accessibilityTraits = titleObject.accessibilityTraits;\n    self.imageView.image = titleObject.image;\n  }\n  if ([object isKindOfClass:[NISubtitleCellObject class]]) {\n    NISubtitleCellObject* subtitleObject = object;\n    self.detailTextLabel.text = subtitleObject.subtitle;\n  }\n  return YES;\n}\n\n@end\n\n\n@interface NIDrawRectBlockView : UIView\n@property (nonatomic, copy) NICellDrawRectBlock block;\n@property (nonatomic, strong) id object;\n@property (nonatomic, weak) UITableViewCell* cell;\n@end\n\n\n@implementation NIDrawRectBlockView\n\n\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.backgroundColor = [UIColor clearColor];\n  }\n  return self;\n}\n\n- (void)drawRect:(CGRect)rect {\n  if (nil != self.block) {\n    self.block(rect, self.object, self.cell);\n  }\n}\n\n@end\n\n\n@implementation NIDrawRectBlockCell\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier])) {\n    self.selectionStyle = UITableViewCellSelectionStyleNone;\n\n    _blockView = [[NIDrawRectBlockView alloc] initWithFrame:self.contentView.bounds];\n    _blockView.autoresizingMask =\n        (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n    _blockView.contentMode = UIViewContentModeRedraw;\n    [self.contentView addSubview:_blockView];\n\n    [self.textLabel removeFromSuperview];\n    [self.imageView removeFromSuperview];\n    [self.detailTextLabel removeFromSuperview];\n  }\n  return self;\n}\n\n- (BOOL)shouldUpdateCellWithObject:(id)object {\n  NSAssert([object isKindOfClass:[NIDrawRectBlockCellObject class]],\n           @\"object must be NIDrawRectBlockCellObject\");\n  NIDrawRectBlockCellObject *blockCell = (NIDrawRectBlockCellObject *)object;\n  NIDrawRectBlockView* blockView = (NIDrawRectBlockView *)self.blockView;\n  blockView.block = blockCell.block;\n  blockView.object = blockCell.object;\n  blockView.cell = self;\n  [blockView setNeedsDisplay];\n  return YES;\n}\n\n+ (CGFloat)heightForObject:(id)object atIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView {\n  NSAssert([object isKindOfClass:[NIDrawRectBlockCellObject class]],\n           @\"object must be NIDrawRectBlockCellObject\");\n  NIDrawRectBlockCellObject *blockCell = (NIDrawRectBlockCellObject *)object;\n  return blockCell.block(tableView.bounds, blockCell.object, nil);\n}\n\n@end\n"
  },
  {
    "path": "src/models/src/NICellFactory+Private.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICellFactory.h\"\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n// Private classes for use in Nimbus.\n@interface NICellObject ()\n\n// A property to change the cell class of this cell object.\n@property(nonatomic, assign) Class cellClass;\n\n@end\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/models/src/NICellFactory.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NITableViewModel.h\"\n\n/**\n * A simple factory for creating table view cells from objects.\n *\n * This factory provides a single method that accepts an object and returns a UITableViewCell\n * for use in a UITableView. A cell will only be returned if the object passed to the factory\n * conforms to the NICellObject protocol. The created cell should ideally conform to\n * the NICell protocol. If it does, the object will be passed to it via\n * @link NICell::shouldUpdateCellWithObject: shouldUpdateCellWithObject:@endlink before the\n * factory method returns.\n *\n * This factory is designed to be used with NITableViewModels, though one could easily use\n * it with other table view data source implementations simply by providing nil for the table\n * view model.\n *\n * If you instantiate an NICellFactory then you can provide explicit mappings from objects\n * to cells. This is helpful if the effort required to implement the NICell protocol on\n * an object outweighs the benefit of using the factory, i.e. when you want to map\n * simple types such as NSString to cells.\n *\n * @ingroup TableCellFactory\n */\n@interface NICellFactory : NSObject <NITableViewModelDelegate>\n\n/**\n * Creates a cell from a given object if and only if the object conforms to the NICellObject\n * protocol.\n *\n * This method signature matches the NITableViewModelDelegate method so that you can\n * set this factory as the model's delegate:\n *\n * @code\n// Must cast to id to avoid compiler warnings.\n_model.delegate = (id)[NICellFactory class];\n * @endcode\n *\n * If you would like to customize the factory's output, implement the model's delegate method\n * and call the factory method. Remember that if the factory doesn't know how to map\n * the object to a cell it will return nil.\n *\n * @code\n- (UITableViewCell *)tableViewModel:(NITableViewModel *)tableViewModel\n                   cellForTableView:(UITableView *)tableView\n                        atIndexPath:(NSIndexPath *)indexPath\n                         withObject:(id)object {\n  UITableViewCell* cell = [NICellFactory tableViewModel:tableViewModel\n                                       cellForTableView:tableView\n                                            atIndexPath:indexPath\n                                             withObject:object];\n  if (nil == cell) {\n    // Custom cell creation here.\n  }\n  return cell;\n}\n * @endcode\n */\n+ (UITableViewCell *)tableViewModel:(NITableViewModel *)tableViewModel cellForTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath withObject:(id)object;\n\n/**\n * Map an object's class to a cell's class.\n *\n * If an object implements the NICell protocol AND is found in this factory\n * mapping, the factory mapping will take precedence. This allows you to\n * explicitly override the mapping on a case-by-case basis.\n */\n- (void)mapObjectClass:(Class)objectClass toCellClass:(Class)cellClass;\n\n/**\n * Returns the height for a row at a given index path.\n *\n * Uses the heightForObject:atIndexPath:tableView: selector from the NICell protocol to ask the\n * object at indexPath in the model what its height should be. If a class mapping has been made for\n * the given object in this factory then that class mapping will be used over the result of\n * cellClass from the NICellObject protocol.\n *\n * If the cell returns a height of zero then tableView.rowHeight will be used.\n *\n * Example implementation:\n *\n@code\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {\n  return [self.cellFactory tableView:tableView heightForRowAtIndexPath:indexPath model:self.model];\n}\n@endcode\n *\n * @param tableView The table view within which the cell exists.\n * @param indexPath The location of the cell in the table view.\n * @param model The backing model being used by the table view.\n * @returns The height of the cell mapped to the object at indexPath, if it implements\n *               heightForObject:atIndexPath:tableView:; otherwise, returns tableView.rowHeight.\n */\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath model:(NITableViewModel *)model;\n\n/**\n * Returns the height for a row at a given index path.\n *\n * Uses the heightForObject:atIndexPath:tableView: selector from the NICell protocol to ask the\n * object at indexPath in the model what its height should be. Only implicit mappings will be\n * checked with this static implementation. If you would like to provide explicit mappings you must\n * create an instance of NICellFactory.\n *\n * If the cell returns a height of zero then tableView.rowHeight will be used.\n *\n * Example implementation:\n *\n@code\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {\n  return [NICellFactory tableView:tableView heightForRowAtIndexPath:indexPath model:self.model];\n}\n@endcode\n *\n * @param tableView The table view within which the cell exists.\n * @param indexPath The location of the cell in the table view.\n * @param model The backing model being used by the table view.\n * @returns The height of the cell mapped to the object at indexPath, if it implements\n *               heightForObject:atIndexPath:tableView:; otherwise, returns tableView.rowHeight.\n */\n+ (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath model:(NITableViewModel *)model;\n\n@end\n\n/**\n * The protocol for an object that can be used in the NICellFactory.\n *\n * @ingroup TableCellFactory\n */\n@protocol NICellObject <NSObject>\n@required\n/** The class of cell to be created when this object is passed to the cell factory. */\n- (Class)cellClass;\n\n@optional\n/** The style of UITableViewCell to be used when initializing the cell for the first time. */\n- (UITableViewCellStyle)cellStyle;\n@end\n\n/**\n * The protocol for an object that can be used in the NICellFactory with Interface Builder nibs.\n *\n * @ingroup TableCellFactory\n */\n@protocol NINibCellObject <NSObject>\n@required\n\n/** A nib that contains a table view cell to display this object's contents. */\n- (UINib *)cellNib;\n\n/** When call the tableView's heightForRowAtIndexPath method, we need get cell class and call NITableViewModelDelegate's heightForRowAtIndexPath */\n- (Class)cellNibClass;\n\n@end\n\n/**\n * The protocol for a cell created in the NICellFactory.\n *\n * Cells that implement this protocol are given the object that implemented the NICellObject\n * protocol and returned this cell's class name in @link NICellObject::cellClass cellClass@endlink.\n *\n * @ingroup TableCellFactory\n */\n@protocol NICell <NSObject>\n@required\n/**\n * Called when a cell is created and reused.\n *\n * Implement this method to customize the cell's properties for display using the given object.\n */\n- (BOOL)shouldUpdateCellWithObject:(id)object;\n\n@optional\n\n/**\n * Asks the receiver whether the mapped object class should be appended to the reuse identifier\n * in order to create a unique cell.object identifier key.\n *\n * This is useful when you have a cell that is intended to be used by a variety of different\n * objects.\n */\n+ (BOOL)shouldAppendObjectClassToReuseIdentifier;\n\n/**\n * Asks the receiver to calculate its height.\n *\n * The following is an appropiate implementation in your tableView's delegate:\n *\n@code\n-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {\n  CGFloat height = tableView.rowHeight;\n  id object = [(NITableViewModel *)tableView.dataSource objectAtIndexPath:indexPath];\n  id class = [object cellClass];\n  if ([class respondsToSelector:@selector(heightForObject:atIndexPath:tableView:)]) {\n    height = [class heightForObject:object atIndexPath:indexPath tableView:tableView];\n  }\n  return height;\n}\n@endcode\n *\n * You may also use the\n * @link NICellFactory::tableView:heightForRowAtIndexPath:model: tableView:heightForRowAtIndexPath:model:@endlink\n * methods on NICellFactory to achieve the same result. Using the above example allows you to\n * customize the logic according to your specific needs.\n */\n+ (CGFloat)heightForObject:(id)object atIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView;\n\n@end\n\n/**\n * A light-weight implementation of the NICellObject protocol.\n *\n * Use this object in cases where you can't set up a hard binding between an object and a cell,\n * or when you simply don't want to.\n *\n * For example, let's say that you want to show a cell that shows a loading indicator.\n * Rather than create a new interface, LoadMoreObject, simply for the cell and binding it\n * to the cell view, you can create an NICellObject and pass the class name of the cell.\n *\n@code\n[tableContents addObject:[NICellObject objectWithCellClass:[LoadMoreCell class]]];\n@endcode\n */\n@interface NICellObject : NSObject <NICellObject>\n\n// Designated initializer.\n- (id)initWithCellClass:(Class)cellClass userInfo:(id)userInfo;\n- (id)initWithCellClass:(Class)cellClass;\n\n+ (id)objectWithCellClass:(Class)cellClass userInfo:(id)userInfo;\n+ (id)objectWithCellClass:(Class)cellClass;\n\n@property (nonatomic, strong) id userInfo;\n\n@end\n\n/**\n * An object that can be used to populate information in the cell.\n *\n * @fn NICellObject::userInfo\n */\n"
  },
  {
    "path": "src/models/src/NICellFactory.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICellFactory.h\"\n#import \"NICellFactory+Private.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NICellFactory()\n@property (nonatomic, copy) NSMutableDictionary* objectToCellMap;\n@end\n\n\n@implementation NICellFactory\n\n\n\n- (id)init {\n  if ((self = [super init])) {\n    _objectToCellMap = [[NSMutableDictionary alloc] init];\n  }\n  return self;\n}\n\n+ (UITableViewCell *)cellWithClass:(Class)cellClass\n                         tableView:(UITableView *)tableView\n                            object:(id)object {\n  UITableViewCell* cell = nil;\n\n  NSString* identifier = NSStringFromClass(cellClass);\n\n  if ([cellClass respondsToSelector:@selector(shouldAppendObjectClassToReuseIdentifier)]\n      && [cellClass shouldAppendObjectClassToReuseIdentifier]) {\n    identifier = [identifier stringByAppendingFormat:@\".%@\", NSStringFromClass([object class])];\n  }\n\n  cell = [tableView dequeueReusableCellWithIdentifier:identifier];\n\n  if (nil == cell) {\n    UITableViewCellStyle style = UITableViewCellStyleDefault;\n    if ([object respondsToSelector:@selector(cellStyle)]) {\n      style = [object cellStyle];\n    }\n    cell = [[cellClass alloc] initWithStyle:style reuseIdentifier:identifier];\n  }\n\n  // Allow the cell to configure itself with the object's information.\n  if ([cell respondsToSelector:@selector(shouldUpdateCellWithObject:)]) {\n    [(id<NICell>)cell shouldUpdateCellWithObject:object];\n  }\n\n  return cell;\n}\n\n+ (UITableViewCell *)cellWithNib:(UINib *)cellNib\n                       tableView:(UITableView *)tableView\n                       indexPath:(NSIndexPath *)indexPath\n                          object:(id)object {\n  UITableViewCell* cell = nil;\n\n  NSString* identifier = NSStringFromClass([object class]);\n  [tableView registerNib:cellNib forCellReuseIdentifier:identifier];\n\n  cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];\n\n  // Allow the cell to configure itself with the object's information.\n  if ([cell respondsToSelector:@selector(shouldUpdateCellWithObject:)]) {\n    [(id<NICell>)cell shouldUpdateCellWithObject:object];\n  }\n\n  return cell;\n}\n\n+ (UITableViewCell *)tableViewModel:(NITableViewModel *)tableViewModel\n                   cellForTableView:(UITableView *)tableView\n                        atIndexPath:(NSIndexPath *)indexPath\n                         withObject:(id)object {\n  UITableViewCell* cell = nil;\n\n  // Only NICellObject-conformant objects may pass.\n  if ([object respondsToSelector:@selector(cellClass)]) {\n    Class cellClass = [object cellClass];\n    cell = [self cellWithClass:cellClass tableView:tableView object:object];\n\n  } else if ([object respondsToSelector:@selector(cellNib)]) {\n    UINib* nib = [object cellNib];\n    cell = [self cellWithNib:nib tableView:tableView indexPath:indexPath object:object];\n  }\n\n  // If this assertion fires then your app is about to crash. You need to either add an explicit\n  // binding in a NICellFactory object or implement the NICellObject protocol on this object and\n  // return a cell class.\n  NIDASSERT(nil != cell);\n\n  return cell;\n}\n\n- (Class)cellClassFromObject:(id)object {\n  if (nil == object) {\n    return nil;\n  }\n  Class objectClass = [object class];\n  Class cellClass = [self.objectToCellMap objectForKey:objectClass];\n\n  BOOL hasExplicitMapping = (nil != cellClass && cellClass != [NSNull class]);\n\n  if (!hasExplicitMapping && [object respondsToSelector:@selector(cellClass)]) {\n    cellClass = [object cellClass];\n  }\n\n  if (nil == cellClass) {\n    cellClass = [NIActions objectFromKeyClass:objectClass map:self.objectToCellMap];\n  }\n\n  return cellClass;\n}\n\n- (UITableViewCell *)tableViewModel:(NITableViewModel *)tableViewModel\n                   cellForTableView:(UITableView *)tableView\n                        atIndexPath:(NSIndexPath *)indexPath\n                         withObject:(id)object {\n  UITableViewCell* cell = nil;\n\n  Class cellClass = [self cellClassFromObject:object];\n  if (nil != cellClass) {\n    cell = [[self class] cellWithClass:cellClass tableView:tableView object:object];\n\n  } else if ([object respondsToSelector:@selector(cellNib)]) {\n    UINib* nib = [object cellNib];\n    cell = [[self class] cellWithNib:nib tableView:tableView indexPath:indexPath object:object];\n  }\n\n  // If this assertion fires then your app is about to crash. You need to either add an explicit\n  // binding in a NICellFactory object or implement the NICellObject protocol on this object and\n  // return a cell class.\n  NIDASSERT(nil != cell);\n\n  return cell;\n}\n\n- (void)mapObjectClass:(Class)objectClass toCellClass:(Class)cellClass {\n  [self.objectToCellMap setObject:cellClass forKey:(id<NSCopying>)objectClass];\n}\n\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath model:(NITableViewModel *)model {\n  CGFloat height = tableView.rowHeight;\n  id object = [model objectAtIndexPath:indexPath];\n  Class cellClass = [self cellClassFromObject:object];\n  if ([cellClass respondsToSelector:@selector(heightForObject:atIndexPath:tableView:)]) {\n    CGFloat cellHeight = [cellClass heightForObject:object\n                                        atIndexPath:indexPath tableView:tableView];\n    if (cellHeight > 0) {\n      height = cellHeight;\n    }\n  }\n  return height;\n}\n\n+ (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath model:(NITableViewModel *)model {\n  CGFloat height = tableView.rowHeight;\n  id object = [model objectAtIndexPath:indexPath];\n  Class cellClass = nil;\n  if ([object respondsToSelector:@selector(cellClass)]) {\n    cellClass = [object cellClass];\n  }\n  if ([cellClass respondsToSelector:@selector(heightForObject:atIndexPath:tableView:)]) {\n    CGFloat cellHeight = [cellClass heightForObject:object\n                                        atIndexPath:indexPath tableView:tableView];\n    if (cellHeight > 0) {\n      height = cellHeight;\n    }\n  }\n  return height;\n}\n\n@end\n\n\n\n@implementation NICellObject\n\n\n\n- (id)initWithCellClass:(Class)cellClass userInfo:(id)userInfo {\n  if ((self = [super init])) {\n    _cellClass = cellClass;\n    _userInfo = userInfo;\n  }\n  return self;\n}\n\n- (id)initWithCellClass:(Class)cellClass {\n  return [self initWithCellClass:cellClass userInfo:nil];\n}\n\n+ (id)objectWithCellClass:(Class)cellClass userInfo:(id)userInfo {\n  return [[self alloc] initWithCellClass:cellClass userInfo:userInfo];\n}\n\n+ (id)objectWithCellClass:(Class)cellClass {\n  return [[self alloc] initWithCellClass:cellClass userInfo:nil];\n}\n\n@end\n"
  },
  {
    "path": "src/models/src/NIFormCellCatalog.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NICellFactory.h\"\n\n#pragma mark Form Elements\n\n/**\n * A single element of a form with an ID property.\n *\n * Each form element has, at the very least, an element ID property which can be used to\n * differentiate the form elements when change notifications are received. Each element cell\n * will assign the element ID to the tag property of its views.\n *\n * @ingroup TableCellCatalog\n */\n@interface NIFormElement : NSObject <NICellObject>\n\n// Designated initializer\n+ (id)elementWithID:(NSInteger)elementID;\n\n@property (nonatomic, assign) NSInteger elementID;\n\n@end\n\n/**\n * A text input form element.\n *\n * This element is similar to HTML's &lt;input type=\"text\">. It presents a simple text field\n * control with optional placeholder text. You can assign a delegate to this object that will\n * be assigned to the text field, allowing you to receive text field delegate notifications.\n *\n * Bound to NITextInputFormElementCell when using the @link TableCellFactory Nimbus cell factory@endlink.\n *\n * @ingroup TableCellCatalog\n */\n@interface NITextInputFormElement : NIFormElement\n\n// Designated initializer\n+ (id)textInputElementWithID:(NSInteger)elementID placeholderText:(NSString *)placeholderText value:(NSString *)value delegate:(id<UITextFieldDelegate>)delegate;\n+ (id)textInputElementWithID:(NSInteger)elementID placeholderText:(NSString *)placeholderText value:(NSString *)value;\n\n+ (id)passwordInputElementWithID:(NSInteger)elementID placeholderText:(NSString *)placeholderText value:(NSString *)value delegate:(id<UITextFieldDelegate>)delegate;\n+ (id)passwordInputElementWithID:(NSInteger)elementID placeholderText:(NSString *)placeholderText value:(NSString *)value;\n\n@property (nonatomic, copy) NSString* placeholderText;\n@property (nonatomic, copy) NSString* value;\n@property (nonatomic, assign) BOOL isPassword;\n@property (nonatomic, weak) id<UITextFieldDelegate> delegate;\n\n@end\n\n/**\n * A switch form element.\n *\n * This element is similar to the Settings app's switch fields. It shows a label with a switch\n * align to the right edge of the row.\n *\n * Bound to NISwitchFormElementCell when using the @link TableCellFactory Nimbus cell factory@endlink.\n *\n * @ingroup TableCellCatalog\n */\n@interface NISwitchFormElement : NIFormElement\n\n// Designated initializer\n+ (id)switchElementWithID:(NSInteger)elementID labelText:(NSString *)labelText value:(BOOL)value didChangeTarget:(id)target didChangeSelector:(SEL)selector;\n+ (id)switchElementWithID:(NSInteger)elementID labelText:(NSString *)labelText value:(BOOL)value;\n\n@property (nonatomic, copy) NSString* labelText;\n@property (nonatomic, assign) BOOL value;\n@property (nonatomic, weak) id didChangeTarget;\n@property (nonatomic, assign) SEL didChangeSelector;\n\n@end\n\n/**\n * A slider form element.\n *\n * This element is a slider that can be embedded in a form. It shows a label with a switch\n * align to the right edge of the row.\n *\n * Bound to NISliderFormElementCell when using the @link TableCellFactory Nimbus cell factory@endlink.\n *\n * @ingroup TableCellCatalog\n */\n@interface NISliderFormElement : NIFormElement\n\n// Designated initializer\n+ (id)sliderElementWithID:(NSInteger)elementID labelText:(NSString *)labelText value:(float)value minimumValue:(float)minimumValue maximumValue:(float)maximumValue didChangeTarget:(id)target didChangeSelector:(SEL)selector;\n+ (id)sliderElementWithID:(NSInteger)elementID labelText:(NSString *)labelText value:(float)value minimumValue:(float)minimumValue maximumValue:(float)maximumValue;\n\n@property (nonatomic, copy) NSString* labelText;\n@property (nonatomic, assign) float value;\n@property (nonatomic, assign) float minimumValue;\n@property (nonatomic, assign) float maximumValue;\n@property (nonatomic, weak) id didChangeTarget;\n@property (nonatomic, assign) SEL didChangeSelector;\n\n@end\n\n/**\n * A segmented control form element.\n *\n * This element presents a segmented control. You can initialize it with a label for the cell, an \n * array of NSString or UIImage objects acting as segments for the segmented control and a \n * selectedIndex. The selectedIndex can be -1 if you don't want to preselect a segment.\n *\n * A delegate method (didChangeSelector) will be called on the didChangeTarget once a different \n * segment is selected. The segmented control will be passed as an argument to this method.\n *\n * @ingroup TableCellCatalog\n */\n@interface NISegmentedControlFormElement : NIFormElement\n\n/**\n * Initializes a segmented control form cell with callback method for value change events.\n *\n * @param elementID An ID for this element.\n * @param labelText Text to show on the left side of the form cell.\n * @param segments An array containing NSString or UIImage objects that will be used as \n *                      segments of the control. The order in the array is used as order of the \n *                      segments.\n * @param selectedIndex Index of the selected segment. -1 if no segment is selected.\n * @param target Receiver for didChangeSelector calls.\n * @param selector Method that is called when a segment is selected.\n */\n+ (id)segmentedControlElementWithID:(NSInteger)elementID labelText:(NSString *)labelText segments:(NSArray *)segments selectedIndex:(NSInteger)selectedIndex didChangeTarget:(id)target didChangeSelector:(SEL)selector ;\n\n/**\n * Initializes a segmented control form cell.\n *\n * @param elementID An ID for this element.\n * @param labelText Text to show on the left side of the form cell.\n * @param segments An array containing NSString or UIImage objects that will be used as \n *                      segments of the control. The order in the array is used as order of the\n *                      segments.\n * @param selectedIndex Index of the selected segment. -1 if no segment is selected.\n */\n+ (id)segmentedControlElementWithID:(NSInteger)elementID labelText:(NSString *)labelText segments:(NSArray *)segments selectedIndex:(NSInteger)selectedIndex;\n\n@property (nonatomic, copy) NSString *labelText;\n@property (nonatomic, assign) NSInteger selectedIndex;\n@property (nonatomic, strong) NSArray *segments;\n@property (nonatomic, weak) id didChangeTarget;\n@property (nonatomic, assign) SEL didChangeSelector;\n\n@end\n\n/**\n * A date picker form element.\n *\n * This element shows a date that can be modified.\n *\n * You can initialize it with a labelText showing on the left in the table cell, a date that will \n * be used to initialize the date picker and a delegate target and method that gets called when a \n * different date is selected.\n *\n * To change the date picker format you can access the datePicker property of the \n * NIDatePickerFormElementCell sibling object.\n *\n * @ingroup TableCellCatalog\n */\n@interface NIDatePickerFormElement : NIFormElement\n\n/**\n * Initializes a date picker form element with callback method for value changed events.\n *\n * @param elementID An ID for this element.\n * @param labelText Text to show on the left side of the form cell.\n * @param date Initial date to show in the picker\n * @param datePickerMode UIDatePickerMode to user for the date picker\n * @param target Receiver for didChangeSelector calls.\n * @param selector Method that is called when a segment is selected.\n */\n+ (id)datePickerElementWithID:(NSInteger)elementID labelText:(NSString *)labelText date:(NSDate *)date datePickerMode:(UIDatePickerMode)datePickerMode didChangeTarget:(id)target didChangeSelector:(SEL)selector;\n\n/**\n * Initializes a date picker form element with callback method for value changed events.\n *\n * @param elementID An ID for this element.\n * @param labelText Text to show on the left side of the form cell.\n * @param date Initial date to show in the picker\n * @param datePickerMode UIDatePickerMode to user for the date picker\n */\n+ (id)datePickerElementWithID:(NSInteger)elementID labelText:(NSString *)labelText date:(NSDate *)date datePickerMode:(UIDatePickerMode)datePickerMode;\n\n@property (nonatomic, copy) NSString *labelText;\n@property (nonatomic, strong) NSDate *date;\n@property (nonatomic, assign) UIDatePickerMode datePickerMode;\n@property (nonatomic, weak) id didChangeTarget;\n@property (nonatomic, assign) SEL didChangeSelector;\n\n@end\n\n\n#pragma mark - Form Element Cells\n\n/**\n * The base class for form element cells.\n *\n * Doesn't do anything particularly interesting other than retaining the element.\n *\n * @ingroup TableCellCatalog\n */\n@interface NIFormElementCell : UITableViewCell <NICell>\n@property (nonatomic, readonly, strong) NIFormElement* element;\n@end\n\n/**\n * The cell sibling to NITextInputFormElement.\n *\n * Displays a simple text field that fills the entire content view.\n *\n * @image html NITextInputCellExample1.png \"Example of a NITextInputFormElementCell.\"\n *\n * @ingroup TableCellCatalog\n */\n@interface NITextInputFormElementCell : NIFormElementCell <UITextFieldDelegate>\n@property (nonatomic, readonly, strong) UITextField* textField;\n@end\n\n/**\n * The cell sibling to NISwitchFormElement.\n *\n * Displays a left-aligned label and a right-aligned switch.\n *\n * @image html NISwitchFormElementCellExample1.png \"Example of a NISwitchFormElementCell.\"\n *\n * @ingroup TableCellCatalog\n */\n@interface NISwitchFormElementCell : NIFormElementCell <UITextFieldDelegate>\n@property (nonatomic, readonly, strong) UISwitch* switchControl;\n@end\n\n/**\n * The cell sibling to NISliderFormElement.\n *\n * Displays a left-aligned label and a right-aligned slider.\n *\n * @image html NISliderFormElementCellExample1.png \"Example of a NISliderFormElementCell.\"\n *\n * @ingroup TableCellCatalog\n */\n@interface NISliderFormElementCell : NIFormElementCell <UITextFieldDelegate>\n@property (nonatomic, readonly, strong) UISlider* sliderControl;\n@end\n\n@interface NITableViewModel (NIFormElementSearch)\n\n// Finds an element in the static table view model with the given element id.\n- (id)elementWithID:(NSInteger)elementID;\n\n@end\n\n/**\n * The cell sibling to NISegmentedControlFormElement.\n *\n * Displays a left-aligned label and a right-aligned segmented control.\n *\n * @ingroup TableCellCatalog\n */\n@interface NISegmentedControlFormElementCell : NIFormElementCell\n@property (nonatomic, readonly, strong) UISegmentedControl *segmentedControl;\n@end\n\n/**\n * The cell sibling to NIDatePickerFormElement\n *\n * Displays a left-aligned label and a right-aligned date.\n *\n * @ingroup TableCellCatalog\n */\n@interface NIDatePickerFormElementCell : NIFormElementCell <UITextFieldDelegate>\n@property (nonatomic, readonly, strong) UITextField *dateField;\n@property (nonatomic, readonly, strong) UIDatePicker *datePicker;\n@end\n\n"
  },
  {
    "path": "src/models/src/NIFormCellCatalog.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIFormCellCatalog.h\"\n\n#import \"NITableViewModel+Private.h\"\n\n#import \"NimbusCore.h\"\n#import <objc/message.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic const CGFloat kSwitchLeftMargin = 10;\nstatic const CGFloat kImageViewRightMargin = 10;\nstatic const CGFloat kSegmentedControlMargin = 5;\nstatic const CGFloat kDatePickerTextFieldRightMargin = 5;\n\n@implementation NIFormElement\n\n\n\n+ (id)elementWithID:(NSInteger)elementID {\n  NIFormElement* element = [[self alloc] init];\n  element.elementID = elementID;\n  return element;\n}\n\n- (Class)cellClass {\n  // You must implement cellClass in your subclass of this object.\n  NIDASSERT(NO);\n  return nil;\n}\n\n@end\n\n\n@implementation NITextInputFormElement\n\n\n\n+ (id)textInputElementWithID:(NSInteger)elementID placeholderText:(NSString *)placeholderText value:(NSString *)value delegate:(id<UITextFieldDelegate>)delegate {\n  NITextInputFormElement* element = [super elementWithID:elementID];\n  element.placeholderText = placeholderText;\n  element.value = value;\n  element.delegate = delegate;\n  return element;\n}\n\n+ (id)textInputElementWithID:(NSInteger)elementID placeholderText:(NSString *)placeholderText value:(NSString *)value {\n  return [self textInputElementWithID:elementID placeholderText:placeholderText value:value delegate:nil];\n}\n\n+ (id)passwordInputElementWithID:(NSInteger)elementID placeholderText:(NSString *)placeholderText value:(NSString *)value delegate:(id<UITextFieldDelegate>)delegate {\n  NITextInputFormElement* element = [self textInputElementWithID:elementID placeholderText:placeholderText value:value delegate:delegate];\n  element.isPassword = YES;\n  return element;\n}\n\n+ (id)passwordInputElementWithID:(NSInteger)elementID placeholderText:(NSString *)placeholderText value:(NSString *)value {\n  return [self passwordInputElementWithID:elementID placeholderText:placeholderText value:value delegate:nil];\n}\n\n- (Class)cellClass {\n  return [NITextInputFormElementCell class];\n}\n\n@end\n\n\n@implementation NISwitchFormElement\n\n\n\n+ (id)switchElementWithID:(NSInteger)elementID labelText:(NSString *)labelText value:(BOOL)value didChangeTarget:(id)target didChangeSelector:(SEL)selector {\n  NISwitchFormElement* element = [super elementWithID:elementID];\n  element.labelText = labelText;\n  element.value = value;\n  element.didChangeTarget = target;\n  element.didChangeSelector = selector;\n  return element;\n}\n\n+ (id)switchElementWithID:(NSInteger)elementID labelText:(NSString *)labelText value:(BOOL)value {\n  return [self switchElementWithID:elementID labelText:labelText value:value didChangeTarget:nil didChangeSelector:nil];\n}\n\n- (Class)cellClass {\n  return [NISwitchFormElementCell class];\n}\n\n@end\n\n\n@implementation NISliderFormElement\n\n\n\n+ (id)sliderElementWithID:(NSInteger)elementID labelText:(NSString *)labelText value:(float)value minimumValue:(float)minimumValue maximumValue:(float)maximumValue didChangeTarget:(id)target didChangeSelector:(SEL)selector {\n  NISliderFormElement* element = [super elementWithID:elementID];\n  element.labelText = labelText;\n  element.value = value;\n  element.minimumValue = minimumValue;\n  element.maximumValue = maximumValue;\n  element.didChangeTarget = target;\n  element.didChangeSelector = selector;\n  return element;\n}\n\n+ (id)sliderElementWithID:(NSInteger)elementID labelText:(NSString *)labelText value:(float)value minimumValue:(float)minimumValue maximumValue:(float)maximumValue {\n  return [self sliderElementWithID:elementID labelText:labelText value:value minimumValue:minimumValue maximumValue:maximumValue didChangeTarget:nil didChangeSelector:nil];\n}\n\n- (Class)cellClass {\n  return [NISliderFormElementCell class];\n}\n\n@end\n\n\n@implementation NISegmentedControlFormElement\n\n\n\n+ (id)segmentedControlElementWithID:(NSInteger)elementID labelText:(NSString *)labelText segments:(NSArray *)segments selectedIndex:(NSInteger)selectedIndex didChangeTarget:(id)target didChangeSelector:(SEL)selector {\n    NISegmentedControlFormElement *element = [super elementWithID:elementID];\n    element.labelText = labelText;\n    element.selectedIndex = selectedIndex;\n    element.segments = segments;\n    element.didChangeTarget = target;\n    element.didChangeSelector = selector;\n    return element;\n}\n\n+ (id)segmentedControlElementWithID:(NSInteger)elementID labelText:(NSString *)labelText segments:(NSArray *)segments selectedIndex:(NSInteger)selectedIndex {\n    return [self segmentedControlElementWithID:elementID labelText:labelText segments:segments selectedIndex:selectedIndex didChangeTarget:nil didChangeSelector:nil];\n}\n\n- (Class)cellClass {\n    return [NISegmentedControlFormElementCell class];\n}\n\n@end\n\n\n@implementation NIDatePickerFormElement\n\n\n+ (id)datePickerElementWithID:(NSInteger)elementID labelText:(NSString *)labelText date:(NSDate *)date datePickerMode:(UIDatePickerMode)datePickerMode didChangeTarget:(id)target didChangeSelector:(SEL)selector {\n    NIDatePickerFormElement *element = [super elementWithID:elementID];\n    element.labelText = labelText;\n    element.date = date;\n    element.datePickerMode = datePickerMode;\n    element.didChangeTarget = target;\n    element.didChangeSelector = selector;\n    return element;\n}\n\n+ (id)datePickerElementWithID:(NSInteger)elementID labelText:(NSString *)labelText date:(NSDate *)date datePickerMode:(UIDatePickerMode)datePickerMode {\n    return [self datePickerElementWithID:elementID labelText:labelText date:date datePickerMode:datePickerMode didChangeTarget:nil didChangeSelector:nil];\n}\n\n- (Class)cellClass {\n    return [NIDatePickerFormElementCell class];\n}\n\n@end\n\n\n#pragma mark - Form Element Cells\n\n\n@implementation NIFormElementCell\n\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];\n    if (self) {\n        [self.textLabel setAdjustsFontSizeToFitWidth:YES];\n        if ([self.textLabel respondsToSelector:@selector(minimumScaleFactor)]) {\n          self.textLabel.minimumScaleFactor = 0.5;\n        } else {\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n          [self.textLabel setMinimumFontSize:10.0f];\n#endif\n        }\n    }\n    return self;\n}\n\n- (void)prepareForReuse {\n  [super prepareForReuse];\n  \n  _element = nil;\n}\n\n- (BOOL)shouldUpdateCellWithObject:(id)object {\n  if (_element != object) {\n    _element = object;\n\n    self.tag = _element.elementID;\n\n    return YES;\n  }\n\n  return NO;\n}\n\n@end\n\n\n@implementation NITextInputFormElementCell\n\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {\n    self.selectionStyle = UITableViewCellSelectionStyleNone;\n\n    _textField = [[UITextField alloc] init];\n    [_textField setTag:self.element.elementID];\n    [_textField setAdjustsFontSizeToFitWidth:YES];\n    [_textField setMinimumFontSize:10.0f];\n    [_textField addTarget:self action:@selector(textFieldDidChangeValue) forControlEvents:UIControlEventAllEditingEvents];\n    [self.contentView addSubview:_textField];\n\n    [self.textLabel removeFromSuperview];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  _textField.frame = UIEdgeInsetsInsetRect(self.contentView.bounds, NICellContentPadding());\n}\n\n- (void)prepareForReuse {\n  [super prepareForReuse];\n\n  _textField.placeholder = nil;\n  _textField.text = nil;\n}\n\n- (BOOL)shouldUpdateCellWithObject:(NITextInputFormElement *)textInputElement {\n  if ([super shouldUpdateCellWithObject:textInputElement]) {\n    _textField.placeholder = textInputElement.placeholderText;\n    _textField.text = textInputElement.value;\n    _textField.delegate = textInputElement.delegate;\n    _textField.secureTextEntry = textInputElement.isPassword;\n\n    _textField.tag = self.tag;\n\n    [self setNeedsLayout];\n    return YES;\n  }\n  return NO;\n}\n\n- (void)textFieldDidChangeValue {\n  NITextInputFormElement* textInputElement = (NITextInputFormElement *)self.element;\n  textInputElement.value = _textField.text;\n}\n\n@end\n\n\n@implementation NISwitchFormElementCell\n\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {\n    self.selectionStyle = UITableViewCellSelectionStyleNone;\n\n    _switchControl = [[UISwitch alloc] init];\n    [_switchControl addTarget:self action:@selector(switchDidChangeValue) forControlEvents:UIControlEventValueChanged];\n    [self.contentView addSubview:_switchControl];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  UIEdgeInsets contentPadding = NICellContentPadding();\n  CGRect contentFrame = UIEdgeInsetsInsetRect(self.contentView.frame, contentPadding);\n\n  [_switchControl sizeToFit];\n  CGRect frame = _switchControl.frame;\n  frame.origin.y = NICGFloatFloor((self.contentView.frame.size.height - frame.size.height) / 2);\n  frame.origin.x = self.contentView.frame.size.width - frame.size.width - frame.origin.y;\n  _switchControl.frame = frame;\n\n  frame = self.textLabel.frame;\n  CGFloat leftEdge = 0;\n  // Take into account the size of the image view.\n  if (nil != self.imageView.image) {\n    leftEdge = self.imageView.frame.size.width + kImageViewRightMargin;\n  }\n  frame.size.width = (self.contentView.frame.size.width\n                      - contentFrame.origin.x\n                      - _switchControl.frame.size.width\n                      - _switchControl.frame.origin.y\n                      - kSwitchLeftMargin\n                      - leftEdge);\n  self.textLabel.frame = frame;\n}\n\n- (void)prepareForReuse {\n  [super prepareForReuse];\n\n  self.textLabel.text = nil;\n}\n\n- (BOOL)shouldUpdateCellWithObject:(NISwitchFormElement *)switchElement {\n  if ([super shouldUpdateCellWithObject:switchElement]) {\n    _switchControl.on = switchElement.value;\n    self.textLabel.text = switchElement.labelText;\n\n    _switchControl.tag = self.tag;\n\n    [self setNeedsLayout];\n    return YES;\n  }\n  return NO;\n}\n\n- (void)switchDidChangeValue {\n  NISwitchFormElement* switchElement = (NISwitchFormElement *)self.element;\n  switchElement.value = _switchControl.on;\n\n  if (nil != switchElement.didChangeSelector && nil != switchElement.didChangeTarget\n      && [switchElement.didChangeTarget respondsToSelector:switchElement.didChangeSelector]) {\n    \n      // this will lead to crash on ARMx64 devices\n      // The following is a workaround to supress the warning and requires <objc/message.h>\n      //    objc_msgSend(switchElement.didChangeTarget,\n      //                 switchElement.didChangeSelector, _switchControl);\n      \n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n    [switchElement.didChangeTarget performSelector:switchElement.didChangeSelector\n                                        withObject:_switchControl];\n#pragma clang diagnostic pop\n\n  }\n}\n\n@end\n\n\n@implementation NISliderFormElementCell\n\n\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {\n    self.selectionStyle = UITableViewCellSelectionStyleNone;\n\n    _sliderControl = [[UISlider alloc] init];\n    [_sliderControl addTarget:self action:@selector(sliderDidChangeValue) forControlEvents:UIControlEventValueChanged];\n    [self.contentView addSubview:_sliderControl];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  UIEdgeInsets contentPadding = NICellContentPadding();\n  CGRect contentFrame = UIEdgeInsetsInsetRect(self.contentView.frame, contentPadding);\n  CGFloat labelWidth = contentFrame.size.width * 0.5f;\n\n  CGRect frame = self.textLabel.frame;\n  frame.size.width = labelWidth;\n  self.textLabel.frame = frame;\n\n  static const CGFloat kSliderLeftMargin = 8;\n  [_sliderControl sizeToFit];\n  frame = _sliderControl.frame;\n  frame.origin.y = NICGFloatFloor((self.contentView.frame.size.height - frame.size.height) / 2);\n  frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width + kSliderLeftMargin;\n  frame.size.width = contentFrame.size.width - frame.origin.x;\n  _sliderControl.frame = frame;\n}\n\n- (void)prepareForReuse {\n  [super prepareForReuse];\n\n  self.textLabel.text = nil;\n}\n\n- (BOOL)shouldUpdateCellWithObject:(NISliderFormElement *)sliderElement {\n  if ([super shouldUpdateCellWithObject:sliderElement]) {\n    _sliderControl.minimumValue = sliderElement.minimumValue;\n    _sliderControl.maximumValue = sliderElement.maximumValue;\n    _sliderControl.value = sliderElement.value;\n    self.textLabel.text = sliderElement.labelText;\n\n    _sliderControl.tag = self.tag;\n\n    [self setNeedsLayout];\n    return YES;\n  }\n  return NO;\n}\n\n- (void)sliderDidChangeValue {\n  NISliderFormElement* sliderElement = (NISliderFormElement *)self.element;\n  sliderElement.value = _sliderControl.value;\n\n  if (nil != sliderElement.didChangeSelector && nil != sliderElement.didChangeTarget\n      && [sliderElement.didChangeTarget respondsToSelector:sliderElement.didChangeSelector]) {\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n    [sliderElement.didChangeTarget performSelector:sliderElement.didChangeSelector\n                                        withObject:_sliderControl];\n#pragma clang diagnostic pop\n  }\n}\n\n@end\n\n@implementation NISegmentedControlFormElementCell\n\n\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {\n    self.selectionStyle = UITableViewCellSelectionStyleNone;\n\n    _segmentedControl = [[UISegmentedControl alloc] init];\n    [_segmentedControl addTarget:self action:@selector(selectedSegmentDidChangeValue) forControlEvents:UIControlEventValueChanged];\n    [self.contentView addSubview:self.segmentedControl];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  UIEdgeInsets contentPadding = NICellContentPadding();\n  CGRect contentFrame = UIEdgeInsetsInsetRect(self.contentView.frame, contentPadding);\n\n  [_segmentedControl sizeToFit];\n  CGRect frame = _segmentedControl.frame;\n  frame.size.height = self.contentView.frame.size.height - (2 * kSegmentedControlMargin);\n  frame.origin.y = NICGFloatFloor((self.contentView.frame.size.height - frame.size.height) / 2);\n  frame.origin.x = CGRectGetMaxX(contentFrame) - frame.size.width - kSegmentedControlMargin;\n  _segmentedControl.frame = frame;\n\n  frame = self.textLabel.frame;\n  CGFloat leftEdge = 0;\n  // Take into account the size of the image view.\n  if (nil != self.imageView.image) {\n    leftEdge = self.imageView.frame.size.width + kImageViewRightMargin;\n  }\n  frame.size.width = (self.contentView.frame.size.width\n                      - contentFrame.origin.x\n                      - _segmentedControl.frame.size.width\n                      - kSegmentedControlMargin\n                      - kSwitchLeftMargin\n                      - leftEdge);\n  self.textLabel.frame = frame;\n}\n\n- (void)prepareForReuse {\n  [super prepareForReuse];\n\n  self.textLabel.text = nil;\n  [self.segmentedControl removeAllSegments];\n}\n\n- (BOOL)shouldUpdateCellWithObject:(NISegmentedControlFormElement *)segmentedControlElement {\n  if ([super shouldUpdateCellWithObject:segmentedControlElement]) {\n    self.textLabel.text = segmentedControlElement.labelText;\n    [segmentedControlElement.segments enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {\n      if ([obj isKindOfClass:[NSString class]]) {\n        [self->_segmentedControl insertSegmentWithTitle:obj atIndex:idx animated:NO];\n\n      } else if ([obj isKindOfClass:[UIImage class]]) {\n        [self->_segmentedControl insertSegmentWithImage:obj atIndex:idx animated:NO];\n      }\n    }];\n    _segmentedControl.tag = self.tag;\n    _segmentedControl.selectedSegmentIndex = segmentedControlElement.selectedIndex;\n\n    [self setNeedsLayout];\n    return YES;\n  }\n  return NO;\n}\n\n- (void)selectedSegmentDidChangeValue {\n  NISegmentedControlFormElement *segmentedControlElement = (NISegmentedControlFormElement *)self.element;\n  segmentedControlElement.selectedIndex = self.segmentedControl.selectedSegmentIndex;\n\n  if (nil != segmentedControlElement.didChangeSelector && nil != segmentedControlElement.didChangeTarget\n      && [segmentedControlElement.didChangeTarget respondsToSelector:segmentedControlElement.didChangeSelector]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n    [segmentedControlElement.didChangeTarget performSelector:segmentedControlElement.didChangeSelector\n                                                  withObject:_segmentedControl];\n#pragma clang diagnostic pop\n  }\n}\n\n@end\n\n\n@interface NIDatePickerFormElementCell()\n@property (nonatomic, strong) UITextField* dumbDateField;\n@end\n\n\n@implementation NIDatePickerFormElementCell\n\n\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {\n    self.selectionStyle = UITableViewCellSelectionStyleNone;\n    \n    _datePicker = [[UIDatePicker alloc] init];\n    [_datePicker addTarget:self \n                    action:@selector(selectedDateDidChange) \n          forControlEvents:UIControlEventValueChanged];\n\n    _dateField = [[UITextField alloc] init];\n    _dateField.delegate = self;\n    _dateField.font = [UIFont systemFontOfSize:16.0f];\n    _dateField.minimumFontSize = 10.0f;\n    _dateField.backgroundColor = [UIColor clearColor];\n    _dateField.adjustsFontSizeToFitWidth = YES;\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n    _dateField.textAlignment = UITextAlignmentRight;\n#else\n    _dateField.textAlignment = NSTextAlignmentRight;\n#endif\n    _dateField.inputView = _datePicker;\n    [self.contentView addSubview:_dateField];\n\n    _dumbDateField = [[UITextField alloc] init];\n    _dumbDateField.hidden = YES;\n    _dumbDateField.enabled = NO;\n    [self.contentView addSubview:_dumbDateField];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n  \n  UIEdgeInsets contentPadding = NICellContentPadding();\n  CGRect contentFrame = UIEdgeInsetsInsetRect(self.contentView.frame, contentPadding);\n  \n  [_dateField sizeToFit];\n  CGRect frame = _dateField.frame;\n  frame.origin.y = NICGFloatFloor((self.contentView.frame.size.height - frame.size.height) / 2);\n  frame.origin.x = self.contentView.frame.size.width - frame.size.width - kDatePickerTextFieldRightMargin;\n  _dateField.frame = frame;\n  self.dumbDateField.frame = _dateField.frame;\n  \n  frame = self.textLabel.frame;\n  CGFloat leftEdge = 0;\n  // Take into account the size of the image view.\n  if (nil != self.imageView.image) {\n    leftEdge = self.imageView.frame.size.width + kImageViewRightMargin;\n  }\n  frame.size.width = (self.contentView.frame.size.width\n                      - contentFrame.origin.x\n                      - _dateField.frame.size.width\n                      - _dateField.frame.origin.y\n                      - leftEdge);\n  self.textLabel.frame = frame;\n}\n\n- (void)prepareForReuse {\n  [super prepareForReuse];\n  \n  self.textLabel.text = nil;\n  _dateField.text = nil;\n}\n\n- (BOOL)shouldUpdateCellWithObject:(NIDatePickerFormElement *)datePickerElement {\n  if ([super shouldUpdateCellWithObject:datePickerElement]) {\n    self.textLabel.text = datePickerElement.labelText;\n    self.datePicker.datePickerMode = datePickerElement.datePickerMode;\n    self.datePicker.date = datePickerElement.date;\n    \n    switch (self.datePicker.datePickerMode) {\n      case UIDatePickerModeDate:\n        self.dateField.text = [NSDateFormatter localizedStringFromDate:self.datePicker.date \n                                                             dateStyle:NSDateFormatterShortStyle \n                                                             timeStyle:NSDateFormatterNoStyle];\n        break;\n        \n      case UIDatePickerModeTime:\n        self.dateField.text = [NSDateFormatter localizedStringFromDate:self.datePicker.date \n                                                             dateStyle:NSDateFormatterNoStyle \n                                                             timeStyle:NSDateFormatterShortStyle];\n        break;\n        \n      case UIDatePickerModeCountDownTimer:\n        if (self.datePicker.countDownDuration == 0) {\n          self.dateField.text = NSLocalizedString(@\"0 minutes\", @\"0 minutes\");\n        } else {\n          int hours = (int)(self.datePicker.countDownDuration / 3600);\n          int minutes = (int)((self.datePicker.countDownDuration - hours * 3600) / 60);\n          \n          self.dateField.text = [NSString stringWithFormat:\n                                 NSLocalizedString(@\"%d hours, %d min\", \n                                                   @\"datepicker countdown hours and minutes\"), \n                                 hours, \n                                 minutes];\n        }\n        break;\n        \n      case UIDatePickerModeDateAndTime:\n      default:\n        self.dateField.text = [NSDateFormatter localizedStringFromDate:self.datePicker.date \n                                                             dateStyle:NSDateFormatterShortStyle \n                                                             timeStyle:NSDateFormatterShortStyle];\n        break;\n    }\n\n    self.dumbDateField.text = self.dateField.text;\n    \n    _dateField.tag = self.tag;\n    \n    _datePicker.date = datePickerElement.date;\n    _datePicker.tag = self.tag;\n    \n    [self setNeedsLayout];\n    return YES;\n  }\n  return NO;\n}\n\n- (void)selectedDateDidChange {\n  switch (self.datePicker.datePickerMode) {\n    case UIDatePickerModeDate:\n      self.dateField.text = [NSDateFormatter localizedStringFromDate:_datePicker.date \n                                                           dateStyle:NSDateFormatterShortStyle \n                                                           timeStyle:NSDateFormatterNoStyle];\n      break;\n      \n    case UIDatePickerModeTime:\n      self.dateField.text = [NSDateFormatter localizedStringFromDate:_datePicker.date \n                                                           dateStyle:NSDateFormatterNoStyle \n                                                           timeStyle:NSDateFormatterShortStyle];\n      break;\n      \n    case UIDatePickerModeCountDownTimer:\n      if (self.datePicker.countDownDuration == 0) {\n        self.dateField.text = NSLocalizedString(@\"0 minutes\", @\"0 minutes\");\n      } else {\n        int hours = (int)(self.datePicker.countDownDuration / 3600);\n        int minutes = (int)((self.datePicker.countDownDuration - hours * 3600) / 60);\n        \n        self.dateField.text = [NSString stringWithFormat:\n                               NSLocalizedString(@\"%d hours, %d min\", \n                                                 @\"datepicker countdown hours and minutes\"), \n                               hours, \n                               minutes];\n      }\n      break;\n      \n    case UIDatePickerModeDateAndTime:\n    default:\n      self.dateField.text = [NSDateFormatter localizedStringFromDate:_datePicker.date \n                                                           dateStyle:NSDateFormatterShortStyle \n                                                           timeStyle:NSDateFormatterShortStyle];\n      break;\n  }\n\n  self.dumbDateField.text = self.dateField.text;\n\n  NIDatePickerFormElement *datePickerElement = (NIDatePickerFormElement *)self.element;\n  datePickerElement.date = _datePicker.date;\n  \n  if (nil != datePickerElement.didChangeSelector && nil != datePickerElement.didChangeTarget\n      && [datePickerElement.didChangeTarget respondsToSelector:datePickerElement.didChangeSelector]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n    [datePickerElement.didChangeTarget performSelector:datePickerElement.didChangeSelector\n                                            withObject:_datePicker];\n#pragma clang diagnostic pop\n  }\n}\n\n- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {\n  self.dumbDateField.delegate = self.dateField.delegate;\n  self.dumbDateField.font = self.dateField.font;\n  self.dumbDateField.minimumFontSize = self.dateField.minimumFontSize;\n  self.dumbDateField.backgroundColor = self.dateField.backgroundColor;\n  self.dumbDateField.adjustsFontSizeToFitWidth = self.dateField.adjustsFontSizeToFitWidth;\n  self.dumbDateField.textAlignment = self.dateField.textAlignment;\n  self.dumbDateField.textColor = self.dateField.textColor;\n\n  textField.hidden = YES;\n  self.dumbDateField.hidden = NO;\n  return YES;\n}\n\n- (void)textFieldDidEndEditing:(UITextField *)textField {\n  textField.hidden = NO;\n  self.dumbDateField.hidden = YES;\n}\n\n- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {\n  return NO;\n}\n\n@end\n\n@implementation NITableViewModel (NIFormElementSearch)\n\n\n- (id)elementWithID:(NSInteger)elementID {\n  for (NITableViewModelSection* section in self.sections) {\n    for (NIFormElement* element in section.rows) {\n      if (![element isKindOfClass:[NIFormElement class]]) {\n        continue;\n      }\n      if (element.elementID == elementID) {\n        return element;\n      }\n    }\n  }\n  return nil;\n}\n\n@end\n"
  },
  {
    "path": "src/models/src/NIMutableTableViewModel+Private.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIMutableTableViewModel.h\"\n#import \"NITableViewModel+Private.h\"\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n@interface NIMutableTableViewModel (Private)\n\n@property (nonatomic, strong) NSMutableArray* sections; // Array of NITableViewModelSection\n@property (nonatomic, strong) NSMutableArray* sectionIndexTitles;\n@property (nonatomic, strong) NSMutableDictionary* sectionPrefixToSectionIndex;\n\n@end\n\n@interface NITableViewModelSection (Mutable)\n\n- (NSMutableArray *)mutableRows;\n\n@end\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/models/src/NIMutableTableViewModel.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NITableViewModel.h\"\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n@class NIMutableTableViewModel;\n\n/**\n * A protocol for NIMutableTableViewModel to handle editing states for objects.\n *\n * @ingroup TableViewModels\n */\n@protocol NIMutableTableViewModelDelegate <NSObject, NITableViewModelDelegate>\n\n@optional\n\n/**\n * Asks the receiver whether the object at the given index path should be editable.\n *\n * If this method is not implemented, the default response is assumed to be NO.\n */\n- (BOOL)tableViewModel:(nonnull NIMutableTableViewModel *)tableViewModel\n         canEditObject:(nonnull id)object\n           atIndexPath:(nonnull NSIndexPath *)indexPath\n           inTableView:(nonnull UITableView *)tableView;\n\n/**\n * Asks the receiver whether the object at the given index path should be moveable.\n *\n * If this method is not implemented, the default response is assumed to be NO.\n */\n- (BOOL)tableViewModel:(nonnull NIMutableTableViewModel *)tableViewModel\n         canMoveObject:(nonnull id)object\n           atIndexPath:(nonnull NSIndexPath *)indexPath\n           inTableView:(nonnull UITableView *)tableView;\n\n/**\n * Asks the receiver whether the given object should be moved.\n *\n * If this method is not implemented, the default response is assumed to be YES.\n *\n * Returning NO will stop the model from handling the move logic.\n */\n- (BOOL)tableViewModel:(nonnull NIMutableTableViewModel *)tableViewModel\n      shouldMoveObject:(nonnull id)object\n           atIndexPath:(nonnull NSIndexPath *)indexPath\n           toIndexPath:(nonnull NSIndexPath *)toIndexPath\n           inTableView:(nonnull UITableView *)tableView;\n\n/**\n * Asks the receiver what animation should be used when deleting the object at the given index path.\n *\n * If this method is not implemented, the default response is assumed to be\n * UITableViewRowAnimationAutomatic.\n */\n- (UITableViewRowAnimation)tableViewModel:(nonnull NIMutableTableViewModel *)tableViewModel\n              deleteRowAnimationForObject:(nonnull id)object\n                              atIndexPath:(nonnull NSIndexPath *)indexPath\n                              inTableView:(nonnull UITableView *)tableView;\n\n/**\n * Asks the receiver whether the given object should be deleted.\n *\n * If this method is not implemented, the default response is assumed to be YES.\n *\n * Returning NO will stop the model from handling the deletion logic. This is a good opportunity for\n * you to show a UIAlertView or similar feedback prompt to the user before initiating the deletion\n * yourself.\n *\n * If you implement the deletion of the object yourself, your code may resemble the following:\n@code\nNSArray *indexPaths = [self removeObjectAtIndexPath:indexPath];\n[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];\n@endcode\n */\n- (BOOL)tableViewModel:(nonnull NIMutableTableViewModel *)tableViewModel\n    shouldDeleteObject:(nonnull id)object\n           atIndexPath:(nonnull NSIndexPath *)indexPath\n           inTableView:(nonnull UITableView *)tableView;\n\n@end\n\n/**\n * The NIMutableTableViewModel class is a mutable table view model.\n *\n * When modifications are made to the model there are two ways to reflect the changes in the table\n * view.\n *\n * - Call reloadData on the table view. This is the most destructive way to update the table view.\n * - Call insert/delete/reload methods on the table view with the retuned index path arrays.\n *\n * The latter option is the recommended approach to adding new cells to a table view. Each method in\n * the mutable table view model returns a data structure that can be used to inform the table view\n * of the exact modifications that have been made to the model.\n *\n * Example of adding a new section:\n@code\n// Appends a new section to the end of the model.\nNSIndexSet* indexSet = [self.model addSectionWithTitle:@\"New section\"];\n\n// Appends a cell to the last section in the model (in this case, the new section we just created).\n[self.model addObject:[NITitleCellObject objectWithTitle:@\"A cell\"]];\n\n// Inform the table view that we've modified the model.\n[self.tableView insertSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];\n@endcode\n *\n * @ingroup TableViewModels\n */\n@interface NIMutableTableViewModel : NITableViewModel\n\n- (nonnull NSArray *)addObject:(nonnull id)object;\n- (nonnull NSArray *)addObject:(nonnull id)object toSection:(NSUInteger)section;\n- (nonnull NSArray *)addObjectsFromArray:(nonnull NSArray *)array;\n- (nonnull NSArray *)insertObject:(nonnull id)object atRow:(NSUInteger)row inSection:(NSUInteger)section;\n- (nonnull NSArray *)removeObjectAtIndexPath:(nonnull NSIndexPath *)indexPath;\n\n- (nonnull NSIndexSet *)addSectionWithTitle:(nonnull NSString *)title;\n- (nonnull NSIndexSet *)insertSectionWithTitle:(nonnull NSString *)title atIndex:(NSUInteger)index;\n- (nonnull NSIndexSet *)removeSectionAtIndex:(NSUInteger)index;\n\n- (void)updateSectionIndex;\n\n@property (nonatomic, weak, nullable) id<NIMutableTableViewModelDelegate> delegate;\n\n@end\n\n/** @name Modifying Objects */\n\n/**\n * Appends an object to the last section.\n *\n * If no sections exist, a section will be created without a title and the object will be added to\n * this new section.\n *\n * @param object The object to append to the last section.\n * @returns An array with a single NSIndexPath representing the index path of the new object\n *               in the model.\n * @fn NIMutableTableViewModel::addObject:\n */\n\n/**\n * Appends an object to the end of the given section.\n *\n * @param object The object to append to the section.\n * @param section The index of the section to which this object should be appended.\n * @returns An array with a single NSIndexPath representing the index path of the new object\n *               in the model.\n * @fn NIMutableTableViewModel::addObject:toSection:\n */\n\n/**\n * Appends an array of objects to the last section.\n *\n * If no section exists, a section will be created without a title and the objects will be added to\n * this new section.\n *\n * @param array The array of objects to append to the last section.\n * @returns An array of NSIndexPath objects representing the index paths of the objects in the\n *               model.\n * @fn NIMutableTableViewModel::addObjectsFromArray:\n */\n\n/**\n * Inserts an object into the given section at the given row.\n *\n * @param object The object to append to the section.\n * @param row The row within the section at which to insert the object.\n * @param section The index of the section in which the object should be inserted.\n * @returns An array with a single NSIndexPath representing the index path of the new object\n *               in the model.\n * @fn NIMutableTableViewModel::insertObject:atRow:inSection:\n */\n\n/**\n * Removes an object at the given index path.\n *\n * If the index path does not represent a valid object then a debug assertion will fire and the\n * method will return nil without removing any object.\n *\n * @param indexPath The index path at which to remove a single object.\n * @returns An array with a single NSIndexPath representing the index path of the object that\n *               was removed from the model, or nil if no object exists at the given index path.\n * @fn NIMutableTableViewModel::removeObjectAtIndexPath:\n */\n\n/** @name Modifying Sections */\n\n/**\n * Appends a section with a given title to the model.\n *\n * @param title The title of the new section.\n * @returns An index set with a single index representing the index of the new section.\n * @fn NIMutableTableViewModel::addSectionWithTitle:\n */\n\n/**\n * Inserts a section with a given title to the model at the given index.\n *\n * @param title The title of the new section.\n * @param index The index in the model at which to add the new section.\n * @returns An index set with a single index representing the index of the new section.\n * @fn NIMutableTableViewModel::insertSectionWithTitle:atIndex:\n */\n\n/**\n * Removes a section at the given index.\n *\n * @param index The index in the model of the section to remove.\n * @returns An index set with a single index representing the index of the removed section.\n * @fn NIMutableTableViewModel::removeSectionAtIndex:\n */\n\n/** @name Updating the Section Index */\n\n/**\n * Updates the section index with the current section index settings.\n *\n * This method should be called after modifying the model if a section index is being used.\n *\n * @fn NIMutableTableViewModel::updateSectionIndex\n */\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/models/src/NIMutableTableViewModel.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIMutableTableViewModel.h\"\n\n#import \"NITableViewModel+Private.h\"\n#import \"NIMutableTableViewModel+Private.h\"\n#import \"NimbusCore.h\"\n\n\n@implementation NIMutableTableViewModel\n\n@dynamic delegate;\n\n#pragma mark - Public\n\n\n- (NSArray *)addObject:(id)object {\n  NITableViewModelSection* section = self.sections.count == 0 ? [self _appendSection] : self.sections.lastObject;\n  [section.mutableRows addObject:object];\n  return [NSArray arrayWithObject:[NSIndexPath indexPathForRow:section.mutableRows.count - 1\n                                                     inSection:self.sections.count - 1]];\n}\n\n- (NSArray *)addObject:(id)object toSection:(NSUInteger)sectionIndex {\n  NIDASSERT(sectionIndex >= 0 && sectionIndex < self.sections.count);\n  NITableViewModelSection *section = [self.sections objectAtIndex:sectionIndex];\n  [section.mutableRows addObject:object];\n  return [NSArray arrayWithObject:[NSIndexPath indexPathForRow:section.mutableRows.count - 1\n                                                     inSection:sectionIndex]];\n}\n\n- (NSArray *)addObjectsFromArray:(NSArray *)array {\n  NSMutableArray* indices = [NSMutableArray array];\n  for (id object in array) {\n    [indices addObject:[[self addObject:object] objectAtIndex:0]];\n  }\n  return indices;\n}\n\n- (NSArray *)insertObject:(id)object atRow:(NSUInteger)row inSection:(NSUInteger)sectionIndex {\n  NIDASSERT(sectionIndex >= 0 && sectionIndex < self.sections.count);\n  NITableViewModelSection *section = [self.sections objectAtIndex:sectionIndex];\n  [section.mutableRows insertObject:object atIndex:row];\n  return [NSArray arrayWithObject:[NSIndexPath indexPathForRow:row inSection:sectionIndex]];\n}\n\n- (NSArray *)removeObjectAtIndexPath:(NSIndexPath *)indexPath {\n  NIDASSERT(indexPath.section < (NSInteger)self.sections.count);\n  if (indexPath.section >= (NSInteger)self.sections.count) {\n    return nil;\n  }\n  NITableViewModelSection* section = [self.sections objectAtIndex:indexPath.section];\n  NIDASSERT(indexPath.row < (NSInteger)section.mutableRows.count);\n  if (indexPath.row >= (NSInteger)section.mutableRows.count) {\n    return nil;\n  }\n  [section.mutableRows removeObjectAtIndex:indexPath.row];\n  return [NSArray arrayWithObject:indexPath];\n}\n\n- (NSIndexSet *)addSectionWithTitle:(NSString *)title {\n  NITableViewModelSection* section = [self _appendSection];\n  section.headerTitle = title;\n  return [NSIndexSet indexSetWithIndex:self.sections.count - 1];\n}\n\n- (NSIndexSet *)insertSectionWithTitle:(NSString *)title atIndex:(NSUInteger)index {\n  NITableViewModelSection* section = [self _insertSectionAtIndex:index];\n  section.headerTitle = title;\n  return [NSIndexSet indexSetWithIndex:index];\n}\n\n- (NSIndexSet *)removeSectionAtIndex:(NSUInteger)index {\n  NIDASSERT(index >= 0 && index < self.sections.count);\n  [self.sections removeObjectAtIndex:index];\n  return [NSIndexSet indexSetWithIndex:index];\n}\n\n- (void)updateSectionIndex {\n  [self _compileSectionIndex];\n}\n\n#pragma mark - Private\n\n\n- (NITableViewModelSection *)_appendSection {\n  if (nil == self.sections) {\n    [self _setSectionsWithArray:[NSMutableArray array]];\n  }\n  NITableViewModelSection* section = nil;\n  section = [[NITableViewModelSection alloc] init];\n  section.rows = [NSMutableArray array];\n  [self.sections addObject:section];\n  return section;\n}\n\n- (NITableViewModelSection *)_insertSectionAtIndex:(NSUInteger)index {\n  if (nil == self.sections) {\n    [self _setSectionsWithArray:[NSMutableArray array]];\n  }\n  NITableViewModelSection* section = nil;\n  section = [[NITableViewModelSection alloc] init];\n  section.rows = [NSMutableArray array];\n  NIDASSERT(index >= 0 && index <= self.sections.count);\n  [self.sections insertObject:section atIndex:index];\n  return section;\n}\n\n- (void)_setSectionsWithArray:(NSArray *)sectionsArray {\n  if ([sectionsArray isKindOfClass:[NSMutableArray class]]) {\n    self.sections = (NSMutableArray *)sectionsArray;\n  } else {\n    self.sections = [sectionsArray mutableCopy];\n  }\n}\n\n#pragma mark - UITableViewDataSource\n\n\n- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {\n  if ([self.delegate respondsToSelector:@selector(tableViewModel:canEditObject:atIndexPath:inTableView:)]) {\n    id object = [self objectAtIndexPath:indexPath];\n    return [self.delegate tableViewModel:self canEditObject:object atIndexPath:indexPath inTableView:tableView];\n  } else {\n    return NO;\n  }\n}\n\n- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {\n  id object = [self objectAtIndexPath:indexPath];\n  if (editingStyle == UITableViewCellEditingStyleDelete) {\n    BOOL shouldDelete = YES;\n    if ([self.delegate respondsToSelector:@selector(tableViewModel:shouldDeleteObject:atIndexPath:inTableView:)]) {\n      shouldDelete = [self.delegate tableViewModel:self shouldDeleteObject:object atIndexPath:indexPath inTableView:tableView];\n    }\n    if (shouldDelete) {\n      NSArray *indexPaths = [self removeObjectAtIndexPath:indexPath];\n      UITableViewRowAnimation animation = UITableViewRowAnimationAutomatic;\n      if ([self.delegate respondsToSelector:@selector(tableViewModel:deleteRowAnimationForObject:atIndexPath:inTableView:)]) {\n        animation = [self.delegate tableViewModel:self deleteRowAnimationForObject:object atIndexPath:indexPath inTableView:tableView];\n      }\n      [tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation];\n    }\n  }\n}\n\n- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {\n  if ([self.delegate respondsToSelector:@selector(tableViewModel:canMoveObject:atIndexPath:inTableView:)]) {\n    id object = [self objectAtIndexPath:indexPath];\n    return [self.delegate tableViewModel:self canMoveObject:object atIndexPath:indexPath inTableView:tableView];\n  } else {\n    return NO;\n  }\n}\n\n- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {\n  id object = [self objectAtIndexPath:sourceIndexPath];\n  BOOL shouldMove = YES;\n  if ([self.delegate respondsToSelector:@selector(tableViewModel:shouldMoveObject:atIndexPath:toIndexPath:inTableView:)]) {\n    shouldMove = [self.delegate tableViewModel:self shouldMoveObject:object atIndexPath:sourceIndexPath toIndexPath:destinationIndexPath inTableView:tableView];\n  }\n  if (shouldMove) {\n    [self removeObjectAtIndexPath:sourceIndexPath];\n    [self insertObject:object atRow:destinationIndexPath.row inSection:destinationIndexPath.section];\n  }\n}\n\n@end\n\n\n@implementation NITableViewModelSection (Mutable)\n\n\n- (NSMutableArray *)mutableRows {\n  NIDASSERT([self.rows isKindOfClass:[NSMutableArray class]] || nil == self.rows);\n    \n  self.rows = nil == self.rows ? [NSMutableArray array] : self.rows;\n  return (NSMutableArray *)self.rows;\n}\n\n@end\n"
  },
  {
    "path": "src/models/src/NIRadioGroup.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NICellFactory.h\"\n\n@protocol NIRadioGroupDelegate;\n@class NIRadioGroupController;\n\n/**\n * A general-purpose radio group.\n *\n * This group object manages radio-style selection of objects. Only one object may be selected at\n * a time.\n *\n * Due to the general-purpose nature of this object, it can be used with UITableViews or any other\n * view that has sets of objects being displayed. This object can insert itself into a\n * UITableViewDelegate call chain to minimize the amount of code that needs to be written in your\n * controller.\n *\n * If you add a NIRadioGroup object to a NITableViewModel, it will show a cell that displays the\n * current radio group selection. This cell is also tappable. Tapping this cell will push a\n * controller onto the navigation stack that presents the radio group options for the user to\n * select. The radio group delegate is notified immediately when a selection is made and the\n * tapped cell is also updated to reflect the new selection.\n *\n * @ingroup ModelTools\n */\n@interface NIRadioGroup : NSObject <NICellObject, UITableViewDelegate>\n\n// Designated initializer.\n- (id)initWithController:(UIViewController *)controller;\n\n@property (nonatomic, weak) id<NIRadioGroupDelegate> delegate;\n\n#pragma mark Mapping Objects\n\n- (id)mapObject:(id)object toIdentifier:(NSInteger)identifier;\n\n#pragma mark Selection\n\n- (BOOL)hasSelection;\n@property (nonatomic, assign) NSInteger selectedIdentifier;\n- (void)clearSelection;\n\n#pragma mark Object State\n\n- (BOOL)isObjectInRadioGroup:(id)object;\n- (BOOL)isObjectSelected:(id)object;\n- (NSInteger)identifierForObject:(id)object;\n\n#pragma mark Forwarding\n\n@property (nonatomic, assign) UITableViewCellSelectionStyle tableViewCellSelectionStyle;\n- (id<UITableViewDelegate>)forwardingTo:(id<UITableViewDelegate>)forwardDelegate;\n- (void)removeForwarding:(id<UITableViewDelegate>)forwardDelegate;\n\n#pragma mark Sub Radio Groups\n\n@property (nonatomic, copy) NSString* cellTitle;\n@property (nonatomic, copy) NSString* controllerTitle;\n- (NSArray *)allObjects;\n\n@end\n\n/**\n * The delegate for NIRadioGroup.\n *\n * @ingroup ModelTools\n */\n@protocol NIRadioGroupDelegate <NSObject>\n@required\n\n/**\n * Called when the user changes the radio group selection.\n *\n * @param radioGroup The radio group object.\n * @param identifier The newly selected identifier.\n */\n- (void)radioGroup:(NIRadioGroup *)radioGroup didSelectIdentifier:(NSInteger)identifier;\n\n@optional\n\n/**\n * Fetches the text that will be displayed in a radio group cell for the current selection.\n *\n * This is only used when the radio group is added to a table view as a sub radio group.\n */\n- (NSString *)radioGroup:(NIRadioGroup *)radioGroup textForIdentifier:(NSInteger)identifier;\n\n/**\n * The radio group controller is about to appear.\n *\n * This method provides a customization point for the radio group view controller.\n *\n * @return YES if controller should be pushed onto the current navigation stack.\n *              NO if you are going to present the controller yourself.\n */\n- (BOOL)radioGroup:(NIRadioGroup *)radioGroup radioGroupController:(NIRadioGroupController *)radioGroupController willAppear:(BOOL)animated;\n\n@end\n\n/**\n * The cell that is displayed for a NIRadioGroup object when it is displayed in a UITableView.\n *\n * This class is exposed publicly so that you may subclass it and customize the way it displays\n * its information. You can override the cell class that the radio group uses in two ways:\n *\n * 1. Subclass NIRadioGroup and return a different cell class in -cellClass.\n * 2. Create a NICellFactory and map NIRadioGroup to a different cell class and then use this\n *    factory for your model in your table view controller.\n *\n * By default this cell displays the cellTitle property of the radio group on the left and the\n * text retrieved from the radio group delegate's radioGroup:textForIdentifier: method on the right.\n */\n@interface NIRadioGroupCell : UITableViewCell <NICell>\n@end\n\n/** @name Creating Radio Groups */\n\n/**\n * Initializes a newly allocated radio group object with the given controller.\n *\n * This is the designated initializer.\n *\n * The given controller is stored as a weak reference internally.\n *\n * @param controller The controller that will be used when this object is used as a sub radio\n *                        group.\n * @fn NIRadioGroup::initWithController:\n */\n\n/** @name Mapping Objects */\n\n/**\n * Maps the given object to the given identifier.\n *\n * The identifier will be used in all subsequent operations and is a means of abstracting away\n * the objects. The identifier range does not have to be sequential. The only reserved value is\n * NSIntegerMin, which is used to signify that no selection exists.\n *\n * You can NOT map the same object to multiple identifiers. Attempts to do so fill fire a debug\n * assertion and will not map the new object in the radio group.\n *\n * @param object The object to map to the identifier.\n * @param identifier The identifier that will represent the object.\n * @returns The object that was mapped.\n * @fn NIRadioGroup::mapObject:toIdentifier:\n */\n\n/** @name Selection */\n\n/**\n * Whether or not a selection has been made.\n *\n * @fn NIRadioGroup::hasSelection\n */\n\n/**\n * The currently selected identifier if one is selected, otherwise returns NSIntegerMin.\n *\n * @fn NIRadioGroup::selectedIdentifier\n */\n\n/**\n * Removes the selection from this cell group.\n *\n * @fn NIRadioGroup::clearSelection\n */\n\n/** @name Object State */\n\n/**\n * Returns YES if the given object is in this radio group.\n *\n * @fn NIRadioGroup::isObjectInRadioGroup:\n */\n\n/**\n * Returns YES if the given object is selected.\n *\n * This method should only be called after verifying that the object is contained within the radio\n * group with isObjectInRadioGroup:.\n *\n * @fn NIRadioGroup::isObjectSelected:\n */\n\n/**\n * Returns the mapped identifier for this object.\n *\n * This method should only be called after verifying that the object is contained within the radio\n * group with isObjectInRadioGroup:.\n *\n * @fn NIRadioGroup::identifierForObject:\n */\n\n/** @name Forwarding */\n\n/**\n * The cell selection style that will be applied to the cell when it is displayed using\n * delegate forwarding.\n *\n * By default this is UITableViewCellSelectionStyleBlue.\n *\n * @fn NIRadioGroup::tableViewCellSelectionStyle\n */\n\n/**\n * Sets the delegate that table view methods should be forwarded to.\n *\n * This method allows you to insert the radio group into the call chain for the table view's\n * delegate methods.\n *\n * Example:\n *\n@code\n// Let the radio group handle delegate methods and then forward them to whatever delegate was\n// already assigned.\nself.tableView.delegate = [self.radioGroup forwardingTo:self.tableView.delegate];\n@endcode\n *\n * @param forwardDelegate The delegate to forward invocations to.\n * @returns self so that this method can be chained.\n * @fn NIRadioGroup::forwardingTo:\n */\n\n/**\n * Removes the delegate from the forwarding chain.\n *\n * If a forwared delegate is about to be released but this object may live on, you must remove the\n * forwarding in order to avoid invalid access errors at runtime.\n *\n * @param forwardDelegate The delegate to stop forwarding invocations to.\n * @fn NIRadioGroup::removeForwarding:\n */\n\n/**\n * The title of the cell that is displayed for a radio group in a UITableView.\n *\n * @fn NIRadioGroup::cellTitle\n */\n\n/**\n * The title of the controller that shows the sub radio group selection.\n *\n * @fn NIRadioGroup::controllerTitle\n */\n\n/**\n * An array of mapped objects in this radio group, ordered in the same order they were mapped.\n *\n * This is used primarily by NIRadioGroupController to display the radio group options.\n *\n * @fn NIRadioGroup::allObjects\n */\n"
  },
  {
    "path": "src/models/src/NIRadioGroup.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIRadioGroup.h\"\n\n#import \"NIRadioGroupController.h\"\n#import \"NITableViewModel.h\"\n#import \"NimbusCore.h\"\n#import <objc/runtime.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic const NSInteger kInvalidSelection = NSIntegerMin;\n\n@interface NIRadioGroup()\n@property (nonatomic, readonly, weak) UIViewController* controller;\n@property (nonatomic, readonly, strong) NSMutableDictionary* objectMap;\n@property (nonatomic, readonly, strong) NSMutableSet* objectSet;\n@property (nonatomic, readonly, strong) NSMutableArray* objectOrder;\n@property (nonatomic, assign) BOOL hasSelection;\n@property (nonatomic, readonly, strong) NSMutableSet* forwardDelegates;\n@end\n\n@implementation NIRadioGroup\n\n@synthesize selectedIdentifier = _selectedIdentifier;\n\n- (id)initWithController:(UIViewController *)controller {\n  if ((self = [super init])) {\n    _controller = controller;\n    _objectMap = [[NSMutableDictionary alloc] init];\n    _objectSet = [[NSMutableSet alloc] init];\n    _objectOrder = [[NSMutableArray alloc] init];\n    _forwardDelegates = NICreateNonRetainingMutableSet();\n\n    _tableViewCellSelectionStyle = UITableViewCellSelectionStyleBlue;\n  }\n  return self;\n}\n\n- (id)init {\n  return [self initWithController:nil];\n}\n\n#pragma mark - Private\n\n\n- (id)keyForIdentifier:(NSInteger)identifier {\n  return [NSNumber numberWithInteger:identifier];\n}\n\n#pragma mark - NICellObject\n\n\n- (Class)cellClass {\n  return [NIRadioGroupCell class];\n}\n\n- (UITableViewCellStyle)cellStyle {\n  return UITableViewCellStyleValue1;\n}\n\n#pragma mark - Forward Invocations\n\n\n- (BOOL)shouldForwardSelector:(SEL)selector {\n  struct objc_method_description description;\n  description = protocol_getMethodDescription(@protocol(UITableViewDelegate), selector, NO, YES);\n  return (description.name != NULL && description.types != NULL);\n}\n\n- (BOOL)respondsToSelector:(SEL)selector {\n  if ([super respondsToSelector:selector]) {\n    return YES;\n    \n  } else if ([self shouldForwardSelector:selector]) {\n    for (id delegate in self.forwardDelegates) {\n      if ([delegate respondsToSelector:selector]) {\n        return YES;\n      }\n    }\n  }\n  return NO;\n}\n\n- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {\n  NSMethodSignature *signature = [super methodSignatureForSelector:selector];\n  if (signature == nil) {\n    for (id delegate in self.forwardDelegates) {\n      if ([delegate respondsToSelector:selector]) {\n        signature = [delegate methodSignatureForSelector:selector];\n      }\n    }\n  }\n  return signature;\n}\n\n- (void)forwardInvocation:(NSInvocation *)invocation {\n  BOOL didForward = NO;\n\n  if ([self shouldForwardSelector:invocation.selector]) {\n    for (id delegate in self.forwardDelegates) {\n      if ([delegate respondsToSelector:invocation.selector]) {\n        [invocation invokeWithTarget:delegate];\n        didForward = YES;\n        break;\n      }\n    }\n  }\n\n  if (!didForward) {\n    [super forwardInvocation:invocation];\n  }\n}\n\n- (id<UITableViewDelegate>)forwardingTo:(id<UITableViewDelegate>)forwardDelegate {\n  [self.forwardDelegates addObject:forwardDelegate];\n  return self;\n}\n\n- (void)removeForwarding:(id<UITableViewDelegate>)forwardDelegate {\n  [self.forwardDelegates removeObject:forwardDelegate];\n}\n\n#pragma mark - Public\n\n\n- (id)mapObject:(id)object toIdentifier:(NSInteger)identifier {\n  NIDASSERT(nil != object);\n  NIDASSERT(identifier != kInvalidSelection);\n  NIDASSERT(![self isObjectInRadioGroup:object]);\n  if (nil == object) {\n    return nil;\n  }\n  if (kInvalidSelection == identifier) {\n    return nil;\n  }\n  if ([self isObjectInRadioGroup:object]) {\n    return nil;\n  }\n  [self.objectMap setObject:object forKey:[self keyForIdentifier:identifier]];\n  [self.objectSet addObject:object];\n  [self.objectOrder addObject:object];\n  return object;\n}\n\n- (void)setSelectedIdentifier:(NSInteger)selectedIdentifier {\n  id key = [self keyForIdentifier:selectedIdentifier];\n  NIDASSERT(nil != [self.objectMap objectForKey:key]);\n  if (nil != [self.objectMap objectForKey:key]) {\n    _selectedIdentifier = selectedIdentifier;\n    self.hasSelection = YES;\n  } else {\n    // If we set an invalid identifier then clear the current selection.\n    self.hasSelection = NO;\n  }\n}\n\n- (NSInteger)selectedIdentifier {\n  return self.hasSelection ? _selectedIdentifier : kInvalidSelection;\n}\n\n- (void)clearSelection {\n  self.hasSelection = NO;\n}\n\n- (BOOL)isObjectInRadioGroup:(id)object {\n  if (nil == object) {\n    return NO;\n  }\n  return [self.objectSet containsObject:object];\n}\n\n- (BOOL)isObjectSelected:(id)object {\n  if (nil == object) {\n    return NO;\n  }\n  NIDASSERT(nil != object);\n  NIDASSERT([self isObjectInRadioGroup:object]);\n  NSArray* keys = [self.objectMap allKeysForObject:object];\n  NSInteger selectedIdentifier = self.selectedIdentifier;\n  for (NSNumber* key in keys) {\n    if ([key intValue] == selectedIdentifier) {\n      return YES;\n    }\n  }\n  return NO;\n}\n\n- (NSInteger)identifierForObject:(id)object {\n  if (nil == object) {\n    return NO;\n  }\n  NIDASSERT(nil != object);\n  NIDASSERT([self isObjectInRadioGroup:object]);\n  NSArray* keys = [self.objectMap allKeysForObject:object];\n  return keys.count > 0 ? [[keys objectAtIndex:0] intValue] : kInvalidSelection;\n}\n\n- (NSArray *)allObjects {\n  return [self.objectOrder copy];\n}\n\n#pragma mark - UITableViewDelegate\n\n\n- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {\n  NIDASSERT([tableView.dataSource isKindOfClass:[NITableViewModel class]]);\n  if ([tableView.dataSource isKindOfClass:[NITableViewModel class]]) {\n    NITableViewModel* model = (NITableViewModel *)tableView.dataSource;\n    id object = [model objectAtIndexPath:indexPath];\n    if ([self isObjectInRadioGroup:object]) {\n      cell.accessoryType = ([self isObjectSelected:object]\n                            ? UITableViewCellAccessoryCheckmark\n                            : UITableViewCellAccessoryNone);\n      cell.selectionStyle = self.tableViewCellSelectionStyle;\n    }\n  }\n\n  // Forward the invocation along.\n  for (id<UITableViewDelegate> delegate in self.forwardDelegates) {\n    if ([delegate respondsToSelector:_cmd]) {\n      [delegate tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath];\n    }\n  }\n}\n\n- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {\n  NIDASSERT([tableView.dataSource isKindOfClass:[NITableViewModel class]]);\n  if ([tableView.dataSource isKindOfClass:[NITableViewModel class]]) {\n    NITableViewModel* model = (NITableViewModel *)tableView.dataSource;\n    id object = [model objectAtIndexPath:indexPath];\n\n    if (object == self) {\n      // You must provide a controller in the initWithController: initializer.\n      NIDASSERT(nil != self.controller);\n\n      NIRadioGroupController* controller = [[NIRadioGroupController alloc] initWithRadioGroup:self tappedCell:(id<NICell>)[tableView cellForRowAtIndexPath:indexPath]];\n      controller.title = self.controllerTitle;\n\n      BOOL shouldPush = YES;\n      // Notify the delegate that the controller is about to appear.\n      if ([self.delegate respondsToSelector:@selector(radioGroup:radioGroupController:willAppear:)]) {\n        shouldPush = [self.delegate radioGroup:self radioGroupController:controller willAppear:YES];\n      }\n\n      if (shouldPush) {\n        [self.controller.navigationController pushViewController:controller animated:YES];\n      }\n\n    } else if ([self isObjectInRadioGroup:object]) {\n      NSInteger newSelection = [self identifierForObject:object];\n\n      if (newSelection != self.selectedIdentifier) {\n        [self setSelectedIdentifier:newSelection];\n\n        // It's easiest to simply reload the visible table cells. Reloading only the radio group\n        // cells would require iterating through the visible cell objects and determining whether\n        // each was in the radio group. This is more complex behavior that should be relegated to\n        // the controller.\n        [tableView reloadRowsAtIndexPaths:tableView.indexPathsForVisibleRows\n                         withRowAnimation:UITableViewRowAnimationNone];\n\n        // After we reload the table view the selection will be lost, so set the selection again.\n        [tableView selectRowAtIndexPath:indexPath\n                               animated:NO\n                         scrollPosition:UITableViewScrollPositionNone];\n\n        [self.delegate radioGroup:self didSelectIdentifier:newSelection];\n      }\n\n      // Fade the selection out.\n      [tableView deselectRowAtIndexPath:indexPath animated:YES];\n    }\n  }\n\n  // Forward the invocation along.\n  for (id<UITableViewDelegate> delegate in self.forwardDelegates) {\n    if ([delegate respondsToSelector:_cmd]) {\n      [delegate tableView:tableView didSelectRowAtIndexPath:indexPath];\n    }\n  }\n}\n\n@end\n\n\n@implementation NIRadioGroupCell\n\n\n- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {\n  if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {\n    self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;\n  }\n  return self;\n}\n\n- (void)prepareForReuse {\n  [super prepareForReuse];\n\n  self.textLabel.text = nil;\n  self.detailTextLabel.text = nil;\n}\n\n- (BOOL)shouldUpdateCellWithObject:(NIRadioGroup *)radioGroup {\n  self.selectionStyle = radioGroup.tableViewCellSelectionStyle;\n\n  // You should provide a cell title for the radio group.\n  NIDASSERT(NIIsStringWithAnyText(radioGroup.cellTitle));\n  self.textLabel.text = radioGroup.cellTitle;\n\n  if ([radioGroup.delegate respondsToSelector:@selector(radioGroup:textForIdentifier:)]) {\n    self.detailTextLabel.text = [radioGroup.delegate radioGroup:radioGroup\n                                              textForIdentifier:radioGroup.selectedIdentifier];\n  }\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "src/models/src/NIRadioGroupController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NIRadioGroup;\n@protocol NICell;\n\n/**\n * A controller that displays the set of options in a radio group.\n *\n * This controller is instantiated and pushed onto the navigation stack when the user taps a radio\n * group cell.\n *\n * @ingroup ModelTools\n */\n@interface NIRadioGroupController : UITableViewController\n\n// Designated initializer.\n- (id)initWithRadioGroup:(NIRadioGroup *)radioGroup tappedCell:(id<NICell>)tappedCell;\n\n@end\n\n/**\n * Initializes a newly allocated radio group controller with the given radio group and cell.\n *\n * The radio group and cell are strongly referenced for the lifetime of this controller.\n *\n * @fn NIRadioGroupController::initWithRadioGroup:tappedCell:\n */\n"
  },
  {
    "path": "src/models/src/NIRadioGroupController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIRadioGroupController.h\"\n\n#import \"NICellFactory.h\"\n#import \"NIRadioGroup.h\"\n#import \"NISDKAvailability.h\"\n#import \"NITableViewModel.h\"\n\n#import \"NIDebuggingTools.h\"\n#import \"NIDeviceOrientation.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NIRadioGroupController ()\n@property (nonatomic, readonly, strong) NIRadioGroup* radioGroup;\n@property (nonatomic, readonly, strong) id<NICell> tappedCell;\n@property (nonatomic, readonly, strong) NITableViewModel* model;\n@end\n\n\n@implementation NIRadioGroupController\n\n\n\n- (void)dealloc {\n  [_radioGroup removeForwarding:self];\n}\n\n- (id)initWithRadioGroup:(NIRadioGroup *)radioGroup tappedCell:(id<NICell>)tappedCell {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    // A valid radio group must be provided.\n    NIDASSERT(nil != radioGroup);\n    _radioGroup = radioGroup;\n    _tappedCell = tappedCell;\n\n    _model = [[NITableViewModel alloc] initWithListArray:_radioGroup.allObjects\n                                                delegate:(id)[NICellFactory class]];\n  }\n  return self;\n}\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  // Use the initWithRadioGroup initializer.\n  NIDASSERT(NO);\n  return [self initWithRadioGroup:nil tappedCell:nil];\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  self.tableView.dataSource = self.model;\n  self.tableView.delegate = [self.radioGroup forwardingTo:self.tableView.delegate];\n}\n\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {\n  return NIIsSupportedOrientation(toInterfaceOrientation);\n}\n#endif\n\n#if (defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0)\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n#else\n- (NSUInteger)supportedInterfaceOrientations {\n#endif\n  return UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n#pragma mark - UITableViewDelegate\n\n\n- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {\n  [self.tappedCell shouldUpdateCellWithObject:self.radioGroup];\n}\n\n@end\n"
  },
  {
    "path": "src/models/src/NITableViewActions.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NimbusCore.h\"\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n/**\n * The NITableViewActions class provides an interface for attaching actions to objects from a\n * NIActionsDataSource.\n *\n * <h2>Basic Use</h2>\n *\n * NIActionsDataSource and NITableViewActions cooperate to solve two related tasks: data\n * representation and user actions, respectively. A NIActionsDataSource provides objects and\n * NITableViewActions maintains a mapping of actions to these objects. The object's attached actions\n * are executed when the user interacts with the cell representing an object.\n *\n * <h3>Delegate Forwarding</h3>\n *\n * NITableViewActions will apply the correct accessoryType and selectionStyle values to the cell\n * when the cell is displayed using a mechanism known as <i>delegate chaining</i>. This effect is\n * achieved by invoking @link NITableViewActions::forwardingTo: forwardingTo:@endlink on the\n * NITableViewActions instance and providing the appropriate object to forward to (generally\n * @c self).\n *\n@code\ntableView.delegate = [self.actions forwardingTo:self];\n@endcode\n *\n * The dataSource property of the table view must conform to NIActionsDataSource.\n *\n * @ingroup ModelTools\n */\n@interface NITableViewActions : NIActions <UITableViewDelegate>\n\n#pragma mark Forwarding\n\n- (id<UITableViewDelegate>)forwardingTo:(id<UITableViewDelegate>)forwardDelegate;\n- (void)removeForwarding:(id<UITableViewDelegate>)forwardDelegate;\n\n#pragma mark Object state\n\n- (UITableViewCellAccessoryType)accessoryTypeForObject:(id)object;\n- (UITableViewCellSelectionStyle)selectionStyleForObject:(id)object;\n\n#pragma mark Configurable Properties\n\n@property (nonatomic, assign) UITableViewCellSelectionStyle tableViewCellSelectionStyle;\n\n@end\n\n/** @name Forwarding */\n\n/**\n * Sets the delegate that table view methods should be forwarded to.\n *\n * This method allows you to insert the actions into the call chain for the table view's\n * delegate methods.\n *\n * Example:\n *\n@code\n// Let the actions handle delegate methods and then forward them to whatever delegate was\n// already assigned.\nself.tableView.delegate = [self.actions forwardingTo:self.tableView.delegate];\n@endcode\n *\n * @param forwardDelegate The delegate to forward invocations to.\n * @returns self so that this method can be chained.\n * @fn NITableViewActions::forwardingTo:\n */\n\n/**\n * Removes the delegate from the forwarding chain.\n *\n * If a forwared delegate is about to be released but this object may live on, you must remove the\n * forwarding in order to avoid invalid access errors at runtime.\n *\n * @param forwardDelegate The delegate to stop forwarding invocations to.\n * @fn NITableViewActions::removeForwarding:\n */\n\n/** @name Object State */\n\n/**\n * Returns the accessory type this actions object will apply to a cell for the\n * given object when it is displayed.\n *\n * @param object The object to determine the accessory type for.\n * @returns the accessory type this object's cell will have.\n * @fn NITableViewActions::accessoryTypeForObject:\n */\n\n/**\n * Returns the cell selection style this actions object will apply to a cell\n * for the given object when it is displayed.\n *\n * @param object The object to determine the selection style for.\n * @returns the selection style this object's cell will have.\n * @fn NITableViewActions::selectionStyleForObject:\n */\n\n/** @name Configurable Properties */\n\n/**\n * The cell selection style that will be applied to the cell when it is displayed using\n * delegate forwarding.\n *\n * By default this is UITableViewCellSelectionStyleBlue.\n *\n * @fn NITableViewActions::tableViewCellSelectionStyle\n */\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/models/src/NITableViewActions.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NITableViewActions.h\"\n\n#import \"NICellFactory.h\"\n#import \"NimbusCore.h\"\n#import \"NIActions+Subclassing.h\"\n#import <objc/runtime.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NITableViewActions()\n@property (nonatomic, strong) NSMutableSet* forwardDelegates;\n@end\n\n@implementation NITableViewActions\n\n\n\n- (id)initWithTarget:(id)target {\n  if ((self = [super initWithTarget:target])) {\n    _forwardDelegates = NICreateNonRetainingMutableSet();\n    _tableViewCellSelectionStyle = UITableViewCellSelectionStyleBlue;\n  }\n  return self;\n}\n\n#pragma mark - Forward Invocations\n\n\n- (BOOL)shouldForwardSelector:(SEL)selector {\n  struct objc_method_description description;\n  description = protocol_getMethodDescription(@protocol(UITableViewDelegate), selector, NO, YES);\n  return (description.name != NULL && description.types != NULL);\n}\n\n- (BOOL)respondsToSelector:(SEL)selector {\n  if ([super respondsToSelector:selector]) {\n    return YES;\n    \n  } else if ([self shouldForwardSelector:selector]) {\n    for (id delegate in self.forwardDelegates) {\n      if ([delegate respondsToSelector:selector]) {\n        return YES;\n      }\n    }\n  }\n  return NO;\n}\n\n- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {\n  NSMethodSignature *signature = [super methodSignatureForSelector:selector];\n  if (signature == nil) {\n    for (id delegate in self.forwardDelegates) {\n      if ([delegate respondsToSelector:selector]) {\n        signature = [delegate methodSignatureForSelector:selector];\n      }\n    }\n  }\n  return signature;\n}\n\n- (void)forwardInvocation:(NSInvocation *)invocation {\n  BOOL didForward = NO;\n  \n  if ([self shouldForwardSelector:invocation.selector]) {\n    for (id delegate in self.forwardDelegates) {\n      if ([delegate respondsToSelector:invocation.selector]) {\n        [invocation invokeWithTarget:delegate];\n        didForward = YES;\n        break;\n      }\n    }\n  }\n  \n  if (!didForward) {\n    [super forwardInvocation:invocation];\n  }\n}\n\n- (id<UITableViewDelegate>)forwardingTo:(id<UITableViewDelegate>)forwardDelegate {\n  [self.forwardDelegates addObject:forwardDelegate];\n  return self;\n}\n\n- (void)removeForwarding:(id<UITableViewDelegate>)forwardDelegate {\n  [self.forwardDelegates removeObject:forwardDelegate];\n}\n\n#pragma mark - Object State\n\n\n- (UITableViewCellAccessoryType)accessoryTypeForObject:(id)object {\n  NIObjectActions* action = [self actionForObjectOrClassOfObject:object];\n  // Detail disclosure indicator takes precedence over regular disclosure indicator.\n  if (nil != action.detailAction || nil != action.detailSelector) {\n    return UITableViewCellAccessoryDetailDisclosureButton;\n\n  } else if (nil != action.navigateAction || nil != action.navigateSelector) {\n    return  UITableViewCellAccessoryDisclosureIndicator;\n\n  }\n  // We must maintain consistency of modifications to the accessoryType within this call due\n  // to the fact that cells will be reused.\n  return UITableViewCellAccessoryNone;\n}\n\n- (UITableViewCellSelectionStyle)selectionStyleForObject:(id)object {\n  // If the cell is tappable, reflect that in the selection style.\n  NIObjectActions* action = [self actionForObjectOrClassOfObject:object];\n  if (action.navigateAction || action.tapAction\n      || action.navigateSelector || action.tapSelector) {\n    return self.tableViewCellSelectionStyle;\n\n  }\n  return UITableViewCellSelectionStyleNone;\n}\n\n#pragma mark - UITableViewDelegate\n\n\n- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {\n  NIDASSERT([tableView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]);\n  if ([tableView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]) {\n    id object = [(id<NIActionsDataSource>)tableView.dataSource objectAtIndexPath:indexPath];\n    if ([self isObjectActionable:object]) {\n      cell.accessoryType = [self accessoryTypeForObject:object];\n      cell.selectionStyle = [self selectionStyleForObject:object];\n    } else {\n      cell.accessoryType = UITableViewCellAccessoryNone;\n      cell.selectionStyle = UITableViewCellSelectionStyleNone;\n    }\n  }\n\n  // Forward the invocation along.\n  for (id<UITableViewDelegate> delegate in self.forwardDelegates) {\n    if ([delegate respondsToSelector:_cmd]) {\n      [delegate tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath];\n    }\n  }\n}\n\n- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {\n  NIDASSERT([tableView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]);\n\n  // On iOS 8 and below, UITableViewDelegate is marked \"assign\". This means that the delegate\n  // (i.e. self) is not retained before delegate methods (such as this one) are invoked.\n  // Therefore, if any of the actions ends up removing a reference to self, we may become\n  // dealloc'd before the end of this method invocation. So we create a strong reference to self\n  // to make sure all actions are carried out as expected.\n      NITableViewActions *strongSelf = self;\n\n  if ([tableView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]) {\n    id object = [(id<NIActionsDataSource>)tableView.dataSource objectAtIndexPath:indexPath];\n\n    if ([self isObjectActionable:object]) {\n      NIObjectActions* action = [self actionForObjectOrClassOfObject:object];\n\n      BOOL shouldDeselect = NO;\n      if (action.tapAction) {\n        // Tap actions can deselect the row if they return YES.\n        shouldDeselect = action.tapAction(object, strongSelf.target, indexPath);\n      }\n      if (action.tapSelector && [strongSelf.target respondsToSelector:action.tapSelector]) {\n        NSMethodSignature *methodSignature = [strongSelf.target methodSignatureForSelector:action.tapSelector];\n        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];\n        invocation.selector = action.tapSelector;\n        if (methodSignature.numberOfArguments >= 3) {\n          [invocation setArgument:&object atIndex:2];\n        }\n        if (methodSignature.numberOfArguments >= 4) {\n          [invocation setArgument:&indexPath atIndex:3];\n        }\n        [invocation invokeWithTarget:strongSelf.target];\n\n        NSUInteger length = invocation.methodSignature.methodReturnLength;\n        if (length > 0) {\n          char *buffer = (void *)malloc(length);\n          memset(buffer, 0, sizeof(char) * length);\n          [invocation getReturnValue:buffer];\n          for (NSUInteger index = 0; index < length; ++index) {\n            if (buffer[index]) {\n              shouldDeselect = YES;\n              break;\n            }\n          }\n          free(buffer);\n        }\n      }\n      if (shouldDeselect) {\n        [tableView deselectRowAtIndexPath:indexPath animated:YES];\n      }\n\n      if (action.navigateAction) {\n        action.navigateAction(object, strongSelf.target, indexPath);\n      }\n      if (action.navigateSelector && [strongSelf.target respondsToSelector:action.navigateSelector]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n        [strongSelf.target performSelector:action.navigateSelector withObject:object withObject:indexPath];\n#pragma clang diagnostic pop\n      }\n    }\n  }\n\n  // Forward the invocation along.\n  for (id<UITableViewDelegate> delegate in strongSelf.forwardDelegates) {\n    if ([delegate respondsToSelector:_cmd]) {\n      [delegate tableView:tableView didSelectRowAtIndexPath:indexPath];\n    }\n  }\n}\n\n- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {\n  NIDASSERT([tableView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]);\n  if ([tableView.dataSource conformsToProtocol:@protocol(NIActionsDataSource)]) {\n    id object = [(id<NIActionsDataSource>)tableView.dataSource objectAtIndexPath:indexPath];\n\n    if ([self isObjectActionable:object]) {\n      NIObjectActions* action = [self actionForObjectOrClassOfObject:object];\n\n      if (action.detailAction) {\n        action.detailAction(object, self.target, indexPath);\n      }\n      if (action.detailSelector && [self.target respondsToSelector:action.detailSelector]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n        [self.target performSelector:action.detailSelector withObject:object withObject:indexPath];\n#pragma clang diagnostic pop\n      }\n    }\n  }\n\n  // Forward the invocation along.\n  for (id<UITableViewDelegate> delegate in self.forwardDelegates) {\n    if ([delegate respondsToSelector:_cmd]) {\n      [delegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];\n    }\n  }\n}\n\n@end\n"
  },
  {
    "path": "src/models/src/NITableViewModel+Private.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"NITableViewModel.h\"\n\n@interface NITableViewModel()\n\n@property (nonatomic, strong) NSArray* sections; // Array of NITableViewModelSection\n@property (nonatomic, strong) NSArray* sectionIndexTitles;\n@property (nonatomic, strong) NSDictionary* sectionPrefixToSectionIndex;\n\n- (void)_resetCompiledData;\n- (void)_compileDataWithListArray:(NSArray *)listArray;\n- (void)_compileDataWithSectionedArray:(NSArray *)sectionedArray;\n- (void)_compileSectionIndex;\n- (void)_setSectionsWithArray:(NSArray *)sectionsArray;\n\n@end\n\n@interface NITableViewModelSection : NSObject\n\n+ (id)section;\n\n@property (nonatomic, copy) NSString* headerTitle;\n@property (nonatomic, copy) NSString* footerTitle;\n@property (nonatomic, strong) NSArray* rows;\n\n@end\n"
  },
  {
    "path": "src/models/src/NITableViewModel.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIActions.h\"  /* for NIActionsDataSource */\n#import \"NIPreprocessorMacros.h\" /* for weak */\n\nAPI_DEPRECATED_BEGIN(\"🕘 Schedule time to migrate. \"\n                     \"Use branded UITableView or UICollectionView instead: go/material-ios-lists. \"\n                     \"This is go/material-ios-migrations#not-scriptable 🕘\",\n                     ios(12, API_TO_BE_DEPRECATED))\n\n#if NS_BLOCKS_AVAILABLE\ntypedef UITableViewCell * _Nonnull (^NITableViewModelCellForIndexPathBlock)(UITableView* _Nonnull tableView, NSIndexPath* _Nonnull indexPath, id _Nonnull object);\n#endif // #if NS_BLOCKS_AVAILABLE\n\n@protocol NITableViewModelDelegate;\n\n\n#pragma mark Sectioned Array Objects\n\n// Classes used when creating NITableViewModels.\n@class NITableViewModelFooter;  // Provides the information for a footer.\n\ntypedef enum {\n  NITableViewModelSectionIndexNone, // Displays no section index.\n  NITableViewModelSectionIndexDynamic, // Generates a section index from the first letters of the section titles.\n  NITableViewModelSectionIndexAlphabetical, // Generates an alphabetical section index.\n} NITableViewModelSectionIndex;\n\n/**\n * A non-mutable table view model that complies to the UITableViewDataSource protocol.\n *\n * This model allows you to easily create a data source for a UITableView without having to\n * implement the UITableViewDataSource methods in your UITableViewController.\n *\n * This base class is non-mutable, much like an NSArray. You must initialize this model with\n * the contents when you create it.\n *\n * @ingroup TableViewModels\n */\n@interface NITableViewModel : NSObject <NIActionsDataSource, UITableViewDataSource>\n\n#pragma mark Creating Table View Models\n\n// Designated initializer.\n- (nonnull id)initWithDelegate:(nullable id<NITableViewModelDelegate>)delegate NS_DESIGNATED_INITIALIZER;\n- (nonnull id)initWithListArray:(nonnull NSArray *)sectionedArray delegate:(nullable id<NITableViewModelDelegate>)delegate;\n// Each NSString in the array starts a new section. Any other object is a new row (with exception of certain model-specific objects).\n- (nonnull id)initWithSectionedArray:(nonnull NSArray *)sectionedArray delegate:(nullable id<NITableViewModelDelegate>)delegate;\n\n#pragma mark Accessing Objects\n\n// This method is not appropriate for performance critical codepaths.\n- (nullable NSIndexPath *)indexPathForObject:(nonnull id)object;\n\n#pragma mark Configuration\n\n// Immediately compiles the section index.\n- (void)setSectionIndexType:(NITableViewModelSectionIndex)sectionIndexType showsSearch:(BOOL)showsSearch showsSummary:(BOOL)showsSummary;\n\n@property (nonatomic, readonly, assign) NITableViewModelSectionIndex sectionIndexType; // Default: NITableViewModelSectionIndexNone\n@property (nonatomic, readonly, assign) BOOL sectionIndexShowsSearch; // Default: NO\n@property (nonatomic, readonly, assign) BOOL sectionIndexShowsSummary; // Default: NO\n\n#pragma mark Creating Table View Cells\n\n@property (nonatomic, weak, nullable) id<NITableViewModelDelegate> delegate;\n\n#if NS_BLOCKS_AVAILABLE\n// If both the delegate and this block are provided, cells returned by this block will be used\n// and the delegate will not be called.\n@property (nonatomic, copy, nullable) NITableViewModelCellForIndexPathBlock createCellBlock;\n#endif // #if NS_BLOCKS_AVAILABLE\n\n@end\n\n/**\n * A protocol for NITableViewModel to fetch rows to be displayed for the table view.\n *\n * @ingroup TableViewModels\n */\n@protocol NITableViewModelDelegate <NSObject>\n\n@required\n\n/**\n * Fetches a table view cell at a given index path with a given object.\n *\n * The implementation of this method will generally use object to customize the cell.\n */\n- (nonnull UITableViewCell *)tableViewModel: (nonnull NITableViewModel *)tableViewModel\n                           cellForTableView: (nonnull UITableView *)tableView\n                                atIndexPath: (nonnull NSIndexPath *)indexPath\n                                 withObject: (nonnull id)object;\n\n@end\n\n/**\n * An object used in sectioned arrays to denote a section header title.\n *\n * Meant to be used in a sectioned array for NITableViewModel.\n *\n * <h3>Example</h3>\n *\n * @code\n *  [NITableViewModelHeader headerWithTitle:@\"Header\"]\n * @endcode\n */\n@interface NITableViewModelHeader : NSObject\n\n+ (nonnull instancetype)headerWithTitle:(nonnull NSString *)title;\n- (nonnull instancetype)initWithTitle:(nonnull NSString *)title;\n\n@property (nonatomic, copy, nullable) NSString* title;\n\n@end\n\n/**\n * An object used in sectioned arrays to denote a section footer title.\n *\n * Meant to be used in a sectioned array for NITableViewModel.\n *\n * <h3>Example</h3>\n *\n * @code\n *  [NITableViewModelFooter footerWithTitle:@\"Footer\"]\n * @endcode\n */\n@interface NITableViewModelFooter : NSObject\n\n+ (nonnull id)footerWithTitle:(nonnull NSString *)title;\n- (nonnull id)initWithTitle:(nonnull NSString *)title;\n\n@property (nonatomic, copy, nullable) NSString* title;\n\n@end\n\n/** @name Creating Table View Models */\n\n/**\n * Initializes a newly allocated static model with the given delegate and empty contents.\n *\n * This method can be used to create an empty model.\n *\n * @fn NITableViewModel::initWithDelegate:\n */\n\n/**\n * Initializes a newly allocated static model with the contents of a list array.\n *\n * A list array is a one-dimensional array that defines a flat list of rows. There will be\n * no sectioning of contents in any way.\n *\n * <h3>Example</h3>\n *\n * @code\n * NSArray* contents =\n * [NSArray arrayWithObjects:\n *  [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n *  [NSDictionary dictionaryWithObject:@\"Row 2\" forKey:@\"title\"],\n *  [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n *  nil];\n * [[NIStaticTableViewModel alloc] initWithListArray:contents delegate:self];\n * @endcode\n *\n * @fn NITableViewModel::initWithListArray:delegate:\n */\n\n/**\n * Initializes a newly allocated static model with the contents of a sectioned array.\n *\n * A sectioned array is a one-dimensional array that defines a list of sections and each\n * section's contents. Each NSString begins a new section and any other object defines a\n * row for the current section.\n *\n * <h3>Example</h3>\n *\n * @code\n * NSArray* contents =\n * [NSArray arrayWithObjects:\n *  @\"Section 1\",\n *  [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n *  [NSDictionary dictionaryWithObject:@\"Row 2\" forKey:@\"title\"],\n *  @\"Section 2\",\n *  // This section is empty.\n *  @\"Section 3\",\n *  [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n *  [NITableViewModelFooter footerWithTitle:@\"Footer\"],\n *  nil];\n * [[NITableViewModel alloc] initWithSectionedArray:contents delegate:self];\n * @endcode\n *\n * <h3>Example using NITableViewModelHeader</h3>\n *\n * When a NITableViewModelHeader is present in the array then strings will no longer be\n * treated as section headers; NITableViewModelHeader instances will be used as section\n * headers instead. This enables strings to be used as simple objects in a sectioned\n * array, similar to how they can be used in a list array.\n *\n * @code\n * NSArray* contents =\n * [NSArray arrayWithObjects:\n *  [NITableViewModelHeader headerWithTitle:@\"Section 1\"],\n *  @\"Row 1\",\n *  @\"Row 2\",\n *  [NITableViewModelHeader headerWithTitle:@\"Section 2\"],\n *  // This section is empty.\n *  [NITableViewModelHeader headerWithTitle:@\"Section 3\"],\n *  @\"Row 3\",\n *  [NITableViewModelFooter footerWithTitle:@\"Footer\"],\n *  nil];\n * [[NITableViewModel alloc] initWithSectionedArray:contents delegate:self];\n * @endcode\n *\n * @fn NITableViewModel::initWithSectionedArray:delegate:\n */\n\n\n/** @name Accessing Objects */\n\n/**\n * Returns the object at the given index path.\n *\n * If no object exists at the given index path (an invalid index path, for example) then nil\n * will be returned.\n *\n * @fn NITableViewModel::objectAtIndexPath:\n */\n\n/**\n * Returns the index path of the given object within the model.\n *\n * If the model does not contain the object then nil will be returned.\n *\n * @fn NITableViewModel::indexPathForObject:\n */\n\n/** @name Configuration */\n\n/**\n * Configures the model's section index properties.\n *\n * Calling this method will compile the section index depending on the index type chosen.\n *\n * @param sectionIndexType The type of section index to display.\n * @param showsSearch      Whether or not to show the search icon at the top of the index.\n * @param showsSummary     Whether or not to show the summary icon at the bottom of the index.\n * @fn NITableViewModel::setSectionIndexType:showsSearch:showsSummary:\n */\n\n/**\n * The section index type.\n *\n * You will likely use NITableViewModelSectionIndexAlphabetical in practice.\n *\n * NITableViewModelSectionIndexNone by default.\n *\n * @fn NITableViewModel::sectionIndexType\n */\n\n/**\n * Whether or not the search symbol will be shown in the section index.\n *\n * NO by default.\n *\n * @fn NITableViewModel::sectionIndexShowsSearch\n */\n\n/**\n * Whether or not the summary symbol will be shown in the section index.\n *\n * NO by default.\n *\n * @fn NITableViewModel::sectionIndexShowsSummary\n */\n\n\n/** @name Creating Table View Cells */\n\n/**\n * A delegate used to fetch table view cells for the data source.\n *\n * @fn NITableViewModel::delegate\n */\n\n#if NS_BLOCKS_AVAILABLE\n\n/**\n * A block used to create a UITableViewCell for a given object.\n *\n * @fn NITableViewModel::createCellBlock\n */\n\n#endif // #if NS_BLOCKS_AVAILABLE\n\nAPI_DEPRECATED_END\n"
  },
  {
    "path": "src/models/src/NITableViewModel.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NITableViewModel.h\"\n\n#import \"NITableViewModel+Private.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NITableViewModel\n\n#if NS_BLOCKS_AVAILABLE\n#endif // #if NS_BLOCKS_AVAILABLE\n\n\n- (id)initWithDelegate:(id<NITableViewModelDelegate>)delegate {\n  if ((self = [super init])) {\n    self.delegate = delegate;\n\n    _sectionIndexType = NITableViewModelSectionIndexNone;\n    _sectionIndexShowsSearch = NO;\n    _sectionIndexShowsSummary = NO;\n\n    [self _resetCompiledData];\n  }\n  return self;\n}\n\n- (id)initWithListArray:(NSArray *)listArray delegate:(id<NITableViewModelDelegate>)delegate {\n  if ((self = [self initWithDelegate:delegate])) {\n    [self _compileDataWithListArray:listArray];\n  }\n  return self;\n}\n\n- (id)initWithSectionedArray:(NSArray *)sectionedArray delegate:(id<NITableViewModelDelegate>)delegate {\n  if ((self = [self initWithDelegate:delegate])) {\n    [self _compileDataWithSectionedArray:sectionedArray];\n  }\n  return self;\n}\n\n- (id)init {\n  return [self initWithDelegate:nil];\n}\n\n#pragma mark - Compiling Data\n\n\n- (void)_resetCompiledData {\n  [self _setSectionsWithArray:nil];\n  self.sectionIndexTitles = nil;\n  self.sectionPrefixToSectionIndex = nil;\n}\n\n- (void)_compileDataWithListArray:(NSArray *)listArray {\n  [self _resetCompiledData];\n\n  if (nil != listArray) {\n    NITableViewModelSection* section = [NITableViewModelSection section];\n    section.rows = [listArray mutableCopy];\n    [self _setSectionsWithArray:@[ section ]];\n  }\n}\n\n- (void)_compileDataWithSectionedArray:(NSArray *)sectionedArray {\n  [self _resetCompiledData];\n\n  NSMutableArray* sections = [NSMutableArray array];\n\n  NSString* currentSectionHeaderTitle = nil;\n  NSString* currentSectionFooterTitle = nil;\n  NSMutableArray* currentSectionRows = nil;\n\n  BOOL hasAnySectionHeaders = NO;\n  for (id object in sectionedArray) {\n    if ([object isKindOfClass:[NITableViewModelHeader class]]) {\n      hasAnySectionHeaders = YES;\n      break;\n    }\n  }\n\n  for (id object in sectionedArray) {\n    BOOL isSection = (hasAnySectionHeaders\n                      ? [object isKindOfClass:[NITableViewModelHeader class]]\n                      : [object isKindOfClass:[NSString class]]);\n    BOOL isSectionFooter = [object isKindOfClass:[NITableViewModelFooter class]];\n\n    NSString* nextSectionHeaderTitle = nil;\n\n    if (isSection) {\n      nextSectionHeaderTitle = hasAnySectionHeaders ? [object title] : object;\n\n    } else if (isSectionFooter) {\n      NITableViewModelFooter* footer = object;\n      currentSectionFooterTitle = footer.title;\n\n    } else {\n      if (nil == currentSectionRows) {\n        currentSectionRows = [[NSMutableArray alloc] init];\n      }\n      [currentSectionRows addObject:object];\n    }\n\n    // A section footer or title has been encountered,\n    if (nil != nextSectionHeaderTitle || nil != currentSectionFooterTitle) {\n      if (nil != currentSectionHeaderTitle\n          || nil != currentSectionFooterTitle\n          || nil != currentSectionRows) {\n        NITableViewModelSection* section = [NITableViewModelSection section];\n        section.headerTitle = currentSectionHeaderTitle;\n        section.footerTitle = currentSectionFooterTitle;\n        section.rows = currentSectionRows;\n        [sections addObject:section];\n      }\n\n      currentSectionRows = nil;\n      currentSectionHeaderTitle = nextSectionHeaderTitle;\n      currentSectionFooterTitle = nil;\n    }\n  }\n\n  // Commit any unfinished sections.\n  if ([currentSectionRows count] > 0 || nil != currentSectionHeaderTitle) {\n    NITableViewModelSection* section = [NITableViewModelSection section];\n    section.headerTitle = currentSectionHeaderTitle;\n    section.footerTitle = currentSectionFooterTitle;\n    section.rows = currentSectionRows;\n    [sections addObject:section];\n  }\n  currentSectionRows = nil;\n\n  // Update the compiled information for this data source.\n  [self _setSectionsWithArray:sections];\n}\n\n- (void)_compileSectionIndex {\n  _sectionIndexTitles = nil;\n\n  // Prime the section index and the map\n  NSMutableArray* titles = nil;\n  NSMutableDictionary* sectionPrefixToSectionIndex = nil;\n  if (NITableViewModelSectionIndexNone != _sectionIndexType) {\n    titles = [NSMutableArray array];\n    sectionPrefixToSectionIndex = [NSMutableDictionary dictionary];\n\n    // The search symbol is always first in the index.\n    if (_sectionIndexShowsSearch) {\n      [titles addObject:UITableViewIndexSearch];\n    }\n  }\n\n  // A dynamic index shows the first letter of every section in the index in whatever order the\n  // sections are ordered (this may not be alphabetical).\n  if (NITableViewModelSectionIndexDynamic == _sectionIndexType) {\n    for (NITableViewModelSection* section in _sections) {\n      NSString* headerTitle = section.headerTitle;\n      if ([headerTitle length] > 0) {\n        NSString* prefix = [headerTitle substringToIndex:1];\n        [titles addObject:prefix];\n      }\n    }\n\n  } else if (NITableViewModelSectionIndexAlphabetical == _sectionIndexType) {\n    // Use the localized indexed collation to create the index. In English, this will always be\n    // the entire alphabet.\n    NSArray* sectionIndexTitles = [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];\n\n    // The localized indexed collection sometimes includes a # for summaries, but we might\n    // not want to show a summary in the index, so prune it out. It's not guaranteed that\n    // a # will actually be included in the section index titles, so we always attempt to\n    // remove it for consistency's sake and then add it back down below if it is requested.\n    for (NSString* letter in sectionIndexTitles) {\n      if (![letter isEqualToString:@\"#\"]) {\n        [titles addObject:letter];\n      }\n    }\n  }\n\n  // Add the section summary symbol if it was requested.\n  if (_sectionIndexShowsSummary) {\n    [titles addObject:@\"#\"];\n  }\n\n  // Build the prefix => section index map.\n  if (NITableViewModelSectionIndexNone != _sectionIndexType) {\n\n    // Map all of the sections to indices.\n    NSInteger sectionIndex = 0;\n    for (NITableViewModelSection* section in _sections) {\n      NSString* headerTitle = section.headerTitle;\n      if ([headerTitle length] > 0) {\n        NSString* prefix = [headerTitle substringToIndex:1];\n        if (nil == [sectionPrefixToSectionIndex objectForKey:prefix]) {\n          [sectionPrefixToSectionIndex setObject:[NSNumber numberWithInteger:sectionIndex] forKey:prefix];\n        }\n      }\n      ++sectionIndex;\n    }\n\n    // Map the unmapped section titles to the next closest earlier section.\n    NSInteger lastIndex = 0;\n    for (NSString* title in titles) {\n      NSString* prefix = [title substringToIndex:1];\n      if (nil != [sectionPrefixToSectionIndex objectForKey:prefix]) {\n        lastIndex = [[sectionPrefixToSectionIndex objectForKey:prefix] intValue];\n        \n      } else {\n        [sectionPrefixToSectionIndex setObject:[NSNumber numberWithInteger:lastIndex] forKey:prefix];\n      }\n    }\n  }\n\n  self.sectionIndexTitles = titles;\n  self.sectionPrefixToSectionIndex = sectionPrefixToSectionIndex;\n}\n\n- (void)_setSectionsWithArray:(NSArray *)sectionsArray {\n  self.sections = sectionsArray;\n}\n\n#pragma mark - UITableViewDataSource\n\n\n- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {\n  return self.sections.count;\n}\n\n- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {\n  NIDASSERT((section >= 0 && (NSUInteger)section < self.sections.count) || 0 == self.sections.count);\n  if (section >= 0 && (NSUInteger)section < self.sections.count) {\n    return [[self.sections objectAtIndex:section] headerTitle];\n\n  } else {\n    return nil;\n  }\n}\n\n- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {\n  NIDASSERT((section >= 0 && (NSUInteger)section < self.sections.count) || 0 == self.sections.count);\n  if (section >= 0 && (NSUInteger)section < self.sections.count) {\n    return [[self.sections objectAtIndex:section] footerTitle];\n    \n  } else {\n    return nil;\n  }\n}\n\n- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {\n  // This is a static model; nothing can be edited.\n  return NO;\n}\n\n- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {\n  return self.sectionIndexTitles;\n}\n\n- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {\n  if (tableView.tableHeaderView) {\n    if (index == 0 && [self.sectionIndexTitles count] > 0\n        && [self.sectionIndexTitles objectAtIndex:0] == UITableViewIndexSearch)  {\n      // This is a hack to get the table header to appear when the user touches the\n      // first row in the section index.  By default, it shows the first row, which is\n      // not usually what you want.\n      [tableView scrollRectToVisible:tableView.tableHeaderView.bounds animated:NO];\n      return -1;\n    }\n  }\n\n  NSString* letter = [title substringToIndex:1];\n  NSNumber* sectionIndex = [self.sectionPrefixToSectionIndex objectForKey:letter];\n  return (nil != sectionIndex) ? [sectionIndex intValue] : -1;\n}\n\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {\n  NIDASSERT((NSUInteger)section < self.sections.count || 0 == self.sections.count);\n  if ((NSUInteger)section < self.sections.count) {\n    return [[[self.sections objectAtIndex:section] rows] count];\n\n  } else {\n    return 0;\n  }\n}\n\n- (UITableViewCell *)tableView: (UITableView *)tableView\n         cellForRowAtIndexPath: (NSIndexPath *)indexPath {\n  id object = [self objectAtIndexPath:indexPath];\n\n  UITableViewCell* cell = nil;\n\n#if NS_BLOCKS_AVAILABLE\n  if (nil != self.createCellBlock) {\n    cell = self.createCellBlock(tableView, indexPath, object);\n  }\n#endif\n\n  if (nil == cell) {\n    cell = [self.delegate tableViewModel:self\n                        cellForTableView:tableView\n                             atIndexPath:indexPath\n                              withObject:object];\n  }\n\n  return cell;\n}\n\n#pragma mark - Public\n\n\n- (id)objectAtIndexPath:(NSIndexPath *)indexPath {\n  if (nil == indexPath) {\n    return nil;\n  }\n\n  NSInteger section = [indexPath section];\n  NSInteger row = [indexPath row];\n\n  id object = nil;\n\n  NIDASSERT((NSUInteger)section < self.sections.count);\n  if ((NSUInteger)section < self.sections.count) {\n    NSArray* rows = [[self.sections objectAtIndex:section] rows];\n\n    NIDASSERT((NSUInteger)row < rows.count);\n    if ((NSUInteger)row < rows.count) {\n      object = [rows objectAtIndex:row];\n    }\n  }\n\n  return object;\n}\n\n- (NSIndexPath *)indexPathForObject:(id)object {\n  if (nil == object) {\n    return nil;\n  }\n\n  NSArray *sections = self.sections;\n  for (NSUInteger sectionIndex = 0; sectionIndex < [sections count]; sectionIndex++) {\n    NSArray* rows = [[sections objectAtIndex:sectionIndex] rows];\n    for (NSUInteger rowIndex = 0; rowIndex < [rows count]; rowIndex++) {\n      if ([object isEqual:[rows objectAtIndex:rowIndex]]) {\n        return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];\n      }\n    }\n  }\n\n  return nil;\n}\n\n- (void)setSectionIndexType:(NITableViewModelSectionIndex)sectionIndexType showsSearch:(BOOL)showsSearch showsSummary:(BOOL)showsSummary {\n  if (_sectionIndexType != sectionIndexType\n      || _sectionIndexShowsSearch != showsSearch\n      || _sectionIndexShowsSummary != showsSummary) {\n    _sectionIndexType = sectionIndexType;\n    _sectionIndexShowsSearch = showsSearch;\n    _sectionIndexShowsSummary = showsSummary;\n\n    [self _compileSectionIndex];\n  }\n}\n\n@end\n\n@implementation NITableViewModelHeader\n\n+ (instancetype)headerWithTitle:(NSString *)title {\n  return [[self alloc] initWithTitle:title];\n}\n\n- (instancetype)initWithTitle:(NSString *)title {\n  if ((self = [super init])) {\n    self.title = title;\n  }\n  return self;\n}\n\n@end\n\n@implementation NITableViewModelFooter\n\n\n\n+ (NITableViewModelFooter *)footerWithTitle:(NSString *)title {\n  return [[self alloc] initWithTitle:title];\n}\n\n- (id)initWithTitle:(NSString *)title {\n  if ((self = [super init])) {\n    self.title = title;\n  }\n  return self;\n}\n\n@end\n\n\n@implementation NITableViewModelSection\n\n\n\n+ (id)section {\n  return [[self alloc] init];\n}\n\n@end\n"
  },
  {
    "path": "src/models/src/NimbusModels.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#pragma mark - Nimbus Models\n\n/**\n * @defgroup NimbusModels Nimbus Models\n * @{\n *\n * <div id=\"github\" feature=\"models\"></div>\n *\n * A model is an implementation of a data source protocol.\n *\n * Data sources are required by various UI components throughout UIKit and Nimbus.\n * It can be painful to have to rewrite the same data source logic over and over\n * again. Nimbus models allow you to separate the data source logic from your view\n * controller and recycle common functionality throughout your application. You'll\n * find that your view controller can then focus on the broader implementation details\n * rather than implementing dozens of data source methods.\n *\n * <h2>Vanilla UIKit vs Nimbus Models</h2>\n *\n * If you would like to see an example of Nimbus models being used, check out\n * the ModelCatalog example application.\n */\n\n#pragma mark * Table View Models\n\n/**\n * @defgroup TableViewModels Table View Models\n *\n * Nimbus table view models make building table views remarkably easy. Rather than implement\n * the data source methods in each table view controller, you assign a model to\n * self.tableView.dataSource and only think about row creation.\n *\n * Nimbus table view models implement many of the standard table view data source methods,\n * including methods for section titles, grouped rows, and section indices. By\n * providing this functionality in one object, Nimbus provides much more\n * efficient implementations than one-off implementations that might otherwise\n * be copied from one controller to another.\n *\n * <h2>Creating Generic Static Models</h2>\n *\n * In order to use the Nimbus table view model you create a model, assign\n * it to your table view's data source after the table view has been created, and implement\n * the model delegate to create the table view cells. You can use the\n * @link TableCellFactory Nimbus cell factory@endlink to avoid implementing the model\n * delegate.\n *\n * Below is an example of creating a basic list model:\n *\n * @code\nNSArray* tableContents =\n [NSArray arrayWithObjects:\n  [NITitleCellObject objectWithTitle:@\"Row 1\"],\n  [NITitleCellObject objectWithTitle:@\"Row 2\"],\n  [NITitleCellObject objectWithTitle:@\"Row 3\"],\n  nil];\n\n_model = [[NITableViewModel alloc] initWithListArray:tableContents\n                                            delegate:self];\n * @endcode\n *\n * Below is an example of creating a basic sectioned model:\n *\n * @code\nNSArray* tableContents =\n [NSArray arrayWithObjects:\n  @\"Section Title\",\n  [NITitleCellObject objectWithTitle:@\"Row 1\"],\n  [NITitleCellObject objectWithTitle:@\"Row 2\"],\n\n  @\"Section Title\",\n  [NITitleCellObject objectWithTitle:@\"Row 3\"],\n  nil];\n\n_model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                 delegate:self];\n * @endcode\n *\n * Both of the above examples would implement the model delegate like so:\n *\n * @code\n- (UITableViewCell *)tableViewModel: (NITableViewModel *)tableViewModel\n                   cellForTableView: (UITableView *)tableView\n                        atIndexPath: (NSIndexPath *)indexPath\n                         withObject: (id)object {\n  UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@\"row\"];\n\n  if (nil == cell) {\n    cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault\n                                   reuseIdentifier: @\"row\"]\n            autorelease];\n  }\n\n  cell.textLabel.text = [object objectForKey:@\"title\"];\n\n  return cell;\n}\n * @endcode\n *\n * <h2>Creating Forms</h2>\n *\n * Let's say you want to create a form for a user to enter their username and password. You\n * can easily do this with Nimbus using the @link TableCellFactory Nimbus cell factory@endlink\n * and the Nimbus form elements from the @link TableCellCatalog table cell catalog@endlink.\n *\n * @code\n\nNSArray* tableContents =\n[NSArray arrayWithObjects:\n @\"Sign In\",\n [NITextInputFormElement textInputElementWithID:kUsernameField placeholderText:@\"Username\" value:nil],\n [NITextInputFormElement passwordInputElementWithID:kPasswordField placeholderText:@\"Password\" value:nil],\n nil];\n\n_model = [[NITableViewModel alloc] initWithSectionedArray:tableContents\n                                                 delegate:(id)[NICellFactory class]];\n * @endcode\n *\n * When the user then hits the button to sign in, you can grab the values from the model by using\n * the elementWithID: category method added to NITableViewModel by the form support.\n *\n * @code\nNSString* username = [[_model elementWithID:kUsernameField] value];\nNSString* password = [[_model elementWithID:kPasswordField] value];\n * @endcode\n *\n * See example: @link ExampleStaticTableModel.m Static Table Model Creation@endlink\n */\n\n#pragma mark * Table Cell Factory\n\n/**\n * @defgroup TableCellFactory Table Cell Factory\n *\n * A table cell factory automatically creates UITableViewCells from objects.\n *\n * The Nimbus table cell factory works by requiring that objects implement a basic protocol,\n * NICellObject, which sets up a binding from the object to a specific cell implementation.\n * This cell implementation can optionally implement the NICell protocol. In practice this is\n * nearly always the case. You then simply use the factory in your table's data source and\n * the factory will handle the rest. This allows you to completely separate presentation from\n * data in your table view controllers.\n *\n * <h2>A Simple Example: A Twitter Application</h2>\n *\n * Let's say you want to build a Twitter news feed. We'll assume you've\n * already figured out the network requests and now have individual tweets itching to be displayed.\n * To use the Nimbus factory you will need two different classes: one for the tweet object\n * and its data, and another for the tweet table view cell. Let's call them Tweet and\n * TweetCell, respectively. You may even already have a Tweet object.\n *\n * <h3>Implement the NICellObject Protocol</h3>\n *\n * You must first implement the NICellObject protocol in your Tweet object. We want to link\n * the TweetCell table view cell to the Tweet object so that the factory can create a TweetCell\n * when it needs to present the Tweet object.\n *\n * @code\n@interface Tweet : NSObject <NICellObject> {\n// ...\n}\n@end\n\n@implementation Tweet\n\n- (Class)cellClass {\n  return [TweetCell class];\n}\n\n@end\n * @endcode\n *\n * Now that we've pointed the Tweet object to the TweetCell class, let's make the\n * table controller use the NICellFactory.\n *\n * <h3>Using the Factory</h3>\n *\n * There are a few ways you can use the factory in your code. We'll walk through increasingly\n * Nimbus-like implementations, starting with a vanilla UIKit implementation.\n *\n * The following vanilla UIKit implementation has the advantage of allowing you to use\n * NICellFactory in your existing code base without requiring a full rewrite of your data\n * source. If you are attempting to switch to a pure Nimbus implementation using the cell factory\n * then this is a good first step because it is the least invasive.\n *\n * @code\n- (UITableViewCell *)tableView: (UITableView *)tableView\n         cellForRowAtIndexPath: (NSIndexPath *)indexPath {\n  // Note: You must fetch the object at this index path somehow. The objectAtIndexPath:\n  // is simply an example; replace it with your own implementation.\n  id object = [self objectAtIndexPath:indexPath];\n\n  UITableViewCell* cell = [NICellFactory tableViewModel:nil cellForTableView:tableView atIndexPath:indexPath withObject:object];\n  if (nil == cell) {\n    // Here would be whatever code you were originally using to create cells. nil is only returned\n    // when the factory wasn't able to create a cell, likely due to the NICellObject protocol\n    // not being implemented for the given object. As you implement these protocols on\n    // more objects the factory will automatically start returning the correct cells\n    // and you can start removing this special-case logic.\n  }\n  return cell;\n}\n * @endcode\n *\n * This next implementation is what your vanilla data source implementation would look like once\n * you have no more custom cell creation code.\n *\n * @code\n- (UITableViewCell *)tableView: (UITableView *)tableView\n         cellForRowAtIndexPath: (NSIndexPath *)indexPath {\n  // Note: You must fetch the object at this index path somehow. The objectAtIndexPath:\n  // is simply an example; replace it with your own implementation.\n  id object = [self objectAtIndexPath:indexPath];\n\n  // Only use the factory to create cells now that every object used in this controller\n  // implements the factory protocols.\n  return [NICellFactory tableViewModel:nil cellForTableView:tableView atIndexPath:indexPath withObject:object];\n}\n * @endcode\n *\n * If you are using Nimbus models then your code gets even simpler because the object is passed\n * to your model delegate method.\n *\n * @code\n- (UITableViewCell *)tableViewModel: (NITableViewModel *)tableViewModel\n                   cellForTableView: (UITableView *)tableView\n                        atIndexPath: (NSIndexPath *)indexPath\n                         withObject: (id)object {\n  // The model gives us the object, making this much simpler and likely more efficient than the vanilla UIKit implementation.\n  return [NICellFactory tableViewModel:tableViewModel cellForTableView:tableView atIndexPath:indexPath withObject:object];\n}\n * @endcode\n *\n * And finally, if you require no custom code in your model delegate, the above example can\n * be shortened to a one-liner when you initialize the model:\n *\n * @code\n// This is functionally identical to implementing the delegate in this controller and simply\n// calling the factory method.\n_model.delegate = (id)[NICellFactory class];\n * @endcode\n *\n * <h3>Customizing the Cell</h3>\n *\n * We want to customize the cells as they are presented, otherwise all of the cells will look\n * the same. After our TweetCell object is created in the factory, the factory will call\n * the @link NICell::shouldUpdateCellWithObject: shouldUpdateCellWithObject:@endlink method\n * on the cell, if it is implemented. Remember that cells are reused in table views and that\n * any modification you may make to the cell could still be present the next time this cell\n * is updated with an object.\n *\n * @code\n- (BOOL)shouldUpdateCellWithObject:(id)object {\n  // We can be rest assured that `object` is a Tweet object because that's how we set up\n  // the bindings. If more than one type of object maps to this cell class then we'd have\n  // to check the object type accordingly.\n  Tweet* tweet = object;\n  self.textLabel.text = tweet.text;\n\n  // Returning YES or NO here is intended purely for subclassing purposes. Returning YES means\n  // that the object changed the cell in some way.\n  return YES;\n}\n * @endcode\n *\n * <h3>Conclusions</h3>\n *\n * The Nimbus cell factory can greatly reduce the amount of code you have to write in your\n * table controllers while separating the data from the presentation. You can slowly ease\n * yourself into using the factory if you already have a large existing code base.\n *\n * If you are migrating from Three20, you will find that Nimbus' table factory is very similar\n * to TTTableViewController, though greatly simplified and decoupled from the rest of the Three20\n * ecosystem. Where Three20 provided a tightly integrated solution, Nimbus allows you to plug\n * in the factory where it makes sense.\n */\n\n#pragma mark * Table Cell Catalog\n\n/**\n * @defgroup TableCellCatalog Table Cell Catalog\n *\n * This is a catalog of Nimbus' pre-built cells and objects for use in UITableViews.\n *\n * All of these cells are designed primarily to be used with the\n * @link TableCellFactory Nimbus cell factory@endlink, though it is entirely possible to use\n * the cells in a vanilla UIKit application as well.\n *\n * <h2>Form Element Catalog</h2>\n *\n * Building forms with Nimbus is incredibly easy thanks to the pre-built form elements. The\n * available form elements are listed below.\n *\n * Form elements require an element ID that can be used to differentiate between the form\n * elements, much like in HTML. If you are using the table cell factory then the element ID\n * will be assigned to the cell's view tag and the control tags as well. Let's say you want\n * to add a text input element that is disabled under certain conditions. Your code would look\n * something like the following:\n *\n * @code\n// In your model, create an element with the delegate provided.\n[NITextInputFormElement elementWithID:kUsernameField placeholderText:@\"Username\" value:nil delegate:self],\n\n// And then implement the UITextFieldDelegate\n- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {\n  if (textField.tag == kUsernameField) {\n    return NO;\n  }\n  return YES;\n}\n * @endcode\n *\n * <h3>NITextInputFormElement</h3>\n *\n * @image html NITextInputCellExample1.png \"NITextInputFormElement => NITextInputFormElementCell\"\n *\n * Example use in a NITableViewModel:\n * @code\n// Create a text input field.\n[NITextInputFormElement textInputElementWithID:kUsernameField placeholderText:@\"Username\" value:nil],\n// Create a password input field\n[NITextInputFormElement passwordInputElementWithID:kPasswordField placeholderText:@\"Password\" value:nil],\n * @endcode\n *\n * <h3>NISwitchFormElement</h3>\n *\n * @image html NISwitchFormElementCellExample1.png \"NISwitchFormElement => NISwitchFormElementCell\"\n *\n * Example use in a NITableViewModel:\n * @code\n [NISwitchFormElement switchElementWithID:kPushNotifications labelText:@\"Push Notifications\" value:NO],\n * @endcode\n *\n */\n\n#pragma mark * Table Cell Backgrounds\n\n/**\n * @defgroup TableCellBackgrounds Table Cell Backgrounds\n *\n * NICellBackground is a tool for creating backgrounds that can be used to customize cells in\n * UITableViews.\n */\n\n#pragma mark * Model Tools\n\n/**\n * @defgroup ModelTools Model Tools\n *\n * Model tools are objects that abstract common functionality used in view controllers.\n *\n * <h2>Radio Groups</h2>\n *\n * One commonly-required feature for table views is radio button functionality. This is useful when\n * you need the user to make a choice from a set of options. Implementing this is trivial with the\n * Nimbus NIRadioGroup object.\n *\n * The radio group object allows you to map a set of table objects to a group of identifiers and\n * then support radio button interactions. You can find a working example of this in the\n * ModelCatalog sample application.\n *\n * Provided below is a quick overview of implementing the iOS Settings app's notifications page.\n *\n@code\n// We first define the enumeration of identifiers that we will use to map the table objects\n// to unique identifiers.\ntypedef enum {\n  AppSortManual,\n  AppSortByTime,\n} AppSort;\n\n// You will create and retain a radio group object for the lifecycle of your controller.\n@property (nonatomic, retain) NIRadioGroup* radioGroup;\n\n- (void)refreshModel {\n  id manual = [NITitleCellObject cellWithTitle:@\"Manually\"];\n  id byTime = [NITitleCellObject cellWithTitle:@\"By Time\"];\n\n  NSArray* contents =\n  [NSArray arrayWithObjects:\n   @\"Sort Apps:\",\n   manual, byTime,\n   nil];\n\n  self.model = [[NITableViewModel alloc] initWithSectionedArray:contents\n                                                       delegate:(id)[NICellFactory class]];\n  self.tableView.dataSource = self.model;\n\n  self.radioGroup = [[[NIRadioGroup alloc] init] autorelease];\n\n  // Selection notifications are sent through the delegate.\n  self.radioGroup.delegate = self;\n\n  // Map the objects to their corresponding identifiers.\n  [self.radioGroup mapObject:manual toIdentifier:AppSortManual];\n  [self.radioGroup mapObject:byTime toIdentifier:AppSortByTime];\n\n  // Set the initial selection.\n  self.radioGroup.selectedIdentifier = AppSortManual;\n\n  // Insert the radio group into the delegate call chain.\n  self.tableView.delegate = [self.radioGroup forwardingTo:self.tableView.delegate];\n\n  [self.tableView reloadData];\n}\n\n- (void)radioGroup:(NIRadioGroup *)radioGroup didSelectIdentifier:(NSInteger)identifier {\n  NSLog(@\"Radio group selection changed: %d\", identifier);\n}\n@endcode\n *\n * <h2>Table View Actions</h2>\n *\n * Separating actions from presentation is an important aspect in simplifying table view cell\n * design. It can be tempting to add delegate and selector properties to cells, but this ends up\n * forcing a lot of logic to be written on the cell level so that the cells accurately represent\n * their actionable state.\n *\n * Nimbus provides a solution with NITableViewActions. NITableViewActions manages the cell <=>\n * action mapping by inserting itself in the delegate call chain invocation forwarding. When cells\n * are displayed, their accessoryType and selectionStyle are updated to reflect the actions that\n * have been attached to them. When cells are tapped, the correct set of actions are performed.\n *\n * Below is an example of implementing the \"General\" page of the Settings app.\n *\n@code\n// You will create and retain an actions object for the lifecycle of your controller.\n@property (nonatomic, retain) NITableViewActions* actions;\n\n- (void)refreshModel {\n  id about = [NITitleCellObject cellWithTitle:@\"About\"];\n  id softwareUpdate = [NITitleCellObject cellWithTitle:@\"Software Update\"];\n\n  NSArray* contents =\n  [NSArray arrayWithObjects:\n   @\"\",\n   about, softwareUpdate,\n   nil];\n\n  self.model = [[NITableViewModel alloc] initWithSectionedArray:contents\n                                                       delegate:(id)[NICellFactory class]];\n  self.tableView.dataSource = self.model;\n\n  // The controller we provide here will be passed to the action blocks.\n  self.actions = [[[NITableViewActions alloc] initWithController:self] autorelease];\n \n  [self.actions attachNavigationAction:NIPushControllerAction([AboutViewController class])\n                              toObject:about];\n  [self.actions attachNavigationAction:NIPushControllerAction([SoftwareUpdateViewController class])\n                              toObject:softwareUpdate];\n\n  // Insert the actions into the delegate call chain.\n  self.tableView.delegate = [self.actions forwardingTo:self.tableView.delegate];\n\n  [self.tableView reloadData];\n}\n@endcode\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NITableViewModel.h\"\n#import \"NIMutableTableViewModel.h\"\n#import \"NICellBackgrounds.h\"\n#import \"NICellCatalog.h\"\n#import \"NICellFactory.h\"\n#import \"NITableViewActions.h\"\n\n/**@}*/\n"
  },
  {
    "path": "src/models/unittests/NICellCatalogTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCore.h\"\n#import \"NimbusModels.h\"\n\n@interface NICellCatalogTests : XCTestCase\n@end\n\n@interface TestTitleCellObject : NITitleCellObject\n@property (nonatomic, assign) BOOL designatedInitializerWasExecuted;\n@end\n\n@interface TestSubtitleCellObject : NISubtitleCellObject\n@property (nonatomic, assign) BOOL designatedInitializerWasExecuted;\n@end\n\n@implementation NICellCatalogTests\n\n- (void)testCellObjectSubclassInitialization {\n  TestTitleCellObject *titleCellObject = [[TestTitleCellObject alloc] initWithTitle:@\"Title\"];\n  XCTAssertTrue(titleCellObject.designatedInitializerWasExecuted,\n                @\"%@'s designated initializer override did not run.\", [titleCellObject class]);\n  TestSubtitleCellObject *subtitleCellObject = [[TestSubtitleCellObject alloc] initWithTitle:@\"Title\"];\n  XCTAssertTrue(subtitleCellObject.designatedInitializerWasExecuted,\n                @\"%@'s designated initializer override did not run.\", [subtitleCellObject class]);\n}\n\n@end\n\n@implementation TestTitleCellObject\n\n- (id)initWithTitle:(NSString *)title image:(UIImage *)image {\n  self = [super initWithTitle:title image:image];\n  if (self) {\n    _designatedInitializerWasExecuted = YES;\n  }\n  return self;\n}\n\n@end\n\n@implementation TestSubtitleCellObject\n\n- (id)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle image:(UIImage *)image {\n  self = [super initWithTitle:title subtitle:subtitle image:image];\n  if (self) {\n    _designatedInitializerWasExecuted = YES;\n  }\n  return self;\n}\n\n@end\n"
  },
  {
    "path": "src/models/unittests/NICellFactoryTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCore.h\"\n#import \"NimbusModels.h\"\n\n@interface NICellFactoryTests : XCTestCase\n@end\n\n@implementation NICellFactoryTests\n\n- (void)testKeyClassMapping {\n  NSMutableDictionary* map = [NSMutableDictionary dictionary];\n  [map setObject:[NSObject class] forKey:(id<NSCopying>)[NSString class]];\n\n  // @\"\" is the constant NSString class, which is a subclass of NSString.\n  Class class = [NIActions objectFromKeyClass:[@\"\" class] map:map];\n  XCTAssertNotNil(class, @\"NSString constant should be a subclass of NSString, but no class returned from the map.\");\n  XCTAssertEqual(map.count, (NSUInteger)2, @\"Should be two classes mapped to NSObject now.\");\n  for (class in map.allValues) {\n    XCTAssertEqual(class, [NSObject class], @\"All the mappings should be to NSObject.\");\n  }\n\n  class = [NIActions objectFromKeyClass:NSNumber.class map:map];\n  XCTAssertNil(class, @\"NSNumber should not be mapped.\");\n  XCTAssertEqual(map.count, (NSUInteger)3, @\"Should now be three classes mapped.\");\n\n  class = [NIActions objectFromKeyClass:NSNumber.class map:map];\n  XCTAssertNil(class, @\"NSNumber should still not be mapped.\");\n  XCTAssertEqual(map.count, (NSUInteger)3, @\"Should now be three classes mapped.\");\n}\n\n@end\n"
  },
  {
    "path": "src/models/unittests/NIMutableTableViewModelTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCore.h\"\n#import \"NimbusModels.h\"\n#import \"NITableViewModel+Private.h\"\n\n@interface NIMutableTableViewModelTests : XCTestCase {\n}\n\n@end\n\n\n@implementation NIMutableTableViewModelTests\n\n\n- (void)testInitialization {\n  NIMutableTableViewModel* model = [[NIMutableTableViewModel alloc] initWithDelegate:nil];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 0, @\"The model should be empty.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 0, @\"There should not be any sections.\");\n\n  XCTAssertEqual(model.sections.count, 0U, @\"Should have zero sections.\");\n}\n\n- (void)testAddingObject {\n  NIMutableTableViewModel* model = [[NIMutableTableViewModel alloc] initWithDelegate:nil];\n  \n  [model addObject:[NSNumber numberWithBool:YES]];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 1, @\"The model should have one row.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 1, @\"There should only be one section.\");\n  XCTAssertEqual(model.sections.count, 1U, @\"Should have one section.\");\n\n  [model addObject:[NSNumber numberWithBool:NO]];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 2, @\"The model should have two rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 1, @\"There should only be one section.\");\n  XCTAssertEqual(model.sections.count, 1U, @\"Should have one section.\");\n}\n\n- (void)testAddingObjectToSection {\n  NIMutableTableViewModel* model = [[NIMutableTableViewModel alloc] initWithDelegate:nil];\n\n  [model addObject:[NSNumber numberWithBool:YES]];\n  [model addSectionWithTitle:@\"\"];\n  [model addObject:[NSNumber numberWithBool:NO] toSection:0];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 2, @\"The section should have two rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 2, @\"There should be two sections.\");\n  XCTAssertEqual(model.sections.count, 2U, @\"Should have two sections.\");\n}\n\n- (void)testAddingObjects {\n  NIMutableTableViewModel* model = [[NIMutableTableViewModel alloc] initWithDelegate:nil];\n\n  [model addObjectsFromArray:[NSArray arrayWithObjects:\n                              [NSNumber numberWithBool:YES],\n                              [NSNumber numberWithBool:NO],\n                              nil]];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 2, @\"The model should have two rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 1, @\"There should only be one section.\");\n  XCTAssertEqual(model.sections.count, 1U, @\"Should have one section.\");\n\n  [model addObjectsFromArray:[NSArray arrayWithObjects:\n                              [NSNumber numberWithBool:YES],\n                              [NSNumber numberWithBool:NO],\n                              nil]];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 4, @\"The model should have four rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 1, @\"There should only be one section.\");\n  XCTAssertEqual(model.sections.count, 1U, @\"Should have one section.\");\n}\n\n- (void)testRemovingObject {\n  NIMutableTableViewModel* model = [[NIMutableTableViewModel alloc] initWithDelegate:nil];\n  \n  [model addObject:[NSNumber numberWithBool:YES]];\n  [model addObject:[NSNumber numberWithBool:YES]];\n  [model addObject:[NSNumber numberWithBool:YES]];\n  \n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 3, @\"The model should have three rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 1, @\"There should only be one section.\");\n  \n  [model removeObjectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 2, @\"The model should have two rows.\");\n\n  [model removeObjectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];\n  [model removeObjectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 0, @\"The model should have zero rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 1, @\"There should still be one section.\");\n  XCTAssertEqual(model.sections.count, 1U, @\"Should have one section.\");\n}\n\n- (void)testAddingSection {\n  NIMutableTableViewModel* model = [[NIMutableTableViewModel alloc] initWithDelegate:nil];\n\n  [model addObject:[NSNumber numberWithBool:YES]];\n  [model addSectionWithTitle:@\"Section 2\"];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 1, @\"The first section should have one row.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 2, @\"There should be two sections.\");\n  XCTAssertEqual(model.sections.count, 2U, @\"Should have two sections.\");\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:1], 0, @\"The second section should have no rows.\");\n\n  [model addObject:[NSNumber numberWithBool:YES]];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:1], 1, @\"The second section should have one row.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 2, @\"There should be two sections.\");\n  XCTAssertEqual(model.sections.count, 2U, @\"Should have two sections.\");\n}\n\n- (void)testInsertingSection {\n  NIMutableTableViewModel* model = [[NIMutableTableViewModel alloc] initWithDelegate:nil];\n\n  [model addObject:[NSNumber numberWithBool:YES]];\n  [model insertSectionWithTitle:@\"Section 0\" atIndex:0];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 0, @\"The first section should have zero rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 2, @\"There should be two sections.\");\n  XCTAssertEqual(model.sections.count, 2U, @\"Should have two sections.\");\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:1], 1, @\"The second section should have one row.\");\n  XCTAssertTrue([[model tableView:nil titleForHeaderInSection:0] isEqual:@\"Section 0\"], @\"The section title should have been set.\");\n}\n\n@end\n"
  },
  {
    "path": "src/models/unittests/NITableViewModelTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusCore.h\"\n#import \"NimbusModels.h\"\n#import \"NITableViewModel+Private.h\"\n\n@interface NITableViewModelTests : XCTestCase {\n}\n\n@end\n\n\n@implementation NITableViewModelTests\n\n\n- (void)testEmptyTableViewModel {\n  NITableViewModel* model = [[NITableViewModel alloc] init];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 0, @\"The model should be empty.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 0, @\"There should not be any sections.\");\n  XCTAssertEqual(model.sections.count, 0U, @\"Should have zero sections.\");\n  \n  model = [[NITableViewModel alloc] initWithListArray:nil delegate:nil];\n  \n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 0, @\"The model should be empty.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 0, @\"There should not be any sections.\");\n  \n  model = [[NITableViewModel alloc] initWithSectionedArray:nil delegate:nil];\n  \n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 0, @\"The model should be empty.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 0, @\"There should not be any sections.\");\n  \n  model = [[NITableViewModel alloc] initWithListArray:[NSArray array] delegate:nil];\n  \n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 0, @\"The model should be empty.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 1, @\"There should be one empty section.\");\n  \n  model = [[NITableViewModel alloc] initWithSectionedArray:[NSArray array] delegate:nil];\n  \n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 0, @\"The model should be empty.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 0, @\"There should not be any sections.\");\n}\n\n- (void)testInvalidAccess {\n  NITableViewModel* model = [[NITableViewModel alloc] init];\n\n  XCTAssertNil([model tableView:nil titleForHeaderInSection:0], @\"There should not be a header title.\");\n  XCTAssertNil([model tableView:nil titleForFooterInSection:0], @\"There should not be a footer title.\");\n\n  XCTAssertNil([model tableView:nil titleForHeaderInSection:1], @\"There should not be a header title.\");\n  XCTAssertNil([model tableView:nil titleForFooterInSection:1], @\"There should not be a footer title.\");\n  \n  XCTAssertNil([model tableView:nil titleForHeaderInSection:-1], @\"There should not be a header title.\");\n  XCTAssertNil([model tableView:nil titleForFooterInSection:-1], @\"There should not be a footer title.\");\n}\n\n- (void)testEditing {\n  NITableViewModel* model = [[NITableViewModel alloc] init];\n\n  XCTAssertFalse([model tableView:nil canEditRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]],\n                @\"Should not be able to edit anything.\");\n  XCTAssertFalse([model tableView:nil canEditRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:1]],\n                @\"Should not be able to edit anything.\");\n}\n\n- (void)testListTableViewModel {\n  NSArray* contents = [NSArray arrayWithObjects:\n                       @\"This is a string\",\n                       [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 2\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n                       nil];\n  NITableViewModel* model = [[NITableViewModel alloc] initWithListArray:contents delegate:nil];\n\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 4, @\"The model should have 4 rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 1, @\"There should be 1 section.\");\n  XCTAssertNil([model tableView:nil titleForHeaderInSection:0], @\"There should be no section title.\");\n}\n\n- (void)testListTableViewModel_objectAtIndexPath {\n  id object1 = [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"];\n  id object2 = [NSArray array];\n  id object3 = [NSSet set];\n  NSArray* contents = [NSArray arrayWithObjects:\n                       @\"This is a string\",\n                       object1,\n                       object2,\n                       object3,\n                       nil];\n  NITableViewModel* model = [[NITableViewModel alloc] initWithListArray:contents delegate:nil];\n  \n  XCTAssertEqual([model objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]], @\"This is a string\", @\"The first object should be the string.\");\n  XCTAssertEqual([model objectAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]], object1, @\"Object mismatch.\");\n  XCTAssertEqual([model objectAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]], object2, @\"Object mismatch.\");\n  XCTAssertEqual([model objectAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]], object3, @\"Object mismatch.\");\n\n  XCTAssertNil([model objectAtIndexPath:nil], @\"Should be nil.\");\n\n  NIDebugAssertionsShouldBreak = NO;\n  XCTAssertNil([model objectAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:0]], @\"Should be nil.\");\n  XCTAssertNil([model objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]], @\"Should be nil.\");\n  NIDebugAssertionsShouldBreak = YES;\n}\n\n- (void)testListTableViewModel_indexPathOfObject {\n  id object1 = [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"];\n  id object2 = [NSArray array];\n  id object3 = [NSSet set];\n  NSArray* contents = [NSArray arrayWithObjects:\n                       object1,\n                       object2,\n                       object3,\n                       nil];\n  NITableViewModel* model = [[NITableViewModel alloc] initWithListArray:contents delegate:nil];\n\n  XCTAssertEqualObjects([model indexPathForObject:object1], [NSIndexPath indexPathForRow:0 inSection:0], @\"Object not found at expected index path.\");\n  XCTAssertEqualObjects([model indexPathForObject:object2], [NSIndexPath indexPathForRow:1 inSection:0], @\"Object not found at expected index path.\");\n  XCTAssertEqualObjects([model indexPathForObject:object3], [NSIndexPath indexPathForRow:2 inSection:0], @\"Object not found at expected index path.\");\n\n  XCTAssertNil([model indexPathForObject:nil], @\"Should be nil.\");\n\n  NIDebugAssertionsShouldBreak = NO;\n  XCTAssertNil([model indexPathForObject:@\"Random string\"], @\"Should be nil.\");\n  NIDebugAssertionsShouldBreak = YES;\n}\n\n- (void)testSectionedTableViewModel {\n  NSArray* contents = [NSArray arrayWithObjects:\n                       @\"Section 1\",\n                       [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 2\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n                       @\"Section 2\",\n                       [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n                       @\"Section 3\",\n                       @\"Section 4\",\n                       @\"Section 5\",\n                       nil];\n  NITableViewModel* model = [[NITableViewModel alloc] initWithSectionedArray:contents delegate:nil];\n  \n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 3, @\"The first section should have 3 rows.\");\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:1], 2, @\"The second section should have 2 rows.\");\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:2], 0, @\"The third section should have 0 rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 5, @\"There should be 5 sections.\");\n}\n\n- (void)testSectionedTableViewModelWithFooters {\n  NSArray* contents = [NSArray arrayWithObjects:\n                       @\"Section 1\",\n                       [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 2\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 1\"],\n                       @\"Section 2\",\n                       [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 2\"],\n                       @\"Section 3\",\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 3\"],\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 4\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 5\"],\n                       @\"Section 6\",\n                       @\"Section 7\",\n                       nil];\n  NITableViewModel* model = [[NITableViewModel alloc] initWithSectionedArray:contents delegate:nil];\n  \n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:0], 3, @\"The first section should have 3 rows.\");\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:1], 2, @\"The second section should have 2 rows.\");\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:2], 0, @\"The third section should have 0 rows.\");\n  XCTAssertEqual([model tableView:nil numberOfRowsInSection:3], 0, @\"The fourth section should have 0 rows.\");\n  XCTAssertEqual([model numberOfSectionsInTableView:nil], 7, @\"There should be 7 sections.\");\n  XCTAssertEqual([model tableView:nil titleForHeaderInSection:0], @\"Section 1\", @\"The titles should match.\");\n  XCTAssertEqual([model tableView:nil titleForHeaderInSection:1], @\"Section 2\", @\"The titles should match.\");\n  XCTAssertEqual([model tableView:nil titleForFooterInSection:0], @\"Footer 1\", @\"The titles should match.\");\n  XCTAssertEqual([model tableView:nil titleForFooterInSection:1], @\"Footer 2\", @\"The titles should match.\");\n  XCTAssertNil([model tableView:nil titleForFooterInSection:6], @\"There should not be a title.\");\n}\n\n- (void)testDynamicSectionedIndex {\n  NSArray* contents = [NSArray arrayWithObjects:\n                       @\"A\",\n                       [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 2\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 1\"],\n                       @\"C\",\n                       [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 2\"],\n                       @\"D\",\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 3\"],\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 4\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 1\" forKey:@\"title\"],\n                       [NSDictionary dictionaryWithObject:@\"Row 3\" forKey:@\"title\"],\n                       [NITableViewModelFooter footerWithTitle:@\"Footer 5\"],\n                       nil];\n  NITableViewModel* model = [[NITableViewModel alloc] initWithSectionedArray:contents delegate:nil];\n  [model setSectionIndexType:NITableViewModelSectionIndexDynamic showsSearch:YES showsSummary:YES];\n\n  XCTAssertEqual(model.sectionIndexType, NITableViewModelSectionIndexDynamic, @\"Section index type should have been set.\");\n  NSArray* sectionIndexTitles = [model sectionIndexTitlesForTableView:nil];\n  NSArray* expectedTitle = [NSArray arrayWithObjects:UITableViewIndexSearch, @\"A\", @\"C\", @\"D\", @\"#\", nil];\n  XCTAssertEqual(sectionIndexTitles.count, expectedTitle.count, @\"Arrays should be the same size.\");\n  for (NSInteger ix = 0; ix < sectionIndexTitles.count; ++ix) {\n    XCTAssertEqual([sectionIndexTitles objectAtIndex:ix], [expectedTitle objectAtIndex:ix], @\"Objects should match.\");\n  }\n\n  [model setSectionIndexType:NITableViewModelSectionIndexDynamic showsSearch:NO showsSummary:YES];\n\n  XCTAssertEqual(model.sectionIndexType, NITableViewModelSectionIndexDynamic, @\"Section index type should have been set.\");\n  sectionIndexTitles = [model sectionIndexTitlesForTableView:nil];\n  expectedTitle = [NSArray arrayWithObjects:@\"A\", @\"C\", @\"D\", @\"#\", nil];\n  XCTAssertEqual(sectionIndexTitles.count, expectedTitle.count, @\"Arrays should be the same size.\");\n  for (NSInteger ix = 0; ix < sectionIndexTitles.count; ++ix) {\n    XCTAssertEqual([sectionIndexTitles objectAtIndex:ix], [expectedTitle objectAtIndex:ix], @\"Objects should match.\");\n  }\n\n  [model setSectionIndexType:NITableViewModelSectionIndexDynamic showsSearch:YES showsSummary:NO];\n\n  XCTAssertEqual(model.sectionIndexType, NITableViewModelSectionIndexDynamic, @\"Section index type should have been set.\");\n  sectionIndexTitles = [model sectionIndexTitlesForTableView:nil];\n  expectedTitle = [NSArray arrayWithObjects:UITableViewIndexSearch, @\"A\", @\"C\", @\"D\", nil];\n  XCTAssertEqual(sectionIndexTitles.count, expectedTitle.count, @\"Arrays should be the same size.\");\n  for (NSInteger ix = 0; ix < sectionIndexTitles.count; ++ix) {\n    XCTAssertEqual([sectionIndexTitles objectAtIndex:ix], [expectedTitle objectAtIndex:ix], @\"Objects should match.\");\n  }\n\n  [model setSectionIndexType:NITableViewModelSectionIndexDynamic showsSearch:NO showsSummary:NO];\n\n  XCTAssertEqual(model.sectionIndexType, NITableViewModelSectionIndexDynamic, @\"Section index type should have been set.\");\n  sectionIndexTitles = [model sectionIndexTitlesForTableView:nil];\n  expectedTitle = [NSArray arrayWithObjects:@\"A\", @\"C\", @\"D\", nil];\n  XCTAssertEqual(sectionIndexTitles.count, expectedTitle.count, @\"Arrays should be the same size.\");\n  for (NSInteger ix = 0; ix < sectionIndexTitles.count; ++ix) {\n    XCTAssertEqual([sectionIndexTitles objectAtIndex:ix], [expectedTitle objectAtIndex:ix], @\"Objects should match.\");\n  }\n}\n\n@end\n"
  },
  {
    "path": "src/models/unittests/NimbusModelsTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/networkcontrollers/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\n"
  },
  {
    "path": "src/networkcontrollers/src/NINetworkTableViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n/**\n * The NINetworkTableViewController class provides a similar implementation to UITableViewController\n * but with a more structured view hierarchy.\n *\n * UITableViewController's self.view \\em is its self.tableView. This can be problematic if you want\n * to introduce any sibling views that have a higher or lower z-index. This class provides an\n * implementation that, to the best of its abilities, mimics the functionality of\n * UITableViewController in every way but one: self.tableView is a subview of self.view. This simple\n * difference allows us to add new views above the tableView in the z-index.\n *\n * In this particular implementation we include an activity indicator component which may be used\n * to show that data is currently being loaded.\n *\n * @ingroup NimbusNetworkControllers\n */\n@interface NINetworkTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>\n\n// Designated initializer.\n- (id)initWithStyle:(UITableViewStyle)style activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle;\n\n@property (nonatomic, strong) UITableView* tableView;\n@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator;\n@property (nonatomic, assign) BOOL clearsSelectionOnViewWillAppear; // Default: YES\n\n- (void)setIsLoading:(BOOL)isLoading;\n\n@end\n\n/**\n * Sets the loading state of the view controller.\n *\n * @param isLoading When YES, the table view will be hidden and an activity indicator will be\n *                       shown centered in the view controller's view.\n *                       When NO, the table view will be shown and the activity indicator hidden.\n * @fn NINetworkTableViewController::setIsLoading:\n */\n"
  },
  {
    "path": "src/networkcontrollers/src/NINetworkTableViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NINetworkTableViewController.h\"\n\n#import \"NimbusCore+Additions.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NINetworkTableViewController()\n@property (nonatomic, assign) UIActivityIndicatorViewStyle activityIndicatorStyle;\n@property (nonatomic, assign) UITableViewStyle tableViewStyle;\n@end\n\n\n@implementation NINetworkTableViewController\n\n\n\n- (void)dealloc {\n  _tableView.delegate = nil;\n  _tableView.dataSource = nil;\n}\n\n- (id)initWithStyle:(UITableViewStyle)style activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle {\n  if ((self = [super initWithNibName:nil bundle:nil])) {\n    self.tableViewStyle = style;\n    self.activityIndicatorStyle = activityIndicatorStyle;\n    self.clearsSelectionOnViewWillAppear = YES;\n  }\n  return self;\n}\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  return [self initWithStyle:UITableViewStylePlain\n      activityIndicatorStyle:UIActivityIndicatorViewStyleGray];\n}\n\n- (void)loadView {\n  [super loadView];\n\n  self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:self.tableViewStyle];\n  self.tableView.autoresizingMask =\n      (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  self.tableView.delegate = self;\n  self.tableView.dataSource = self;\n  [self.view addSubview:self.tableView];\n\n  self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorStyle];\n  self.activityIndicator.autoresizingMask =\n      (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin\n       | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin);\n  [self.activityIndicator sizeToFit];\n  self.activityIndicator.frame = NIFrameOfCenteredViewWithinView(self.activityIndicator, self.view);\n  [self.view addSubview:self.activityIndicator];\n}\n\n- (void)viewWillAppear:(BOOL)animated {\n  [super viewWillAppear:animated];\n\n  if (self.clearsSelectionOnViewWillAppear) {\n    [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow\n                                  animated:animated];\n  }\n}\n\n#pragma mark - UITableViewDataSource\n\n\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {\n  return 0;\n}\n\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {\n  return nil;\n}\n\n#pragma mark - Public\n\n\n- (void)setIsLoading:(BOOL)isLoading {\n  self.tableView.hidden = isLoading;\n\n  if (isLoading) {\n    [self.activityIndicator startAnimating];\n\n  } else {\n    [self.activityIndicator stopAnimating];\n  }\n}\n\n@end\n"
  },
  {
    "path": "src/networkcontrollers/src/NimbusNetworkControllers.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * @defgroup NimbusNetworkControllers Nimbus Network Controllers\n * @{\n *\n * <div id=\"github\" feature=\"networkcontrollers\"></div>\n *\n * View controllers that display loading states while they load information from the network or\n * disk.\n *\n * Whether you are loading data from the disk or from the network, it is important to present\n * the fact that information is loading to your user. This ensures that your application feels\n * responsive and also comforts the user by letting them know that your application is working\n * on something.\n *\n * The Nimbus network controllers are designed to provide functionality for the most common states\n * used when loading resources asynchronously. These states include:\n *\n * - Fresh load: when no data exists and we are loading new data.\n * - Refresh load: when data exists and we are reloading new data.\n * - Error: the previous request failed.\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NINetworkTableViewController.h\"\n\n/**@}*/\n"
  },
  {
    "path": "src/networkcontrollers/unittests/NINetworkTableViewControllerTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusNetworkControllers.h\"\n\n@interface NINetworkTableViewControllerTests : XCTestCase\n@end\n\n\n@implementation NINetworkTableViewControllerTests\n\n\n- (void)testNothing {\n}\n\n@end\n"
  },
  {
    "path": "src/networkcontrollers/unittests/NetworkControllersTests-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": "src/networkimage/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\nAFNetworking"
  },
  {
    "path": "src/networkimage/src/NIImageProcessing.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NINetworkImageView.h\"  // For NINetworkImageViewScaleOptions\n\n#import \"NimbusCore.h\"\n\n@interface NIImageProcessing : NSObject\n\n/** @name Image Modifications */\n\n/**\n * Takes a source image and resizes/crops it according to a set of display properties.\n *\n * On devices with retina displays, the resulting image will be returned at the correct\n * resolution for the device.\n *\n * @param src                  The source image.\n * @param contentMode          The content mode to use when cropping and resizing the image.\n * @param cropRect             An initial crop rect to apply to the src image.\n * @param displaySize          The requested display size for the image. The resulting image\n *                                  may or may not match these dimensions depending on the scale\n *                                  options being used.\n * @param scaleOptions         See the NINetworkImageViewScaleOptions documentation for more\n *                                  details.\n * @param interpolationQuality The interpolation quality to use when resizing the image.\n *\n * @returns The resized and cropped image.\n */\n+ (UIImage *)imageFromSource:(UIImage *)src\n             withContentMode:(UIViewContentMode)contentMode\n                    cropRect:(CGRect)cropRect\n                 displaySize:(CGSize)displaySize\n                scaleOptions:(NINetworkImageViewScaleOptions)scaleOptions\n        interpolationQuality:(CGInterpolationQuality)interpolationQuality;\n\n@end\n"
  },
  {
    "path": "src/networkimage/src/NIImageProcessing.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIImageProcessing.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NIImageProcessing\n\n/**\n * Calculate the source rect in the source image from which we'll extract the image before drawing\n * it in the destination image.\n */\n+ (CGRect)sourceRectWithImageSize:(CGSize)imageSize\n                      displaySize:(CGSize)displaySize\n                      contentMode:(UIViewContentMode)contentMode {\n  if (UIViewContentModeScaleToFill == contentMode) {\n    // Scale to fill draws the original image by squashing it to fit the destination's\n    // aspect ratio, so the source and destination rects aren't modified.\n    return CGRectMake(0, 0, imageSize.width, imageSize.height);\n\n  } else if (UIViewContentModeScaleAspectFit == contentMode) {\n    // Aspect fit grabs the entire original image and squashes it down to a frame that fits\n    // the destination and leaves the unfilled space transparent.\n    return CGRectMake(0, 0, imageSize.width, imageSize.height);\n\n  } else if (UIViewContentModeScaleAspectFill == contentMode) {\n    // Aspect fill requires that we take the destination rectangle and \"fit\" it within the\n    // source rectangle; this gives us the area of the source image we'll crop out to draw into\n    // the destination image.\n    CGFloat scale = MIN(imageSize.width / displaySize.width,\n                        imageSize.height / displaySize.height);\n    CGSize scaledDisplaySize = CGSizeMake(displaySize.width * scale, displaySize.height * scale);\n    return CGRectMake(floorf((imageSize.width - scaledDisplaySize.width) / 2),\n                      floorf((imageSize.height - scaledDisplaySize.height) / 2),\n                      scaledDisplaySize.width,\n                      scaledDisplaySize.height);\n\n  } else if (UIViewContentModeCenter == contentMode) {\n    // We need to cut out a hole the size of the display in the center of the source image.\n    return CGRectMake(floorf((imageSize.width - displaySize.width) / 2),\n                      floorf((imageSize.width - displaySize.width) / 2),\n                      displaySize.width, displaySize.height);\n\n  } else if (UIViewContentModeTop == contentMode) {\n    // We need to cut out a hole the size of the display in the top center of the source image.\n    return CGRectMake(floorf((imageSize.width - displaySize.width) / 2),\n                      0,\n                      displaySize.width, displaySize.height);\n\n  } else if (UIViewContentModeBottom == contentMode) {\n    // We need to cut out a hole the size of the display in the bottom center of the source image.\n    return CGRectMake(floorf((imageSize.width - displaySize.width) / 2),\n                      imageSize.height - displaySize.height,\n                      displaySize.width, displaySize.height);\n\n  } else if (UIViewContentModeLeft == contentMode) {\n    // We need to cut out a hole the size of the display in the left center of the source image.\n    return CGRectMake(0,\n                      floorf((imageSize.width - displaySize.width) / 2),\n                      displaySize.width, displaySize.height);\n\n  } else if (UIViewContentModeRight == contentMode) {\n    // We need to cut out a hole the size of the display in the right center of the source image.\n    return CGRectMake(imageSize.width - displaySize.width,\n                      floorf((imageSize.width - displaySize.width) / 2),\n                      displaySize.width, displaySize.height);\n\n  } else if (UIViewContentModeTopLeft == contentMode) {\n    // We need to cut out a hole the size of the display in the top left of the source image.\n    return CGRectMake(0,\n                      0,\n                      displaySize.width, displaySize.height);\n\n  } else if (UIViewContentModeTopRight == contentMode) {\n    // We need to cut out a hole the size of the display in the top right of the source image.\n    return CGRectMake(imageSize.width - displaySize.width,\n                      0,\n                      displaySize.width, displaySize.height);\n\n  } else if (UIViewContentModeBottomLeft == contentMode) {\n    // We need to cut out a hole the size of the display in the bottom left of the source image.\n    return CGRectMake(0,\n                      imageSize.height - displaySize.height,\n                      displaySize.width, displaySize.height);\n\n  } else if (UIViewContentModeBottomRight == contentMode) {\n    // We need to cut out a hole the size of the display in the bottom right of the source image.\n    return CGRectMake(imageSize.width - displaySize.width,\n                      imageSize.height - displaySize.height,\n                      displaySize.width, displaySize.height);\n\n  } else {\n    // Not implemented\n    NIDERROR(@\"The following content mode has not been implemented: %zd\", contentMode);\n    return CGRectMake(0, 0, imageSize.width, imageSize.height);\n  }\n}\n\n/**\n * Calculate the destination rect in the destination image where we will draw the cropped source\n * image.\n */\n+ (CGRect)destinationRectWithImageSize:(CGSize)imageSize\n                           displaySize:(CGSize)displaySize\n                           contentMode:(UIViewContentMode)contentMode {\n  if (UIViewContentModeScaleAspectFit == contentMode) {\n    // Fit the image right in the center of the source frame and maintain the aspect ratio.\n    CGFloat scale = MIN(displaySize.width / imageSize.width,\n                        displaySize.height / imageSize.height);\n    CGSize scaledImageSize = CGSizeMake(imageSize.width * scale, imageSize.height * scale);\n    return CGRectMake(floorf((displaySize.width - scaledImageSize.width) / 2),\n                      floorf((displaySize.height - scaledImageSize.height) / 2),\n                      scaledImageSize.width,\n                      scaledImageSize.height);\n\n  } else if (UIViewContentModeScaleToFill == contentMode\n             || UIViewContentModeScaleAspectFill == contentMode\n             || UIViewContentModeCenter == contentMode\n             || UIViewContentModeTop == contentMode\n             || UIViewContentModeBottom == contentMode\n             || UIViewContentModeLeft == contentMode\n             || UIViewContentModeRight == contentMode\n             || UIViewContentModeTopLeft == contentMode\n             || UIViewContentModeTopRight == contentMode\n             || UIViewContentModeBottomLeft == contentMode\n             || UIViewContentModeBottomRight == contentMode) {\n    // We're filling the entire destination, so the destination rect is the display rect.\n    return CGRectMake(0, 0, displaySize.width, displaySize.height);\n\n  } else {\n    // Not implemented\n    NIDERROR(@\"The following content mode has not been implemented: %zd\", contentMode);\n    return CGRectMake(0, 0, displaySize.width, displaySize.height);\n  }\n}\n\n+ (UIImage *)imageFromSource:(UIImage *)src\n             withContentMode:(UIViewContentMode)contentMode\n                    cropRect:(CGRect)cropRect\n                 displaySize:(CGSize)displaySize\n                scaleOptions:(NINetworkImageViewScaleOptions)scaleOptions\n        interpolationQuality:(CGInterpolationQuality)interpolationQuality {\n\n  UIImage* resultImage = src;\n\n  CGImageRef srcImageRef = src.CGImage;\n  CGImageRef croppedImageRef = nil;\n  CGImageRef trimmedImageRef = nil;\n\n  CGRect srcRect = CGRectMake(0, 0, src.size.width, src.size.height);\n\n  // Cropping\n  if (!CGRectIsEmpty(cropRect)\n      && !CGRectEqualToRect(cropRect, CGRectMake(0, 0, 1, 1))) {\n    CGRect innerRect = CGRectMake(floorf(src.size.width * cropRect.origin.x),\n                                  floorf(src.size.height * cropRect.origin.y),\n                                  floorf(src.size.width * cropRect.size.width),\n                                  floorf(src.size.height * cropRect.size.height));\n\n    // Create a new image containing only the cropped inner rect.\n    srcImageRef = CGImageCreateWithImageInRect(srcImageRef, innerRect);\n    croppedImageRef = srcImageRef;\n\n    // This new image will likely have a different width and height, so we have to update\n    // the source rect as a result.\n    srcRect = CGRectMake(0, 0, CGRectGetWidth(innerRect), CGRectGetHeight(innerRect));\n  }\n\n  // Display\n  if (0 < displaySize.width\n      && 0 < displaySize.height) {\n\n    if ((NINetworkImageViewScaleToFillLeavesExcess\n         == (NINetworkImageViewScaleToFillLeavesExcess & scaleOptions))\n        && UIViewContentModeScaleAspectFill == contentMode) {\n      // Make the display size match the aspect ratio of the source image by growing the\n      // display size.\n      CGFloat imageAspectRatio = srcRect.size.width / srcRect.size.height;\n      CGFloat displayAspectRatio = displaySize.width / displaySize.height;\n\n      if (imageAspectRatio > displayAspectRatio) {\n        // The image is wider than the display, so let's increase the width.\n        displaySize.width = displaySize.height * imageAspectRatio;\n\n      } else if (imageAspectRatio < displayAspectRatio) {\n        // The image is taller than the display, so let's increase the height.\n        displaySize.height = displaySize.width * (srcRect.size.height / srcRect.size.width);\n      }\n\n    } else if ((NINetworkImageViewScaleToFitCropsExcess\n                == (NINetworkImageViewScaleToFitCropsExcess & scaleOptions))\n               && UIViewContentModeScaleAspectFit == contentMode) {\n      // Make the display size match the aspect ratio of the source image by shrinking the\n      // display size.\n      CGFloat imageAspectRatio = srcRect.size.width / srcRect.size.height;\n      CGFloat displayAspectRatio = displaySize.width / displaySize.height;\n\n      if (imageAspectRatio > displayAspectRatio) {\n        // The image is wider than the display, so let's decrease the height.\n        displaySize.height = displaySize.width * (srcRect.size.height / srcRect.size.width);\n\n      } else if (imageAspectRatio < displayAspectRatio) {\n        // The image is taller than the display, so let's decrease the width.\n        displaySize.width = displaySize.height * imageAspectRatio;\n      }\n    }\n\n    CGRect srcCropRect = [self sourceRectWithImageSize: srcRect.size\n                                           displaySize: displaySize\n                                           contentMode: contentMode];\n    srcCropRect = CGRectMake(floorf(srcCropRect.origin.x),\n                             floorf(srcCropRect.origin.y),\n                             roundf(srcCropRect.size.width),\n                             roundf(srcCropRect.size.height));\n\n    // Do we need to crop the source?\n    if (!CGRectEqualToRect(srcCropRect, srcRect)) {\n      srcImageRef = CGImageCreateWithImageInRect(srcImageRef, srcCropRect);\n      trimmedImageRef = srcImageRef;\n\n      srcRect = CGRectMake(0, 0,\n                           CGRectGetWidth(srcCropRect),\n                           CGRectGetHeight(srcCropRect));\n\n      // Release the cropped image source to reduce this thread's memory consumption.\n      if (nil != croppedImageRef) {\n        CGImageRelease(croppedImageRef);\n        croppedImageRef = nil;\n      }\n    }\n\n    // Calcuate the destination frame.\n    CGRect dstBlitRect = [self destinationRectWithImageSize: srcRect.size\n                                                displaySize: displaySize\n                                                contentMode: contentMode];\n    dstBlitRect = CGRectMake(floorf(dstBlitRect.origin.x),\n                             floorf(dstBlitRect.origin.y),\n                             roundf(dstBlitRect.size.width),\n                             roundf(dstBlitRect.size.height));\n\n    // Round any remainder on the display size dimensions.\n    displaySize = CGSizeMake(roundf(displaySize.width), roundf(displaySize.height));\n\n    // See table \"Supported Pixel Formats\" in the following guide for support iOS bitmap formats:\n    // http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html\n    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();\n    CGBitmapInfo bmi = (CGBitmapInfo)kCGImageAlphaPremultipliedLast;\n\n    // For screen sizes with higher resolutions, we create a larger image with a scale value\n    // so that it appears crisper on the screen.\n    CGFloat screenScale = NIScreenScale();\n\n    // Create our final composite image.\n    CGContextRef dstBmp = CGBitmapContextCreate(NULL,\n                                                displaySize.width * screenScale,\n                                                displaySize.height * screenScale,\n                                                8,\n                                                0,\n                                                colorSpace,\n                                                bmi);\n\n    // If this fails then we're likely creating an invalid bitmap and shit's about to go down.\n    // In production this will fail somewhat gracefully, in that we'll end up just using the\n    // source image instead of the cropped and resized image.\n    NIDASSERT(nil != dstBmp);\n\n    if (nil != dstBmp) {\n      CGRect dstRect = CGRectMake(0, 0,\n                                  displaySize.width * screenScale,\n                                  displaySize.height * screenScale);\n\n      // Render the source image into the destination image.\n      CGContextClearRect(dstBmp, dstRect);\n      CGContextSetInterpolationQuality(dstBmp, interpolationQuality);\n\n      CGRect scaledBlitRect = CGRectMake(dstBlitRect.origin.x * screenScale,\n                                         dstBlitRect.origin.y * screenScale,\n                                         dstBlitRect.size.width * screenScale,\n                                         dstBlitRect.size.height * screenScale);\n      CGContextDrawImage(dstBmp, scaledBlitRect, srcImageRef);\n\n      CGImageRef resultImageRef = CGBitmapContextCreateImage(dstBmp);\n\n      if (nil != resultImageRef) {\n        resultImage = [UIImage imageWithCGImage:resultImageRef\n                                          scale:screenScale\n                                    orientation:src.imageOrientation];\n        CGImageRelease(resultImageRef);\n      }\n\n      CGContextRelease(dstBmp);\n    }\n\n    CGColorSpaceRelease(colorSpace);\n\n  } else if (nil != croppedImageRef) {\n    resultImage = [UIImage imageWithCGImage:srcImageRef];\n  }\n\n  // Memory cleanup.\n  if (nil != trimmedImageRef) {\n    CGImageRelease(trimmedImageRef);\n  }\n  if (nil != croppedImageRef) {\n    CGImageRelease(croppedImageRef);\n  }\n\n  return resultImage;\n}\n\n@end\n"
  },
  {
    "path": "src/networkimage/src/NIImageResponseSerializer.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"AFURLResponseSerialization.h\"\n\n#import \"NINetworkImageView.h\" // For NINetworkImageViewScaleOptions.\n\n/**\n * The NIImageResponseSerializer class provides an implementation of the AFNetworking serializer\n * object for Nimbus network images.\n *\n * This object is used internally with NINetworkImageView, though it can be used with custom\n * AFNetworking implementations. Each of the properties should be respected as per the documentation\n * in NIImageProcessing.\n */\n@interface NIImageResponseSerializer : AFImageResponseSerializer\n@property (nonatomic, assign) UIViewContentMode contentMode;\n@property (nonatomic, assign) CGRect cropRect;\n@property (nonatomic, assign) CGSize displaySize;\n@property (nonatomic, assign) NINetworkImageViewScaleOptions scaleOptions;\n@property (nonatomic, assign) CGInterpolationQuality interpolationQuality;\n@end\n"
  },
  {
    "path": "src/networkimage/src/NIImageResponseSerializer.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIImageResponseSerializer.h\"\n\n#import \"NIImageProcessing.h\"\n\n@implementation NIImageResponseSerializer\n\n- (id)responseObjectForResponse:(NSURLResponse *)response\n                           data:(NSData *)data\n                          error:(NSError *__autoreleasing *)error {\n  id responseObject = [super responseObjectForResponse:response data:data error:error];\n  if (nil != responseObject && [responseObject isKindOfClass:[UIImage class]]) {\n    responseObject = [NIImageProcessing imageFromSource:responseObject\n                                        withContentMode:self.contentMode\n                                               cropRect:self.cropRect\n                                            displaySize:self.displaySize\n                                           scaleOptions:self.scaleOptions\n                                   interpolationQuality:self.interpolationQuality];\n  }\n  return responseObject;\n}\n\n@end\n"
  },
  {
    "path": "src/networkimage/src/NINetworkImageView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIInMemoryCache.h\"\n#import \"NIOperations.h\"\n#import \"NimbusCore.h\"\n\n@protocol NINetworkImageViewDelegate;\n@protocol ASICacheDelegate;\n\n// See the diskCacheLifetime property for more documentation related to this enumeration.\ntypedef enum {\n  /**\n   * Store images on disk in the session disk cache. Images stored with this lifetime will\n   * be removed when the app starts again or when the session cache is explicitly cleared.\n   */\n  NINetworkImageViewDiskCacheLifetimeSession,\n\n  /**\n   * Store images on disk in the permanent disk cache. Images stored with this lifetime will\n   * only be removed when the permanent cache is explicitly cleared.\n   */\n  NINetworkImageViewDiskCacheLifetimePermanent,\n} NINetworkImageViewDiskCacheLifetime;\n\ntypedef enum {\n  NINetworkImageViewScaleToFitLeavesExcessAndScaleToFillCropsExcess = 0x00,\n  NINetworkImageViewScaleToFitCropsExcess    = 0x01,\n  NINetworkImageViewScaleToFillLeavesExcess  = 0x02,\n} NINetworkImageViewScaleOptions;\n\n/**\n * A protocol defining the set of characteristics for an operation to be used with\n * NINetworkImageView.\n */\n@protocol NINetworkImageOperation <NSObject>\n@required\n@property (readonly, copy) NSString* cacheIdentifier;\n@property (assign) CGRect imageCropRect;\n@property (assign) CGSize imageDisplaySize;\n@property (assign) NINetworkImageViewScaleOptions scaleOptions;\n@property (assign) CGInterpolationQuality interpolationQuality;\n@property (assign) UIViewContentMode imageContentMode;\n@property (strong) UIImage* imageCroppedAndSizedForDisplay;\n@end\n\n/**\n * A network-enabled image view that consumes minimal amounts of memory.\n *\n * Intelligently crops and resizes images for optimal memory use and uses threads to avoid\n * processing images on the UI thread.\n *\n * @ingroup NimbusNetworkImage\n */\n@interface NINetworkImageView : UIImageView <NIOperationDelegate>\n\n#pragma mark Creating a Network Image View\n\n- (id)initWithImage:(UIImage *)image;\n\n#pragma mark Configurable Presentation Properties\n\n@property (nonatomic, strong) UIImage* initialImage;     // Default: nil\n@property (nonatomic, assign) BOOL sizeForDisplay;       // Default: YES\n@property (nonatomic, assign) NINetworkImageViewScaleOptions scaleOptions; // Default: NINetworkImageViewScaleToFitLeavesExcessAndScaleToFillCropsExcess\n@property (nonatomic, assign) CGInterpolationQuality interpolationQuality; // Default: kCGInterpolationDefault\n\n#pragma mark Configurable Properties\n\n@property (nonatomic, strong) NIImageMemoryCache* imageMemoryCache;    // Default: [Nimbus imageMemoryCache]\n@property (nonatomic, strong) NSOperationQueue* networkOperationQueue; // Default: [Nimbus networkOperationQueue]\n\n@property (nonatomic, assign) NSTimeInterval maxAge;     // Default: 0\n\n#pragma mark Requesting a Network Image\n\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage;\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage forDisplaySize:(CGSize)displaySize;\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage forDisplaySize:(CGSize)displaySize contentMode:(UIViewContentMode)contentMode;\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage forDisplaySize:(CGSize)displaySize contentMode:(UIViewContentMode)contentMode cropRect:(CGRect)cropRect;\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage cropRect:(CGRect)cropRect;\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage contentMode:(UIViewContentMode)contentMode;\n\n- (void)setNetworkImageOperation:(NIOperation<NINetworkImageOperation> *)operation forDisplaySize:(CGSize)displaySize contentMode:(UIViewContentMode)contentMode cropRect:(CGRect)cropRect;\n\n#pragma mark State\n\n@property (nonatomic, readonly, assign, getter=isLoading) BOOL loading;\n\n#pragma mark Reusable View\n\n- (void)prepareForReuse;\n\n#pragma mark Delegation\n\n@property (nonatomic, weak) id<NINetworkImageViewDelegate> delegate;\n\n#pragma mark Subclassing\n\n- (void)networkImageViewDidStartLoading;\n- (void)networkImageViewDidLoadImage:(UIImage *)image;\n- (void)networkImageViewDidFailWithError:(NSError *)error;\n\n@end\n\n\n/**\n * The image view delegate used to inform of state changes.\n *\n * @ingroup NimbusNetworkImage\n */\n@protocol NINetworkImageViewDelegate <NSObject>\n@optional\n\n/**\n * The image has begun an asynchronous download of the image.\n */\n- (void)networkImageViewDidStartLoad:(NINetworkImageView *)imageView;\n\n/**\n * The image has completed an asynchronous download of the image.\n */\n- (void)networkImageView:(NINetworkImageView *)imageView didLoadImage:(UIImage *)image;\n\n/**\n * The asynchronous download failed.\n */\n- (void)networkImageView:(NINetworkImageView *)imageView didFailWithError:(NSError *)error;\n\n/**\n * The progress of the download.\n */\n- (void)networkImageView:(NINetworkImageView *)imageView readBytes:(long long)readBytes totalBytes:(long long)totalBytes;\n\n@end\n\n/**\n * Flags for modifying the way cropping is handled when scaling images to fit or fill.\n *\n * @enum NINetworkImageViewScaleOptions\n * @ingroup NimbusNetworkImage\n *\n * By default the network image view will behave in the following way for these content modes:\n *\n * - <b>UIViewContentModeScaleAspectFit</b>: Leaves unfilled space as transparent.\n * - <b>UIViewContentModeScaleAspectFill</b>: Crops any excess pixels.\n *\n * The resulting image size will exactly match the display size.\n *\n * You can modify this behavior using the following two flags which should be set using\n * binary operators.\n *\n * @htmlonly\n * <pre>\n *   NINetworkImageViewScaleToFitCropsRemainder\n *   The final image size will be shrunk to fit the image such that there is no transparency.\n *\n *   NINetworkImageViewScaleToFillLeavesRemainder\n *   The final image size will be grown to include the excess pixels.\n * </pre>\n * @endhtmlonly\n *\n * <h1>Examples</h1>\n *\n * The following examples use this image:\n *\n * @image html clouds500x375.jpeg \"Dimensions: 500x375\"\n *\n *\n * <h2>Default settings with UIViewContentModeScaleAspectFit</h2>\n *\n * <h3>Result image (display size 100x100)</h3>\n *\n * @image html clouds100x100-fit.png \"Fit image with default settings leaves transparent pixels. Size: 100x100.\"\n *\n * <h3>Example code</h3>\n *\n * @code\n *  imageView.scaleOptions = NINetworkImageViewScaleToFitLeavesExcessAndScaleToFillCropsExcess;\n *\n *  [imageView setPathToNetworkImage: @\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"\n *                    forDisplaySize: CGSizeMake(100, 100)\n *                       contentMode: UIViewContentModeScaleAspectFit];\n *\n *       source image size: 500x375  [aspect ratio: 1.3333]\n *            display size: 100x100  [aspect ratio: 1]\n *       result image size: 100x100  [aspect ratio: 1] (transparency on the left and right edges)\n *          image blt size: 100x75   [aspect ratio: 1.3333]\n * @endcode\n *\n *\n * <h2>Default settings with UIViewContentModeScaleAspectFill</h2>\n *\n * <h3>Result image (display size 100x100)</h3>\n *\n * @image html clouds100x100-fill.png \"Fill image with default settings chops excess pixels. Size: 100x100.\"\n *\n * <h3>Example code</h3>\n *\n * @code\n *  [imageView setPathToNetworkImage: @\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"\n *                    forDisplaySize: CGSizeMake(100, 100)\n *                       contentMode: UIViewContentModeScaleAspectFill];\n *\n *       source image size: 500x375  [aspect ratio: 1.3333]\n *            display size: 100x100  [aspect ratio: 1]\n *       result image size: 100x100  [aspect ratio: 1]\n *          image blt size: 133x100  [aspect ratio: 1.3333]\n * @endcode\n *\n *\n * <h2>NINetworkImageViewScaleToFitCropsExcess with UIViewContentModeScaleAspectFit</h2>\n *\n * <h3>Result image (display size 100x100)</h3>\n *\n * @image html clouds100x100-fit-cropped.png \"Fit image with NINetworkImageViewScaleToFitCropsExcess crops the transparency. Size: 100x75.\"\n *\n * <h3>Example code</h3>\n *\n * @code\n *  // Turn on NINetworkImageViewScaleToFitCropsExcess\n *  imageView.scaleOptions |= NINetworkImageViewScaleToFitCropsExcess;\n *\n *  [imageView setPathToNetworkImage: @\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"\n *                    forDisplaySize: CGSizeMake(100, 100)\n *                       contentMode: UIViewContentModeScaleAspectFill];\n *\n *       source image size: 500x375  [aspect ratio: 1.3333]\n *            display size: 100x100  [aspect ratio: 1]\n *       result image size: 100x75   [aspect ratio: 1.3333]\n *          image blt size: 100x75   [aspect ratio: 1.3333]\n * @endcode\n *\n *\n * <h2>NINetworkImageViewScaleToFillLeavesExcess with UIViewContentModeScaleAspectFill</h2>\n *\n * <h3>Result image (display size 100x100)</h3>\n *\n * @image html clouds100x100-fill-excess.png \"Fill image with NINetworkImageViewScaleToFillLeavesExcess leaves the excess. Size: 133x100.\"\n *\n * <h3>Example code</h3>\n *\n * @code\n *  // Turn on NINetworkImageViewScaleToFillLeavesExcess\n *  imageView.scaleOptions |= NINetworkImageViewScaleToFillLeavesExcess;\n *\n *  [imageView setPathToNetworkImage: @\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"\n *                    forDisplaySize: CGSizeMake(100, 100)\n *                       contentMode: UIViewContentModeScaleAspectFill];\n *\n *       source image size: 500x375  [aspect ratio: 1.3333]\n *            display size: 100x100  [aspect ratio: 1]\n *       result image size: 133x100  [aspect ratio: 1.3333]\n *          image blt size: 133x100  [aspect ratio: 1.3333]\n * @endcode\n */\n\n/**\n * @class NINetworkImageView\n *\n *\n * <h2>Examples</h2>\n *\n * <h3>Two basic methods for setting the display size of the network image</h3>\n *\n * @code\n *  UIImage* image; // some previously loaded image.\n *  NINetworkImageView* imageView = [[[NINetworkImageView alloc] initWithImage:image] autorelease];\n *\n *  // Method #1: Use the image's frame to determine the display size for the network image.\n *  imageView.frame = CGRectMake(0, 0, 100, 100);\n *  [imageView setPathToNetworkImage:@\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"];\n *\n *  // Method #2: use the method setPathToNetworkImage:forDisplaySize:\n *  [imageView setPathToNetworkImage: @\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"\n *                    forDisplaySize: CGSizeMake(100, 100)];\n * @endcode\n *\n * <i>Code Breakdown</i>\n *\n * @code\n *  NINetworkImageView* imageView = [[[NINetworkImageView alloc] initWithImage:image] autorelease];\n * @endcode\n *\n * Initializes the network image view with a preloaded image, usually a \"default\" image\n * to be displayed until the network image downloads.\n *\n * @code\n *  imageView.frame = CGRectMake(0, 0, 100, 100);\n *  [imageView setPathToNetworkImage:@\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"];\n * @endcode\n *\n * We must take care to set the frame before requesting the network image, otherwise the\n * image's display size will be 0,0 and the network image won't be cropped or sized to fit.\n *\n * @code\n *  [imageView setPathToNetworkImage: @\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"\n *                    forDisplaySize: CGSizeMake(100, 100)];\n * @endcode\n *\n * If you don't want to modify the frame of the image, you can alternatively specify\n * the display size as a parameter to the setPathToNetworkImage: method.\n *\n *\n * <h3>Use a different contentMode for the network image.</h3>\n *\n * @code\n *  UIImage* image; // some previously loaded image.\n *  NINetworkImageView* imageView = [[[NINetworkImageView alloc] initWithImage:image] autorelease];\n *\n *  imageView.frame = CGRectMake(0, 0, 100, 100);\n *  imageView.contentMode = UIViewContentModeCenter; // Centers the image in the frame.\n *  [imageView setPathToNetworkImage: @\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"\n *                       contentMode: UIViewContentModeScaleAspectFill];\n * @endcode\n *\n * <i>Code Breakdown</i>\n *\n * @code\n *  [imageView setPathToNetworkImage: @\"http://farm2.static.flickr.com/1165/644335254_4b8a712be5.jpg\"\n *                       contentMode: UIViewContentModeScaleAspectFill];\n * @endcode\n *\n * This means: <i>after the image is downloaded, crop and resize the image with an aspect\n * fill content mode.</i>\n * The image returned from the thread will be cropped and sized to fit the imageView perfectly\n * at the given 100x100 dimensions.\n * Because imageView has a contentMode of UIViewContentModeCenter, if we were to make the\n * image view larger the downloaded image would stay in the center of the image view and\n * leave empty space on all sides.\n */\n\n\n/** @name Creating a Network Image View */\n\n/**\n * Designated initializer.\n *\n * @param image  This will be the initialImage.\n * @fn NINetworkImageView::initWithImage:\n */\n\n\n/**\n * @name Configurable Presentation Properties\n */\n\n/**\n * The image being displayed while the network image is being fetched.\n *\n * This is the same image passed into initWithImage: immediately after initialization. This\n * is used when preparing this view for reuse. Changing the initial image after creating\n * the object will only display the new image if the currently displayed image is\n * is the initial image or nil.\n *\n * The initial image is drawn only using the view's contentMode. Cropping and resizing are only\n * performed on the image fetched from the network.\n *\n * @fn NINetworkImageView::initialImage\n */\n\n/**\n * A flag for enabling the resizing of images for display.\n *\n * When enabled, the downloaded image will be resized to fit the dimensions of the image view\n * using the image view's content mode.\n *\n * When disabled, the full image is drawn as-is. This is generally much less efficient when\n * working with large photos and will also increase the memory footprint.\n *\n * If your images are pre-cropped and sized then this isn't necessary, but the network image\n * loader is smart enough to realize this so it's in your best interest to leave this on.\n *\n * By default this is YES.\n *\n * @fn NINetworkImageView::sizeForDisplay\n */\n\n/**\n * Options for modifying the way images are cropped when scaling.\n *\n * By default this is NINetworkImageViewScaleToFitLeavesExcessAndScaleToFillCropsExcess.\n *\n * @see NINetworkImageViewScaleOptions\n * @fn NINetworkImageView::scaleOptions\n */\n\n/**\n * The interpolation quality to use when resizing the image.\n *\n * The default value is kCGInterpolationDefault.\n *\n * @fn NINetworkImageView::interpolationQuality\n */\n\n\n/** @name Configurable Properties */\n\n\n/**\n * The image memory cache used by this image view to store the image in memory.\n *\n * It may be useful to specify your own image memory cache if you have a unique memory requirement\n * and do not want the image being placed in the global memory cache, potentially pushing out\n * other images.\n *\n * By default this is [Nimbus imageMemoryCache].\n *\n * @attention Setting this to nil will disable the memory cache. This will force the\n *                 image view to load the image from the disk cache or network, depending on\n *                 what is available.\n *\n * @remark If you replace Nimbus' global image memory cache with a new image cache after\n *              creating this image view, this image view will still use the old image cache.\n *\n * @see Nimbus::globalImageMemoryCache\n * @see Nimbus::setGlobalImageMemoryCache:\n * @fn NINetworkImageView::imageMemoryCache\n */\n\n/**\n * The image disk cache used by this image view to store the image on disk.\n *\n * After the image has finished downloading we store it in a disk cache to avoid hitting the\n * network again if we want to load the image later on.\n *\n * By default this is [ASIDownloadCache sharedCache].\n *\n * @attention Setting this to nil will disable the disk cache. Images downloaded from the\n *                 network will be stored in the memory cache, if available.\n *\n * @fn NINetworkImageView::imageMemoryCache\n */\n\n/**\n * The network operation queue used by this image view to load the image from network and disk.\n *\n * By default this is [Nimbus networkOperationQueue].\n *\n * @attention This property must be non-nil. If you attempt to set it to nil, a debug\n *                 assertion will fire and Nimbus' global network operation queue will be set.\n *\n * @see Nimbus::globalNetworkOperationQueue\n * @see Nimbus::setGlobalNetworkOperationQueue:\n *\n * @fn NINetworkImageView::networkOperationQueue\n */\n\n/**\n * The maximum amount of time that an image will stay in memory after the request completes.\n *\n * A negative value will cause this image to NOT be stored in the memory cache.\n *\n * By default this is 0.\n *\n * @fn NINetworkImageView::maxAge\n */\n\n/**\n * The lifetime for an image stored in the disk cache.\n *\n * You can choose to keep the image around forever (until explicitly deleted) or for the life\n * of an applicaton's session (when the app starts the next time the cache will be cleared).\n *\n * Example: Clearing the session cache.\n * @code\n *  [imageDiskCache clearCachedResponsesForStoragePolicy:ASICacheForSessionDurationCacheStoragePolicy];\n * @endcode\n *\n * Example: Clearing the permanent cache.\n * @code\n *  [imageDiskCache clearCachedResponsesForStoragePolicy:ASICachePermanentlyCacheStoragePolicy];\n * @endcode\n *\n * By default this is NINetworkImageViewDiskCacheLifetimePermanent.\n *\n * @fn NINetworkImageView::diskCacheLifetime\n */\n\n/**\n * The last path assigned to the image view.\n *\n * This property may be used to avoid setting the network path repeatedly and clobbering\n * previous requests.\n *\n * @note It is debatable whether this has any practical use and is being considered\n *            for removal.\n *\n * @fn NINetworkImageView::lastPathToNetworkImage\n */\n\n\n/** @name State */\n\n/**\n * Whether there is an active request for this image view.\n *\n * If there is currently an image being fetched then this will be YES.\n *\n * @fn NINetworkImageView::isLoading\n */\n\n\n/** @name Delegation */\n\n/**\n * Delegate for state change notifications.\n *\n * @fn NINetworkImageView::delegate\n */\n\n\n/** @name Reusable View */\n\n/**\n * Kill any network requests and replace the displayed image with the initial image.\n *\n * Prepares this view for reuse by cancelling any existing requests and displaying the\n * initial image again.\n *\n * @fn NINetworkImageView::prepareForReuse\n */\n\n\n/**\n * @name Requesting a Network Image\n */\n\n/**\n * Load an image from the network using the current frame as the display size.\n *\n * Loads the image from the memory cache if possible, otherwise fires off a network request\n * with this object's network image information.\n *\n * Uses self.contentMode to crop and resize the image.\n *\n * The image's current frame will be used as the display size for the image.\n *\n * @param pathToNetworkImage  The network path to the image to be displayed.\n * @fn NINetworkImageView::setPathToNetworkImage:\n */\n\n/**\n * Load an image from the network with a specific display size.\n *\n * Loads the image from the memory cache if possible, otherwise fires off a network request\n * with this object's network image information.\n *\n * Uses self.contentMode to crop and resize the image.\n *\n * @param pathToNetworkImage  The network path to the image to be displayed.\n * @param displaySize         Used instead of the image's frame to determine the display size.\n * @fn NINetworkImageView::setPathToNetworkImage:forDisplaySize:\n */\n\n/**\n * Load an image from the network with a specific display size.\n *\n * Loads the image from the memory cache if possible, otherwise fires off a network request\n * with this object's network image information.\n *\n * @param pathToNetworkImage  The network path to the image to be displayed.\n * @param displaySize         Used instead of the image's frame to determine the display size.\n * @param contentMode         The content mode used to crop and resize the image.\n * @fn NINetworkImageView::setPathToNetworkImage:forDisplaySize:contentMode:\n */\n\n/**\n * Load an image from the network with a crop rect and the current frame as the display size.\n *\n * Loads the image from the memory cache if possible, otherwise fires off a network request\n * with this object's network image information.\n *\n * Uses self.contentMode to crop and resize the image.\n *\n * The image's current frame will be used as the display size for the image.\n *\n * @param pathToNetworkImage  The network path to the image to be displayed.\n * @param cropRect            x/y, width/height are in percent coordinates.\n *                                 Valid range is [0..1] for all values.\n * @fn NINetworkImageView::setPathToNetworkImage:cropRect:\n */\n\n/**\n * Load an image from the network with a specific display size.\n *\n * Loads the image from the memory cache if possible, otherwise fires off a network request\n * with this object's network image information.\n *\n * The image's current frame will be used as the display size for the image.\n *\n * @param pathToNetworkImage  The network path to the image to be displayed.\n * @param contentMode         The content mode used to crop and resize the image.\n * @fn NINetworkImageView::setPathToNetworkImage:contentMode:\n */\n\n/**\n * Load an image from the network with a specific display size and crop rect.\n *\n * Loads the image from the memory cache if possible, otherwise fires off a network request\n * with this object's network image information.\n *\n * @param pathToNetworkImage  The network path to the image to be displayed.\n * @param cropRect            x/y, width/height are in percent coordinates.\n *                                 Valid range is [0..1] for all values.\n * @param displaySize         Used instead of the image's frame to determine the display size.\n * @param contentMode         The content mode used to crop and resize the image.\n * @fn NINetworkImageView::setPathToNetworkImage:forDisplaySize:contentMode:cropRect:\n */\n\n\n/**\n * @name Subclassing\n *\n * The following methods are provided to aid in subclassing and are not meant to be\n * used externally.\n */\n\n/**\n * A network request has begun.\n *\n * @fn NINetworkImageView::networkImageViewDidStartLoading\n */\n\n/**\n * The image has been loaded, either from the network or in-memory.\n *\n * @fn NINetworkImageView::networkImageViewDidLoadImage:\n */\n\n/**\n * A network request failed to load.\n *\n * @fn NINetworkImageView::networkImageViewDidFailWithError:\n */\n"
  },
  {
    "path": "src/networkimage/src/NINetworkImageView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 June 15, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NINetworkImageView.h\"\n\n#import \"NimbusCore.h\"\n#import \"AFNetworking.h\"\n#import \"NIImageProcessing.h\"\n#import \"NIImageResponseSerializer.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NINetworkImageView()\n@property (nonatomic, strong) NSOperation* operation;\n@property (nonatomic, strong) AFHTTPSessionManager *httpSessionManager;\n@end\n\n\n@implementation NINetworkImageView\n\n\n\n- (void)cancelOperation {\n  if ([self.operation isKindOfClass:[NIOperation class]]) {\n    NIOperation* request = (NIOperation *)self.operation;\n    // Clear the delegate so that we don't receive a didFail notification when we cancel the\n    // operation.\n    request.delegate = nil;\n  }\n  [self.operation cancel];\n  [self.httpSessionManager invalidateSessionCancelingTasks:YES];\n}\n\n- (void)dealloc {\n  [self cancelOperation];\n}\n\n- (void)assignDefaults {\n  self.sizeForDisplay = YES;\n  self.scaleOptions = NINetworkImageViewScaleToFitLeavesExcessAndScaleToFillCropsExcess;\n  self.interpolationQuality = kCGInterpolationDefault;\n\n  self.imageMemoryCache = [Nimbus imageMemoryCache];\n  self.networkOperationQueue = [Nimbus networkOperationQueue];\n}\n\n- (id)initWithImage:(UIImage *)image {\n  if ((self = [super initWithImage:image])) {\n    [self assignDefaults];\n\n    // Retain the initial image.\n    self.initialImage = image;\n  }\n  return self;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [self initWithImage:nil])) {\n    self.frame = frame;\n  }\n  return self;\n}\n\n- (id)initWithCoder:(NSCoder *)aDecoder {\n  if ((self = [super initWithCoder:aDecoder])) {\n    if (nil != self.image) {\n      self.initialImage = self.image;\n    }\n    [self assignDefaults];\n  }\n  return self;\n}\n\n- (id)init {\n  return [self initWithImage:nil];\n}\n\n- (NSString *)cacheKeyForCacheIdentifier:(NSString *)cacheIdentifier\n                               imageSize:(CGSize)imageSize\n                                cropRect:(CGRect)cropRect\n                             contentMode:(UIViewContentMode)contentMode\n                            scaleOptions:(NINetworkImageViewScaleOptions)scaleOptions {\n  NIDASSERT(NIIsStringWithAnyText(cacheIdentifier));\n\n  NSString* cacheKey = cacheIdentifier;\n\n  // Append the size to the key. This allows us to differentiate cache keys by image dimension.\n  // If the display size ever changes, we want to ensure that we're fetching the correct image\n  // from the cache.\n  if (self.sizeForDisplay) {\n    cacheKey = [cacheKey stringByAppendingFormat:@\"%@%@{%@,%@}\",\n                NSStringFromCGSize(imageSize), NSStringFromCGRect(cropRect), [@(contentMode) stringValue], [@(scaleOptions) stringValue]];\n  }\n\n  // The resulting cache key will look like:\n  // /path/to/image({width,height}{contentMode,cropImageForDisplay})\n\n  return cacheKey;\n}\n\n- (NSDate *)expirationDate {\n  return (self.maxAge != 0) ? [NSDate dateWithTimeIntervalSinceNow:self.maxAge] : nil;\n}\n\n#pragma mark - Internal consistent implementation of state changes\n\n\n- (void)_didStartLoading {\n  if ([self.delegate respondsToSelector:@selector(networkImageViewDidStartLoad:)]) {\n    [self.delegate networkImageViewDidStartLoad:self];\n  }\n\n  [self networkImageViewDidStartLoading];\n}\n\n- (void)_didFinishLoadingWithImage:(UIImage *)image\n                   cacheIdentifier:(NSString *)cacheIdentifier\n                       displaySize:(CGSize)displaySize\n                          cropRect:(CGRect)cropRect\n                       contentMode:(UIViewContentMode)contentMode\n                      scaleOptions:(NINetworkImageViewScaleOptions)scaleOptions\n                    expirationDate:(NSDate *)expirationDate {\n  // Store the result image in the memory cache.\n  if (nil != self.imageMemoryCache && nil != image) {\n    NSString* cacheKey = [self cacheKeyForCacheIdentifier:cacheIdentifier\n                                                imageSize:displaySize\n                                                 cropRect:cropRect\n                                              contentMode:contentMode\n                                             scaleOptions:scaleOptions];\n\n    // Store the image in the memory cache, possibly with an expiration date.\n    [self.imageMemoryCache storeObject: image\n                              withName: cacheKey\n                          expiresAfter: expirationDate];\n  }\n\n  if (nil != image) {\n    // Display the new image.\n    [self setImage:image];\n\n  } else {\n    [self setImage:self.initialImage];\n  }\n\n  self.operation = nil;\n  self.httpSessionManager = nil;\n\n  if ([self.delegate respondsToSelector:@selector(networkImageView:didLoadImage:)]) {\n    [self.delegate networkImageView:self didLoadImage:self.image];\n  }\n\n  [self networkImageViewDidLoadImage:image];\n}\n\n- (void)_didFailToLoadWithError:(NSError *)error {\n  self.operation = nil;\n  self.httpSessionManager = nil;\n\n  if ([self.delegate respondsToSelector:@selector(networkImageView:didFailWithError:)]) {\n    [self.delegate networkImageView:self didFailWithError:error];\n  }\n\n  [self networkImageViewDidFailWithError:error];\n}\n\n#pragma mark - NIOperationDelegate\n\n\n- (void)nimbusOperationDidStart:(NIOperation *)operation {\n  [self _didStartLoading];\n}\n\n- (void)nimbusOperationDidFinish:(NIOperation<NINetworkImageOperation> *)operation {\n  if (operation.isCancelled || operation != self.operation) {\n    return;\n  }\n  [self _didFinishLoadingWithImage:operation.imageCroppedAndSizedForDisplay\n                   cacheIdentifier:operation.cacheIdentifier\n                       displaySize:operation.imageDisplaySize\n                          cropRect:operation.imageCropRect\n                       contentMode:operation.imageContentMode\n                      scaleOptions:operation.scaleOptions\n                    expirationDate:[self expirationDate]];\n}\n\n- (void)nimbusOperationDidFail:(NIOperation *)operation withError:(NSError *)error {\n  [self _didFailToLoadWithError:error];\n}\n\n#pragma mark - Subclassing\n\n\n- (void)networkImageViewDidStartLoading {\n  // No-op. Meant to be overridden.\n}\n\n- (void)networkImageViewDidLoadImage:(UIImage *)image {\n  // No-op. Meant to be overridden.\n}\n\n- (void)networkImageViewDidFailWithError:(NSError *)error {\n  // No-op. Meant to be overridden.\n}\n\n#pragma mark - Public\n\n\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage {\n  [self setPathToNetworkImage: pathToNetworkImage\n               forDisplaySize: CGSizeZero\n                  contentMode: self.contentMode\n                     cropRect: CGRectZero];\n}\n\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage forDisplaySize:(CGSize)displaySize {\n  [self setPathToNetworkImage: pathToNetworkImage\n               forDisplaySize: displaySize\n                  contentMode: self.contentMode\n                     cropRect: CGRectZero];\n}\n\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage forDisplaySize:(CGSize)displaySize contentMode:(UIViewContentMode)contentMode {\n  [self setPathToNetworkImage: pathToNetworkImage\n               forDisplaySize: displaySize\n                  contentMode: contentMode\n                     cropRect: CGRectZero];\n}\n\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage cropRect:(CGRect)cropRect {\n  [self setPathToNetworkImage: pathToNetworkImage\n               forDisplaySize: CGSizeZero\n                  contentMode: self.contentMode\n                     cropRect: cropRect];\n}\n\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage contentMode:(UIViewContentMode)contentMode {\n  [self setPathToNetworkImage: pathToNetworkImage\n               forDisplaySize: CGSizeZero\n                  contentMode: contentMode\n                     cropRect: CGRectZero];\n}\n\n- (void)setPathToNetworkImage:(NSString *)pathToNetworkImage forDisplaySize:(CGSize)displaySize contentMode:(UIViewContentMode)contentMode cropRect:(CGRect)cropRect {\n  [self cancelOperation];\n\n  if (NIIsStringWithAnyText(pathToNetworkImage)) {\n    NSURL* url = nil;\n\n    // Check for file URLs.\n    if ([pathToNetworkImage hasPrefix:@\"/\"]) {\n      // If the url starts with / then it's likely a file URL, so treat it accordingly.\n      url = [NSURL fileURLWithPath:pathToNetworkImage];\n\n    } else {\n      // Otherwise we assume it's a regular URL.\n      url = [NSURL URLWithString:[pathToNetworkImage stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];\n    }\n\n    // If the URL failed to be created, there's not much we can do here.\n    if (nil == url) {\n      return;\n    }\n    // We explicitly do not allow negative display sizes. Check the call stack to figure\n    // out who is providing a negative display size. It's possible that displaySize is an\n    // uninitialized CGSize structure.\n    NIDASSERT(displaySize.width >= 0);\n    NIDASSERT(displaySize.height >= 0);\n    \n    // If an invalid display size IS provided, use the image view's frame instead.\n    if (0 >= displaySize.width || 0 >= displaySize.height) {\n      displaySize = self.frame.size;\n    }\n    \n    UIImage* image = nil;\n    \n    // Attempt to load the image from memory first.\n    NSString* cacheKey = nil;\n    if (nil != self.imageMemoryCache) {\n      cacheKey = [self cacheKeyForCacheIdentifier:pathToNetworkImage\n                                        imageSize:displaySize\n                                         cropRect:cropRect\n                                      contentMode:contentMode\n                                     scaleOptions:self.scaleOptions];\n      image = [self.imageMemoryCache objectWithName:cacheKey];\n    }\n\n    if (nil != image) {\n      // We successfully loaded the image from memory.\n      [self setImage:image];\n      \n      if ([self.delegate respondsToSelector:@selector(networkImageView:didLoadImage:)]) {\n        [self.delegate networkImageView:self didLoadImage:self.image];\n      }\n      \n      [self networkImageViewDidLoadImage:image];\n\n    } else {\n      if (!self.sizeForDisplay) {\n        displaySize = CGSizeZero;\n        contentMode = UIViewContentModeScaleToFill;\n      }\n\n      NIImageResponseSerializer* serializer = [NIImageResponseSerializer serializer];\n      // We handle image scaling ourselves in the image processing method, so we need to disable\n      // AFNetworking from doing so as well.\n      serializer.imageScale = 1;\n      serializer.contentMode = contentMode;\n      serializer.cropRect = cropRect;\n      serializer.displaySize = displaySize;\n      serializer.scaleOptions = self.scaleOptions;\n      serializer.interpolationQuality = self.interpolationQuality;\n\n      NSString* originalCacheKey = [self cacheKeyForCacheIdentifier:pathToNetworkImage\n                                                          imageSize:displaySize\n                                                           cropRect:cropRect\n                                                        contentMode:contentMode\n                                                       scaleOptions:self.scaleOptions];\n\n      self.httpSessionManager = [AFHTTPSessionManager manager];\n      self.httpSessionManager.responseSerializer = serializer;\n      [self.httpSessionManager GET:url.absoluteString\n        parameters:nil\n          progress:^(NSProgress * _Nonnull downloadProgress) {\n            if ([self.delegate respondsToSelector:@selector(networkImageView:readBytes:totalBytes:)]) {\n              [self.delegate networkImageView:self\n                                    readBytes:downloadProgress.completedUnitCount\n                                   totalBytes:downloadProgress.totalUnitCount];\n            }\n          }\n           success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {\n             NSString* blockCacheKey = [self cacheKeyForCacheIdentifier:pathToNetworkImage\n                                                              imageSize:displaySize\n                                                               cropRect:cropRect\n                                                            contentMode:contentMode\n                                                           scaleOptions:self.scaleOptions];\n\n             // Only keep this result if it's for the most recent request.\n             if ([blockCacheKey isEqualToString:originalCacheKey]) {\n               [self _didFinishLoadingWithImage:responseObject\n                                cacheIdentifier:pathToNetworkImage\n                                    displaySize:displaySize\n                                       cropRect:cropRect\n                                    contentMode:contentMode\n                                   scaleOptions:self.scaleOptions\n                                 expirationDate:[self expirationDate]];\n             }\n\n           } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {\n             [self _didFailToLoadWithError:error];\n           }];\n\n      [self _didStartLoading];\n    }\n  }\n}\n\n- (void)setNetworkImageOperation:(NIOperation<NINetworkImageOperation> *)operation forDisplaySize:(CGSize)displaySize contentMode:(UIViewContentMode)contentMode cropRect:(CGRect)cropRect {\n  [self cancelOperation];\n\n  if (nil != operation) {\n    // We explicitly do not allow negative display sizes. Check the call stack to figure\n    // out who is providing a negative display size. It's possible that displaySize is an\n    // uninitialized CGSize structure.\n    NIDASSERT(displaySize.width >= 0);\n    NIDASSERT(displaySize.height >= 0);\n\n    // If an invalid display size IS provided, use the image view's frame instead.\n    if (0 >= displaySize.width || 0 >= displaySize.height) {\n      displaySize = self.frame.size;\n    }\n\n    UIImage* image = nil;\n\n    // Attempt to load the image from memory first.\n    if (nil != self.imageMemoryCache) {\n      NSString* cacheKey = [self cacheKeyForCacheIdentifier:operation.cacheIdentifier\n                                                  imageSize:displaySize\n                                                   cropRect:cropRect\n                                                contentMode:contentMode\n                                               scaleOptions:self.scaleOptions];\n      image = [self.imageMemoryCache objectWithName:cacheKey];\n    }\n\n    if (nil != image) {\n      // We successfully loaded the image from memory.\n      [self setImage:image];\n\n      if ([self.delegate respondsToSelector:@selector(networkImageView:didLoadImage:)]) {\n        [self.delegate networkImageView:self didLoadImage:self.image];\n      }\n\n      [self networkImageViewDidLoadImage:image];\n\n    } else {\n      // Unable to load the image from memory, so let's fire off the operation now.\n      operation.delegate = self;\n\n      operation.imageCropRect = cropRect;\n      operation.scaleOptions = self.scaleOptions;\n      operation.interpolationQuality = self.interpolationQuality;\n      if (self.sizeForDisplay) {\n        operation.imageDisplaySize = displaySize;\n        operation.imageContentMode = contentMode;\n      }\n\n      self.operation = operation;\n\n      [self.networkOperationQueue addOperation:self.operation];\n    }\n  }\n}\n\n- (void)prepareForReuse {\n  [self cancelOperation];\n\n  [self setImage:self.initialImage];\n}\n\n#pragma mark - Properties\n\n\n- (void)setInitialImage:(UIImage *)initialImage {\n  if (_initialImage != initialImage) {\n    // Only update the displayed image if we're currently showing the old initial image.\n    BOOL updateDisplayedImage = (_initialImage == self.image);\n    _initialImage = initialImage;\n\n    if (updateDisplayedImage) {\n      [self setImage:_initialImage];\n    }\n  }\n}\n\n- (BOOL)isLoading {\n  return [self.operation isExecuting];\n}\n\n- (void)setNetworkOperationQueue:(NSOperationQueue *)queue {\n  // Don't allow a nil network operation queue.\n  NIDASSERT(nil != queue);\n  if (nil == queue) {\n    queue = [Nimbus networkOperationQueue];\n  }\n  _networkOperationQueue = queue;\n}\n\n@end\n\n"
  },
  {
    "path": "src/networkimage/src/NimbusNetworkImage.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * @defgroup NimbusNetworkImage Nimbus Network Image\n * @{\n *\n * <div id=\"github\" feature=\"networkimage\"></div>\n *\n * Image views that load images from the network and efficiently store the result in memory and on\n * disk.\n *\n * @image html NINetworkImageViewExample1.png \"The various available content modes.\"\n *\n * <h2>Minimum Requirements</h2>\n *\n * Required frameworks:\n *\n * - UIKit.framework\n * - CoreText.framework\n * - AFNetworking https://github.com/AFNetworking/AFNetworking\n *\n * Minimum Operating System: <b>iOS 4.0</b>\n *\n * Source located in <code>src/networkimage/src</code>\n *\n * Presented below is an architectural overview of the Nimbus network image library.\n *\n * @image html NINetworkImageDesign1.png \"NINetworkImage Design\"\n *\n * -# To begin using a network image view, simply create an instance of an NINetworkImageView\n *    and use it as you would a UIImageView. The initial image you assign to the view will be\n *    used as the \"loading\" image and must be a locally accessible image. Note that this\n *    image will not be cropped and resized in any way, so you should take care to crop and\n *    resize it beforehand as necessary.\n * -# Once you have created your network image view and assigned the initial image, the next step\n *    is to load the network image. Call any of the @link NINetworkImageView::setPathToNetworkImage: setPathToNetworkImage@endlink methods to fire\n *    off a network request for the image on a separate thread.\n * -# A new NINetworkImageRequest thread will spin off and initiate the request to the network.\n * -# Once the image has been retrieved from the net, the thread crops and resizes the image\n *    depending on the presentation configurations specified by the image view. In this example,\n *    @link NINetworkImageView::sizeForDisplay sizeForDisplay@endlink and\n *    @link NINetworkImageView::cropImageForDisplay cropImageForDisplay@endlink are enabled.\n *    In this step the image is resized to fit the aspect ratio of the display size.\n * -# We then crop the image to fit the display frame.\n * -# Upon completion of all image modifications, we complete the request and return only the\n *    modified image to the image view. This helps to reduce memory usage.\n * -# The resized and cropped image is then stored in the in-memory image cache for quick access\n *    in the future.\n * -# At last, the image view sets the new image and displays it.\n *\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NimbusCore.h\"\n#import \"NIImageProcessing.h\"\n#import \"NINetworkImageView.h\"\n\n/**@}*/\n"
  },
  {
    "path": "src/networkimage/unittests/NINetworkImageViewTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusNetworkImage.h\"\n\n@interface NINetworkImageViewTests : XCTestCase\n@end\n\n\n@implementation NINetworkImageViewTests\n\n\n- (void)testNothing {\n}\n\n@end\n"
  },
  {
    "path": "src/networkimage/unittests/NimbusNetworkImageTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/overview/deps",
    "content": "core\n\n[NIOverviewImageCacheController]\nmodels\n\n[Frameworks]\nFoundation.framework\nUIKit.framework"
  },
  {
    "path": "src/overview/src/NIDeviceInfo.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n/**\n * Formats a number of bytes in a human-readable format.\n *\n * Will create a string showing the size in bytes, KBs, MBs, or GBs.\n */\nNSString* NIStringFromBytes(unsigned long long bytes);\n\n\n/**\n * An interface for accessing device information.\n *\n * @ingroup Overview-Sensors\n *\n * This class is not meant to be instantiated. All methods are class implementations.\n *\n * This class aims to simplify the interface for collecting device information. The low-level\n * mach APIs provide a host of valuable information but it's often in formats that aren't\n * ready for presentation.\n *\n * @attention When using this class on the simulator, the values returned will reflect\n *                 those of the computer within which you're running the simulator, not the\n *                 simulated device. This is because the simulator is a first-class citizen\n *                 on the computer and has full access to your RAM and disk space.\n */\n@interface NIDeviceInfo : NSObject\n\n#pragma mark Memory /** @name Memory */\n\n/**\n * The number of bytes in memory that are free.\n *\n * Calculated using the number of free pages of memory.\n */\n+ (unsigned long long)bytesOfFreeMemory;\n\n/**\n * The total number of bytes of memory.\n *\n * Calculated by adding together the number of free, wired, active, and inactive pages of memory.\n *\n * This value may change over time on the device due to the way iOS partitions available memory\n * for applications.\n */\n+ (unsigned long long)bytesOfTotalMemory;\n\n/**\n * Simulate low memory warning\n *\n * Don't use this in production because it uses private API\n */\n+ (void)simulateLowMemoryWarning;\n\n#pragma mark Disk Space /** @name Disk Space */\n\n/**\n * The number of bytes free on disk.\n */\n+ (unsigned long long)bytesOfFreeDiskSpace;\n\n/**\n * The total number of bytes of disk space.\n */\n+ (unsigned long long)bytesOfTotalDiskSpace;\n\n\n#pragma mark Battery /** @name Battery */\n\n/**\n * The battery charge level in the range 0 .. 1.0. -1.0 if UIDeviceBatteryStateUnknown.\n *\n * This is a thin wrapper for [[UIDevice currentDevice] batteryLevel].\n */\n+ (CGFloat)batteryLevel;\n\n/**\n * The current battery state.\n *\n * This is a thin wrapper for [[UIDevice currentDevice] batteryState].\n */\n+ (UIDeviceBatteryState)batteryState;\n\n\n#pragma mark Caching /** @name Caching */\n\n/**\n * Fetches the device's current information and then caches it.\n *\n * All subsequent calls to NIDeviceInfo methods will use this cached information.\n *\n * This can be a useful way to freeze the device info at a moment in time.\n *\n * Example:\n *\n * @code\n *  [NIDeviceInfo beginCachedDeviceInfo];\n *\n *  // All calls to NIDeviceInfo methods here will use the information retrieved when\n *  // beginCachedDeviceInfo was called.\n *\n *  [NIDeviceInfo endCachedDeviceInfo];\n * @endcode\n */\n+ (BOOL)beginCachedDeviceInfo;\n\n/**\n * Stop using the cache for the device info methods.\n */\n+ (void)endCachedDeviceInfo;\n\n\n@end\n"
  },
  {
    "path": "src/overview/src/NIDeviceInfo.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIDeviceInfo.h\"\n\n#import \"NimbusCore.h\"\n\n#import <mach/mach.h>\n#import <mach/mach_host.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n// Static local state.\nstatic BOOL                 sIsCaching = NO;\nstatic BOOL                 sLastUpdateResult = NO;\nstatic vm_size_t            sPageSize = 0;\nstatic vm_statistics_data_t sVMStats;\nstatic NSDictionary*        sFileSystem = nil;\n\n\nNSString* NIStringFromBytes(unsigned long long bytes) {\n  static const void* sOrdersOfMagnitude[] = {\n    @\"bytes\", @\"KB\", @\"MB\", @\"GB\"\n  };\n\n  // Determine what magnitude the number of bytes is by shifting off 10 bits at a time\n  // (equivalent to dividing by 1024).\n  unsigned long magnitude = 0;\n  unsigned long long highbits = bytes;\n  unsigned long long inverseBits = ~((unsigned long long)0x3FF);\n  while ((highbits & inverseBits)\n         && magnitude + 1 < (sizeof(sOrdersOfMagnitude) / sizeof(void *))) {\n    // Shift off an order of magnitude.\n    highbits >>= 10;\n    magnitude++;\n  }\n\n  if (magnitude > 0) {\n    unsigned long long dividend = 1024 << (magnitude - 1) * 10;\n    double result = ((double)bytes / (double)(dividend));\n    return [NSString stringWithFormat:@\"%.2f %@\",\n            result,\n            sOrdersOfMagnitude[magnitude]];\n\n  } else {\n    // We don't need to bother with dividing bytes.\n    return [NSString stringWithFormat:@\"%lld %@\", bytes, sOrdersOfMagnitude[magnitude]];\n  }\n}\n\n@implementation NIDeviceInfo\n\n\n+ (void)initialize {\n  [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];\n  memset(&sVMStats, 0, sizeof(sVMStats));\n}\n\n+ (BOOL)updateHostStatistics {\n  mach_port_t host_port = mach_host_self();\n  mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);\n  host_page_size(host_port, &sPageSize);\n  return (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&sVMStats, &host_size)\n          == KERN_SUCCESS);\n}\n\n+ (BOOL)updateFileSystemAttributes {\n\tNSError* error = nil;\n  // This path could be any path that is on the device's local disk.\n\tNSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);\n\n  // Fetch the file system information based on the path given (the user's documents directory).\n\tsFileSystem =\n  [[NSFileManager defaultManager] attributesOfFileSystemForPath: [paths lastObject]\n                                                           error: &error];\n  return (nil == error);\n}\n\n#pragma mark - Public\n\n\n+ (unsigned long long)bytesOfFreeMemory {\n  if (!sIsCaching && ![self updateHostStatistics]) {\n    return 0;\n  }\n  unsigned long long mem_free = ((unsigned long long)sVMStats.free_count\n                                 * (unsigned long long)sPageSize);\n  return mem_free;\n}\n\n+ (unsigned long long)bytesOfTotalMemory {\n  if (!sIsCaching && ![self updateHostStatistics]) {\n    return 0;\n  }\n  unsigned long long mem_free = (((unsigned long long)sVMStats.free_count\n                                  + (unsigned long long)sVMStats.active_count\n                                  + (unsigned long long)sVMStats.inactive_count\n                                  + (unsigned long long)sVMStats.wire_count)\n                                 * (unsigned long long)sPageSize);\n  return mem_free;\n}\n\n+ (void)simulateLowMemoryWarning\n{\n  SEL memoryWarningSel =  NSSelectorFromString(@\"_performMemoryWarning\");\n  if ([[UIApplication sharedApplication] respondsToSelector:memoryWarningSel]) {\n    NIDINFO(@\"Simulate low memory warning\");\n    // Supress the warning. -Wundeclared-selector was used while ARC is enabled.\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n    [[UIApplication sharedApplication] performSelector:memoryWarningSel];\n#pragma clang diagnostic pop\n  } else {\n    // UIApplication no loger responds to _performMemoryWarning\n    exit(1);\n  }\n}\n\n+ (unsigned long long)bytesOfFreeDiskSpace {\n  if (!sIsCaching && ![self updateFileSystemAttributes]) {\n    return 0;\n  }\n\tunsigned long long bytes = 0;\n\n  NSNumber* number = [sFileSystem objectForKey:NSFileSystemFreeSize];\n\tbytes = [number unsignedLongLongValue];\n\n  return bytes;\n}\n\n+ (unsigned long long)bytesOfTotalDiskSpace {\n  if (!sIsCaching && ![self updateFileSystemAttributes]) {\n    return 0;\n  }\n\tunsigned long long bytes = 0;\n  \n  NSNumber* number = [sFileSystem objectForKey:NSFileSystemSize];\n  bytes = [number unsignedLongLongValue];\n  \n  return bytes;\n}\n\n+ (CGFloat)batteryLevel {\n  return [[UIDevice currentDevice] batteryLevel];\n}\n\n+ (UIDeviceBatteryState)batteryState {\n  return [[UIDevice currentDevice] batteryState];\n}\n\n#pragma mark - Caching\n\n\n+ (BOOL)beginCachedDeviceInfo {\n  if (!sIsCaching) {\n    sIsCaching = YES;\n\n    sLastUpdateResult = [self updateHostStatistics];\n    sLastUpdateResult = ([self updateFileSystemAttributes] && sLastUpdateResult);\n  }\n\n  return sLastUpdateResult;\n}\n\n+ (void)endCachedDeviceInfo {\n  sIsCaching = NO;\n}\n\n@end\n"
  },
  {
    "path": "src/overview/src/NIOverview.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n@class NIOverviewView;\n@class NIOverviewLogger;\n\n/**\n * The Overview state management class.\n *\n * @ingroup Overview\n *\n * <h2>What is the Overview?</h2>\n *\n * The Overview is a paged view that sits directly below the status bar and presents information\n * about the device and the currently running application. The Overview is extensible, in that\n * you can write your own pages and add them to the Overview. The included pages allow you to\n * see the current and historical state of memory and disk use, the console logs, and important\n * events that have occurred (such as memory warnings).\n *\n *\n * <h2>Before Using the Overview</h2>\n *\n * None of the Overview methods will do anything unless you have the DEBUG preprocessor\n * macro defined. This is by design. The Overview swizzles private API methods in order to\n * trick the device into showing the Overview as part of the status bar.\n *\n *            DO *NOT* SUBMIT YOUR APP TO THE APP STORE WITH DEBUG DEFINED.\n *\n * If you submit your app to the App Store with DEBUG defined, you *will* be rejected.\n * Overview works only because it hacks certain aspects of the device using private APIs\n * and method swizzling. For good reason, Apple will not look too kindly to the Overview\n * being included in production code. If Apple ever changes any of the APIs that\n * the Overview depends on then the Overview would break.\n */\n@interface NIOverview : NSObject\n\n#pragma mark Initializing the Overview /** @name Initializing the Overview */\n\n/**\n * Call this immediately in application:didFinishLaunchingWithOptions:.\n *\n * This method calls applicationDidFinishLaunchingWithStatusBarHeightOverride: with\n * |overrideStatusBarHeight| set to NO.\n */\n+ (void)applicationDidFinishLaunching;\n\n/**\n * Call this immediately in application:didFinishLaunchingWithOptions:.\n *\n * Swizzles the necessary methods for adding the Overview to the view hierarchy and registers\n * notifications for device state changes if |overrideStatusBarHeight| is true.\n */\n+ (void)applicationDidFinishLaunchingWithStatusBarHeightOverride:(BOOL)overrideStatusBarHeight;\n\n/**\n * Adds the Overview to the given window.\n *\n * This methods calls addOverviewToWindow:enableDraggingVertically: with |enableDraggingVertically|\n * set to NO.\n */\n+ (void)addOverviewToWindow:(UIWindow *)window;\n\n/**\n * Adds the Overview to the given window.\n *\n * The Overview will always be fixed at the top of the device's screen directly\n * beneath the status bar (if it is visible) if enableDraggingVertically is false. Otherwise,\n * the overview can be drag vertically.\n */\n+ (void)addOverviewToWindow:(UIWindow *)window\n   enableDraggingVertically:(BOOL)enableDraggingVertically;\n\n#pragma mark Accessing State Information /** @name Accessing State Information */\n\n/**\n * The height of the Overview.\n */\n+ (CGFloat)height;\n\n/**\n * The frame of the Overview.\n */\n+ (CGRect)frame;\n\n/**\n * The Overview view.\n */\n+ (NIOverviewView *)view;\n\n/**\n * The Overview logger.\n *\n * This is the logger that all of the Overview pages use to present their information.\n */\n+ (NIOverviewLogger *)logger;\n\n@end\n"
  },
  {
    "path": "src/overview/src/NIOverview.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIOverview.h\"\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\n#import \"NIDeviceInfo.h\"\n#import \"NIOverviewView.h\"\n#import \"NIOverviewPageView.h\"\n#import \"NIOverviewSwizzling.h\"\n#import \"NIOverviewLogger.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n// Static state.\nstatic CGFloat  sOverviewHeight                      = 60;\nstatic BOOL     sOverviewIsAwake                     = NO;\nstatic BOOL     sOverviewHasOverridenStatusBarHeight = NO;\n\nstatic NIOverviewView* sOverviewView = nil;\n\n\n#pragma mark - Logging\n\n\n/**\n * @internal\n *\n * An undocumented method that replaces the default logging mechanism with a custom implementation.\n *\n * Your method prototype should look like this:\n *\n *   void logger(const char *message, unsigned length, BOOL withSyslogBanner)\n *\n * @attention This method is undocumented, unsupported, and unlikely to be around\n *                 forever. Don't go using it in production code.\n *\n * Source: http://support.apple.com/kb/TA45403?viewlocale=en_US\n */\nextern void _NSSetLogCStringFunction(void(*)(const char *, unsigned, BOOL));\n\nvoid NIOverviewLogMethod(const char* message, unsigned length, BOOL withSyslogBanner);\n\n\n/**\n * Pipes NSLog messages to the Overview and stderr.\n *\n * This method is passed as an argument to _NSSetLogCStringFunction to pipe all NSLog\n * messages through here.\n */\nvoid NIOverviewLogMethod(const char* message, unsigned length, BOOL withSyslogBanner) {\n  static NSDateFormatter* formatter = nil;\n  if (nil == formatter) {\n    formatter = [[NSDateFormatter alloc] init];\n    [formatter setTimeStyle:NSDateFormatterMediumStyle];\n    [formatter setDateStyle:NSDateFormatterMediumStyle];\n  }\n\n  // Don't autorelease here in an attempt to minimize autorelease thrashing in tight\n  // loops.\n  \n  NSString* formattedLogMessage = [[NSString alloc] initWithCString: message\n                                                           encoding: NSUTF8StringEncoding];\n\n  dispatch_async(dispatch_get_main_queue(), ^{\n    NIOverviewConsoleLogEntry* entry = [[NIOverviewConsoleLogEntry alloc]\n                                        initWithLog:formattedLogMessage];\n\n    [[NIOverview logger] addConsoleLog:entry];\n  });\n\n  formattedLogMessage = [[NSString alloc] initWithFormat:\n                         @\"%@: %s\\n\", [formatter stringFromDate:[NSDate date]], message];\n\n  fprintf(stderr, \"%s\", [formattedLogMessage UTF8String]);\n}\n\n#endif\n\n@implementation NIOverview\n\n\n#pragma mark - Device Orientation Changes\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\n+ (void)didChangeOrientation {\n  static UIDeviceOrientation lastOrientation = UIDeviceOrientationUnknown;\n\n  // Don't animate the overview if the device didn't actually change orientations.\n  if (lastOrientation != [[UIDevice currentDevice] orientation]\n      && [[UIDevice currentDevice] orientation] != UIDeviceOrientationUnknown\n      && [[UIDevice currentDevice] orientation] != UIDeviceOrientationFaceUp\n      && [[UIDevice currentDevice] orientation] != UIDeviceOrientationFaceDown) {\n\n    // When we flip from landscape to landscape or portait to portait the animation lasts\n    // twice as long.\n    UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];\n    BOOL isLongAnimation = (UIDeviceOrientationIsLandscape(lastOrientation)\n                            == UIDeviceOrientationIsLandscape(currentOrientation));\n    lastOrientation = currentOrientation;\n\n    // Hide the overview right away, we'll make it fade back in when the rotation is\n    // finished.\n    sOverviewView.hidden = YES;\n\n    // Delay showing the overview again until the rotation finishes.\n    [self cancelPreviousPerformRequestsWithTarget:self];\n    [self performSelector:@selector(showoverviewAfterRotation) withObject:nil\n               afterDelay:NIDeviceRotationDuration(isLongAnimation)];\n  }\n}\n\n+ (void)statusBarWillChangeFrame {\n  [UIView beginAnimations:nil context:nil];\n  [UIView setAnimationDuration:NIStatusBarBoundsChangeAnimationDuration()];\n  [UIView setAnimationCurve:NIStatusBarBoundsChangeAnimationCurve()];\n  CGRect frame = [NIOverview frame];\n  sOverviewView.center = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));\n  [UIView commitAnimations];\n}\n\n+ (void)showoverviewAfterRotation {\n  // Don't modify the overview's frame directly, just modify the transform/center/bounds\n  // properties so that the view is rotated with the device.\n\n  sOverviewView.transform = NIRotateTransformForOrientation(NIInterfaceOrientation());\n\n  // Fetch the frame only to calculate the center.\n  CGRect frame = [NIOverview frame];\n  sOverviewView.center = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));\n\n  CGRect bounds = sOverviewView.bounds;\n  if (UIInterfaceOrientationIsLandscape(NIInterfaceOrientation())) {\n    bounds.size.width = frame.size.height;\n    bounds.size.height = frame.size.width;\n  } else {\n    bounds.size = frame.size;\n  }\n  sOverviewView.bounds = bounds;\n\n  // Get ready to fade the overview back in.\n  sOverviewView.hidden = NO;\n  sOverviewView.alpha = 0;\n  \n  [sOverviewView flashScrollIndicators];\n\n  // Fade!\n  [UIView beginAnimations:nil context:nil];\n  [UIView setAnimationDuration:0.2];\n  sOverviewView.alpha = 1;\n  [UIView commitAnimations];\n}\n\n+ (void)didReceiveMemoryWarning {\n  [[NIOverview logger] addEventLog:\n   [[NIOverviewEventLogEntry alloc] initWithType:NIOverviewEventDidReceiveMemoryWarning]];\n}\n\n#endif\n\n\n#pragma mark - Public\n\n\n+ (void)applicationDidFinishLaunching {\n#if defined(DEBUG) || defined(NI_DEBUG)\n  [self applicationDidFinishLaunchingWithStatusBarHeightOverride:YES];\n#endif\n}\n\n+ (void)applicationDidFinishLaunchingWithStatusBarHeightOverride:(BOOL)overrideStatusBarHeight {\n#if defined(DEBUG) || defined(NI_DEBUG)\n  if (!sOverviewIsAwake) {\n    sOverviewIsAwake = YES;\n    sOverviewHasOverridenStatusBarHeight = overrideStatusBarHeight;\n\n    // Set up the logger right away so that all calls to NSLog will be captured by the\n    // overview.\n    _NSSetLogCStringFunction(NIOverviewLogMethod);\n\n    if (overrideStatusBarHeight) {\n      NIOverviewSwizzleMethods();\n    }\n\n    [[NSNotificationCenter defaultCenter] addObserver: self\n                                             selector: @selector(didChangeOrientation)\n                                                 name: UIDeviceOrientationDidChangeNotification\n                                               object: nil];\n    [[NSNotificationCenter defaultCenter] addObserver: self\n                                             selector: @selector(statusBarWillChangeFrame)\n                                                 name: UIApplicationWillChangeStatusBarFrameNotification\n                                               object: nil];\n    [[NSNotificationCenter defaultCenter] addObserver: self\n                                             selector: @selector(didReceiveMemoryWarning)\n                                                 name: UIApplicationDidReceiveMemoryWarningNotification\n                                               object: nil];\n\n  }\n#endif\n}\n\n+ (void)addOverviewToWindow:(UIWindow *)window {\n#if defined(DEBUG) || defined(NI_DEBUG)\n  [self addOverviewToWindow:window enableDraggingVertically:NO];\n#endif\n}\n\n+ (void)addOverviewToWindow:(UIWindow *)window\n   enableDraggingVertically:(BOOL)enableDraggingVertically {\n#if defined(DEBUG) || defined(NI_DEBUG)\n  if (nil != sOverviewView) {\n    // Remove the old overview in case this gets called multiple times (not sure why you would\n    // though).\n    [sOverviewView removeFromSuperview];\n  }\n\n  sOverviewView = [[NIOverviewView alloc] initWithFrame:[self frame]];\n  [sOverviewView setEnableDraggingVertically:enableDraggingVertically];\n\n  [sOverviewView addPageView:[NIInspectionOverviewPageView page]];\n  [sOverviewView addPageView:[NIOverviewMemoryPageView page]];\n  [sOverviewView addPageView:[NIOverviewDiskPageView page]];\n  [sOverviewView addPageView:[NIOverviewMemoryCachePageView page]];\n  [sOverviewView addPageView:[NIOverviewConsoleLogPageView page]];\n  [sOverviewView addPageView:[NIOverviewMaxLogLevelPageView page]];\n\n  // Hide the view initially because the initial frame will be wrong when the device\n  // starts the app in any orientation other than portrait. Don't worry, we'll fade the\n  // view in once we get our first device notification.\n  sOverviewView.hidden = YES;\n\n  [window addSubview:sOverviewView];\n  \n  NSLog(@\"The overview has been added to a window.\");\n#endif\n}\n\n+ (NIOverviewLogger *)logger {\n#if defined(DEBUG) || defined(NI_DEBUG)\n  return [NIOverviewLogger sharedLogger];\n#else\n  return nil;\n#endif\n}\n\n+ (CGFloat)height {\n#if defined(DEBUG) || defined(NI_DEBUG)\n  return sOverviewHeight;\n#else\n  return 0;\n#endif\n}\n\n+ (CGRect)frame {\n#if defined(DEBUG) || defined(NI_DEBUG)\n  UIInterfaceOrientation orient = NIInterfaceOrientation();\n  CGFloat overviewWidth;\n  CGRect frame;\n  CGFloat overviewHeight =\n      sOverviewHasOverridenStatusBarHeight ? NIOverviewStatusBarHeight() : NIStatusBarHeight();\n\n  // We can't take advantage of automatic view positioning because the overview exists\n  // at the topmost view level (even above the root view controller). As such, we have to\n  // calculate the frame depending on the interface orientation.\n  if (orient == UIInterfaceOrientationLandscapeLeft) {\n    overviewWidth = [UIScreen mainScreen].bounds.size.height;\n    frame = CGRectMake(overviewHeight, 0, sOverviewHeight, overviewWidth);\n\n  } else if (orient == UIInterfaceOrientationLandscapeRight) {\n    overviewWidth = [UIScreen mainScreen].bounds.size.height;\n    frame = CGRectMake([UIScreen mainScreen].bounds.size.width\n                       - (overviewHeight + sOverviewHeight), 0, sOverviewHeight, overviewWidth);\n\n  } else if (orient == UIInterfaceOrientationPortraitUpsideDown) {\n    overviewWidth = [UIScreen mainScreen].bounds.size.width;\n    frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height\n                       - (overviewHeight + sOverviewHeight), overviewWidth, sOverviewHeight);\n\n  } else if (orient == UIInterfaceOrientationPortrait) {\n    overviewWidth = [UIScreen mainScreen].bounds.size.width;\n    frame = CGRectMake(0, overviewHeight, overviewWidth, sOverviewHeight);\n\n  } else {\n    overviewWidth = [UIScreen mainScreen].bounds.size.width;\n    frame = CGRectMake(0, overviewHeight, overviewWidth, sOverviewHeight);\n  }\n  if ([[UIApplication sharedApplication] isStatusBarHidden]) {\n    // When the status bar is hidden we want to position the overview offscreen.\n    switch (orient) {\n      case UIInterfaceOrientationLandscapeLeft: {\n        frame = CGRectOffset(frame, -frame.size.width, 0);\n        break;\n      }\n      case UIInterfaceOrientationLandscapeRight: {\n        frame = CGRectOffset(frame, frame.size.width, 0);\n        break;\n      }\n#if defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0\n        // Only defined in >= iOS8 SDK\n      case UIInterfaceOrientationUnknown:\n#endif  // defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0\n      case UIInterfaceOrientationPortrait: {\n        frame = CGRectOffset(frame, 0, -frame.size.height);\n        break;\n      }\n      case UIInterfaceOrientationPortraitUpsideDown: {\n        frame = CGRectOffset(frame, 0, frame.size.height);\n        break;\n      }\n    }\n  }\n  return frame;\n\n#else\n  return CGRectZero;\n#endif\n}\n\n+ (UIView *)view {\n#if defined(DEBUG) || defined(NI_DEBUG)\n  return sOverviewView;\n#else\n  return nil;\n#endif\n}\n\n@end\n"
  },
  {
    "path": "src/overview/src/NIOverviewGraphView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n#import \"NIPreprocessorMacros.h\" /* for weak */\n\n@protocol NIOverviewGraphViewDataSource;\n\n/**\n * A graph view.\n *\n * @ingroup Overview-Pages\n */\n@interface NIOverviewGraphView : UIView\n\n/**\n * The data source for this graph view.\n */\n@property (nonatomic, weak) id<NIOverviewGraphViewDataSource> dataSource;\n\n@end\n\n/**\n * The data source for NIOverviewGraphView.\n *\n * @ingroup Overview-Pages\n */\n@protocol NIOverviewGraphViewDataSource <NSObject>\n\n@required\n\n/**\n * Fetches the total range of all x values for this graph.\n */\n- (CGFloat)graphViewXRange:(NIOverviewGraphView *)graphView;\n\n/**\n * Fetches the total range of all y values for this graph.\n */\n- (CGFloat)graphViewYRange:(NIOverviewGraphView *)graphView;\n\n/**\n * The data source should reset its iterator for fetching points in the graph.\n */\n- (void)resetPointIterator;\n\n/**\n * Fetches the next point in the graph to plot.\n */\n- (BOOL)nextPointInGraphView: (NIOverviewGraphView *)graphView\n                       point: (CGPoint *)point;\n\n/**\n * The data source should reset its iterator for fetching events in the graph.\n */\n- (void)resetEventIterator;\n\n/**\n * Fetches the next event in the graph to plot.\n */\n- (BOOL)nextEventInGraphView: (NIOverviewGraphView *)graphView\n                      xValue: (CGFloat *)xValue\n                       color: (UIColor **)color;\n\n@end\n"
  },
  {
    "path": "src/overview/src/NIOverviewGraphView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIOverviewGraphView.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n#import \"NIFoundationMethods.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NIOverviewGraphView\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.opaque = NO;\n    self.layer.borderWidth = 1;\n    self.layer.borderColor = [UIColor colorWithWhite:1 alpha:0.2f].CGColor;\n  }\n  return self;\n}\n\n- (void)drawGraphWithContext:(CGContextRef)context {\n  CGSize contentSize = self.bounds.size;\n\n  CGFloat xRange = [self.dataSource graphViewXRange:self];\n  CGFloat yRange = [self.dataSource graphViewYRange:self];\n  if (xRange == 0 || yRange == 0) {\n    return;\n  }\n\n  [self.dataSource resetPointIterator];\n\n  CGContextSetLineWidth(context, 1);\n  CGContextSetShouldAntialias(context, YES);\n\n  BOOL isFirstPoint = YES;\n  CGPoint point = CGPointZero;\n  while ([self.dataSource nextPointInGraphView:self point:&point]) {\n    CGPoint scaledPoint = CGPointMake(point.x / xRange, point.y / yRange);\n    CGPoint plotPoint = CGPointMake(NICGFloatFloor(scaledPoint.x * contentSize.width) - 0.5f,\n                                    contentSize.height\n                                    - NICGFloatFloor((scaledPoint.y * 0.8f + 0.1f)\n                                                     * contentSize.height) - 0.5f);\n    if (!isFirstPoint) {\n      CGContextAddLineToPoint(context, plotPoint.x, plotPoint.y);\n    }\n    CGContextMoveToPoint(context, plotPoint.x, plotPoint.y);\n    isFirstPoint = NO;\n  }\n\n\tCGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:1 alpha:0.6f].CGColor);\n\tCGContextStrokePath(context);\n  \n  [self.dataSource resetEventIterator];\n\n  CGFloat xValue = 0;\n  UIColor* color = nil;\n  while ([self.dataSource nextEventInGraphView:self xValue:&xValue color:&color]) {\n    CGFloat scaledXValue = xValue / xRange;\n    CGFloat plotXValue = NICGFloatFloor(scaledXValue * contentSize.width) - 0.5f;\n    CGContextMoveToPoint(context, plotXValue, 0);\n    CGContextAddLineToPoint(context, plotXValue, contentSize.height);\n\n    CGContextSetStrokeColorWithColor(context, color.CGColor);\n    CGContextStrokePath(context);\n  }\n}\n\n- (void)drawRect:(CGRect)rect {\n\tCGContextRef context = UIGraphicsGetCurrentContext();\n\n  CGRect bounds = self.bounds;\n  \n  UIGraphicsPushContext(context);\n\n  [self drawGraphWithContext:context];\n  \n\tCGContextSetFillColorWithColor(context, [UIColor colorWithWhite:1 alpha:0.2f].CGColor);\n\tCGContextFillRect(context, bounds);\n\n  CGGradientRef glossGradient = nil;\n  CGColorSpaceRef colorspace = nil;\n  size_t numberOfLocations = 2;\n  CGFloat locations[2] = { 0.0f, 1.0f };\n  CGFloat components[8] = {\n    1.0f, 1.0f, 1.0f, 0.35f,\n    1.0f, 1.0f, 1.0f, 0.06f\n  };\n\n  colorspace = CGColorSpaceCreateDeviceRGB();\n  glossGradient = CGGradientCreateWithColorComponents(colorspace,\n                                                      components, locations, numberOfLocations);\n\n  CGPoint topCenter = CGPointMake(CGRectGetMidX(bounds), 0.0f);\n  CGPoint midCenter = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));\n  CGContextDrawLinearGradient(context, glossGradient, topCenter, midCenter, 0);\n\n  CGGradientRelease(glossGradient);\n  glossGradient = nil;\n  CGColorSpaceRelease(colorspace);\n  colorspace = nil;\n\n  UIGraphicsPopContext();\n}\n\n@end\n"
  },
  {
    "path": "src/overview/src/NIOverviewLogger.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nextern NSString* const NIOverviewLoggerDidAddDeviceLog;\nextern NSString* const NIOverviewLoggerDidAddConsoleLog;\nextern NSString* const NIOverviewLoggerDidAddEventLog;\n\n@class NIOverviewDeviceLogEntry;\n@class NIOverviewConsoleLogEntry;\n@class NIOverviewEventLogEntry;\n\n/**\n * The Overview logger.\n *\n * @ingroup Overview-Logger\n *\n * This object stores all of the historical information used to draw the graphs in the\n * Overview memory and disk pages, as well as the console log page.\n *\n * The primary log should be accessed by calling [NIOverview @link NIOverview::logger logger@endlink].\n */\n@interface NIOverviewLogger : NSObject\n\n#pragma mark Configuration Settings /** @name Configuration Settings */\n\n/**\n * The oldest age of a memory or disk log entry.\n *\n * Log entries older than this number of seconds will be pruned from the log.\n *\n * By default this is 1 minute.\n */\n@property (nonatomic, assign) NSTimeInterval oldestLogAge;\n\n\n+ (NIOverviewLogger*)sharedLogger;\n\n\n#pragma mark Adding Log Entries /** @name Adding Log Entries */\n\n/**\n * Add a device log.\n *\n * This method will first prune expired entries and then add the new entry to the log.\n */\n- (void)addDeviceLog:(NIOverviewDeviceLogEntry *)logEntry;\n\n/**\n * Add a console log.\n *\n * This method will not prune console log entries.\n */\n- (void)addConsoleLog:(NIOverviewConsoleLogEntry *)logEntry;\n\n/**\n * Add a event log.\n *\n * This method will first prune expired entries and then add the new entry to the log.\n */\n- (void)addEventLog:(NIOverviewEventLogEntry *)logEntry;\n\n\n#pragma mark Accessing Logs /** @name Accessing Logs */\n\n/**\n * The linked list of device logs.\n *\n * Log entries are in increasing chronological order.\n */\n@property (nonatomic, readonly, strong) NSMutableOrderedSet* deviceLogs;\n\n/**\n * The linked list of console logs.\n *\n * Log entries are in increasing chronological order.\n */\n@property (nonatomic, readonly, strong) NSMutableOrderedSet* consoleLogs;\n\n/**\n * The linked list of events.\n *\n * Log entries are in increasing chronological order.\n */\n@property (nonatomic, readonly, strong) NSMutableOrderedSet* eventLogs;\n\n@end\n\n\n/**\n * The basic requirements for a log entry.\n *\n * @ingroup Overview-Logger-Entries\n *\n * A basic log entry need only define a timestamp in order to be particularly useful.\n */\n@interface NIOverviewLogEntry : NSObject\n\n#pragma mark Creating an Entry /** @name Creating an Entry */\n\n/**\n * Designated initializer.\n */\n- (id)initWithTimestamp:(NSDate *)timestamp;\n\n\n#pragma mark Entry Information /** @name Entry Information */\n\n/**\n * The timestamp for this log entry.\n */\n@property (nonatomic, retain) NSDate* timestamp;\n\n@end\n\n\n/**\n * A device log entry.\n *\n * @ingroup Overview-Logger-Entries\n */\n@interface NIOverviewDeviceLogEntry : NIOverviewLogEntry\n\n#pragma mark Entry Information /** @name Entry Information */\n\n/**\n * The number of bytes of free memory.\n */\n@property (nonatomic, assign) unsigned long long bytesOfFreeMemory;\n\n/**\n * The number of bytes of total memory.\n */\n@property (nonatomic, assign) unsigned long long bytesOfTotalMemory;\n\n/**\n * The number of bytes of free disk space.\n */\n@property (nonatomic, assign) unsigned long long bytesOfFreeDiskSpace;\n\n/**\n * The number of bytes of total disk space.\n */\n@property (nonatomic, assign) unsigned long long bytesOfTotalDiskSpace;\n\n/**\n * The battery level.\n */\n@property (nonatomic, assign) CGFloat batteryLevel;\n\n/**\n * The state of the battery.\n */\n@property (nonatomic, assign) UIDeviceBatteryState batteryState;\n\n@end\n\n\n/**\n * A console log entry.\n *\n * @ingroup Overview-Logger-Entries\n */\n@interface NIOverviewConsoleLogEntry : NIOverviewLogEntry\n\n#pragma mark Creating an Entry /** @name Creating an Entry */\n\n/**\n * Designated initializer.\n */\n- (id)initWithLog:(NSString *)log;\n\n\n#pragma mark Entry Information /** @name Entry Information */\n\n/**\n * The text that was written to the console log.\n */\n@property (nonatomic, copy) NSString* log;\n\n@end\n\n\ntypedef enum {\n  NIOverviewEventDidReceiveMemoryWarning,\n} NIOverviewEventType;\n\n/**\n * An event log entry.\n *\n * @ingroup Overview-Logger-Entries\n */\n@interface NIOverviewEventLogEntry : NIOverviewLogEntry\n\n#pragma mark Creating an Entry /** @name Creating an Entry */\n\n/**\n * Designated initializer.\n */\n- (id)initWithType:(NSInteger)type;\n\n\n#pragma mark Entry Information /** @name Entry Information */\n\n/**\n * The type of event.\n */\n@property (nonatomic, assign) NSInteger type;\n\n@end\n"
  },
  {
    "path": "src/overview/src/NIOverviewLogger.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIOverviewLogger.h\"\n#import \"NIDeviceInfo.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nNSString* const NIOverviewLoggerDidAddDeviceLog = @\"NIOverviewLoggerDidAddDeviceLog\";\nNSString* const NIOverviewLoggerDidAddConsoleLog = @\"NIOverviewLoggerDidAddConsoleLog\";\nNSString* const NIOverviewLoggerDidAddEventLog = @\"NIOverviewLoggerDidAddEventLog\";\n\n@implementation NIOverviewLogger {\n  NSMutableOrderedSet* _deviceLogs;\n  NSMutableOrderedSet* _consoleLogs;\n  NSMutableOrderedSet* _eventLogs;\n  NSTimeInterval _oldestLogAge;\n  NSTimer* _heartbeatTimer;\n}\n\n+ (NIOverviewLogger*)sharedLogger\n{\n  static dispatch_once_t pred = 0;\n  static NIOverviewLogger* instance = nil;\n  \n  dispatch_once(&pred, ^{\n    instance = [[NIOverviewLogger alloc] init];\n  });\n  \n  return instance;\n}\n\n- (id)init {\n  if ((self = [super init])) {\n    _deviceLogs = [[NSMutableOrderedSet alloc] init];\n    _consoleLogs = [[NSMutableOrderedSet alloc] init];\n    _eventLogs = [[NSMutableOrderedSet alloc] init];\n    \n    _oldestLogAge = 60;\n    \n    _heartbeatTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5\n                                                       target: self\n                                                     selector: @selector(heartbeat)\n                                                     userInfo: nil\n                                                      repeats: YES];\n  }\n  return self;\n}\n\n- (void)dealloc {\n  [_heartbeatTimer invalidate];\n  _heartbeatTimer = nil;\n}\n\n- (void)heartbeat {\n  [NIDeviceInfo beginCachedDeviceInfo];\n  NIOverviewDeviceLogEntry* logEntry =\n  [[NIOverviewDeviceLogEntry alloc] initWithTimestamp:[NSDate date]];\n  logEntry.bytesOfTotalDiskSpace = [NIDeviceInfo bytesOfTotalDiskSpace];\n  logEntry.bytesOfFreeDiskSpace = [NIDeviceInfo bytesOfFreeDiskSpace];\n  logEntry.bytesOfFreeMemory = [NIDeviceInfo bytesOfFreeMemory];\n  logEntry.bytesOfTotalMemory = [NIDeviceInfo bytesOfTotalMemory];\n  logEntry.batteryLevel = [NIDeviceInfo batteryLevel];\n  logEntry.batteryState = [NIDeviceInfo batteryState];\n  [NIDeviceInfo endCachedDeviceInfo];\n  \n  [self addDeviceLog:logEntry];\n}\n\n- (void)pruneEntriesFromLinkedList:(NSMutableOrderedSet *)ll {\n  NSDate* cutoffDate = [NSDate dateWithTimeIntervalSinceNow:-_oldestLogAge];\n  while ([[((NIOverviewLogEntry *)[ll firstObject])\n           timestamp] compare:cutoffDate] == NSOrderedAscending) {\n    [ll removeObjectAtIndex:0];\n  }\n}\n\n- (void)addDeviceLog:(NIOverviewDeviceLogEntry *)logEntry {\n  [self pruneEntriesFromLinkedList:_deviceLogs];\n\n  [_deviceLogs addObject:logEntry];\n  \n  [[NSNotificationCenter defaultCenter] postNotificationName:NIOverviewLoggerDidAddDeviceLog\n                                                      object:nil\n                                                    userInfo:@{@\"entry\":logEntry}];\n}\n\n- (void)addConsoleLog:(NIOverviewConsoleLogEntry *)logEntry {\n  [_consoleLogs addObject:logEntry];\n  \n  [[NSNotificationCenter defaultCenter] postNotificationName:NIOverviewLoggerDidAddConsoleLog\n                                                      object:nil\n                                                    userInfo:@{@\"entry\":logEntry}];\n}\n\n- (void)addEventLog:(NIOverviewEventLogEntry *)logEntry {\n  [self pruneEntriesFromLinkedList:_eventLogs];\n\n  [_eventLogs addObject:logEntry];\n  \n  [[NSNotificationCenter defaultCenter] postNotificationName:NIOverviewLoggerDidAddEventLog\n                                                      object:nil\n                                                    userInfo:@{@\"entry\":logEntry}];\n}\n\n@end\n\n\n@implementation NIOverviewLogEntry\n\n- (id)initWithTimestamp:(NSDate *)timestamp {\n  if ((self = [super init])) {\n    _timestamp = timestamp;\n  }\n  return self;\n}\n\n@end\n\n\n@implementation NIOverviewDeviceLogEntry\n@end\n\n\n@implementation NIOverviewConsoleLogEntry\n\n- (id)initWithLog:(NSString *)logText {\n  if ((self = [super initWithTimestamp:[NSDate date]])) {\n    _log = [logText copy];\n  }\n\n  return self;\n}\n\n@end\n\n\n@implementation NIOverviewEventLogEntry\n\n- (id)initWithType:(NSInteger)type {\n  if ((self = [super initWithTimestamp:[NSDate date]])) {\n    _type = type;\n  }\n  \n  return self;\n}\n\n@end\n"
  },
  {
    "path": "src/overview/src/NIOverviewMemoryCacheController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@class NIMemoryCache;\n\n/**\n * A view controller that displays the contents of an in-memory cache.\n *\n * Requires the [models] feature.\n *\n * This controller provides useful debugging insights into the contents of an in-memory cache.\n * It presents a simple summary of the contents of the cache, followed by a listing of each\n * object in the cache.\n *\n * When the cache is a NIImageMemoryCache, the pixel information will also be displayed in the\n * summary and each of the images will be displayed.\n *\n * @ingroup Overview\n */\n@interface NIOverviewMemoryCacheController : UITableViewController\n\n// Designated initializer.\n- (id)initWithMemoryCache:(NIMemoryCache *)cache;\n\n@end\n\n/**\n * Initializes a newly allocated cache controller with the given cache object.\n *\n * @fn NIOverviewImageCacheController::initWithMemoryCache:\n */\n"
  },
  {
    "path": "src/overview/src/NIOverviewMemoryCacheController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIOverviewMemoryCacheController.h\"\n\n#import \"NIDeviceInfo.h\"\n#import \"NimbusModels.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NIMemoryCache(Private)\n@property (nonatomic, strong) NSMutableOrderedSet* lruCacheObjects;\n@end\n\n// Anonymous private category for LRU cache objects.\n@interface NSObject(Private)\n- (NSDate *)lastAccessTime;\n@end\n\n@interface NIOverviewMemoryCacheController()\n@property (nonatomic, readonly, strong) NIMemoryCache* cache;\n@property (nonatomic, strong) NITableViewModel* model;\n@end\n\n@implementation NIOverviewMemoryCacheController\n\n- (void)dealloc {\n  NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];\n  [nc removeObserver:self];\n}\n\n- (id)initWithMemoryCache:(NIMemoryCache *)cache {\n  if ((self = [super initWithStyle:UITableViewStyleGrouped])) {\n    _cache = cache;\n\n    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];\n    [nc addObserver: self\n           selector: @selector(didReceiveMemoryWarning:)\n               name: UIApplicationDidReceiveMemoryWarningNotification\n             object: nil];\n    UIBarButtonItem* refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(didTapRefreshButton:)];\n    self.navigationItem.rightBarButtonItem = refreshButton;\n  }\n  return self;\n}\n\n- (id)initWithStyle:(UITableViewStyle)style {\n  return [self initWithMemoryCache:[Nimbus imageMemoryCache]];\n}\n\n#pragma mark - Model\n\n\n- (void)refreshModel {\n  NSMutableArray* contents = [NSMutableArray array];\n  NSString* summary = nil;\n\n  // Display a summary.\n  if ([self.cache isKindOfClass:[NIImageMemoryCache class]]) {\n    NIImageMemoryCache* imageCache = (NIImageMemoryCache *)self.cache;\n    summary = [NSString stringWithFormat:\n               @\"Number of images: %zd\\nNumber of pixels: %@/%@\\nStress limit: %@\",\n               self.cache.count,\n               NIStringFromBytes(imageCache.numberOfPixels),\n               NIStringFromBytes(imageCache.maxNumberOfPixels),\n               NIStringFromBytes(imageCache.maxNumberOfPixelsUnderStress)];\n\n  } else {\n    summary = [NSString stringWithFormat:\n               @\"Number of objects: %zd\",\n               self.cache.count];\n  }\n  [contents addObject:[NITableViewModelFooter footerWithTitle:summary]];\n\n  NSDateFormatter* formatter = [[NSDateFormatter alloc] init];\n  // We care more about time than date here.\n  [formatter setDateStyle:NSDateFormatterShortStyle];\n  [formatter setTimeStyle:NSDateFormatterMediumStyle];\n\n  // Add each of the cache objects to the model.\n  for (id cacheObject in self.cache.lruCacheObjects) {\n    NSString* name = nil;\n    UIImage* image = nil;\n    NSDate* lastAccessTime = nil;\n\n    // We're accessing a private object from the core here, so we can't assume that any of\n    // these selectors will be around forever. That being said, we should try to remember to\n    // update this controller if the cache object internals ever change.\n    // If any of these assertions fire it means we've changed the cache object signatures but\n    // haven't gotten around to updating this controller yet.\n    NIDASSERT([cacheObject respondsToSelector:@selector(name)]);\n    if ([cacheObject respondsToSelector:@selector(name)]) {\n      name = [cacheObject performSelector:@selector(name)];\n    }\n    NIDASSERT([cacheObject respondsToSelector:@selector(object)]);\n    if ([cacheObject respondsToSelector:@selector(object)]) {\n      id object = [cacheObject performSelector:@selector(object)];\n      if ([object isKindOfClass:[UIImage class]]) {\n        image = object;\n      }\n    }\n    NIDASSERT([cacheObject respondsToSelector:@selector(lastAccessTime)]);\n    if ([cacheObject respondsToSelector:@selector(lastAccessTime)]) {\n      lastAccessTime = [cacheObject performSelector:@selector(lastAccessTime)];\n    }\n\n    [contents addObject:\n     [NISubtitleCellObject objectWithTitle:name\n                                  subtitle:[NSString stringWithFormat:\n                                            @\"Last access: %@\",\n                                            [formatter stringFromDate:lastAccessTime]]\n                                     image:image]];\n  }\n\n  if (0 == self.cache.count) {\n    [contents addObject:[NITitleCellObject objectWithTitle:@\"No cache objects\"]];\n  }\n\n  [contents addObject:[NITableViewModelFooter footerWithTitle:\n                       @\"The most-recently-used object is here at the bottom\"]];\n\n  self.model = [[NITableViewModel alloc] initWithSectionedArray:contents\n                                                       delegate:(id)[NICellFactory class]];\n  self.tableView.dataSource = self.model;\n  [self.tableView reloadData];\n}\n\n- (void)viewDidLoad {\n  [super viewDidLoad];\n\n  [self refreshModel];\n}\n\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {\n  return NIIsSupportedOrientation(toInterfaceOrientation);\n}\n\n#endif\n\n#pragma mark - Notifications\n\n\n- (void)didReceiveMemoryWarning:(NSNotification *)notification {\n  [self refreshModel];\n}\n\n#pragma mark - Actions\n\n\n- (void)didTapRefreshButton:(UIBarButtonItem *)button {\n  [self refreshModel];\n}\n\n@end\n"
  },
  {
    "path": "src/overview/src/NIOverviewPageView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\n#import \"NIOverviewGraphView.h\"\n\n@class NIMemoryCache;\n\n/**\n * A page in the Overview.\n *\n * @ingroup Overview-Pages\n */\n@interface NIOverviewPageView : UIView\n\n#pragma mark Creating a Page /** @name Creating a Page */\n\n/**\n * Returns an autoreleased instance of this view.\n */\n+ (NIOverviewPageView *)page;\n\n\n#pragma mark Updating a Page /** @name Updating a Page */\n\n/**\n * Request that this page update its information.\n *\n * Should be implemented by the subclass. The default implementation does nothing.\n */\n- (void)update;\n\n\n#pragma mark Configuring a Page /** @name Configuring a Page */\n\n/**\n * The title of the page.\n */\n@property (nonatomic, copy) NSString* pageTitle;\n\n\n/**\n * The following methods are provided to aid in subclassing and are not meant to be\n * used externally.\n */\n#pragma mark Subclassing /** @name Subclassing */\n\n/**\n * The title label for this page.\n *\n * By default this label will be placed flush to the bottom middle of the page.\n */\n@property (nonatomic, readonly, strong) UILabel* titleLabel;\n\n/**\n * Creates a generic label for use in the page.\n */\n- (UILabel *)label;\n\n@end\n\n\n/**\n * A page that renders a graph and two labels.\n *\n * @ingroup Overview-Pages\n */\n@interface NIOverviewGraphPageView : NIOverviewPageView <\n  NIOverviewGraphViewDataSource\n> {\n@private\n  UILabel* _label1;\n  UILabel* _label2;\n  NIOverviewGraphView* _graphView;\n  NSEnumerator* _eventEnumerator;\n}\n\n@property (nonatomic, readonly, strong) UILabel* label1;\n@property (nonatomic, readonly, strong) UILabel* label2;\n@property (nonatomic, readonly, strong) NIOverviewGraphView* graphView;\n\n@end\n\n\n/**\n * A page that renders a graph showing free memory.\n *\n * @image html overview-memory1.png \"The memory page.\"\n *\n * @ingroup Overview-Pages\n */\n@interface NIOverviewMemoryPageView : NIOverviewGraphPageView {\n@private\n  NSEnumerator* _enumerator;\n  unsigned long long _minMemory;\n}\n\n@end\n\n\n/**\n * A page that renders a graph showing free disk space.\n *\n * @image html overview-disk1.png \"The disk page.\"\n *\n * @ingroup Overview-Pages\n */\n@interface NIOverviewDiskPageView : NIOverviewGraphPageView {\n@private\n  NSEnumerator* _enumerator;\n  unsigned long long _minDiskUse;\n}\n\n@end\n\n\n/**\n * A page that shows all of the logs sent to the console.\n *\n * @image html overview-log1.png \"The log page.\"\n *\n * @ingroup Overview-Pages\n */\n@interface NIOverviewConsoleLogPageView : NIOverviewPageView {\n@private\n  UIScrollView* _logScrollView;\n  UILabel* _logLabel;\n}\n\n@end\n\n\n/**\n * A page that allows you to modify NIMaxLogLevel.\n *\n * @image html overview-maxloglevel1.png \"The max log level page.\"\n *\n * @ingroup Overview-Pages\n */\n@interface NIOverviewMaxLogLevelPageView : NIOverviewPageView {\n@private\n  UISlider* _logLevelSlider;\n  UILabel* _errorLogLevelLabel;\n  UILabel* _warningLogLevelLabel;\n  UILabel* _infoLogLevelLabel;\n}\n\n@end\n\n\n/**\n * A page that shows information regarding an in-memory cache.\n *\n * @ingroup Overview-Pages\n */\n@interface NIOverviewMemoryCachePageView : NIOverviewGraphPageView\n\n/**\n * Returns an autoreleased instance of this page with the given cache.\n */\n+ (id)pageWithCache:(NIMemoryCache *)cache;\n\n@property (nonatomic, strong) NIMemoryCache* cache;\n@end\n\n\n/**\n * A page that adds run-time inspection features.\n *\n * @ingroup Overview-Pages\n */\n@interface NIInspectionOverviewPageView : NIOverviewPageView\n@end\n\n\n#endif\n"
  },
  {
    "path": "src/overview/src/NIOverviewPageView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIOverviewPageView.h\"\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\n#import \"NIOverview.h\"\n#import \"NIOverviewView.h\"\n#import \"NIDeviceInfo.h\"\n#import \"NIOverviewGraphView.h\"\n#import \"NIOverviewLogger.h\"\n#import \"NimbusCore.h\"\n#import <QuartzCore/QuartzCore.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic UIEdgeInsets kPagePadding;\nstatic const CGFloat kGraphRightMargin = 5;\n\n@interface NSObject ()\n- (id)initWithMemoryCache:(NIMemoryCache *)memoryCache;\n@end\n\n\n@implementation NIOverviewPageView\n\n\n\n+ (void)initialize {\n  kPagePadding = UIEdgeInsetsMake(5, 5, 10, 5);\n}\n\n+ (NIOverviewPageView *)page {\n  return [[[self class] alloc] initWithFrame:CGRectZero];\n}\n\n- (UILabel *)label {\n  UILabel* label = [[UILabel alloc] init];\n  label.backgroundColor = [UIColor clearColor];\n  label.font = [UIFont boldSystemFontOfSize:12];\n  label.textColor = [UIColor whiteColor];\n  if (!NIIsTintColorGloballySupported()) {\n    label.shadowColor = [UIColor colorWithWhite:0 alpha:0.5f];\n    label.shadowOffset = CGSizeMake(0, 1);\n  }\n\n  return label;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.clipsToBounds = YES;\n\n    _titleLabel = [[UILabel alloc] init];\n    _titleLabel.backgroundColor = [UIColor clearColor];\n    _titleLabel.font = [UIFont boldSystemFontOfSize:11];\n    _titleLabel.textColor = [UIColor colorWithWhite:1 alpha:0.8f];\n    [self addSubview:_titleLabel];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  [_titleLabel sizeToFit];\n  CGRect frame = _titleLabel.frame;\n  frame.origin.x = NICGFloatFloor((self.bounds.size.width - frame.size.width) / 2);\n  frame.origin.y = self.bounds.size.height - frame.size.height;\n  _titleLabel.frame = frame;\n}\n\n- (void)setPageTitle:(NSString *)pageTitle {\n  if (_pageTitle != pageTitle) {\n    _pageTitle = [pageTitle copy];\n\n    _titleLabel.text = _pageTitle;\n    [self setNeedsLayout];\n  }\n}\n\n- (void)update {\n  // No-op.\n}\n\n@end\n\n\n@implementation NIOverviewGraphPageView\n\n\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.pageTitle = NSLocalizedString(@\"Memory\", @\"Overview Page Title: Memory\");\n\n    _label1 = [self label];\n    [self addSubview:_label1];\n    _label2 = [self label];\n    [self addSubview:_label2];\n\n    _graphView = [[NIOverviewGraphView alloc] init];\n    _graphView.dataSource = self;\n    [self addSubview:_graphView];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  CGFloat contentWidth = self.frame.size.width - kPagePadding.left - kPagePadding.right;\n  CGFloat contentHeight = self.frame.size.height - kPagePadding.top - kPagePadding.bottom;\n\n  [_label1 sizeToFit];\n  [_label2 sizeToFit];\n\n  CGFloat maxLabelWidth = MAX(_label1.frame.size.width,\n                              _label2.frame.size.width);\n  CGFloat remainingContentWidth = contentWidth - maxLabelWidth - kGraphRightMargin;\n\n  CGRect frame = _label1.frame;\n  frame.origin.x = kPagePadding.left + remainingContentWidth + kGraphRightMargin;\n  frame.origin.y = kPagePadding.top;\n  _label1.frame = frame;\n\n  frame = _label2.frame;\n  frame.origin.x = kPagePadding.left + remainingContentWidth + kGraphRightMargin;\n  frame.origin.y = CGRectGetMaxY(_label1.frame);\n  _label2.frame = frame;\n\n  frame = self.titleLabel.frame;\n  frame.origin.x = kPagePadding.left + remainingContentWidth + kGraphRightMargin;\n  frame.origin.y = CGRectGetMaxY(_label2.frame);\n  self.titleLabel.frame = frame;\n\n  _graphView.frame = CGRectMake(kPagePadding.left, kPagePadding.top,\n                                remainingContentWidth, contentHeight);\n}\n\n- (void)update {\n  [_graphView setNeedsDisplay];\n}\n\n#pragma mark - NIOverviewGraphViewDataSource\n\n\n- (CGFloat)graphViewXRange:(NIOverviewGraphView *)graphView {\n  NSMutableOrderedSet* deviceLogs = [[NIOverview logger] deviceLogs];\n  NIOverviewLogEntry* firstEntry = [deviceLogs firstObject];\n  NIOverviewLogEntry* lastEntry = [deviceLogs lastObject];\n  NSTimeInterval interval = [lastEntry.timestamp timeIntervalSinceDate:firstEntry.timestamp];\n  return (CGFloat)interval;\n}\n\n- (CGFloat)graphViewYRange:(NIOverviewGraphView *)graphView {\n  return 0;\n}\n\n- (void)resetPointIterator {\n}\n\n- (BOOL)nextPointInGraphView: (NIOverviewGraphView *)graphView\n                       point: (CGPoint *)point {\n  return NO;\n}\n\n- (NSDate *)initialTimestamp {\n  return nil;\n}\n\n- (void)resetEventIterator {\n  _eventEnumerator = [[[NIOverview logger] eventLogs] objectEnumerator];\n}\n\n- (BOOL)nextEventInGraphView: (NIOverviewGraphView *)graphView\n                      xValue: (CGFloat *)xValue\n                       color: (UIColor **)color {\n  static NSArray* sEventColors = nil;\n  if (nil == sEventColors) {\n    sEventColors = [NSArray arrayWithObjects:\n                     [UIColor redColor], // NIOverviewEventDidReceiveMemoryWarning\n                     nil];\n  }\n  NIOverviewEventLogEntry* entry = [_eventEnumerator nextObject];\n  if (nil != entry) {\n    NSTimeInterval interval = [entry.timestamp timeIntervalSinceDate:[self initialTimestamp]];\n    *xValue = (CGFloat)interval;\n    *color = [sEventColors objectAtIndex:entry.type];\n  }\n  return nil != entry;\n}\n\n@end\n\n\n@implementation NIOverviewMemoryPageView\n\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.pageTitle = NSLocalizedString(@\"Memory\", @\"Overview Page Title: Memory\");\n\n    self.graphView.dataSource = self;\n\n    UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap:)];\n    // We still want to be able to drag the pages.\n    tap.cancelsTouchesInView = NO;\n    [self addGestureRecognizer:tap];\n  }\n  return self;\n}\n\n- (void)update {\n  [super update];\n\n  [NIDeviceInfo beginCachedDeviceInfo];\n\n  self.label1.text = [NSString stringWithFormat:@\"%@ free\",\n                      NIStringFromBytes([NIDeviceInfo bytesOfFreeMemory])];\n\n  self.label2.text = [NSString stringWithFormat:@\"%@ total\",\n                      NIStringFromBytes([NIDeviceInfo bytesOfTotalMemory])];\n\n  [NIDeviceInfo endCachedDeviceInfo];\n\n  [self setNeedsLayout];\n}\n\n- (void)didTap:(UIGestureRecognizer *)gesture {\n  // Simulate low memory warning while tapping on NIOverviewMemoryPageView\n  [NIDeviceInfo simulateLowMemoryWarning];\n}\n\n#pragma mark - NIOverviewGraphViewDataSource\n\n\n- (CGFloat)graphViewYRange:(NIOverviewGraphView *)graphView {\n  NSMutableOrderedSet* deviceLogs = [[NIOverview logger] deviceLogs];\n  if ([deviceLogs count] == 0) {\n    return 0;\n  }\n\n  unsigned long long minY = (unsigned long long)-1;\n  unsigned long long maxY = 0;\n  for (NIOverviewDeviceLogEntry* entry in deviceLogs) {\n    minY = MIN(entry.bytesOfFreeMemory, minY);\n    maxY = MAX(entry.bytesOfFreeMemory, maxY);\n  }\n  unsigned long long range = maxY - minY;\n  _minMemory = minY;\n  return (CGFloat)((double)range / 1024.0 / 1024.0);\n}\n\n- (void)resetPointIterator {\n  _enumerator = [[[NIOverview logger] deviceLogs] objectEnumerator];\n}\n\n- (NSDate *)initialTimestamp {\n  NSMutableOrderedSet* deviceLogs = [[NIOverview logger] deviceLogs];\n  NIOverviewLogEntry* firstEntry = [deviceLogs firstObject];\n  return firstEntry.timestamp;\n}\n\n- (BOOL)nextPointInGraphView: (NIOverviewGraphView *)graphView\n                       point: (CGPoint *)point {\n  NIOverviewDeviceLogEntry* entry = [_enumerator nextObject];\n  if (nil != entry) {\n    NSTimeInterval interval = [entry.timestamp timeIntervalSinceDate:[self initialTimestamp]];\n    *point = CGPointMake((CGFloat)interval,\n                         (CGFloat)(((double)(entry.bytesOfFreeMemory - _minMemory))\n                                   / 1024.0 / 1024.0));\n  }\n  return nil != entry;\n}\n\n@end\n\n\n@implementation NIOverviewDiskPageView\n\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.pageTitle = NSLocalizedString(@\"Storage\", @\"Overview Page Title: Storage\");\n\n    self.graphView.dataSource = self;\n  }\n  return self;\n}\n\n- (void)update {\n  [super update];\n\n  [NIDeviceInfo beginCachedDeviceInfo];\n\n  self.label1.text = [NSString stringWithFormat:@\"%@ free\",\n                      NIStringFromBytes([NIDeviceInfo bytesOfFreeDiskSpace])];\n\n  self.label2.text = [NSString stringWithFormat:@\"%@ total\",\n                      NIStringFromBytes([NIDeviceInfo bytesOfTotalDiskSpace])];\n\n  [NIDeviceInfo endCachedDeviceInfo];\n\n  [self setNeedsLayout];\n}\n\n#pragma mark - NIOverviewGraphViewDataSource\n\n\n- (CGFloat)graphViewYRange:(NIOverviewGraphView *)graphView {\n  NSMutableOrderedSet* deviceLogs = [[NIOverview logger] deviceLogs];\n  if ([deviceLogs count] == 0) {\n    return 0;\n  }\n\n  unsigned long long minY = (unsigned long long)-1;\n  unsigned long long maxY = 0;\n  for (NIOverviewDeviceLogEntry* entry in deviceLogs) {\n    minY = MIN(entry.bytesOfFreeDiskSpace, minY);\n    maxY = MAX(entry.bytesOfFreeDiskSpace, maxY);\n  }\n  unsigned long long range = maxY - minY;\n  _minDiskUse = minY;\n  return (CGFloat)((double)range / 1024.0 / 1024.0);\n}\n\n- (void)resetPointIterator {\n  _enumerator = [[[NIOverview logger] deviceLogs] objectEnumerator];\n}\n\n- (NSDate *)initialTimestamp {\n  NSMutableOrderedSet* deviceLogs = [[NIOverview logger] deviceLogs];\n  NIOverviewLogEntry* firstEntry = [deviceLogs firstObject];\n  return firstEntry.timestamp;\n}\n\n- (BOOL)nextPointInGraphView: (NIOverviewGraphView *)graphView\n                       point: (CGPoint *)point {\n  NIOverviewDeviceLogEntry* entry = [_enumerator nextObject];\n  if (nil != entry) {\n    NSTimeInterval interval = [entry.timestamp timeIntervalSinceDate:[self initialTimestamp]];\n    double difference = ((double)entry.bytesOfFreeDiskSpace / 1024.0 / 1024.0\n                         - (double)_minDiskUse / 1024.0 / 1024.0);\n    *point = CGPointMake((CGFloat)interval, (CGFloat)difference);\n  }\n  return nil != entry;\n}\n\n@end\n\n\n@implementation NIOverviewConsoleLogPageView\n\n\n- (void)dealloc {\n  [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (UILabel *)label {\n  UILabel* label = [[UILabel alloc] init];\n\n  label.font = [UIFont boldSystemFontOfSize:11];\n  label.textColor = [UIColor whiteColor];\n  if (!NIIsTintColorGloballySupported()) {\n    label.shadowColor = [UIColor colorWithWhite:0 alpha:0.5f];\n    label.shadowOffset = CGSizeMake(0, 1);\n  }\n  label.backgroundColor = [UIColor clearColor];\n  label.lineBreakMode = NSLineBreakByWordWrapping;\n  label.numberOfLines = 0;\n\n  return label;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.pageTitle = NSLocalizedString(@\"Logs\", @\"Overview Page Title: Logs\");\n\n    self.titleLabel.textColor = [UIColor colorWithWhite:1 alpha:0.5f];\n\n    _logScrollView = [[UIScrollView alloc] initWithFrame:self.bounds];\n    _logScrollView.showsHorizontalScrollIndicator = NO;\n    _logScrollView.alwaysBounceVertical = YES;\n    _logScrollView.contentInset = kPagePadding;\n\n    _logScrollView.backgroundColor = [UIColor colorWithWhite:1 alpha:0.2f];\n\n    [self addSubview:_logScrollView];\n\n    _logLabel = [self label];\n    [_logScrollView addSubview:_logLabel];\n\n    [[NSNotificationCenter defaultCenter] addObserver: self\n                                             selector: @selector(didAddLog:)\n                                                 name: NIOverviewLoggerDidAddConsoleLog\n                                               object: nil];\n  }\n  return self;\n}\n\n- (void)contentSizeChanged {\n  BOOL isBottomNearby = NO;\n  if (_logScrollView.contentOffset.y + _logScrollView.bounds.size.height\n      >= _logScrollView.contentSize.height - _logScrollView.bounds.size.height) {\n    isBottomNearby = YES;\n  }\n\n  _logScrollView.frame = CGRectMake(0, 0,\n                                    self.bounds.size.width,\n                                    self.bounds.size.height);\n\n  CGSize labelSize = [_logLabel.text sizeWithFont: _logLabel.font\n                                constrainedToSize: CGSizeMake(_logScrollView.bounds.size.width,\n                                                              CGFLOAT_MAX)\n                                    lineBreakMode: _logLabel.lineBreakMode];\n  _logLabel.frame = CGRectMake(0, 0,\n                               labelSize.width, labelSize.height);\n\n  _logScrollView.contentSize = CGSizeMake(_logScrollView.bounds.size.width\n                                          - kPagePadding.left - kPagePadding.right,\n                                          _logLabel.frame.size.height);\n\n  if (isBottomNearby) {\n    _logScrollView.contentOffset = CGPointMake(-kPagePadding.left,\n                                               MAX(_logScrollView.contentSize.height\n                                                   - _logScrollView.bounds.size.height\n                                                   + kPagePadding.top,\n                                                   -kPagePadding.top));\n    [_logScrollView flashScrollIndicators];\n  }\n}\n\n- (void)setFrame:(CGRect)frame {\n  [super setFrame:frame];\n\n  [self contentSizeChanged];\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  CGRect labelFrame = self.titleLabel.frame;\n  labelFrame.origin.x = (self.bounds.size.width\n                         - kPagePadding.right - self.titleLabel.frame.size.width);\n  labelFrame.origin.y = (self.bounds.size.height\n                         - kPagePadding.bottom - self.titleLabel.frame.size.height);\n  self.titleLabel.frame = labelFrame;\n}\n\n- (void)didAddLog:(NSNotification *)notification {\n  NIOverviewConsoleLogEntry* entry = [[notification userInfo] objectForKey:@\"entry\"];\n\n  static NSDateFormatter* formatter = nil;\n  if (nil == formatter) {\n    formatter = [[NSDateFormatter alloc] init];\n    [formatter setTimeStyle:NSDateFormatterShortStyle];\n    [formatter setDateStyle:NSDateFormatterNoStyle];\n  }\n\n  NSString* formattedLog = [NSString stringWithFormat:@\"%@: %@\",\n                            [formatter stringFromDate:entry.timestamp],\n                            entry.log];\n\n  if (nil != _logLabel.text) {\n    _logLabel.text = [_logLabel.text stringByAppendingFormat:@\"\\n%@\", formattedLog];\n  } else {\n    _logLabel.text = formattedLog;\n  }\n\n  [self contentSizeChanged];\n}\n\n@end\n\n\n@implementation NIOverviewMaxLogLevelPageView\n\n\n- (UILabel *)label {\n  UILabel* label = [[UILabel alloc] init];\n\n  label.font = [UIFont boldSystemFontOfSize:11];\n  label.textColor = [UIColor whiteColor];\n  if (!NIIsTintColorGloballySupported()) {\n    label.shadowColor = [UIColor colorWithWhite:0 alpha:0.5f];\n    label.shadowOffset = CGSizeMake(0, 1);\n  }\n  label.backgroundColor = [UIColor clearColor];\n  label.lineBreakMode = NSLineBreakByWordWrapping;\n  label.numberOfLines = 0;\n\n  return label;\n}\n\n- (void)updateLabels {\n  _warningLogLevelLabel.textColor = [_warningLogLevelLabel.textColor colorWithAlphaComponent:\n                                     (NIMaxLogLevel >= NILOGLEVEL_WARNING) ? 1 : 0.6f];\n  _infoLogLevelLabel.textColor = [_infoLogLevelLabel.textColor colorWithAlphaComponent:\n                                  (NIMaxLogLevel >= NILOGLEVEL_INFO) ? 1 : 0.6f];\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.pageTitle = NSLocalizedString(@\"Max Log Level\", @\"Overview Page Title: Max Log Level\");\n\n    self.titleLabel.textColor = [UIColor colorWithWhite:1 alpha:0.5f];\n\n    _logLevelSlider = [[UISlider alloc] init];\n    _logLevelSlider.minimumValue = 1;\n    _logLevelSlider.maximumValue = 5;\n    [_logLevelSlider addTarget: self\n                        action: @selector(didChangeSliderValue:)\n              forControlEvents: UIControlEventValueChanged];\n    [self addSubview:_logLevelSlider];\n\n    _logLevelSlider.value = NIMaxLogLevel;\n\n    _errorLogLevelLabel = [self label];\n    _warningLogLevelLabel = [self label];\n    _infoLogLevelLabel = [self label];\n\n    _errorLogLevelLabel.text = NSLocalizedString(@\"Error\", @\"Maximum log level: error\");\n    _warningLogLevelLabel.text = NSLocalizedString(@\"Warning\", @\"Maximum log level: warning\");\n    _infoLogLevelLabel.text = NSLocalizedString(@\"Info\", @\"Maximum log level: info\");\n\n    [self addSubview:_errorLogLevelLabel];\n    [self addSubview:_warningLogLevelLabel];\n    [self addSubview:_infoLogLevelLabel];\n\n    [self updateLabels];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  CGFloat contentSize = self.bounds.size.width - kPagePadding.left - kPagePadding.right;\n\n  _logLevelSlider.frame = CGRectMake(kPagePadding.left, kPagePadding.top,\n                                     contentSize,\n                                     20);\n\n  CGFloat sliderBottom = CGRectGetMaxY(_logLevelSlider.frame);\n\n  [_errorLogLevelLabel sizeToFit];\n  _errorLogLevelLabel.frame = CGRectMake(kPagePadding.left, sliderBottom,\n                                         _errorLogLevelLabel.frame.size.width,\n                                         _errorLogLevelLabel.frame.size.height);\n\n  [_warningLogLevelLabel sizeToFit];\n  _warningLogLevelLabel.frame = CGRectMake(NICGFloatFloor((self.bounds.size.width\n                                                           - _warningLogLevelLabel.frame.size.width) / 2),\n                                           sliderBottom,\n                                           _warningLogLevelLabel.frame.size.width,\n                                           _warningLogLevelLabel.frame.size.height);\n\n  [_infoLogLevelLabel sizeToFit];\n  _infoLogLevelLabel.frame = CGRectMake(kPagePadding.left + contentSize\n                                        - _infoLogLevelLabel.frame.size.width,\n                                        sliderBottom,\n                                        _infoLogLevelLabel.frame.size.width,\n                                        _infoLogLevelLabel.frame.size.height);\n}\n\n- (void)didChangeSliderValue:(UISlider *)slider {\n  slider.value = roundf(slider.value);\n  NIMaxLogLevel = lround(slider.value);\n\n  [self updateLabels];\n}\n\n@end\n\n\n@interface NIOverviewMemoryCacheEntry : NSObject\n@property (nonatomic, retain) NSDate* timestamp;\n@property (nonatomic, assign) NSUInteger numberOfObjects;\n@end\n@implementation NIOverviewMemoryCacheEntry\n@end\n\n\n@interface NIOverviewImageMemoryCacheEntry : NIOverviewMemoryCacheEntry\n@property (nonatomic, assign) NSUInteger numberOfPixels;\n@property (nonatomic, assign) NSUInteger maxNumberOfPixels;\n@property (nonatomic, assign) NSUInteger maxNumberOfPixelsUnderStress;\n@end\n@implementation NIOverviewImageMemoryCacheEntry\n@end\n\n\n@interface NIOverviewMemoryCachePageView()\n@property (nonatomic) unsigned long long minValue;\n@property (nonatomic, strong) NSEnumerator* enumerator;\n@property (nonatomic, strong) NSMutableOrderedSet* history;\n@end\n\n\n@implementation NIOverviewMemoryCachePageView\n\n\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.pageTitle = NSLocalizedString(@\"Memory Cache\", @\"Overview Page Title: Memory Cache\");\n    self.cache = [Nimbus imageMemoryCache];\n\n    self.history = [[NSMutableOrderedSet alloc] init];\n    self.graphView.dataSource = self;\n\n    UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap:)];\n    // We still want to be able to drag the pages.\n    tap.cancelsTouchesInView = NO;\n    [self addGestureRecognizer:tap];\n  }\n  return self;\n}\n\n+ (id)pageWithCache:(NIMemoryCache *)cache {\n  NIOverviewMemoryCachePageView* pageView = [[[self class] alloc] initWithFrame:CGRectZero];\n  pageView.cache = cache;\n  return pageView;\n}\n\n- (void)update {\n  [super update];\n\n  NIOverviewMemoryCacheEntry* entry = nil;\n  // Update the labels.\n  if ([self.cache isKindOfClass:[NIImageMemoryCache class]]) {\n    NIImageMemoryCache* imageCache = (NIImageMemoryCache *)self.cache;\n    self.label1.text = [NSString stringWithFormat:@\"%@ total\",\n                        NIStringFromBytes(imageCache.numberOfPixels)];\n\n    self.label2.text = [NSString stringWithFormat:@\"%@|%@\",\n                        NIStringFromBytes(imageCache.maxNumberOfPixelsUnderStress),\n                        NIStringFromBytes(imageCache.maxNumberOfPixels)];\n\n    NIOverviewImageMemoryCacheEntry* imageEntry = [[NIOverviewImageMemoryCacheEntry alloc] init];\n    imageEntry.numberOfPixels = (NSUInteger)imageCache.numberOfPixels;\n    imageEntry.maxNumberOfPixels = (NSUInteger)imageCache.maxNumberOfPixels;\n    imageEntry.maxNumberOfPixelsUnderStress = (NSUInteger)imageCache.maxNumberOfPixelsUnderStress;\n    entry = imageEntry;\n\n  } else {\n    self.label1.text = [NSString stringWithFormat:@\"%zd objects\", self.cache.count];\n    self.label2.text = nil;\n\n    entry = [[NIOverviewMemoryCacheEntry alloc] init];\n  }\n\n  entry.timestamp = [NSDate date];\n  entry.numberOfObjects = self.cache.count;\n  [self.history addObject:entry];\n\n  NSDate* cutoffDate = [NSDate dateWithTimeIntervalSinceNow:-[NIOverview logger].oldestLogAge];\n  while ([[(NIOverviewMemoryCacheEntry *)self.history.firstObject timestamp] compare:cutoffDate] == NSOrderedAscending) {\n    [self.history removeObjectAtIndex:0];\n  }\n\n  [self setNeedsLayout];\n}\n\n- (void)didTap:(UIGestureRecognizer *)gesture {\n  UIViewController* rootController = [UIApplication sharedApplication].keyWindow.rootViewController;\n  if ([rootController respondsToSelector:@selector(pushViewController:animated:)]) {\n    // We want a weak dependency on the overview memory cache controller so that we don't force\n    // a dependency on the models feature.\n    Class class = NSClassFromString(@\"NIOverviewMemoryCacheController\");\n    if (nil != class) {\n      id instance = [class alloc];\n      SEL initSelector = @selector(initWithMemoryCache:);\n      NIDASSERT([instance respondsToSelector:initSelector]);\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n      UIViewController* controller = [instance performSelector:initSelector withObject:self.cache];\n#pragma clang diagnostic pop\n      controller.title = @\"Memory Cache\";\n      [(id)rootController pushViewController:controller animated:YES];\n    }\n  }\n}\n\n#pragma mark - NIOverviewGraphViewDataSource\n\n\n- (CGFloat)graphViewYRange:(NIOverviewGraphView *)graphView {\n  if (0 == self.history.count) {\n    return 0;\n  }\n\n  unsigned long long minY = (unsigned long long)-1;\n  unsigned long long maxY = 0;\n\n  if ([self.cache isKindOfClass:[NIImageMemoryCache class]]) {\n    // For image caches we want to show the number of pixels over time.\n    for (NIOverviewImageMemoryCacheEntry* entry in self.history) {\n      minY = MIN(entry.numberOfPixels, minY);\n      maxY = MAX(entry.numberOfPixels, maxY);\n    }\n    unsigned long long range = maxY - minY;\n    self.minValue = minY;\n    return (CGFloat)((double)range / 1024.0 / 1024.0);\n\n  } else {\n    // For regular memory caches we'll just show the count of objects.\n    for (NIOverviewMemoryCacheEntry* entry in self.history) {\n      minY = MIN(entry.numberOfObjects, minY);\n      maxY = MAX(entry.numberOfObjects, maxY);\n    }\n    unsigned long long range = maxY - minY;\n    self.minValue = minY;\n    return (CGFloat)range;\n  }\n}\n\n- (void)resetPointIterator {\n  _enumerator = [self.history objectEnumerator];\n}\n\n- (NSDate *)initialTimestamp {\n  NIOverviewMemoryCacheEntry* entry = self.history.firstObject;\n  return entry.timestamp;\n}\n\n- (BOOL)nextPointInGraphView: (NIOverviewGraphView *)graphView\n                       point: (CGPoint *)point {\n  NIOverviewMemoryCacheEntry* entry = [_enumerator nextObject];\n  if (nil != entry) {\n    NSTimeInterval interval = [entry.timestamp timeIntervalSinceDate:[self initialTimestamp]];\n\n    if ([self.cache isKindOfClass:[NIImageMemoryCache class]]) {\n      NIOverviewImageMemoryCacheEntry* imageEntry = (NIOverviewImageMemoryCacheEntry *)entry;\n      *point = CGPointMake((CGFloat)interval,\n                           (CGFloat)(((double)(imageEntry.numberOfPixels - self.minValue))\n                                     / 1024.0 / 1024.0));\n\n    } else {\n      *point = CGPointMake((CGFloat)interval,\n                           (CGFloat)(entry.numberOfObjects - self.minValue));\n    }\n  }\n  return nil != entry;\n}\n\n@end\n\ntypedef BOOL (^NIViewRecursionBlock)(UIView *view);\nstatic const CGFloat kButtonSize = 44;\nstatic const CGFloat kButtonMargin = 5;\nstatic const CGFloat kMinimumFontSize = 12;\nstatic const CGFloat kPadding = 10;\nstatic const CGFloat kAvoidedTopHeight = 80;\nstatic const NSTimeInterval kAutoresizingAnimationDuration = 2;\n\n@class NIViewInspectionView;\nstatic NIViewInspectionView *visibleInspectionView = nil;\n\n@interface NIViewInspectionView : UIView\n@end\n\n@implementation NIViewInspectionView {\n  UIView *touchedView_;\n  UIView *interactingView_;\n\n  // For displaying the autoresizing mask visually.\n  UIView *containerView_;\n  UIView *autoresizingView_;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  self = [super initWithFrame:frame];\n  if (self) {\n    // We want our touches to hit the real application views beneath this view.\n    self.userInteractionEnabled = NO;\n    self.opaque = NO;\n  }\n  return self;\n}\n\n- (void)drawRect:(CGRect)rect {\n  CGRect bounds = self.bounds;\n  CGContextRef cx = UIGraphicsGetCurrentContext();\n\n  CGContextClearRect(cx, bounds);\n\n  if (touchedView_) {\n    [[UIColor colorWithWhite:0 alpha:0.8f] set];\n    UIRectFill(bounds);\n\n    CGRect frame = [touchedView_ convertRect:touchedView_.bounds toView:self];\n    if (!CGRectEqualToRect(frame, bounds)) {\n      CGContextClearRect(cx, frame);\n    }\n    [[UIColor colorWithWhite:0 alpha:0.1f] set];\n    UIRectFrame(frame);\n\n    [[UIColor whiteColor] set];\n\n    CGPoint offset = CGPointMake(kPadding, NIStatusBarHeight() + kPadding);\n    if (CGRectGetMaxY(frame) - kAvoidedTopHeight < offset.y) {\n      offset.y += kAvoidedTopHeight;\n    }\n\n    NSString *responder = [NSString stringWithFormat:@\"%@ (%p)\",\n                           NSStringFromClass([interactingView_ class]),\n                           interactingView_];\n    offset.y += [self drawTitle:@\"Responder: \"\n                          value:responder\n                        atPoint:offset];\n    NSString *touched = [NSString stringWithFormat:@\"%@ (%p)\",\n                         NSStringFromClass([touchedView_ class]),\n                         touchedView_];\n    offset.y += [self drawTitle:@\"Touched: \"\n                          value:touched\n                        atPoint:offset];\n    offset.y += [self drawTitle:@\"Frame: \"\n                          value:NSStringFromCGRect(touchedView_.frame)\n                        atPoint:offset];\n    UILabel *label = nil;\n    if ([touchedView_ isKindOfClass:[UILabel class]]) {\n      label =  (UILabel *)touchedView_;\n    } else if ([touchedView_ isKindOfClass:[UIButton class]]) {\n      UIButton *button =  (UIButton *)touchedView_;\n      label =  (UILabel *)button.titleLabel;\n      // Display button title frame as well.\n      offset.y += [self drawTitle:@\"Title frame: \"\n                            value:NSStringFromCGRect(label.frame)\n                          atPoint:offset];\n    }\n    if (label) {\n      const CGFloat *components = CGColorGetComponents(label.textColor.CGColor);\n      offset.y += [self drawTitle:@\"Font: \"\n                            value:[NSString stringWithFormat:@\"%0.1fpx, \"\n                                   \"color: (%x,%x,%x)\",\n                                   label.font.pointSize,\n                                   (int)(components[0]*255),\n                                   (int)(components[1]*255),\n                                   (int)(components[2]*255)]\n                          atPoint:offset];\n    }\n\n  } else {\n    [[UIColor colorWithWhite:1 alpha:0.5f] set];\n    UIRectFill(bounds);\n\n    [[UIColor colorWithWhite:0.5 alpha:0.5f] set];\n    UIRectFrame(NIRectShift(CGRectInset(bounds, kPadding, kPadding),\n                            0,\n                            NIStatusBarHeight()));\n  }\n}\n\n- (CGFloat)drawTitle:(NSString *)title\n               value:(NSString *)value\n             atPoint:(CGPoint)point {\n  UIFont *infoFont = [UIFont systemFontOfSize:[UIFont systemFontSize]];\n  CGSize size = [title drawAtPoint:point withFont:infoFont];\n  point = CGPointMake(point.x + size.width, point.y);\n  CGRect bounds = self.bounds;\n  [value drawAtPoint:point\n      forWidth:bounds.size.width - point.x - kPadding\n      withFont:infoFont\n      minFontSize:kMinimumFontSize\n      actualFontSize:nil\n      lineBreakMode:NSLineBreakByTruncatingMiddle\n      baselineAdjustment:UIBaselineAdjustmentAlignBaselines];\n  return size.height;\n}\n\n- (void)setTouchedView:(UIView *)view\n       interactingView:(UIView *)interactingView {\n  interactingView_ = interactingView;\n\n  if (touchedView_ != view) {\n    touchedView_ = view;\n\n    [containerView_ removeFromSuperview];\n\n    containerView_ = [[UIView alloc] init];\n    containerView_.backgroundColor = [UIColor colorWithWhite:1 alpha:0.7f];\n    autoresizingView_ = [[UIView alloc] init];\n    autoresizingView_.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5f];\n    autoresizingView_.layer.borderColor =\n        [UIColor colorWithWhite:0 alpha:0.2f].CGColor;\n    autoresizingView_.layer.borderWidth = 1;\n    autoresizingView_.autoresizingMask = view.autoresizingMask;\n    [self addSubview:containerView_];\n    [containerView_ addSubview:autoresizingView_];\n\n    containerView_.frame =\n        CGRectMake(kPadding,\n                   self.bounds.size.height - 80 - 30 - kPadding, 100, 80);\n    autoresizingView_.frame = CGRectInset(containerView_.bounds, 20, 20);\n\n    void (^animationBlock)(void) = ^{\n      containerView_.frame = NIRectExpand(containerView_.frame, 50, 30);\n    };\n\n    [UIView animateWithDuration:kAutoresizingAnimationDuration\n                          delay:0\n                        options:(UIViewAnimationOptionRepeat\n                                 | UIViewAnimationOptionAutoreverse)\n                     animations:animationBlock\n                     completion:nil];\n  }\n\n  [self setNeedsDisplay];\n}\n\n@end\n\n@interface UIView (DebugUtilities)\n@property (nonatomic, assign) BOOL debugColorizeSubviews;\n- (void)recurseWithCallback:(NIViewRecursionBlock)callback;\n@end\n\n@implementation UIView (DebugUtilities)\n\n@dynamic debugColorizeSubviews;\n\n- (void)recurseWithCallback:(NIViewRecursionBlock)callback {\n  if (callback(self)) {\n    for (UIView *subview in self.subviews) {\n      [subview recurseWithCallback:callback];\n    }\n  }\n}\n\n@end\n\n@interface UIWindow (Interceptor)\n@end\n\n@implementation UIWindow (Interceptor)\n\n- (void)_azInterceptSendEvent:(UIEvent *)event {\n  if (event.type == UIEventTypeTouches) {\n    UITouch *touch = [[event allTouches] anyObject];\n\n    if ([touch.view isDescendantOfView:[NIOverview view]]) {\n      [self _azInterceptSendEvent:event];\n    } else {\n      UIView *interactingView = touch.view;\n      CGPoint touchPoint = [touch locationInView:self];\n      __block UIView *touchedView = [self hitTest:[touch locationInView:self]\n                                        withEvent:event];\n      [touchedView recurseWithCallback:^(UIView *view) {\n        CGPoint viewPoint = [view convertPoint:touchPoint fromView:self];\n        if ([view pointInside:viewPoint withEvent:event]) {\n          touchedView = view;\n          if ([touchedView isKindOfClass:[UIButton class]]\n              || [touchedView isKindOfClass:[UITextField class]]) {\n            // Don't select any subviews of these classes.\n            return NO;\n          }\n        }\n        return YES;\n      }];\n      [visibleInspectionView setTouchedView:touchedView\n                            interactingView:interactingView];\n    }\n  } else {\n    [self _azInterceptSendEvent:event];\n  }\n}\n\n@end\n\n@implementation NIInspectionOverviewPageView {\n  NSArray *buttons_;\n  NIViewInspectionView *inspectionView_;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    self.pageTitle = @\"Inspection\";\n\n    UIButton *colorizeButton = [UIButton buttonWithType:UIButtonTypeCustom];\n    [colorizeButton setBackgroundImage:[self backgroundForColorizeButton]\n                              forState:UIControlStateNormal];\n    colorizeButton.frame =\n        CGRectMake(0, 0, kButtonSize, kButtonSize);\n    [self addSubview:colorizeButton];\n    [colorizeButton addTarget:self\n                       action:@selector(didTapColorizeButton:)\n             forControlEvents:UIControlEventTouchUpInside];\n\n    UIButton *pinpointButton = [UIButton buttonWithType:UIButtonTypeCustom];\n    [pinpointButton setBackgroundImage:[self backgroundForPinpointButton]\n                              forState:UIControlStateNormal];\n    pinpointButton.frame =\n        CGRectMake(0, 0, kButtonSize, kButtonSize);\n    [self addSubview:pinpointButton];\n    [pinpointButton addTarget:self\n                       action:@selector(didTapPinpointButton:)\n             forControlEvents:UIControlEventTouchUpInside];\n\n    buttons_ = [NSArray arrayWithObjects:colorizeButton, pinpointButton, nil];\n  }\n  return self;\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n\n  CGFloat leftEdge = kButtonMargin;\n  for (UIButton *button in buttons_) {\n    CGRect frame = button.frame;\n    frame.origin = CGPointMake(leftEdge, kButtonMargin);\n    button.frame = frame;\n\n    leftEdge = CGRectGetMaxX(button.frame) + kButtonMargin;\n  }\n}\n\n#pragma mark - User Actions\n\n- (void)didTapColorizeButton:(UIButton *)button {\n  [[self rootView] recurseWithCallback:^(UIView *view) {\n    if ([view respondsToSelector:@selector(setDebugColorizeSubviews:)]) {\n      [(id)view setDebugColorizeSubviews:YES];\n      [view setNeedsLayout];\n    }\n    return YES;\n  }];\n}\n\n- (void)didTapPinpointButton:(UIButton *)button {\n  NISwapInstanceMethods([UIWindow class],\n                        @selector(sendEvent:),\n                        @selector(_azInterceptSendEvent:));\n\n  if (inspectionView_ != nil) {\n    [inspectionView_ removeFromSuperview];\n    inspectionView_ = nil;\n    visibleInspectionView = nil;\n    return;\n  }\n\n  UIView *rootView = [self rootView];\n  [rootView endEditing:YES];\n  inspectionView_ = [[NIViewInspectionView alloc] initWithFrame:rootView.bounds];\n  inspectionView_.autoresizingMask =\n      (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n  [rootView addSubview:inspectionView_];\n  visibleInspectionView = inspectionView_;\n}\n\n#pragma mark - Utilities\n\n- (UIView *)rootView {\n  return [UIApplication sharedApplication].keyWindow.rootViewController.view;\n}\n\n#pragma mark - Button Images\n\n- (UIColor *)randomColor {\n  return RGBCOLOR(arc4random_uniform(128) + 128,\n                  arc4random_uniform(128) + 128,\n                  arc4random_uniform(128) + 128);\n}\n\n- (UIImage *)backgroundForColorizeButton {\n  CGRect imageRect = CGRectMake(0, 0, kButtonSize, kButtonSize);\n  UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0);\n\n  CGContextRef cx = UIGraphicsGetCurrentContext();\n\n  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();\n  NSArray *gradientColors = [NSMutableArray arrayWithObjects:\n                             (id)[self randomColor].CGColor,\n                             (id)[self randomColor].CGColor,\n                             (id)[self randomColor].CGColor,\n                             (id)[self randomColor].CGColor,\n                             (id)[self randomColor].CGColor,\n                             (id)[self randomColor].CGColor,\n                             (id)[self randomColor].CGColor,\n                             (id)[self randomColor].CGColor,\n                             (id)[self randomColor].CGColor,\n                             nil];\n  CGGradientRef gradient =\n  CGGradientCreateWithColors(colorSpace,\n                             (__bridge CFArrayRef)gradientColors,\n                             nil);\n  CGColorSpaceRelease(colorSpace);\n  colorSpace = nil;\n\n  CGContextDrawRadialGradient(cx,\n                              gradient,\n                              CGPointMake(0, 0),\n                              0,\n                              CGPointMake(kButtonSize, kButtonSize),\n                              kButtonSize,\n                              0);\n  CGGradientRelease(gradient);\n  gradient = nil;\n\n  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();\n  UIGraphicsEndImageContext();\n\n  return image;\n}\n\n- (UIImage *)backgroundForPinpointButton {\n  CGRect imageRect = CGRectMake(0, 0, kButtonSize, kButtonSize);\n  UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0);\n\n  CGContextRef cx = UIGraphicsGetCurrentContext();\n\n  [[UIColor whiteColor] set];\n  CGContextStrokeEllipseInRect(cx, CGRectInset(imageRect, 10, 10));\n\n  CGFloat midX = CGRectGetMidX(imageRect);\n  CGFloat midY = CGRectGetMidY(imageRect);\n  CGContextBeginPath(cx);\n  CGContextMoveToPoint(cx, midX, midY - kButtonSize / 2);\n  CGContextAddLineToPoint(cx, midX, midY + kButtonSize / 2);\n  CGContextMoveToPoint(cx, midX - kButtonSize / 2, midY);\n  CGContextAddLineToPoint(cx, midX + kButtonSize / 2, midY);\n  CGContextStrokePath(cx);\n\n  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();\n  UIGraphicsEndImageContext();\n\n  return image;\n}\n\n@end\n\n#endif\n"
  },
  {
    "path": "src/overview/src/NIOverviewSwizzling.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n/**\n * Returns the true status bar height when the Overview is active.\n *\n * @ingroup Overview-Tools\n *\n * The Overview swizzles the methods used by NIStatusBarHeight.\n */\nCGFloat NIOverviewStatusBarHeight();\n\n/**\n * Swizzles all the necessary methods to get the Overview working.\n *\n * @ingroup Overview-Tools\n */\nvoid NIOverviewSwizzleMethods();\n"
  },
  {
    "path": "src/overview/src/NIOverviewSwizzling.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIOverviewSwizzling.h\"\n\n#import \"NimbusCore.h\"\n\n#import \"NIOverview.h\"\n#import \"NIOverviewView.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\n@interface UIApplication (Private)\n- (CGRect)_statusBarFrame;\n- (CGFloat)statusBarHeightForOrientation:(UIInterfaceOrientation)orientation;\n@end\n\n@interface UIViewController (Private)\n- (CGFloat)_statusBarHeightForCurrentInterfaceOrientation;\n- (CGFloat)_statusBarHeightAdjustmentForCurrentOrientation;\n@end\n\nCGFloat NIOverviewStatusBarHeight(void);\nvoid NIOverviewSwizzleMethods(void);\n\n\nCGFloat NIOverviewStatusBarHeight(void) {\n  CGRect statusBarFrame = [[UIApplication sharedApplication] _statusBarFrame];\n  CGFloat statusBarHeight = MIN(statusBarFrame.size.width, statusBarFrame.size.height);\n  return statusBarHeight;\n}\n\n@implementation UIViewController (NIDebugging)\n\n/**\n * Swizzled implementation of private API - (CGFloat)_statusBarHeightAdjustmentForCurrentOrientation\n *\n * This method is used by view controllers to adjust the size of their views on iOS 7 devices.\n */\n- (CGFloat)__statusBarHeightAdjustmentForCurrentOrientation {\n  return NIOverviewStatusBarHeight() + [NIOverview height];\n}\n\n/**\n * Swizzled implementation of private API - (CGFloat)_statusBarHeightForCurrentInterfaceOrientation\n *\n * This method is used by view controllers to adjust the size of their views on pre-iOS 7 devices.\n */\n- (CGFloat)__statusBarHeightForCurrentInterfaceOrientation {\n  return NIOverviewStatusBarHeight() + [NIOverview height];\n}\n\n@end\n\n\n@implementation UIApplication (NIDebugging)\n\n\n/**\n * Swizzled implementation of - (CGRect)statusBarFrame\n *\n * The real magic that causes view controllers to adjust their sizes happens in\n * __statusBarHeightForCurrentInterfaceOrientation. This method is swizzled purely\n * for application-level code that depends on statusBarFrame for calculations.\n */\n- (CGRect)_statusBarFrame {\n  return CGRectMake(0, 0,\n                    CGFLOAT_MAX, NIOverviewStatusBarHeight() + [NIOverview height]);\n}\n\n/**\n * Swizzled implementation of - (CGFloat)statusBarHeightForOrientation:\n *\n * This allows us to make the status bar larger for view controllers that aren't in\n * navigation controllers.\n */\n- (CGFloat)_statusBarHeightForOrientation:(int)arg1 {\n  return NIOverviewStatusBarHeight() + [NIOverview height];\n}\n\n/**\n * Swizzled implementation of - (void)setStatusBarHidden:withAnimation:\n *\n * This allows us to hide the overview when the status bar is hidden.\n */\n- (void)_setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation {\n  [self _setStatusBarHidden:hidden withAnimation:animation];\n\n  if (UIStatusBarAnimationNone == animation) {\n    [NIOverview view].alpha = 1;\n    [NIOverview view].hidden = hidden;\n\n  } else if (UIStatusBarAnimationSlide == animation) {\n    [NIOverview view].alpha = 1;\n\n    CGRect frame = [NIOverview frame];\n\n    [UIView beginAnimations:nil context:nil];\n    [UIView setAnimationDuration:NIStatusBarAnimationDuration()];\n    [UIView setAnimationCurve:NIStatusBarAnimationCurve()];\n\n    [NIOverview view].frame = frame;\n\n    [UIView commitAnimations];\n    \n  } else if (UIStatusBarAnimationFade == animation) {\n    CGRect frame = [NIOverview frame];\n    [NIOverview view].frame = frame;\n\n    [UIView beginAnimations:nil context:nil];\n    [UIView setAnimationDuration:NIStatusBarAnimationDuration()];\n    [UIView setAnimationCurve:NIStatusBarAnimationCurve()];\n    \n    [NIOverview view].alpha = hidden ? 0 : 1;\n    \n    [UIView commitAnimations];\n  }\n}\n\n/**\n * Swizzled implementation of - (void)setStatusBarStyle:animated:\n */\n- (void)_setStatusBarStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated {\n  [self _setStatusBarStyle:statusBarStyle animated:animated];\n\n  if (animated) {\n    [UIView beginAnimations:nil context:nil];\n    [UIView setAnimationDuration:0.3];\n  }\n\n  // TODO (jverkoey July 23, 2011): Add a translucent property to the overview view.\n  if (UIStatusBarStyleDefault == statusBarStyle\n      || UIStatusBarStyleBlackOpaque == statusBarStyle) {\n    [[NIOverview view] setTranslucent:NO];\n\n  } else if (UIStatusBarStyleBlackTranslucent == statusBarStyle) {\n    [[NIOverview view] setTranslucent:YES];\n  }\n\n  if (animated) {\n    [UIView commitAnimations];\n  }\n}\n\n@end\n\n\nvoid NIOverviewSwizzleMethods(void) {\n  NISwapInstanceMethods([UIViewController class],\n                        @selector(_statusBarHeightForCurrentInterfaceOrientation),\n                        @selector(__statusBarHeightForCurrentInterfaceOrientation));\n  NISwapInstanceMethods([UIViewController class],\n                        @selector(_statusBarHeightAdjustmentForCurrentOrientation),\n                        @selector(__statusBarHeightAdjustmentForCurrentOrientation));\n  NISwapInstanceMethods([UIApplication class],\n                        @selector(statusBarFrame),\n                        @selector(_statusBarFrame));\n  NISwapInstanceMethods([UIApplication class],\n                        @selector(statusBarHeightForOrientation:),\n                        @selector(_statusBarHeightForOrientation:));\n  NISwapInstanceMethods([UIApplication class],\n                        @selector(setStatusBarHidden:withAnimation:),\n                        @selector(_setStatusBarHidden:withAnimation:));\n  NISwapInstanceMethods([UIApplication class],\n                        @selector(setStatusBarStyle:animated:),\n                        @selector(_setStatusBarStyle:animated:));\n}\n\n#endif\n"
  },
  {
    "path": "src/overview/src/NIOverviewView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\n@class NIOverviewPageView;\n\n/**\n * The root scrolling page view of the Overview.\n *\n * @ingroup Overview\n */\n@interface NIOverviewView : UIView\n\n/**\n * Whether the view has a translucent background or not.\n */\n@property (nonatomic, assign) BOOL translucent;\n\n/**\n * Whether the view can be draggable vertically or not.\n */\n@property (nonatomic, assign) BOOL enableDraggingVertically;\n\n/**\n * Prepends a new page to the Overview.\n */\n- (void)prependPageView:(NIOverviewPageView *)page;\n\n/**\n * Adds a new page to the Overview.\n */\n- (void)addPageView:(NIOverviewPageView *)page;\n\n/**\n * Removes a page from the Overview.\n */\n- (void)removePageView:(NIOverviewPageView *)page;\n\n/**\n * Update all of the views.\n */\n- (void)updatePages;\n\n- (void)flashScrollIndicators;\n\n@end\n\n#endif\n"
  },
  {
    "path": "src/overview/src/NIOverviewView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIOverviewView.h\"\n\n#if defined(DEBUG) || defined(NI_DEBUG)\n\n#import \"NimbusCore.h\"\n\n#import \"NIOverviewLogger.h\"\n#import \"NIDeviceInfo.h\"\n#import \"NIOverviewPageView.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic const NSUInteger kNumberOfFingersForPanGestureRecognizer = 1;\n\n@interface NIOverviewView()\n\n- (CGFloat)pageHorizontalMargin;\n- (CGRect)frameForPagingScrollView;\n\n@end\n\n@implementation NIOverviewView {\n  UIImage*  _backgroundImage;\n\n  // State\n  BOOL            _translucent;\n  NSMutableArray* _pageViews;\n\n  // Views\n  UIScrollView* _pagingScrollView;\n\n  // Gesture recognizer\n  CGRect _initialFrame;\n  UIPanGestureRecognizer *_panGestureRecognizer;\n}\n\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    _pageViews = [[NSMutableArray alloc] init];\n\n    _backgroundImage = [UIImage imageWithContentsOfFile:\n                        NIPathForBundleResource(nil, @\"NimbusOverviewer.bundle/gfx/blueprint.gif\")];\n    self.backgroundColor = NIIsTintColorGloballySupported() ? self.tintColor : [UIColor colorWithPatternImage:_backgroundImage];\n\n    _pagingScrollView = [[UIScrollView alloc] initWithFrame:[self frameForPagingScrollView]];\n    _pagingScrollView.pagingEnabled = YES;\n    _pagingScrollView.scrollIndicatorInsets = UIEdgeInsetsMake(0, self.pageHorizontalMargin,\n                                                               0, self.pageHorizontalMargin);\n\n    _pagingScrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth\n                                          | UIViewAutoresizingFlexibleHeight);\n\n    [self addSubview:_pagingScrollView];\n    \n    self.autoresizingMask = UIViewAutoresizingFlexibleWidth;\n    \n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(updatePages)\n                                                 name:NIOverviewLoggerDidAddDeviceLog\n                                               object:nil];\n    _panGestureRecognizer =\n        [[UIPanGestureRecognizer alloc] initWithTarget:self\n                                                action:@selector(didPanMapWithGestureRecognizer:)];\n    _panGestureRecognizer.maximumNumberOfTouches = kNumberOfFingersForPanGestureRecognizer;\n    _panGestureRecognizer.minimumNumberOfTouches = kNumberOfFingersForPanGestureRecognizer;\n    [self addGestureRecognizer:_panGestureRecognizer];\n  }\n  return self;\n}\n\n- (void)dealloc {\n  [[NSNotificationCenter defaultCenter] removeObserver:self\n                                                  name:NIOverviewLoggerDidAddDeviceLog\n                                                object:nil];\n}\n\n#pragma mark - Page Layout\n\n\n- (CGFloat)pageHorizontalMargin {\n  return 10;\n}\n\n- (CGRect)frameForPagingScrollView {\n  CGRect frame = self.bounds;\n\n  // We make the paging scroll view a little bit wider on the side edges so that there\n  // there is space between the pages when flipping through them.\n  frame.origin.x -= self.pageHorizontalMargin;\n  frame.size.width += (2 * self.pageHorizontalMargin);\n\n  return frame;\n}\n\n- (CGSize)contentSizeForPagingScrollView {\n  CGRect bounds = _pagingScrollView.bounds;\n  return CGSizeMake(bounds.size.width * [_pageViews count], bounds.size.height);\n}\n\n- (CGRect)frameForPageAtIndex:(NSInteger)pageIndex {\n  // We have to use our paging scroll view's bounds, not frame, to calculate the page\n  // placement. When the device is in landscape orientation, the frame will still be in\n  // portrait because the pagingScrollView is the root view controller's view, so its\n  // frame is in window coordinate space, which is never rotated. Its bounds, however,\n  // will be in landscape because it has a rotation transform applied.\n  CGRect bounds = _pagingScrollView.bounds;\n  CGRect pageFrame = bounds;\n\n  // We need to counter the extra spacing added to the paging scroll view in\n  // frameForPagingScrollView:\n  pageFrame.size.width -= self.pageHorizontalMargin * 2;\n  pageFrame.origin.x = (bounds.size.width * pageIndex) + self.pageHorizontalMargin;\n\n  return pageFrame;\n}\n\n- (void)layoutPages {\n  _pagingScrollView.contentSize = [self contentSizeForPagingScrollView];\n\n  for (NSUInteger ix = 0; ix < [_pageViews count]; ++ix) {\n    UIView* pageView = [_pageViews objectAtIndex:ix];\n    pageView.frame = [self frameForPageAtIndex:ix];\n  }\n}\n\n- (NSInteger)visiblePageIndex {\n  CGFloat offset = _pagingScrollView.contentOffset.x;\n  CGFloat pageWidth = _pagingScrollView.bounds.size.width;\n\n  return (NSInteger)(offset / pageWidth);\n}\n\n- (void)setBounds:(CGRect)bounds {\n  NSInteger visiblePageIndex = [self visiblePageIndex];\n\n  [super setBounds:bounds];\n\n  [self layoutPages];\n\n  CGFloat pageWidth = _pagingScrollView.bounds.size.width;\n  CGFloat newOffset = (visiblePageIndex * pageWidth);\n  _pagingScrollView.contentOffset = CGPointMake(newOffset, 0);\n}\n\n- (void)setFrame:(CGRect)frame {\n  NSInteger visiblePageIndex = [self visiblePageIndex];\n  \n  [super setFrame:frame];\n  \n  [self layoutPages];\n  \n  CGFloat pageWidth = _pagingScrollView.bounds.size.width;\n  CGFloat newOffset = (visiblePageIndex * pageWidth);\n  _pagingScrollView.contentOffset = CGPointMake(newOffset, 0);\n}\n\n#pragma mark - Public\n\n\n- (void)setTranslucent:(BOOL)translucent {\n  if (_translucent != translucent) {\n    _translucent = translucent;\n\n    _pagingScrollView.indicatorStyle = (_translucent\n                                        ? UIScrollViewIndicatorStyleWhite\n                                        : UIScrollViewIndicatorStyleDefault);\n\n    self.backgroundColor = (_translucent\n                            ? [UIColor colorWithWhite:0 alpha:0.5f]\n                            : ((NIIsTintColorGloballySupported() && self.tintColor)\n                               ? self.tintColor\n                               : [UIColor colorWithPatternImage:_backgroundImage]));\n  }\n}\n\n- (void)prependPageView:(NIOverviewPageView *)page {\n  [_pageViews insertObject:page atIndex:0];\n  [_pagingScrollView addSubview:page];\n\n  [self layoutPages];\n}\n\n- (void)addPageView:(NIOverviewPageView *)page {\n  [_pageViews addObject:page];\n  [_pagingScrollView addSubview:page];\n\n  [self layoutPages];\n}\n\n- (void)removePageView:(NIOverviewPageView *)page {\n  [_pageViews removeObject:page];\n  [page removeFromSuperview];\n\n  [self layoutPages];\n}\n\n- (void)updatePages {\n  for (NIOverviewPageView* pageView in _pageViews) {\n    [pageView update];\n  }\n}\n\n- (void)flashScrollIndicators {\n  [_pagingScrollView flashScrollIndicators];\n}\n\n#pragma mark - Gesture Recognizer\n\n\n\n- (void)didPanMapWithGestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer {\n  if (!_enableDraggingVertically || _panGestureRecognizer != gestureRecognizer) {\n    return;\n  }\n\n  if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {\n    _initialFrame = self.frame;\n  } else if (gestureRecognizer.state == UIGestureRecognizerStateChanged) {\n    CGPoint translation = [gestureRecognizer translationInView:self.superview];\n    UIInterfaceOrientation orientation = NIInterfaceOrientation();\n    CGRect rect = self.frame;\n    CGRect superRect = self.superview.frame;\n    if (UIInterfaceOrientationIsPortrait(orientation)) {\n      CGFloat y = _initialFrame.origin.y + translation.y;\n      rect.origin.y = MIN(MAX(y, 0), superRect.size.height - _initialFrame.size.height);\n    } else if (UIInterfaceOrientationIsLandscape(orientation)) {\n      CGFloat x = _initialFrame.origin.x + translation.x;\n      rect.origin.x = MIN(MAX(x, 0), superRect.size.width - _initialFrame.size.width);\n    }\n    self.frame = rect;\n  }\n}\n\n@end\n\n#endif\n"
  },
  {
    "path": "src/overview/src/NimbusOverview.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n/**\n * @defgroup NimbusOverview Nimbus Overview\n * @{\n *\n * <div id=\"github\" feature=\"overview\"></div>\n *\n * The Overview is a debugging tool for quickly understanding the current state of your\n * application. When added to an application, it will insert a paged\n * scroll view beneath the status bar that contains any number of pages of information.\n * These pages can show anything from graphs of current memory usage to console logs to\n * configuration settings.\n *\n * @image html overview1.png \"The Overview added to the network photo album app.\"\n *\n *\n * <h2>Built-in Overview Pages</h2>\n *\n * The Overview comes with a few basic pages for viewing the device state and console logs.\n *\n *\n * <h3>NIOverviewMemoryPageView</h3>\n *\n * @image html overview-memory1.png \"The memory page.\"\n *\n * This page shows a graph of the relative available memory on the device.\n *\n *\n * <h3>NIOverviewDiskPageView</h3>\n *\n * @image html overview-disk1.png \"The disk page.\"\n *\n * This page shows a graph of the relative available disk space on the device.\n *\n *\n * <h3>NIOverviewConsoleLogPageView</h3>\n *\n * @image html overview-log1.png \"The log page.\"\n *\n * This page shows all messages sent to NSLog since the Overview was initialized.\n *\n *\n * <h3>NIOverviewMaxLogLevelPageView</h3>\n *\n * @image html overview-maxloglevel1.png \"The max log level page.\"\n *\n * This page allows you to modify NIMaxLogLevel while the app is running.\n *\n *\n * <h2>How to Use the Overview</h2>\n *\n * To begin using the Overview you need to add two lines of code to your app and define\n * DEBUG in your applicaton's preprocessor macros Debug target settings.\n *\n * @code\n - (BOOL)              application:(UIApplication *)application\n *    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n *  // Line #1 - Swizzles the necessary methods for making the Overview appear as part of the\n *  // the status bar.\n *  [NIOverview applicationDidFinishLaunching];\n *\n *  // After you create the UIWindow for your application and add the root view controller,\n *  // i.e.:\n *  [self.window addSubview:_rootViewController.view];\n *\n *  // then you add the Overview view to the window.\n *  [NIOverview addOverviewToWindow:self.window];\n * @endcode\n *\n *\n * <h2>Events</h2>\n *\n * Certain events are useful in providing context while debugging an application. When a\n * memory warning is received it can be helpful to see how much memory was released. for example.\n *\n * The Overview visually presents events on Overview graphs as vertical lines. Memory warnings\n * are red.\n *\n * In the screenshot below, you can see when a memory warning occurred and the resulting\n * increase in available memory.\n *\n * @image html overview-memorywarning1.png \"A memory warning received on the iPad is shown with a vertical red line.\"\n *\n * <h2>How the Overview is Displayed</h2>\n *\n * The Overview is displayed by tricking the application into thinking that the status bar is\n * 60 pixels larger than it actually is. If your app respects the status bar frame correctly\n * then the Overview will always be visible above the chrome of your application, directly\n * underneath the status bar. If the status bar is hidden, the Overview will also be hidden.\n *\n *\n * <h2>Creating a Custom Page</h2>\n *\n * You can build your own page by subclassing NIOverviewPageView and adding it to the\n * overview via [[NIOverview @link NIOverview::view view@endlink] @link NIOverviewView::addPageView: addPageView:@endlink].\n */\n\n/**\n * The sensors used to power the Overview.\n *\n * @defgroup Overview-Sensors Sensors\n */\n\n/**\n * The primary classes you'll use when dealing with the Overview.\n *\n * @defgroup Overview Overview\n */\n\n/**\n * The Overview logger.\n *\n * @defgroup Overview-Logger Logger\n */\n\n/**\n * The pages that are shown in the Overview.\n *\n * @defgroup Overview-Pages Pages\n */\n\n/**@}*/\n\n/**\n * Log entries for the Overview logger.\n *\n * @defgroup Overview-Logger-Entries Log Entries\n * @ingroup Overview-Logger\n */\n\n#import \"NimbusCore.h\"\n#import \"NIOverview.h\"\n"
  },
  {
    "path": "src/overview/unittests/NIOverviewTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusOverview.h\"\n\n@interface NIOverviewTests : XCTestCase\n@end\n\n\n@implementation NIOverviewTests\n\n\n- (void)testNothing {\n}\n\n@end\n"
  },
  {
    "path": "src/overview/unittests/NimbusOverviewTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/pagingscrollview/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\n"
  },
  {
    "path": "src/pagingscrollview/src/NIPagingScrollView+Subclassing.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPagingScrollView.h\"\n\n// Methods that are meant to be subclassed.\n@interface NIPagingScrollView (Subclassing)\n\n// Meant to be subclassed. Default implementations are stubs.\n- (void)willDisplayPage:(UIView<NIPagingScrollViewPage> *)pageView;\n- (void)didRecyclePage:(UIView<NIPagingScrollViewPage> *)pageView;\n- (void)didReloadNumberOfPages;\n- (void)didChangeCenterPageIndexFrom:(NSInteger)from to:(NSInteger)to;\n\n// Meant to be subclassed.\n- (UIView<NIPagingScrollViewPage> *)loadPageAtIndex:(NSInteger)pageIndex;\n\n#pragma mark Accessing Child Views\n\n- (UIScrollView *)scrollView;\n- (NSMutableSet *)visiblePages; // Set of UIView<NIPagingScrollViewPage>*\n\n@end\n\n// Methods that are not meant to be subclassed.\n@interface NIPagingScrollView (ProtectedMethods)\n\n- (void)setCenterPageIndexIvar:(NSInteger)centerPageIndex;\n- (void)recyclePageAtIndex:(NSInteger)pageIndex;\n- (void)displayPageAtIndex:(NSInteger)pageIndex;\n- (CGFloat)pageScrollableDimension;\n- (void)layoutVisiblePages;\n\n@end\n\n/**\n * Called before the page is about to be shown and after its frame has been set.\n *\n * Meant to be subclassed. By default this method does nothing.\n *\n * @fn NIPagingScrollView::willDisplayPage:\n */\n\n/**\n * Called immediately after the page is removed from the paging scroll view.\n *\n * Meant to be subclassed. By default this method does nothing.\n *\n * @fn NIPagingScrollView::didRecyclePage:\n */\n\n/**\n * Called immediately after the data source has been queried for its number of\n * pages.\n *\n * Meant to be subclassed. By default this method does nothing.\n *\n * @fn NIPagingScrollView::didReloadNumberOfPages\n */\n\n/**\n * Called when the visible page has changed.\n *\n * Meant to be subclassed. By default this method does nothing.\n *\n * @fn NIPagingScrollView::didChangeCenterPageIndexFrom:to:\n */\n\n/**\n * Called when a page needs to be loaded before it is displayed.\n *\n * By default this method asks the data source for the page at the given index.\n * A subclass may chose to modify the page index using a transformation method\n * before calling super.\n *\n * @fn NIPagingScrollView::loadPageAtIndex:\n */\n\n/**\n * Sets the centerPageIndex ivar without side effects.\n *\n * @fn NIPagingScrollView::setCenterPageIndexIvar:\n */\n\n/**\n * Recycles the page at the given index.\n *\n * @fn NIPagingScrollView::recyclePageAtIndex:\n */\n\n/**\n * Displays the page at the given index.\n *\n * @fn NIPagingScrollView::displayPageAtIndex:\n */\n\n/**\n * Returns the page's scrollable dimension.\n *\n * This is the width of the paging scroll view for horizontal scroll views, or\n * the height of the paging scroll view for vertical scroll views.\n *\n * @fn NIPagingScrollView::pageScrollableDimension\n */\n\n/**\n * Updates the frames of all visible pages based on their page indices.\n *\n * @fn NIPagingScrollView::layoutVisiblePages\n */\n"
  },
  {
    "path": "src/pagingscrollview/src/NIPagingScrollView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Copyright 2012 Manu Cornet (vertical layouts)\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NimbusCore.h\"\n\n/**\n * numberOfPages will be this value until reloadData is called.\n */\nextern const NSInteger NIPagingScrollViewUnknownNumberOfPages;\n\n/**\n * The default number of pixels on the side of each page.\n *\n * Value: 10\n */\nextern const CGFloat NIPagingScrollViewDefaultPageMargin;\n\ntypedef enum {\n  NIPagingScrollViewHorizontal = 0,\n  NIPagingScrollViewVertical,\n} NIPagingScrollViewType;\n\n@protocol NIPagingScrollViewDataSource;\n@protocol NIPagingScrollViewDelegate;\n@protocol NIPagingScrollViewPage;\n@class NIViewRecycler;\n\n/**\n * The NIPagingScrollView class provides a UITableView-like interface for loading pages via a data\n * source.\n *\n * @ingroup NimbusPagingScrollView\n */\n@interface NIPagingScrollView : UIView <UIScrollViewDelegate>\n\n#pragma mark Data Source\n\n- (void)reloadData;\n@property (nonatomic, weak) id<NIPagingScrollViewDataSource> dataSource;\n@property (nonatomic, weak) id<NIPagingScrollViewDelegate> delegate;\n\n// It is highly recommended that you use this method to manage view recycling.\n- (UIView<NIPagingScrollViewPage> *)dequeueReusablePageWithIdentifier:(NSString *)identifier;\n\n#pragma mark State\n\n- (UIView<NIPagingScrollViewPage> *)centerPageView;\n@property (nonatomic) NSInteger centerPageIndex; // Use moveToPageAtIndex:animated: to animate to a given page.\n\n@property (nonatomic, readonly) NSInteger numberOfPages;\n\n#pragma mark Configuring Presentation\n\n// Controls the border between pages.\n@property (nonatomic) CGFloat pageMargin;\n// Used to make the view smaller than the frame of the paging scroll view, thus showing\n// neighboring pages, either horizontally or vertically depending on the configuration\n// of the view.\n@property (nonatomic) CGFloat pageInset;\n@property (nonatomic) NIPagingScrollViewType type; // Default: NIPagingScrollViewHorizontal\n// Controls layout for RTL.\n// For iOS versions 9 and higher the initial value is determined based on the semanticContentAttribute property.\n// For previous iOS versions please set this to true for RTL languages to display correctly.\n// RTL is achieved by concatenating UIView transforms.\n// Warning: if you require the transform to not be touched or want to handle RTL yourself, please\n// set this to NO.\n@property (nonatomic) BOOL RTLEnabled\n    NS_DEPRECATED_IOS(2_0, 9_0, \"Use the semanticContentAttribute property instead.\");\n\n#pragma mark Visible Pages\n\n- (BOOL)hasNext;\n- (BOOL)hasPrevious;\n- (void)moveToNextAnimated:(BOOL)animated;\n- (void)moveToPreviousAnimated:(BOOL)animated;\n- (BOOL)moveToPageAtIndex:(NSInteger)pageIndex animated:(BOOL)animated updateVisiblePagesWhileScrolling:(BOOL)updateVisiblePagesWhileScrolling;\n\n// Short form for moveToPageAtIndex:pageIndex animated:animated updateVisiblePagesWhileScrolling:NO\n- (BOOL)moveToPageAtIndex:(NSInteger)pageIndex animated:(BOOL)animated;\n\n#pragma mark Rotating the Scroll View\n\n- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;\n\n@end\n\n/**\n * The delegate for NIPagingScrollView.\n *\n * @ingroup NimbusPagingScrollView\n */\n@protocol NIPagingScrollViewDelegate <UIScrollViewDelegate>\n@optional\n\n#pragma mark Scrolling and Zooming /** @name [NIPhotoAlbumScrollViewDelegate] Scrolling and Zooming */\n\n/**\n * The user is scrolling between two photos.\n */\n- (void)pagingScrollViewDidScroll:(NIPagingScrollView *)pagingScrollView;\n\n#pragma mark Changing Pages /** @name [NIPagingScrollViewDelegate] Changing Pages */\n\n/**\n * The current page will change.\n *\n * pagingScrollView.centerPageIndex will reflect the old page index, not the new\n * page index.\n */\n- (void)pagingScrollViewWillChangePages:(NIPagingScrollView *)pagingScrollView;\n\n/**\n * The current page has changed.\n *\n * pagingScrollView.centerPageIndex will reflect the changed page index.\n */\n- (void)pagingScrollViewDidChangePages:(NIPagingScrollView *)pagingScrollView;\n\n@end\n\n/**\n * The data source for NIPagingScrollView.\n *\n * @ingroup NimbusPagingScrollView\n */\n@protocol NIPagingScrollViewDataSource <NSObject>\n@required\n\n#pragma mark Fetching Required Album Information /** @name [NIPagingScrollViewDataSource] Fetching Required Album Information */\n\n/**\n * Fetches the total number of pages in the scroll view.\n *\n * The value returned in this method will be cached by the scroll view until reloadData\n * is called again.\n */\n- (NSInteger)numberOfPagesInPagingScrollView:(NIPagingScrollView *)pagingScrollView;\n\n/**\n * Fetches a page that will be displayed at the given page index.\n *\n * You should always try to reuse pages by calling dequeueReusablePageWithIdentifier: on the\n * paging scroll view before allocating a new page.\n */\n- (UIView<NIPagingScrollViewPage> *)pagingScrollView:(NIPagingScrollView *)pagingScrollView pageViewForIndex:(NSInteger)pageIndex;\n\n@end\n\n/**\n * The protocol that a paging scroll view page should implement.\n *\n * By providing a protocol instead of a UIView base class we allow more flexibility when\n * building pages.\n *\n * @ingroup NimbusPagingScrollView\n */\n@protocol NIPagingScrollViewPage <NIRecyclableView>\n@required\n\n/**\n * The index of this page view.\n */\n@property (nonatomic, assign) NSInteger pageIndex;\n\n@optional\n\n/**\n * Called after the page has gone off-screen.\n *\n * This method should be used to reset any state information after a page goes off-screen.\n * For example, in the Nimbus photo viewer we reset the zoom scale so that if the photo\n * was zoomed in it will fit on the screen again when the user flips back and forth between\n * two pages.\n */\n- (void)pageDidDisappear;\n\n/**\n * Called when the frame of the page is going to change.\n *\n * Use this method to maintain any state that may be affected by the frame changing.\n * The Nimbus photo viewer uses this method to save and restore the zoom and center\n * point. This makes the photo always appear to rotate around the center point of the screen\n * rather than the center of the photo.\n */\n- (void)setFrameAndMaintainState:(CGRect)frame;\n\n@end\n\n/** @name Data Source */\n\n/**\n * The data source for this page album view.\n *\n * This is the only means by which this paging view acquires any information about the\n * album to be displayed.\n *\n * @fn NIPagingScrollView::dataSource\n */\n\n/**\n * Force the view to reload its data by asking the data source for information.\n *\n * This must be called at least once after dataSource has been set in order for the view\n * to gather any presentable information.\n *\n * This method is cheap because we only fetch new information about the currently displayed\n * pages. If the number of pages shrinks then the current center page index will be decreased\n * accordingly.\n *\n * @fn NIPagingScrollView::reloadData\n */\n\n/**\n * Dequeues a reusable page from the set of recycled pages.\n *\n * If no pages have been recycled for the given identifier then this will return nil.\n * In this case it is your responsibility to create a new page.\n *\n * @fn NIPagingScrollView::dequeueReusablePageWithIdentifier:\n */\n\n/**\n * The delegate for this paging view.\n *\n * Any user interactions or state changes are sent to the delegate through this property.\n *\n * @fn NIPagingScrollView::delegate\n */\n\n/** @name Configuring Presentation */\n\n/**\n * The number of pixels on either side of each page.\n *\n * The space between each page will be 2x this value.\n *\n * By default this is NIPagingScrollViewDefaultPageMargin.\n *\n * @fn NIPagingScrollView::pageMargin\n */\n\n/**\n * The type of paging scroll view to display.\n *\n * This property allows you to configure whether you want a horizontal or vertical paging scroll\n * view. You should set this property before you present the scroll view and not modify it after.\n *\n * By default this is NIPagingScrollViewHorizontal.\n *\n * @fn NIPagingScrollView::type\n */\n\n/** @name State */\n\n/**\n * The current center page view.\n *\n * If no pages exist then this will return nil.\n *\n * @fn NIPagingScrollView::centerPageView\n */\n\n/**\n * The current center page index.\n *\n * This is a zero-based value. If you intend to use this in a label such as \"page ## of n\" be\n * sure to add one to this value.\n *\n * Setting this value directly will center the new page without any animation.\n *\n * @fn NIPagingScrollView::centerPageIndex\n */\n\n/**\n * Change the center page index with optional animation.\n *\n * This method is deprecated in favor of\n * @link NIPagingScrollView::moveToPageAtIndex:animated: moveToPageAtIndex:animated:@endlink\n *\n * @fn NIPagingScrollView::setCenterPageIndex:animated:\n */\n\n/**\n * The total number of pages in this paging view, as gathered from the data source.\n *\n * This value is cached after reloadData has been called.\n *\n * Until reloadData is called the first time, numberOfPages will be\n * NIPagingScrollViewUnknownNumberOfPages.\n *\n * @fn NIPagingScrollView::numberOfPages\n */\n\n/** @name Changing the Visible Page */\n\n/**\n * Returns YES if there is a next page.\n *\n * @fn NIPagingScrollView::hasNext\n */\n\n/**\n * Returns YES if there is a previous page.\n *\n * @fn NIPagingScrollView::hasPrevious\n */\n\n/**\n * Move to the next page if there is one.\n *\n * @fn NIPagingScrollView::moveToNextAnimated:\n */\n\n/**\n * Move to the previous page if there is one.\n *\n * @fn NIPagingScrollView::moveToPreviousAnimated:\n */\n\n/**\n * Move to the given page index with optional animation.\n *\n * @returns NO if a page change animation is already in effect and we couldn't change the page\n *               again.\n * @fn NIPagingScrollView::moveToPageAtIndex:animated:\n */\n\n/**\n * Move to the given page index with optional animation and option to enable page updates while\n * scrolling.\n *\n * NOTE: Passing YES for moveToPageAtIndex:animated:updateVisiblePagesWhileScrolling will cause\n * every page from the present page to the destination page to be loaded. This has the potential to\n * cause choppy animations.\n *\n * @param updateVisiblePagesWhileScrolling If YES, will query the data source for any pages\n *                                              that become visible while the animation occurs.\n * @returns NO if a page change animation is already in effect and we couldn't change the page\n *               again.\n * @fn NIPagingScrollView::moveToPageAtIndex:animated:updateVisiblePagesWhileScrolling:\n */\n\n/** @name Rotating the Scroll View */\n\n/**\n * Stores the current state of the scroll view in preparation for rotation.\n *\n * This must be called in conjunction with willAnimateRotationToInterfaceOrientation:duration:\n * in the methods by the same name from the view controller containing this view.\n *\n * @fn NIPagingScrollView::willRotateToInterfaceOrientation:duration:\n */\n\n/**\n * Updates the frame of the scroll view while maintaining the current visible page's state.\n *\n * @fn NIPagingScrollView::willAnimateRotationToInterfaceOrientation:duration:\n */\n\n/** @name Subclassing */\n\n/**\n * The internal scroll view.\n *\n * Meant to be used by subclasses only.\n *\n * @fn NIPagingScrollView::pagingScrollView\n */\n\n/**\n * The set of currently visible pages.\n *\n * Meant to be used by subclasses only.\n *\n * @fn NIPagingScrollView::visiblePages\n */\n"
  },
  {
    "path": "src/pagingscrollview/src/NIPagingScrollView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Copyright 2012 Manu Cornet (vertical layouts)\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPagingScrollView.h\"\n#import \"NIPagingScrollView+Subclassing.h\"\n\n#import \"NimbusCore.h\"\n\n#import <objc/runtime.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nconst NSInteger NIPagingScrollViewUnknownNumberOfPages = -1;\nconst CGFloat NIPagingScrollViewDefaultPageMargin = 10;\nconst CGFloat NIPagingScrollViewDefaultPageInset = 0;\n\n@implementation NIPagingScrollView {\n  NIViewRecycler* _viewRecycler;\n  UIScrollView* _scrollView;\n\n  NSMutableSet* _visiblePages;\n\n  // Animating to Pages\n  NSInteger _animatingToPageIndex;\n  BOOL _isKillingAnimation;\n  NSInteger _queuedAnimationPageIndex;\n  BOOL _shouldUpdateVisiblePagesWhileScrolling;\n\n  // Rotation State\n  NSInteger _firstVisiblePageIndexBeforeRotation;\n  CGFloat _percentScrolledIntoFirstVisiblePage;\n}\n\n- (void)commonInit {\n  // Default state.\n  self.pageMargin = NIPagingScrollViewDefaultPageMargin;\n  self.pageInset = NIPagingScrollViewDefaultPageInset;\n  self.type = NIPagingScrollViewHorizontal;\n\n  // Internal state\n  _animatingToPageIndex = -1;\n  _firstVisiblePageIndexBeforeRotation = -1;\n  _percentScrolledIntoFirstVisiblePage = -1;\n  _centerPageIndex = -1;\n  _numberOfPages = NIPagingScrollViewUnknownNumberOfPages;\n\n  _viewRecycler = [[NIViewRecycler alloc] init];\n\n  // The internal scroll view that powers this paging scroll view.\n  _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];\n  _scrollView.pagingEnabled = YES;\n  _scrollView.scrollsToTop = NO;\n\n  // Allows the scroll view to show adjacent pages...\n  _scrollView.clipsToBounds = NO;\n  // ...while still clipping contents to the bounds of the paging scroll view.\n  self.clipsToBounds = YES;\n\n  _scrollView.autoresizingMask =\n      (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n\n  _scrollView.delegate = self;\n\n  _scrollView.showsVerticalScrollIndicator = NO;\n  _scrollView.showsHorizontalScrollIndicator = NO;\n\n  if ([[UIView class]\n          respondsToSelector:@selector(userInterfaceLayoutDirectionForSemanticContentAttribute:)] && [self respondsToSelector:@selector(semanticContentAttribute)] && [UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft) {\n    [self setRTLEnabled:YES];\n  }\n\n  [self addSubview:_scrollView];\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    [self commonInit];\n  }\n  return self;\n}\n\n- (id)initWithCoder:(NSCoder *)aDecoder {\n  if ((self = [super initWithCoder:aDecoder])) {\n    [self commonInit];\n  }\n  return self;\n}\n\n#pragma mark - Page Layout\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n  _scrollView.frame = [self frameForPagingScrollView];\n\n  // Retain the current position.\n  CGPoint offset = [self frameForPageAtIndex:_centerPageIndex].origin;\n  _scrollView.contentOffset = [self contentOffsetFromPageOffset:offset];\n\n  _scrollView.contentSize = [self contentSizeForPagingScrollView];\n  [self layoutVisiblePages];\n}\n\n// The following three methods are from Apple's ImageScrollView example application and have\n// been used here because they are well-documented and concise.\n\n- (CGRect)frameForPagingScrollView {\n  CGRect frame = self.bounds;\n\n  if (NIPagingScrollViewHorizontal == self.type) {\n    // We make the paging scroll view a little bit wider on the side edges so that there\n    // there is space between the pages when flipping through them.\n    frame = CGRectInset(frame, self.pageInset - self.pageMargin, 0);\n\n  } else if (NIPagingScrollViewVertical == self.type) {\n    frame = CGRectInset(frame, 0, self.pageInset - self.pageMargin);\n  }\n\n  return frame;\n}\n\n- (CGRect)frameForPageAtIndex:(NSInteger)pageIndex {\n  // We have to use our paging scroll view's bounds, not frame, to calculate the page\n  // placement. When the device is in landscape orientation, the frame will still be in\n  // portrait because the pagingScrollView is the root view controller's view, so its\n  // frame is in window coordinate space, which is never rotated. Its bounds, however,\n  // will be in landscape because it has a rotation transform applied.\n  CGRect bounds = _scrollView.bounds;\n  CGRect pageFrame = bounds;\n\n  if (NIPagingScrollViewHorizontal == self.type) {\n    pageFrame.origin.x = (bounds.size.width * pageIndex);\n    // We need to counter the extra spacing added to the paging scroll view in\n    // frameForPagingScrollView.\n    pageFrame = CGRectInset(pageFrame, self.pageMargin, 0);\n\n  } else if (NIPagingScrollViewVertical == self.type) {\n    pageFrame.origin.y = (bounds.size.height * pageIndex);\n    pageFrame = CGRectInset(pageFrame, 0, self.pageMargin);\n  }\n\n  return pageFrame;\n}\n\n- (CGSize)contentSizeForPagingScrollView {\n  // We use the paging scroll view's bounds to calculate the contentSize, for the same reason\n  // outlined above.\n  CGRect bounds = _scrollView.bounds;\n  if (NIPagingScrollViewHorizontal == self.type) {\n    return CGSizeMake(bounds.size.width * self.numberOfPages, bounds.size.height);\n\n  } else if (NIPagingScrollViewVertical == self.type) {\n    return CGSizeMake(bounds.size.width, bounds.size.height * self.numberOfPages);\n  }\n\n  return CGSizeZero;\n}\n\n- (CGPoint)contentOffsetFromPageOffset:(CGPoint)offset {\n  if (NIPagingScrollViewHorizontal == self.type) {\n    offset.x -= self.pageMargin;\n\n  } else if (NIPagingScrollViewVertical == self.type) {\n    offset.y -= self.pageMargin;\n  }\n\n  return offset;\n}\n\n- (CGFloat)pageScrollableDimension {\n  if (NIPagingScrollViewHorizontal == self.type) {\n    return _scrollView.bounds.size.width;\n\n  } else if (NIPagingScrollViewVertical == self.type) {\n    return _scrollView.bounds.size.height;\n  }\n\n  return 0;\n}\n\n- (CGPoint)contentOffsetFromOffset:(CGFloat)offset {\n  if (NIPagingScrollViewHorizontal == self.type) {\n    return CGPointMake(offset, 0);\n\n  } else if (NIPagingScrollViewVertical == self.type) {\n    return CGPointMake(0, offset);\n  }\n\n  return CGPointMake(0, 0);\n}\n\n- (CGFloat)scrolledPageOffset {\n  if (NIPagingScrollViewHorizontal == self.type) {\n    return _scrollView.contentOffset.x;\n\n  } else if (NIPagingScrollViewVertical == self.type) {\n    return _scrollView.contentOffset.y;\n  }\n\n  return 0;\n}\n\n#pragma mark - Visible Page Management\n\n- (BOOL)isDisplayingPageForIndex:(NSInteger)pageIndex {\n  BOOL foundPage = NO;\n\n  // There will never be more than a handful (3 without insets) of visible pages in this array, so this lookup is\n  // effectively O(C) constant time.\n  for (UIView <NIPagingScrollViewPage>* page in _visiblePages) {\n    if (page.pageIndex == pageIndex) {\n      foundPage = YES;\n      break;\n    }\n  }\n\n  return foundPage;\n}\n\n- (NSInteger)currentVisiblePageIndex {\n  CGPoint contentOffset = _scrollView.contentOffset;\n  CGSize boundsSize = _scrollView.bounds.size;\n\n  if (NIPagingScrollViewHorizontal == self.type) {\n    // Whatever image is currently displayed in the center of the screen is the currently\n    // visible image.\n    return NIBoundi((NSInteger)(NICGFloatFloor((contentOffset.x + boundsSize.width / 2) / boundsSize.width)\n                              + 0.5f),\n                  0, self.numberOfPages - 1);\n\n  } else if (NIPagingScrollViewVertical == self.type) {\n    return NIBoundi((NSInteger)(NICGFloatFloor((contentOffset.y + boundsSize.height / 2) / boundsSize.height)\n                              + 0.5f),\n                  0, self.numberOfPages - 1);\n  }\n\n  return 0;\n}\n\n- (NSRange)rangeOfVisiblePages {\n  if (0 >= self.numberOfPages) {\n    return NSMakeRange(0, 0);\n  }\n\n  NSInteger visibleRange = 1;\n  if (_pageInset != 0) {\n    CGSize boundsSize = _scrollView.bounds.size;\n    CGSize frameSize = self.frame.size;\n    visibleRange = (NSInteger)ceil(frameSize.width / (boundsSize.width + _pageMargin));\n  }\n\n  NSInteger currentVisiblePageIndex = [self currentVisiblePageIndex];\n\n  NSInteger firstVisiblePageIndex = NIBoundi(currentVisiblePageIndex - visibleRange, 0, self.numberOfPages - 1);\n  NSInteger lastVisiblePageIndex  = NIBoundi(currentVisiblePageIndex + visibleRange, 0, self.numberOfPages - 1);\n\n  return NSMakeRange(firstVisiblePageIndex, lastVisiblePageIndex - firstVisiblePageIndex + 1);\n}\n\n- (void)willDisplayPage:(UIView<NIPagingScrollViewPage> *)pageView atIndex:(NSInteger)pageIndex {\n  pageView.pageIndex = pageIndex;\n  pageView.frame = [self frameForPageAtIndex:pageIndex];\n\n  [self willDisplayPage:pageView];\n}\n\n- (void)resetPage:(id<NIPagingScrollViewPage>)page {\n  if ([page respondsToSelector:@selector(pageDidDisappear)]) {\n    [page pageDidDisappear];\n  }\n}\n\n- (void)resetSurroundingPages {\n  for (id<NIPagingScrollViewPage> page in _visiblePages) {\n    if (page.pageIndex != self.centerPageIndex) {\n      [self resetPage:page];\n    }\n  }\n}\n\n- (UIView<NIPagingScrollViewPage> *)dequeueReusablePageWithIdentifier:(NSString *)identifier {\n  NIDASSERT(nil != identifier);\n  if (nil == identifier) {\n    return nil;\n  }\n\n  return (UIView<NIPagingScrollViewPage> *)[_viewRecycler dequeueReusableViewWithIdentifier:identifier];\n}\n\n- (UIView<NIPagingScrollViewPage> *)loadPageAtIndex:(NSInteger)pageIndex {\n  id<NIPagingScrollViewDataSource> dataSource = self.dataSource;\n  if (dataSource == nil) {\n    // If there's no data source, just return a nil page.\n    return nil;\n  }\n\n  UIView<NIPagingScrollViewPage> *page = [dataSource pagingScrollView:self pageViewForIndex:pageIndex];\n\n  NIDASSERT([page isKindOfClass:[UIView class]]);\n  NIDASSERT([page conformsToProtocol:@protocol(NIPagingScrollViewPage)]);\n\n  if (nil == page || ![page isKindOfClass:[UIView class]]\n      || ![page conformsToProtocol:@protocol(NIPagingScrollViewPage)]) {\n    // Bail out! This page is malformed.\n    return nil;\n  }\n\n  return page;\n}\n\n- (void)displayPageAtIndex:(NSInteger)pageIndex {\n  UIView<NIPagingScrollViewPage>* page = [self loadPageAtIndex:pageIndex];\n  if (nil == page) {\n    return;\n  }\n\n  // This will only be called once, before the page is shown.\n  [self willDisplayPage:page atIndex:pageIndex];\n\n  if (_RTLEnabled) {\n    [self concatInvertXTransformation:page];\n  }\n\n  [_scrollView addSubview:page];\n  [_visiblePages addObject:page];\n}\n\n- (void)recyclePageAtIndex:(NSInteger)pageIndex {\n  for (UIView<NIPagingScrollViewPage>* page in [_visiblePages copy]) {\n    if (page.pageIndex == pageIndex) {\n      [self recyclePage:page];\n    }\n  }\n}\n\n- (void)preloadOffscreenPages {\n  NSRange rangeOfVisiblePages = [self rangeOfVisiblePages];\n  for (NSUInteger pageIndex = rangeOfVisiblePages.location;\n       pageIndex < NSMaxRange(rangeOfVisiblePages); ++pageIndex) {\n    if (![self isDisplayingPageForIndex:pageIndex]) {\n      [self displayPageAtIndex:pageIndex];\n    }\n  }\n}\n\n- (void)updateVisiblePagesShouldNotifyDelegate:(BOOL)shouldNotifyDelegate {\n  // Before updating _centerPageIndex, notify delegate\n  if (shouldNotifyDelegate && (self.numberOfPages > 0) &&\n      ([self currentVisiblePageIndex] != self.centerPageIndex) &&\n      [self.delegate respondsToSelector:@selector(pagingScrollViewWillChangePages:)]) {\n    [self.delegate pagingScrollViewWillChangePages:self];\n  }\n\n  NSRange rangeOfVisiblePages = [self rangeOfVisiblePages];\n  // Recycle no-longer-visible pages. We copy _visiblePages because we may modify it while we're\n  // iterating over it.\n  for (UIView<NIPagingScrollViewPage>* page in [_visiblePages copy]) {\n    if (!NSLocationInRange(page.pageIndex, rangeOfVisiblePages)) {\n      [self recyclePage:page];\n    }\n  }\n\n  NSInteger oldCenterPageIndex = self.centerPageIndex;\n\n  if (self.numberOfPages > 0) {\n    _centerPageIndex = [self currentVisiblePageIndex];\n\n    [self didChangeCenterPageIndexFrom:oldCenterPageIndex to:_centerPageIndex];\n\n    if (_pageInset != 0) {\n      // Load all visible insetted pages immediately.\n      [self preloadOffscreenPages];\n    } else {\n      // Prioritize displaying the currently visible page.\n      if (![self isDisplayingPageForIndex:_centerPageIndex]) {\n        [self displayPageAtIndex:_centerPageIndex];\n      }\n\n      // Add missing pages after displaying the current page.\n      [self performSelector:@selector(preloadOffscreenPages)\n                 withObject:nil\n                 afterDelay:0];\n    }\n  } else {\n    _centerPageIndex = -1;\n  }\n\n  if (shouldNotifyDelegate && oldCenterPageIndex != _centerPageIndex\n      && [self.delegate respondsToSelector:@selector(pagingScrollViewDidChangePages:)]) {\n    [self.delegate pagingScrollViewDidChangePages:self];\n  }\n}\n\n- (void)layoutVisiblePages {\n  for (UIView<NIPagingScrollViewPage>* page in _visiblePages) {\n    CGRect pageFrame = [self frameForPageAtIndex:page.pageIndex];\n    if ([page respondsToSelector:@selector(setFrameAndMaintainState:)]) {\n      [page setFrameAndMaintainState:pageFrame];\n\n    } else {\n      [page setFrame:pageFrame];\n    }\n  }\n}\n\n- (void)recyclePage:(UIView<NIPagingScrollViewPage> *)page {\n  [_viewRecycler recycleView:page];\n  [page removeFromSuperview];\n\n  [self didRecyclePage:page];\n\n  [_visiblePages removeObject:page];\n\n  if (_RTLEnabled) {\n    [self concatInvertXTransformation:page];\n  }\n}\n\n- (void)concatInvertXTransformation:(UIView *)view {\n  CGAffineTransform currentTransform = view.transform;\n  CGAffineTransform finalTransform = CGAffineTransformConcat(currentTransform,\n                                                             CGAffineTransformMakeScale(-1, 1));\n  [view setTransform:finalTransform];\n}\n\n#pragma mark - UIView\n\n- (void)setFrame:(CGRect)frame {\n  // We have to modify this method because it eventually leads to changing the content offset\n  // programmatically. When this happens we end up getting a scrollViewDidScroll: message\n  // during which we do not want to modify the visible pages because this is handled elsewhere.\n  [super setFrame:frame];\n\n  _scrollView.contentSize = [self contentSizeForPagingScrollView];\n  [self layoutVisiblePages];\n}\n\n- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {\n  UIView *view = [super hitTest:point withEvent:event];\n  // We must forward hits for the scrollView or else the smaller frame when\n  // it is inset will prevent touches outside the scrollView bounds.\n  if (view == self) {\n    return _scrollView;\n  }\n  return view;\n}\n\n#pragma mark - UIScrollViewDelegate\n\n- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {\n  [self updateVisiblePagesShouldNotifyDelegate:YES];\n  _isKillingAnimation = NO;\n\n  if ([self.delegate respondsToSelector:_cmd]) {\n    [self.delegate scrollViewWillBeginDragging:scrollView];\n  }\n}\n\n- (void)scrollViewDidScroll:(UIScrollView *)scrollView {\n  if ([scrollView isTracking] && [scrollView isDragging]) {\n    if ([self.delegate respondsToSelector:@selector(pagingScrollViewDidScroll:)]) {\n      [self.delegate pagingScrollViewDidScroll:self];\n    }\n  }\n  if (_shouldUpdateVisiblePagesWhileScrolling\n      && ![scrollView isTracking] && ![scrollView isDragging]) {\n    [self updateVisiblePagesShouldNotifyDelegate:YES];\n  }\n\n  if ([self.delegate respondsToSelector:_cmd]) {\n    [self.delegate scrollViewDidScroll:scrollView];\n  }\n\n  if (_isKillingAnimation) {\n    // The content size is calculated based on the number of pages and the scroll view frame.\n    CGPoint offset = [self frameForPageAtIndex:_centerPageIndex].origin;\n    offset = [self contentOffsetFromPageOffset:offset];\n    _scrollView.contentOffset = offset;\n  }\n}\n\n- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {\n  _isKillingAnimation = NO;\n\n  if (!decelerate) {\n    [self updateVisiblePagesShouldNotifyDelegate:YES];\n    [self resetSurroundingPages];\n  }\n\n  if ([self.delegate respondsToSelector:_cmd]) {\n    [self.delegate scrollViewDidEndDragging:scrollView willDecelerate:decelerate];\n  }\n}\n\n- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {\n  [self updateVisiblePagesShouldNotifyDelegate:YES];\n  [self resetSurroundingPages];\n\n  if ([self.delegate respondsToSelector:_cmd]) {\n    [self.delegate scrollViewDidEndDecelerating:scrollView];\n  }\n}\n\n- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {\n  if (_animatingToPageIndex >= 0) {\n    [self didAnimateToPage:_animatingToPageIndex];\n\n    if ([self.delegate respondsToSelector:_cmd]) {\n      [self.delegate scrollViewDidEndScrollingAnimation:scrollView];\n    }\n  }\n}\n\n#pragma mark - Forward UIScrollViewDelegate Methods\n\n\n- (BOOL)shouldForwardSelectorToDelegate:(SEL)aSelector {\n  struct objc_method_description description;\n  // Only forward the selector if it's part of the UIScrollViewDelegate protocol.\n  description = protocol_getMethodDescription(@protocol(UIScrollViewDelegate),\n                                              aSelector,\n                                              NO,\n                                              YES);\n\n  BOOL isSelectorInScrollViewDelegate = (description.name != NULL && description.types != NULL);\n  return (isSelectorInScrollViewDelegate\n          && [self.delegate respondsToSelector:aSelector]);\n}\n\n- (BOOL)respondsToSelector:(SEL)aSelector {\n  if ([super respondsToSelector:aSelector] == YES) {\n    return YES;\n\n  } else {\n    return [self shouldForwardSelectorToDelegate:aSelector];\n  }\n}\n\n- (id)forwardingTargetForSelector:(SEL)aSelector {\n  if ([self shouldForwardSelectorToDelegate:aSelector]) {\n    return self.delegate;\n\n  } else {\n    return nil;\n  }\n}\n\n#pragma mark - Subclassing\n\n\n- (void)willDisplayPage:(UIView<NIPagingScrollViewPage> *)pageView {\n  // No-op.\n}\n\n- (void)didRecyclePage:(UIView<NIPagingScrollViewPage> *)pageView {\n  // No-op\n}\n\n- (void)didReloadNumberOfPages {\n  // No-op\n}\n\n- (void)didChangeCenterPageIndexFrom:(NSInteger)from to:(NSInteger)to {\n  // No-op\n}\n\n- (void)setCenterPageIndexIvar:(NSInteger)centerPageIndex {\n  _centerPageIndex = centerPageIndex;\n}\n\n#pragma mark - Public\n\n\n- (void)reloadData {\n  _animatingToPageIndex = -1;\n  NIDASSERT(nil != _dataSource);\n\n  // Remove any visible pages from the view before we release the sets.\n  for (UIView<NIPagingScrollViewPage>* page in _visiblePages) {\n    [_viewRecycler recycleView:page];\n    [(UIView *)page removeFromSuperview];\n\n    [self didRecyclePage:page];\n  }\n\n  _visiblePages = nil;\n\n  // If there is no data source then we can't do anything particularly interesting.\n  if (nil == _dataSource) {\n    _scrollView.contentSize = self.bounds.size;\n    _scrollView.contentOffset = CGPointZero;\n\n    // May as well just get rid of all the views then.\n    [_viewRecycler removeAllViews];\n\n    return;\n  }\n\n  _visiblePages = [[NSMutableSet alloc] init];\n\n  // Cache the number of pages.\n  _numberOfPages = [_dataSource numberOfPagesInPagingScrollView:self];\n  _scrollView.frame = [self frameForPagingScrollView];\n  _scrollView.contentSize = [self contentSizeForPagingScrollView];\n\n  [self didReloadNumberOfPages];\n\n  NSInteger oldCenterPageIndex = _centerPageIndex;\n  if (oldCenterPageIndex >= 0) {\n    _centerPageIndex = NIBoundi(_centerPageIndex, 0, self.numberOfPages - 1);\n\n    if (![_scrollView isTracking] && ![_scrollView isDragging]) {\n      // The content size is calculated based on the number of pages and the scroll view frame.\n      CGPoint offset = [self frameForPageAtIndex:_centerPageIndex].origin;\n      offset = [self contentOffsetFromPageOffset:offset];\n      _scrollView.contentOffset = offset;\n\n      _isKillingAnimation = YES;\n    }\n  }\n\n  // Begin requesting the page information from the data source.\n  [self updateVisiblePagesShouldNotifyDelegate:NO];\n}\n\n- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation\n                                duration: (NSTimeInterval)duration {\n  // Here, our pagingScrollView bounds have not yet been updated for the new interface\n  // orientation. This is a good place to calculate the content offset that we will\n  // need in the new orientation.\n  CGFloat offset = [self scrolledPageOffset];\n  CGFloat pageScrollableDimension = [self pageScrollableDimension];\n\n  if (pageScrollableDimension == 0) {\n    _firstVisiblePageIndexBeforeRotation = 0;\n    _percentScrolledIntoFirstVisiblePage = 0.f;\n    return;\n  }\n\n  if (offset >= 0) {\n    _firstVisiblePageIndexBeforeRotation = (NSInteger)NICGFloatFloor(offset / pageScrollableDimension);\n    _percentScrolledIntoFirstVisiblePage = ((offset\n        - (_firstVisiblePageIndexBeforeRotation * pageScrollableDimension))\n        / pageScrollableDimension);\n\n  } else {\n    _firstVisiblePageIndexBeforeRotation = 0;\n    _percentScrolledIntoFirstVisiblePage = offset / pageScrollableDimension;\n  }\n}\n\n- (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation\n                                         duration: (NSTimeInterval)duration {\n  // Recalculate contentSize based on current orientation.\n  _scrollView.contentSize = [self contentSizeForPagingScrollView];\n\n  [self layoutVisiblePages];\n\n  // Adjust contentOffset to preserve page location based on values collected prior to location.\n  CGFloat pageScrollableDimension = [self pageScrollableDimension];\n  CGFloat newOffset = ((_firstVisiblePageIndexBeforeRotation * pageScrollableDimension)\n                       + (_percentScrolledIntoFirstVisiblePage * pageScrollableDimension));\n  _scrollView.contentOffset = [self contentOffsetFromOffset:newOffset];\n}\n\n- (BOOL)hasNext {\n  return (self.centerPageIndex < self.numberOfPages - 1);\n}\n\n- (BOOL)hasPrevious {\n  return self.centerPageIndex > 0;\n}\n\n- (void)didAnimateToPage:(NSInteger)pageIndex {\n  _shouldUpdateVisiblePagesWhileScrolling = NO;\n  _animatingToPageIndex = -1;\n  if (_queuedAnimationPageIndex >= 0 && _queuedAnimationPageIndex != pageIndex) {\n    [self moveToPageAtIndex:_queuedAnimationPageIndex animated:YES];\n    return;\n  }\n\n  // Reset the content offset once the animation completes, just to be sure that the\n  // viewer sits on a page bounds even if we rotate the device while animating.\n  CGPoint offset = [self frameForPageAtIndex:pageIndex].origin;\n  offset = [self contentOffsetFromPageOffset:offset];\n\n  _scrollView.contentOffset = offset;\n\n  [self updateVisiblePagesShouldNotifyDelegate:YES];\n}\n\n- (BOOL)moveToPageAtIndex:(NSInteger)pageIndex animated:(BOOL)animated {\n  return [self moveToPageAtIndex:pageIndex animated:animated updateVisiblePagesWhileScrolling:NO];\n}\n\n- (BOOL)moveToPageAtIndex:(NSInteger)pageIndex animated:(BOOL)animated updateVisiblePagesWhileScrolling:(BOOL)updateVisiblePagesWhileScrolling {\n  if (_animatingToPageIndex >= 0) {\n    // Don't allow re-entry for sliding animations.\n    _queuedAnimationPageIndex = pageIndex;\n    return NO;\n  }\n  _shouldUpdateVisiblePagesWhileScrolling = updateVisiblePagesWhileScrolling;\n  _isKillingAnimation = NO;\n  _queuedAnimationPageIndex = -1;\n\n  CGPoint offset = [self frameForPageAtIndex:pageIndex].origin;\n  offset = [self contentOffsetFromPageOffset:offset];\n\n  // The paging scroll view won't actually animate if the offsets are identical.\n  animated = animated && !CGPointEqualToPoint(offset, _scrollView.contentOffset);\n\n  if (animated) {\n    _animatingToPageIndex = pageIndex;\n  }\n  [_scrollView setContentOffset:offset animated:animated];\n  if (!animated) {\n    [self resetSurroundingPages];\n    [self didAnimateToPage:pageIndex];\n  }\n  return YES;\n}\n\n- (void)moveToNextAnimated:(BOOL)animated {\n  if ([self hasNext]) {\n    NSInteger pageIndex = self.centerPageIndex + 1;\n\n    [self moveToPageAtIndex:pageIndex animated:animated];\n  }\n}\n\n- (void)moveToPreviousAnimated:(BOOL)animated {\n  if ([self hasPrevious]) {\n    NSInteger pageIndex = self.centerPageIndex - 1;\n\n    [self moveToPageAtIndex:pageIndex animated:animated];\n  }\n}\n\n- (UIView<NIPagingScrollViewPage> *)centerPageView {\n  for (UIView<NIPagingScrollViewPage>* page in _visiblePages) {\n    if (page.pageIndex == self.centerPageIndex) {\n      return page;\n    }\n  }\n  return nil;\n}\n\n- (void)setCenterPageIndex:(NSInteger)centerPageIndex {\n  [self moveToPageAtIndex:centerPageIndex animated:NO];\n}\n\n- (void)setPageMargin:(CGFloat)pageMargin {\n  _pageMargin = pageMargin;\n  [self setNeedsLayout];\n}\n\n- (void)setPageInset:(CGFloat)pageInset {\n  _pageInset = pageInset;\n  [self setNeedsLayout];\n}\n\n- (void)setType:(NIPagingScrollViewType)type {\n  if (_type != type) {\n    _type = type;\n    _scrollView.scrollsToTop = (type == NIPagingScrollViewVertical);\n  }\n}\n\n- (void)setRTLEnabled:(BOOL)RTLEnabled {\n  // Apply the transformation only if the state is changing.\n  if (!_RTLEnabled != !RTLEnabled) {\n    [self concatInvertXTransformation:_scrollView];\n  }\n  _RTLEnabled = RTLEnabled;\n}\n\n- (UIScrollView *)scrollView {\n  return _scrollView;\n}\n\n- (NSMutableSet *)visiblePages {\n  return _visiblePages;\n}\n\n@end\n"
  },
  {
    "path": "src/pagingscrollview/src/NIPagingScrollViewPage.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n#import \"NIPagingScrollView.h\"\n\n/**\n * A skeleton implementation of a page view.\n *\n * This view simply implements the required properties of NIPagingScrollViewPage.\n *\n * @ingroup NimbusPagingScrollView\n */\n@interface NIPagingScrollViewPage : NIRecyclableView <NIPagingScrollViewPage>\n@property (nonatomic) NSInteger pageIndex;\n@end\n\n/**\n * The page index.\n *\n * @fn NIPagingScrollViewPage::pageIndex\n */\n"
  },
  {
    "path": "src/pagingscrollview/src/NIPagingScrollViewPage.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPagingScrollViewPage.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NIPagingScrollViewPage\n@end\n"
  },
  {
    "path": "src/pagingscrollview/src/NimbusPagingScrollView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n/**\n * @defgroup NimbusPagingScrollView Nimbus Paging Scroll View\n * @{\n *\n * <div id=\"github\" feature=\"pagingscrollview\"></div>\n *\n * A paging scroll view is a UIScrollView that scrolls horizontally and shows a series of\n * pages that are efficiently recycled.\n *\n * The Nimbus paging scroll view is powered by a datasource that allows you to separate the\n * data from the view. This makes it easy to efficiently recycle pages and only create as many\n * pages of content as may be visible at any given point in time. Nimbus' implementation also\n * provides helpful features such as keeping the center page centered when the device changes\n * orientation.\n *\n * Paging scroll views are commonly used in many iOS applications. For example, Nimbus' Photos\n * feature uses a paging scroll view to power its NIPhotoAlbumScrollView.\n *\n * <h2>Building a Component with NIPagingScrollView</h2>\n *\n * NIPagingScrollView works much like a UITableView in that you must implement a data source\n * and optionally a delegate. The data source fetches information about the contents of the\n * paging scroll view, such as the total number of pages and the view for a given page when it\n * is required. The views that you return for pages must conform to the NIPagingScrollViewPage\n * protocol. This is similar to UITableViewCell, but rather than subclass a view you can simply\n * implement a protocol. If you would prefer not to implement the protocol, you can subclass\n * NIPageView which implements the required methods of NIPagingScrollViewPage.\n */\n\n/**@}*/\n\n#import \"NIPagingScrollView.h\"\n#import \"NIPagingScrollViewPage.h\"\n\n#import \"NimbusCore.h\"\n"
  },
  {
    "path": "src/pagingscrollview/unittests/NIPagingScrollViewTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusPagingScrollView.h\"\n\n@interface NIPagingScrollViewTests : XCTestCase\n@end\n\n@implementation NIPagingScrollViewTests\n\n/** Test that rotating with a zero frame does not throw exceptions. */\n- (void)testRotationWithZeroFrame {\n  NIPagingScrollView *pagingScrollView = [[NIPagingScrollView alloc] initWithFrame:CGRectZero];\n  UIInterfaceOrientation targetInterfaceOrientation = UIInterfaceOrientationPortrait;\n  XCTAssertNoThrow([pagingScrollView willRotateToInterfaceOrientation:targetInterfaceOrientation\n                                                             duration:0.25]);\n  XCTAssertNoThrow([pagingScrollView willAnimateRotationToInterfaceOrientation:targetInterfaceOrientation\n                                                                      duration:0.25]);\n\n}\n\n@end\n"
  },
  {
    "path": "src/pagingscrollview/unittests/NimbusPagingScrollViewTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/photos/deps",
    "content": "core\npagingscrollview\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\n"
  },
  {
    "path": "src/photos/src/NIPhotoAlbumScrollView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPhotoScrollViewDelegate.h\"\n#import \"NIPhotoAlbumScrollViewDataSource.h\"\n#import \"NIPhotoAlbumScrollViewDelegate.h\"\n\n#import \"NimbusPagingScrollView.h\"\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n/**\n * A paged scroll view that shows a collection of photos.\n *\n * @ingroup NimbusPhotos\n *\n * This view provides a light-weight implementation of a photo viewer, complete with\n * pinch-to-zoom and swiping to change photos. It is designed to perform well with\n * large sets of photos and large images that are loaded from either the network or\n * disk.\n *\n * It is intended for this view to be used in conjunction with a view controller that\n * implements the data source protocol and presents any required chrome.\n *\n * @see NIToolbarPhotoViewController\n */\n@interface NIPhotoAlbumScrollView : NIPagingScrollView <NIPhotoScrollViewDelegate>\n\n#pragma mark Data Source\n\n// For use in your pagingScrollView:pageForIndex: data source implementation.\n- (UIView<NIPagingScrollViewPage> *)pagingScrollView:(NIPagingScrollView *)pagingScrollView pageViewForIndex:(NSInteger)pageIndex;\n\n@property (nonatomic, weak) id<NIPhotoAlbumScrollViewDataSource> dataSource;\n@property (nonatomic, weak) id<NIPhotoAlbumScrollViewDelegate> delegate;\n\n#pragma mark Configuring Functionality\n\n@property (nonatomic, assign, getter=isZoomingEnabled) BOOL zoomingIsEnabled;\n@property (nonatomic, assign, getter=isZoomingAboveOriginalSizeEnabled) BOOL zoomingAboveOriginalSizeIsEnabled;\n@property (nonatomic, strong) UIColor* photoViewBackgroundColor;\n\n#pragma mark Configuring Presentation\n\n@property (nonatomic, strong) UIImage* loadingImage;\n\n#pragma mark Notifying the View of Loaded Photos\n\n- (void)didLoadPhoto: (UIImage *)image\n             atIndex: (NSInteger)photoIndex\n           photoSize: (NIPhotoScrollViewPhotoSize)photoSize;\n\n@end\n\n\n/** @name Data Source */\n\n/**\n * The data source for this photo album view.\n *\n * This is the only means by which this photo album view acquires any information about the\n * album to be displayed.\n *\n * @fn NIPhotoAlbumScrollView::dataSource\n */\n\n/**\n * Use this method in your implementation of NIPhotoAlbumScrollViewDataSource's\n * pagingScrollView:pageForIndex:.\n *\n * Example:\n *\n@code\n- (id<NIPagingScrollViewPage>)pagingScrollView:(NIPagingScrollView *)pagingScrollView pageForIndex:(NSInteger)pageIndex {\n  return [self.photoAlbumView pagingScrollView:pagingScrollView pageForIndex:pageIndex];\n}\n@endcode\n *\n * Automatically uses the paging scroll view's page recycling methods and creates\n * NIPhotoScrollViews as needed.\n *\n * @fn NIPhotoAlbumScrollView::pagingScrollView:pageForIndex:\n */\n\n/**\n * The delegate for this photo album view.\n *\n * Any user interactions or state changes are sent to the delegate through this property.\n *\n * @fn NIPhotoAlbumScrollView::delegate\n */\n\n\n/** @name Configuring Functionality */\n\n/**\n * Whether zooming is enabled or not.\n *\n * Regardless of whether this is enabled, only original-sized images will be zoomable.\n * This is because we often don't know how large the final image is so we can't\n * calculate min and max zoom amounts correctly.\n *\n * By default this is YES.\n *\n * @fn NIPhotoAlbumScrollView::zoomingIsEnabled\n */\n\n/**\n * Whether small photos can be zoomed at least until they fit the screen.\n *\n * @see NIPhotoScrollView::zoomingAboveOriginalSizeIsEnabled\n *\n * By default this is YES.\n *\n * @fn NIPhotoAlbumScrollView::zoomingAboveOriginalSizeIsEnabled\n */\n\n/**\n * The background color of each photo's view.\n *\n * By default this is [UIColor blackColor].\n *\n * @fn NIPhotoAlbumScrollView::photoViewBackgroundColor\n */\n\n\n/** @name Configuring Presentation */\n\n/**\n * An image that is displayed while the photo is loading.\n *\n * This photo will be presented if no image is returned in the data source's implementation\n * of photoAlbumScrollView:photoAtIndex:photoSize:isLoading:.\n *\n * Zooming is disabled when showing a loading image, regardless of the state of zoomingIsEnabled.\n *\n * By default this is nil.\n *\n * @fn NIPhotoAlbumScrollView::loadingImage\n */\n\n\n/** @name Notifying the View of Loaded Photos */\n\n/**\n * Notify the scroll view that a photo has been loaded at a given index.\n *\n * You should notify the completed loading of thumbnails as well. Calling this method\n * is fairly lightweight and will only update the images of the visible pages. Err on the\n * side of calling this method too much rather than too little.\n *\n * The photo at the given index will only be replaced with the given image if photoSize\n * is of a higher quality than the currently-displayed photo's size.\n *\n * @fn NIPhotoAlbumScrollView::didLoadPhoto:atIndex:photoSize:\n */\n"
  },
  {
    "path": "src/photos/src/NIPhotoAlbumScrollView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPhotoAlbumScrollView.h\"\n\n#import \"NIPagingScrollView+Subclassing.h\"\n#import \"NIPhotoScrollView.h\"\n#import \"NIPhotoAlbumScrollViewDataSource.h\"\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NIPhotoAlbumScrollView {\n  // Configurable Properties\n  UIImage* _loadingImage;\n  BOOL _zoomingIsEnabled;\n  BOOL _zoomingAboveOriginalSizeIsEnabled;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    // Default state.\n    self.zoomingIsEnabled = YES;\n    self.zoomingAboveOriginalSizeIsEnabled = YES;\n  }\n  return self;\n}\n\n- (void)setBackgroundColor:(UIColor *)backgroundColor {\n  [super setBackgroundColor:backgroundColor];\n\n  self.scrollView.backgroundColor = backgroundColor;\n}\n\n- (void)notifyDelegatePhotoDidLoadAtIndex:(NSInteger)photoIndex {\n  if (photoIndex == (self.centerPageIndex + 1)\n      && [self.delegate respondsToSelector:@selector(photoAlbumScrollViewDidLoadNextPhoto:)]) {\n    [self.delegate photoAlbumScrollViewDidLoadNextPhoto:self];\n\n  } else if (photoIndex == (self.centerPageIndex - 1)\n             && [self.delegate respondsToSelector:@selector(photoAlbumScrollViewDidLoadPreviousPhoto:)]) {\n    [self.delegate photoAlbumScrollViewDidLoadPreviousPhoto:self];\n  }\n}\n\n#pragma mark - Visible Page Management\n\n\n- (void)willDisplayPage:(NIPhotoScrollView *)page {\n  // When we ask the data source for the image we expect the following to happen:\n  // 1) If the data source has any image at this index, it should return it and set the\n  //    photoSize accordingly.\n  // 2) If the returned photo is not the highest quality available, the data source should\n  //    start loading the high quality photo and set isLoading to YES.\n  // 3) If no photo was available, then the data source should start loading the photo\n  //    at its highest available quality and nil should be returned. The loadingImage property\n  //    will be displayed until the image is loaded. isLoading should be set to YES.\n  NIPhotoScrollViewPhotoSize photoSize = NIPhotoScrollViewPhotoSizeUnknown;\n  BOOL isLoading = NO;\n  CGSize originalPhotoDimensions = CGSizeZero;\n  UIImage* image = [self.dataSource photoAlbumScrollView: self\n                                            photoAtIndex: page.pageIndex\n                                               photoSize: &photoSize\n                                               isLoading: &isLoading\n                                 originalPhotoDimensions: &originalPhotoDimensions];\n\n  page.photoDimensions = originalPhotoDimensions;\n  // Only mark the view as loading if the center image is loading.\n  page.loading = (page.pageIndex == self.centerPageIndex) && isLoading;\n\n  if (nil == image) {\n    page.zoomingIsEnabled = NO;\n    [page setImage:self.loadingImage photoSize:NIPhotoScrollViewPhotoSizeUnknown];\n\n  } else {\n    BOOL updateImage = photoSize > page.photoSize;\n    if (updateImage) {\n      [page setImage:image photoSize:photoSize];\n    }\n\n    // Configure this after the image is set otherwise if the page's image isn't there\n\t// e.g. (after prepareForReuse), zooming will always be disabled\n    page.zoomingIsEnabled = ([self isZoomingEnabled]\n                             && (NIPhotoScrollViewPhotoSizeOriginal == photoSize));\n\n    if (updateImage && NIPhotoScrollViewPhotoSizeOriginal == photoSize) {\n      [self notifyDelegatePhotoDidLoadAtIndex:page.pageIndex];\n    }\n  }\n}\n\n- (void)didRecyclePage:(UIView<NIPagingScrollViewPage> *)page {\n  // Give the data source the opportunity to kill any asynchronous operations for this\n  // now-recycled page.\n  if ([self.dataSource respondsToSelector:\n       @selector(photoAlbumScrollView:stopLoadingPhotoAtIndex:)]) {\n    [self.dataSource photoAlbumScrollView: self\n                  stopLoadingPhotoAtIndex: page.pageIndex];\n  }\n}\n\n#pragma mark - NIPhotoScrollViewDelegate\n\n\n- (void)photoScrollViewDidDoubleTapToZoom: (NIPhotoScrollView *)photoScrollView\n                                didZoomIn: (BOOL)didZoomIn {\n  if ([self.delegate respondsToSelector:@selector(photoAlbumScrollView:didZoomIn:)]) {\n    [self.delegate photoAlbumScrollView:self didZoomIn:didZoomIn];\n  }\n}\n\n#pragma mark - Public\n\n\n- (UIView<NIPagingScrollViewPage> *)pagingScrollView:(NIPagingScrollView *)pagingScrollView\n                                    pageViewForIndex:(NSInteger)pageIndex {\n  UIView<NIPagingScrollViewPage>* pageView = nil;\n  NSString* reuseIdentifier = @\"photo\";\n  pageView = [pagingScrollView dequeueReusablePageWithIdentifier:reuseIdentifier];\n  if (nil == pageView) {\n    pageView = [[NIPhotoScrollView alloc] init];\n    pageView.reuseIdentifier = reuseIdentifier;\n    pageView.backgroundColor = self.photoViewBackgroundColor;\n  }\n\n  NIPhotoScrollView* photoScrollView = (NIPhotoScrollView *)pageView;\n  photoScrollView.photoScrollViewDelegate = self;\n  photoScrollView.zoomingAboveOriginalSizeIsEnabled = [self isZoomingAboveOriginalSizeEnabled];\n\n  return pageView;\n}\n\n- (void)didLoadPhoto: (UIImage *)image\n             atIndex: (NSInteger)pageIndex\n           photoSize: (NIPhotoScrollViewPhotoSize)photoSize {\n  // This modifies the UI and therefor MUST be executed on the main thread.\n  NIDASSERT([NSThread isMainThread]);\n\n  for (NIPhotoScrollView* page in self.visiblePages) {\n    if (page.pageIndex == pageIndex) {\n\n      // Only replace the photo if it's of a higher quality than one we're already showing.\n      if (photoSize > page.photoSize) {\n        page.loading = NO;\n        [page setImage:image photoSize:photoSize];\n\n        page.zoomingIsEnabled = ([self isZoomingEnabled]\n                                 && (NIPhotoScrollViewPhotoSizeOriginal == photoSize));\n\n        // Notify the delegate that the photo has been loaded.\n        if (NIPhotoScrollViewPhotoSizeOriginal == photoSize) {\n          [self notifyDelegatePhotoDidLoadAtIndex:pageIndex];\n        }\n      }\n      break;\n    }\n  }\n}\n\n- (void)setZoomingAboveOriginalSizeIsEnabled:(BOOL)enabled {\n  _zoomingAboveOriginalSizeIsEnabled = enabled;\n\n  for (NIPhotoScrollView* page in self.visiblePages) {\n    page.zoomingAboveOriginalSizeIsEnabled = enabled;\n  }\n}\n\n- (void)setPhotoViewBackgroundColor:(UIColor *)photoViewBackgroundColor {\n  if (_photoViewBackgroundColor != photoViewBackgroundColor) {\n      _photoViewBackgroundColor = photoViewBackgroundColor;\n    \n    for (UIView<NIPagingScrollViewPage>* page in self.visiblePages) {\n      page.backgroundColor = photoViewBackgroundColor;\n    }\n  }\n}\n\n- (BOOL)hasNext {\n  return (self.centerPageIndex < self.numberOfPages - 1);\n}\n\n- (BOOL)hasPrevious {\n  return self.centerPageIndex > 0;\n}\n\n- (id<NIPhotoAlbumScrollViewDataSource>)dataSource {\n  NIDASSERT([[super dataSource] conformsToProtocol:@protocol(NIPhotoAlbumScrollViewDataSource)]);\n  return (id<NIPhotoAlbumScrollViewDataSource>)[super dataSource];\n}\n\n- (void)setDataSource:(id<NIPhotoAlbumScrollViewDataSource>)dataSource {\n  [super setDataSource:(id<NIPagingScrollViewDataSource>)dataSource];\n}\n\n- (id<NIPhotoAlbumScrollViewDelegate>)delegate {\n  id<NIPagingScrollViewDelegate> superDelegate = [super delegate];\n  NIDASSERT(nil == superDelegate\n            || [superDelegate conformsToProtocol:@protocol(NIPhotoAlbumScrollViewDelegate)]);\n  return (id<NIPhotoAlbumScrollViewDelegate>)superDelegate;\n}\n\n- (void)setDelegate:(id<NIPhotoAlbumScrollViewDelegate>)delegate {\n  [super setDelegate:(id<NIPhotoAlbumScrollViewDelegate>)delegate];\n}\n\n@end\n"
  },
  {
    "path": "src/photos/src/NIPhotoAlbumScrollViewDataSource.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPhotoScrollViewPhotoSize.h\"\n\n#import \"NimbusPagingScrollView.h\"\n\n#import <Foundation/Foundation.h>\n\n@class NIPhotoAlbumScrollView;\n\n/**\n * The photo album scroll data source.\n *\n * @ingroup NimbusPhotos\n *\n * This data source emphasizes speed and memory efficiency by requesting images only when\n * they're needed and encouraging immediate responses from the data source implementation.\n *\n * @see NIPhotoAlbumScrollView\n */\n@protocol NIPhotoAlbumScrollViewDataSource <NIPagingScrollViewDataSource>\n\n@required\n\n#pragma mark Fetching Required Album Information /** @name [NIPhotoAlbumScrollViewDataSource] Fetching Required Album Information */\n\n/**\n * Fetches the highest-quality image available for the photo at the given index.\n *\n * Your goal should be to make this implementation return as fast as possible. Avoid\n * hitting the disk or blocking on a network request. Aim to load images asynchronously.\n *\n * If you already have the highest-quality image in memory (like in an NIImageMemoryCache),\n * then you can simply return the image and set photoSize to be\n * NIPhotoScrollViewPhotoSizeOriginal.\n *\n * If the highest-quality image is not available when this method is called then you should\n * spin off an asynchronous operation to load the image and set isLoading to YES.\n *\n * If you have a thumbnail in memory but not the full-size image yet, then you should return\n * the thumbnail, set isLoading to YES, and set photoSize to NIPhotoScrollViewPhotoSizeThumbnail.\n *\n * Once the high-quality image finishes loading, call didLoadPhoto:atIndex:photoSize: with\n * the image.\n *\n * This method will be called to prefetch the next and previous photos in the scroll view.\n * The currently displayed photo will always be requested first.\n *\n * @attention The photo scroll view does not hold onto the UIImages for very long at all.\n *                 It is up to the controller to decide on an adequate caching policy to ensure\n *                 that images are kept in memory through the life of the photo album.\n *                 In your implementation of the data source you should prioritize thumbnails\n *                 being kept in memory over full-size images. When a memory warning is received,\n *                 the original photos should be relinquished from memory first.\n */\n- (UIImage *)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView\n                     photoAtIndex: (NSInteger)photoIndex\n                        photoSize: (NIPhotoScrollViewPhotoSize *)photoSize\n                        isLoading: (BOOL *)isLoading\n          originalPhotoDimensions: (CGSize *)originalPhotoDimensions;\n\n@optional\n\n#pragma mark Optimizing Data Retrieval /** @name [NIPhotoAlbumScrollViewDataSource] Optimizing Data Retrieval */\n\n/**\n * Called when you should cancel any asynchronous loading requests for the given photo.\n *\n * When a photo is not immediately visible this method is called to allow the data\n * source to minimize the number of active asynchronous operations in place.\n *\n * This method is optional, though recommended because it focuses the device's processing\n * power on the most immediately accessible photos.\n */\n- (void)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView\n     stopLoadingPhotoAtIndex: (NSInteger)photoIndex;\n\n@end\n\n"
  },
  {
    "path": "src/photos/src/NIPhotoAlbumScrollViewDelegate.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"NimbusPagingScrollView.h\"\n\n@class NIPhotoAlbumScrollView;\n\n/**\n * The photo album scroll view delegate.\n *\n * @ingroup Photos-Protocols\n * @see NIPhotoAlbumScrollView\n */\n@protocol NIPhotoAlbumScrollViewDelegate <NIPagingScrollViewDelegate>\n\n@optional\n\n#pragma mark Scrolling and Zooming /** @name [NIPhotoAlbumScrollViewDelegate] Scrolling and Zooming */\n\n/**\n * The user double-tapped to zoom in or out.\n */\n- (void)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView\n                   didZoomIn: (BOOL)didZoomIn;\n\n\n#pragma mark Data Availability /** @name [NIPhotoAlbumScrollViewDelegate] Data Availability */\n\n/**\n * The next photo in the album has been loaded and is ready to be displayed.\n */\n- (void)photoAlbumScrollViewDidLoadNextPhoto:(NIPhotoAlbumScrollView *)photoAlbumScrollView;\n\n/**\n * The previous photo in the album has been loaded and is ready to be displayed.\n */\n- (void)photoAlbumScrollViewDidLoadPreviousPhoto:(NIPhotoAlbumScrollView *)photoAlbumScrollView;\n\n@end\n\n"
  },
  {
    "path": "src/photos/src/NIPhotoScrollView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPagingScrollViewPage.h\"\n#import \"NIPhotoScrollViewPhotoSize.h\"\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n@protocol NIPhotoScrollViewDelegate;\n@class NICenteringScrollView;\n\n/**\n * A single photo view that supports zooming and rotation.\n *\n * @ingroup NimbusPhotos\n */\n@interface NIPhotoScrollView : UIView <UIScrollViewDelegate, NIPagingScrollViewPage>\n\n#pragma mark Configuring Functionality\n\n@property (nonatomic, assign, getter=isZoomingEnabled) BOOL zoomingIsEnabled; // default: yes\n@property (nonatomic, assign, getter=isZoomingAboveOriginalSizeEnabled) BOOL zoomingAboveOriginalSizeIsEnabled; // default: yes\n@property (nonatomic, assign, getter=isDoubleTapToZoomEnabled) BOOL doubleTapToZoomIsEnabled; // default: yes\n@property (nonatomic, assign) CGFloat maximumScale; // default: 0 (autocalculate)\n@property (nonatomic, weak) id<NIPhotoScrollViewDelegate> photoScrollViewDelegate;\n\n#pragma mark State\n\n- (UIImage *)image;\n- (NIPhotoScrollViewPhotoSize)photoSize;\n- (void)setImage:(UIImage *)image photoSize:(NIPhotoScrollViewPhotoSize)photoSize;\n@property (nonatomic, assign, getter = isLoading) BOOL loading;\n\n@property (nonatomic, assign) NSInteger pageIndex;\n@property (nonatomic, assign) CGSize photoDimensions;\n@property (nonatomic, readonly, strong) UITapGestureRecognizer* doubleTapGestureRecognizer;\n\n@end\n\n/** @name Configuring Functionality */\n\n/**\n * Whether the photo is allowed to be zoomed.\n *\n * By default this is YES.\n *\n * @fn NIPhotoScrollView::zoomingIsEnabled\n */\n\n/**\n * Whether small photos can be zoomed at least until they fit the screen.\n *\n * If this is disabled, images smaller than the view size can not be zoomed in beyond\n * their original dimensions.\n *\n * If this is enabled, images smaller than the view size can be zoomed in only until\n * they fit the view bounds.\n *\n * The default behavior in Photos.app allows small photos to be zoomed in.\n *\n * @attention This will allow photos to be zoomed in even if they don't have any more\n *                 pixels to show, causing the photo to blur. This can look ok for photographs,\n *                 but might not look ok for software design mockups.\n *\n * By default this is YES.\n *\n * @fn NIPhotoScrollView::zoomingAboveOriginalSizeIsEnabled\n */\n\n/**\n * Whether double-tapping zooms in and out of the image.\n *\n * Available on iOS 3.2 and later.\n *\n * By default this is YES.\n *\n * @fn NIPhotoScrollView::doubleTapToZoomIsEnabled\n */\n\n/**\n * The maximum scale of the image.\n *\n * By default this is 0, meaning the view will automatically determine the maximum scale.\n * Setting this to a non-zero value will override the automatically-calculated maximum scale.\n *\n * @fn NIPhotoScrollView::maximumScale\n */\n\n/**\n * The photo scroll view delegate.\n *\n * @fn NIPhotoScrollView::photoScrollViewDelegate\n */\n\n\n/** @name State */\n\n/**\n * The currently-displayed photo.\n *\n * @fn NIPhotoScrollView::image\n */\n\n/**\n * Set a new photo with a specific size.\n *\n * If image is nil then the photoSize will be overridden as NIPhotoScrollViewPhotoSizeUnknown.\n *\n * Resets the current zoom levels and zooms to fit the image.\n *\n * @fn NIPhotoScrollView::setImage:photoSize:\n */\n\n/**\n * The index of this photo within a photo album.\n *\n * @fn NIPhotoScrollView::pageIndex\n */\n\n/**\n * The current size of the photo.\n *\n * This is used to replace the photo only with successively higher-quality versions.\n *\n * @fn NIPhotoScrollView::photoSize\n */\n\n/**\n * The largest dimensions of the photo.\n *\n * This is used to show the thumbnail at the final image size in case the final image size\n * is smaller than the album's frame. Without this value we have to assume that the thumbnail\n * will take up the full screen. If the final image doesn't take up the full screen, then\n * the photo view will appear to \"snap\" to the smaller full-size image when the final image\n * does load.\n *\n * CGSizeZero is used to signify an unknown final photo dimension.\n *\n * @fn NIPhotoScrollView::photoDimensions\n */\n\n/**\n * The gesture recognizer for double-tapping zooms in and out of the image.\n *\n * This is used mainly for setting up dependencies between gesture recognizers.\n *\n * @fn NIPhotoScrollView::doubleTapGestureRecognizer\n */\n"
  },
  {
    "path": "src/photos/src/NIPhotoScrollView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPhotoScrollView.h\"\n\n#import \"NIPhotoScrollViewDelegate.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NIPhotoScrollView ()\n@property (nonatomic, assign) NIPhotoScrollViewPhotoSize photoSize;\n- (void)setMaxMinZoomScalesForCurrentBounds;\n@end\n\n@implementation NIPhotoScrollView {\n  // The photo view to be zoomed.\n  UIImageView* _imageView;\n  // The scroll view.\n  UIScrollView* _scrollView;\n  UIActivityIndicatorView* _loadingView;\n\n  // Photo Information\n  NIPhotoScrollViewPhotoSize _photoSize;\n  CGSize _photoDimensions;\n\n  // Configurable State\n  BOOL _zoomingIsEnabled;\n  BOOL _zoomingAboveOriginalSizeIsEnabled;\n\n  UITapGestureRecognizer* _doubleTapGestureRecognizer;\n}\n\n@synthesize reuseIdentifier;\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n    // Default configuration.\n    self.zoomingIsEnabled = YES;\n    self.zoomingAboveOriginalSizeIsEnabled = YES;\n    self.doubleTapToZoomIsEnabled = YES;\n\n    // Autorelease so that we don't have to worry about releasing the subviews in dealloc.\n    _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];\n    _scrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth\n                                    | UIViewAutoresizingFlexibleHeight);\n\n    _loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];\n    [_loadingView sizeToFit];\n    _loadingView.frame = NIFrameOfCenteredViewWithinView(_loadingView, self);\n    _loadingView.autoresizingMask =\n        (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin\n         | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin);\n\n    // We implement viewForZoomingInScrollView: and return the image view for zooming.\n    _scrollView.delegate = self;\n\n    // Disable the scroll indicators.\n    _scrollView.showsVerticalScrollIndicator = NO;\n    _scrollView.showsHorizontalScrollIndicator = NO;\n\n    // Photo viewers should feel sticky when you're panning around, not smooth and slippery\n    // like a UITableView.\n    _scrollView.decelerationRate = UIScrollViewDecelerationRateFast;\n\n    // Ensure that empty areas of the scroll view are draggable.\n    self.backgroundColor = [UIColor blackColor];\n    _scrollView.backgroundColor = self.backgroundColor;\n\n    _imageView = [[UIImageView alloc] initWithFrame:CGRectZero];\n\n    [_scrollView addSubview:_imageView];\n    [self addSubview:_scrollView];\n    [self addSubview:_loadingView];\n  }\n  return self;\n}\n\n- (void)setBackgroundColor:(UIColor *)backgroundColor {\n  [super setBackgroundColor:backgroundColor];\n\n  _scrollView.backgroundColor = backgroundColor;\n}\n\n#pragma mark - UIScrollView\n\n\n- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {\n  return _imageView;\n}\n\n- (void)scrollViewDidZoom:(UIScrollView *)scrollView {\n  [self centerImageView];\n}\n\n#pragma mark - Gesture Recognizers\n\n\n- (CGRect)rectAroundPoint:(CGPoint)point atZoomScale:(CGFloat)zoomScale {\n  NIDASSERT(zoomScale > 0);\n\n  // Define the shape of the zoom rect.\n  CGSize boundsSize = self.bounds.size;\n\n  // Modify the size according to the requested zoom level.\n  // For example, if we're zooming in to 0.5 zoom, then this will increase the bounds size\n  // by a factor of two.\n  CGSize scaledBoundsSize = CGSizeMake(boundsSize.width / zoomScale,\n                                       boundsSize.height / zoomScale);\n\n  CGRect rect = CGRectMake(point.x - scaledBoundsSize.width / 2,\n                           point.y - scaledBoundsSize.height / 2,\n                           scaledBoundsSize.width,\n                           scaledBoundsSize.height);\n\n  // When the image is zoomed out there is a bit of empty space around the image due\n  // to the fact that it's centered on the screen. When we created the rect around the\n  // point we need to take this \"space\" into account.\n\n  // 1: get the frame of the image in this view's coordinates.\n  CGRect imageScaledFrame = [self convertRect:_imageView.frame toView:self];\n\n  // 2: Offset the frame by the excess amount. This will ensure that the zoomed location\n  //    is always centered on the tap location. We only allow positive values because a\n  //    negative value implies that there isn't actually any offset.\n  rect = CGRectOffset(rect, -MAX(0, imageScaledFrame.origin.x), -MAX(0, imageScaledFrame.origin.y));\n\n  return rect;\n}\n\n- (void)didDoubleTap:(UITapGestureRecognizer *)tapGesture {\n  BOOL isCompletelyZoomedIn = (_scrollView.maximumZoomScale <= _scrollView.zoomScale + FLT_EPSILON);\n\n  BOOL didZoomIn;\n\n  if (isCompletelyZoomedIn) {\n    // Zoom the photo back out.\n    [_scrollView setZoomScale:_scrollView.minimumZoomScale animated:YES];\n\n    didZoomIn = NO;\n\n  } else {\n    // Zoom into the tap point.\n    CGPoint tapCenter = [tapGesture locationInView:_imageView];\n\n    CGRect maxZoomRect = [self rectAroundPoint:tapCenter atZoomScale:_scrollView.maximumZoomScale];\n    [_scrollView zoomToRect:maxZoomRect animated:YES];\n\n    didZoomIn = YES;\n  }\n\n  if ([self.photoScrollViewDelegate respondsToSelector:\n       @selector(photoScrollViewDidDoubleTapToZoom:didZoomIn:)]) {\n    [self.photoScrollViewDelegate photoScrollViewDidDoubleTapToZoom:self didZoomIn:didZoomIn];\n  }\n}\n\n#pragma mark - NIPagingScrollViewPage\n\n\n- (void)prepareForReuse {\n  _imageView.image = nil;\n  self.photoSize = NIPhotoScrollViewPhotoSizeUnknown;\n  _scrollView.zoomScale = 1;\n  _scrollView.contentSize = self.bounds.size;\n}\n\n- (void)pageDidDisappear {\n  _scrollView.zoomScale = _scrollView.minimumZoomScale;\n}\n\n#pragma mark - Public\n\n\n- (void)setImage:(UIImage *)image photoSize:(NIPhotoScrollViewPhotoSize)photoSize {\n  _imageView.image = image;\n  [_imageView sizeToFit];\n\n  if (nil == image) {\n    self.photoSize = NIPhotoScrollViewPhotoSizeUnknown;\n\n  } else {\n    self.photoSize = photoSize;\n  }\n\n  // The min/max zoom values assume that the content size is the image size. The max zoom will\n  // be a value that allows the image to be seen at a 1-to-1 pixel resolution, while the min\n  // zoom will be small enough to fit the image on the screen perfectly.\n  if (nil != image) {\n    _scrollView.contentSize = image.size;\n\n  } else {\n    _scrollView.contentSize = self.bounds.size;\n  }\n\n  [self setMaxMinZoomScalesForCurrentBounds];\n\n  // Start off with the image fully-visible on the screen.\n  _scrollView.zoomScale = _scrollView.minimumZoomScale;\n\n  [self setNeedsLayout];\n}\n\n- (void)setLoading:(BOOL)loading {\n  _loading = loading;\n\n  if (loading) {\n    [_loadingView startAnimating];\n  } else {\n    [_loadingView stopAnimating];\n  }\n}\n\n- (UIImage *)image {\n  return _imageView.image;\n}\n\n- (void)setZoomingIsEnabled:(BOOL)enabled {\n  _zoomingIsEnabled = enabled;\n\n  if (nil != _imageView.image) {\n    [self setMaxMinZoomScalesForCurrentBounds];\n\n    // Fit the image on screen.\n    _scrollView.zoomScale = _scrollView.minimumZoomScale;\n\n    // Disable zoom bouncing if zooming is disabled, otherwise the view will allow pinching.\n    _scrollView.bouncesZoom = enabled;\n\n  } else {\n    // Reset to the defaults if there is no set image yet.\n    _scrollView.zoomScale = 1;\n    _scrollView.minimumZoomScale = 1;\n    _scrollView.maximumZoomScale = 1;\n    _scrollView.bouncesZoom = NO;\n  }\n}\n\n- (void)setDoubleTapToZoomIsEnabled:(BOOL)enabled {\n  if (enabled && nil == _doubleTapGestureRecognizer) {\n    _doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didDoubleTap:)];\n    _doubleTapGestureRecognizer.numberOfTapsRequired = 2;\n    [self addGestureRecognizer:_doubleTapGestureRecognizer];\n  }\n\n  _doubleTapGestureRecognizer.enabled = enabled;\n}\n\n- (BOOL)isDoubleTapToZoomEnabled {\n  return [_doubleTapGestureRecognizer isEnabled];\n}\n\n- (CGFloat)scaleForSize:(CGSize)size boundsSize:(CGSize)boundsSize useMinimalScale:(BOOL)minimalScale {\n  CGFloat xScale = boundsSize.width / size.width;   // The scale needed to perfectly fit the image width-wise.\n  CGFloat yScale = boundsSize.height / size.height; // The scale needed to perfectly fit the image height-wise.\n  CGFloat minScale = minimalScale ? MIN(xScale, yScale) : MAX(xScale, yScale); // Use the minimum of these to allow the image to become fully visible, or the maximum to get fullscreen size\n  \n  return minScale;\n}\n\n/**\n * Calculate the min and max scale for the given dimensions and photo size.\n *\n * minScale will fit the photo to the bounds, unless it is too small in which case it will\n * show the image at a 1-to-1 resolution.\n *\n * maxScale will be whatever value shows the image at a 1-to-1 resolution, UNLESS\n * isZoomingAboveOriginalSizeEnabled is enabled, in which case maxScale will be calculated\n * such that the image completely fills the bounds.\n *\n * Exception:  If the photo size is unknown (this is a loading image, for example) then\n * the minimum scale will be set without considering the screen scale. This allows the\n * loading image to draw with its own image scale if it's a high-res @2x image.\n */\n- (void)minAndMaxScaleForDimensions: (CGSize)dimensions\n                         boundsSize: (CGSize)boundsSize\n                         photoScale: (CGFloat)photoScale\n                          photoSize: (NIPhotoScrollViewPhotoSize)photoSize\n                           minScale: (CGFloat *)pMinScale\n                           maxScale: (CGFloat *)pMaxScale {\n  NIDASSERT(nil != pMinScale);\n  NIDASSERT(nil != pMaxScale);\n  if (nil == pMinScale\n      || nil == pMaxScale) {\n    return;\n  }\n\n  CGFloat minScale = [self scaleForSize: dimensions\n                             boundsSize: boundsSize\n                        useMinimalScale: YES];\n\n  // On high resolution screens we have double the pixel density, so we will be seeing\n  // every pixel if we limit the maximum zoom scale to 0.5.\n  // If the photo size is unknown, it's likely that we're showing the loading image and\n  // don't want to shrink it down with the zoom because it should be a scaled image.\n  CGFloat maxScale = ((NIPhotoScrollViewPhotoSizeUnknown == photoSize)\n                      ? 1\n                      : (photoScale / NIScreenScale()));\n\n  if (NIPhotoScrollViewPhotoSizeThumbnail != photoSize) {\n    // Don't let minScale exceed maxScale. (If the image is smaller than the screen, we\n    // don't want to force it to be zoomed.)\n    minScale = MIN(minScale, maxScale);\n  }\n\n  // At this point if the image is small, then minScale and maxScale will be the same because\n  // we don't want to allow the photo to be zoomed.\n\n  // If zooming above the original size IS enabled, however, expand the max zoom to\n  // whatever value would make the image fit the view perfectly.\n  if ([self isZoomingAboveOriginalSizeEnabled]) {\n    CGFloat idealMaxScale = [self scaleForSize: dimensions\n                                    boundsSize: boundsSize\n                               useMinimalScale: NO];\n    maxScale = MAX(maxScale, idealMaxScale);\n  }\n\n  *pMinScale = minScale;\n  *pMaxScale = maxScale;\n}\n\n- (void)setMaxMinZoomScalesForCurrentBounds {\n  CGSize imageSize = _imageView.bounds.size;\n  \n  // Avoid crashing if the image has no dimensions.\n  if (imageSize.width <= 0 || imageSize.height <= 0) {\n    _scrollView.maximumZoomScale = 1;\n    _scrollView.minimumZoomScale = 1;\n    return;\n  }\n  \n  // The following code is from Apple's ImageScrollView example application and has been used\n  // here because it is well-documented and concise.\n  \n  CGSize boundsSize = _scrollView.bounds.size;\n  \n  CGFloat minScale = 0;\n  CGFloat maxScale = 0;\n  \n  // Calculate the min/max scale for the image to be presented.\n  [self minAndMaxScaleForDimensions: imageSize\n                         boundsSize: boundsSize\n                         photoScale: _imageView.image.scale\n                          photoSize: self.photoSize\n                           minScale: &minScale\n                           maxScale: &maxScale];\n  \n  // When we show thumbnails for images that are too small for the bounds, we try to use\n  // the known photo dimensions to scale the minimum scale to match what the final image\n  // would be. This avoids any \"snapping\" effects from stretching the thumbnail too large.\n  if ((NIPhotoScrollViewPhotoSizeThumbnail == self.photoSize)\n      && !CGSizeEqualToSize(self.photoDimensions, CGSizeZero)) {\n    CGFloat scaleToFitOriginal = 0;\n    CGFloat originalMaxScale = 0;\n    // Calculate the original-sized image's min/max scale.\n    [self minAndMaxScaleForDimensions: self.photoDimensions\n                           boundsSize: boundsSize\n                           photoScale: _imageView.image.scale\n                            photoSize: NIPhotoScrollViewPhotoSizeOriginal\n                             minScale: &scaleToFitOriginal\n                             maxScale: &originalMaxScale];\n    \n    if (scaleToFitOriginal + FLT_EPSILON >= (1.0 / NIScreenScale())) {\n      // If the final image will be smaller than the view then we want to use that\n      // scale as the \"true\" scale and adjust it relatively to the thumbnail's dimensions.\n      // This ensures that the thumbnail will always be the same visual size as the original\n      // image, giving us that sexy \"crisping\" effect when the thumbnail is loaded.\n      CGFloat relativeSize = self.photoDimensions.width / imageSize.width;\n      minScale = scaleToFitOriginal * relativeSize;\n    }\n  }\n  \n  // If zooming is disabled then we flatten the range for zooming to only allow the min zoom.\n  if (self.isZoomingEnabled && NIPhotoScrollViewPhotoSizeOriginal == self.photoSize && self.maximumScale > 0) {\n    _scrollView.maximumZoomScale = self.maximumScale;\n  } else {\n    _scrollView.maximumZoomScale = self.isZoomingEnabled ? maxScale : minScale;\n  }\n  _scrollView.minimumZoomScale = minScale;\n}\n\n#pragma mark Saving/Restoring Offset and Scale\n\n// Parts of the following code are from Apple's ImageScrollView example application and\n// have been used here because they are well-documented and concise.\n\n\n// Fetch the visual center point of this view in the image view's coordinate space.\n- (CGPoint)pointToCenterAfterRotation {\n  CGRect bounds = _scrollView.bounds;\n  CGPoint boundsCenter = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));\n  return [self convertPoint:boundsCenter toView:_imageView];\n}\n\n- (CGFloat)scaleToRestoreAfterRotation {\n  CGFloat contentScale = _scrollView.zoomScale;\n  \n  // If we're at the minimum zoom scale, preserve that by returning 0, which\n  // will be converted to the minimum allowable scale when the scale is restored.\n  if (contentScale <= _scrollView.minimumZoomScale + FLT_EPSILON) {\n    contentScale = 0;\n  }\n  \n  return contentScale;\n}\n\n- (CGPoint)maximumContentOffset {\n  CGSize contentSize = _scrollView.contentSize;\n  CGSize boundsSize = _scrollView.bounds.size;\n  return CGPointMake(contentSize.width - boundsSize.width,\n                     contentSize.height - boundsSize.height);\n}\n\n- (CGPoint)minimumContentOffset {\n  return CGPointZero;\n}\n\n- (void)restoreCenterPoint:(CGPoint)oldCenter scale:(CGFloat)oldScale {\n  // Step 1: restore zoom scale, making sure it is within the allowable range.\n  _scrollView.zoomScale = NIBoundf(oldScale,\n                                 _scrollView.minimumZoomScale, _scrollView.maximumZoomScale);\n\n  // Step 2: restore center point, making sure it is within the allowable range.\n\n  // 2a: convert our desired center point back to the scroll view's coordinate space from the\n  //     image's coordinate space.\n  CGPoint boundsCenter = [self convertPoint:oldCenter fromView:_imageView];\n\n  // 2b: calculate the content offset that would yield that center point\n  CGPoint offset = CGPointMake(boundsCenter.x - _scrollView.bounds.size.width / 2.0f,\n                               boundsCenter.y - _scrollView.bounds.size.height / 2.0f);\n\n  // 2c: restore offset, adjusted to be within the allowable range\n  CGPoint maxOffset = [self maximumContentOffset];\n  CGPoint minOffset = [self minimumContentOffset];\n  offset.x = NIBoundf(offset.x, minOffset.x, maxOffset.x);\n  offset.y = NIBoundf(offset.y, minOffset.y, maxOffset.y);\n  _scrollView.contentOffset = offset;\n}\n\n#pragma mark Saving/Restoring Offset and Scale\n\n\n- (void)setFrameAndMaintainState:(CGRect)frame {\n  CGPoint restorePoint = [self pointToCenterAfterRotation];\n  CGFloat restoreScale = [self scaleToRestoreAfterRotation];\n  self.frame = frame;\n  [self setMaxMinZoomScalesForCurrentBounds];\n  [self restoreCenterPoint:restorePoint scale:restoreScale];\n}\n\n#pragma mark Centering\n\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n  [self centerImageView];\n}\n\n- (void)centerImageView {\n  // Center the image as it becomes smaller than the size of the screen.\n  CGSize boundsSize = self.bounds.size;\n  CGRect frameToCenter = _imageView.frame;\n\n  // Center horizontally.\n  if (frameToCenter.size.width < boundsSize.width) {\n    frameToCenter.origin.x = NICGFloatFloor((boundsSize.width - frameToCenter.size.width) / 2);\n\n  } else {\n    frameToCenter.origin.x = 0;\n  }\n\n  // Center vertically.\n  if (frameToCenter.size.height < boundsSize.height) {\n    frameToCenter.origin.y = NICGFloatFloor((boundsSize.height - frameToCenter.size.height) / 2);\n\n  } else {\n    frameToCenter.origin.y = 0;\n  }\n\n  _imageView.frame = frameToCenter;\n}\n\n@end\n"
  },
  {
    "path": "src/photos/src/NIPhotoScrollViewDelegate.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n@class NIPhotoScrollView;\n\n/**\n * The photo scroll view delegate.\n *\n * @ingroup NimbusPhotos\n */\n@protocol NIPhotoScrollViewDelegate <NSObject>\n\n@optional\n\n#pragma mark Zooming /** @name [NIPhotoScrollViewDelegate] Zooming */\n\n/**\n * The user has double-tapped the photo to zoom either in or out.\n *\n * @param photoScrollView  The photo scroll view that was tapped.\n * @param didZoomIn        YES if the photo was zoomed in. NO if the photo was zoomed out.\n */\n- (void)photoScrollViewDidDoubleTapToZoom: (NIPhotoScrollView *)photoScrollView\n                                didZoomIn: (BOOL)didZoomIn;\n\n@end\n"
  },
  {
    "path": "src/photos/src/NIPhotoScrollViewPhotoSize.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n\n/**\n * Contextual information about the size of the photo.\n */\ntypedef enum {\n  // Unknown photo size.\n  NIPhotoScrollViewPhotoSizeUnknown,\n  \n  // A smaller version of the image.\n  NIPhotoScrollViewPhotoSizeThumbnail,\n  \n  // The full-size image.\n  NIPhotoScrollViewPhotoSizeOriginal,\n} NIPhotoScrollViewPhotoSize;\n"
  },
  {
    "path": "src/photos/src/NIPhotoScrubberView.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPreprocessorMacros.h\" /* for weak */\n\n@protocol NIPhotoScrubberViewDataSource;\n@protocol NIPhotoScrubberViewDelegate;\n\n/**\n * A control built for quickly skimming through a collection of images.\n *\n * @ingroup NimbusPhotos\n *\n * The user interacts with the scrubber by \"scrubbing\" their finger along the control,\n * or more simply, touching the control and moving their finger along a single axis.\n * Scrubbers can be seen in the Photos.app on the iPad.\n *\n * The thumbnails displayed in a scrubber will be a subset of the overall set of photos.\n * The wider the scrubber, the more thumbnails will be shown. The displayed thumbnails will\n * be chosen at constant intervals in the album, with a larger \"selected\" thumbnail image\n * that will show whatever image is currently selected. This larger thumbnail will be\n * positioned relatively within the scrubber to show the user what the current selection\n * is in a physically intuitive way.\n *\n * This view is a completely independent view from the photo scroll view so you can choose\n * to use this in your already built photo viewer.\n *\n * @image html scrubber1.png \"Screenshot of NIPhotoScrubberView on the iPad.\"\n *\n * @see NIPhotoScrubberViewDataSource\n * @see NIPhotoScrubberViewDelegate\n */\n@interface NIPhotoScrubberView : UIView\n\n#pragma mark Data Source /** @name Data Source */\n\n/**\n * The data source for this scrubber view.\n */\n@property (nonatomic, weak) id<NIPhotoScrubberViewDataSource> dataSource;\n\n/**\n * Forces the scrubber view to reload all of its data.\n *\n * This must be called at least once after dataSource has been set in order for the view\n * to gather any presentable information.\n *\n * This method is expensive. It will reset the state of the view and remove all existing\n * thumbnails before requesting the new information from the data source.\n */\n- (void)reloadData;\n\n/**\n * Notify the scrubber view that a thumbnail has been loaded at a given index.\n *\n * This method is cheap, so do not be afraid to call it whenever a thumbnail loads.\n * It will only modify visible thumbnails.\n */\n- (void)didLoadThumbnail: (UIImage *)image\n                 atIndex: (NSInteger)photoIndex;\n\n#pragma mark Delegate /** @name Delegate */\n\n/**\n * The delegate for this scrubber view.\n */\n@property (nonatomic, weak) id<NIPhotoScrubberViewDelegate> delegate;\n\n#pragma mark Accessing Selection /** @name Accessing Selection */\n\n/**\n * The selected photo index.\n */\n@property (nonatomic, assign) NSInteger selectedPhotoIndex;\n\n/**\n * Set the selected photo with animation.\n */\n- (void)setSelectedPhotoIndex:(NSInteger)photoIndex animated:(BOOL)animated;\n\n@end\n\n/**\n * The data source for the photo scrubber.\n *\n * @ingroup NimbusPhotos\n *\n * <h2>Performance Considerations</h2>\n *\n * A scrubber view's purpose is for instantly flipping through an album of photos. As such,\n * it's crucial that your implementation of the data source performs blazingly fast. When\n * the scrubber requests a thumbnail from you you should *not* be hitting the disk or blocking\n * on a network call. If you don't have the thumbnail available at that exact moment, fire\n * off an asynchronous load request (using NIReadFileFromDiskOperation or NIHTTPRequest)\n * and return nil. Once the thumbnail is loaded, call didLoadThumbnail:atIndex: to notify\n * the scrubber that it can display the thumbnail now.\n *\n * It is not recommended to use high-res images for your scrubber thumbnails. This is because\n * the scrubber will keep a large set of images in memory and if you're giving it\n * high-resolution images then you'll find that your app quickly burns through memory.\n * If you don't have access to thumbnails from whatever API you're using then you should consider\n * not using a scrubber.\n *\n * @see NIPhotoScrubberView\n */\n@protocol NIPhotoScrubberViewDataSource <NSObject>\n\n@required\n\n#pragma mark Fetching Required Information /** @name Fetching Required Information */\n\n/**\n * Fetches the total number of photos in the scroll view.\n *\n * The value returned in this method will be cached by the scroll view until reloadData\n * is called again.\n */\n- (NSInteger)numberOfPhotosInScrubberView:(NIPhotoScrubberView *)photoScrubberView;\n\n/**\n * Fetch the thumbnail image for the given photo index.\n *\n * Please read and understand the performance considerations for this data source.\n */\n- (UIImage *)photoScrubberView: (NIPhotoScrubberView *)photoScrubberView\n              thumbnailAtIndex: (NSInteger)thumbnailIndex;\n\n@end\n\n/**\n * The delegate for the photo scrubber.\n *\n * @ingroup NimbusPhotos\n *\n * Sends notifications of state changes.\n *\n * @see NIPhotoScrubberView\n */\n@protocol NIPhotoScrubberViewDelegate <NSObject>\n\n@optional\n\n#pragma mark Selection Changes /** @name Selection Changes */\n\n/**\n * The photo scrubber changed its selection.\n *\n * Use photoScrubberView.selectedPhotoIndex to access the current selection.\n */\n- (void)photoScrubberViewDidChangeSelection:(NIPhotoScrubberView *)photoScrubberView;\n\n@end\n"
  },
  {
    "path": "src/photos/src/NIPhotoScrubberView.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIPhotoScrubberView.h\"\n\n#import \"NimbusCore.h\"\n\n#import <QuartzCore/QuartzCore.h>\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\nstatic const NSInteger NIPhotoScrubberViewUnknownTag = -1;\n\n@interface NIPhotoScrubberView()\n\n/**\n * @internal\n *\n * A method to encapsulate initilization logic that can be shared by different init methods.\n */\n- (void)initializeScrubber;\n\n/**\n * @internal\n *\n * A lightweight method for updating all of the visible thumbnails in the scrubber.\n *\n * This method will force the scrubber to lay itself out, calculate how many thumbnails might\n * be visible, and then lay out the thumbnails and fetch any thumbnail images it can find.\n *\n * This method should never take much time to run, so it can safely be used in layoutSubviews.\n */\n- (void)updateVisiblePhotos;\n\n/**\n * @internal\n *\n * Returns a new, autoreleased image view in the style of this photo scrubber.\n *\n * This implementation returns an image with a 1px solid white border and a black background.\n */\n- (UIImageView *)photoView;\n\n@end\n\n\n@implementation NIPhotoScrubberView {\n  NSMutableArray* _visiblePhotoViews;\n  NSMutableSet* _recycledPhotoViews;\n\n  UIView* _containerView;\n  UIImageView* _selectionView;\n\n  // State\n  NSInteger _selectedPhotoIndex;\n\n  // Cached data source values\n  NSInteger _numberOfPhotos;\n\n  // Cached display values\n  NSInteger _numberOfVisiblePhotos;\n}\n\n- (id)initWithFrame:(CGRect)frame {\n  if ((self = [super initWithFrame:frame])) {\n      [self initializeScrubber];\n  }\n\n  return self;\n}\n\n- (id)initWithCoder:(NSCoder *)aDecoder {\n    if ((self = [super initWithCoder:aDecoder])) {\n        [self initializeScrubber];\n    }\n    \n    return self;\n}\n\n- (void)initializeScrubber {\n    // Only one finger should be allowed to interact with the scrubber at a time.\n    self.multipleTouchEnabled = NO;\n    \n    _containerView = [[UIView alloc] init];\n    _containerView.layer.borderColor = [UIColor colorWithWhite:1 alpha:0.1f].CGColor;\n    _containerView.layer.borderWidth = 1;\n    _containerView.backgroundColor = [UIColor colorWithWhite:1 alpha:0.3f];\n    _containerView.userInteractionEnabled = NO;\n    [self addSubview:_containerView];\n    \n    _selectionView = [self photoView];\n    [self addSubview:_selectionView];\n    \n    _selectedPhotoIndex = -1;\n}\n\n#pragma mark - View Creation\n\n\n- (UIImageView *)photoView {\n  UIImageView* imageView = [[UIImageView alloc] init];\n  \n  imageView.layer.borderColor = [UIColor whiteColor].CGColor;\n  imageView.layer.borderWidth = 1;\n  imageView.backgroundColor = [UIColor blackColor];\n  imageView.clipsToBounds = YES;\n  \n  imageView.userInteractionEnabled = NO;\n  \n  imageView.contentMode = UIViewContentModeScaleAspectFill;\n  \n  imageView.tag = NIPhotoScrubberViewUnknownTag;\n  \n  return imageView;\n}\n\n#pragma mark - Layout\n\n\n- (CGSize)photoSize {\n  CGSize boundsSize = self.bounds.size;\n\n  // These numbers are roughly estimated from the Photos.app's scrubber.\n  CGFloat photoWidth  = NICGFloatFloor(boundsSize.height / 2.4f);\n  CGFloat photoHeight = NICGFloatFloor(photoWidth * 0.75f);\n  \n  return CGSizeMake(photoWidth, photoHeight);\n}\n\n- (CGSize)selectionSize {\n  CGSize boundsSize = self.bounds.size;\n  \n  // These numbers are roughly estimated from the Photos.app's scrubber.\n  CGFloat selectionWidth  = NICGFloatFloor(boundsSize.height / 1.2f);\n  CGFloat selectionHeight = NICGFloatFloor(selectionWidth * 0.75f);\n  \n  return CGSizeMake(selectionWidth, selectionHeight);\n}\n\n// The amount of space on either side of the scrubber's left and right edges.\n- (CGFloat)horizontalMargins {\n  CGSize photoSize = [self photoSize];\n  return NICGFloatFloor(photoSize.width / 2);\n}\n\n- (CGFloat)spaceBetweenPhotos {\n  return 1;\n}\n\n// The maximum number of pixels that the scrubber can utilize. The scrubber layer's border\n// is contained within this width and must be considered when laying out the thumbnails.\n- (CGFloat)maxContentWidth {\n  CGSize boundsSize = self.bounds.size;\n  CGFloat horizontalMargins = [self horizontalMargins];\n  \n  CGFloat maxContentWidth = (boundsSize.width\n                             - horizontalMargins * 2);\n  return maxContentWidth;\n}\n\n- (NSInteger)numberOfVisiblePhotos {\n  CGSize photoSize = [self photoSize];\n  CGFloat spaceBetweenPhotos = [self spaceBetweenPhotos];\n  \n  // Here's where we take into account the container layer's border because we don't want to\n  // display thumbnails on top of the border.\n  CGFloat maxContentWidth = ([self maxContentWidth]\n                             - _containerView.layer.borderWidth * 2);\n\n  NSInteger numberOfPhotosThatFit = (NSInteger)floor((maxContentWidth + spaceBetweenPhotos)\n                                                     / (photoSize.width + spaceBetweenPhotos));\n  return MIN(_numberOfPhotos, numberOfPhotosThatFit);\n}\n\n- (CGRect)frameForSelectionAtIndex:(NSInteger)photoIndex {\n  CGSize photoSize = [self photoSize];\n  CGSize selectionSize = [self selectionSize];\n\n  CGFloat containerWidth = _containerView.bounds.size.width;\n  // TODO (jverkoey July 21, 2011): I need to figure out why this is necessary.\n  // Basically, when there are a lot of photos it seems like the selection frame\n  // slowly gets offset from the thumbnail frame it's supposed to be representing until by the end\n  // it's off the right edge by a noticeable amount. Trimming off some fat from the right\n  // edge seems to fix this.\n  if (_numberOfVisiblePhotos < _numberOfPhotos) {\n    containerWidth -= photoSize.width / 2;\n  }\n\n  // Calculate the offset into the container view based on index/numberOfPhotos.\n  CGFloat relativeOffset = NICGFloatFloor((((CGFloat)photoIndex * containerWidth)\n                                          / (CGFloat)MAX(1, _numberOfPhotos)));\n  \n  return CGRectMake(NICGFloatFloor(_containerView.frame.origin.x\n                                   + relativeOffset\n                                   + photoSize.width / 2 - selectionSize.width / 2),\n                    NICGFloatFloor(_containerView.center.y - selectionSize.height / 2),\n                    selectionSize.width, selectionSize.height);\n}\n\n- (CGRect)frameForThumbAtIndex:(NSInteger)thumbIndex {\n  CGSize photoSize = [self photoSize];\n  CGFloat spaceBetweenPhotos = [self spaceBetweenPhotos];\n  return CGRectMake(_containerView.layer.borderWidth\n                    + (photoSize.width + spaceBetweenPhotos) * thumbIndex,\n                    _containerView.layer.borderWidth,\n                    photoSize.width, photoSize.height);\n}\n\n- (void)layoutSubviews {\n  [super layoutSubviews];\n  \n  CGSize boundsSize = self.bounds.size;\n  \n  CGSize photoSize = [self photoSize];\n  CGFloat spaceBetweenPhotos = [self spaceBetweenPhotos];\n  CGFloat maxContentWidth = [self maxContentWidth];\n\n  // Update the total number of visible photos.\n  _numberOfVisiblePhotos = [self numberOfVisiblePhotos];\n\n  // Hide views if there isn't any interesting information to show.\n  _containerView.hidden = (0 == _numberOfVisiblePhotos);\n  _selectionView.hidden = (_selectedPhotoIndex < 0 || _containerView.hidden);\n\n  // Calculate the container width using the number of visible photos.\n  CGFloat containerWidth = ((_numberOfVisiblePhotos * photoSize.width)\n                            + (MAX(0, _numberOfVisiblePhotos - 1) * spaceBetweenPhotos)\n                            + _containerView.layer.borderWidth * 2);\n\n  // Then we center the container in the content area.\n  CGFloat containerMargins = MAX(0, NICGFloatFloor((maxContentWidth - containerWidth) / 2));\n  CGFloat horizontalMargins = [self horizontalMargins];\n  CGFloat containerHeight = photoSize.height + _containerView.layer.borderWidth * 2;\n\n  CGFloat containerLeftMargin = horizontalMargins + containerMargins;\n  CGFloat containerTopMargin = NICGFloatFloor((boundsSize.height - containerHeight) / 2);\n\n  _containerView.frame = CGRectMake(containerLeftMargin,\n                                    containerTopMargin,\n                                    containerWidth,\n                                    containerHeight);\n\n  // Don't bother updating the selected photo index if there isn't a selection; the\n  // selection view will be hidden anyway.\n  if (_selectedPhotoIndex >= 0) {\n    _selectionView.frame = [self frameForSelectionAtIndex:_selectedPhotoIndex];\n  }\n\n  // Update the frames for all of the thumbnails.\n  [self updateVisiblePhotos];\n}\n\n// Transforms an index into the number of visible photos into an index into the total\n// number of photos.\n- (NSInteger)photoIndexAtScrubberIndex:(NSInteger)scrubberIndex {\n  return (NSInteger)(NICGFloatCeil((CGFloat)(scrubberIndex * _numberOfPhotos)\n                                   / (CGFloat)_numberOfVisiblePhotos)\n                     + 0.5f);\n}\n\n- (void)updateVisiblePhotos {\n  if (nil == self.dataSource) {\n    return;\n  }\n\n  // This will update the number of visible photos if the layout did indeed change.\n  [self layoutIfNeeded];\n\n  // Recycle any views that we no longer need.\n  while ([_visiblePhotoViews count] > (NSUInteger)_numberOfVisiblePhotos) {\n    UIView* photoView = [_visiblePhotoViews lastObject];\n    [photoView removeFromSuperview];\n\n    [_recycledPhotoViews addObject:photoView];\n\n    [_visiblePhotoViews removeLastObject];\n  }\n\n  // Lay out the visible photos.\n  for (NSUInteger ix = 0; ix < (NSUInteger)_numberOfVisiblePhotos; ++ix) {\n    UIImageView* photoView = nil;\n\n    // We must first get the photo view at this index.\n\n    // If there aren't enough visible photo views then try to recycle another view.\n    if (ix >= [_visiblePhotoViews count]) {\n      photoView = [_recycledPhotoViews anyObject];\n      if (nil == photoView) {\n        // Couldn't recycle the view, so create a new one.\n        photoView = [self photoView];\n\n      } else {\n        [_recycledPhotoViews removeObject:photoView];\n      }\n      [_containerView addSubview:photoView];\n      [_visiblePhotoViews addObject:photoView];\n\n    } else {\n      photoView = [_visiblePhotoViews objectAtIndex:ix];\n    }\n\n    NSInteger photoIndex = [self photoIndexAtScrubberIndex:ix];\n\n    // Only request the thumbnail if this thumbnail's photo index has changed. Otherwise\n    // we assume that this photo either already has the thumbnail or it's still loading.\n    if (photoView.tag != photoIndex) {\n      photoView.tag = photoIndex;\n\n      UIImage* image = [self.dataSource photoScrubberView:self thumbnailAtIndex:photoIndex];\n      photoView.image = image;\n\n      if (_selectedPhotoIndex == photoIndex) {\n        _selectionView.image = image;\n      }\n    }\n\n    photoView.frame = [self frameForThumbAtIndex:ix];\n  }\n}\n\n#pragma mark - Changing Selection\n\n\n- (NSInteger)photoIndexAtPoint:(CGPoint)point {\n  NSInteger photoIndex;\n  \n  if (point.x <= 0) {\n    // Beyond the left edge\n    photoIndex = 0;\n    \n  } else if (point.x >= _containerView.bounds.size.width) {\n    // Beyond the right edge\n    photoIndex = (_numberOfPhotos - 1);\n    \n  } else {\n    // Somewhere in between\n    photoIndex = (NSInteger)(NICGFloatFloor((point.x / _containerView.bounds.size.width) * _numberOfPhotos)\n                             + 0.5f);\n  }\n  \n  return photoIndex;\n}\n\n- (void)updateSelectionWithPoint:(CGPoint)point {\n  NSInteger photoIndex = [self photoIndexAtPoint:point];\n  \n  if (photoIndex != _selectedPhotoIndex) {\n    [self setSelectedPhotoIndex:photoIndex];\n    \n    if ([self.delegate respondsToSelector:@selector(photoScrubberViewDidChangeSelection:)]) {\n      [self.delegate photoScrubberViewDidChangeSelection:self];\n    }\n  }\n}\n\n#pragma mark - UIResponder\n\n\n- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {\n  [super touchesBegan:touches withEvent:event];\n  \n  UITouch* touch = [touches anyObject];\n  CGPoint touchPoint = [touch locationInView:_containerView];\n\n  [self updateSelectionWithPoint:touchPoint];\n}\n\n- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {\n  [super touchesMoved:touches withEvent:event];\n  \n  UITouch* touch = [touches anyObject];\n  CGPoint touchPoint = [touch locationInView:_containerView];\n  \n  [self updateSelectionWithPoint:touchPoint];\n}\n\n#pragma mark - Public\n\n\n- (void)didLoadThumbnail: (UIImage *)image\n                 atIndex: (NSInteger)photoIndex {\n  for (UIImageView* thumbView in _visiblePhotoViews) {\n    if (thumbView.tag == photoIndex) {\n      thumbView.image = image;\n      break;\n    }\n  }\n\n  // Update the selected thumbnail if it's the one that just received a photo.\n  if (_selectedPhotoIndex == photoIndex) {\n    _selectionView.image = image;\n  }\n}\n\n- (void)reloadData {\n  NIDASSERT(nil != _dataSource);\n\n  // Remove any visible photos from the view before we release the sets.\n  for (UIView* photoView in _visiblePhotoViews) {\n    [photoView removeFromSuperview];\n  }\n\n  // If there is no data source then we can't do anything particularly interesting.\n  if (nil == _dataSource) {\n    return;\n  }\n\n  _visiblePhotoViews = [[NSMutableArray alloc] init];\n  _recycledPhotoViews = [[NSMutableSet alloc] init];\n\n  // Cache the number of photos.\n  _numberOfPhotos = [_dataSource numberOfPhotosInScrubberView:self];\n\n  [self setNeedsLayout];\n\n  // This will call layoutIfNeeded and layoutSubviews will then be called because we\n  // set the needsLayout flag.\n  [self updateVisiblePhotos];\n}\n\n- (void)setSelectedPhotoIndex:(NSInteger)photoIndex animated:(BOOL)animated {\n  if (_selectedPhotoIndex != photoIndex) {\n    // Don't animate the selection if it was previously invalid.\n    animated = animated && (_selectedPhotoIndex >= 0);\n\n    _selectedPhotoIndex = photoIndex;\n    \n    if (animated) {\n      [UIView beginAnimations:nil context:nil];\n      [UIView setAnimationDuration:0.2];\n      [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];\n      [UIView setAnimationBeginsFromCurrentState:YES];\n    }\n\n    _selectionView.frame = [self frameForSelectionAtIndex:_selectedPhotoIndex];\n    \n    if (animated) {\n      [UIView commitAnimations];\n    }\n\n    _selectionView.image = [self.dataSource photoScrubberView: self\n                                             thumbnailAtIndex: _selectedPhotoIndex];\n  }\n}\n\n- (void)setSelectedPhotoIndex:(NSInteger)photoIndex {\n  [self setSelectedPhotoIndex:photoIndex animated:NO];\n}\n\n@end\n"
  },
  {
    "path": "src/photos/src/NIToolbarPhotoViewController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPhotoAlbumScrollView.h\"\n#import \"NIPhotoScrubberView.h\"\n\n@class NIPhotoAlbumScrollView;\n\n/**\n * A simple photo album view controller implementation with a toolbar.\n *\n * @ingroup NimbusPhotos\n *\n * This controller does not implement the photo album data source, it simply implements\n * some of the most common UI elements that are associated with a photo viewer.\n *\n * For an example of implementing the data source, see the photos examples in the\n * examples directory.\n *\n * <h2>Implementing Delegate Methods</h2>\n *\n * This view controller already implements NIPhotoAlbumScrollViewDelegate. If you want to\n * implement methods of this delegate you should take care to call the super implementation\n * if necessary. The following methods have implementations in this class:\n *\n * - photoAlbumScrollViewDidScroll:\n * - photoAlbumScrollView:didZoomIn:\n * - photoAlbumScrollViewDidChangePages:\n *\n *\n * <h2>Recommended Configurations</h2>\n *\n * <h3>Default: Zooming enabled with translucent toolbar</h3>\n *\n * The default settings are good for showing a photo album that takes up the entire screen.\n * The photos will be visible beneath the toolbar because it is translucent. The chrome will\n * be hidden whenever the user starts interacting with the photos.\n *\n * @code\n *  toolbarIsTranslucent = YES;\n *  hidesChromeWhenScrolling = YES;\n *  chromeCanBeHidden = YES;\n * @endcode\n *\n * <h3>Zooming disabled with opaque toolbar</h3>\n *\n * The following settings are good for viewing photo albums when you want to keep the chrome\n * visible at all times without zooming enabled.\n *\n * @code\n *  toolbarIsTranslucent = NO;\n *  chromeCanBeHidden = NO;\n *  photoAlbumView.zoomingIsEnabled = NO;\n * @endcode\n */\n@interface NIToolbarPhotoViewController : UIViewController <NIPhotoAlbumScrollViewDelegate, NIPhotoScrubberViewDelegate>\n\n#pragma mark Configuring Functionality\n\n@property (nonatomic, assign, getter=isToolbarTranslucent) BOOL toolbarIsTranslucent; // default: yes\n@property (nonatomic, assign) BOOL hidesChromeWhenScrolling; // default: yes\n@property (nonatomic, assign) BOOL chromeCanBeHidden; // default: yes\n@property (nonatomic, assign) BOOL animateMovingToNextAndPreviousPhotos; // default: no\n@property (nonatomic, assign, getter=isScrubberEnabled) BOOL scrubberIsEnabled; // default: ipad yes - iphone no\n\n#pragma mark Views\n\n@property (nonatomic, readonly, strong) UIToolbar* toolbar;\n@property (nonatomic, readonly, strong) NIPhotoAlbumScrollView* photoAlbumView;\n@property (nonatomic, readonly, strong) NIPhotoScrubberView* photoScrubberView;\n- (void)refreshChromeState;\n\n#pragma mark Toolbar Buttons\n\n@property (nonatomic, readonly, strong) UIBarButtonItem* nextButton;\n@property (nonatomic, readonly, strong) UIBarButtonItem* previousButton;\n\n#pragma mark Subclassing\n\n- (void)setChromeVisibility:(BOOL)isVisible animated:(BOOL)animated;\n- (void)setChromeTitle;\n\n@end\n\n/** @name Configuring Functionality */\n\n/**\n * Whether the toolbar is translucent and shows photos beneath it or not.\n *\n * If this is enabled, the toolbar will be translucent and the photo view will\n * take up the entire view controller's bounds.\n *\n * If this is disabled, the photo will only occupy the remaining space above the\n * toolbar. The toolbar will also not be hidden when the chrome is dismissed. This is by design\n * because dismissing the toolbar when photos can't be displayed beneath it would leave\n * an empty space below the album.\n *\n * By default this is YES.\n *\n * @fn NIToolbarPhotoViewController::toolbarIsTranslucent\n */\n\n/**\n * Whether or not to hide the chrome when the user begins interacting with the photo.\n *\n * If this is enabled, then the chrome will be hidden when the user starts swiping from\n * one photo to another.\n *\n * The chrome is the toolbar and the system status bar.\n *\n * By default this is YES.\n *\n * @attention This will be set to NO if toolbarCanBeHidden is set to NO.\n *\n * @fn NIToolbarPhotoViewController::hidesChromeWhenScrolling\n */\n\n/**\n * Whether or not to allow hiding the chrome.\n *\n * If this is enabled then the user will be able to single-tap to dismiss or show the\n * toolbar.\n *\n * The chrome is the toolbar and the system status bar.\n *\n * If this is disabled then the chrome will always be visible.\n *\n * By default this is YES.\n *\n * @attention Setting this to NO will also disable hidesToolbarWhenScrolling.\n *\n * @fn NIToolbarPhotoViewController::chromeCanBeHidden\n */\n\n/**\n * Whether to animate moving to a next or previous photo when the user taps the button.\n *\n * By default this is NO.\n *\n * @fn NIToolbarPhotoViewController::animateMovingToNextAndPreviousPhotos\n */\n\n/**\n * Whether to show a scrubber in the toolbar instead of next/previous buttons.\n *\n * By default this is YES on the iPad and NO on the iPhone.\n *\n * @fn NIToolbarPhotoViewController::scrubberIsEnabled\n */\n\n\n/** @name Views */\n\n/**\n * The toolbar view.\n *\n * @fn NIToolbarPhotoViewController::toolbar\n */\n\n/**\n * The photo album view.\n *\n * @fn NIToolbarPhotoViewController::photoAlbumView\n */\n\n/**\n * The photo scrubber view.\n *\n * @fn NIToolbarPhotoViewController::photoScrubberView\n */\n\n\n/** @name Toolbar Buttons */\n\n/**\n * The 'next' button.\n *\n * @fn NIToolbarPhotoViewController::nextButton\n */\n\n/**\n * The 'previous' button.\n *\n * @fn NIToolbarPhotoViewController::previousButton\n */\n"
  },
  {
    "path": "src/photos/src/NIToolbarPhotoViewController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIToolbarPhotoViewController.h\"\n\n#import \"NIPhotoAlbumScrollView.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@implementation NIToolbarPhotoViewController {\n  // Views\n  UIToolbar*              _toolbar;\n  NIPhotoAlbumScrollView* _photoAlbumView;\n\n  // Scrubber View\n  NIPhotoScrubberView* _photoScrubberView;\n\n  // Toolbar Buttons\n  UIBarButtonItem* _nextButton;\n  UIBarButtonItem* _previousButton;\n\n  // Gestures\n  UITapGestureRecognizer* _tapGesture;\n\n  // State\n  BOOL _isAnimatingChrome;\n  BOOL _isChromeHidden;\n  BOOL _prefersStatusBarHidden;\n\n  // Configuration\n  BOOL _toolbarIsTranslucent;\n  BOOL _hidesChromeWhenScrolling;\n  BOOL _chromeCanBeHidden;\n  BOOL _animateMovingToNextAndPreviousPhotos;\n  BOOL _scrubberIsEnabled;\n}\n\n\n- (void)shutdown_NIToolbarPhotoViewController {\n  _toolbar = nil;\n  _photoAlbumView = nil;\n  _nextButton = nil;\n  _previousButton = nil;\n  _photoScrubberView = nil;\n  _tapGesture = nil;\n}\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n    // Default Configuration Settings\n    self.toolbarIsTranslucent = YES;\n    self.hidesChromeWhenScrolling = YES;\n    self.chromeCanBeHidden = YES;\n    self.animateMovingToNextAndPreviousPhotos = NO;\n    if ([self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)]) {\n      self.automaticallyAdjustsScrollViewInsets = NO;\n    }\n    \n    // The scrubber is better use of the extra real estate on the iPad.\n    // If you ask me, though, the scrubber works pretty well on the iPhone too. It's up\n    // to you if you want to use it in your own implementations.\n    self.scrubberIsEnabled = NIIsPad();\n\n    // Allow the photos to display beneath the status bar.\n    self.wantsFullScreenLayout = YES;\n  }\n  return self;\n}\n\n- (void)addTapGestureToView {\n  if ([self isViewLoaded]) {\n    if (nil == _tapGesture) {\n      _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap)];\n      [self.photoAlbumView addGestureRecognizer:_tapGesture];\n    }\n  }\n\n  _tapGesture.enabled = YES;\n}\n\n- (void)updateToolbarItems {\n  UIBarItem* flexibleSpace =\n  [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace\n                                                 target: nil\n                                                 action: nil];\n\n  if ([self isScrubberEnabled]) {\n    _nextButton = nil;\n    _previousButton = nil;\n\n    if (nil == _photoScrubberView) {\n      CGRect scrubberFrame = CGRectMake(0, 0,\n                                        self.toolbar.bounds.size.width,\n                                        self.toolbar.bounds.size.height);\n      _photoScrubberView = [[NIPhotoScrubberView alloc] initWithFrame:scrubberFrame];\n      _photoScrubberView.autoresizingMask = (UIViewAutoresizingFlexibleWidth\n                                             | UIViewAutoresizingFlexibleHeight);\n      _photoScrubberView.delegate = self;\n    }\n\n    UIBarButtonItem* scrubberItem =\n    [[UIBarButtonItem alloc] initWithCustomView:self.photoScrubberView];\n    self.toolbar.items = [NSArray arrayWithObjects:\n                          flexibleSpace, scrubberItem, flexibleSpace,\n                          nil];\n\n    [_photoScrubberView setSelectedPhotoIndex:self.photoAlbumView.centerPageIndex];\n    \n  } else {\n    _photoScrubberView = nil;\n\n    if (nil == _nextButton) {\n      UIImage* nextIcon = [UIImage imageWithContentsOfFile:\n                           NIPathForBundleResource(nil, @\"NimbusPhotos.bundle/gfx/next.png\")];\n\n      // We weren't able to find the next or previous icons in your application's resources.\n      // Ensure that you've dragged the NimbusPhotos.bundle from src/photos/resources into your\n      // application with the \"Create Folder References\" option selected. You can verify that\n      // you've done this correctly by expanding the NimbusPhotos.bundle file in your project\n      // and verifying that the 'gfx' directory is blue. Also verify that the bundle is being\n      // copied in the Copy Bundle Resources phase.\n      NIDASSERT(nil != nextIcon);\n\n      _nextButton = [[UIBarButtonItem alloc] initWithImage: nextIcon\n                                                     style: UIBarButtonItemStylePlain\n                                                    target: self\n                                                    action: @selector(didTapNextButton)];\n      \n    }\n\n    if (nil == _previousButton) {\n      UIImage* previousIcon = [UIImage imageWithContentsOfFile:\n                               NIPathForBundleResource(nil, @\"NimbusPhotos.bundle/gfx/previous.png\")];\n\n      // We weren't able to find the next or previous icons in your application's resources.\n      // Ensure that you've dragged the NimbusPhotos.bundle from src/photos/resources into your\n      // application with the \"Create Folder References\" option selected. You can verify that\n      // you've done this correctly by expanding the NimbusPhotos.bundle file in your project\n      // and verifying that the 'gfx' directory is blue. Also verify that the bundle is being\n      // copied in the Copy Bundle Resources phase.\n      NIDASSERT(nil != previousIcon);\n\n      _previousButton = [[UIBarButtonItem alloc] initWithImage: previousIcon\n                                                         style: UIBarButtonItemStylePlain\n                                                        target: self\n                                                        action: @selector(didTapPreviousButton)];\n    }\n\n    self.toolbar.items = [NSArray arrayWithObjects:\n                          flexibleSpace, self.previousButton,\n                          flexibleSpace, self.nextButton,\n                          flexibleSpace,\n                          nil];\n  }\n\n}\n\n- (void)loadView {\n  [super loadView];\n\n  self.view.backgroundColor = [UIColor blackColor];\n\n  CGRect bounds = self.view.bounds;\n\n  // Toolbar Setup\n\n  CGFloat toolbarHeight = NIToolbarHeightForOrientation(NIInterfaceOrientation());\n  CGRect toolbarFrame = CGRectMake(0, bounds.size.height - toolbarHeight,\n                                   bounds.size.width, toolbarHeight);\n\n  _toolbar = [[UIToolbar alloc] initWithFrame:toolbarFrame];\n  _toolbar.barStyle = UIBarStyleBlack;\n  _toolbar.translucent = self.toolbarIsTranslucent;\n  _toolbar.autoresizingMask = (UIViewAutoresizingFlexibleWidth\n                               | UIViewAutoresizingFlexibleTopMargin);\n\n  [self updateToolbarItems];\n\n  // Photo Album View Setup\n\n  CGRect photoAlbumFrame = bounds;\n  if (!self.toolbarIsTranslucent) {\n    photoAlbumFrame = NIRectContract(bounds, 0, toolbarHeight);\n  }\n  _photoAlbumView = [[NIPhotoAlbumScrollView alloc] initWithFrame:photoAlbumFrame];\n  _photoAlbumView.autoresizingMask = (UIViewAutoresizingFlexibleWidth\n                                      | UIViewAutoresizingFlexibleHeight);\n  _photoAlbumView.delegate = self;\n\n  [self.view addSubview:_photoAlbumView];\n  [self.view addSubview:_toolbar];\n\n  if (self.hidesChromeWhenScrolling || self.chromeCanBeHidden) {\n    [self addTapGestureToView];\n  }\n}\n\n- (void)viewWillAppear:(BOOL)animated {\n  [super viewWillAppear:animated];\n\n  [[UIApplication sharedApplication] setStatusBarStyle: (NIIsPad()\n                                                         ? UIStatusBarStyleBlackOpaque\n                                                         : UIStatusBarStyleBlackTranslucent)\n                                              animated: animated];\n\n  UINavigationBar* navBar = self.navigationController.navigationBar;\n  navBar.barStyle = UIBarStyleBlack;\n  navBar.translucent = self.toolbarIsTranslucent;\n\n  _previousButton.enabled = [self.photoAlbumView hasPrevious];\n  _nextButton.enabled = [self.photoAlbumView hasNext];\n}\n\n#if __IPHONE_OS_VERSION_MIN_REQUIRED < NIIOS_6_0\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {\n  return NIIsSupportedOrientation(toInterfaceOrientation);\n}\n#endif\n\n\n- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation\n                                duration: (NSTimeInterval)duration {\n  [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n\n  [self.photoAlbumView willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];\n}\n\n- (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation\n                                         duration: (NSTimeInterval)duration {\n  [self.photoAlbumView willAnimateRotationToInterfaceOrientation: toInterfaceOrientation\n                                                        duration: duration];\n\n  [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation\n                                          duration:duration];\n\n  CGRect toolbarFrame = self.toolbar.frame;\n  toolbarFrame.size.height = NIToolbarHeightForOrientation(toInterfaceOrientation);\n  toolbarFrame.origin.y = self.view.bounds.size.height - toolbarFrame.size.height;\n  self.toolbar.frame = toolbarFrame;\n\n  if (!self.toolbarIsTranslucent) {\n    CGRect photoAlbumFrame = self.photoAlbumView.frame;\n    photoAlbumFrame.size.height = self.view.bounds.size.height - toolbarFrame.size.height;\n    self.photoAlbumView.frame = photoAlbumFrame;\n  }\n}\n\n- (UIView *)rotatingFooterView {\n  return self.toolbar.hidden ? nil : self.toolbar;\n}\n\n- (void)didHideChrome {\n  _isAnimatingChrome = NO;\n  if (self.toolbarIsTranslucent) {\n    self.toolbar.hidden = YES;\n  }\n\n  [self.navigationController setNavigationBarHidden:YES animated:NO];\n  _isChromeHidden = YES;\n}\n\n- (void)didShowChrome {\n  _isAnimatingChrome = NO;\n\n  _isChromeHidden = NO;\n}\n\n- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {\n  return UIStatusBarAnimationSlide;\n}\n\n- (BOOL)prefersStatusBarHidden {\n  return _prefersStatusBarHidden;\n}\n\n- (void)setChromeVisibility:(BOOL)isVisible animated:(BOOL)animated {\n  if (_isAnimatingChrome\n      || (!isVisible && _isChromeHidden)\n      || (isVisible && !_isChromeHidden)\n      || !self.chromeCanBeHidden) {\n    // Nothing to do here.\n    return;\n  }\n\n  CGRect toolbarFrame = self.toolbar.frame;\n  CGRect bounds = self.view.bounds;\n\n  if (self.toolbarIsTranslucent) {\n    // Reset the toolbar's initial position.\n    if (!isVisible) {\n      toolbarFrame.origin.y = bounds.size.height - toolbarFrame.size.height;\n\n    } else {\n      // Ensure that the toolbar is visible through the animation.\n      self.toolbar.hidden = NO;\n\n      toolbarFrame.origin.y = bounds.size.height;\n    }\n    self.toolbar.frame = toolbarFrame;\n  }\n\n  // Show/hide the system chrome.\n  BOOL isStatusBarAppearanceSupported = [self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)];\n  if (!isStatusBarAppearanceSupported) {\n    [[UIApplication sharedApplication] setStatusBarHidden:!isVisible\n                                            withAnimation:(animated\n                                                           ? UIStatusBarAnimationSlide\n                                                           : UIStatusBarAnimationNone)];\n  }\n\n  if (self.toolbarIsTranslucent) {\n    // Place the toolbar at its final location.\n    if (isVisible) {\n      // Slide up.\n      toolbarFrame.origin.y = bounds.size.height - toolbarFrame.size.height;\n\n    } else {\n      // Slide down.\n      toolbarFrame.origin.y = bounds.size.height;\n    }\n  }\n\n  // If there is a navigation bar, place it at its final location.\n  CGRect navigationBarFrame = self.navigationController.navigationBar.frame;\n\n  if (animated) {\n    [UIView beginAnimations:nil context:nil];\n    [UIView setAnimationDelegate:self];\n    [UIView setAnimationDidStopSelector:(isVisible\n                                         ? @selector(didShowChrome)\n                                         : @selector(didHideChrome))];\n\n    // Ensure that the animation matches the status bar's.\n    [UIView setAnimationDuration:NIStatusBarAnimationDuration()];\n    [UIView setAnimationCurve:NIStatusBarAnimationCurve()];\n  }\n\n  if (isStatusBarAppearanceSupported) {\n    _prefersStatusBarHidden = !isVisible;\n    [self setNeedsStatusBarAppearanceUpdate];\n  }\n\n  if (nil != self.navigationController.navigationBar) {\n    if (isVisible) {\n      [UIView setAnimationsEnabled:NO];\n      [self.navigationController setNavigationBarHidden:NO animated:NO];\n      navigationBarFrame.origin.y = 0;\n      self.navigationController.navigationBar.frame = navigationBarFrame;\n      self.navigationController.navigationBar.alpha = 0;\n      [UIView setAnimationsEnabled:YES];\n\n      navigationBarFrame.origin.y = NIStatusBarHeight();\n\n    } else {\n      navigationBarFrame.origin.y = 0;\n    }\n  }\n\n  if (self.toolbarIsTranslucent) {\n    self.toolbar.frame = toolbarFrame;\n  }\n  if (nil != self.navigationController.navigationBar) {\n    self.navigationController.navigationBar.frame = navigationBarFrame;\n    self.navigationController.navigationBar.alpha = (isVisible ? 1 : 0);\n  }\n\n  if (animated) {\n    _isAnimatingChrome = YES;\n    [UIView commitAnimations];\n\n  } else if (!isVisible) {\n    [self didHideChrome];\n\n  } else if (isVisible) {\n    [self didShowChrome];\n  }\n}\n\n- (void)toggleChromeVisibility {\n  [self setChromeVisibility:(_isChromeHidden || _isAnimatingChrome) animated:YES];\n}\n\n#pragma mark - UIGestureRecognizer\n\n\n- (void)didTap {\n  SEL selector = @selector(toggleChromeVisibility);\n  if (self.photoAlbumView.zoomingIsEnabled) {\n    // Cancel any previous delayed performs so that we don't stack them.\n    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:selector object:nil];\n\n    // We need to delay taking action on the first tap in case a second tap comes in, causing\n    // a double-tap gesture to be recognized and the photo to be zoomed.\n    [self performSelector: selector\n               withObject: nil\n               afterDelay: 0.3];\n\n  } else {\n    // When zooming is disabled, double-tap-to-zoom is also disabled so we don't have to\n    // be as careful; just toggle the chrome immediately.\n    [self toggleChromeVisibility];\n  }\n}\n\n- (void)refreshChromeState {\n  self.previousButton.enabled = [self.photoAlbumView hasPrevious];\n  self.nextButton.enabled = [self.photoAlbumView hasNext];\n\n  [self setChromeTitle];\n}\n\n- (void)setChromeTitle {\n  self.title = [NSString stringWithFormat:@\"%ld of %ld\",\n                (long)(self.photoAlbumView.centerPageIndex + 1),\n                (long)self.photoAlbumView.numberOfPages];\n}\n\n#pragma mark - NIPhotoAlbumScrollViewDelegate\n\n\n- (void)pagingScrollViewDidScroll:(NIPagingScrollView *)pagingScrollView {\n  if (self.hidesChromeWhenScrolling) {\n    [self setChromeVisibility:NO animated:YES];\n  }\n}\n\n- (void)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView\n                   didZoomIn: (BOOL)didZoomIn {\n  // This delegate method is called after a double-tap gesture, so cancel any pending\n  // single-tap gestures.\n  [NSObject cancelPreviousPerformRequestsWithTarget: self\n                                           selector: @selector(toggleChromeVisibility)\n                                             object: nil];\n}\n\n- (void)pagingScrollViewDidChangePages:(NIPagingScrollView *)pagingScrollView {\n  // We animate the scrubber when the chrome won't disappear as a nice touch.\n  // We don't bother animating if the chrome disappears when scrolling because the user\n  // will barely see the animation happen.\n  [self.photoScrubberView setSelectedPhotoIndex: [pagingScrollView centerPageIndex]\n                                       animated: !self.hidesChromeWhenScrolling];\n\n  [self refreshChromeState];\n}\n\n#pragma mark - NIPhotoScrubberViewDelegate\n\n\n- (void)photoScrubberViewDidChangeSelection:(NIPhotoScrubberView *)photoScrubberView {\n  [self.photoAlbumView moveToPageAtIndex:photoScrubberView.selectedPhotoIndex animated:NO];\n\n  [self refreshChromeState];\n}\n\n#pragma mark - Actions\n\n\n- (void)didTapNextButton {\n  [self.photoAlbumView moveToNextAnimated:self.animateMovingToNextAndPreviousPhotos];\n  \n  [self refreshChromeState];\n}\n\n- (void)didTapPreviousButton {\n  [self.photoAlbumView moveToPreviousAnimated:self.animateMovingToNextAndPreviousPhotos];\n\n  [self refreshChromeState];\n}\n\n#pragma mark - Public\n\n\n- (void)settoolbarIsTranslucent:(BOOL)enabled {\n  _toolbarIsTranslucent = enabled;\n\n  self.toolbar.translucent = enabled;\n}\n\n- (void)setHidesChromeWhenScrolling:(BOOL)hidesToolbar {\n  _hidesChromeWhenScrolling = hidesToolbar;\n\n  if (hidesToolbar) {\n    [self addTapGestureToView];\n\n  } else {\n    [_tapGesture setEnabled:_chromeCanBeHidden];\n  }\n}\n\n- (void)setChromeCanBeHidden:(BOOL)canBeHidden {\n  _chromeCanBeHidden = canBeHidden;\n\n  if (canBeHidden) {\n    [self addTapGestureToView];\n\n  } else {\n    self.hidesChromeWhenScrolling = NO;\n\n    if ([self isViewLoaded]) {\n      // Ensure that the chrome is visible.\n      [self setChromeVisibility:YES animated:NO];\n    }\n  }\n}\n\n- (void)setScrubberIsEnabled:(BOOL)enabled {\n  if (_scrubberIsEnabled != enabled) {\n    _scrubberIsEnabled = enabled;\n\n    if ([self isViewLoaded]) {\n      [self updateToolbarItems];\n    }\n  }\n}\n\n@end\n"
  },
  {
    "path": "src/photos/src/NimbusPhotos.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * @defgroup NimbusPhotos Nimbus Photos\n * @{\n *\n * <div id=\"github\" feature=\"photos\"></div>\n *\n * Photo viewers are a common, non-trivial feature in many types of iOS apps ranging from\n * simple photo viewers to apps that fetch photos from an API. The Nimbus photo album viewer\n * is designed to consume minimal amounts of memory and encourage the use of threads to provide\n * a high quality user experience that doesn't include any blocking of the UI while images\n * are loaded from disk or the network. The photo viewer pre-caches images in an album to either\n * side of the current image so that the user will ideally always have a high-quality\n * photo experience.\n *\n * <h2>Adding the Photos Feature to Your Application</h2>\n *\n * The Nimbus Photos feature uses a small number of custom photos that are stored in the\n * NimbusPhotos bundle. You must add this bundle to your application, ensuring that you select\n * the \"Create Folder References\" option and that the bundle is copied in the\n * \"Copy Bundle Resources\" phase.\n *\n * The bundle can be found at <code>src/photos/resources/NimbusPhotos.bundle</code>.\n *\n *\n * <h2>Feature Breakdown</h2>\n *\n * NIPhotoAlbumScrollView - A paged scroll view that implements a data source similar to that\n * of UITableView. This scroll view consumes minimal amounts of memory and is built to be fast\n * and responsive.\n *\n * NIPhotoScrollView - A single page within the NIPhotoAlbumScrollView. This view implements\n * the zooming and rotation functionality for a photo.\n *\n * NIPhotoScrubberView - A scrubber view for skimming through a set of photos. This view\n * made its debut by Apple on the iPad in Photos.app. Nimbus' implementation of this view\n * is built to be responsive and consume little memory.\n *\n * NIToolbarPhotoViewController - A skeleton implementation of a view controller that includes\n * multiple configurable properties. This controller will show a scrubber on the iPad and\n * next/previous arrows on the iPhone. It also provides support for hiding and showing the\n * app's chrome. If you wish to use this controller you must simply implement the data source\n * for the photo album. NetworkPhotoAlbum in the examples/photos directory demos building\n * a data source that fetches its information from the network.\n *\n *\n * <h2>Architecture</h2>\n *\n * The architectural design of the photo album view takes inspiration from UITableView. Images\n * are requested only when they might become visible and are released when they become\n * inaccessible again. Each page of the photo album view is a recycled NIPhotoScrollView.\n * These page views handle zooming and panning within a given photo. The photo album view\n * NIPhotoAlbumScrollView contains a paging scroll view of these page views and provides\n * interfaces for maintaining the orientation during rotations.\n *\n * The view controller NIToolbarPhotoViewController is provided as a basic implementation of\n * functionality that is expected from a photo viewer. This includes: a toolbar with next and\n * previous arrows; auto-rotation support; and toggling the chrome.\n *\n * <h3>NIPhotoAlbumScrollView</h3>\n *\n * NIPhotoAlbumScrollView is the meat of the Nimbus photo viewer's functionality. Contained\n * within this view are pages of NIPhotoScrollView views. In your view controller you are\n * expected to implement the NIPhotoAlbumScrollViewDataSource in order to provide the photo\n * album view with the necessary information for presenting an album.\n *\n *\n * <h2>Example Applications</h2>\n *\n * <h3>Network Photo Albums</h3>\n *\n * <a href=\"https://github.com/jverkoey/nimbus/tree/master/examples/photos/NetworkPhotoAlbums\">View the README on GitHub</a>\n *\n * This sample application demos the use of the multiple photo APIs to fetch photos from public\n * photo album and display them in high-definition on the iPad and iPhone.\n *\n * The following APIs are currently demoed:\n *\n * - Facebook Graph API\n * - Dribbble Shots\n *\n * Sample location: <code>examples/photos/NetworkPhotoAlbums</code>\n *\n *\n * <h2>Screenshots</h2>\n *\n * @image html photos-iphone-example1.png \"Screenshot of a basic photo album on the iPhone.\"\n *\n * Image source: <a href=\"http://www.flickr.com/photos/janekm/360669001/\">flickr.com/photos/janekm/360669001</a>\n */\n\n/**@}*/\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPhotoAlbumScrollView.h\"\n#import \"NIPhotoAlbumScrollViewDataSource.h\"\n#import \"NIPhotoAlbumScrollViewDelegate.h\"\n#import \"NIPhotoScrollView.h\"\n#import \"NIPhotoScrollViewDelegate.h\"\n#import \"NIPhotoScrollViewPhotoSize.h\"\n\n#import \"NimbusPagingScrollView.h\"\n#import \"NimbusCore.h\"\n"
  },
  {
    "path": "src/photos/unittests/NIPhotoScrollViewTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusPhotos.h\"\n\n@interface NIPhotoScrollViewTests : XCTestCase\n@end\n\n\n@implementation NIPhotoScrollViewTests\n\n\n- (void)testNothing {\n}\n\n@end\n"
  },
  {
    "path": "src/photos/unittests/NimbusPhotosTests-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>English</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>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/resources/lib.xcconfig",
    "content": "//\n// Copyright 2011-2012 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\nGCC_GENERATE_TEST_COVERAGE_FILES=NO\nGCC_INSTRUMENT_PROGRAM_FLOW_ARCS=NO\n"
  },
  {
    "path": "src/resources/unittest.xcconfig",
    "content": "//\n// Copyright 2011-2012 Jeff Verkoeyen\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\nOTHER_LDFLAGS=-ObjC\nTEST_AFTER_BUILD=YES\n"
  },
  {
    "path": "src/textfield/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\n"
  },
  {
    "path": "src/textfield/src/NITextField.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally written by Max Metral\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n/**\n * UITextField leaves a little to be desired on the visual customization front.\n * NITextField attempts to solve the most basic of those gaps so that\n * the CSS subsystem can function properly.\n */\n@interface NITextField : UITextField\n\n/**\n * If non-nil, this color will be used to draw the placeholder text.\n * If nil, we will use the system default.\n */\n@property (nonatomic, strong) UIColor* placeholderTextColor;\n\n/**\n * If non-nil, this font will be used to draw the placeholder text.\n * else the text field font will be used.\n */\n@property (nonatomic, strong) UIFont* placeholderFont;\n\n/**\n * The amount to inset the text by, or zero to use default behavior\n */\n@property (nonatomic, assign) UIEdgeInsets textInsets;\n\n@end\n"
  },
  {
    "path": "src/textfield/src/NITextField.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n// Originally written by Max Metral\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NITextField.h\"\n\n@implementation NITextField\n\n- (void)drawPlaceholderInRect:(CGRect)rect {\n  if (self.placeholderTextColor != nil || self.placeholderFont != nil) {\n    CGContextRef cx = UIGraphicsGetCurrentContext();\n    CGContextSaveGState(cx);\n\n    if (self.placeholderTextColor) {\n      [self.placeholderTextColor setFill];\n    }\n\n    [self.placeholder drawInRect:rect\n                        withFont:(self.placeholderFont != nil ? self.placeholderFont : self.font)\n                   lineBreakMode:NSLineBreakByClipping\n                       alignment:self.textAlignment];\n\n    CGContextRestoreGState(cx);\n\n  } else {\n    [super drawPlaceholderInRect:rect];\n  }\n}\n\n- (CGRect)editingRectForBounds:(CGRect)bounds {\n  if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, self.textInsets)) {\n    return [super editingRectForBounds:bounds];\n  }\n  return UIEdgeInsetsInsetRect(bounds, self.textInsets);\n}\n\n- (CGRect)textRectForBounds:(CGRect)bounds {\n  if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, self.textInsets)) {\n    return [super textRectForBounds:bounds];\n  }\n  return UIEdgeInsetsInsetRect(bounds, self.textInsets);\n}\n\n@end\n"
  },
  {
    "path": "src/webcontroller/deps",
    "content": "core\n\n[Frameworks]\nFoundation.framework\nUIKit.framework\n"
  },
  {
    "path": "src/webcontroller/src/NIWebController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 July 29, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NIPreprocessorMacros.h\" /* for weak */\n\n/**\n * A simple web view controller implementation with a toolbar.\n *\n * <h2>Subclassing</h2>\n *\n * This view controller implements UIWebViewDelegate. If you want to\n * implement methods of this delegate then you should take care to call the super implementation\n * if necessary. The following UIViewWebDelegate methods have implementations in this class:\n *\n * @code\n * - webView:shouldStartLoadWithRequest:navigationType:\n * - webViewDidStartLoad:\n * - webViewDidFinishLoad:\n * - webView:didFailLoadWithError:\n * @endcode\n *\n * This view controller also implements UIActionSheetDelegate. If you want to implement methods of\n * this delegate then you should take care to call the super implementation if necessary. The\n * following UIActionSheetDelegate methods have implementations in this class:\n *\n * @code\n * - actionSheet:clickedButtonAtIndex:\n * - actionSheet:didDismissWithButtonIndex:\n * @endcode\n *\n * In addition to the above methods of the UIActionSheetDelegate, this view controller also provides\n * the following method, which is invoked prior to presenting the internal action sheet to the user\n * and allows subclasses to customize the action sheet or even reject to display it (and provide their\n * own handling instead):\n *\n * @code\n * - shouldPresentActionSheet:\n * @endcode\n *\n *\n * <h2>Recommended Configurations</h2>\n *\n * <h3>Default</h3>\n *\n * The default settings will create a toolbar with the default tint color, which is normally\n * light blue on the iPhone and gray on the iPad.\n *\n *\n * <h3>Colored Toolbar</h3>\n *\n * The following settings will change the toolbar tint color (in this case black)\n *\n * @code\n *  [webController setToolbarTintColor:[UIColor blackColor]];\n * @endcode\n *\n * @ingroup NimbusWebController\n */\n__deprecated_msg(\"No longer supported; please use WKWebView instead. This API will eventually be deleted.\")\n@interface NIWebController : UIViewController <UIWebViewDelegate, UIActionSheetDelegate>\n\n// Designated initializer.\n- (id)initWithRequest:(NSURLRequest *)request;\n- (id)initWithURL:(NSURL *)URL;\n\n- (NSURL *)URL;\n\n- (void)openURL:(NSURL*)URL;\n- (void)openRequest:(NSURLRequest*)request;\n- (void)openHTMLString:(NSString*)htmlString baseURL:(NSURL*)baseUrl;\n\n@property (nonatomic, readonly, strong) UIToolbar* toolbar;\n@property (nonatomic, assign, getter = isToolbarHidden) BOOL toolbarHidden;\n@property (nonatomic, weak) UIColor* toolbarTintColor;\n\n@property (nonatomic, readonly, strong) UIWebView* webView;\n\n// Subclassing\n- (BOOL)shouldPresentActionSheet:(UIActionSheet *)actionSheet;\n@property (nonatomic, strong) NSURL* actionSheetURL;\n\n@end\n\n/** @name Creating a Web Controller */\n\n/**\n * Initializes a newly allocated web controller with a given request.\n *\n * Once the controller is presented it will begin loading the given request.\n *\n * This is the designated initializer.\n *\n * @fn NIWebController::initWithRequest:\n */\n\n/**\n * Initializes a newly allocated web controller with a given URL to request.\n *\n * Once the controller is presented it will begin loading the given URL.\n *\n * @fn NIWebController::initWithURL:\n */\n\n/** @name Accessing the Request Attributes */\n\n/**\n * The current web view URL.\n *\n * If the web view is currently loading a URL then the loading URL is returned.\n * Otherwise this will be the last URL that was loaded.\n *\n * @fn NIWebController::URL:\n */\n\n/** @name Loading a Request */\n\n/**\n * Loads a request with the given URL in the web view.\n *\n * @fn NIWebController::openURL:\n */\n\n/**\n * Load the given request using UIWebView's loadRequest:.\n *\n * @param request  A URL request identifying the location of the content to load.\n *\n * @fn NIWebController::openRequest:\n */\n\n/**\n * Load the given request using UIWebView's loadHTMLString:baseURL:.\n *\n * @param htmlString  The content for the main page.\n * @param baseUrl  The base URL for the content.\n *\n * @fn NIWebController::openHTMLString:baseURL:\n */\n\n/** @name Accessing the Toolbar */\n\n/**\n * The toolbar.\n *\n * @fn NIWebController::toolbar\n */\n\n/**\n * The visibility of the toolbar.\n *\n * If the toolbar is hidden then the web view will take up the controller's entire view.\n *\n * @fn NIWebController::toolbarHidden\n */\n\n/**\n * The tint color of the toolbar.\n *\n * @fn NIWebController::toolbarTintColor\n */\n\n/** @name Accessing the Web View */\n\n/**\n * The internal web view.\n *\n * @fn NIWebController::webView\n */\n\n/** @name Subclassing the Web Controller */\n\n/**\n * This message is called in response to the user clicking the action toolbar button.\n *\n * You can provide your own implementation in your subclass and customize the actionSheet\n * that is shown to the user or even cancel the presentation of the @c actionSheet by\n * returning NO from your implementation.\n *\n * @param actionSheet The UIActionSheet that will be presented to the user.\n * @return YES to present the actionSheet, NO if you want to perform a custom action.\n * @fn NIWebController::shouldPresentActionSheet:\n */\n"
  },
  {
    "path": "src/webcontroller/src/NIWebController.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Forked from Three20 July 29, 2011 - Copyright 2009-2011 Facebook\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"NIWebController.h\"\n\n#import \"NimbusCore.h\"\n\n#if !defined(__has_feature) || !__has_feature(objc_arc)\n#error \"Nimbus requires ARC support.\"\n#endif\n\n@interface NIWebController()\n@property (nonatomic, strong) UIWebView* webView;\n@property (nonatomic, strong) UIToolbar* toolbar;\n@property (nonatomic, strong) UIActionSheet* actionSheet;\n\n@property (nonatomic, strong) UIBarButtonItem* backButton;\n@property (nonatomic, strong) UIBarButtonItem* forwardButton;\n@property (nonatomic, strong) UIBarButtonItem* refreshButton;\n@property (nonatomic, strong) UIBarButtonItem* stopButton;\n@property (nonatomic, strong) UIBarButtonItem* actionButton;\n@property (nonatomic, strong) UIBarButtonItem* activityItem;\n\n@property (nonatomic, strong) NSURL* loadingURL;\n\n@property (nonatomic, strong) NSURLRequest* loadRequest;\n@end\n\n@implementation NIWebController\n\n\n\n- (void)dealloc {\n  _actionSheet.delegate = nil;\n  _webView.delegate = nil;\n}\n\n- (id)initWithRequest:(NSURLRequest *)request {\n  if ((self = [super initWithNibName:nil bundle:nil])) {\n    self.hidesBottomBarWhenPushed = YES;\n\n    if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {\n      self.edgesForExtendedLayout = UIRectEdgeNone;\n    }\n\n    [self openRequest:request];\n  }\n  return self;\n}\n\n- (id)initWithURL:(NSURL *)URL {\n  return [self initWithRequest:[NSURLRequest requestWithURL:URL]];\n}\n\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  return [self initWithRequest:nil];\n}\n\n#pragma mark - Private\n\n\n- (void)didTapBackButton {\n  [self.webView goBack];\n}\n\n- (void)didTapForwardButton {\n  [self.webView goForward];\n}\n\n- (void)didTapRefreshButton {\n  [self.webView reload];\n}\n\n- (void)didTapStopButton {\n  [self.webView stopLoading];\n}\n\n- (void)didTapShareButton {\n  // Dismiss the action menu if the user taps the action button again on the iPad.\n  if ([self.actionSheet isVisible]) {\n    // It shouldn't be possible to tap the share action button again on anything but the iPad.\n    NIDASSERT(NIIsPad());\n\n    [self.actionSheet dismissWithClickedButtonIndex:[self.actionSheet cancelButtonIndex] animated:YES];\n\n    // We remove the action sheet here just in case the delegate isn't properly implemented.\n    self.actionSheet.delegate = nil;\n    self.actionSheet = nil;\n    self.actionSheetURL = nil;\n\n    // Don't show the menu again.\n    return;\n  }\n\n  // Remember the URL at this point\n  self.actionSheetURL = [self.URL copy];\n\n  if (nil == self.actionSheet) {\n    self.actionSheet =\n    [[UIActionSheet alloc] initWithTitle:[self.actionSheetURL absoluteString]\n                                delegate:self\n                       cancelButtonTitle:nil\n                  destructiveButtonTitle:nil\n                       otherButtonTitles:nil];\n\n    // Let -shouldPresentActionSheet: setup the action sheet\n    if (![self shouldPresentActionSheet:self.actionSheet] || self.actionSheet.numberOfButtons == 0) {\n      // A subclass decided to handle the action in another way\n      self.actionSheet = nil;\n      self.actionSheetURL = nil;\n      return;\n    }\n    // Add \"Cancel\" button except for iPads\n    if (!NIIsPad()) {\n      [self.actionSheet setCancelButtonIndex:[self.actionSheet addButtonWithTitle:NSLocalizedString(@\"Cancel\", @\"\")]];\n    }\n  }\n\n  if (NIIsPad()) {\n    [self.actionSheet showFromBarButtonItem:self.actionButton animated:YES];\n  } else {\n    [self.actionSheet showInView:self.view];\n  }\n}\n\n- (void)updateToolbarWithOrientation:(UIInterfaceOrientation)interfaceOrientation {\n  if (!self.toolbarHidden) {\n    CGRect toolbarFrame = self.toolbar.frame;\n    toolbarFrame.size.height = NIToolbarHeightForOrientation(interfaceOrientation);\n    toolbarFrame.origin.y = self.view.bounds.size.height - toolbarFrame.size.height;\n    self.toolbar.frame = toolbarFrame;\n\n    CGRect webViewFrame = self.webView.frame;\n    webViewFrame.size.height = self.view.bounds.size.height - toolbarFrame.size.height;\n    self.webView.frame = webViewFrame;\n\n  } else {\n    self.webView.frame = self.view.bounds;\n  }\n}\n\n#pragma mark - UIViewController\n\n\n- (void)updateWebViewFrame {\n  if (self.toolbarHidden) {\n    self.webView.frame = self.view.bounds;\n    \n  } else {\n    self.webView.frame = NIRectContract(self.view.bounds, 0, self.toolbar.frame.size.height);\n  }\n}\n\n- (void)loadView {\n  [super loadView];\n\n  CGRect bounds = self.view.bounds;\n\n  CGFloat toolbarHeight = NIToolbarHeightForOrientation(NIInterfaceOrientation());\n  CGRect toolbarFrame = CGRectMake(0, bounds.size.height - toolbarHeight,\n                                   bounds.size.width, toolbarHeight);\n\n  self.toolbar = [[UIToolbar alloc] initWithFrame:toolbarFrame];\n  self.toolbar.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin\n                               | UIViewAutoresizingFlexibleWidth);\n  self.toolbar.tintColor = self.toolbarTintColor;\n  self.toolbar.hidden = self.toolbarHidden;\n\n  UIActivityIndicatorView* spinner =\n  [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:\n    UIActivityIndicatorViewStyleWhite];\n  [spinner startAnimating];\n  self.activityItem = [[UIBarButtonItem alloc] initWithCustomView:spinner];\n\n  UIImage* backIcon = [UIImage imageWithContentsOfFile:\n                      NIPathForBundleResource(nil, @\"NimbusWebController.bundle/gfx/backIcon.png\")];\n  // We weren't able to find the forward or back icons in your application's resources.\n  // Ensure that you've dragged the NimbusWebController.bundle from src/webcontroller/resources\n  //into your application with the \"Create Folder References\" option selected. You can verify that\n  // you've done this correctly by expanding the NimbusPhotos.bundle file in your project\n  // and verifying that the 'gfx' directory is blue. Also verify that the bundle is being\n  // copied in the Copy Bundle Resources phase.\n  NIDASSERT(nil != backIcon);\n\n  self.backButton =\n  [[UIBarButtonItem alloc] initWithImage:backIcon\n                                   style:UIBarButtonItemStylePlain\n                                  target:self\n                                  action:@selector(didTapBackButton)];\n  self.backButton.tag = 2;\n  self.backButton.enabled = NO;\n\n  UIImage* forwardIcon = [UIImage imageWithContentsOfFile:\n                  NIPathForBundleResource(nil, @\"NimbusWebController.bundle/gfx/forwardIcon.png\")];\n  // We weren't able to find the forward or back icons in your application's resources.\n  // Ensure that you've dragged the NimbusWebController.bundle from src/webcontroller/resources\n  // into your application with the \"Create Folder References\" option selected. You can verify that\n  // you've done this correctly by expanding the NimbusPhotos.bundle file in your project\n  // and verifying that the 'gfx' directory is blue. Also verify that the bundle is being\n  // copied in the Copy Bundle Resources phase.\n  NIDASSERT(nil != forwardIcon);\n\n  self.forwardButton =\n  [[UIBarButtonItem alloc] initWithImage:forwardIcon\n                                   style:UIBarButtonItemStylePlain\n                                  target:self\n                                  action:@selector(didTapForwardButton)];\n  self.forwardButton.tag = 1;\n  self.forwardButton.enabled = NO;\n  self.refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:\n                    UIBarButtonSystemItemRefresh target:self action:@selector(didTapRefreshButton)];\n  self.refreshButton.tag = 3;\n  self.stopButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:\n                 UIBarButtonSystemItemStop target:self action:@selector(didTapStopButton)];\n  self.stopButton.tag = 3;\n  self.actionButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:\n                   UIBarButtonSystemItemAction target:self action:@selector(didTapShareButton)];\n\n  UIBarItem* flexibleSpace =\n  [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace\n                                                 target: nil\n                                                 action: nil];\n\n  self.toolbar.items = [NSArray arrayWithObjects:\n                    self.backButton,\n                    flexibleSpace,\n                    self.forwardButton,\n                    flexibleSpace,\n                    self.refreshButton,\n                    flexibleSpace,\n                    self.actionButton,\n                    nil];\n\n  self.webView = [[UIWebView alloc] initWithFrame:CGRectZero];\n  [self updateWebViewFrame];\n  self.webView.delegate = self;\n  self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth\n                               | UIViewAutoresizingFlexibleHeight);\n  self.webView.scalesPageToFit = YES;\n\n  [self.view addSubview:self.webView];\n  [self.view addSubview:self.toolbar];\n\n  if (nil != self.loadRequest) {\n    [self.webView loadRequest:self.loadRequest];\n  }\n}\n\n- (void)viewWillAppear:(BOOL)animated {\n  [super viewWillAppear:animated];\n\n  [self updateToolbarWithOrientation:self.interfaceOrientation];\n}\n\n- (void)viewWillDisappear:(BOOL)animated {\n  // If the browser launched the media player, it steals the key window and never gives it\n  // back, so this is a way to try and fix that.\n  [self.view.window makeKeyWindow];\n\n  [super viewWillDisappear:animated];\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n  return NIIsPad() ? UIInterfaceOrientationMaskAll : UIInterfaceOrientationMaskAllButUpsideDown;\n}\n\n- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation\n                                         duration:(NSTimeInterval)duration {\n  [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];\n  [self updateToolbarWithOrientation:toInterfaceOrientation];\n}\n\n#pragma mark - UIWebViewDelegate\n\n\n- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {\n  self.loadingURL = [request.mainDocumentURL copy];\n  self.backButton.enabled = [self.webView canGoBack];\n  self.forwardButton.enabled = [self.webView canGoForward];\n  return YES;\n}\n\n- (void)webViewDidStartLoad:(UIWebView*)webView {\n  self.title = NSLocalizedString(@\"Loading...\", @\"\");\n  if (!self.navigationItem.rightBarButtonItem) {\n    [self.navigationItem setRightBarButtonItem:self.activityItem animated:YES];\n  }\n\n  NSInteger buttonIndex = 0;\n  for (UIBarButtonItem* button in self.toolbar.items) {\n    if (button.tag == 3) {\n      NSMutableArray* newItems = [NSMutableArray arrayWithArray:self.toolbar.items];\n      [newItems replaceObjectAtIndex:buttonIndex withObject:self.stopButton];\n      self.toolbar.items = newItems;\n      break;\n    }\n    ++buttonIndex;\n  }\n  self.backButton.enabled = [self.webView canGoBack];\n  self.forwardButton.enabled = [self.webView canGoForward];\n}\n\n- (void)webViewDidFinishLoad:(UIWebView*)webView {\n  self.loadingURL = nil;\n  self.title = [self.webView stringByEvaluatingJavaScriptFromString:@\"document.title\"];\n  if (self.navigationItem.rightBarButtonItem == self.activityItem) {\n    [self.navigationItem setRightBarButtonItem:nil animated:YES];\n  }\n\n  NSInteger buttonIndex = 0;\n  for (UIBarButtonItem* button in self.toolbar.items) {\n    if (button.tag == 3) {\n      NSMutableArray* newItems = [NSMutableArray arrayWithArray:self.toolbar.items];\n      [newItems replaceObjectAtIndex:buttonIndex withObject:self.refreshButton];\n      self.toolbar.items = newItems;\n      break;\n    }\n    ++buttonIndex;\n  }\n\n  self.backButton.enabled = [self.webView canGoBack];\n  self.forwardButton.enabled = [self.webView canGoForward];\n}\n\n- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error {\n  self.loadingURL = nil;\n  [self webViewDidFinishLoad:webView];\n}\n\n#pragma mark - UIActionSheetDelegate\n\n\n- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {\n  if (actionSheet == self.actionSheet) {\n    if (buttonIndex == 0) {\n      [[UIApplication sharedApplication] openURL:self.actionSheetURL];\n    } else if (buttonIndex == 1) {\n      [[UIPasteboard generalPasteboard] setURL:self.actionSheetURL];\n    }\n  }\n}\n\n- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {\n  if (actionSheet == self.actionSheet) {\n    self.actionSheet.delegate = nil;\n    self.actionSheet = nil;\n    self.actionSheetURL = nil;\n  }\n}\n\n#pragma mark - Public\n\n\n- (NSURL *)URL {\n  return self.loadingURL ? self.loadingURL : self.webView.request.mainDocumentURL;\n}\n\n- (void)openURL:(NSURL*)URL {\n  NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:URL];\n  [self openRequest:request];\n}\n\n- (void)openRequest:(NSURLRequest *)request {\n  self.loadRequest = request;\n\n  if ([self isViewLoaded]) {\n    if (nil != request) {\n      [self.webView loadRequest:request];\n\n    } else {\n      [self.webView stopLoading];\n    }\n  }\n}\n\n- (void)openHTMLString:(NSString*)htmlString baseURL:(NSURL*)baseUrl {\n\tNIDASSERT([self isViewLoaded]);\n\t[_webView loadHTMLString:htmlString baseURL:baseUrl];\n}\n\n- (void)setToolbarHidden:(BOOL)hidden {\n  _toolbarHidden = hidden;\n  if ([self isViewLoaded]) {\n    self.toolbar.hidden = hidden;\n    [self updateWebViewFrame];\n  }\n}\n\n- (void)setToolbarTintColor:(UIColor*)color {\n  if (color != _toolbarTintColor) {\n    _toolbarTintColor = color;\n  }\n\n  if ([self isViewLoaded]) {\n    self.toolbar.tintColor = color;\n  }\n}\n\n- (BOOL)shouldPresentActionSheet:(UIActionSheet *)actionSheet {\n  if (actionSheet == self.actionSheet && nil != self.actionSheetURL) {\n    [self.actionSheet addButtonWithTitle:NSLocalizedString(@\"Open in Safari\", @\"\")];\n    [self.actionSheet addButtonWithTitle:NSLocalizedString(@\"Copy URL\", @\"\")];\n  }\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "src/webcontroller/src/NimbusWebController.h",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * @defgroup NimbusWebController Nimbus Web Controller\n * @{\n *\n * <div id=\"github\" feature=\"webcontroller\"></div>\n *\n * This controller presents a UIWebView with a toolbar containing basic chrome for interacting\n * with it. The chrome shows forward, back, stop and refresh buttons on a toolbar aligned\n * to the bottom of the view controller's view. The toolbar includes an option to open the\n * URL in Safari. If the controller is shown in a navigation controller, self.title will\n * show the current web page's title. A spinner will be shown in the navigation bar's right\n * bar button area if there are any active requests.\n *\n * @image html webcontroller-iphone-example1.png \"Screenshot of a basic web controller on the iPhone\"\n *\n * <h2>Minimum Requirements</h2>\n *\n * Required frameworks:\n *\n * - Foundation.framework\n * - UIKit.framework\n *\n * Minimum Operating System: <b>iOS 4.0</b>\n *\n * Source located in <code>src/webcontroller/src</code>\n *\n * <h2>Adding the Web Controller to Your Application</h2>\n *\n * The web controller uses a small number of custom icons that are stored in the NimbusWebController\n * bundle. You must add this bundle to your application, ensuring that you select the \"Create Folder\n * References\" option and that the bundle is copied in the \"Copy Bundle Resources\" phase.\n *\n * The bundle can be found at <code>src/webcontroller/resources/NimbusWebController.bundle</code>.\n *\n * @}*/\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#import \"NimbusCore.h\"\n#import \"NIWebController.h\"\n"
  },
  {
    "path": "src/webcontroller/unittests/NIWebControllerTests.m",
    "content": "//\n// Copyright 2011-2014 NimbusKit\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// See: http://bit.ly/hS5nNh for unit test macros.\n\n#import <XCTest/XCTest.h>\n\n#import \"NimbusWebController.h\"\n\n@interface NIWebControllerTests : XCTestCase\n@end\n\n\n@implementation NIWebControllerTests\n\n\n- (void)testNothing {\n}\n\n@end\n"
  },
  {
    "path": "src/webcontroller/unittests/NimbusWebControllerTests-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": "templates/install",
    "content": "#!/bin/bash\n#\n# Copyright 2011 Jeff Verkoeyen\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\necho \"Nimbus template installer\"\n\nXCODE3_BASE_TEMPLATE_DIR=\"$HOME/Library/Application Support/Developer/Shared/Xcode\"\nXCODE4_BASE_TEMPLATE_DIR=\"$HOME/Library/Developer/Xcode/Templates\"\n\n\n# Installs the xcode 3 project templates. Overwrites any existing files.\ncopy_xcode3_project_templates(){\n\techo \"Installing xcode 3 project templates\"\n\tTEMPLATE_DIR=\"${XCODE3_BASE_TEMPLATE_DIR}/Project Templates/Nimbus Application\"\n\tmkdir -p \"${TEMPLATE_DIR}\"\n\tcp -r xcode3/projects/ \"${TEMPLATE_DIR}\"\n}\n\n# Installs the xcode 3 source templates. Overwrites any existing files.\ncopy_xcode3_file_templates(){\n\techo \"Installing xcode 3 file templates\"\n\tTEMPLATE_DIR=\"${XCODE3_BASE_TEMPLATE_DIR}/File Templates\"\n\tmkdir -p \"${TEMPLATE_DIR}\"\n\tcp -r xcode3/source/ \"${TEMPLATE_DIR}\"\n}\n\n# Installs the xcode 4 project templates. Overwrites any existing files.\ncopy_xcode4_project_templates(){\n\techo \"Installing xcode 4 project templates\"\n\tTEMPLATE_DIR=\"${XCODE4_BASE_TEMPLATE_DIR}/Project Templates/Nimbus Application\"\n\tmkdir -p \"${TEMPLATE_DIR}\"\n\tcp -r xcode4/projects/ \"${TEMPLATE_DIR}\"\n}\n\ncopy_xcode3_project_templates\ncopy_xcode3_file_templates\ncopy_xcode4_project_templates\n\n#mkdir -p ~/Library/Application\\ Support/Developer/Shared/Xcode/Project\\ Templates/Nimbus\\ Application\n#cp -r projects/ ~/Library/Application\\ Support/Developer/Shared/Xcode/Project\\ Templates/Nimbus\\ Application\n\n# Installs the source templates. Overwrites any existing files.\n\n#mkdir -p ~/Library/Application\\ Support/Developer/Shared/Xcode/File\\ Templates\n#cp -r source/ ~/Library/Application\\ Support/Developer/Shared/Xcode/File\\ Templates\n"
  },
  {
    "path": "templates/xcode3/projects/Skeleton App/Skeleton App (Apache 2.0 Licensed)/___PROJECTNAME___.xcodeproj/TemplateInfo.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>Description</key>\n\t<string>This is a simple skeleton application licensed under the Apache 2.0 open source license. It programmatically sets up the UIWindow, does not use nibs, and only has one entry point for both the iPhone and iPad.</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "templates/xcode3/projects/Skeleton App/Skeleton App (Apache 2.0 Licensed)/___PROJECTNAME___.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 45;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };\n\t\t1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };\n\t\t288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; };\n\t\t66EA058313C011D6004FFE1A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 66EA058113C011D6004FFE1A /* AppDelegate.m */; };\n\t\t66EA058813C011EC004FFE1A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 66EA058713C011EC004FFE1A /* main.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };\n\t\t1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ___PROJECTNAME___.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };\n\t\t288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };\n\t\t66EA058013C011D6004FFE1A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = src/AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t66EA058113C011D6004FFE1A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = src/AppDelegate.m; sourceTree = \"<group>\"; };\n\t\t66EA058213C011D6004FFE1A /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ___PROJECTNAMEASIDENTIFIER____Prefix.pch; path = src/___PROJECTNAMEASIDENTIFIER____Prefix.pch; sourceTree = \"<group>\"; };\n\t\t66EA058713C011EC004FFE1A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = src/main.m; sourceTree = \"<group>\"; };\n\t\t66EA05A213C01297004FFE1A /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = \"___PROJECTNAMEASIDENTIFIER___-Info.plist\"; path = \"resources/___PROJECTNAMEASIDENTIFIER___-Info.plist\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t1D60588F0D05DD3D006BFB54 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,\n\t\t\t\t1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,\n\t\t\t\t288765FD0DF74451002DB57D /* CoreGraphics.framework 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\t19C28FACFE9D520D11CA2CBB /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66EA058213C011D6004FFE1A /* ___PROJECTNAMEASIDENTIFIER____Prefix.pch */,\n\t\t\t\t66EA057A13C011C0004FFE1A /* Source */,\n\t\t\t\t66EA058E13C0126F004FFE1A /* Nimbus */,\n\t\t\t\t66EA059D13C0128E004FFE1A /* Resources */,\n\t\t\t\t29B97323FDCFA39411CA2CEA /* Frameworks */,\n\t\t\t\t19C28FACFE9D520D11CA2CBB /* Products */,\n\t\t\t);\n\t\t\tname = CustomTemplate;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t29B97323FDCFA39411CA2CEA /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,\n\t\t\t\t1D30AB110D05D00D00671497 /* Foundation.framework */,\n\t\t\t\t288765FC0DF74451002DB57D /* CoreGraphics.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66EA057A13C011C0004FFE1A /* Source */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66EA058013C011D6004FFE1A /* AppDelegate.h */,\n\t\t\t\t66EA058113C011D6004FFE1A /* AppDelegate.m */,\n\t\t\t\t66EA058713C011EC004FFE1A /* main.m */,\n\t\t\t);\n\t\t\tname = Source;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66EA058E13C0126F004FFE1A /* Nimbus */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = Nimbus;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t66EA059D13C0128E004FFE1A /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66EA05A213C01297004FFE1A /* ___PROJECTNAMEASIDENTIFIER___-Info.plist */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget \"___PROJECTNAME___\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t1D60588D0D05DD3D006BFB54 /* Resources */,\n\t\t\t\t1D60588E0D05DD3D006BFB54 /* Sources */,\n\t\t\t\t1D60588F0D05DD3D006BFB54 /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = ___PROJECTNAME___;\n\t\t\tproductName = ___PROJECTNAME___;\n\t\t\tproductReference = 1D6058910D05DD3D006BFB54 /* ___PROJECTNAME___.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t29B97313FDCFA39411CA2CEA /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tbuildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject \"___PROJECTNAME___\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.1\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 1;\n\t\t\tknownRegions = (\n\t\t\t\tEnglish,\n\t\t\t\tJapanese,\n\t\t\t\tFrench,\n\t\t\t\tGerman,\n\t\t\t);\n\t\t\tmainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t1D6058900D05DD3D006BFB54 /* ___PROJECTNAME___ */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t1D60588D0D05DD3D006BFB54 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t1D60588E0D05DD3D006BFB54 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t66EA058313C011D6004FFE1A /* AppDelegate.m in Sources */,\n\t\t\t\t66EA058813C011EC004FFE1A /* main.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t1D6058940D05DD3E006BFB54 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = src/___PROJECTNAMEASIDENTIFIER____Prefix.pch;\n\t\t\t\tINFOPLIST_FILE = \"resources/___PROJECTNAMEASIDENTIFIER___-Info.plist\";\n\t\t\t\tPRODUCT_NAME = ___PROJECTNAME___;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t1D6058950D05DD3E006BFB54 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = src/___PROJECTNAMEASIDENTIFIER____Prefix.pch;\n\t\t\t\tINFOPLIST_FILE = \"resources/___PROJECTNAMEASIDENTIFIER___-Info.plist\";\n\t\t\t\tPRODUCT_NAME = ___PROJECTNAME___;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC01FCF4F08A954540054247B /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tARCHS = \"$(ARCHS_STANDARD_32_BIT)\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = c99;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tPREBINDING = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC01FCF5008A954540054247B /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tARCHS = \"$(ARCHS_STANDARD_32_BIT)\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = c99;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tOTHER_CFLAGS = \"-DNS_BLOCK_ASSERTIONS=1\";\n\t\t\t\tPREBINDING = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget \"___PROJECTNAME___\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t1D6058940D05DD3E006BFB54 /* Debug */,\n\t\t\t\t1D6058950D05DD3E006BFB54 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC01FCF4E08A954540054247B /* Build configuration list for PBXProject \"___PROJECTNAME___\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC01FCF4F08A954540054247B /* Debug */,\n\t\t\t\tC01FCF5008A954540054247B /* 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 = 29B97313FDCFA39411CA2CEA /* Project object */;\n}\n"
  },
  {
    "path": "templates/xcode3/projects/Skeleton App/Skeleton App (Apache 2.0 Licensed)/resources/___PROJECTNAMEASIDENTIFIER___-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>English</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>CFBundleIconFile</key>\n\t<string></string>\n\t<key>CFBundleIdentifier</key>\n\t<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</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>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>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "templates/xcode3/projects/Skeleton App/Skeleton App (Apache 2.0 Licensed)/src/AppDelegate.h",
    "content": "//\n// Copyright ___YEAR___ ___ORGANIZATIONNAME___\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : NSObject <UIApplicationDelegate> {\n  UIWindow* _window;\n}\n\n@property (nonatomic, readwrite, retain) UIWindow* window;\n\n@end\n\n"
  },
  {
    "path": "templates/xcode3/projects/Skeleton App/Skeleton App (Apache 2.0 Licensed)/src/AppDelegate.m",
    "content": "//\n// Copyright ___YEAR___ ___ORGANIZATIONNAME___\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"AppDelegate.h\"\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n@implementation AppDelegate\n\n@synthesize window = _window;\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n- (void)dealloc {\n  [_window release];\n  _window = nil;\n\n  [super dealloc];\n}\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n#pragma mark -\n#pragma mark Application lifecycle\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n- (BOOL)              application:(UIApplication *)application\n    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n  self.window = [[[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds] autorelease];\n  [self.window makeKeyAndVisible];\n\n  return YES;\n}\n\n\n@end\n"
  },
  {
    "path": "templates/xcode3/projects/Skeleton App/Skeleton App (Apache 2.0 Licensed)/src/___PROJECTNAMEASIDENTIFIER____Prefix.pch",
    "content": "//\n// Copyright ___YEAR___ ___ORGANIZATIONNAME___\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#ifdef __OBJC__\n    #import <Foundation/Foundation.h>\n    #import <UIKit/UIKit.h>\n#endif\n"
  },
  {
    "path": "templates/xcode3/projects/Skeleton App/Skeleton App (Apache 2.0 Licensed)/src/main.m",
    "content": "//\n// Copyright ___YEAR___ ___ORGANIZATIONNAME___\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\nint main(int argc, char *argv[]) {\n  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];\n  int retVal = UIApplicationMain(argc, argv, nil, @\"AppDelegate\");\n  [pool release];\n  return retVal;\n}\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/NSObject subclass.pbfiletemplate/TemplateInfo.plist",
    "content": "{\n\tMainTemplateFile = \"class.m\";\n\tCounterpartTemplateFile = \"class.h\";\n\tDescription = \"An Objective-C class that inherits from NSObject. Licensed with Apache 2.0.\";\n}\n\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/NSObject subclass.pbfiletemplate/class.h",
    "content": "//\n// Copyright «YEAR» «ORGANIZATIONNAME»\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n@interface «FILEBASENAMEASIDENTIFIER» : NSObject {\n\n}\n\n@end\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/NSObject subclass.pbfiletemplate/class.m",
    "content": "//\n// Copyright «YEAR» «ORGANIZATIONNAME»\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"«FILEBASENAMEASIDENTIFIER».h\"\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n@implementation «FILEBASENAMEASIDENTIFIER»\n\n@end\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/TemplateChooser.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>OptionsLabel</key>\n\t<string>Subclass of</string>\n\t<key>PopupMenu</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>Key</key>\n\t\t\t<string>NSObject</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>NSObject</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>Key</key>\n\t\t\t<string>UIView</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>UIView</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>Key</key>\n\t\t\t<string>UIViewController</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>UIViewController</string>\n\t\t</dict>\n\t</array>\n\t<key>TemplateSelection</key>\n\t<dict>\n\t\t<key></key>\n\t\t<string>NSObject subclass</string>\n\t\t<key>NSObject</key>\n\t\t<string>NSObject subclass</string>\n\t\t<key>UIView</key>\n\t\t<string>UIView subclass</string>\n\t\t<key>UIViewController</key>\n\t\t<string>UIViewController subclass</string>\n\t</dict>\n</dict>\n</plist>\n\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/UIView subclass.pbfiletemplate/TemplateInfo.plist",
    "content": "{\n\tMainTemplateFile = \"class.m\";\n\tCounterpartTemplateFile = \"class.h\";\n\tDescription = \"An Objective-C class that inherits from UIView. Licensed with Apache 2.0.\";\n}\n\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/UIView subclass.pbfiletemplate/class.h",
    "content": "//\n// Copyright «YEAR» «ORGANIZATIONNAME»\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n@interface «FILEBASENAMEASIDENTIFIER» : UIView {\n\n}\n\n@end\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/UIView subclass.pbfiletemplate/class.m",
    "content": "//\n// Copyright «YEAR» «ORGANIZATIONNAME»\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"«FILEBASENAMEASIDENTIFIER».h\"\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n@implementation «FILEBASENAMEASIDENTIFIER»\n\n@end\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/UIViewController subclass.pbfiletemplate/TemplateInfo.plist",
    "content": "{\n\tMainTemplateFile = \"class.m\";\n\tCounterpartTemplateFile = \"class.h\";\n\tDescription = \"An Objective-C class that inherits from UIViewController. Licensed with Apache 2.0.\";\n}\n\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/UIViewController subclass.pbfiletemplate/class.h",
    "content": "//\n// Copyright «YEAR» «ORGANIZATIONNAME»\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n@interface «FILEBASENAMEASIDENTIFIER» : UIViewController {\n\n}\n\n@end\n"
  },
  {
    "path": "templates/xcode3/source/Nimbus Hacking/Objective-C Class/UIViewController subclass.pbfiletemplate/class.m",
    "content": "//\n// Copyright «YEAR» «ORGANIZATIONNAME»\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"«FILEBASENAMEASIDENTIFIER».h\"\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n@implementation «FILEBASENAMEASIDENTIFIER»\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {\n  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {\n\n  }\n\n  return self;\n}\n\n\n@end\n"
  },
  {
    "path": "templates/xcode4/projects/Base.xctemplate/TemplateInfo.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>Identifier</key>\n\t<string>com.nimbus.base</string>\n\t<key>Kind</key>\n\t<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>\n\t<key>Options</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>Description</key>\n\t\t\t<string>Your new product&apos;s name.</string>\n\t\t\t<key>EmptyReplacement</key>\n\t\t\t<string>ProductName</string>\n\t\t\t<key>Identifier</key>\n\t\t\t<string>productName</string>\n\t\t\t<key>Name</key>\n\t\t\t<string>Product Name</string>\n\t\t\t<key>NotPersisted</key>\n\t\t\t<true/>\n\t\t\t<key>Required</key>\n\t\t\t<true/>\n\t\t\t<key>Type</key>\n\t\t\t<string>text</string>\n\t\t</dict>\n\t</array>\n\t<key>Project</key>\n\t<dict>\n\t\t<key>Configurations</key>\n\t\t<dict>\n\t\t\t<key>Debug</key>\n\t\t\t<dict>\n\t\t\t\t<key>GCC_OPTIMIZATION_LEVEL</key>\n\t\t\t\t<string>0</string>\n\t\t\t\t<key>GCC_PREPROCESSOR_DEFINITIONS</key>\n\t\t\t\t<string>DEBUG</string>\n\t\t\t\t<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>\n\t\t\t\t<string>NO</string>\n\t\t\t</dict>\n\t\t\t<key>Release</key>\n\t\t\t<dict/>\n\t\t</dict>\n\t\t<key>SharedSettings</key>\n\t\t<dict>\n\t\t\t<key>GCC_C_LANGUAGE_STANDARD</key>\n\t\t\t<string>gnu99</string>\n\t\t\t<key>GCC_WARN_ABOUT_RETURN_TYPE</key>\n\t\t\t<string>YES</string>\n\t\t\t<key>GCC_WARN_UNUSED_VARIABLE</key>\n\t\t\t<string>YES</string>\n\t\t</dict>\n\t</dict>\n\t<key>Targets</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>Configurations</key>\n\t\t\t<dict>\n\t\t\t\t<key>Debug</key>\n\t\t\t\t<dict/>\n\t\t\t\t<key>Release</key>\n\t\t\t\t<dict/>\n\t\t\t</dict>\n\t\t\t<key>Name</key>\n\t\t\t<string>___PACKAGENAME___</string>\n\t\t\t<key>SharedSettings</key>\n\t\t\t<dict>\n\t\t\t\t<key>ALWAYS_SEARCH_USER_PATHS</key>\n\t\t\t\t<string>NO</string>\n\t\t\t\t<key>PRODUCT_NAME</key>\n\t\t\t\t<string>$(TARGET_NAME)</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "templates/xcode4/projects/Bundle Base.xctemplate/TemplateInfo.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>Ancestors</key>\n\t<array>\n\t\t<string>com.nimbus.base</string>\n\t</array>\n\t<key>Identifier</key>\n\t<string>com.nimbus.bundleBase</string>\n\t<key>Kind</key>\n\t<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>\n\t<key>Options</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>Description</key>\n\t\t\t<string>Your company&apos;s bundle identifier prefix.</string>\n\t\t\t<key>EmptyReplacement</key>\n\t\t\t<string>com.yourcompany</string>\n\t\t\t<key>Identifier</key>\n\t\t\t<string>bundleIdentifierPrefix</string>\n\t\t\t<key>Name</key>\n\t\t\t<string>Company Identifier</string>\n\t\t\t<key>Required</key>\n\t\t\t<true/>\n\t\t\t<key>Type</key>\n\t\t\t<string>text</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>Default</key>\n\t\t\t<string>___VARIABLE_bundleIdentifierPrefix:bundleIdentifier___.___VARIABLE_productName:RFC1034Identifier___</string>\n\t\t\t<key>Description</key>\n\t\t\t<string>Your new product&apos;s bundle identifier.</string>\n\t\t\t<key>Identifier</key>\n\t\t\t<string>bundleIdentifier</string>\n\t\t\t<key>Name</key>\n\t\t\t<string>Bundle Identifier</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>static</string>\n\t\t</dict>\n\t</array>\n\t<key>Targets</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>SharedSettings</key>\n\t\t\t<dict>\n\t\t\t\t<key>GCC_PRECOMPILE_PREFIX_HEADER</key>\n\t\t\t\t<string>YES</string>\n\t\t\t\t<key>GCC_PREFIX_HEADER</key>\n\t\t\t\t<string>___PACKAGENAME___/src/___PROJECTNAMEASIDENTIFIER____Prefix.pch</string>\n\t\t\t\t<key>INFOPLIST_FILE</key>\n\t\t\t\t<string>___PACKAGENAME___/resources/___PROJECTNAMEASIDENTIFIER___-Info.plist</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "templates/xcode4/projects/Cocoa Touch Application.xctemplate/TemplateInfo.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>Ancestors</key>\n\t<array>\n\t\t<string>com.nimbus.objectiveCApplication</string>\n\t\t<string>com.nimbus.iPhoneBase</string>\n\t</array>\n\t<key>Identifier</key>\n\t<string>com.nimbus.cocoaTouchApplication</string>\n\t<key>Kind</key>\n\t<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>\n\t<key>Project</key>\n\t<dict>\n\t\t<key>Configurations</key>\n\t\t<dict>\n\t\t\t<key>Release</key>\n\t\t\t<dict>\n\t\t\t\t<key>OTHER_CFLAGS</key>\n\t\t\t\t<string>-DNS_BLOCK_ASSERTIONS=1</string>\n\t\t\t</dict>\n\t\t</dict>\n\t\t<key>SharedSettings</key>\n\t\t<dict>\n\t\t\t<key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>\n\t\t\t<string>iPhone Developer</string>\n\t\t</dict>\n\t</dict>\n\t<key>Targets</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>Configurations</key>\n\t\t\t<dict>\n\t\t\t\t<key>Release</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>VALIDATE_PRODUCT</key>\n\t\t\t\t\t<string>YES</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<key>Frameworks</key>\n\t\t\t<array>\n\t\t\t\t<string>UIKit</string>\n\t\t\t\t<string>Foundation</string>\n\t\t\t\t<string>CoreGraphics</string>\n\t\t\t</array>\n\t\t</dict>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "templates/xcode4/projects/Objective-C Application.xctemplate/TemplateInfo.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>Ancestors</key>\n\t<array>\n\t\t<string>com.nimbus.bundleBase</string>\n\t</array>\n\t<key>Identifier</key>\n\t<string>com.nimbus.objectiveCApplication</string>\n\t<key>Kind</key>\n\t<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>\n\t<key>Targets</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>BuildPhases</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>Class</key>\n\t\t\t\t\t<string>Sources</string>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>Class</key>\n\t\t\t\t\t<string>Frameworks</string>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>Class</key>\n\t\t\t\t\t<string>Resources</string>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t\t<key>Configurations</key>\n\t\t\t<dict>\n\t\t\t\t<key>Debug</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>COPY_PHASE_STRIP</key>\n\t\t\t\t\t<string>NO</string>\n\t\t\t\t\t<key>GCC_DYNAMIC_NO_PIC</key>\n\t\t\t\t\t<string>NO</string>\n\t\t\t\t</dict>\n\t\t\t\t<key>Release</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>COPY_PHASE_STRIP</key>\n\t\t\t\t\t<string>YES</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<key>ProductType</key>\n\t\t\t<string>com.apple.product-type.application</string>\n\t\t\t<key>SharedSettings</key>\n\t\t\t<dict>\n\t\t\t\t<key>WRAPPER_EXTENSION</key>\n\t\t\t\t<string>app</string>\n\t\t\t</dict>\n\t\t</dict>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "templates/xcode4/projects/Skeleton App (Apache 2.0 Licensed).xctemplate/TemplateInfo.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>Ancestors</key>\n\t<array>\n\t\t<string>com.nimbus.cocoaTouchApplication</string>\n\t</array>\n\t<key>Concrete</key>\n\t<true/>\n\t<key>Definitions</key>\n\t<dict>\n\t\t<key>___PROJECTNAMEASIDENTIFIER____Prefix.pch</key>\n\t\t<dict>\n\t\t\t<key>Path</key>\n\t\t\t<string>src/___PROJECTNAMEASIDENTIFIER____Prefix.pch</string>\n\t\t\t<key>TargetIndices</key>\n\t\t\t<array/>\n\t\t</dict>\n\t\t<key>src/AppDelegate.h</key>\n\t\t<dict>\n\t\t\t<key>Group</key>\n\t\t\t<string>Source</string>\n\t\t\t<key>Path</key>\n\t\t\t<string>src/AppDelegate.h</string>\n\t\t\t<key>TargetIndices</key>\n\t\t\t<array/>\n\t\t</dict>\n\t\t<key>src/AppDelegate.m</key>\n\t\t<dict>\n\t\t\t<key>Group</key>\n\t\t\t<string>Source</string>\n\t\t\t<key>Path</key>\n\t\t\t<string>src/AppDelegate.m</string>\n\t\t</dict>\n\t\t<key>src/main.m</key>\n\t\t<dict>\n\t\t\t<key>Group</key>\n\t\t\t<string>Source</string>\n\t\t\t<key>Path</key>\n\t\t\t<string>src/main.m</string>\n\t\t</dict>\n\t\t<key>nimbus</key>\n\t\t<dict>\n\t\t\t<key>Group</key>\n\t\t\t<string>Nimbus</string>\n\t\t</dict>\n\t\t<key>resources/___PROJECTNAMEASIDENTIFIER___-Info.plist</key>\n\t\t<dict>\n\t\t\t<key>Group</key>\n\t\t\t<string>Resources</string>\n\t\t\t<key>Path</key>\n\t\t\t<string>resources/___PROJECTNAMEASIDENTIFIER___-Info.plist</string>\n\t\t\t<key>TargetIndices</key>\n\t\t\t<array/>\n\t\t</dict>\n\t</dict>\n\t<key>Description</key>\n\t<string>This is a simple skeleton application licensed under the Apache 2.0 open source license. It programmatically sets up the UIWindow, does not use nibs, and only has one entry point for both the iPhone and iPad.</string>\n\t<key>Identifier</key>\n\t<string>com.nimbus.skeletonApplicationApache2</string>\n\t<key>Kind</key>\n\t<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>\n\t<key>Nodes</key>\n\t<array>\n\t\t<string>src/___PROJECTNAMEASIDENTIFIER____Prefix.pch</string>\n\t\t<string>src/AppDelegate.h</string>\n\t\t<string>src/AppDelegate.m</string>\n\t\t<string>src/main.m</string>\n\t\t<string>resources/___PROJECTNAMEASIDENTIFIER___-Info.plist</string>\n\t</array>\n\t<key>Project</key>\n\t<dict>\n\t\t<key>SharedSettings</key>\n\t\t<dict>\n\t\t\t<key>TARGETED_DEVICE_FAMILY</key>\n\t\t\t<string>1,2</string>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "templates/xcode4/projects/Skeleton App (Apache 2.0 Licensed).xctemplate/resources/___PROJECTNAMEASIDENTIFIER___-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>English</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>CFBundleIconFile</key>\n\t<string></string>\n\t<key>CFBundleIdentifier</key>\n\t<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</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>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>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "templates/xcode4/projects/Skeleton App (Apache 2.0 Licensed).xctemplate/src/AppDelegate.h",
    "content": "//\n// Copyright ___YEAR___ ___ORGANIZATIONNAME___\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : NSObject <UIApplicationDelegate> {\n  UIWindow* _window;\n}\n\n@property (nonatomic, readwrite, retain) UIWindow* window;\n\n@end\n\n"
  },
  {
    "path": "templates/xcode4/projects/Skeleton App (Apache 2.0 Licensed).xctemplate/src/AppDelegate.m",
    "content": "//\n// Copyright ___YEAR___ ___ORGANIZATIONNAME___\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import \"AppDelegate.h\"\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n@implementation AppDelegate\n\n@synthesize window = _window;\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n- (void)dealloc {\n  [_window release];\n  _window = nil;\n\n  [super dealloc];\n}\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////////////////////////////////\n#pragma mark -\n#pragma mark Application lifecycle\n\n\n///////////////////////////////////////////////////////////////////////////////////////////////////\n- (BOOL)              application:(UIApplication *)application\n    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n  self.window = [[[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds] autorelease];\n  [self.window makeKeyAndVisible];\n\n  return YES;\n}\n\n\n@end\n"
  },
  {
    "path": "templates/xcode4/projects/Skeleton App (Apache 2.0 Licensed).xctemplate/src/___PROJECTNAMEASIDENTIFIER____Prefix.pch",
    "content": "//\n// Copyright ___YEAR___ ___ORGANIZATIONNAME___\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#ifdef __OBJC__\n    #import <Foundation/Foundation.h>\n    #import <UIKit/UIKit.h>\n#endif\n"
  },
  {
    "path": "templates/xcode4/projects/Skeleton App (Apache 2.0 Licensed).xctemplate/src/main.m",
    "content": "//\n// Copyright ___YEAR___ ___ORGANIZATIONNAME___\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n#import <UIKit/UIKit.h>\n\nint main(int argc, char *argv[]) {\n  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];\n  int retVal = UIApplicationMain(argc, argv, nil, @\"AppDelegate\");\n  [pool release];\n  return retVal;\n}\n"
  },
  {
    "path": "templates/xcode4/projects/iPhone Base.xctemplate/TemplateInfo.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>Identifier</key>\n\t<string>com.nimbus.iPhoneBase</string>\n\t<key>Kind</key>\n\t<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>\n\t<key>Platforms</key>\n\t<array>\n\t\t<string>com.apple.platform.iphoneos</string>\n\t</array>\n\t<key>Project</key>\n\t<dict>\n\t\t<key>SDK</key>\n\t\t<string>iphoneos</string>\n\t\t<key>SharedSettings</key>\n\t\t<dict>\n\t\t\t<key>ARCHS</key>\n\t\t\t<string>$(ARCHS_STANDARD_32_BIT)</string>\n\t\t\t<key>GCC_VERSION</key>\n\t\t\t<string>com.apple.compilers.llvmgcc42</string>\n\t\t\t<key>IPHONEOS_DEPLOYMENT_TARGET</key>\n\t\t\t<string>latest_iphoneos</string>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  }
]