<commit_before>import UIKit

var distilleries: [Distillery] = []

public func closeDistilleries() {

  distilleries.forEach { $0.ingredients.forEach { $0.forEach { $0.view.layer.removeAllAnimations() } } }
}

public class Distillery: NSObject {

  var ingredients: [[Ingredient]] = [[]]
  var delays: [NSTimeInterval] = []
  var closures: [(() -> Void)?] = []
  var final: (() -> Void)?
  var shouldProceed = true

  /**
   Then gets called when the animation block above has ended.
   */
  public func then(closure: () -> Void) -> Distillery {
    closures.append(closure)

    return self
  }

  /**
   Finally is the last method that gets called when the chain of animations is done.
   */
  public func finally(closure: () -> Void) {
    final = closure
  }

  // MARK: - Animate

  func animate() {
    guard let delay = delays.first else { return }

    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
    dispatch_after(time, dispatch_get_main_queue()) {
      guard let ingredient = self.ingredients.first else { return }

      for (_, ingredient) in ingredient.enumerate() {
        guard let presentedLayer = ingredient.view.layer.presentationLayer() as? CALayer else { return }

        for (index, animation) in ingredient.animations.enumerate() {
          let property = ingredient.properties[index]

          if ingredient.kind == .Bezier {
            animation.values?.insert(Animation.propertyValue(property, layer: presentedLayer), atIndex: 0)
          } else if let value = ingredient.finalValues.first, spring = ingredient.springs.first {
            let distill = Distill()
            
            animation.values = distill.calculateSpring(property, finalValue: value,
              layer: presentedLayer, type: ingredient.calculation, spring: spring)
            animation.duration = distill.springTiming

            ingredient.springs.removeFirst()
          }

          if !ingredient.finalValues.isEmpty { ingredient.finalValues.removeFirst() }
          ingredient.view.layer.addAnimation(animation, forKey: "animation-\(index)-\(self.description)")
        }
      }
    }
  }

  // MARK: - Finish animation

  public override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
    guard var group = ingredients.first, let animation = anim as? CAKeyframeAnimation else { return }

    var index = 0
    var animationIndex = 0
    for (position, ingredient) in group.enumerate() {
      for (animationPosition, _) in ingredient.animations.enumerate()
        where ingredient.view.layer.animationForKey("animation-\(animationPosition)-\(self.description)") == animation {

        index = position
        animationIndex = animationPosition
      }
    }

    let ingredient = group[index]

    guard let layer = ingredient.view.layer.presentationLayer() as? CALayer else { return }

    ingredient.view.layer.position = layer.position
    ingredient.view.layer.frame.size = layer.frame.size
    ingredient.view.layer.transform = layer.transform
    ingredient.view.layer.cornerRadius = layer.cornerRadius
    ingredient.view.layer.opacity = layer.opacity
    ingredient.view.layer.removeAnimationForKey("animation-\(animationIndex)-\(self.description)")
    ingredient.animations.removeAtIndex(animationIndex)
    ingredient.properties.removeAtIndex(animationIndex)

    if ingredient.animations.isEmpty {
      group.removeAtIndex(index)
<commit_msg>Improves the final part<commit_after>import UIKit

var distilleries: [Distillery] = []

public func closeDistilleries() {

  distilleries.forEach { $0.ingredients.forEach { $0.forEach { $0.view.layer.removeAllAnimations() } } }
}

public class Distillery: NSObject {

  var ingredients: [[Ingredient]] = [[]]
  var delays: [NSTimeInterval] = []
  var closures: [(() -> Void)?] = []
  var final: (() -> Void)?
  var shouldProceed = true

  /**
   Then gets called when the animation block above has ended.
   */
  public func then(closure: () -> Void) -> Distillery {
    closures.append(closure)

    return self
  }

  /**
   Finally is the last method that gets called when the chain of animations is done.
   */
  public func finally(closure: () -> Void) {
    final = closure
  }

  // MARK: - Animate

  func animate() {
    guard let delay = delays.first else { return }

    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
    dispatch_after(time, dispatch_get_main_queue()) {
      guard let ingredient = self.ingredients.first else { return }

      for (_, ingredient) in ingredient.enumerate() {
        guard let presentedLayer = ingredient.view.layer.presentationLayer() as? CALayer else { return }

        for (index, animation) in ingredient.animations.enumerate() {
          let property = ingredient.properties[index]

          if ingredient.kind == .Bezier {
            animation.values?.insert(Animation.propertyValue(property, layer: presentedLayer), atIndex: 0)
          } else if let value = ingredient.finalValues.first, spring = ingredient.springs.first {
            let distill = Distill()
            
            animation.values = distill.calculateSpring(property, finalValue: value,
              layer: presentedLayer, type: ingredient.calculation, spring: spring)
            animation.duration = distill.springTiming

            ingredient.springs.removeFirst()
          }

          if !ingredient.finalValues.isEmpty { ingredient.finalValues.removeFirst() }
          ingredient.view.layer.addAnimation(animation, forKey: "animation-\(index)-\(self.description)")
        }
      }
    }
  }

  // MARK: - Finish animation

  public override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
    guard var group = ingredients.first, let animation = anim as? CAKeyframeAnimation else { return }

    var index = 0
    var animationIndex = 0
    for (position, ingredient) in group.enumerate() {
      for (animationPosition, _) in ingredient.animations.enumerate()
        where ingredient.view.layer.animationForKey("animation-\(animationPosition)-\(self.description)") == animation {

        index = position
        animationIndex = animationPosition
      }
    }

    let ingredient = group[index]

    guard let layer = ingredient.view.layer.presentationLayer() as? CALayer else { return }

    if ingredient.properties.contains(.Transform) {
      ingredient.view.layer.transform = layer.transform
    } else {
      ingredient.view.layer.position = layer.position
      ingredient.view.layer.frame.size = layer.frame.size
      ingredient.view.layer.cornerRadius = layer.cornerRadius
      ingredient.view.layer.opacity = layer.opacity
    }

    ingredient.view.layer.removeAnimationForKey("animation-\(animationIndex)-\(self.description)")
    ingredient.animations.removeAtIndex(animationIndex)
    ingredient.properties.removeAtIndex(animationIndex)

    if ingredient.animations.isEmpty {
      group.removeAtIndex(index)

{'fraction_non_alphanumeric': 0.10853939045428407, 'fraction_numerical': 0.0023001725129384704, 'mean_word_length': 3.114133648728563, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4991510', 'n_tokens_mistral': 1995, 'n_tokens_neox': 1883, 'n_words': 448}