<commit_before>class UIView

  class << self

    # If options is a Numeric, it is used as the duration.  Otherwise, duration
    # is an option, and defaults to 0.3.  All the transition methods work this
    # way.
    # @option options [Float] :duration Animation duration. default: 0.3
    # @option options [Float] :delay Delay before animations begin. default: 0
    # @option options [Float] :damping Enables the "spring" animation.  Value of 1.0 is a stiff spring.
    # @option options [Float] :velocity Used in a spring animation to set the initial velocity
    # @option options [Proc]  :after A block that is executed when the animation is complete, useful for chaining (though the `animation_chain` method is better!)
    # @option options [Fixnum] :options The options parameter that is passed to the UIView.animateWithDuration(...) method.  You can also use the more verbose options `:curve`, `:from_current`, and `:allow_interaction`
    # @option options [Fixnum] :curve The animation curve option. default: UIViewAnimationOptionCurveEaseIn
    # @option options [Boolean] :from_current Whether or not to have animations start from their current position (aka UIViewAnimationOptionBeginFromCurrentState)
    # @option options [Boolean] :allow_interaction aka UIViewAnimationOptionAllowUserInteraction
    def animate(options={}, more_options={}, &animations)
      raise "animation block is required" unless animations

      if options.is_a? Numeric
        duration = options
        options = more_options
      else
        duration = options[:duration] || 0.3
      end

      delay = options[:delay] || 0

      damping_ratio = options[:damping] || nil
      spring_velocity = options[:velocity] || 0.0

      # chain: true is used inside animation_chain blocks to prevent some weird
      # animation errors (nested animations do not delay/queue as you'd expect)
      if options[:chain] || Thread.current[:sugarcube_chaining]
        duration = 0
        delay = 0
        raise "Completion blocks cannot be used within an animation_chain block" if options[:after]
      end

      after_animations = options[:after]
      if after_animations
        if after_animations.arity == 0
          after_adjusted = ->(finished){ after_animations.call }
        else
          after_adjusted = after_animations
        end
      else
        after_adjusted = nil
      end

      animation_options = options[:options]
      unless animation_options
        curve = options.fetch(:curve, UIViewAnimationOptionCurveEaseInOut)
        curve = curve.uianimationcurve if curve.is_a?(Symbol)

        from_current = options.fetch(:from_current, true) ? UIViewAnimationOptionBeginFromCurrentState : 0
        allow_interaction = options.fetch(:allow_interaction, false) ? UIViewAnimationOptionAllowUserInteraction : 0

        animation_options = curve | from_current
      end

      if duration == 0 && delay == 0
        animations.call
        after_adjusted.call(true) if after_adjusted
      else
        prev_value = Thread.current[:sugarcube_chaining]
        Thread.current[:sugarcube_chaining] = true

        if damping_ratio
          UIView.animateWithDuration( duration,
                               delay: delay,
              usingSpringWithDamping: damping_ratio,
               initialSpringVelocity: spring_velocity,
                             options: animation_options,
                          animations: animations,
                          completion: after_adjusted
                                    )
        else
          UIView.animateWithDuration( duration,
                               delay: delay,
                             options: animation_options,
                          animations: animations,
                          completion: after_adjusted
                                    )
        end
        Thread.current[:sugarcube_chaining] = prev_value
      end
      nil
    end

    # Animation chains are great for consecutive animation blocks.  Each chain can
    # take the same options that UIView##animate take.
    def animation_chain(options={}, &first)
      chain = SugarCube::AnimationChain.new
      if first
        chain.and_then(options, &first)
      end
      return chain
    end

  end

  def show
    self.hidden = false
    return self
  end

  def hide
    self.hidden = true
    return self
  end

  # Same as UIView##animate, but acts on self
  def animate(options={}, more_options={}, &animations)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    assign = options[:assign] || {}

    UIView.animate(options) do
      animations.call if animations

      assign.each do |key, value|
        self.send("#{key}=", value)
      end
    end
    return self
  end

  # Changes the layer opacity.
  def fade(options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = { opacity: options }
    end

    options[:after] = after

    animate(options) do
      self.alpha = options[:opacity]
    end
  end

  # Changes the layer opacity to 0.
  # @see #fade
  def fade_out(options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    options[:opacity] ||= 0.0

    fade(options, &after)
  end

  # Changes the layer opacity to 1.
  # @see #fade
  def fade_in(options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    options[:opacity] ||= 1.0

    fade(options, &after)
  end

  # Changes the layer opacity to 0 and then removes the view from its superview
  # @see #fade_out
  def fade_out_and_remove(options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    original_opacity = self.alpha

    after_remove = proc do
      self.alpha = original_opacity
      removeFromSuperview
      after.call if after
    end

    fade_out(options, &after_remove)
  end

  def move_to(position, options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    options[:after] = after

    animate(options) do
      f = self.frame
      f.origin = SugarCube::CoreGraphics::Point(position)
      self.frame = f
    end
  end

  def delta_to(delta, options={}, more_options={}, &after)
    f = self.frame
    delta = SugarCube::CoreGraphics::Point(delta)
    position = SugarCube::CoreGraphics::Point(f.origin)
    to_position = CGPoint.new(position.x + delta.x, position.y + delta.y)
    move_to(to_position, options, more_options, &after)<commit_msg>Added center_to and scale_to animations.<commit_after>class UIView

  class << self

    # If options is a Numeric, it is used as the duration.  Otherwise, duration
    # is an option, and defaults to 0.3.  All the transition methods work this
    # way.
    # @option options [Float] :duration Animation duration. default: 0.3
    # @option options [Float] :delay Delay before animations begin. default: 0
    # @option options [Float] :damping Enables the "spring" animation.  Value of 1.0 is a stiff spring.
    # @option options [Float] :velocity Used in a spring animation to set the initial velocity
    # @option options [Proc]  :after A block that is executed when the animation is complete, useful for chaining (though the `animation_chain` method is better!)
    # @option options [Fixnum] :options The options parameter that is passed to the UIView.animateWithDuration(...) method.  You can also use the more verbose options `:curve`, `:from_current`, and `:allow_interaction`
    # @option options [Fixnum] :curve The animation curve option. default: UIViewAnimationOptionCurveEaseIn
    # @option options [Boolean] :from_current Whether or not to have animations start from their current position (aka UIViewAnimationOptionBeginFromCurrentState)
    # @option options [Boolean] :allow_interaction aka UIViewAnimationOptionAllowUserInteraction
    def animate(options={}, more_options={}, &animations)
      raise "animation block is required" unless animations

      if options.is_a? Numeric
        duration = options
        options = more_options
      else
        duration = options[:duration] || 0.3
      end

      delay = options[:delay] || 0

      damping_ratio = options[:damping] || nil
      spring_velocity = options[:velocity] || 0.0

      # chain: true is used inside animation_chain blocks to prevent some weird
      # animation errors (nested animations do not delay/queue as you'd expect)
      if options[:chain] || Thread.current[:sugarcube_chaining]
        duration = 0
        delay = 0
        raise "Completion blocks cannot be used within an animation_chain block" if options[:after]
      end

      after_animations = options[:after]
      if after_animations
        if after_animations.arity == 0
          after_adjusted = ->(finished){ after_animations.call }
        else
          after_adjusted = after_animations
        end
      else
        after_adjusted = nil
      end

      animation_options = options[:options]
      unless animation_options
        curve = options.fetch(:curve, UIViewAnimationOptionCurveEaseInOut)
        curve = curve.uianimationcurve if curve.is_a?(Symbol)

        from_current = options.fetch(:from_current, true) ? UIViewAnimationOptionBeginFromCurrentState : 0
        allow_interaction = options.fetch(:allow_interaction, false) ? UIViewAnimationOptionAllowUserInteraction : 0

        animation_options = curve | from_current
      end

      if duration == 0 && delay == 0
        animations.call
        after_adjusted.call(true) if after_adjusted
      else
        prev_value = Thread.current[:sugarcube_chaining]
        Thread.current[:sugarcube_chaining] = true

        if damping_ratio
          UIView.animateWithDuration( duration,
                               delay: delay,
              usingSpringWithDamping: damping_ratio,
               initialSpringVelocity: spring_velocity,
                             options: animation_options,
                          animations: animations,
                          completion: after_adjusted
                                    )
        else
          UIView.animateWithDuration( duration,
                               delay: delay,
                             options: animation_options,
                          animations: animations,
                          completion: after_adjusted
                                    )
        end
        Thread.current[:sugarcube_chaining] = prev_value
      end
      nil
    end

    # Animation chains are great for consecutive animation blocks.  Each chain can
    # take the same options that UIView##animate take.
    def animation_chain(options={}, &first)
      chain = SugarCube::AnimationChain.new
      if first
        chain.and_then(options, &first)
      end
      return chain
    end

  end

  def show
    self.hidden = false
    return self
  end

  def hide
    self.hidden = true
    return self
  end

  # Same as UIView##animate, but acts on self
  def animate(options={}, more_options={}, &animations)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    assign = options[:assign] || {}

    UIView.animate(options) do
      animations.call if animations

      assign.each do |key, value|
        self.send("#{key}=", value)
      end
    end
    return self
  end

  # Changes the layer opacity.
  def fade(options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = { opacity: options }
    end

    options[:after] = after

    animate(options) do
      self.alpha = options[:opacity]
    end
  end

  # Changes the layer opacity to 0.
  # @see #fade
  def fade_out(options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    options[:opacity] ||= 0.0

    fade(options, &after)
  end

  # Changes the layer opacity to 1.
  # @see #fade
  def fade_in(options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    options[:opacity] ||= 1.0

    fade(options, &after)
  end

  # Changes the layer opacity to 0 and then removes the view from its superview
  # @see #fade_out
  def fade_out_and_remove(options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    original_opacity = self.alpha

    after_remove = proc do
      self.alpha = original_opacity
      removeFromSuperview
      after.call if after
    end

    fade_out(options, &after_remove)
  end

  def scale_to(scale, options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(scale: options)
    end

    options[:after] = after

    animate(options) {
      radians = Math.atan2(self.transform.b, self.transform.a)
      # radians = self.valueForKeyPath('layer.transform.rotation.z')
      rotation_t = CGAffineTransformMakeRotation(radians)
      scale_t = CGAffineTransformMakeScale(scale, scale)
      self.transform = CGAffineTransformConcat(rotation_t, scale_t)
    }
  end

  def center_to(center, options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(center: options)
    end

    options[:after] = after

    animate(options) {
      self.center = SugarCube::CoreGraphics::Point(center)
    }
  end

  def move_to(position, options={}, more_options={}, &after)
    if options.is_a? Numeric
      options = more_options.merge(duration: options)
    end

    options[:after] = after

    animate(options) do
      f = self.frame
      f.origin = SugarCube::CoreGraphics::Point(position)
      self.frame = f
    end
  end

  def delta_to(delta, options={}, more_options={}, &after)
    f = self.frame
    delta = SugarCube::CoreGraphics::Point(delta)
    position = SugarCube::CoreGraphics::Point(f.origin)
    to_position = CGPoint.new(position.x + delta.x, position.y + delta.y)
    move_to(to_position, options, more_options, &after)
{'fraction_non_alphanumeric': 0.08459044128013535, 'fraction_numerical': 0.0037360778232059778, 'mean_word_length': 2.609005342152124, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1192427', 'n_tokens_mistral': 4059, 'n_tokens_neox': 3846, 'n_words': 1176}