<commit_before>//
//  Animator.swift
//  Foil
//
//  Created by <NAME> on 23/01/17.
//  Copyright © 2017 pixelrock. All rights reserved.
//

import CoreGraphics
import Foundation

class Animation {
	
	let curve: AnimationCurve
	let duration: TimeInterval
	
	var repeats: Bool = false
	
	fileprivate(set)
	var isRunning: Bool = false
	private(set)
	var hasCompleted: Bool = false
	private(set)
	var progressedTime: TimeInterval = 0
	
	var progress: Double {
		return curve.value(for: progressedTime / duration)
	}
	
	init(curve: AnimationCurve, duration: TimeInterval, repeats: Bool = false) {
		self.curve = curve
		self.duration = duration
		self.repeats = repeats
	}
	
	@discardableResult func start() -> Self {
		if !Animator.shared.animations.contains(self) {
			Animator.start(self)
		}
		return self
	}
	
	func stop() {
		isRunning = false
		hasCompleted = true
	}
	
	@discardableResult func loop() -> Self {
		repeats = true
		return self
	}
	
	@discardableResult func reset() -> Self {
		hasCompleted = false
		progressedTime = 0
		return self
	}
	
	func update(delta: TimeInterval) {
		let totalTime = progressedTime + delta
		if repeats {
			progressedTime = totalTime.truncatingRemainder(dividingBy: duration)
		} else {
			progressedTime = min(totalTime, duration)
		}
		didUpdate(delta: delta)
		if progressedTime >= duration {
			isRunning = false
			hasCompleted = true
		}
	}
	
	func didUpdate(delta: TimeInterval) {}
}

extension Animation: Equatable {
	static func ==(lhs: Animation, rhs: Animation) -> Bool {
		return lhs === rhs
	}
}

struct Property: RawRepresentable, Equatable, Hashable {
    
    let rawValue: String
    let index: Int
	let isRelative: Bool
    
    init(rawValue: Property.RawValue) {
        self.rawValue = rawValue
        self.index = -1
		self.isRelative = false
    }
    
	init(_ rawValue: Property.RawValue, at index: Int = -1, relative: Bool = false) {
        self.rawValue = rawValue
        self.index = index
		self.isRelative = relative
    }
    
    static var position: Property = Property(rawValue:"position")
	static var positionX: Property = Property(rawValue: "positionX")
	static var positionY: Property = Property(rawValue: "positionY")
	
	static let scale: Property = Property(rawValue:"scale")
	static var scaleWidth: Property = Property(rawValue: "scaleWidth")
	static var scaleHeight: Property = Property(rawValue: "scaleHeight")
	
    static let rotation: Property = Property(rawValue:"rotation")
	static let relativeRotation: Property = Property("relativeRotation", relative: true)
    
    var hashValue: Int {
		return rawValue.hashValue + (self.index + 1)
    }
    
    static func ==(lhs: Property, rhs: Property) -> Bool {
        return lhs.hashValue == rhs.hashValue
    }
}

protocol TargetPropertyContainer {
	weak var target: Animatable? { get }
	var property: Property { get }
}<commit_msg>Properties `RawRepresentable` instead of `String`<commit_after>//
//  Animator.swift
//  Foil
//
//  Created by <NAME> on 23/01/17.
//  Copyright © 2017 pixelrock. All rights reserved.
//

import CoreGraphics
import Foundation

class Animation {
	
	let curve: AnimationCurve
	let duration: TimeInterval
	
	var repeats: Bool = false
	
	fileprivate(set)
	var isRunning: Bool = false
	private(set)
	var hasCompleted: Bool = false
	private(set)
	var progressedTime: TimeInterval = 0
	
	var progress: Double {
		return curve.value(for: progressedTime / duration)
	}
	
	init(curve: AnimationCurve, duration: TimeInterval, repeats: Bool = false) {
		self.curve = curve
		self.duration = duration
		self.repeats = repeats
	}
	
	@discardableResult func start() -> Self {
		if !Animator.shared.animations.contains(self) {
			Animator.start(self)
		}
		return self
	}
	
	func stop() {
		isRunning = false
		hasCompleted = true
	}
	
	@discardableResult func loop() -> Self {
		repeats = true
		return self
	}
	
	@discardableResult func reset() -> Self {
		hasCompleted = false
		progressedTime = 0
		return self
	}
	
	func update(delta: TimeInterval) {
		let totalTime = progressedTime + delta
		if repeats {
			progressedTime = totalTime.truncatingRemainder(dividingBy: duration)
		} else {
			progressedTime = min(totalTime, duration)
		}
		didUpdate(delta: delta)
		if progressedTime >= duration {
			isRunning = false
			hasCompleted = true
		}
	}
	
	func didUpdate(delta: TimeInterval) {}
}

extension Animation: Equatable {
	static func ==(lhs: Animation, rhs: Animation) -> Bool {
		return lhs === rhs
	}
}

struct Property: Equatable, Hashable {
    
    let rawValue: String
    let index: Int
	let isRelative: Bool
    
    init(rawValue: String) {
        self.rawValue = rawValue
        self.index = -1
		self.isRelative = false
    }
    
	init(_ rawValue: String, at index: Int = -1, relative: Bool = false) {
        self.rawValue = rawValue
        self.index = index
		self.isRelative = relative
    }
    
    static var position: Property = Property(rawValue:"position")
	static var positionX: Property = Property(rawValue: "positionX")
	static var positionY: Property = Property(rawValue: "positionY")
	
	static let scale: Property = Property(rawValue:"scale")
	static var scaleWidth: Property = Property(rawValue: "scaleWidth")
	static var scaleHeight: Property = Property(rawValue: "scaleHeight")
	
    static let rotation: Property = Property(rawValue:"rotation")
	static let relativeRotation: Property = Property("relativeRotation", relative: true)
    
    var hashValue: Int {
		return rawValue.hashValue + (self.index + 1)
    }
    
    static func ==(lhs: Property, rhs: Property) -> Bool {
        return lhs.hashValue == rhs.hashValue
    }
}

protocol TargetPropertyContainer {
	weak var target: Animatable? { get }
	var property: Property { get }
}
{'fraction_non_alphanumeric': 0.10114902506963788, 'fraction_numerical': 0.005222841225626741, 'mean_word_length': 3.4328703703703702, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, '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': '943241', 'n_tokens_mistral': 1921, 'n_tokens_neox': 1729, 'n_words': 507}