"use strict";

function createSlotClass(branding, construct, getters, methods, staticMethods) {
  function Class(...args) {
    if (!(this instanceof Class)) {
      throw new TypeError(internal.invalidCallingContext);
    }
    setSlots(this, construct(...args));
  }
  function bindMethod(method, methodName) {
    return Object.defineProperties((function(...args) {
      return method.call(this, getSpecificSlots(this), ...args);
    }), internal.createNameDescriptors(methodName));
  }
  function getSpecificSlots(obj) {
    const slots = getSlots(obj);
    if (!slots || slots.branding !== branding) {
      throw new TypeError(internal.invalidCallingContext);
    }
    return slots;
  }
  return Object.defineProperties(Class.prototype, {
    ...internal.createGetterDescriptors(internal.mapProps(bindMethod, getters)),
    ...internal.createPropDescriptors(internal.mapProps(bindMethod, methods)),
    ...internal.createStringTagDescriptors("Temporal." + branding)
  }), Object.defineProperties(Class, {
    ...internal.createPropDescriptors(staticMethods),
    ...internal.createNameDescriptors(branding)
  }), [ Class, slots => {
    const instance = Object.create(Class.prototype);
    return setSlots(instance, slots), instance;
  }, getSpecificSlots ];
}

function rejectInvalidBag(bag) {
  if (getSlots(bag) || void 0 !== bag.calendar || void 0 !== bag.timeZone) {
    throw new TypeError(internal.invalidBag);
  }
  return bag;
}

function getCalendarIdFromBag(bag) {
  return extractCalendarIdFromBag(bag) || internal.isoCalendarId;
}

function extractCalendarIdFromBag(bag) {
  const {calendar: calendarArg} = bag;
  if (void 0 !== calendarArg) {
    return refineCalendarArg(calendarArg);
  }
}

function refineCalendarArg(arg) {
  if (internal.isObjectLike(arg)) {
    const {calendar: calendar} = getSlots(arg) || {};
    if (!calendar) {
      throw new TypeError(internal.invalidCalendar(arg));
    }
    return calendar;
  }
  return (arg => internal.resolveCalendarId(internal.parseCalendarId(internal.requireString(arg))))(arg);
}

function createCalendarGetters(methodNameMap) {
  const methods = {};
  for (const methodName in methodNameMap) {
    methods[methodName] = slots => {
      const {calendar: calendar} = slots;
      return internal.createNativeStandardOps(calendar)[methodName](slots);
    };
  }
  return methods;
}

function neverValueOf() {
  throw new TypeError(internal.forbiddenValueOf);
}

function refineTimeZoneArg(arg) {
  if (internal.isObjectLike(arg)) {
    const {timeZone: timeZone} = getSlots(arg) || {};
    if (!timeZone) {
      throw new TypeError(internal.invalidTimeZone(arg));
    }
    return timeZone;
  }
  return (arg => internal.resolveTimeZoneId(internal.parseTimeZoneId(internal.requireString(arg))))(arg);
}

function toDurationSlots(arg) {
  if (internal.isObjectLike(arg)) {
    const slots = getSlots(arg);
    return slots && slots.branding === internal.DurationBranding ? slots : internal.refineDurationBag(arg);
  }
  return internal.parseDuration(arg);
}

function refinePublicRelativeTo(relativeTo) {
  if (void 0 !== relativeTo) {
    if (internal.isObjectLike(relativeTo)) {
      const slots = getSlots(relativeTo) || {};
      switch (slots.branding) {
       case internal.ZonedDateTimeBranding:
       case internal.PlainDateBranding:
        return slots;

       case internal.PlainDateTimeBranding:
        return internal.createPlainDateSlots(slots);
      }
      const calendarId = getCalendarIdFromBag(relativeTo);
      return {
        ...internal.refineMaybeZonedDateTimeBag(refineTimeZoneArg, internal.queryNativeTimeZone, internal.createNativeStandardOps(calendarId), relativeTo),
        calendar: calendarId
      };
    }
    return internal.parseRelativeToSlots(relativeTo);
  }
}

function toPlainTimeSlots(arg, options) {
  if (internal.isObjectLike(arg)) {
    const slots = getSlots(arg) || {};
    switch (slots.branding) {
     case internal.PlainTimeBranding:
      return internal.refineOverflowOptions(options), slots;

     case internal.PlainDateTimeBranding:
      return internal.refineOverflowOptions(options), internal.createPlainTimeSlots(slots);

     case internal.ZonedDateTimeBranding:
      return internal.refineOverflowOptions(options), internal.zonedDateTimeToPlainTime(internal.queryNativeTimeZone, slots);
    }
    return internal.refinePlainTimeBag(arg, options);
  }
  const timeSlots = internal.parsePlainTime(arg);
  return internal.refineOverflowOptions(options), timeSlots;
}

function optionalToPlainTimeFields(timeArg) {
  return void 0 === timeArg ? void 0 : toPlainTimeSlots(timeArg);
}

function toPlainDateTimeSlots(arg, options) {
  if (internal.isObjectLike(arg)) {
    const slots = getSlots(arg) || {};
    switch (slots.branding) {
     case internal.PlainDateTimeBranding:
      return internal.refineOverflowOptions(options), slots;

     case internal.PlainDateBranding:
      return internal.refineOverflowOptions(options), internal.createPlainDateTimeSlots({
        ...slots,
        ...internal.isoTimeFieldDefaults
      });

     case internal.ZonedDateTimeBranding:
      return internal.refineOverflowOptions(options), internal.zonedDateTimeToPlainDateTime(internal.queryNativeTimeZone, slots);
    }
    return internal.refinePlainDateTimeBag(internal.createNativeStandardOps(getCalendarIdFromBag(arg)), arg, options);
  }
  const res = internal.parsePlainDateTime(arg);
  return internal.refineOverflowOptions(options), res;
}

function toPlainMonthDaySlots(arg, options) {
  if (internal.isObjectLike(arg)) {
    const slots = getSlots(arg);
    if (slots && slots.branding === internal.PlainMonthDayBranding) {
      return internal.refineOverflowOptions(options), slots;
    }
    const calendarIdMaybe = extractCalendarIdFromBag(arg), calendarId = calendarIdMaybe || internal.isoCalendarId;
    return internal.refinePlainMonthDayBag(internal.createNativeStandardOps(calendarId), !calendarIdMaybe, arg, options);
  }
  const res = internal.parsePlainMonthDay(internal.createNativeStandardOps, arg);
  return internal.refineOverflowOptions(options), res;
}

function toPlainYearMonthSlots(arg, options) {
  if (internal.isObjectLike(arg)) {
    const slots = getSlots(arg);
    return slots && slots.branding === internal.PlainYearMonthBranding ? (internal.refineOverflowOptions(options), 
    slots) : internal.refinePlainYearMonthBag(internal.createNativeStandardOps(getCalendarIdFromBag(arg)), arg, options);
  }
  const res = internal.parsePlainYearMonth(internal.createNativeStandardOps, arg);
  return internal.refineOverflowOptions(options), res;
}

function toPlainDateSlots(arg, options) {
  if (internal.isObjectLike(arg)) {
    const slots = getSlots(arg) || {};
    switch (slots.branding) {
     case internal.PlainDateBranding:
      return internal.refineOverflowOptions(options), slots;

     case internal.PlainDateTimeBranding:
      return internal.refineOverflowOptions(options), internal.createPlainDateSlots(slots);

     case internal.ZonedDateTimeBranding:
      return internal.refineOverflowOptions(options), internal.zonedDateTimeToPlainDate(internal.queryNativeTimeZone, slots);
    }
    return internal.refinePlainDateBag(internal.createNativeStandardOps(getCalendarIdFromBag(arg)), arg, options);
  }
  const res = internal.parsePlainDate(arg);
  return internal.refineOverflowOptions(options), res;
}

function toZonedDateTimeSlots(arg, options) {
  if (internal.isObjectLike(arg)) {
    const slots = getSlots(arg);
    if (slots && slots.branding === internal.ZonedDateTimeBranding) {
      return internal.refineZonedFieldOptions(options), slots;
    }
    const calendarId = getCalendarIdFromBag(arg);
    return internal.refineZonedDateTimeBag(refineTimeZoneArg, internal.queryNativeTimeZone, internal.createNativeStandardOps(calendarId), calendarId, arg, options);
  }
  return internal.parseZonedDateTime(arg, options);
}

function adaptDateMethods(methods) {
  return internal.mapProps((method => slots => method(slotsToIso(slots))), methods);
}

function slotsToIso(slots) {
  return internal.zonedEpochSlotsToIso(slots, internal.queryNativeTimeZone);
}

function toInstantSlots(arg) {
  if (internal.isObjectLike(arg)) {
    const slots = getSlots(arg);
    if (slots) {
      switch (slots.branding) {
       case internal.InstantBranding:
        return slots;

       case internal.ZonedDateTimeBranding:
        return internal.createInstantSlots(slots.epochNanoseconds);
      }
    }
  }
  return internal.parseInstant(arg);
}

function createFormatMethod(methodName) {
  return Object.defineProperties((function(...formattables) {
    const prepFormat = internalsMap.get(this), [format, ...rawFormattables] = prepFormat(methodName.includes("Range"), ...formattables);
    return format[methodName](...rawFormattables);
  }), internal.createNameDescriptors(methodName));
}

function createProxiedMethod(methodName) {
  return Object.defineProperties((function(...args) {
    return internalsMap.get(this).rawFormat[methodName](...args);
  }), internal.createNameDescriptors(methodName));
}

function createFormatPrepperForBranding(branding) {
  const config = classFormatConfigs[branding];
  if (!config) {
    throw new TypeError(internal.invalidFormatType(branding));
  }
  return internal.createFormatPrepper(config, internal.memoize(internal.createFormatForPrep), 1);
}

var internal = require("./internal.cjs");

const slotsMap = new WeakMap, getSlots = slotsMap.get.bind(slotsMap), setSlots = slotsMap.set.bind(slotsMap), yearMonthOnlyRefiners = {
  era: internal.requireStringOrUndefined,
  eraYear: internal.requireIntegerOrUndefined,
  year: internal.requireInteger,
  month: internal.requirePositiveInteger,
  daysInMonth: internal.requirePositiveInteger,
  daysInYear: internal.requirePositiveInteger,
  inLeapYear: internal.requireBoolean,
  monthsInYear: internal.requirePositiveInteger
}, monthOnlyRefiners = {
  monthCode: internal.requireString
}, dayOnlyRefiners = {
  day: internal.requirePositiveInteger
}, dateOnlyRefiners = {
  dayOfWeek: internal.requirePositiveInteger,
  dayOfYear: internal.requirePositiveInteger,
  weekOfYear: internal.requirePositiveIntegerOrUndefined,
  yearOfWeek: internal.requireIntegerOrUndefined,
  daysInWeek: internal.requirePositiveInteger
}, dateGetters = createCalendarGetters({
  ...yearMonthOnlyRefiners,
  ...monthOnlyRefiners,
  ...dayOnlyRefiners,
  ...dateOnlyRefiners
}), yearMonthGetters = createCalendarGetters({
  ...yearMonthOnlyRefiners,
  ...monthOnlyRefiners
}), monthDayGetters = createCalendarGetters({
  ...monthOnlyRefiners,
  ...dayOnlyRefiners
}), calendarIdGetters = {
  calendarId: slots => slots.calendar
}, durationGetters = internal.mapPropNames((propName => slots => slots[propName]), internal.durationFieldNamesAsc.concat("sign")), timeGetters = internal.mapPropNames(((_name, i) => slots => slots[internal.isoTimeFieldNamesAsc[i]]), internal.timeFieldNamesAsc), epochGetters = {
  epochMilliseconds: internal.getEpochMilli,
  epochNanoseconds: internal.getEpochNano
}, [Duration, createDuration, getDurationSlots] = createSlotClass(internal.DurationBranding, internal.constructDurationSlots, {
  ...durationGetters,
  blank: internal.getDurationBlank
}, {
  with: (slots, mod) => createDuration(internal.durationWithFields(slots, mod)),
  negated: slots => createDuration(internal.negateDuration(slots)),
  abs: slots => createDuration(internal.absDuration(slots)),
  add: (slots, otherArg, options) => createDuration(internal.addDurations(refinePublicRelativeTo, internal.createNativeStandardOps, internal.queryNativeTimeZone, 0, slots, toDurationSlots(otherArg), options)),
  subtract: (slots, otherArg, options) => createDuration(internal.addDurations(refinePublicRelativeTo, internal.createNativeStandardOps, internal.queryNativeTimeZone, 1, slots, toDurationSlots(otherArg), options)),
  round: (slots, options) => createDuration(internal.roundDuration(refinePublicRelativeTo, internal.createNativeStandardOps, internal.queryNativeTimeZone, slots, options)),
  total: (slots, options) => internal.totalDuration(refinePublicRelativeTo, internal.createNativeStandardOps, internal.queryNativeTimeZone, slots, options),
  toLocaleString(slots, locales, options) {
    return Intl.DurationFormat ? new Intl.DurationFormat(locales, options).format(this) : internal.formatDurationIso(slots);
  },
  toString: internal.formatDurationIso,
  toJSON: slots => internal.formatDurationIso(slots),
  valueOf: neverValueOf
}, {
  from: arg => createDuration(toDurationSlots(arg)),
  compare: (durationArg0, durationArg1, options) => internal.compareDurations(refinePublicRelativeTo, internal.createNativeStandardOps, internal.queryNativeTimeZone, toDurationSlots(durationArg0), toDurationSlots(durationArg1), options)
}), classFormatConfigs = {
  Instant: internal.instantConfig,
  PlainDateTime: internal.dateTimeConfig,
  PlainDate: internal.dateConfig,
  PlainTime: internal.timeConfig,
  PlainYearMonth: internal.yearMonthConfig,
  PlainMonthDay: internal.monthDayConfig
}, prepInstantFormat = internal.createFormatPrepper(internal.instantConfig), prepZonedDateTimeFormat = internal.createFormatPrepper(internal.zonedConfig), prepPlainDateTimeFormat = internal.createFormatPrepper(internal.dateTimeConfig), prepPlainDateFormat = internal.createFormatPrepper(internal.dateConfig), prepPlainTimeFormat = internal.createFormatPrepper(internal.timeConfig), prepPlainYearMonthFormat = internal.createFormatPrepper(internal.yearMonthConfig), prepPlainMonthDayFormat = internal.createFormatPrepper(internal.monthDayConfig), [PlainTime, createPlainTime] = createSlotClass(internal.PlainTimeBranding, internal.constructPlainTimeSlots, timeGetters, {
  with(_slots, mod, options) {
    return createPlainTime(internal.plainTimeWithFields(this, rejectInvalidBag(mod), options));
  },
  add: (slots, durationArg) => createPlainTime(internal.movePlainTime(0, slots, toDurationSlots(durationArg))),
  subtract: (slots, durationArg) => createPlainTime(internal.movePlainTime(1, slots, toDurationSlots(durationArg))),
  until: (slots, otherArg, options) => createDuration(internal.diffPlainTimes(0, slots, toPlainTimeSlots(otherArg), options)),
  since: (slots, otherArg, options) => createDuration(internal.diffPlainTimes(1, slots, toPlainTimeSlots(otherArg), options)),
  round: (slots, options) => createPlainTime(internal.roundPlainTime(slots, options)),
  equals: (slots, other) => internal.plainTimesEqual(slots, toPlainTimeSlots(other)),
  toLocaleString(slots, locales, options) {
    const [format, epochMilli] = prepPlainTimeFormat(locales, options, slots);
    return format.format(epochMilli);
  },
  toString: internal.formatPlainTimeIso,
  toJSON: slots => internal.formatPlainTimeIso(slots),
  valueOf: neverValueOf
}, {
  from: (arg, options) => createPlainTime(toPlainTimeSlots(arg, options)),
  compare: (arg0, arg1) => internal.compareIsoTimeFields(toPlainTimeSlots(arg0), toPlainTimeSlots(arg1))
}), [PlainDateTime, createPlainDateTime] = createSlotClass(internal.PlainDateTimeBranding, internal.bindArgs(internal.constructPlainDateTimeSlots, internal.refineCalendarId), {
  ...calendarIdGetters,
  ...dateGetters,
  ...timeGetters
}, {
  with: (slots, mod, options) => createPlainDateTime(internal.plainDateTimeWithFields(internal.createNativeStandardOps, slots, rejectInvalidBag(mod), options)),
  withCalendar: (slots, calendarArg) => createPlainDateTime(internal.slotsWithCalendarId(slots, refineCalendarArg(calendarArg))),
  withPlainTime: (slots, plainTimeArg) => createPlainDateTime(internal.plainDateTimeWithPlainTime(slots, optionalToPlainTimeFields(plainTimeArg))),
  add: (slots, durationArg, options) => createPlainDateTime(internal.movePlainDateTime(internal.createNativeStandardOps, 0, slots, toDurationSlots(durationArg), options)),
  subtract: (slots, durationArg, options) => createPlainDateTime(internal.movePlainDateTime(internal.createNativeStandardOps, 1, slots, toDurationSlots(durationArg), options)),
  until: (slots, otherArg, options) => createDuration(internal.diffPlainDateTimes(internal.createNativeStandardOps, 0, slots, toPlainDateTimeSlots(otherArg), options)),
  since: (slots, otherArg, options) => createDuration(internal.diffPlainDateTimes(internal.createNativeStandardOps, 1, slots, toPlainDateTimeSlots(otherArg), options)),
  round: (slots, options) => createPlainDateTime(internal.roundPlainDateTime(slots, options)),
  equals: (slots, otherArg) => internal.plainDateTimesEqual(slots, toPlainDateTimeSlots(otherArg)),
  toZonedDateTime: (slots, timeZoneArg, options) => createZonedDateTime(internal.plainDateTimeToZonedDateTime(internal.queryNativeTimeZone, slots, refineTimeZoneArg(timeZoneArg), options)),
  toPlainDate: slots => createPlainDate(internal.createPlainDateSlots(slots)),
  toPlainTime: slots => createPlainTime(internal.createPlainTimeSlots(slots)),
  toLocaleString(slots, locales, options) {
    const [format, epochMilli] = prepPlainDateTimeFormat(locales, options, slots);
    return format.format(epochMilli);
  },
  toString: internal.formatPlainDateTimeIso,
  toJSON: slots => internal.formatPlainDateTimeIso(slots),
  valueOf: neverValueOf
}, {
  from: (arg, options) => createPlainDateTime(toPlainDateTimeSlots(arg, options)),
  compare: (arg0, arg1) => internal.compareIsoDateTimeFields(toPlainDateTimeSlots(arg0), toPlainDateTimeSlots(arg1))
}), [PlainMonthDay, createPlainMonthDay, getPlainMonthDaySlots] = createSlotClass(internal.PlainMonthDayBranding, internal.bindArgs(internal.constructPlainMonthDaySlots, internal.refineCalendarId), {
  ...calendarIdGetters,
  ...monthDayGetters
}, {
  with: (slots, mod, options) => createPlainMonthDay(internal.plainMonthDayWithFields(internal.createNativeStandardOps, slots, rejectInvalidBag(mod), options)),
  equals: (slots, otherArg) => internal.plainMonthDaysEqual(slots, toPlainMonthDaySlots(otherArg)),
  toPlainDate(slots, bag) {
    return createPlainDate(internal.plainMonthDayToPlainDate(internal.createNativeStandardOps, slots, this, bag));
  },
  toLocaleString(slots, locales, options) {
    const [format, epochMilli] = prepPlainMonthDayFormat(locales, options, slots);
    return format.format(epochMilli);
  },
  toString: internal.formatPlainMonthDayIso,
  toJSON: slots => internal.formatPlainMonthDayIso(slots),
  valueOf: neverValueOf
}, {
  from: (arg, options) => createPlainMonthDay(toPlainMonthDaySlots(arg, options))
}), [PlainYearMonth, createPlainYearMonth, getPlainYearMonthSlots] = createSlotClass(internal.PlainYearMonthBranding, internal.bindArgs(internal.constructPlainYearMonthSlots, internal.refineCalendarId), {
  ...calendarIdGetters,
  ...yearMonthGetters
}, {
  with: (slots, mod, options) => createPlainYearMonth(internal.plainYearMonthWithFields(internal.createNativeStandardOps, slots, rejectInvalidBag(mod), options)),
  add: (slots, durationArg, options) => createPlainYearMonth(internal.movePlainYearMonth(internal.createNativeStandardOps, 0, slots, toDurationSlots(durationArg), options)),
  subtract: (slots, durationArg, options) => createPlainYearMonth(internal.movePlainYearMonth(internal.createNativeStandardOps, 1, slots, toDurationSlots(durationArg), options)),
  until: (slots, otherArg, options) => createDuration(internal.diffPlainYearMonth(internal.createNativeStandardOps, 0, slots, toPlainYearMonthSlots(otherArg), options)),
  since: (slots, otherArg, options) => createDuration(internal.diffPlainYearMonth(internal.createNativeStandardOps, 1, slots, toPlainYearMonthSlots(otherArg), options)),
  equals: (slots, otherArg) => internal.plainYearMonthsEqual(slots, toPlainYearMonthSlots(otherArg)),
  toPlainDate(slots, bag) {
    return createPlainDate(internal.plainYearMonthToPlainDate(internal.createNativeStandardOps, slots, this, bag));
  },
  toLocaleString(slots, locales, options) {
    const [format, epochMilli] = prepPlainYearMonthFormat(locales, options, slots);
    return format.format(epochMilli);
  },
  toString: internal.formatPlainYearMonthIso,
  toJSON: slots => internal.formatPlainYearMonthIso(slots),
  valueOf: neverValueOf
}, {
  from: (arg, options) => createPlainYearMonth(toPlainYearMonthSlots(arg, options)),
  compare: (arg0, arg1) => internal.compareIsoDateFields(toPlainYearMonthSlots(arg0), toPlainYearMonthSlots(arg1))
}), [PlainDate, createPlainDate, getPlainDateSlots] = createSlotClass(internal.PlainDateBranding, internal.bindArgs(internal.constructPlainDateSlots, internal.refineCalendarId), {
  ...calendarIdGetters,
  ...dateGetters
}, {
  with: (slots, mod, options) => createPlainDate(internal.plainDateWithFields(internal.createNativeStandardOps, slots, rejectInvalidBag(mod), options)),
  withCalendar: (slots, calendarArg) => createPlainDate(internal.slotsWithCalendarId(slots, refineCalendarArg(calendarArg))),
  add: (slots, durationArg, options) => createPlainDate(internal.movePlainDate(internal.createNativeStandardOps, 0, slots, toDurationSlots(durationArg), options)),
  subtract: (slots, durationArg, options) => createPlainDate(internal.movePlainDate(internal.createNativeStandardOps, 1, slots, toDurationSlots(durationArg), options)),
  until: (slots, otherArg, options) => createDuration(internal.diffPlainDates(internal.createNativeStandardOps, 0, slots, toPlainDateSlots(otherArg), options)),
  since: (slots, otherArg, options) => createDuration(internal.diffPlainDates(internal.createNativeStandardOps, 1, slots, toPlainDateSlots(otherArg), options)),
  equals: (slots, otherArg) => internal.plainDatesEqual(slots, toPlainDateSlots(otherArg)),
  toZonedDateTime(slots, options) {
    const optionsObj = internal.isObjectLike(options) ? options : {
      timeZone: options
    };
    return createZonedDateTime(internal.plainDateToZonedDateTime(refineTimeZoneArg, toPlainTimeSlots, internal.queryNativeTimeZone, slots, optionsObj));
  },
  toPlainDateTime: (slots, plainTimeArg) => createPlainDateTime(internal.plainDateToPlainDateTime(slots, optionalToPlainTimeFields(plainTimeArg))),
  toPlainYearMonth(slots) {
    return createPlainYearMonth(internal.plainDateToPlainYearMonth(internal.createNativeStandardOps, slots, this));
  },
  toPlainMonthDay(slots) {
    return createPlainMonthDay(internal.plainDateToPlainMonthDay(internal.createNativeStandardOps, slots, this));
  },
  toLocaleString(slots, locales, options) {
    const [format, epochMilli] = prepPlainDateFormat(locales, options, slots);
    return format.format(epochMilli);
  },
  toString: internal.formatPlainDateIso,
  toJSON: slots => internal.formatPlainDateIso(slots),
  valueOf: neverValueOf
}, {
  from: (arg, options) => createPlainDate(toPlainDateSlots(arg, options)),
  compare: (arg0, arg1) => internal.compareIsoDateFields(toPlainDateSlots(arg0), toPlainDateSlots(arg1))
}), [ZonedDateTime, createZonedDateTime] = createSlotClass(internal.ZonedDateTimeBranding, internal.bindArgs(internal.constructZonedDateTimeSlots, internal.refineCalendarId, internal.refineTimeZoneId), {
  ...epochGetters,
  ...calendarIdGetters,
  ...adaptDateMethods(dateGetters),
  ...adaptDateMethods(timeGetters),
  offset: slots => internal.formatOffsetNano(slotsToIso(slots).offsetNanoseconds),
  offsetNanoseconds: slots => slotsToIso(slots).offsetNanoseconds,
  timeZoneId: slots => slots.timeZone,
  hoursInDay: slots => internal.computeZonedHoursInDay(internal.queryNativeTimeZone, slots)
}, {
  with: (slots, mod, options) => createZonedDateTime(internal.zonedDateTimeWithFields(internal.createNativeStandardOps, internal.queryNativeTimeZone, slots, rejectInvalidBag(mod), options)),
  withCalendar: (slots, calendarArg) => createZonedDateTime(internal.slotsWithCalendarId(slots, refineCalendarArg(calendarArg))),
  withTimeZone: (slots, timeZoneArg) => createZonedDateTime(internal.slotsWithTimeZoneId(slots, refineTimeZoneArg(timeZoneArg))),
  withPlainTime: (slots, plainTimeArg) => createZonedDateTime(internal.zonedDateTimeWithPlainTime(internal.queryNativeTimeZone, slots, optionalToPlainTimeFields(plainTimeArg))),
  add: (slots, durationArg, options) => createZonedDateTime(internal.moveZonedDateTime(internal.createNativeStandardOps, internal.queryNativeTimeZone, 0, slots, toDurationSlots(durationArg), options)),
  subtract: (slots, durationArg, options) => createZonedDateTime(internal.moveZonedDateTime(internal.createNativeStandardOps, internal.queryNativeTimeZone, 1, slots, toDurationSlots(durationArg), options)),
  until: (slots, otherArg, options) => createDuration(internal.createDurationSlots(internal.diffZonedDateTimes(internal.createNativeStandardOps, internal.queryNativeTimeZone, 0, slots, toZonedDateTimeSlots(otherArg), options))),
  since: (slots, otherArg, options) => createDuration(internal.createDurationSlots(internal.diffZonedDateTimes(internal.createNativeStandardOps, internal.queryNativeTimeZone, 1, slots, toZonedDateTimeSlots(otherArg), options))),
  round: (slots, options) => createZonedDateTime(internal.roundZonedDateTime(internal.queryNativeTimeZone, slots, options)),
  startOfDay: slots => createZonedDateTime(internal.computeZonedStartOfDay(internal.queryNativeTimeZone, slots)),
  equals: (slots, otherArg) => internal.zonedDateTimesEqual(slots, toZonedDateTimeSlots(otherArg)),
  toInstant: slots => createInstant(internal.zonedDateTimeToInstant(slots)),
  toPlainDateTime: slots => createPlainDateTime(internal.zonedDateTimeToPlainDateTime(internal.queryNativeTimeZone, slots)),
  toPlainDate: slots => createPlainDate(internal.zonedDateTimeToPlainDate(internal.queryNativeTimeZone, slots)),
  toPlainTime: slots => createPlainTime(internal.zonedDateTimeToPlainTime(internal.queryNativeTimeZone, slots)),
  toLocaleString(slots, locales, options = {}) {
    const [format, epochMilli] = prepZonedDateTimeFormat(locales, options, slots);
    return format.format(epochMilli);
  },
  toString: (slots, options) => internal.formatZonedDateTimeIso(internal.queryNativeTimeZone, slots, options),
  toJSON: slots => internal.formatZonedDateTimeIso(internal.queryNativeTimeZone, slots),
  valueOf: neverValueOf,
  getTimeZoneTransition(slots, options) {
    const {timeZone: timeZoneId, epochNanoseconds: epochNano} = slots, direction = internal.refineDirectionOptions(options), newEpochNano = internal.queryNativeTimeZone(timeZoneId).getTransition(epochNano, direction);
    return newEpochNano ? createZonedDateTime({
      ...slots,
      epochNanoseconds: newEpochNano
    }) : null;
  }
}, {
  from: (arg, options) => createZonedDateTime(toZonedDateTimeSlots(arg, options)),
  compare: (arg0, arg1) => internal.compareZonedDateTimes(toZonedDateTimeSlots(arg0), toZonedDateTimeSlots(arg1))
}), [Instant, createInstant, getInstantSlots] = createSlotClass(internal.InstantBranding, internal.constructInstantSlots, epochGetters, {
  add: (slots, durationArg) => createInstant(internal.moveInstant(0, slots, toDurationSlots(durationArg))),
  subtract: (slots, durationArg) => createInstant(internal.moveInstant(1, slots, toDurationSlots(durationArg))),
  until: (slots, otherArg, options) => createDuration(internal.diffInstants(0, slots, toInstantSlots(otherArg), options)),
  since: (slots, otherArg, options) => createDuration(internal.diffInstants(1, slots, toInstantSlots(otherArg), options)),
  round: (slots, options) => createInstant(internal.roundInstant(slots, options)),
  equals: (slots, otherArg) => internal.instantsEqual(slots, toInstantSlots(otherArg)),
  toZonedDateTimeISO: (slots, timeZoneArg) => createZonedDateTime(internal.instantToZonedDateTime(slots, refineTimeZoneArg(timeZoneArg))),
  toLocaleString(slots, locales, options) {
    const [format, epochMilli] = prepInstantFormat(locales, options, slots);
    return format.format(epochMilli);
  },
  toString: (slots, options) => internal.formatInstantIso(refineTimeZoneArg, internal.queryNativeTimeZone, slots, options),
  toJSON: slots => internal.formatInstantIso(refineTimeZoneArg, internal.queryNativeTimeZone, slots),
  valueOf: neverValueOf
}, {
  from: arg => createInstant(toInstantSlots(arg)),
  fromEpochMilliseconds: epochMilli => createInstant(internal.epochMilliToInstant(epochMilli)),
  fromEpochNanoseconds: epochNano => createInstant(internal.epochNanoToInstant(epochNano)),
  compare: (a, b) => internal.compareInstants(toInstantSlots(a), toInstantSlots(b))
}), Now = Object.defineProperties({}, {
  ...internal.createStringTagDescriptors("Temporal.Now"),
  ...internal.createPropDescriptors({
    timeZoneId: () => internal.getCurrentTimeZoneId(),
    instant: () => createInstant(internal.createInstantSlots(internal.getCurrentEpochNano())),
    zonedDateTimeISO: (timeZoneArg = internal.getCurrentTimeZoneId()) => createZonedDateTime(internal.createZonedDateTimeSlots(internal.getCurrentEpochNano(), refineTimeZoneArg(timeZoneArg), internal.isoCalendarId)),
    plainDateTimeISO: (timeZoneArg = internal.getCurrentTimeZoneId()) => createPlainDateTime(internal.createPlainDateTimeSlots(internal.getCurrentIsoDateTime(internal.queryNativeTimeZone(refineTimeZoneArg(timeZoneArg))), internal.isoCalendarId)),
    plainDateISO: (timeZoneArg = internal.getCurrentTimeZoneId()) => createPlainDate(internal.createPlainDateSlots(internal.getCurrentIsoDateTime(internal.queryNativeTimeZone(refineTimeZoneArg(timeZoneArg))), internal.isoCalendarId)),
    plainTimeISO: (timeZoneArg = internal.getCurrentTimeZoneId()) => createPlainTime(internal.createPlainTimeSlots(internal.getCurrentIsoDateTime(internal.queryNativeTimeZone(refineTimeZoneArg(timeZoneArg)))))
  })
}), Temporal = Object.defineProperties({}, {
  ...internal.createStringTagDescriptors("Temporal"),
  ...internal.createPropDescriptors({
    PlainYearMonth: PlainYearMonth,
    PlainMonthDay: PlainMonthDay,
    PlainDate: PlainDate,
    PlainTime: PlainTime,
    PlainDateTime: PlainDateTime,
    ZonedDateTime: ZonedDateTime,
    Instant: Instant,
    Duration: Duration,
    Now: Now
  })
}), DateTimeFormat = function() {
  function DateTimeFormatFunc(locales, options) {
    return new DateTimeFormatNew(locales, options);
  }
  function DateTimeFormatNew(locales, options = Object.create(null)) {
    internalsMap.set(this, ((locales, options) => {
      const rawFormat = new internal.RawDateTimeFormat(locales, options), resolveOptions = rawFormat.resolvedOptions(), resolvedLocale = resolveOptions.locale, copiedOptions = internal.pluckProps(Object.keys(options), resolveOptions), queryFormatPrepperForBranding = internal.memoize(createFormatPrepperForBranding), prepFormat = (isRange, ...formattables) => {
        if (isRange) {
          if (2 !== formattables.length) {
            throw new TypeError(internal.mismatchingFormatTypes);
          }
          for (const formattable of formattables) {
            if (void 0 === formattable) {
              throw new TypeError(internal.mismatchingFormatTypes);
            }
          }
        }
        isRange || void 0 !== formattables[0] || (formattables = []);
        const formattableEssences = formattables.map((formattable => getSlots(formattable) || Number(formattable)));
        let overallBranding, i = 0;
        for (const formattableEssence of formattableEssences) {
          const slotsBranding = "object" == typeof formattableEssence ? formattableEssence.branding : void 0;
          if (i++ && slotsBranding !== overallBranding) {
            throw new TypeError(internal.mismatchingFormatTypes);
          }
          overallBranding = slotsBranding;
        }
        return overallBranding ? queryFormatPrepperForBranding(overallBranding)(resolvedLocale, copiedOptions, ...formattableEssences) : [ rawFormat, ...formattableEssences ];
      };
      return prepFormat.rawFormat = rawFormat, prepFormat;
    })(locales, options));
  }
  const members = internal.RawDateTimeFormat.prototype, memberDescriptors = Object.getOwnPropertyDescriptors(members), classDescriptors = Object.getOwnPropertyDescriptors(internal.RawDateTimeFormat);
  for (const memberName in memberDescriptors) {
    const memberDescriptor = memberDescriptors[memberName], formatLikeMethod = memberName.startsWith("format") && createFormatMethod(memberName);
    "function" == typeof memberDescriptor.value ? memberDescriptor.value = "constructor" === memberName ? DateTimeFormatFunc : formatLikeMethod || createProxiedMethod(memberName) : formatLikeMethod && (memberDescriptor.get = function() {
      if (!internalsMap.has(this)) {
        throw new TypeError(internal.invalidCallingContext);
      }
      return (...args) => formatLikeMethod.apply(this, args);
    }, Object.defineProperties(memberDescriptor.get, internal.createNameDescriptors(`get ${memberName}`)));
  }
  return classDescriptors.prototype.value = DateTimeFormatNew.prototype = Object.create({}, memberDescriptors), 
  Object.defineProperties(DateTimeFormatFunc, classDescriptors), DateTimeFormatFunc;
}(), internalsMap = new WeakMap, IntlExtended = Object.defineProperties(Object.create(Intl), internal.createPropDescriptors({
  DateTimeFormat: DateTimeFormat
}));

exports.DateTimeFormat = DateTimeFormat, exports.IntlExtended = IntlExtended, exports.Temporal = Temporal, 
exports.toTemporalInstant = function() {
  const epochMilli = Date.prototype.valueOf.call(this);
  return createInstant(internal.createInstantSlots(internal.numberToBigNano(internal.requireNumberIsInteger(epochMilli), internal.nanoInMilli)));
};
