hunk.code_window: <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
   <plist version="1.0">
   <dict>
   	<key>isShell</key>
   	<true/>
   	<key>developmentUrl</key>
  
hunk.labels: keep keep add keep keep keep
hunk.after_edit: 	<key>isRemoteJSEnabled</key>
   	<true/>
  
hunk.file_path: ios/Exponent/Supporting/EXShell.plist.example
hunk.type: add
file: /**
   * Copyright (c) 2015-present, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   */
  
  #import "ABI10_0_0RCTText.h"
  
  #import "ABI10_0_0RCTShadowText.h"
  #import "ABI10_0_0RCTUtils.h"
  #import "UIView+ReactABI10_0_0.h"
  
  static void collectNonTextDescendants(ABI10_0_0RCTText *view, NSMutableArray *nonTextDescendants)
  {
    for (UIView *child in view.ReactABI10_0_0Subviews) {
      if ([child isKindOfClass:[ABI10_0_0RCTText class]]) {
        collectNonTextDescendants((ABI10_0_0RCTText *)child, nonTextDescendants);
      } else if (!CGRectEqualToRect(child.frame, CGRectZero)) {
        [nonTextDescendants addObject:child];
      }
    }
  }
  
  @implementation ABI10_0_0RCTText
  {
    NSTextStorage *_textStorage;
    CAShapeLayer *_highlightLayer;
  }
  
  - (instancetype)initWithFrame:(CGRect)frame
  {
    if ((self = [super initWithFrame:frame])) {
      _textStorage = [NSTextStorage new];
      self.isAccessibilityElement = YES;
      self.accessibilityTraits |= UIAccessibilityTraitStaticText;
  
      self.opaque = NO;
      self.contentMode = UIViewContentModeRedraw;
    }
    return self;
  }
  
  - (NSString *)description
  {
    NSString *superDescription = super.description;
    NSRange semicolonRange = [superDescription rangeOfString:@";"];
    NSString *replacement = [NSString stringWithFormat:@"; ReactABI10_0_0Tag: %@; text: %@", self.ReactABI10_0_0Tag, self.textStorage.string];
    return [superDescription stringByReplacingCharactersInRange:semicolonRange withString:replacement];
  }
  
  - (void)ReactABI10_0_0SetFrame:(CGRect)frame
  {
    // Text looks super weird if its frame is animated.
    // This disables the frame animation, without affecting opacity, etc.
    [UIView performWithoutAnimation:^{
      [super ReactABI10_0_0SetFrame:frame];
    }];
  }
  
  - (void)ReactABI10_0_0SetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
  {
    self.backgroundColor = inheritedBackgroundColor;
  }
  
  - (void)didUpdateReactABI10_0_0Subviews
  {
    // Do nothing, as subviews are managed by `setTextStorage:` method
  }
  
  - (void)setTextStorage:(NSTextStorage *)textStorage
  {
    if (_textStorage != textStorage) {
      _textStorage = textStorage;
  
      // Update subviews
      NSMutableArray *nonTextDescendants = [NSMutableArray new];
      collectNonTextDescendants(self, nonTextDescendants);
      NSArray *subviews = self.subviews;
      if (![subviews isEqualToArray:nonTextDescendants]) {
        for (UIView *child in subviews) {
          if (![nonTextDescendants containsObject:child]) {
            [child removeFromSuperview];
          }
        }
        for (UIView *child in nonTextDescendants) {
          [self addSubview:child];
        }
      }
  
      [self setNeedsDisplay];
    }
  }
  
  - (void)drawRect:(CGRect)rect
  {
    NSLayoutManager *layoutManager = [_textStorage.layoutManagers firstObject];
    NSTextContainer *textContainer = [layoutManager.textContainers firstObject];
  
    NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
    CGRect textFrame = self.textFrame;
    [layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:textFrame.origin];
    [layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:textFrame.origin];
  
    __block UIBezierPath *highlightPath = nil;
    NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
    [layoutManager.textStorage enumerateAttribute:ABI10_0_0RCTIsHighlightedAttributeName inRange:characterRange options:0 usingBlock:^(NSNumber *value, NSRange range, BOOL *_) {
      if (!value.boolValue) {
        return;
      }
  
      [layoutManager enumerateEnclosingRectsForGlyphRange:range withinSelectedGlyphRange:range inTextContainer:textContainer usingBlock:^(CGRect enclosingRect, __unused BOOL *__) {
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(enclosingRect, -2, -2) cornerRadius:2];
        if (highlightPath) {
          [highlightPath appendPath:path];
        } else {
          highlightPath = path;
        }
      }];
    }];
  
    if (highlightPath) {
      if (!_highlightLayer) {
        _highlightLayer = [CAShapeLayer layer];
        _highlightLayer.fillColor = [UIColor colorWithWhite:0 alpha:0.25].CGColor;
        [self.layer addSublayer:_highlightLayer];
      }
      _highlightLayer.position = (CGPoint){_contentInset.left, _contentInset.top};
      _highlightLayer.path = highlightPath.CGPath;
    } else {
      [_highlightLayer removeFromSuperlayer];
      _highlightLayer = nil;
    }
  }
  
  - (NSNumber *)ReactABI10_0_0TagAtPoint:(CGPoint)point
  {
    NSNumber *ReactABI10_0_0Tag = self.ReactABI10_0_0Tag;
  
    CGFloat fraction;
    NSLayoutManager *layoutManager = _textStorage.layoutManagers.firstObject;
    NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
    NSUInteger characterIndex = [layoutManager characterIndexForPoint:point
                                                      inTextContainer:textContainer
                             fractionOfDistanceBetweenInsertionPoints:&fraction];
  
    // If the point is not before (fraction == 0.0) the first character and not
    // after (fraction == 1.0) the last character, then the attribute is valid.
    if (_textStorage.length > 0 && (fraction > 0 || characterIndex > 0) && (fraction < 1 || characterIndex < _textStorage.length - 1)) {
      ReactABI10_0_0Tag = [_textStorage attribute:ABI10_0_0RCTReactABI10_0_0TagAttributeName atIndex:characterIndex effectiveRange:NULL];
    }
    return ReactABI10_0_0Tag;
  }
  
  - (void)didMoveToWindow
  {
    [super didMoveToWindow];
  
    if (!self.window) {
      self.layer.contents = nil;
      if (_highlightLayer) {
        [_highlightLayer removeFromSuperlayer];
        _highlightLayer = nil;
      }
    } else if (_textStorage.length) {
      [self setNeedsDisplay];
    }
  }
  
  
  #pragma mark - Accessibility
  
  - (NSString *)accessibilityLabel
  {
    return _textStorage.string;
  }
  
  @end
  