import {
  map2 as map
} from "./chunk-3AL4EMTU.mjs";
import {
  separated
} from "./chunk-RAKKSTP2.mjs";
import {
  wiltDefault,
  witherDefault
} from "./chunk-DQQFH64X.mjs";
import {
  flap
} from "./chunk-WKK6AYQI.mjs";
import {
  fromEquals
} from "./chunk-YQKF55QL.mjs";
import {
  isLeft,
  isNone,
  isSome,
  none,
  some
} from "./chunk-WPJQNT3M.mjs";
import {
  SK,
  pipe
} from "./chunk-ZI34HWXZ.mjs";
import {
  __export
} from "./chunk-QK4PKNB3.mjs";

// src/ReadonlyMap.ts
var ReadonlyMap_exports = {};
__export(ReadonlyMap_exports, {
  Compactable: () => Compactable,
  Filterable: () => Filterable,
  Functor: () => Functor,
  URI: () => URI,
  collect: () => collect,
  compact: () => compact,
  deleteAt: () => deleteAt,
  difference: () => difference,
  elem: () => elem,
  empty: () => empty,
  filter: () => filter,
  filterMap: () => filterMap,
  filterMapWithIndex: () => filterMapWithIndex,
  filterWithIndex: () => filterWithIndex,
  flap: () => flap2,
  foldMap: () => foldMap,
  foldMapWithIndex: () => foldMapWithIndex,
  fromFoldable: () => fromFoldable,
  fromMap: () => fromMap,
  getDifferenceMagma: () => getDifferenceMagma,
  getEq: () => getEq,
  getFilterableWithIndex: () => getFilterableWithIndex,
  getFoldable: () => getFoldable,
  getFoldableWithIndex: () => getFoldableWithIndex,
  getFunctorWithIndex: () => getFunctorWithIndex,
  getIntersectionSemigroup: () => getIntersectionSemigroup,
  getMonoid: () => getMonoid,
  getShow: () => getShow,
  getTraversable: () => getTraversable,
  getTraversableWithIndex: () => getTraversableWithIndex,
  getUnionMonoid: () => getUnionMonoid,
  getUnionSemigroup: () => getUnionSemigroup,
  getWitherable: () => getWitherable,
  insertAt: () => insertAt,
  intersection: () => intersection,
  isEmpty: () => isEmpty,
  isSubmap: () => isSubmap,
  keys: () => keys,
  lookup: () => lookup,
  lookupWithKey: () => lookupWithKey,
  map: () => map2,
  mapWithIndex: () => mapWithIndex,
  member: () => member,
  modifyAt: () => modifyAt,
  partition: () => partition,
  partitionMap: () => partitionMap,
  partitionMapWithIndex: () => partitionMapWithIndex,
  partitionWithIndex: () => partitionWithIndex,
  pop: () => pop,
  readonlyMap: () => readonlyMap,
  reduce: () => reduce,
  reduceRight: () => reduceRight,
  reduceRightWithIndex: () => reduceRightWithIndex,
  reduceWithIndex: () => reduceWithIndex,
  separate: () => separate,
  singleton: () => singleton,
  size: () => size,
  toMap: () => toMap,
  toReadonlyArray: () => toReadonlyArray,
  toUnfoldable: () => toUnfoldable,
  union: () => union,
  updateAt: () => updateAt,
  upsertAt: () => upsertAt,
  values: () => values
});
var fromMap = (m) => new Map(m);
function toMap(m) {
  return new Map(m);
}
function getShow(SK2, SA) {
  return {
    show: (m) => {
      const entries = [];
      m.forEach((a, k) => {
        entries.push(`[${SK2.show(k)}, ${SA.show(a)}]`);
      });
      return `new Map([${entries.sort().join(", ")}])`;
    }
  };
}
var size = (m) => m.size;
var isEmpty = (m) => m.size === 0;
function member(E) {
  const lookupE = lookup(E);
  return (k, m) => {
    if (m === void 0) {
      const memberE = member(E);
      return (m2) => memberE(k, m2);
    }
    return isSome(lookupE(k, m));
  };
}
function elem(E) {
  return (a, m) => {
    if (m === void 0) {
      const elemE = elem(E);
      return (m2) => elemE(a, m2);
    }
    const values2 = m.values();
    let e;
    while (!(e = values2.next()).done) {
      const v = e.value;
      if (E.equals(a, v)) {
        return true;
      }
    }
    return false;
  };
}
var keys = (O) => (m) => Array.from(m.keys()).sort(O.compare);
var values = (O) => (m) => Array.from(m.values()).sort(O.compare);
function collect(O) {
  const keysO = keys(O);
  return (f) => (m) => {
    const out = [];
    const ks = keysO(m);
    for (const key of ks) {
      out.push(f(key, m.get(key)));
    }
    return out;
  };
}
var toReadonlyArray = (O) => collect(O)((k, a) => [k, a]);
function toUnfoldable(ord, U) {
  const toReadonlyArrayO = toReadonlyArray(ord);
  return (d) => {
    const kas = toReadonlyArrayO(d);
    const len = kas.length;
    return U.unfold(0, (b) => b < len ? some([kas[b], b + 1]) : none);
  };
}
var upsertAt = (E) => {
  const lookupWithKeyE = lookupWithKey(E);
  return (k, a) => {
    const lookupWithKeyEk = lookupWithKeyE(k);
    return (m) => {
      const found = lookupWithKeyEk(m);
      if (isNone(found)) {
        const out = new Map(m);
        out.set(k, a);
        return out;
      } else if (found.value[1] !== a) {
        const out = new Map(m);
        out.set(found.value[0], a);
        return out;
      }
      return m;
    };
  };
};
var deleteAt = (E) => {
  const lookupWithKeyE = lookupWithKey(E);
  return (k) => (m) => {
    const found = lookupWithKeyE(k, m);
    if (isSome(found)) {
      const r = new Map(m);
      r.delete(found.value[0]);
      return r;
    }
    return m;
  };
};
var updateAt = (E) => {
  const modifyAtE = modifyAt(E);
  return (k, a) => modifyAtE(k, () => a);
};
var modifyAt = (E) => {
  const lookupWithKeyE = lookupWithKey(E);
  return (k, f) => (m) => {
    const found = lookupWithKeyE(k, m);
    if (isNone(found)) {
      return none;
    }
    const [fk, fv] = found.value;
    const next = f(fv);
    if (next === fv) {
      return some(m);
    }
    const r = new Map(m);
    r.set(fk, next);
    return some(r);
  };
};
function pop(E) {
  const lookupE = lookup(E);
  const deleteAtE = deleteAt(E);
  return (k) => {
    const deleteAtEk = deleteAtE(k);
    return (m) => pipe(
      lookupE(k, m),
      map((a) => [a, deleteAtEk(m)])
    );
  };
}
function lookupWithKey(E) {
  return (k, m) => {
    if (m === void 0) {
      const lookupWithKeyE = lookupWithKey(E);
      return (m2) => lookupWithKeyE(k, m2);
    }
    const entries = m.entries();
    let e;
    while (!(e = entries.next()).done) {
      const [ka, a] = e.value;
      if (E.equals(ka, k)) {
        return some([ka, a]);
      }
    }
    return none;
  };
}
function lookup(E) {
  const lookupWithKeyE = lookupWithKey(E);
  return (k, m) => {
    if (m === void 0) {
      const lookupE = lookup(E);
      return (m2) => lookupE(k, m2);
    }
    return pipe(
      lookupWithKeyE(k, m),
      map(([_, a]) => a)
    );
  };
}
function isSubmap(SK2, SA) {
  const lookupWithKeyS = lookupWithKey(SK2);
  return (me, that) => {
    if (that === void 0) {
      const isSubmapSKSA = isSubmap(SK2, SA);
      return (that2) => isSubmapSKSA(that2, me);
    }
    const entries = me.entries();
    let e;
    while (!(e = entries.next()).done) {
      const [k, a] = e.value;
      const d2OptA = lookupWithKeyS(k, that);
      if (isNone(d2OptA) || !SK2.equals(k, d2OptA.value[0]) || !SA.equals(a, d2OptA.value[1])) {
        return false;
      }
    }
    return true;
  };
}
var empty = (
  // the type annotation here is intended (otherwise it doesn't type-check)
  /* @__PURE__ */ new Map()
);
function getEq(SK2, SA) {
  const isSubmapSKSA = isSubmap(SK2, SA);
  return fromEquals((x, y) => isSubmapSKSA(x, y) && isSubmapSKSA(y, x));
}
function getMonoid(SK2, SA) {
  const lookupWithKeyS = lookupWithKey(SK2);
  return {
    concat: (mx, my) => {
      if (isEmpty(mx)) {
        return my;
      }
      if (isEmpty(my)) {
        return mx;
      }
      const r = new Map(mx);
      const entries = my.entries();
      let e;
      while (!(e = entries.next()).done) {
        const [k, a] = e.value;
        const mxOptA = lookupWithKeyS(k, mx);
        if (isSome(mxOptA)) {
          r.set(mxOptA.value[0], SA.concat(mxOptA.value[1], a));
        } else {
          r.set(k, a);
        }
      }
      return r;
    },
    empty
  };
}
var singleton = (k, a) => /* @__PURE__ */ new Map([[k, a]]);
function fromFoldable(E, M, F) {
  return (fka) => {
    const lookupWithKeyE = lookupWithKey(E);
    return F.reduce(fka, /* @__PURE__ */ new Map(), (b, [k, a]) => {
      const bOpt = lookupWithKeyE(k, b);
      if (isSome(bOpt)) {
        b.set(bOpt.value[0], M.concat(bOpt.value[1], a));
      } else {
        b.set(k, a);
      }
      return b;
    });
  };
}
var _mapWithIndex = (fa, f) => {
  const m = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [key, a] = e.value;
    m.set(key, f(key, a));
  }
  return m;
};
var partitionMapWithIndex = (f) => (fa) => {
  const left = /* @__PURE__ */ new Map();
  const right = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [k, a] = e.value;
    const ei = f(k, a);
    if (isLeft(ei)) {
      left.set(k, ei.left);
    } else {
      right.set(k, ei.right);
    }
  }
  return separated(left, right);
};
function partitionWithIndex(predicateWithIndex) {
  return (m) => {
    const left = /* @__PURE__ */ new Map();
    const right = /* @__PURE__ */ new Map();
    const entries = m.entries();
    let e;
    while (!(e = entries.next()).done) {
      const [k, a] = e.value;
      if (predicateWithIndex(k, a)) {
        right.set(k, a);
      } else {
        left.set(k, a);
      }
    }
    return separated(left, right);
  };
}
var filterMapWithIndex = (f) => (fa) => {
  const m = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [k, a] = e.value;
    const o = f(k, a);
    if (isSome(o)) {
      m.set(k, o.value);
    }
  }
  return m;
};
function filterWithIndex(predicateWithIndex) {
  return (m) => {
    const out = /* @__PURE__ */ new Map();
    const entries = m.entries();
    let e;
    while (!(e = entries.next()).done) {
      const [k, a] = e.value;
      if (predicateWithIndex(k, a)) {
        out.set(k, a);
      }
    }
    return out;
  };
}
var _map = (fa, f) => _mapWithIndex(fa, (_, a) => f(a));
var _filter = (fa, p) => _filterWithIndex(fa, (_, a) => p(a));
var _filterMap = (fa, f) => _filterMapWithIndex(fa, (_, a) => f(a));
var _partition = (fa, predicate) => _partitionWithIndex(fa, (_, a) => predicate(a));
var _partitionMap = (fa, f) => _partitionMapWithIndex(fa, (_, a) => f(a));
var _filterWithIndex = (fa, p) => pipe(fa, filterWithIndex(p));
var _filterMapWithIndex = (fa, f) => pipe(fa, filterMapWithIndex(f));
var _partitionWithIndex = (fa, p) => pipe(fa, partitionWithIndex(p));
var _partitionMapWithIndex = (fa, f) => pipe(fa, partitionMapWithIndex(f));
var compact = (fa) => {
  const m = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [k, oa] = e.value;
    if (isSome(oa)) {
      m.set(k, oa.value);
    }
  }
  return m;
};
var filter = (predicate) => (fa) => _filter(fa, predicate);
var filterMap = (f) => (fa) => _filterMap(fa, f);
var map2 = (f) => (fa) => _map(fa, f);
var mapWithIndex = (f) => (fa) => _mapWithIndex(fa, f);
var partition = (predicate) => (fa) => _partition(fa, predicate);
var partitionMap = (f) => (fa) => _partitionMap(fa, f);
var separate = (fa) => {
  const left = /* @__PURE__ */ new Map();
  const right = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [k, ei] = e.value;
    if (isLeft(ei)) {
      left.set(k, ei.left);
    } else {
      right.set(k, ei.right);
    }
  }
  return separated(left, right);
};
var URI = "ReadonlyMap";
var getUnionSemigroup = (E, S) => {
  const unionES = union(E, S);
  return {
    concat: (first, second) => unionES(second)(first)
  };
};
var getUnionMonoid = (E, S) => ({
  concat: getUnionSemigroup(E, S).concat,
  empty
});
var getIntersectionSemigroup = (E, S) => {
  const intersectionES = intersection(E, S);
  return {
    concat: (first, second) => intersectionES(second)(first)
  };
};
var getDifferenceMagma = (E) => () => {
  const differenceE = difference(E);
  return {
    concat: (first, second) => differenceE(second)(first)
  };
};
function getFilterableWithIndex() {
  return {
    URI,
    _E: void 0,
    map: _map,
    mapWithIndex: _mapWithIndex,
    compact,
    separate,
    filter: _filter,
    filterMap: _filterMap,
    partition: _partition,
    partitionMap: _partitionMap,
    partitionMapWithIndex: _partitionMapWithIndex,
    partitionWithIndex: _partitionWithIndex,
    filterMapWithIndex: _filterMapWithIndex,
    filterWithIndex: _filterWithIndex
  };
}
var Functor = {
  URI,
  map: _map
};
var flap2 = /* @__PURE__ */ flap(Functor);
var getFunctorWithIndex = () => ({
  URI,
  _E: void 0,
  map: _map,
  mapWithIndex: _mapWithIndex
});
var Compactable = {
  URI,
  compact,
  separate
};
var Filterable = {
  URI,
  map: _map,
  compact,
  separate,
  filter: _filter,
  filterMap: _filterMap,
  partition: _partition,
  partitionMap: _partitionMap
};
var reduce = (O) => {
  const reduceWithIndexO = reduceWithIndex(O);
  return (b, f) => reduceWithIndexO(b, (_, b2, a) => f(b2, a));
};
var foldMap = (O) => {
  const foldMapWithIndexO = foldMapWithIndex(O);
  return (M) => {
    const foldMapWithIndexOM = foldMapWithIndexO(M);
    return (f) => foldMapWithIndexOM((_, a) => f(a));
  };
};
var reduceRight = (O) => {
  const reduceRightWithIndexO = reduceRightWithIndex(O);
  return (b, f) => reduceRightWithIndexO(b, (_, b2, a) => f(b2, a));
};
var getFoldable = (O) => {
  const reduceO = reduce(O);
  const foldMapO = foldMap(O);
  const reduceRightO = reduceRight(O);
  return {
    URI,
    _E: void 0,
    reduce: (fa, b, f) => pipe(fa, reduceO(b, f)),
    foldMap: (M) => {
      const foldMapOM = foldMapO(M);
      return (fa, f) => pipe(fa, foldMapOM(f));
    },
    reduceRight: (fa, b, f) => pipe(fa, reduceRightO(b, f))
  };
};
var reduceWithIndex = (O) => {
  const keysO = keys(O);
  return (b, f) => (m) => {
    let out = b;
    for (const k of keysO(m)) {
      out = f(k, out, m.get(k));
    }
    return out;
  };
};
var foldMapWithIndex = (O) => {
  const keysO = keys(O);
  return (M) => (f) => (m) => {
    let out = M.empty;
    for (const k of keysO(m)) {
      out = M.concat(out, f(k, m.get(k)));
    }
    return out;
  };
};
var reduceRightWithIndex = (O) => {
  const keysO = keys(O);
  return (b, f) => (m) => {
    let out = b;
    const ks = keysO(m);
    const len = ks.length;
    for (let i = len - 1; i >= 0; i--) {
      const k = ks[i];
      out = f(k, m.get(k), out);
    }
    return out;
  };
};
var getFoldableWithIndex = (O) => {
  const F = getFoldable(O);
  const reduceWithIndexO = reduceWithIndex(O);
  const foldMapWithIndexO = foldMapWithIndex(O);
  const reduceRightWithIndexO = reduceRightWithIndex(O);
  return {
    URI,
    _E: void 0,
    reduce: F.reduce,
    foldMap: F.foldMap,
    reduceRight: F.reduceRight,
    reduceWithIndex: (fa, b, f) => pipe(fa, reduceWithIndexO(b, f)),
    foldMapWithIndex: (M) => {
      const foldMapWithIndexOM = foldMapWithIndexO(M);
      return (fa, f) => pipe(fa, foldMapWithIndexOM(f));
    },
    reduceRightWithIndex: (fa, b, f) => pipe(fa, reduceRightWithIndexO(b, f))
  };
};
var getTraversable = (O) => {
  const TWI = getTraversableWithIndex(O);
  const F = getFoldable(O);
  return {
    URI,
    _E: void 0,
    map: _map,
    reduce: F.reduce,
    foldMap: F.foldMap,
    reduceRight: F.reduceRight,
    traverse: TWI.traverse,
    sequence: TWI.sequence
  };
};
var getTraversableWithIndex = (O) => {
  const FWI = getFoldableWithIndex(O);
  const keysO = keys(O);
  const traverseWithIndex = (F) => {
    return (ta, f) => {
      let fm = F.of(/* @__PURE__ */ new Map());
      const ks = keysO(ta);
      const len = ks.length;
      for (let i = 0; i < len; i++) {
        const key = ks[i];
        const a = ta.get(key);
        fm = F.ap(
          F.map(fm, (m) => (b) => m.set(key, b)),
          f(key, a)
        );
      }
      return fm;
    };
  };
  const traverse = (F) => {
    const traverseWithIndexF = traverseWithIndex(F);
    return (ta, f) => traverseWithIndexF(ta, (_, a) => f(a));
  };
  const sequence = (F) => {
    const traverseWithIndexF = traverseWithIndex(F);
    return (ta) => traverseWithIndexF(ta, SK);
  };
  return {
    URI,
    _E: void 0,
    map: _map,
    mapWithIndex: _mapWithIndex,
    reduce: FWI.reduce,
    foldMap: FWI.foldMap,
    reduceRight: FWI.reduceRight,
    reduceWithIndex: FWI.reduceWithIndex,
    foldMapWithIndex: FWI.foldMapWithIndex,
    reduceRightWithIndex: FWI.reduceRightWithIndex,
    traverse,
    sequence,
    traverseWithIndex
  };
};
function getWitherable(O) {
  const TWI = getTraversableWithIndex(O);
  return {
    URI,
    _E: void 0,
    map: _map,
    compact,
    separate,
    filter: _filter,
    filterMap: _filterMap,
    partition: _partition,
    partitionMap: _partitionMap,
    reduce: TWI.reduce,
    foldMap: TWI.foldMap,
    reduceRight: TWI.reduceRight,
    traverse: TWI.traverse,
    sequence: TWI.sequence,
    mapWithIndex: _mapWithIndex,
    reduceWithIndex: TWI.reduceWithIndex,
    foldMapWithIndex: TWI.foldMapWithIndex,
    reduceRightWithIndex: TWI.reduceRightWithIndex,
    traverseWithIndex: TWI.traverseWithIndex,
    wilt: wiltDefault(TWI, Compactable),
    wither: witherDefault(TWI, Compactable)
  };
}
var union = (E, M) => {
  const lookupE = lookup(E);
  return (second) => (first) => {
    if (isEmpty(first)) {
      return second;
    }
    if (isEmpty(second)) {
      return first;
    }
    const out = /* @__PURE__ */ new Map();
    const firstEntries = first.entries();
    let e;
    while (!(e = firstEntries.next()).done) {
      const [k, a] = e.value;
      const oka = lookupE(k)(second);
      if (isSome(oka)) {
        out.set(k, M.concat(a, oka.value));
      } else {
        out.set(k, a);
      }
    }
    const secondEntries = second.entries();
    while (!(e = secondEntries.next()).done) {
      const [k, a] = e.value;
      const oka = lookupE(k)(out);
      if (isNone(oka)) {
        out.set(k, a);
      }
    }
    return out;
  };
};
var intersection = (E, M) => {
  const lookupE = lookup(E);
  return (second) => (first) => {
    if (isEmpty(first) || isEmpty(second)) {
      return empty;
    }
    const out = /* @__PURE__ */ new Map();
    const entries = first.entries();
    let e;
    while (!(e = entries.next()).done) {
      const [k, a] = e.value;
      const oka = lookupE(k)(second);
      if (isSome(oka)) {
        out.set(k, M.concat(a, oka.value));
      }
    }
    return out;
  };
};
var difference = (E) => {
  const memberE = member(E);
  return (second) => (first) => {
    if (isEmpty(first)) {
      return second;
    }
    if (isEmpty(second)) {
      return first;
    }
    const out = /* @__PURE__ */ new Map();
    const firstEntries = first.entries();
    let e;
    while (!(e = firstEntries.next()).done) {
      const [k, a] = e.value;
      if (!memberE(k)(second)) {
        out.set(k, a);
      }
    }
    const secondEntries = second.entries();
    while (!(e = secondEntries.next()).done) {
      const [k, a] = e.value;
      if (!memberE(k)(first)) {
        out.set(k, a);
      }
    }
    return out;
  };
};
var insertAt = upsertAt;
var readonlyMap = {
  URI,
  map: _map,
  compact,
  separate,
  filter: _filter,
  filterMap: _filterMap,
  partition: _partition,
  partitionMap: _partitionMap
};

export {
  fromMap,
  toMap,
  getShow,
  size,
  isEmpty,
  member,
  elem,
  keys,
  values,
  collect,
  toReadonlyArray,
  toUnfoldable,
  upsertAt,
  deleteAt,
  updateAt,
  modifyAt,
  pop,
  lookupWithKey,
  lookup,
  isSubmap,
  empty,
  getEq,
  getMonoid,
  singleton,
  fromFoldable,
  partitionMapWithIndex,
  partitionWithIndex,
  filterMapWithIndex,
  filterWithIndex,
  compact,
  filter,
  filterMap,
  map2 as map,
  mapWithIndex,
  partition,
  partitionMap,
  separate,
  URI,
  getUnionSemigroup,
  getUnionMonoid,
  getIntersectionSemigroup,
  getDifferenceMagma,
  getFilterableWithIndex,
  Functor,
  flap2 as flap,
  getFunctorWithIndex,
  Compactable,
  Filterable,
  reduce,
  foldMap,
  reduceRight,
  getFoldable,
  reduceWithIndex,
  foldMapWithIndex,
  reduceRightWithIndex,
  getFoldableWithIndex,
  getTraversable,
  getTraversableWithIndex,
  getWitherable,
  union,
  intersection,
  difference,
  insertAt,
  readonlyMap,
  ReadonlyMap_exports
};
