// Path: app/src/main/java/com/annimon/hotarufx/exceptions/HotaruRuntimeException.java
// public class HotaruRuntimeException extends RuntimeException {
// 
//     public HotaruRuntimeException(String s) {
//         super(s);
//     }
// 
//     public HotaruRuntimeException(String string, SourcePosition start, SourcePosition end) {
//         super(string + " at " + start + " .. " + end);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/exceptions/TypeException.java
// public class TypeException extends HotaruRuntimeException {
// 
//     public TypeException(String message) {
//         super(message);
//     }
// 
//     public TypeException(String message, SourcePosition start, SourcePosition end) {
//         super(message, start, end);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/visual/KeyFrame.java
// public class KeyFrame implements Comparable<KeyFrame> {
// 
//     public static KeyFrame of(int frame) {
//         return new KeyFrame(frame);
//     }
// 
//     private KeyFrame(int frame) {
//         this.frame = frame;
//     }
// 
//     private final int frame;
// 
//     public int getFrame() {
//         return frame;
//     }
// 
//     @Override
//     public int compareTo(KeyFrame o) {
//         return Integer.compare(frame, o.frame);
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
//         KeyFrame keyFrame = (KeyFrame) o;
//         return frame == keyFrame.frame;
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(frame);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/visual/Property.java
// public final class Property {
// 
//     private final PropertyType type;
//     private final Supplier<PropertyTimeline<?>> property;
// 
//     public Property(PropertyType type, Supplier<PropertyTimeline<?>> property) {
//         this.type = type;
//         this.property = property;
//     }
// 
//     public PropertyType getType() {
//         return type;
//     }
// 
//     public Supplier<PropertyTimeline<?>> getProperty() {
//         return property;
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/visual/PropertyTimeline.java
// public class PropertyTimeline<T> {
// 
//     private final WritableValue<T> property;
//     private final Map<KeyFrame, KeyFrameValue<T>> keyFrames;
// 
//     public PropertyTimeline(WritableValue<T> property) {
//         this.property = property;
//         keyFrames = new TreeMap<>();
//     }
// 
//     public WritableValue<T> getProperty() {
//         return property;
//     }
// 
//     public Map<KeyFrame, KeyFrameValue<T>> getKeyFrames() {
//         return keyFrames;
//     }
// 
//     public PropertyTimeline<T> add(KeyFrame keyFrame, T value) {
//         keyFrames.put(keyFrame, new KeyFrameValue<>(value));
//         return this;
//     }
// 
//     public PropertyTimeline<T> add(KeyFrame keyFrame, T value, Interpolator interpolator) {
//         keyFrames.put(keyFrame, new KeyFrameValue<>(value, interpolator));
//         return this;
//     }
// 
//     public PropertyTimeline<T> clear() {
//         keyFrames.clear();
//         return this;
//     }
// }


import com.annimon.hotarufx.exceptions.HotaruRuntimeException;
import com.annimon.hotarufx.exceptions.TypeException;
import com.annimon.hotarufx.visual.KeyFrame;
import com.annimon.hotarufx.visual.Property;
import com.annimon.hotarufx.visual.PropertyTimeline;
import java.util.HashMap;
import java.util.Map;
import javafx.animation.Interpolator;
import javafx.scene.Node;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;

    @Override
    public int type() {
        return Types.PROPERTY;
    }

    public Value getField(String name) {
        final var field = fields.get(name);
        if (field == null) {
            throw new HotaruRuntimeException("PropertyValue does not have " + name + " field");
        }
        return field;
    }

    @SuppressWarnings("unchecked")
    private Function add() {
        return args -> {
            Validator.with(args).checkOrOr(2, 3);
            final Interpolator interpolator;
            if (args.length == 2) {
                interpolator = Interpolator.LINEAR;
            } else {
                if (args[2].type() != Types.INTERPOLATOR) {
                    throw new TypeException("Interpolator required at third argument");
                }
                interpolator = ((InterpolatorValue) args[2]).getInterpolator();
            }
            final var type = property.getType();
            switch (type) {
                case BOOLEAN:
// Path: app/src/main/java/com/annimon/hotarufx/exceptions/HotaruRuntimeException.java
// public class HotaruRuntimeException extends RuntimeException {
// 
//     public HotaruRuntimeException(String s) {
//         super(s);
//     }
// 
//     public HotaruRuntimeException(String string, SourcePosition start, SourcePosition end) {
//         super(string + " at " + start + " .. " + end);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/exceptions/TypeException.java
// public class TypeException extends HotaruRuntimeException {
// 
//     public TypeException(String message) {
//         super(message);
//     }
// 
//     public TypeException(String message, SourcePosition start, SourcePosition end) {
//         super(message, start, end);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/visual/KeyFrame.java
// public class KeyFrame implements Comparable<KeyFrame> {
// 
//     public static KeyFrame of(int frame) {
//         return new KeyFrame(frame);
//     }
// 
//     private KeyFrame(int frame) {
//         this.frame = frame;
//     }
// 
//     private final int frame;
// 
//     public int getFrame() {
//         return frame;
//     }
// 
//     @Override
//     public int compareTo(KeyFrame o) {
//         return Integer.compare(frame, o.frame);
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
//         KeyFrame keyFrame = (KeyFrame) o;
//         return frame == keyFrame.frame;
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(frame);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/visual/Property.java
// public final class Property {
// 
//     private final PropertyType type;
//     private final Supplier<PropertyTimeline<?>> property;
// 
//     public Property(PropertyType type, Supplier<PropertyTimeline<?>> property) {
//         this.type = type;
//         this.property = property;
//     }
// 
//     public PropertyType getType() {
//         return type;
//     }
// 
//     public Supplier<PropertyTimeline<?>> getProperty() {
//         return property;
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/visual/PropertyTimeline.java
// public class PropertyTimeline<T> {
// 
//     private final WritableValue<T> property;
//     private final Map<KeyFrame, KeyFrameValue<T>> keyFrames;
// 
//     public PropertyTimeline(WritableValue<T> property) {
//         this.property = property;
//         keyFrames = new TreeMap<>();
//     }
// 
//     public WritableValue<T> getProperty() {
//         return property;
//     }
// 
//     public Map<KeyFrame, KeyFrameValue<T>> getKeyFrames() {
//         return keyFrames;
//     }
// 
//     public PropertyTimeline<T> add(KeyFrame keyFrame, T value) {
//         keyFrames.put(keyFrame, new KeyFrameValue<>(value));
//         return this;
//     }
// 
//     public PropertyTimeline<T> add(KeyFrame keyFrame, T value, Interpolator interpolator) {
//         keyFrames.put(keyFrame, new KeyFrameValue<>(value, interpolator));
//         return this;
//     }
// 
//     public PropertyTimeline<T> clear() {
//         keyFrames.clear();
//         return this;
//     }
// }


// Path: app/src/main/java/com/annimon/hotarufx/lib/PropertyValue.java
import com.annimon.hotarufx.exceptions.HotaruRuntimeException;
import com.annimon.hotarufx.exceptions.TypeException;
import com.annimon.hotarufx.visual.KeyFrame;
import com.annimon.hotarufx.visual.Property;
import com.annimon.hotarufx.visual.PropertyTimeline;
import java.util.HashMap;
import java.util.Map;
import javafx.animation.Interpolator;
import javafx.scene.Node;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;


    @Override
    public int type() {
        return Types.PROPERTY;
    }

    public Value getField(String name) {
        final var field = fields.get(name);
        if (field == null) {
            throw new HotaruRuntimeException("PropertyValue does not have " + name + " field");
        }
        return field;
    }

    @SuppressWarnings("unchecked")
    private Function add() {
        return args -> {
            Validator.with(args).checkOrOr(2, 3);
            final Interpolator interpolator;
            if (args.length == 2) {
                interpolator = Interpolator.LINEAR;
            } else {
                if (args[2].type() != Types.INTERPOLATOR) {
                    throw new TypeException("Interpolator required at third argument");
                }
                interpolator = ((InterpolatorValue) args[2]).getInterpolator();
            }
            final var type = property.getType();
            switch (type) {
                case BOOLEAN:
                    ((PropertyTimeline<Boolean>)property.getProperty().get()).add(