<commit_before>package com.airbnb.lottie.animation;

import android.graphics.Path;
import android.graphics.PointF;

import com.airbnb.lottie.model.LottieCubicCurveData;
import com.airbnb.lottie.model.LottieShapeData;
import com.airbnb.lottie.utils.LottieKeyframeAnimation;
import com.airbnb.lottie.utils.LottieShapeKeyframeAnimation;
import com.airbnb.lottie.utils.MiscUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import static com.airbnb.lottie.utils.MiscUtils.addPoints;

@SuppressWarnings({"EmptyCatchBlock"})
public class LottieAnimatableShapeValue extends BaseLottieAnimatableValue<LottieShapeData, Path> {
    private final boolean closed;

    public LottieAnimatableShapeValue(JSONObject json, int frameRate, long compDuration, boolean closed) {
        this(json, frameRate, compDuration, closed, true);
    }

    private LottieAnimatableShapeValue(JSONObject json, int frameRate, long compDuration, boolean closed, boolean isDp) {
        super(null, frameRate, compDuration, isDp);
        this.closed = closed;
        init(json);
    }

    @Override
    protected LottieShapeData valueFromObject(Object object, float scale) throws JSONException {
        JSONObject pointsData = null;
        if (object instanceof JSONArray) {
            try {
                Object firstObject = ((JSONArray) object).get(0);
                if (firstObject instanceof JSONObject && ((JSONObject) firstObject).has("v")) {
                    pointsData = (JSONObject) firstObject;
                }
            } catch (JSONException e) {
                throw new IllegalStateException("Unable to get shape. " + object);
            }
        } else if (object instanceof JSONObject && ((JSONObject) object).has("v")) {
            pointsData = (JSONObject) object;
        }

        if (pointsData == null) {
            return null;
        }

        JSONArray pointsArray = null;
        JSONArray inTangents = null;
        JSONArray outTangents = null;
        try {
            pointsArray = pointsData.getJSONArray("v");
            inTangents = pointsData.getJSONArray("i");
            outTangents = pointsData.getJSONArray("o");
        } catch (JSONException e) { }

        if (pointsArray == null || inTangents == null || outTangents == null ||
                pointsArray.length() != inTangents.length() || pointsArray.length() != outTangents.length()) {
            throw new IllegalStateException("Unable to process points array or tangents. " + pointsData);
        }

        LottieShapeData shape = new LottieShapeData();

        PointF vertex = vertexAtIndex(0, pointsArray);
        vertex.x *= scale;
        vertex.y *= scale;
        shape.setInitialPoint(vertex);

        for (int i = 1; i < pointsArray.length(); i++) {
            vertex = vertexAtIndex(i, pointsArray);
            PointF previousVertex = vertexAtIndex(i - 1, pointsArray);
            PointF cp1 = vertexAtIndex(i - 1, outTangents);
            PointF cp2 = vertexAtIndex(i, inTangents);

            PointF shapeCp1 = addPoints(previousVertex, cp1);
            PointF shapeCp2 = addPoints(vertex, cp2);

            shapeCp1.x *= scale;
            shapeCp1.y *= scale;
            shapeCp2.x *= scale;
            shapeCp2.y *= scale;
            vertex.x *= scale;
            vertex.y *= scale;

            shape.addCurve(new LottieCubicCurveData(shapeCp1, shapeCp2, vertex));
        }

        if (closed) {
            vertex = vertexAtIndex(0, pointsArray);
            PointF previousVertex = vertexAtIndex(pointsArray.length() - 1, pointsArray);
            PointF cp1 = vertexAtIndex(pointsArray.length() - 1, outTangents);
            PointF cp2 = vertexAtIndex(0, inTangents);

            PointF shapeCp1 = addPoints(previousVertex, cp1);
            PointF shapeCp2 = addPoints(vertex, cp2);

            if (scale != 1f) {
                shapeCp1.x *= scale;
                shapeCp1.y *= scale;
                shapeCp2.x *= scale;
                shapeCp2.y *= scale;
                vertex.x *= scale;
                vertex.y *= scale;
            }

            shape.addCurve(new LottieCubicCurveData(shapeCp1, shapeCp2, vertex));
        }
        return shape;

    }

    private PointF vertexAtIndex(int idx, JSONArray points) {
        if (idx >= points.length()) {
            throw new IllegalArgumentException("Invalid index " + idx + ". There are only " + points.length() + " points.");
        }

        try {
            JSONArray pointArray = points.getJSONArray(idx);
            Object x = pointArray.get(0);
            Object y = pointArray.get(1);
            return new PointF(
                    x instanceof Double ? new Float((Double) x) : (int) x,
                    y instanceof Double ? new Float((Double) y) : (int) y);
        } catch (JSONException e) {
            throw new IllegalArgumentException("Unable to get point.", e);
        }
    }

    @Override
    public LottieKeyframeAnimation animationForKeyPath() {
        LottieShapeKeyframeAnimation animation = new LottieShapeKeyframeAnimation(duration, compDuration, keyTimes, keyValues, interpolators);
        // TODO: use this
//        animation.setStartDelay(delay);
        animation.addUpdateListener(new LottieKeyframeAnimation.AnimationListener<Path>() {
            @Override
            public void onValueChanged(Path progress) {
                observable.setValue(progress);
            }
        });
        return animation;
    }

    @Override
    Path convertType(LottieShapeData shapeData) {
        if (observable.getValue() == null) {
            observable.setValue(new Path());
        }
        MiscUtils.getPathFromData(shapeData, observable.getValue());
        return observable.getValue();<commit_msg>Reenabled shape start-delays<commit_after>package com.airbnb.lottie.animation;

import android.graphics.Path;
import android.graphics.PointF;

import com.airbnb.lottie.model.LottieCubicCurveData;
import com.airbnb.lottie.model.LottieShapeData;
import com.airbnb.lottie.utils.LottieKeyframeAnimation;
import com.airbnb.lottie.utils.LottieShapeKeyframeAnimation;
import com.airbnb.lottie.utils.MiscUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import static com.airbnb.lottie.utils.MiscUtils.addPoints;

@SuppressWarnings({"EmptyCatchBlock"})
public class LottieAnimatableShapeValue extends BaseLottieAnimatableValue<LottieShapeData, Path> {
    private final boolean closed;

    public LottieAnimatableShapeValue(JSONObject json, int frameRate, long compDuration, boolean closed) {
        this(json, frameRate, compDuration, closed, true);
    }

    private LottieAnimatableShapeValue(JSONObject json, int frameRate, long compDuration, boolean closed, boolean isDp) {
        super(null, frameRate, compDuration, isDp);
        this.closed = closed;
        init(json);
    }

    @Override
    protected LottieShapeData valueFromObject(Object object, float scale) throws JSONException {
        JSONObject pointsData = null;
        if (object instanceof JSONArray) {
            try {
                Object firstObject = ((JSONArray) object).get(0);
                if (firstObject instanceof JSONObject && ((JSONObject) firstObject).has("v")) {
                    pointsData = (JSONObject) firstObject;
                }
            } catch (JSONException e) {
                throw new IllegalStateException("Unable to get shape. " + object);
            }
        } else if (object instanceof JSONObject && ((JSONObject) object).has("v")) {
            pointsData = (JSONObject) object;
        }

        if (pointsData == null) {
            return null;
        }

        JSONArray pointsArray = null;
        JSONArray inTangents = null;
        JSONArray outTangents = null;
        try {
            pointsArray = pointsData.getJSONArray("v");
            inTangents = pointsData.getJSONArray("i");
            outTangents = pointsData.getJSONArray("o");
        } catch (JSONException e) { }

        if (pointsArray == null || inTangents == null || outTangents == null ||
                pointsArray.length() != inTangents.length() || pointsArray.length() != outTangents.length()) {
            throw new IllegalStateException("Unable to process points array or tangents. " + pointsData);
        }

        LottieShapeData shape = new LottieShapeData();

        PointF vertex = vertexAtIndex(0, pointsArray);
        vertex.x *= scale;
        vertex.y *= scale;
        shape.setInitialPoint(vertex);

        for (int i = 1; i < pointsArray.length(); i++) {
            vertex = vertexAtIndex(i, pointsArray);
            PointF previousVertex = vertexAtIndex(i - 1, pointsArray);
            PointF cp1 = vertexAtIndex(i - 1, outTangents);
            PointF cp2 = vertexAtIndex(i, inTangents);

            PointF shapeCp1 = addPoints(previousVertex, cp1);
            PointF shapeCp2 = addPoints(vertex, cp2);

            shapeCp1.x *= scale;
            shapeCp1.y *= scale;
            shapeCp2.x *= scale;
            shapeCp2.y *= scale;
            vertex.x *= scale;
            vertex.y *= scale;

            shape.addCurve(new LottieCubicCurveData(shapeCp1, shapeCp2, vertex));
        }

        if (closed) {
            vertex = vertexAtIndex(0, pointsArray);
            PointF previousVertex = vertexAtIndex(pointsArray.length() - 1, pointsArray);
            PointF cp1 = vertexAtIndex(pointsArray.length() - 1, outTangents);
            PointF cp2 = vertexAtIndex(0, inTangents);

            PointF shapeCp1 = addPoints(previousVertex, cp1);
            PointF shapeCp2 = addPoints(vertex, cp2);

            if (scale != 1f) {
                shapeCp1.x *= scale;
                shapeCp1.y *= scale;
                shapeCp2.x *= scale;
                shapeCp2.y *= scale;
                vertex.x *= scale;
                vertex.y *= scale;
            }

            shape.addCurve(new LottieCubicCurveData(shapeCp1, shapeCp2, vertex));
        }
        return shape;

    }

    private PointF vertexAtIndex(int idx, JSONArray points) {
        if (idx >= points.length()) {
            throw new IllegalArgumentException("Invalid index " + idx + ". There are only " + points.length() + " points.");
        }

        try {
            JSONArray pointArray = points.getJSONArray(idx);
            Object x = pointArray.get(0);
            Object y = pointArray.get(1);
            return new PointF(
                    x instanceof Double ? new Float((Double) x) : (int) x,
                    y instanceof Double ? new Float((Double) y) : (int) y);
        } catch (JSONException e) {
            throw new IllegalArgumentException("Unable to get point.", e);
        }
    }

    @Override
    public LottieKeyframeAnimation animationForKeyPath() {
        LottieShapeKeyframeAnimation animation = new LottieShapeKeyframeAnimation(duration, compDuration, keyTimes, keyValues, interpolators);
        animation.setStartDelay(delay);
        animation.addUpdateListener(new LottieKeyframeAnimation.AnimationListener<Path>() {
            @Override
            public void onValueChanged(Path progress) {
                observable.setValue(progress);
            }
        });
        return animation;
    }

    @Override
    Path convertType(LottieShapeData shapeData) {
        if (observable.getValue() == null) {
            observable.setValue(new Path());
        }
        MiscUtils.getPathFromData(shapeData, observable.getValue());
        return observable.getValue();
{'fraction_non_alphanumeric': 0.10071693875788201, 'fraction_numerical': 0.006219227779217414, 'mean_word_length': 2.3023388476896747, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '422264', 'n_tokens_mistral': 3273, 'n_tokens_neox': 3178, 'n_words': 736}