<commit_before>package com.annimon.hotarufx.visual.objects;

import com.annimon.hotarufx.visual.PropertyBindings;
import com.annimon.hotarufx.visual.PropertyTimeline;
import com.annimon.hotarufx.visual.PropertyTimelineHolder;
import com.annimon.hotarufx.visual.TimeLine;
import com.annimon.hotarufx.visual.visitors.NodeVisitor;
import javafx.scene.shape.SVGPath;
import static com.annimon.hotarufx.visual.PropertyType.STRING;

public class SVGPathNode extends ShapeNode {

    public final SVGPath svgPath;

    private PropertyTimelineHolder<String> content;

    public SVGPathNode() {
        this(new SVGPath());
    }

    private SVGPathNode(SVGPath svgPath) {
        super(svgPath);
        this.svgPath = svgPath;
        content = PropertyTimelineHolder.empty();
    }

    public PropertyTimeline<String> contentProperty() {
        return content.setIfEmptyThenGet(svgPath::contentProperty);
    }

    @Override
    public void buildTimeline(TimeLine timeline) {
        super.buildTimeline(timeline);
        content.applyIfPresent(timeline);
    }

    @Override
    public PropertyBindings propertyBindings(PropertyBindings bindings) {
        return super.propertyBindings(bindings)
                .add("content", STRING, this::contentProperty);
    }

    @Override
    public <R, T> R accept(NodeVisitor<R, T> visitor, T input) {
        return visitor.visit(this, input);
    }
}
<commit_msg>Add fill rule svg property<commit_after>package com.annimon.hotarufx.visual.objects;

import com.annimon.hotarufx.visual.PropertyBindings;
import com.annimon.hotarufx.visual.PropertyTimeline;
import com.annimon.hotarufx.visual.PropertyTimelineHolder;
import com.annimon.hotarufx.visual.TimeLine;
import com.annimon.hotarufx.visual.visitors.NodeVisitor;
import javafx.scene.shape.FillRule;
import javafx.scene.shape.SVGPath;
import static com.annimon.hotarufx.visual.PropertyType.STRING;

public class SVGPathNode extends ShapeNode {

    public final SVGPath svgPath;

    private PropertyTimelineHolder<String> content;
    private PropertyTimelineHolder<String> fillRule;

    public SVGPathNode() {
        this(new SVGPath());
    }

    private SVGPathNode(SVGPath svgPath) {
        super(svgPath);
        this.svgPath = svgPath;
        content = PropertyTimelineHolder.empty();
        fillRule = PropertyTimelineHolder.empty();
    }

    public PropertyTimeline<String> contentProperty() {
        return content.setIfEmptyThenGet(svgPath::contentProperty);
    }

    public PropertyTimeline<String> fillRuleProperty() {
        return fillRule.setIfEmptyThenGet(enumToString(FillRule.class, svgPath.fillRuleProperty()));
    }

    @Override
    public void buildTimeline(TimeLine timeline) {
        super.buildTimeline(timeline);
        content.applyIfPresent(timeline);
        fillRule.applyIfPresent(timeline);
    }

    @Override
    public PropertyBindings propertyBindings(PropertyBindings bindings) {
        return super.propertyBindings(bindings)
                .add("content", STRING, this::contentProperty)
                .add("fillRule", STRING, this::fillRuleProperty);
    }

    @Override
    public <R, T> R accept(NodeVisitor<R, T> visitor, T input) {
        return visitor.visit(this, input);
    }
}

{'fraction_non_alphanumeric': 0.0953259532595326, 'fraction_numerical': 0.0, 'mean_word_length': 3.7489051094890513, 'pattern_counts': {'":': 0, '<': 13, '<?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': '5452798', 'n_tokens_mistral': 1017, 'n_tokens_neox': 962, 'n_words': 173}