// Path: jrand-core/src/main/java/me/xdrop/jrand/Generator.java
// public abstract class Generator<T> {
// 
//     private Rand randGen;
// 
//     public Generator() {
//         this.randGen = new Rand();
//     }
// 
//     public Rand random() {
//         return this.randGen;
//     }
// 
//     public abstract T gen();
// 
//     public String repeat(int times) {
//         StringBuilder sb = new StringBuilder();
//         while (times-- > 0) {
//             sb.append(gen());
//         }
//         return sb.toString();
//     }
// 
//     public String genString() {
//         return gen().toString();
//     }
// 
//     public List<T> genMany(int num) {
//         List<T> many = new ArrayList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return many;
//     }
// 
//     public List<T> genManyUnique(int num) {
//         List<T> many = new LinkedList<>();
//         Set<T> present = new HashSet<>();
// 
// 
//         for (int n = 0; n < num; n++) {
//             T gen;
//             do {
//                 gen = gen();
//             } while (present.contains(gen));
//             many.add(gen);
//             present.add(gen);
//         }
// 
//         return many;
//     }
// 
//     public Set<T> genManyAsSet(int num) {
//         List<T> many = new LinkedList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return new HashSet<>(many);
//     }
// 
// }
// 
// Path: jrand-core/src/main/java/me/xdrop/jrand/model/Range.java
// public class Range<T extends Number> {
//     private T min;
//     private T max;
// 
//     public static <T extends Number> Range<T> from(T min, T max) {
//         return new Range<>(min, max);
//     }
// 
//     public static <T extends Number> Range<T> from(T fixed) {
//         return new Range<>(fixed, fixed);
//     }
// 
//     private Range(T min, T max) {
//         this.min = min;
//         this.max = max;
//     }
// 
//     public boolean isSingle() {
//         return min.equals(max);
//     }
// 
//     public T getMin() {
//         return min;
//     }
// 
//     public T getMax() {
//         return max;
//     }
// 
//     public Range<T> newMin(T min) {
//         return new Range<>(min, max);
//     }
// 
//     public Range<T> newMax(T max) {
//         return new Range<>(min, max);
//     }
// }


import me.xdrop.jrand.Generator;
import me.xdrop.jrand.annotation.Facade;
import me.xdrop.jrand.model.Range;
import java.util.ArrayList;
import java.util.List;
package me.xdrop.jrand.generators.basics;



@Facade(accessor = "natural")
public class NaturalGenerator extends Generator<Integer> {

    protected int min;
    protected int max;

    public NaturalGenerator() {
        this.max = Integer.MAX_VALUE - 1;
        this.min = 0;
    }

    /**
     * Set the minimum value (inclusive)
     *
     * @param min The minimum value
     * @return The same generator
     */
    public NaturalGenerator min(int min) {
        this.min = min;
        return this;
    }

    /**
     * Set the maximum value to return (inclusive)
     *
     * @param max The maximum value to return (inclusive)
     * @return The same generator
     */
    public NaturalGenerator max(int max) {
        this.max = max;
        return this;
    }

    /**
     * Set a min/max range
     *
     * @param min Minimum value to be returned (inclusive)
     * @param max Maximum value to be returned (inclusive)
     * @return The same generator
     */
    public NaturalGenerator range(int min, int max) {
        min(min);
        max(max);
        return this;
    }

    /**
     * Set a range starting from 0
     *
     * @param max Maximum value to be returned (inclusive)
     * @return The same generator
     */
    public NaturalGenerator range(int max) {
        min(0);
        max(max - 1);
        return this;
    }

// Path: jrand-core/src/main/java/me/xdrop/jrand/Generator.java
// public abstract class Generator<T> {
// 
//     private Rand randGen;
// 
//     public Generator() {
//         this.randGen = new Rand();
//     }
// 
//     public Rand random() {
//         return this.randGen;
//     }
// 
//     public abstract T gen();
// 
//     public String repeat(int times) {
//         StringBuilder sb = new StringBuilder();
//         while (times-- > 0) {
//             sb.append(gen());
//         }
//         return sb.toString();
//     }
// 
//     public String genString() {
//         return gen().toString();
//     }
// 
//     public List<T> genMany(int num) {
//         List<T> many = new ArrayList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return many;
//     }
// 
//     public List<T> genManyUnique(int num) {
//         List<T> many = new LinkedList<>();
//         Set<T> present = new HashSet<>();
// 
// 
//         for (int n = 0; n < num; n++) {
//             T gen;
//             do {
//                 gen = gen();
//             } while (present.contains(gen));
//             many.add(gen);
//             present.add(gen);
//         }
// 
//         return many;
//     }
// 
//     public Set<T> genManyAsSet(int num) {
//         List<T> many = new LinkedList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return new HashSet<>(many);
//     }
// 
// }
// 
// Path: jrand-core/src/main/java/me/xdrop/jrand/model/Range.java
// public class Range<T extends Number> {
//     private T min;
//     private T max;
// 
//     public static <T extends Number> Range<T> from(T min, T max) {
//         return new Range<>(min, max);
//     }
// 
//     public static <T extends Number> Range<T> from(T fixed) {
//         return new Range<>(fixed, fixed);
//     }
// 
//     private Range(T min, T max) {
//         this.min = min;
//         this.max = max;
//     }
// 
//     public boolean isSingle() {
//         return min.equals(max);
//     }
// 
//     public T getMin() {
//         return min;
//     }
// 
//     public T getMax() {
//         return max;
//     }
// 
//     public Range<T> newMin(T min) {
//         return new Range<>(min, max);
//     }
// 
//     public Range<T> newMax(T max) {
//         return new Range<>(min, max);
//     }
// }


// Path: jrand-core/src/main/java/me/xdrop/jrand/generators/basics/NaturalGenerator.java
import me.xdrop.jrand.Generator;
import me.xdrop.jrand.annotation.Facade;
import me.xdrop.jrand.model.Range;
import java.util.ArrayList;
import java.util.List;

package me.xdrop.jrand.generators.basics;



@Facade(accessor = "natural")
public class NaturalGenerator extends Generator<Integer> {

    protected int min;
    protected int max;

    public NaturalGenerator() {
        this.max = Integer.MAX_VALUE - 1;
        this.min = 0;
    }

    /**
     * Set the minimum value (inclusive)
     *
     * @param min The minimum value
     * @return The same generator
     */
    public NaturalGenerator min(int min) {
        this.min = min;
        return this;
    }

    /**
     * Set the maximum value to return (inclusive)
     *
     * @param max The maximum value to return (inclusive)
     * @return The same generator
     */
    public NaturalGenerator max(int max) {
        this.max = max;
        return this;
    }

    /**
     * Set a min/max range
     *
     * @param min Minimum value to be returned (inclusive)
     * @param max Maximum value to be returned (inclusive)
     * @return The same generator
     */
    public NaturalGenerator range(int min, int max) {
        min(min);
        max(max);
        return this;
    }

    /**
     * Set a range starting from 0
     *
     * @param max Maximum value to be returned (inclusive)
     * @return The same generator
     */
    public NaturalGenerator range(int max) {
        min(0);
        max(max - 1);
        return this;
    }

    public NaturalGenerator range(Range<Integer> rangeOption) {