// Path: jrand-core/src/main/java/me/xdrop/jrand/Tuple.java
// public class Tuple<K,V> {
//     K key;
//     V val;
// 
//     public Tuple(K key, V val) {
//         this.key = key;
//         this.val = val;
//     }
// 
//     public K getKey() {
//         return key;
//     }
// 
//     public void setKey(K key) {
//         this.key = key;
//     }
// 
//     public V getVal() {
//         return val;
//     }
// 
//     public void setVal(V val) {
//         this.val = val;
//     }
// 
//     public static <K,V> Tuple<K,V> from(K key, V val) {
//         return new Tuple<>(key,val);
//     }
// }


import me.xdrop.jrand.Tuple;
import java.util.*;
package me.xdrop.jrand.data;



public class AssetDescriptor<T> {

    private final String fileName;
    private final AssetMapper<T> mapper;
    private final IndexMapper<T> aliasIndexMapper;
    private final IndexMapper<T> groupingIndexMapper;

    public AssetDescriptor(String fileName, AssetMapper<T> mapper, IndexMapper<T> aliasIndexMapper, IndexMapper<T> groupingIndexMapper) {
        this.fileName = fileName;
        this.mapper = mapper;
        this.aliasIndexMapper = aliasIndexMapper;
        this.groupingIndexMapper = groupingIndexMapper;
    }

    public AssetDescriptor(String fileName, AssetMapper<T> mapper, IndexMapper<T> aliasIndexMapper) {
        this.fileName = fileName;
        this.mapper = mapper;
        this.aliasIndexMapper = aliasIndexMapper;
        this.groupingIndexMapper = null;
    }

    public AssetDescriptor(String fileName, AssetMapper<T> mapper) {
        this.fileName = fileName;
        this.mapper = mapper;
        this.aliasIndexMapper = null;
        this.groupingIndexMapper = null;
    }

    private Map<String, T> createAliasIndex(Asset<T> asset) {
        Map<String,T> aliasIndex = new HashMap<>();
        for (T t : asset.getItems()) {
// Path: jrand-core/src/main/java/me/xdrop/jrand/Tuple.java
// public class Tuple<K,V> {
//     K key;
//     V val;
// 
//     public Tuple(K key, V val) {
//         this.key = key;
//         this.val = val;
//     }
// 
//     public K getKey() {
//         return key;
//     }
// 
//     public void setKey(K key) {
//         this.key = key;
//     }
// 
//     public V getVal() {
//         return val;
//     }
// 
//     public void setVal(V val) {
//         this.val = val;
//     }
// 
//     public static <K,V> Tuple<K,V> from(K key, V val) {
//         return new Tuple<>(key,val);
//     }
// }


// Path: jrand-core/src/main/java/me/xdrop/jrand/data/AssetDescriptor.java
import me.xdrop.jrand.Tuple;
import java.util.*;

package me.xdrop.jrand.data;



public class AssetDescriptor<T> {

    private final String fileName;
    private final AssetMapper<T> mapper;
    private final IndexMapper<T> aliasIndexMapper;
    private final IndexMapper<T> groupingIndexMapper;

    public AssetDescriptor(String fileName, AssetMapper<T> mapper, IndexMapper<T> aliasIndexMapper, IndexMapper<T> groupingIndexMapper) {
        this.fileName = fileName;
        this.mapper = mapper;
        this.aliasIndexMapper = aliasIndexMapper;
        this.groupingIndexMapper = groupingIndexMapper;
    }

    public AssetDescriptor(String fileName, AssetMapper<T> mapper, IndexMapper<T> aliasIndexMapper) {
        this.fileName = fileName;
        this.mapper = mapper;
        this.aliasIndexMapper = aliasIndexMapper;
        this.groupingIndexMapper = null;
    }

    public AssetDescriptor(String fileName, AssetMapper<T> mapper) {
        this.fileName = fileName;
        this.mapper = mapper;
        this.aliasIndexMapper = null;
        this.groupingIndexMapper = null;
    }

    private Map<String, T> createAliasIndex(Asset<T> asset) {
        Map<String,T> aliasIndex = new HashMap<>();
        for (T t : asset.getItems()) {
            Tuple<String, T> alias = Objects.requireNonNull(aliasIndexMapper).indexedMap(t);