// ==UserScript== // @name 雨课堂助手 // @namespace https://github.com/ocsjs // @version 6.0.0 // @description 破解雨课堂的字体混淆:Ctrl-C 复制出正确汉字;并可调用 DeepSeek / 智谱 GLM / 火山方舟 / Kimi K3 自动作答,四家通用的联网搜索会先去题库查原题,可自动提交、自动翻页。 // @author ykt-pass // @match *://*.yuketang.cn/* // @run-at document-start // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_addValueChangeListener // @grant GM_removeValueChangeListener // @grant GM_getTab // @grant GM_saveTab // @grant GM_notification // @grant GM_xmlhttpRequest // @grant GM_info // @grant unsafeWindow // @grant GM_getTabs // @grant GM_getResourceText // @grant GM_registerMenuCommand // @grant GM_setClipboard // @grant GM_openInTab // @connect api.deepseek.com // @connect open.bigmodel.cn // @connect ark.cn-beijing.volces.com // @connect api.openai.com // @connect api.moonshot.cn // @connect dashscope.aliyuncs.com // @connect * // ==/UserScript== (async function () { //#region \0rolldown/runtime.js var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports); //#endregion //#region node_modules/events/events.js var require_events = /* @__PURE__ */ __commonJSMin(((exports, module) => { var R = typeof Reflect === "object" ? Reflect : null; var ReflectApply = R && typeof R.apply === "function" ? R.apply : function ReflectApply(target, receiver, args) { return Function.prototype.apply.call(target, receiver, args); }; var ReflectOwnKeys; if (R && typeof R.ownKeys === "function") ReflectOwnKeys = R.ownKeys; else if (Object.getOwnPropertySymbols) ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)); }; else ReflectOwnKeys = function ReflectOwnKeys(target) { return Object.getOwnPropertyNames(target); }; function ProcessEmitWarning(warning) { if (console && console.warn) console.warn(warning); } var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { return value !== value; }; function EventEmitter() { EventEmitter.init.call(this); } module.exports = EventEmitter; module.exports.once = once; EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = void 0; EventEmitter.prototype._eventsCount = 0; EventEmitter.prototype._maxListeners = void 0; var defaultMaxListeners = 10; function checkListener(listener) { if (typeof listener !== "function") throw new TypeError("The \"listener\" argument must be of type Function. Received type " + typeof listener); } Object.defineProperty(EventEmitter, "defaultMaxListeners", { enumerable: true, get: function() { return defaultMaxListeners; }, set: function(arg) { if (typeof arg !== "number" || arg < 0 || NumberIsNaN(arg)) throw new RangeError("The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received " + arg + "."); defaultMaxListeners = arg; } }); EventEmitter.init = function() { if (this._events === void 0 || this._events === Object.getPrototypeOf(this)._events) { this._events = Object.create(null); this._eventsCount = 0; } this._maxListeners = this._maxListeners || void 0; }; EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { if (typeof n !== "number" || n < 0 || NumberIsNaN(n)) throw new RangeError("The value of \"n\" is out of range. It must be a non-negative number. Received " + n + "."); this._maxListeners = n; return this; }; function _getMaxListeners(that) { if (that._maxListeners === void 0) return EventEmitter.defaultMaxListeners; return that._maxListeners; } EventEmitter.prototype.getMaxListeners = function getMaxListeners() { return _getMaxListeners(this); }; EventEmitter.prototype.emit = function emit(type) { var args = []; for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); var doError = type === "error"; var events = this._events; if (events !== void 0) doError = doError && events.error === void 0; else if (!doError) return false; if (doError) { var er; if (args.length > 0) er = args[0]; if (er instanceof Error) throw er; var err = /* @__PURE__ */ new Error("Unhandled error." + (er ? " (" + er.message + ")" : "")); err.context = er; throw err; } var handler = events[type]; if (handler === void 0) return false; if (typeof handler === "function") ReflectApply(handler, this, args); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args); } return true; }; function _addListener(target, type, listener, prepend) { var m; var events; var existing; checkListener(listener); events = target._events; if (events === void 0) { events = target._events = Object.create(null); target._eventsCount = 0; } else { if (events.newListener !== void 0) { target.emit("newListener", type, listener.listener ? listener.listener : listener); events = target._events; } existing = events[type]; } if (existing === void 0) { existing = events[type] = listener; ++target._eventsCount; } else { if (typeof existing === "function") existing = events[type] = prepend ? [listener, existing] : [existing, listener]; else if (prepend) existing.unshift(listener); else existing.push(listener); m = _getMaxListeners(target); if (m > 0 && existing.length > m && !existing.warned) { existing.warned = true; var w = /* @__PURE__ */ new Error("Possible EventEmitter memory leak detected. " + existing.length + " " + String(type) + " listeners added. Use emitter.setMaxListeners() to increase limit"); w.name = "MaxListenersExceededWarning"; w.emitter = target; w.type = type; w.count = existing.length; ProcessEmitWarning(w); } } return target; } EventEmitter.prototype.addListener = function addListener(type, listener) { return _addListener(this, type, listener, false); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.prependListener = function prependListener(type, listener) { return _addListener(this, type, listener, true); }; function onceWrapper() { if (!this.fired) { this.target.removeListener(this.type, this.wrapFn); this.fired = true; if (arguments.length === 0) return this.listener.call(this.target); return this.listener.apply(this.target, arguments); } } function _onceWrap(target, type, listener) { var state = { fired: false, wrapFn: void 0, target, type, listener }; var wrapped = onceWrapper.bind(state); wrapped.listener = listener; state.wrapFn = wrapped; return wrapped; } EventEmitter.prototype.once = function once(type, listener) { checkListener(listener); this.on(type, _onceWrap(this, type, listener)); return this; }; EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) { checkListener(listener); this.prependListener(type, _onceWrap(this, type, listener)); return this; }; EventEmitter.prototype.removeListener = function removeListener(type, listener) { var list, events, position, i, originalListener; checkListener(listener); events = this._events; if (events === void 0) return this; list = events[type]; if (list === void 0) return this; if (list === listener || list.listener === listener) { if (--this._eventsCount === 0) this._events = Object.create(null); else { delete events[type]; if (events.removeListener) this.emit("removeListener", type, list.listener || listener); } } else if (typeof list !== "function") { position = -1; for (i = list.length - 1; i >= 0; i--) if (list[i] === listener || list[i].listener === listener) { originalListener = list[i].listener; position = i; break; } if (position < 0) return this; if (position === 0) list.shift(); else spliceOne(list, position); if (list.length === 1) events[type] = list[0]; if (events.removeListener !== void 0) this.emit("removeListener", type, originalListener || listener); } return this; }; EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { var listeners, events = this._events, i; if (events === void 0) return this; if (events.removeListener === void 0) { if (arguments.length === 0) { this._events = Object.create(null); this._eventsCount = 0; } else if (events[type] !== void 0) { if (--this._eventsCount === 0) this._events = Object.create(null); else delete events[type]; } return this; } if (arguments.length === 0) { var keys = Object.keys(events); var key; for (i = 0; i < keys.length; ++i) { key = keys[i]; if (key === "removeListener") continue; this.removeAllListeners(key); } this.removeAllListeners("removeListener"); this._events = Object.create(null); this._eventsCount = 0; return this; } listeners = events[type]; if (typeof listeners === "function") this.removeListener(type, listeners); else if (listeners !== void 0) for (i = listeners.length - 1; i >= 0; i--) this.removeListener(type, listeners[i]); return this; }; function _listeners(target, type, unwrap) { var events = target._events; if (events === void 0) return []; var evlistener = events[type]; if (evlistener === void 0) return []; if (typeof evlistener === "function") return unwrap ? [evlistener.listener || evlistener] : [evlistener]; return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); } EventEmitter.prototype.listeners = function listeners(type) { return _listeners(this, type, true); }; EventEmitter.prototype.rawListeners = function rawListeners(type) { return _listeners(this, type, false); }; EventEmitter.listenerCount = function(emitter, type) { if (typeof emitter.listenerCount === "function") return emitter.listenerCount(type); else return listenerCount.call(emitter, type); }; EventEmitter.prototype.listenerCount = listenerCount; function listenerCount(type) { var events = this._events; if (events !== void 0) { var evlistener = events[type]; if (typeof evlistener === "function") return 1; else if (evlistener !== void 0) return evlistener.length; } return 0; } EventEmitter.prototype.eventNames = function eventNames() { return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; }; function arrayClone(arr, n) { var copy = new Array(n); for (var i = 0; i < n; ++i) copy[i] = arr[i]; return copy; } function spliceOne(list, index) { for (; index + 1 < list.length; index++) list[index] = list[index + 1]; list.pop(); } function unwrapListeners(arr) { var ret = new Array(arr.length); for (var i = 0; i < ret.length; ++i) ret[i] = arr[i].listener || arr[i]; return ret; } function once(emitter, name) { return new Promise(function(resolve, reject) { function errorListener(err) { emitter.removeListener(name, resolver); reject(err); } function resolver() { if (typeof emitter.removeListener === "function") emitter.removeListener("error", errorListener); resolve([].slice.call(arguments)); } eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); if (name !== "error") addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true }); }); } function addErrorHandlerIfEventEmitter(emitter, handler, flags) { if (typeof emitter.on === "function") eventTargetAgnosticAddListener(emitter, "error", handler, flags); } function eventTargetAgnosticAddListener(emitter, name, listener, flags) { if (typeof emitter.on === "function") { if (flags.once) emitter.once(name, listener); else emitter.on(name, listener); } else if (typeof emitter.addEventListener === "function") emitter.addEventListener(name, function wrapListener(arg) { if (flags.once) emitter.removeEventListener(name, wrapListener); listener(arg); }); else throw new TypeError("The \"emitter\" argument must be of type EventEmitter. Received type " + typeof emitter); } })); //#endregion //#region node_modules/easy-us/lib/interfaces/common.js var require_common$1 = /* @__PURE__ */ __commonJSMin(((exports) => { var __importDefault = exports && exports.__importDefault || function(mod) { return mod && mod.__esModule ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CommonEventEmitter = void 0; var events_1 = __importDefault(require_events()); var CommonEventEmitter = class extends events_1.default { on(eventName, listener) { return super.on(eventName.toString(), listener); } once(eventName, listener) { return super.once(eventName.toString(), listener); } emit(eventName, ...args) { return super.emit(eventName.toString(), ...args); } off(eventName, listener) { return super.off(eventName.toString(), listener); } }; exports.CommonEventEmitter = CommonEventEmitter; })); //#endregion //#region node_modules/easy-us/lib/interfaces/config.js var require_config$1 = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); })); //#endregion //#region node_modules/lodash/isObject.js var require_isObject = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return value != null && (type == "object" || type == "function"); } module.exports = isObject; })); //#endregion //#region node_modules/lodash/_freeGlobal.js var require__freeGlobal = /* @__PURE__ */ __commonJSMin(((exports, module) => { module.exports = typeof global == "object" && global && global.Object === Object && global; })); //#endregion //#region node_modules/lodash/_root.js var require__root = /* @__PURE__ */ __commonJSMin(((exports, module) => { var freeGlobal = require__freeGlobal(); /** Detect free variable `self`. */ var freeSelf = typeof self == "object" && self && self.Object === Object && self; module.exports = freeGlobal || freeSelf || Function("return this")(); })); //#endregion //#region node_modules/lodash/now.js var require_now = /* @__PURE__ */ __commonJSMin(((exports, module) => { var root = require__root(); /** * Gets the timestamp of the number of milliseconds that have elapsed since * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ * @since 2.4.0 * @category Date * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); * // => Logs the number of milliseconds it took for the deferred invocation. */ var now = function() { return root.Date.now(); }; module.exports = now; })); //#endregion //#region node_modules/lodash/_trimmedEndIndex.js var require__trimmedEndIndex = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** Used to match a single whitespace character. */ var reWhitespace = /\s/; /** * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace * character of `string`. * * @private * @param {string} string The string to inspect. * @returns {number} Returns the index of the last non-whitespace character. */ function trimmedEndIndex(string) { var index = string.length; while (index-- && reWhitespace.test(string.charAt(index))); return index; } module.exports = trimmedEndIndex; })); //#endregion //#region node_modules/lodash/_baseTrim.js var require__baseTrim = /* @__PURE__ */ __commonJSMin(((exports, module) => { var trimmedEndIndex = require__trimmedEndIndex(); /** Used to match leading whitespace. */ var reTrimStart = /^\s+/; /** * The base implementation of `_.trim`. * * @private * @param {string} string The string to trim. * @returns {string} Returns the trimmed string. */ function baseTrim(string) { return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, "") : string; } module.exports = baseTrim; })); //#endregion //#region node_modules/lodash/_Symbol.js var require__Symbol = /* @__PURE__ */ __commonJSMin(((exports, module) => { module.exports = require__root().Symbol; })); //#endregion //#region node_modules/lodash/_getRawTag.js var require__getRawTag = /* @__PURE__ */ __commonJSMin(((exports, module) => { var Symbol = require__Symbol(); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto.toString; /** Built-in value references. */ var symToStringTag = Symbol ? Symbol.toStringTag : void 0; /** * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * * @private * @param {*} value The value to query. * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; try { value[symToStringTag] = void 0; var unmasked = true; } catch (e) {} var result = nativeObjectToString.call(value); if (unmasked) { if (isOwn) value[symToStringTag] = tag; else delete value[symToStringTag]; } return result; } module.exports = getRawTag; })); //#endregion //#region node_modules/lodash/_objectToString.js var require__objectToString = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = Object.prototype.toString; /** * Converts `value` to a string using `Object.prototype.toString`. * * @private * @param {*} value The value to convert. * @returns {string} Returns the converted string. */ function objectToString(value) { return nativeObjectToString.call(value); } module.exports = objectToString; })); //#endregion //#region node_modules/lodash/_baseGetTag.js var require__baseGetTag = /* @__PURE__ */ __commonJSMin(((exports, module) => { var Symbol = require__Symbol(); var getRawTag = require__getRawTag(); var objectToString = require__objectToString(); /** `Object#toString` result references. */ var nullTag = "[object Null]"; var undefinedTag = "[object Undefined]"; /** Built-in value references. */ var symToStringTag = Symbol ? Symbol.toStringTag : void 0; /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) return value === void 0 ? undefinedTag : nullTag; return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value); } module.exports = baseGetTag; })); //#endregion //#region node_modules/lodash/isObjectLike.js var require_isObjectLike = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return value != null && typeof value == "object"; } module.exports = isObjectLike; })); //#endregion //#region node_modules/lodash/isSymbol.js var require_isSymbol = /* @__PURE__ */ __commonJSMin(((exports, module) => { var baseGetTag = require__baseGetTag(); var isObjectLike = require_isObjectLike(); /** `Object#toString` result references. */ var symbolTag = "[object Symbol]"; /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == "symbol" || isObjectLike(value) && baseGetTag(value) == symbolTag; } module.exports = isSymbol; })); //#endregion //#region node_modules/lodash/toNumber.js var require_toNumber = /* @__PURE__ */ __commonJSMin(((exports, module) => { var baseTrim = require__baseTrim(); var isObject = require_isObject(); var isSymbol = require_isSymbol(); /** Used as references for various `Number` constants. */ var NAN = NaN; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt; /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == "number") return value; if (isSymbol(value)) return NAN; if (isObject(value)) { var other = typeof value.valueOf == "function" ? value.valueOf() : value; value = isObject(other) ? other + "" : other; } if (typeof value != "string") return value === 0 ? value : +value; value = baseTrim(value); var isBinary = reIsBinary.test(value); return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; } module.exports = toNumber; })); //#endregion //#region node_modules/lodash/debounce.js var require_debounce = /* @__PURE__ */ __commonJSMin(((exports, module) => { var isObject = require_isObject(); var now = require_now(); var toNumber = require_toNumber(); /** Error message constants. */ var FUNC_ERROR_TEXT = "Expected a function"; var nativeMax = Math.max; var nativeMin = Math.min; /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel * delayed `func` invocations and a `flush` method to immediately invoke them. * Provide `options` to indicate whether `func` should be invoked on the * leading and/or trailing edge of the `wait` timeout. The `func` is invoked * with the last arguments provided to the debounced function. Subsequent * calls to the debounced function return the result of the last `func` * invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the debounced function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to debounce. * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=false] * Specify invoking on the leading edge of the timeout. * @param {number} [options.maxWait] * The maximum time `func` is allowed to be delayed before it's invoked. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != "function") throw new TypeError(FUNC_ERROR_TEXT); wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = "maxWait" in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = "trailing" in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = void 0; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { lastInvokeTime = time; timerId = setTimeout(timerExpired, wait); return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall; return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; } function timerExpired() { var time = now(); if (shouldInvoke(time)) return trailingEdge(time); timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = void 0; if (trailing && lastArgs) return invokeFunc(time); lastArgs = lastThis = void 0; return result; } function cancel() { if (timerId !== void 0) clearTimeout(timerId); lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = void 0; } function flush() { return timerId === void 0 ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === void 0) return leadingEdge(lastCallTime); if (maxing) { clearTimeout(timerId); timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === void 0) timerId = setTimeout(timerExpired, wait); return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } module.exports = debounce; })); //#endregion //#region node_modules/easy-us/lib/utils/const.js var require_const = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.$const = void 0; exports.$const = { TAB_UID: "_uid_", TAB_URLS: "_urls_", TAB_CURRENT_PANEL_NAME: "_current_panel_name_" }; })); //#endregion //#region node_modules/easy-us/lib/interfaces/store.provider.js var require_store_provider = /* @__PURE__ */ __commonJSMin(((exports) => { var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function(resolve) { resolve(value); }); } return new (P || (P = Promise))(function(resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GMStoreProvider = exports.MemoryStoreProvider = exports.LocalStoreChangeEvent = void 0; var const_1 = require_const(); var LocalStoreChangeEvent = class extends Event { constructor() { super(...arguments); this.key = ""; } }; exports.LocalStoreChangeEvent = LocalStoreChangeEvent; /** * 内存存储提供器 */ var MemoryStoreProvider = class MemoryStoreProvider { get(key, defaultValue) { var _a; return (_a = Reflect.get(MemoryStoreProvider._source.store, key)) !== null && _a !== void 0 ? _a : defaultValue; } set(key, value) { var _a; const pre = Reflect.get(MemoryStoreProvider._source.store, key); Reflect.set(MemoryStoreProvider._source.store, key, value); (_a = MemoryStoreProvider.storeListeners.get(key)) === null || _a === void 0 || _a.forEach((lis) => lis(value, pre)); } delete(key) { Reflect.deleteProperty(MemoryStoreProvider._source.store, key); } list() { return Object.keys(MemoryStoreProvider._source.store); } getTab(key) { return __awaiter(this, void 0, void 0, function* () { return Reflect.get(MemoryStoreProvider._source.tab, key); }); } setTab(key, value) { var _a; return __awaiter(this, void 0, void 0, function* () { Reflect.set(MemoryStoreProvider._source.tab, key, value); (_a = MemoryStoreProvider.tabListeners.get(key)) === null || _a === void 0 || _a.forEach((lis) => lis(value, this.getTab(key))); }); } addChangeListener(key, listener) { const listeners = MemoryStoreProvider.storeListeners.get(key) || []; listeners.push(listener); MemoryStoreProvider.storeListeners.set(key, listeners); } removeChangeListener(listener) { MemoryStoreProvider.tabListeners.forEach((lis, key) => { const index = lis.findIndex((l) => l === listener); if (index !== -1) { lis.splice(index, 1); MemoryStoreProvider.tabListeners.set(key, lis); } }); } addTabChangeListener(key, listener) { const listeners = MemoryStoreProvider.tabListeners.get(key) || []; listeners.push(listener); MemoryStoreProvider.tabListeners.set(key, listeners); } removeTabChangeListener(key, listener) { const listeners = MemoryStoreProvider.tabListeners.get(key) || []; const index = listeners.findIndex((l) => l === listener); if (index !== -1) { listeners.splice(index, 1); MemoryStoreProvider.tabListeners.set(key, listeners); } } }; MemoryStoreProvider._source = { store: {}, tab: {} }; MemoryStoreProvider.storeListeners = /* @__PURE__ */ new Map(); MemoryStoreProvider.tabListeners = /* @__PURE__ */ new Map(); exports.MemoryStoreProvider = MemoryStoreProvider; /** * 油猴存储器 */ var GMStoreProvider = class { constructor() { if (self === top && typeof globalThis.GM_listValues !== "undefined") { for (const val of GM_listValues()) if (val.startsWith("_tab_change_")) GM_deleteValue(val); } } /** 获取本地能够触发 tab 监听的key */ getTabChangeHandleKey(tabUid, key) { return `_tab_change_${tabUid}_${key}`; } get(key, defaultValue) { return GM_getValue(key, defaultValue); } set(key, value) { GM_setValue(key, value); } delete(key) { GM_deleteValue(key); } list() { return GM_listValues(); } getTab(key) { return new Promise((resolve, reject) => { GM_getTab((tab = {}) => resolve(Reflect.get(tab, key))); }); } setTab(key, value) { return new Promise((resolve, reject) => { GM_getTab((tab = {}) => { Reflect.set(tab, key, value); GM_saveTab(tab); this.set(this.getTabChangeHandleKey(Reflect.get(tab, const_1.$const.TAB_UID), key), value); resolve(); }); }); } addChangeListener(key, listener) { return GM_addValueChangeListener(key, (_, pre, curr, remote) => { listener(curr, pre, remote); }); } removeChangeListener(listenerId) { if (typeof listenerId === "number") GM_removeValueChangeListener(listenerId); } addTabChangeListener(key, listener) { return __awaiter(this, void 0, void 0, function* () { const uid = yield this.getTab(const_1.$const.TAB_UID); return GM_addValueChangeListener(this.getTabChangeHandleKey(uid, key), (_, pre, curr) => { listener(curr, pre); }); }); } removeTabChangeListener(key, listener) { return this.removeChangeListener(listener); } }; exports.GMStoreProvider = GMStoreProvider; })); //#endregion //#region node_modules/easy-us/lib/utils/store.js var require_store = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.$store = exports.MemoryStoreProvider = exports.GMStoreProvider = void 0; var store_provider_1 = require_store_provider(); var store_provider_2 = require_store_provider(); Object.defineProperty(exports, "GMStoreProvider", { enumerable: true, get: function() { return store_provider_2.GMStoreProvider; } }); Object.defineProperty(exports, "MemoryStoreProvider", { enumerable: true, get: function() { return store_provider_2.MemoryStoreProvider; } }); exports.$store = typeof globalThis.unsafeWindow === "undefined" ? new store_provider_1.MemoryStoreProvider() : new store_provider_1.GMStoreProvider(); })); //#endregion //#region node_modules/easy-us/lib/utils/common.js var require_common = /* @__PURE__ */ __commonJSMin(((exports) => { var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function(resolve) { resolve(value); }); } return new (P || (P = Promise))(function(resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = exports && exports.__rest || function(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") { for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = exports && exports.__importDefault || function(mod) { return mod && mod.__esModule ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveCustomElementName = exports.$ = void 0; var debounce_1 = __importDefault(require_debounce()); var store_1 = require_store(); /** * 公共的工具库 */ exports.$ = { /** * 构造 config 配置对象, 可进行响应式存储 * @param script 脚本 */ createConfigProxy(script) { var _a, _b; const proxy = new Proxy(script.cfg, { set(target, propertyKey, value) { const key = exports.$.namespaceKey(script.namespace, propertyKey); store_1.$store.set(key, value); return Reflect.set(target, propertyKey, value); }, get(target, propertyKey) { const value = store_1.$store.get(exports.$.namespaceKey(script.namespace, propertyKey)); Reflect.set(target, propertyKey, value); return value; } }); for (const key in script.configs) if (Object.prototype.hasOwnProperty.call(script.configs, key)) { const element = Reflect.get(script.configs, key); Reflect.set(proxy, key, store_1.$store.get(exports.$.namespaceKey(script.namespace, key), element.defaultValue)); } if (script.namespace) proxy.notes = (_b = (_a = script.configs) === null || _a === void 0 ? void 0 : _a.notes) === null || _b === void 0 ? void 0 : _b.defaultValue; return proxy; }, /** * 获取所有原生(未处理的)脚本配置 * @param scripts 脚本列表 */ getAllRawConfigs(scripts) { const object = {}; for (const script of scripts) for (const key in script.configs) if (Object.prototype.hasOwnProperty.call(script.configs, key)) { const _a = script.configs[key], { label } = _a, element = __rest(_a, ["label"]); Reflect.set(object, exports.$.namespaceKey(script.namespace, key), Object.assign({ label: exports.$.namespaceKey(script.namespace, key) }, element)); } return object; }, /** * 获取匹配到的脚本 * @param projects 程序列表 */ getMatchedScripts(projects, urls) { const scripts = []; for (const project of projects) for (const key in project.scripts) if (Object.prototype.hasOwnProperty.call(project.scripts, key)) { const script = project.scripts[key]; const script_matches_urls = script.matches.map((u) => Array.isArray(u) ? u[1] : u); const script_excludes_urls = (script.excludes || []).map((u) => Array.isArray(u) ? u[1] : u); if (project.domains === void 0 || project.domains.length === 0 || project.domains.some((d) => urls.some((url) => new URL(url).origin.includes(d)))) { if (script_excludes_urls.some((u) => urls.some((url) => RegExp(u).test(url)))) continue; if (script_matches_urls.some((u) => urls.some((url) => RegExp(u).test(url)))) scripts.push(script); } } return scripts; }, /** * 获取具名键 * @param namespace 命名空间 * @param key 键 */ namespaceKey(namespace, key) { return namespace ? namespace + "." + key.toString() : key.toString(); }, /** 创建唯一id , 不带横杠 */ uuid() { return "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0; return (c === "x" ? r : r & 3 | 8).toString(16); }); }, /** * 生成随机数, 使用 Math.round 取整 * @param min 最小值 * @param max 最大值 */ random(min, max) { return Math.round(Math.random() * (max - min)) + min; }, /** * 暂停 * @param period 毫秒 */ sleep(period) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve) => { setTimeout(resolve, period); }); }); }, /** * 当前是否处于浏览器环境 */ isInBrowser() { return typeof window !== "undefined" && typeof window.document !== "undefined"; }, /** * 监听页面宽度变化 * @param el 任意元素,如果此元素被移除,则不执行 resize 回调 * @param handler resize 回调 */ onresize(el, handler) { const resize = (0, debounce_1.default)(() => { /** * 如果元素被删除,则移除监听器 * 不使用 el.parentElement 是因为如果是顶级元素,例如 shadowRoot 中的一级子元素, el.parentNode 不为空,但是 el.parentElement 为空 */ if (el.parentNode === null) window.removeEventListener("resize", resize); else handler(el); }, 200); resize(); window.addEventListener("resize", resize); }, /** 加载自定义元素 */ loadCustomElements(elements) { for (const element of elements) { const name = resolveCustomElementName(element, "-"); if (customElements.get(name) === void 0) customElements.define(name, element); } }, /** 是否处于顶级 window ,而不是子 iframe */ isInTopWindow() { return self === top; }, /** * 创建弹出窗口 * @param url 地址 * @param winName 窗口名 * @param w 宽 * @param h 高 * @param scroll 滚动条 */ createCenteredPopupWindow(url, winName, opts) { const { width, height, scrollbars, resizable } = opts; const LeftPosition = screen.width ? (screen.width - width) / 2 : 0; const TopPosition = screen.height ? (screen.height - height) / 2 : 0; const settings = "height=" + height + ",width=" + width + ",top=" + TopPosition + ",left=" + LeftPosition + ",scrollbars=" + (scrollbars ? "yes" : "no") + ",resizable=" + (resizable ? "yes" : "no"); return window.open(url, winName, settings); }, waitForElement(selector, opts) { return this.waitFor(() => { return typeof selector === "function" ? selector() : document.querySelector(selector); }, opts); }, waitFor(predicate, opts) { return new Promise((resolve, reject) => { let timeout; const interval = setInterval(() => { const result = predicate(); if (result) { clearInterval(interval); timeout && clearTimeout(timeout); resolve(result); } }, (opts === null || opts === void 0 ? void 0 : opts.check_period_ms) || 1e3); if (opts === null || opts === void 0 ? void 0 : opts.timeout_seconds) timeout = setTimeout(() => { clearInterval(interval); resolve(void 0); }, ((opts === null || opts === void 0 ? void 0 : opts.timeout_seconds) || 10) * 1e3); }); } }; /** * 将每个驼峰前面添加目标字符串,用于自定义元素名的转换 * @param el 自定义元素 * @param target 目标字符串 */ function resolveCustomElementName(el, target) { return el.name.replace(/([A-Z])/g, target + "$1").toLowerCase().split(target).slice(1).join(target); } exports.resolveCustomElementName = resolveCustomElementName; })); //#endregion //#region node_modules/easy-us/lib/utils/dom.js var require_dom = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.enableElementTouchDraggable = exports.enableElementDraggable = exports.$$el = exports.$el = exports.h = void 0; var common_1 = require_common(); /** * 创建元素,效果等同于 document.createElement(tagName, options) * @param element 标签名或者自定义元素构造函数 * @param attrsOrChildren 元素属性,或者子元素列表,或者字符串 * @param childrenOrHandler 子元素列表,或者元素生成的回调函数 */ function h(element, attrsOrChildren, childrenOrHandler) { let name = ""; if (typeof element === "function") name = (0, common_1.resolveCustomElementName)(element, "-"); else name = element; const el = document.createElement(name); if (attrsOrChildren) { if (Array.isArray(attrsOrChildren)) for (const child of attrsOrChildren) if (typeof child === "function") el.append(document.createElement(child.name)); else el.append(child); else if (typeof attrsOrChildren === "string") el.append(attrsOrChildren); else { const attrs = attrsOrChildren; /** 设置属性 */ for (const key in attrs) if (Object.prototype.hasOwnProperty.call(attrs, key)) { if (key === "style") Object.assign(el.style, attrs[key]); else { const value = attrs[key]; Reflect.set(el, key, value); } } } } if (childrenOrHandler) { if (typeof childrenOrHandler === "function") childrenOrHandler.call(el, el); else if (Array.isArray(childrenOrHandler)) for (const child of childrenOrHandler) if (typeof child === "function") el.append(document.createElement(child.name)); else el.append(child); else if (typeof childrenOrHandler === "string") el.append(childrenOrHandler); } return el; } exports.h = h; /** * 选择元素,效果等同于 document.querySelector(selector) */ function $el(selector, root = window.document) { const el = root.querySelector(selector); return el === null ? void 0 : el; } exports.$el = $el; /** * 选择元素列表,效果等同于 document.querySelectorAll(selector) */ function $$el(selector, root = window.document) { return Array.from(root.querySelectorAll(selector)); } exports.$$el = $$el; /** * 使元素可以被拖动 * @param header 拖动块 * @param target 移动块 */ function enableElementDraggable(header, target, ondrag) { let pos1 = 0; let pos2 = 0; let pos3 = 0; let pos4 = 0; header.addEventListener("mousedown", dragMouseDown); function dragMouseDown(e) { e = e || window.event; pos3 = e.clientX; pos4 = e.clientY; document.addEventListener("mouseup", closeDragElement); document.addEventListener("mousemove", elementDrag); } function elementDrag(e) { e.stopPropagation(); e = e || window.event; pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; target.style.top = Math.max(target.offsetTop - pos2, 10) + "px"; target.style.left = target.offsetLeft - pos1 + "px"; } function closeDragElement() { ondrag === null || ondrag === void 0 || ondrag(); document.removeEventListener("mouseup", closeDragElement); document.removeEventListener("mousemove", elementDrag); } } exports.enableElementDraggable = enableElementDraggable; /** * 支持元素移动端拖动支持 */ function enableElementTouchDraggable(header, target, ondrag) { let pos1 = 0; let pos2 = 0; let pos3 = 0; let pos4 = 0; header.addEventListener("touchstart", dragTouchStart); function dragTouchStart(e) { e = e || window.event; const touch = e.touches[0]; pos3 = touch.clientX; pos4 = touch.clientY; document.addEventListener("touchend", closeDragElement); document.addEventListener("touchmove", elementDrag); } function elementDrag(e) { e.stopPropagation(); e = e || window.event; const touch = e.touches[0]; pos1 = pos3 - touch.clientX; pos2 = pos4 - touch.clientY; pos3 = touch.clientX; pos4 = touch.clientY; target.style.top = Math.max(target.offsetTop - pos2, 10) + "px"; target.style.left = target.offsetLeft - pos1 + "px"; } function closeDragElement() { ondrag === null || ondrag === void 0 || ondrag(); document.removeEventListener("touchend", closeDragElement); document.removeEventListener("touchmove", elementDrag); } } exports.enableElementTouchDraggable = enableElementTouchDraggable; })); //#endregion //#region node_modules/easy-us/lib/utils/elements.js var require_elements$1 = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.$elements = void 0; /** * 全局元素 在调用 start 函数后自动挂载 */ exports.$elements = { tooltipContainer: void 0, root: void 0, currentScriptPanel: void 0, wrapper: void 0 }; })); //#endregion //#region node_modules/easy-us/lib/utils/tampermonkey.js var require_tampermonkey = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.$gm = void 0; /** * 油猴封装库 * * 在对本地持久化存储时可以使用 getValue , setValue 等方法 * 在对当前标签页中的临时变量,可以使用 getTab , setTab 的方法 * * 例如设置信息则使用本地持久化存储 * 而对于消息推送,弹窗通知等临时,但是需要跨域的变量,可以使用标签页去存储临时信息 */ exports.$gm = { /** 全局 unsafeWindow 对象 */ unsafeWindow: typeof globalThis.unsafeWindow === "undefined" ? globalThis.window : globalThis.unsafeWindow, isInGMContext() { return typeof GM_info !== "undefined"; }, /** 获取 GM_info */ getInfos() { return typeof GM_info === "undefined" ? void 0 : GM_info; }, /** 与 $store.getTab 不同的是这个直接获取全部 tab 对象 */ getTab(callback) { return typeof GM_getTab === "undefined" ? void 0 : GM_getTab(callback); }, /** * 发送系统通知 * @param content 内容 * @param options 选项 */ notification(content, options) { var _a; const { onclick, ondone, important, duration = 30, silent = true, extraTitle = "" } = options || {}; const { icon, name } = ((_a = exports.$gm.getInfos()) === null || _a === void 0 ? void 0 : _a.script) || {}; GM_notification({ title: name + (extraTitle ? "-" + extraTitle : ""), text: content, image: icon || "", highlight: important, onclick, ondone, silent, timeout: duration * 1e3 }); }, getMetadataFromScriptHead(key) { var _a, _b; const metadataString = (_a = this.getInfos()) === null || _a === void 0 ? void 0 : _a.scriptMetaStr; if (!metadataString) return []; else return ((((_b = metadataString.match(/\/\/\s+==UserScript==([\s\S]+)\/\/\s+==\/UserScript==/)) === null || _b === void 0 ? void 0 : _b[1]) || "").match(/\/\/\s+@(.+?)\s+(.*?)(?:\n|$)/g) || []).map((line) => { const words = line.match(/[\S]+/g) || []; return { key: (words[1] || "").replace("@", ""), value: words.slice(2).join(" ") }; }).filter((l) => l.key === key).map((l) => l.value); } }; })); //#endregion //#region node_modules/easy-us/lib/utils/ui.js var require_ui = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.$ui = void 0; var common_1 = require_common(); var dom_1 = require_dom(); var elements_1 = require_elements$1(); var tampermonkey_1 = require_tampermonkey(); /** * 获取页面 zoom 缩放比例。 * 平台脚本(如智慧树)会通过 html{zoom} 调整界面缩放, * zoom 会同步缩放 position:fixed 的定位坐标,但鼠标事件 clientX/Y 为未缩放值, * 定位 tooltip 等鼠标跟随元素时需要反向补偿,否则会错位。 */ function getPageZoom() { const zoom = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("zoom") || "1"); return Number.isFinite(zoom) && zoom > 0 ? zoom : 1; } /** * 元素创建器 */ exports.$ui = { /** * 启动元素提示气泡,根据元素 title 即时显示,(兼容手机端的提示) * @param target */ tooltip(target) { target.setAttribute("data-title", target.title); if (tampermonkey_1.$gm.isInGMContext()) target.removeAttribute("title"); const onMouseMove = (e) => { if (elements_1.$elements.tooltipContainer && elements_1.$elements.tooltipContainer.style.display !== "none") { const zoom = getPageZoom(); elements_1.$elements.tooltipContainer.style.top = e.y / zoom + "px"; elements_1.$elements.tooltipContainer.style.left = e.x / zoom + "px"; } }; const onTouchMove = (e) => { if (elements_1.$elements.tooltipContainer && elements_1.$elements.tooltipContainer.style.display !== "none") { const zoom = getPageZoom(); const touch = e.touches[0]; elements_1.$elements.tooltipContainer.style.top = touch.clientY / zoom + "px"; elements_1.$elements.tooltipContainer.style.left = touch.clientX / zoom + "px"; } }; const showTitle = (e) => { const dataTitle = target.getAttribute("data-title"); if (elements_1.$elements.tooltipContainer) { if (dataTitle) { const zoom = getPageZoom(); elements_1.$elements.tooltipContainer.innerHTML = dataTitle.split("\n").join("
") || ""; if (e instanceof MouseEvent) { elements_1.$elements.tooltipContainer.style.top = e.y / zoom + "px"; elements_1.$elements.tooltipContainer.style.left = e.x / zoom + "px"; } else if (e instanceof TouchEvent) { const touch = e.touches[0]; elements_1.$elements.tooltipContainer.style.top = touch.clientY / zoom + "px"; elements_1.$elements.tooltipContainer.style.left = touch.clientX / zoom + "px"; } elements_1.$elements.tooltipContainer.style.display = "block"; } else elements_1.$elements.tooltipContainer.style.display = "none"; } window.addEventListener("mousemove", onMouseMove); window.addEventListener("touchmove", onTouchMove); }; const hideTitle = () => { if (elements_1.$elements.tooltipContainer) elements_1.$elements.tooltipContainer.style.display = "none"; window.removeEventListener("mousemove", onMouseMove); window.removeEventListener("touchmove", onTouchMove); }; hideTitle(); target.addEventListener("mouseenter", showTitle); target.addEventListener("click", showTitle); target.addEventListener("mouseleave", hideTitle); target.addEventListener("touchstart", showTitle); target.addEventListener("touchend", hideTitle); target.addEventListener("touchcancel", hideTitle); target.addEventListener("blur", hideTitle); return target; }, scriptPanel(script, store, opts) { var _a, _b, _c, _d; const scriptPanel = (0, dom_1.h)("script-panel-element", { name: script.name }); const notesExpandedKey = `_notes_expanded_${script.fullName()}`; scriptPanel.setNotesExpanded(store.get(notesExpandedKey, true)); scriptPanel.notesHeader.addEventListener("click", () => { const expanded = !scriptPanel.isNotesExpanded(); scriptPanel.setNotesExpanded(expanded); store.set(notesExpandedKey, expanded); }); scriptPanel.notesHeader.title = "点击收缩 / 展开"; this.tooltip(scriptPanel.notesHeader); const updateNotesVisibility = (content) => { scriptPanel.notesContainer.style.display = (content === null || content === void 0 ? void 0 : content.trim()) ? "" : "none"; }; script.onConfigChange("notes", (pre, curr) => { scriptPanel.notesBody.innerHTML = script.cfg.notes || ""; updateNotesVisibility(script.cfg.notes); }); script.panel = scriptPanel; scriptPanel.notesBody.innerHTML = ((_b = (_a = script.configs) === null || _a === void 0 ? void 0 : _a.notes) === null || _b === void 0 ? void 0 : _b.defaultValue) || ""; updateNotesVisibility((_d = (_c = script.configs) === null || _c === void 0 ? void 0 : _c.notes) === null || _d === void 0 ? void 0 : _d.defaultValue); let configs = Object.create({}); const elList = []; for (const key in script.configs) if (Object.prototype.hasOwnProperty.call(script.configs, key)) { const cfg = script.configs[key]; if (cfg.separator) { elList.push(this.configsArea(this.configs(script.namespace, store, configs || {}, opts === null || opts === void 0 ? void 0 : opts.onload, script))); elList.push((0, dom_1.h)("div", { className: "separator", style: { margin: "0px 8px" } }, cfg.separator)); configs = Object.create({}); } configs[key] = cfg; } if (Object.keys(configs).length > 0) elList.push(this.configsArea(this.configs(script.namespace, store, configs || {}, opts === null || opts === void 0 ? void 0 : opts.onload, script))); scriptPanel.configsContainer.replaceChildren(...elList); return scriptPanel; }, /** 创建独立的设置区域 */ configsArea(configElements) { /** 创建设置板块 */ const configsContainer = (0, dom_1.h)("div", { className: "configs card" }); /** 设置区域主体 */ const configsBody = (0, dom_1.h)("div", { className: "configs-body" }); configsBody.append(...Object.entries(configElements).map(([key, el]) => el)); configsContainer.append(configsBody); return configsContainer; }, /** 创建设置元素 */ configs(namespace, store, configs, onload, script) { /** 解析插槽内容,支持函数懒加载(this 绑定 script,参数传 cfg) */ const resolveSlot = (slot) => typeof slot === "function" ? slot.call(script, script === null || script === void 0 ? void 0 : script.cfg) : slot; const elements = Object.create({}); for (const key in configs) if (Object.prototype.hasOwnProperty.call(configs, key)) { const config = configs[key]; if (config.label !== void 0) { const element = (0, dom_1.h)("config-element", { key: common_1.$.namespaceKey(namespace, key), tag: config.tag, sync: config.sync, attrs: config.attrs, _onload: function(el) { var _a; (_a = config.onload) === null || _a === void 0 || _a.call(this, el); onload === null || onload === void 0 || onload(el); }, defaultValue: config.defaultValue, options: config.options, showIf: config.showIf, elementClassName: config.elementClassName, labelClassName: config.labelClassName, providerClassName: config.providerClassName, enableForAttribute: config.enableForAttribute, prefixSlot: resolveSlot(config.prefixSlot), suffixSlot: resolveSlot(config.suffixSlot) }); element.store = store; element.label.textContent = config.label; elements[key] = element; } } return elements; }, /** 创建多行的文本,支持 字符串,元素,以及包含字符串元素的列表,最多二维数组 */ notes(lines, tag = "ul") { return (0, dom_1.h)(tag, lines.map((line) => (0, dom_1.h)("li", Array.isArray(line) ? line.map((node) => typeof node === "string" ? (0, dom_1.h)("div", { innerHTML: node }) : node) : [typeof line === "string" ? (0, dom_1.h)("div", { innerHTML: line }) : line]))); }, /** * 生成一个复制按钮 * @param name 按钮名 * @param value 复制内容 */ copy(name, value) { return (0, dom_1.h)("span", "📄" + name, (btn) => { btn.className = "copy"; btn.addEventListener("click", () => { btn.innerText = "已复制√"; navigator.clipboard.writeText(value); setTimeout(() => { btn.innerText = "📄" + name; }, 500); }); }); }, /** * 创建一个取消默认事件的文字按钮,如果不点击,则执行默认事件 * @param opts 参数 */ preventText(opts) { const { name, delay = 3, autoRemove = true, ondefault, onprevent } = opts; const span = (0, dom_1.h)("span", name); span.style.textDecoration = "underline"; span.style.cursor = "pointer"; span.onclick = () => { clearTimeout(id); if (autoRemove) span.remove(); onprevent === null || onprevent === void 0 || onprevent(span); }; const id = setTimeout(() => { if (autoRemove) span.remove(); ondefault(span); }, delay * 1e3); return span; }, /** * 将所有子元素隔开 * x: 默认 12 * y: 默认 0 * separator: 默认 ' ' */ space(children, options) { return (0, dom_1.h)("div", { className: "space" }, (div) => { var _a, _b, _c; for (let index = 0; index < children.length; index++) { const child = (0, dom_1.h)("span", { className: "space-item" }, [children[index]]); child.style.display = "inline-block"; const x = (_a = options === null || options === void 0 ? void 0 : options.x) !== null && _a !== void 0 ? _a : 12; const y = (_b = options === null || options === void 0 ? void 0 : options.y) !== null && _b !== void 0 ? _b : 0; if (index > 0) { child.style.marginLeft = x / 2 + "px"; child.style.marginRight = x / 2 + "px"; child.style.marginTop = y / 2 + "px"; child.style.marginBottom = y / 2 + "px"; } else { child.style.marginRight = x / 2 + "px"; child.style.marginBottom = y / 2 + "px"; } div.append(child); if (index !== children.length - 1) div.append((0, dom_1.h)("span", [(_c = options === null || options === void 0 ? void 0 : options.separator) !== null && _c !== void 0 ? _c : " "])); } }); }, button(text, attrs, handler) { return (0, dom_1.h)("input", Object.assign({ type: "button" }, attrs), function(btn) { btn.value = text || ""; btn.classList.add("base-style-button"); handler === null || handler === void 0 || handler.apply(this, [btn]); }); } }; })); //#endregion //#region node_modules/easy-us/lib/utils/index.js var require_utils = /* @__PURE__ */ __commonJSMin(((exports) => { var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) desc = { enumerable: true, get: function() { return m[k]; } }; Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; })); var __exportStar = exports && exports.__exportStar || function(m, exports$3) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$3, p)) __createBinding(exports$3, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); __exportStar(require_common(), exports); __exportStar(require_ui(), exports); __exportStar(require_dom(), exports); __exportStar(require_elements$1(), exports); __exportStar(require_tampermonkey(), exports); __exportStar(require_store(), exports); __exportStar(require_const(), exports); })); //#endregion //#region node_modules/easy-us/lib/interfaces/cors.js var require_cors = /* @__PURE__ */ __commonJSMin(((exports) => { var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function(resolve) { resolve(value); }); } return new (P || (P = Promise))(function(resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.cors = exports.CorsEventEmitter = void 0; var utils_1 = require_utils(); var common_1 = require_common(); var const_1 = require_const(); var store_1 = require_store(); /** * 跨域脚本事件通讯 */ var CorsEventEmitter = class { constructor() { this.eventMap = /* @__PURE__ */ new Map(); } eventKey(name) { return "cors.events." + name; } tempKey(...args) { return ["_temp_", ...args].join("."); } keyOfReturn(id) { return this.tempKey("event", id, "return"); } keyOfArguments(id) { return this.tempKey("event", id, "arguments"); } keyOfState(id) { return this.tempKey("event", id, "state"); } /** * 提交事件 * @param name 事件名 * @param args 事件参数 * @param callback 事件回调,可以接收返回值 */ emit(name, args = [], callback) { store_1.$store.getTab(const_1.$const.TAB_UID).then((uid) => { const id = common_1.$.uuid().replace(/-/g, ""); const key = uid + "." + this.eventKey(name); /** 状态, 0 等待交互 , 1 确定 , 2 取消 , 后面紧跟着模态框中获取到的值,如果模态框类型是 prompt 则有值,否则为空字符串 */ store_1.$store.set(this.keyOfState(id), 0); /** 模态框所需参数 */ store_1.$store.set(this.keyOfArguments(id), args); /** * 由于部分脚本管理器API实现不同,脚本猫中 setValue 后立即监听变化会监听到上一个 set 0 的事件 * 所以这里等待一段时间后再进行监听,避免监听到上一个 set 0 的事件 */ setTimeout(() => { const listenerId = store_1.$store.addChangeListener(this.keyOfState(id), () => { store_1.$store.removeChangeListener(listenerId); callback === null || callback === void 0 || callback(store_1.$store.get(this.keyOfReturn(id))); store_1.$store.delete(this.keyOfState(id)); store_1.$store.delete(this.keyOfReturn(id)); store_1.$store.delete(this.keyOfArguments(id)); }) || 0; /** 添加 id 到监听队列 */ store_1.$store.set(key, (store_1.$store.get(key) ? String(store_1.$store.get(key)).split(",") : []).concat(id).join(",")); }, 100); }).catch(console.error); } /** * 监听跨域事件 * @param name 事件名,全局唯一 * @param handler 处理器,可以通过处理器返回任意值作为另外一端的回调值 * @returns */ on(name, handler) { return new Promise((resolve) => { store_1.$store.getTab(const_1.$const.TAB_UID).then((uid) => { const key = uid + "." + this.eventKey(name); const originId = this.eventMap.get(key); if (originId) resolve(originId); else { const id = store_1.$store.addChangeListener(key, (curr, pre, remote) => __awaiter(this, void 0, void 0, function* () { if (remote) { if (curr === void 0) return; const list = String(curr).split(","); const id = list.pop(); if (id) { store_1.$store.set(this.keyOfReturn(id), yield handler(store_1.$store.get(this.keyOfArguments(id)))); setTimeout(() => { store_1.$store.set(this.keyOfState(id), 1); store_1.$store.set(key, list.join(",")); }, 100); } } })) || 0; this.eventMap.set(key, id); resolve(id); } }).catch(console.error); }); } off(name) { const key = this.eventKey(name); const originId = this.eventMap.get(key); if (originId) { this.eventMap.delete(key); store_1.$store.removeChangeListener(originId); } } defineTopFunction(func) { if (utils_1.$gm.isInGMContext() === false) return (() => {}); const event_name = "_top_function_." + getFuncId(func); if (self === top) exports.cors.on(event_name, (args) => __awaiter(this, void 0, void 0, function* () { return yield func(...args); })); return (...args) => __awaiter(this, void 0, void 0, function* () { if (self === top) return yield func(...args); return yield new Promise((resolve, reject) => { try { exports.cors.emit(event_name, args, (val) => { resolve(val); }); } catch (e) { reject(e); } }); }); } }; exports.CorsEventEmitter = CorsEventEmitter; if (typeof GM_listValues !== "undefined" && self === top) window.onload = () => { store_1.$store.list().forEach((key) => { if (/_temp_.event.[0-9a-z]{32}.(state|return|arguments)/.test(key)) store_1.$store.delete(key); if (/_top_function_.*/.test(key)) store_1.$store.delete(key); if (/[0-9a-z]{32}.cors.events/.test(key)) store_1.$store.delete(key); }); }; /** * 全局跨域对象 */ exports.cors = new CorsEventEmitter(); function getFuncId(fn) { if (typeof fn !== "function") throw new Error("first argument in defineTopFunction() is not Function!"); const str = fn.toString(); let hash = 0; for (let i = 0; i < str.length; i++) { hash = (hash << 5) - hash + str.charCodeAt(i); hash |= 0; } return Math.abs(hash).toString(36).padStart(16, "0").slice(-16); } })); //#endregion //#region node_modules/easy-us/lib/interfaces/project.js var require_project = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.Project = void 0; exports.Project = class Project { constructor({ name, domains, scripts }) { this.name = name; this.domains = domains; for (const key in scripts) if (Object.prototype.hasOwnProperty.call(scripts, key)) { const element = scripts[key]; element.projectName = name; } this.scripts = scripts; } static create(opts) { return new Project(opts); } }; })); //#endregion //#region node_modules/easy-us/lib/interfaces/script.js var require_script = /* @__PURE__ */ __commonJSMin(((exports) => { var __importDefault = exports && exports.__importDefault || function(mod) { return mod && mod.__esModule ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Script = exports.BaseScript = void 0; var common_1 = require_common(); var store_1 = require_store(); var common_2 = require_common$1(); var events_1 = __importDefault(require_events()); var BaseScript = class extends common_2.CommonEventEmitter {}; exports.BaseScript = BaseScript; /** * 脚本 */ var Script = class extends BaseScript { get configs() { if (!this._resolvedConfigs) this._resolvedConfigs = typeof this._configs === "function" ? this._configs() : this._configs; return this._resolvedConfigs; } set configs(c) { this._configs = c; } constructor({ name, namespace, matches, excludes, configs, hideInPanel, onstart, onactive, oncomplete, onbeforeunload, onrender, onhistorychange, onhistorychanged, methods, priority }) { super(); /** 排除的链接 [链接的解释,链接/正则表达式][] */ this.excludes = []; /** 通过 configs 映射并经过解析后的配置对象 */ this.cfg = {}; /** 脚本暴露给外部调用的方法 */ this.methods = Object.create({}); /** 自定义事件触发器,避免使用 script.emit , script.on 导致与原有的事件冲突,使用 script.event.emit 和 script.event.on */ this.event = new events_1.default(); this.name = name; this.namespace = namespace; this.matches = matches; this.excludes = excludes; this._configs = configs; this.hideInPanel = hideInPanel; this.onstart = this.errorHandler(onstart); this.onactive = this.errorHandler(onactive); this.oncomplete = this.errorHandler(oncomplete); this.onbeforeunload = this.errorHandler(onbeforeunload); this.onrender = this.errorHandler(onrender); this.onhistorychange = this.errorHandler(onhistorychange); this.onhistorychanged = this.errorHandler(onhistorychanged); this.methods = (methods === null || methods === void 0 ? void 0 : methods.bind(this)()) || Object.create({}); this.priority = priority !== null && priority !== void 0 ? priority : 0; if (this.methods) { for (const key in methods) if (Reflect.has(this.methods, key) && typeof this.methods[key] !== "function") Reflect.set(this.methods, key, this.errorHandler(this.methods[key])); } } onConfigChange(key, handler) { const _key = common_1.$.namespaceKey(this.namespace, key.toString()); return store_1.$store.addChangeListener(_key, (curr, pre, remote) => { handler(curr, pre, !!remote); }); } offConfigChange(listener) { store_1.$store.removeChangeListener(listener); } /** * 获取全路径名 */ fullName() { return this.projectName ? `${this.projectName}-${this.name}` : this.name; } errorHandler(func) { return (...args) => { try { return func === null || func === void 0 ? void 0 : func.apply(this, args); } catch (err) { console.error(err); if (err instanceof Error) this.emit("scripterror", err.message); else this.emit("scripterror", String(err)); } }; } }; exports.Script = Script; })); //#endregion //#region node_modules/easy-us/lib/interfaces/index.js var require_interfaces = /* @__PURE__ */ __commonJSMin(((exports) => { var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) desc = { enumerable: true, get: function() { return m[k]; } }; Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; })); var __exportStar = exports && exports.__exportStar || function(m, exports$2) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$2, p)) __createBinding(exports$2, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); __exportStar(require_common$1(), exports); __exportStar(require_config$1(), exports); __exportStar(require_cors(), exports); __exportStar(require_project(), exports); __exportStar(require_script(), exports); __exportStar(require_store_provider(), exports); })); //#endregion //#region node_modules/easy-us/lib/elements/interface.js var require_interface = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.IElement = void 0; var IElement = class extends HTMLElement { /** 每次将元素添加到文档时调用。规范建议,开发人员应尽可能在此回调中而不是构造函数中实现自定义元素设置。 */ connectedCallback() {} /** 每次从文档中删除元素时调用。 */ disconnectedCallback() {} /** 每次将元素移动到新文档时调用 */ adoptedCallback() {} /** :在更改、添加、删除或替换属性时调用 */ attributeChangedCallback(name, oldValue, newValue) {} }; exports.IElement = IElement; })); //#endregion //#region node_modules/easy-us/lib/elements/config.js var require_config = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigElement = void 0; var ui_1 = require_ui(); var dom_1 = require_dom(); var interface_1 = require_interface(); /** * 配置表单元素 * * 可以根据 {@link Script.configs} 在面板中生成设置表单,并对数据进行双向绑定。 * */ var ConfigElement = class extends interface_1.IElement { constructor(store) { super(); /** 描述 */ this.label = (0, dom_1.h)("label"); /** 外层 */ this.wrapper = (0, dom_1.h)("div", { className: "config-wrapper" }); this.key = ""; this.store = store; } /** * 注意这里的 value 和 provider.value 是不同的,provider 是真正的输入元素,而 ConfigElement 只是外层元素。 */ get value() { return this.store.get(this.key, this.defaultValue); } set value(value) { this.provider.value = value; this.store.set(this.key, value); } connectedCallback() { var _a, _b, _c; switch (this.tag) { case "select": { this.provider = (0, dom_1.h)("select"); const value = this.store.get(this.key, this.defaultValue); for (const item of this.options || []) { const option = ui_1.$ui.tooltip((0, dom_1.h)("option")); if (Array.isArray(item)) { option.value = item[0]; option.textContent = (_a = item[1]) !== null && _a !== void 0 ? _a : item[0]; if (item[2]) option.title = item[2]; if (String(item[0]) === String(value)) { option.selected = true; option.toggleAttribute("selected"); } this.provider.add(option); } else { option.value = item.value; option.textContent = (_b = item.label) !== null && _b !== void 0 ? _b : item.value; if (item.title) option.title = item.title; if (String(item.value) === String(value)) { option.selected = true; option.toggleAttribute("selected"); } this.provider.add(option); } } this.provider.onchange = () => { this.store.set(this.key, this.provider.value); }; break; } case "textarea": this.provider = (0, dom_1.h)("textarea"); this.provider.value = this.store.get(this.key, this.defaultValue); this.provider.onchange = () => { this.store.set(this.key, this.provider.value); }; break; default: this.provider = (0, dom_1.h)("input"); if (["checkbox", "radio"].some((t) => { var _a; return t === ((_a = this.attrs) === null || _a === void 0 ? void 0 : _a.type); })) { this.provider.checked = this.store.get(this.key, this.defaultValue); const provider = this.provider; provider.onchange = () => { this.store.set(this.key, provider.checked); }; } else { this.provider.value = this.store.get(this.key, this.defaultValue); this.provider.setAttribute("value", this.provider.value); this.provider.onchange = () => { const { min, max, type } = this.attrs || {}; /** 计算属性,不能超过 min 和 max */ if (type === "number") { if (this.provider.value.trim() === "") { this.provider.value = this.defaultValue; this.store.set(this.key, this.defaultValue); return; } const val = parseFloat(this.provider.value); const _min = min ? parseFloat(min) : void 0; const _max = max ? parseFloat(max) : void 0; if (_min && val < _min) { this.provider.value = _min.toString(); this.store.set(this.key, parseFloat(this.provider.value)); } else if (_max && val > _max) { this.provider.value = _max.toString(); this.store.set(this.key, parseFloat(this.provider.value)); } else this.store.set(this.key, val); } else this.store.set(this.key, this.provider.value); }; } } if (this.enableForAttribute) { this.provider.setAttribute("id", this.key); this.label.setAttribute("for", this.key); } if (this.labelClassName) this.label.className = this.labelClassName; if (this.providerClassName) this.provider.className = this.providerClassName; if (this.elementClassName) this.className = this.elementClassName; if (this.prefixSlot !== void 0 || this.suffixSlot !== void 0) { const toNode = (slot, className) => typeof slot === "string" ? (0, dom_1.h)("span", { className, innerHTML: slot }) : slot; const children = []; if (this.prefixSlot !== void 0) children.push(toNode(this.prefixSlot, "config-prefix")); children.push(this.provider); if (this.suffixSlot !== void 0) children.push(toNode(this.suffixSlot, "config-suffix")); this.wrapper.replaceChildren((0, dom_1.h)("div", { className: "config-provider-container" }, children)); } else this.wrapper.replaceChildren(this.provider); this.append(this.label, this.wrapper); for (const key in this.attrs) { if (key === "style") { Object.assign(this.provider.style, this.attrs[key]); continue; } if (Object.prototype.hasOwnProperty.call(this.attrs, key)) Reflect.set(this.provider, key, Reflect.get(this.attrs, key)); } if (this.sync) this.store.addChangeListener(this.key, (curr) => { this.provider.value = curr; }); ui_1.$ui.tooltip(this.provider); if (this.showIf) { let show_if = false; if (Array.isArray(this.showIf)) { if (typeof this.showIf[0] !== "string") throw new Error("EUS Config.showIf first element must be a string"); const val = this.store.get(this.showIf[0], false) || false; const res = this.showIf[1].call(null, val, val, this.store); show_if = Boolean(res); } else show_if = this.store.get(this.showIf, false) || false; if (show_if) this.style.display = ""; else this.style.display = "none"; if (Array.isArray(this.showIf)) { if (typeof this.showIf[1] !== "function") throw new Error("EUS Config.showIf second element must be a function"); this.store.addChangeListener(this.showIf[0], (curr, pre) => { if (this.isConnected) { if (this.showIf && Array.isArray(this.showIf)) { if (this.showIf[1].call(null, curr, pre, this.store)) this.style.display = ""; else this.style.display = "none"; } } }); } else this.store.addChangeListener(this.showIf, (curr) => { if (this.isConnected) { if (Boolean(curr)) this.style.display = ""; else this.style.display = "none"; } }); } /** * 触发输入组件的加载回调 * 可用于高度定制化组件 */ (_c = this._onload) === null || _c === void 0 || _c.call(this.provider, this); } }; exports.ConfigElement = ConfigElement; })); //#endregion //#region node_modules/easy-us/lib/elements/container.js var require_container = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.ContainerElement = void 0; var common_1 = require_common(); var ui_1 = require_ui(); var dom_1 = require_dom(); var interface_1 = require_interface(); /** 面板主体元素 */ var ContainerElement = class extends interface_1.IElement { constructor() { super(...arguments); /** 头部 */ this.header = ui_1.$ui.tooltip((0, dom_1.h)("header-element", { title: "菜单栏-可拖动区域" })); /** 内容 */ this.body = (0, dom_1.h)("div", { className: "body", clientHeight: window.innerHeight / 2 }); /** 底部 */ this.footer = (0, dom_1.h)("div", { className: "footer" }); } connectedCallback() { this.append(this.header, this.body, this.footer); const stopScrollPropagation = (e) => e.stopPropagation(); this.addEventListener("wheel", stopScrollPropagation); this.addEventListener("touchmove", stopScrollPropagation); common_1.$.onresize(this, (cont) => { cont.body.style.maxHeight = window.innerHeight - this.header.clientHeight - 64 + "px"; cont.body.style.maxWidth = window.innerWidth - 50 + "px"; }); } }; exports.ContainerElement = ContainerElement; })); //#endregion //#region node_modules/easy-us/lib/elements/dropdown.js var require_dropdown = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.DropdownElement = void 0; var interface_1 = require_interface(); var dom_1 = require_dom(); var DropdownElement = class extends interface_1.IElement { constructor() { super(...arguments); /** 触发元素 */ this.triggerElement = (0, dom_1.h)("button"); /** 下拉框内容 */ this.content = (0, dom_1.h)("div", { className: "dropdown-content" }); this.trigger = "hover"; } connectedCallback() { this.append(this.triggerElement, this.content); this.classList.add("dropdown"); if (this.trigger === "click") { this.triggerElement.onclick = () => { this.content.classList.toggle("show"); }; this.removeDocumentClickHandler(); this.documentClickHandler = (e) => { if (this.content.classList.contains("show") && e.composedPath().includes(this) === false) this.content.classList.remove("show"); }; document.addEventListener("click", this.documentClickHandler); } else { let hideTimer; const show = () => { if (hideTimer !== void 0) { clearTimeout(hideTimer); hideTimer = void 0; } this.content.classList.add("show"); }; const hide = () => { if (hideTimer !== void 0) clearTimeout(hideTimer); hideTimer = setTimeout(() => { this.content.classList.remove("show"); hideTimer = void 0; }, 120); }; this.triggerElement.onmouseenter = show; this.triggerElement.onmouseleave = hide; this.content.onmouseenter = show; this.content.onmouseleave = hide; } this.content.onclick = () => { this.content.classList.remove("show"); }; } disconnectedCallback() { this.removeDocumentClickHandler(); } removeDocumentClickHandler() { if (this.documentClickHandler) { document.removeEventListener("click", this.documentClickHandler); this.documentClickHandler = void 0; } } }; exports.DropdownElement = DropdownElement; })); //#endregion //#region node_modules/easy-us/lib/elements/header.js var require_header = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.HeaderElement = void 0; var interface_1 = require_interface(); var HeaderElement = class extends interface_1.IElement { connectedCallback() { this.append(this.visualSwitcher || ""); } }; exports.HeaderElement = HeaderElement; })); //#endregion //#region node_modules/easy-us/lib/elements/message.js var require_message = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageElement = void 0; var dom_1 = require_dom(); var interface_1 = require_interface(); /** * 消息元素 */ var MessageElement = class extends interface_1.IElement { constructor() { super(...arguments); /** 关闭按钮 */ this.closer = (0, dom_1.h)("span", { className: "message-closer" }, "x"); /** 内容外部元素 */ this.contentContainer = (0, dom_1.h)("span", { className: "message-content-container" }); /** 消息类型 */ this.type = "info"; /** 内容 */ this.content = ""; /** 是否允许关闭 */ this.closeable = true; } connectedCallback() { var _a; this.classList.add(this.type); if (typeof this.content === "string") this.contentContainer.innerHTML = this.content; else this.contentContainer.append(this.content); this.duration = Math.max((_a = this.duration) !== null && _a !== void 0 ? _a : 5, 0); this.append(this.contentContainer); if (this.closeable) { this.append(this.closer); this.closer.addEventListener("click", () => { var _a; (_a = this.onClose) === null || _a === void 0 || _a.call(this); this.remove(); }); } if (this.duration) setTimeout(() => { var _a; (_a = this.onClose) === null || _a === void 0 || _a.call(this); this.remove(); }, this.duration * 1e3); } }; exports.MessageElement = MessageElement; })); //#endregion //#region node_modules/easy-us/lib/elements/modal.js var require_modal = /* @__PURE__ */ __commonJSMin(((exports) => { var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function(resolve) { resolve(value); }); } return new (P || (P = Promise))(function(resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ModalElement = void 0; var common_1 = require_common(); var dom_1 = require_dom(); var tampermonkey_1 = require_tampermonkey(); var interface_1 = require_interface(); /** * 弹窗元素 */ var ModalElement = class extends interface_1.IElement { constructor() { super(...arguments); /** 弹窗标题 */ this._title = (0, dom_1.h)("div", { className: "modal-title" }); /** 弹窗主体 */ this.body = (0, dom_1.h)("div", { className: "modal-body" }); /** 弹窗底部 */ this.footerContainer = (0, dom_1.h)("div", { className: "modal-footer" }); /** 弹窗底部输入框 */ this.modalInput = (0, dom_1.h)("input", { className: "modal-input" }); this.modalInputType = "input"; /** * 弹窗类型 * prompt : 询问弹窗,并带有输入框 * confirm : 确认弹窗,带有取消按钮 * alert : 默认弹窗,只有确认按钮 */ this.type = "alert"; /** 弹窗内容 */ this.content = ""; /** 输入框默认内容 */ this.inputDefaultValue = ""; /** 输入框提示 */ this.placeholder = ""; /** 弹窗元素样式 */ this.modalStyle = {}; } connectedCallback() { var _a; /** * 通过 class 来区分弹窗类型 * prompt : 下方带有输入框 * confirm : 输入框将被隐藏 * alert : 取消框和输入框都将被隐藏 */ this.classList.add(this.type); /** * 合并样式 */ Object.assign(this.style, this.modalStyle || {}); const profile = (0, dom_1.h)("div", { innerText: this.profile || "弹窗来自: OCS " + (((_a = tampermonkey_1.$gm.getInfos()) === null || _a === void 0 ? void 0 : _a.script.version) || ""), className: "modal-profile" }); this._title.innerText = this.title; this.body.append(typeof this.content === "string" ? (0, dom_1.h)("div", { innerHTML: this.content }) : this.content); if (this.modalInputType === "textarea") this.modalInput = (0, dom_1.h)("textarea", { className: "modal-input", style: { height: "100px" } }); this.modalInput.placeholder = this.placeholder || ""; this.modalInput.value = this.inputDefaultValue || ""; this.append(profile, this._title, this.body, this.footerContainer); this.style.width = (this.width || 400) + "px"; if (this.footer === void 0) { this.footerContainer.append(this.modalInput); if (this.cancelButton === void 0) { this.cancelButton = (0, dom_1.h)("button", { className: "modal-cancel-button" }); this.cancelButton.innerText = this.cancelButtonText || "取消"; this.cancelButton.onclick = () => { var _a, _b; (_a = this.onCancel) === null || _a === void 0 || _a.call(this); (_b = this.onClose) === null || _b === void 0 || _b.call(this); this.remove(); }; } if (this.confirmButton === void 0) { this.confirmButton = (0, dom_1.h)("button", { className: "modal-confirm-button" }); this.confirmButton.innerText = this.confirmButtonText || "确定"; this.confirmButton.onclick = () => __awaiter(this, void 0, void 0, function* () { var _b, _c; if ((yield (_b = this.onConfirm) === null || _b === void 0 ? void 0 : _b.call(this, this.modalInput.value)) !== false) { this.remove(); (_c = this.onClose) === null || _c === void 0 || _c.call(this, this.modalInput.value); } }); } this.cancelButton && this.footerContainer.append(this.cancelButton); this.confirmButton && this.footerContainer.append(this.confirmButton); if (this.type === "simple") this.footerContainer.remove(); else if (this.type === "prompt") this.modalInput.focus(); } else this.footerContainer.append(this.footer); common_1.$.onresize(this.body, (modal) => { this.body.style.maxHeight = window.innerHeight - 100 + "px"; this.body.style.maxWidth = window.innerWidth - 50 + "px"; }); } }; exports.ModalElement = ModalElement; })); //#endregion //#region node_modules/easy-us/lib/elements/script.panel.js var require_script_panel = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.ScriptPanelElement = void 0; var dom_1 = require_dom(); var interface_1 = require_interface(); /** * 脚本的面板,创建于悬浮窗下,每当切换页面,或者展开时会重新渲染面板。 * * 主要结构为: * 分隔符 * 提示板块 * 设置表单板块 * 主体 * */ var ScriptPanelElement = class extends interface_1.IElement { constructor() { super(...arguments); /** 分隔符 */ this.separator = (0, dom_1.h)("div", { className: "separator" }); /** 创建提示板块 */ this.notesContainer = (0, dom_1.h)("div", { className: "notes card" }); /** 提示板块头部,点击可收缩/展开 */ this.notesHeader = (0, dom_1.h)("div", { className: "notes-header" }); /** 提示板块主体 */ this.notesBody = (0, dom_1.h)("div", { className: "notes-body" }); /** 创建设置板块 */ this.configsContainer = (0, dom_1.h)("div", { className: "configs-container card" }); /** 主体 */ this.body = (0, dom_1.h)("div", { className: "script-panel-body" }); /** 锁定配置板块 */ this.lockWrapper = (0, dom_1.h)("div", { className: "lock-wrapper" }); } connectedCallback() { this.separator.innerText = this.name || ""; this.notesHeader.append((0, dom_1.h)("span", { className: "notes-title" }, [(0, dom_1.h)("span", { className: "notes-info-icon" }, "i"), "提示"]), (0, dom_1.h)("span", { className: "notes-collapse-icon" }, "▼")); this.notesContainer.append(this.notesHeader); this.notesContainer.append(this.notesBody); this.append(this.separator); this.append(this.notesContainer); this.append(this.configsContainer); this.append(this.body); } /** 设置提示板块展开状态 */ setNotesExpanded(expanded) { this.notesContainer.classList.toggle("collapsed", !expanded); } /** 当前提示板块是否处于展开状态 */ isNotesExpanded() { return !this.notesContainer.classList.contains("collapsed"); } }; exports.ScriptPanelElement = ScriptPanelElement; })); //#endregion //#region node_modules/easy-us/lib/elements/index.js var require_elements = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.definedCustomElements = exports.ScriptPanelElement = exports.ModalElement = exports.MessageElement = exports.HeaderElement = exports.ContainerElement = exports.ConfigElement = void 0; var config_1 = require_config(); var container_1 = require_container(); var dropdown_1 = require_dropdown(); var header_1 = require_header(); var message_1 = require_message(); var modal_1 = require_modal(); var script_panel_1 = require_script_panel(); var config_2 = require_config(); Object.defineProperty(exports, "ConfigElement", { enumerable: true, get: function() { return config_2.ConfigElement; } }); var container_2 = require_container(); Object.defineProperty(exports, "ContainerElement", { enumerable: true, get: function() { return container_2.ContainerElement; } }); var header_2 = require_header(); Object.defineProperty(exports, "HeaderElement", { enumerable: true, get: function() { return header_2.HeaderElement; } }); var message_2 = require_message(); Object.defineProperty(exports, "MessageElement", { enumerable: true, get: function() { return message_2.MessageElement; } }); var modal_2 = require_modal(); Object.defineProperty(exports, "ModalElement", { enumerable: true, get: function() { return modal_2.ModalElement; } }); var script_panel_2 = require_script_panel(); Object.defineProperty(exports, "ScriptPanelElement", { enumerable: true, get: function() { return script_panel_2.ScriptPanelElement; } }); exports.definedCustomElements = [ config_1.ConfigElement, container_1.ContainerElement, header_1.HeaderElement, modal_1.ModalElement, message_1.MessageElement, script_panel_1.ScriptPanelElement, dropdown_1.DropdownElement ]; })); //#endregion //#region node_modules/easy-us/lib/interfaces/custom-window.js var require_custom_window = /* @__PURE__ */ __commonJSMin(((exports) => { var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function(resolve) { resolve(value); }); } return new (P || (P = Promise))(function(resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = exports && exports.__rest || function(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") { for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.modal = exports.CustomWindow = void 0; var _1 = require_interfaces(); var elements_1 = require_elements(); var utils_1 = require_utils(); var start_1 = require_start(); var minimizeSvg = ""; var expandSvg = ""; var CustomWindow = class { constructor(projects, inputStoreProvider, config) { /** 消息内容元素 */ this.messageContainer = (0, utils_1.h)("div", { className: "message-container" }); /** 额外的菜单栏 */ this.extraMenuBar = (0, utils_1.h)("div", { className: "extra-menu-bar" }); /** 默认值 */ this.defaults = { /** 当前页面存在默认页面 */ urls: (urls) => urls && urls.length ? urls : [location.href], /** 默认面板名 */ panelName: (name) => name || this.config.render.defaultPanelName || "" }; this.projects = projects; this.inputStoreProvider = inputStoreProvider; this.config = config; /** 兼容低版本浏览器 */ handleLowLevelBrowser(); /** 加载自定义元素 */ utils_1.$.loadCustomElements(elements_1.definedCustomElements); this.wrapper = (0, utils_1.h)("div"); utils_1.$elements.tooltipContainer = (0, utils_1.h)("div", { className: "tooltip-container" }); utils_1.$elements.wrapper = this.wrapper; this.root = this.wrapper.attachShadow({ mode: "closed" }); utils_1.$elements.root = this.root; /** 根元素 */ this.container = (0, utils_1.h)("container-element"); this.root.append(this.container); const styles = config.render.styles.map((s) => (0, utils_1.h)("style", s)); this.container.append(...styles, this.messageContainer); new MutationObserver(() => this.layoutViewportTopMessages()).observe(this.messageContainer, { childList: true }); /** 处理面板位置 */ const handlePosition = () => { const pos = config.store.getPosition(); if (pos.x > document.documentElement.clientWidth || pos.x < 0) config.store.setPosition(10, 10); if (pos.y > document.documentElement.clientHeight || pos.y < 0) config.store.setPosition(10, 10); this.container.style.left = pos.x + "px"; this.container.style.top = pos.y + "px"; const positionHandler = () => { config.store.setPosition(this.container.offsetLeft, this.container.offsetTop); }; (0, utils_1.enableElementDraggable)(this.container.header, this.container, positionHandler); (0, utils_1.enableElementTouchDraggable)(this.container.header, this.container, positionHandler); }; /** 处理面板可视状态 */ const handleVisible = () => { window.addEventListener("click", (e) => { if (e.detail === Math.max(config.render.switchPoint, 3)) { this.container.style.top = e.y + "px"; this.container.style.left = e.x + "px"; config.store.setPosition(e.x, e.y); this.setVisual("normal"); } }); }; /** 初始化跨域模态框系统 */ const initCorsModalSystem = () => { _1.cors.on("modal", (args) => __awaiter(this, void 0, void 0, function* () { const [type, _attrs] = args || []; return new Promise((resolve, reject) => { const attrs = _attrs; attrs.onCancel = () => resolve(""); attrs.onConfirm = resolve; attrs.onClose = resolve; modal(type, attrs); }); })); }; /** 初始化跨域消息框系统 */ const initCorsMessageSystem = () => { _1.cors.on("message", (args) => __awaiter(this, void 0, void 0, function* () { const [type, attrs] = args || []; console.log("message", type, attrs); this.message(type, attrs); })); }; const switchVisual = () => { this.setVisual(config.store.getVisual() === "hidden" ? "normal" : "hidden"); }; window.addEventListener("keydown", (e) => { if (e.ctrlKey && e.key === config.render.switchKey) { e.stopPropagation(); e.preventDefault(); switchVisual(); } }, { capture: true }); _1.cors.on("switch-visual", () => { switchVisual(); }); handleVisible(); this.setVisual(config.store.getVisual()); (() => __awaiter(this, void 0, void 0, function* () { const urls = yield config.store.getRenderURLs(); const currentPanelName = yield config.store.getCurrentPanelName(); yield this.rerender(this.defaults.urls(urls), this.defaults.panelName(currentPanelName)); }))(); initCorsModalSystem(); initCorsMessageSystem(); handlePosition(); this.setFontSize(config.render.fontsize); } rerender(urls, currentPanelName) { return __awaiter(this, void 0, void 0, function* () { this.initHeader(urls, currentPanelName); yield this.renderBody(currentPanelName); }); } initHeader(urls, currentPanelName) { /** 版本 */ const title = this.config.render.title; const profile = utils_1.$ui.tooltip((0, utils_1.h)("div", { className: "profile", title: "菜单栏(可拖动区域)" }, (el) => { if (title instanceof HTMLElement) el.append(title); else el.innerHTML = title || "无标题"; })); const scriptDropdowns = []; for (const project of this.projects) { const dropdown = (0, utils_1.h)("dropdown-element"); let selected = false; const options = []; if (utils_1.$.getMatchedScripts([project], urls).filter((s) => !s.hideInPanel).length) { for (const key in project.scripts) if (Object.prototype.hasOwnProperty.call(project.scripts, key)) { const script = project.scripts[key]; if (!script.hideInPanel) { const optionSelected = isCurrentPanel(project.name, script, currentPanelName); const option = (0, utils_1.h)("div", { className: "dropdown-option" }, script.name); if (optionSelected) option.classList.add("active"); if (selected !== true && optionSelected) selected = true; option.onclick = () => __awaiter(this, void 0, void 0, function* () { yield this.config.store.setCurrentPanelName(project.name + "-" + script.name); }); options.push(option); } } if (selected) dropdown.classList.add("active"); dropdown.triggerElement = (0, utils_1.h)("div", { className: "dropdown-trigger-element" }, project.name); dropdown.content.append(...options); scriptDropdowns.push(dropdown); } } /** 窗口是否最小化 */ const isMinimize = () => this.config.store.getVisual() === "minimize"; /** 窗口状态切换按钮 */ const visualSwitcher = utils_1.$ui.tooltip((0, utils_1.h)("div", { className: "switch ", title: isMinimize() ? "点击展开窗口" : "点击最小化窗口", innerHTML: isMinimize() ? expandSvg : minimizeSvg, onclick: () => { this.setVisual(isMinimize() ? "normal" : "minimize"); visualSwitcher.title = isMinimize() ? "点击展开窗口" : "点击最小化窗口"; visualSwitcher.innerHTML = isMinimize() ? expandSvg : minimizeSvg; } })); this.container.header.visualSwitcher = visualSwitcher; this.container.header.replaceChildren(); this.container.header.append((0, utils_1.h)("div", { style: { width: "100%" } }, [(0, utils_1.h)("div", { className: "header-menu-bar", style: { display: "flex", width: "100%" } }, [ profile, ...scriptDropdowns, this.container.header.visualSwitcher || "" ]), (0, utils_1.h)("div", { style: { display: "flex", width: "100%" } }, [this.extraMenuBar])])); } renderBody(currentPanelName) { var _a; return __awaiter(this, void 0, void 0, function* () { for (const project of this.projects) for (const key in project.scripts) if (Object.prototype.hasOwnProperty.call(project.scripts, key)) { const script = project.scripts[key]; if (isCurrentPanel(project.name, script, currentPanelName)) { const panel = utils_1.$ui.scriptPanel(script, this.inputStoreProvider); script.projectName = project.name; script.panel = panel; script.header = this.container.header; utils_1.$elements.currentScriptPanel = panel; this.container.body.replaceChildren(panel); (_a = script.onrender) === null || _a === void 0 || _a.call(script, { panel, header: this.container.header }); script.emit("render", { panel, header: this.container.header }); } } }); } setFontSize(fontsize) { this.container.style.font = `${fontsize}px Menlo, Monaco, Consolas, 'Courier New', monospace`; } setVisual(value) { this.container.className = ""; if (value === "minimize") this.container.classList.add("minimize"); else if (value === "hidden") this.container.classList.add("hidden"); else this.container.classList.add("normal"); this.config.store.setVisual(value); } changeRenderURLs(urls) { return __awaiter(this, void 0, void 0, function* () { const currentPanelName = yield this.config.store.getCurrentPanelName(); yield this.rerender(this.defaults.urls(urls), this.defaults.panelName(currentPanelName)); }); } changePanel(currentPanelName) { return __awaiter(this, void 0, void 0, function* () { const urls = (yield this.config.store.getRenderURLs()) || [location.href]; yield this.rerender(this.defaults.urls(urls), this.defaults.panelName(currentPanelName)); }); } /** * 将当前的脚本置顶 * @param script 脚本 */ pin(script) { return __awaiter(this, void 0, void 0, function* () { if (script.projectName) yield this.config.store.setCurrentPanelName(`${script.projectName}-${script.name}`); else if (script.namespace) yield this.config.store.setCurrentPanelName(script.namespace); else console.warn("[ERROR]", `${script.name} 无法置顶, projectName 与 namespace 都为 undefined`); }); } /** * 最小化窗口 */ minimize() { this.setVisual("minimize"); } normal() { this.setVisual("normal"); } hidden() { this.setVisual("hidden"); } /** * 消息推送 */ message(type, attrs) { if (typeof attrs === "string") attrs = { content: attrs }; const message = (0, utils_1.h)("message-element", Object.assign({ type }, attrs)); this.messageContainer.append(message); requestAnimationFrame(() => { const rect = message.getBoundingClientRect(); if (rect.left < 0 || rect.top < 0 || rect.right > window.innerWidth || rect.bottom > window.innerHeight) { message.classList.add("message-viewport-top"); this.layoutViewportTopMessages(); } }); return message; } /** * 视口顶部固定气泡的堆叠布局: * 按创建顺序自上而下累加高度,避免多个 message-viewport-top 气泡重叠在一起 */ layoutViewportTopMessages() { /** 顶部起始位置(px) */ let top = 12; /** 气泡之间的间隙(px) */ const gap = 8; const messages = this.messageContainer.querySelectorAll("message-element.message-viewport-top"); for (const el of Array.from(messages)) { el.style.top = top + "px"; top += el.offsetHeight + gap; } } /** * 注册额外菜单栏 * @param label 名称 * @param config 设置 */ menu(label, config) { return __awaiter(this, void 0, void 0, function* () { this.extraMenuBar.style.display = "flex"; const btn = (0, utils_1.h)("button", label); btn.addEventListener("click", () => { if (config.scriptPanelLink) this.pin(config.scriptPanelLink).then(() => { this.normal(); }).catch(console.error); }); if (config.scriptPanelLink) { btn.title = "快捷跳转:" + ((config.scriptPanelLink.projectName ? config.scriptPanelLink.projectName + " -> " : "") + config.scriptPanelLink.name); btn.setAttribute("data-name", (config.scriptPanelLink.projectName + "-" + config.scriptPanelLink.name).replace(/\s/g, "_")); btn.classList.add("script-panel-link"); } this.extraMenuBar.append(utils_1.$ui.tooltip(btn)); const name = yield utils_1.$store.getTab(utils_1.$const.TAB_CURRENT_PANEL_NAME); if (config.scriptPanelLink) { if (isCurrentPanel(config.scriptPanelLink.projectName, config.scriptPanelLink, name)) { this.extraMenuBar.querySelectorAll(".script-panel-link").forEach((el) => el.classList.remove("active")); btn.classList.add("active"); } } return btn; }); } /** * 随机挂载到指定的父元素 * @param parent 挂载的父元素 */ mount(parent) { parent.children[utils_1.$.random(0, parent.children.length - 1)].after(this.wrapper); } }; exports.CustomWindow = CustomWindow; /** 判断这个脚本是否为当前显示页面 */ function isCurrentPanel(projectName, script, currentPanelName) { return projectName + "-" + script.name === currentPanelName || script.namespace === currentPanelName; } /** 兼容低版本浏览器 */ function handleLowLevelBrowser() { if (typeof Element.prototype.replaceChildren === "undefined") Element.prototype.replaceChildren = function(...nodes) { this.innerHTML = ""; for (const node of nodes) this.append(node); }; } /** * 创建一个模态框代替原生的 alert, confirm, prompt * 如果已经调用了 start 函数那么则会挂载到自定义窗口中,否则可以挂载到全局元素中(可以修改 $elements.root 实现自定义挂载位置),或者 document.body 上 */ function modal(type, attrs, parent = (start_1.$win === null || start_1.$win === void 0 ? void 0 : start_1.$win.container) || utils_1.$elements.root || document.body) { const { maskCloseable = true, onConfirm, onCancel, onClose, notification: notify, notificationOptions, duration } = attrs, _attrs = __rest(attrs, [ "maskCloseable", "onConfirm", "onCancel", "onClose", "notification", "notificationOptions", "duration" ]); if (notify) utils_1.$gm.notification(typeof _attrs.content === "string" ? _attrs.content : _attrs.content.textContent || "", notificationOptions); const wrapper = (0, utils_1.h)("div", { className: "modal-wrapper" }, (wrapper) => { const modal = (0, utils_1.h)("modal-element", Object.assign({ onConfirm(val) { return __awaiter(this, void 0, void 0, function* () { const isClose = yield onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm.apply(modal, [val]); if (isClose !== false) wrapper.remove(); return isClose; }); }, onCancel() { onCancel === null || onCancel === void 0 || onCancel.apply(modal); wrapper.remove(); }, onClose(val) { onClose === null || onClose === void 0 || onClose.apply(modal, [val]); wrapper.remove(); }, type }, _attrs)); wrapper.append(modal); modal.addEventListener("click", (e) => { e.stopPropagation(); }); if (maskCloseable) /** 点击遮罩层关闭模态框 */ wrapper.addEventListener("click", () => { onClose === null || onClose === void 0 || onClose.apply(modal); wrapper.remove(); }); }); if (duration) setTimeout(() => { wrapper.remove(); }, duration * 1e3); parent.append(wrapper); return wrapper; } exports.modal = modal; })); //#endregion //#region node_modules/easy-us/lib/utils/start.js var require_start = /* @__PURE__ */ __commonJSMin(((exports) => { var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function(resolve) { resolve(value); }); } return new (P || (P = Promise))(function(resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = exports && exports.__importDefault || function(mod) { return mod && mod.__esModule ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.addFunctionEventListener = exports.start = exports.$win = void 0; var interfaces_1 = require_interfaces(); var custom_window_1 = require_custom_window(); var common_1 = require_common(); var const_1 = require_const(); var elements_1 = require_elements$1(); var store_1 = require_store(); var debounce_1 = __importDefault(require_debounce()); var mounted = false; /** * 启动项目 * @param startConfig 启动配置 */ function start(startConfig) { return __awaiter(this, void 0, void 0, function* () { /** 为对象添加响应式特性,在设置值的时候同步到本地存储中 */ startConfig.projects = startConfig.projects.map((p) => { for (const key in p.scripts) if (Object.prototype.hasOwnProperty.call(p.scripts, key)) p.scripts[key].cfg = common_1.$.createConfigProxy(p.scripts[key]); return p; }); const scripts = common_1.$.getMatchedScripts(startConfig.projects, [location.href]).sort((a, b) => b.priority - a.priority); /** 执行脚本 */ scripts.forEach((script) => { var _a; script.startConfig = startConfig; script.emit("start", startConfig); (_a = script.onstart) === null || _a === void 0 || _a.call(script, startConfig); }); if ((yield store_1.$store.getTab(const_1.$const.TAB_UID)) === void 0) yield store_1.$store.setTab(const_1.$const.TAB_UID, common_1.$.uuid()); /** * 每个脚本加载之后,统计每个脚本当前所运行的页面链接,链接不会重复 * 初始化页面的脚本可以根据此链接列表,进行脚本页面的生成 */ const urls = yield store_1.$store.getTab(const_1.$const.TAB_URLS); yield store_1.$store.setTab(const_1.$const.TAB_URLS, Array.from(new Set((urls || []).concat(location.href)))); /** 防止 onactive 执行两次 */ let active = false; /** * 如果页面加载元素较少,或者网速极快的情况下 * 存在一开始就是 active 或者 complete 的情况 */ if (document.readyState === "interactive") { active = true; /** 挂载悬浮窗 */ mount(startConfig); scripts.forEach((script) => { var _a; return (_a = script.onactive) === null || _a === void 0 ? void 0 : _a.call(script, startConfig); }); } else if (document.readyState === "complete") { /** 挂载悬浮窗 */ mount(startConfig); scripts.forEach((script) => { var _a; return (_a = script.onactive) === null || _a === void 0 ? void 0 : _a.call(script, startConfig); }); scripts.forEach((script) => { var _a; return (_a = script.oncomplete) === null || _a === void 0 ? void 0 : _a.call(script, startConfig); }); } /** * 监听 readystatechange */ document.addEventListener("readystatechange", () => { /** 挂载悬浮窗 */ mount(startConfig); if (document.readyState === "interactive" && active === false) /** 运行脚本 */ scripts.forEach((script) => { var _a; script.emit("active", startConfig); (_a = script.onactive) === null || _a === void 0 || _a.call(script, startConfig); }); if (document.readyState === "complete") scripts.forEach((script) => { var _a; script.emit("complete"); (_a = script.oncomplete) === null || _a === void 0 || _a.call(script, startConfig); }); }); /** * 监听路由更改 */ window.addEventListener("hashchange", () => { scripts.forEach((script) => { var _a; script.emit("hashchange", startConfig); (_a = script.onhashchange) === null || _a === void 0 || _a.call(script, startConfig); }); }); /** * 监听 history 更改 */ history.pushState = addFunctionEventListener(history, "pushState"); history.replaceState = addFunctionEventListener(history, "replaceState"); window.addEventListener("pushState", () => { scripts.forEach((script) => { var _a; script.emit("historychange", "push", startConfig); (_a = script.onhistorychange) === null || _a === void 0 || _a.call(script, "push", startConfig); }); common_1.$.getMatchedScripts(startConfig.projects, [location.href]).sort((a, b) => b.priority - a.priority).forEach((ns) => { var _a; ns.emit("historychanged", "pushed", startConfig); (_a = ns.onhistorychanged) === null || _a === void 0 || _a.call(ns, "pushed", startConfig); }); }); window.addEventListener("replaceState", () => { scripts.forEach((script) => { var _a; script.emit("historychange", "replace", startConfig); (_a = script.onhistorychange) === null || _a === void 0 || _a.call(script, "replace", startConfig); }); common_1.$.getMatchedScripts(startConfig.projects, [location.href]).sort((a, b) => b.priority - a.priority).forEach((ns) => { var _a; ns.emit("historychanged", "replaced", startConfig); (_a = ns.onhistorychanged) === null || _a === void 0 || _a.call(ns, "replaced", startConfig); }); }); /** * 监听页面离开 */ window.addEventListener("beforeunload", (e) => { var _a; let prevent; for (const script of scripts) { script.emit("beforeunload"); if ((_a = script.onbeforeunload) === null || _a === void 0 ? void 0 : _a.call(script, startConfig)) prevent = true; } if (prevent) { e.preventDefault(); e.returnValue = true; return true; } }); }); } exports.start = start; /** * 添加事件调用监听器 */ function addFunctionEventListener(obj, type) { const origin = obj[type]; return function(...args) { const res = origin.apply(this, args); const e = new Event(type.toString()); e.arguments = args; window.dispatchEvent(e); return res; }; } exports.addFunctionEventListener = addFunctionEventListener; function mount(startConfig) { return __awaiter(this, void 0, void 0, function* () { if (mounted === true) return; mounted = true; if (startConfig === void 0 || startConfig.renderConfig === void 0) { console.warn("the script will not have ui because the renderConfig is not defined."); return; } if (self !== top && startConfig.renderConfig) window.addEventListener("keydown", (e) => { if (e.ctrlKey && e.key === "o") { e.stopPropagation(); e.preventDefault(); interfaces_1.cors.emit("switch-visual", []); } }, { capture: true }); if (self === top) { const { projects, renderConfig } = startConfig; if (typeof renderConfig.renderScript === "undefined") { console.warn("the script will not have ui because the RenderScript is not defined."); return; } if (common_1.$.getMatchedScripts(projects, [location.href]).filter((s) => !!s.hideInPanel === false).length <= 0) return; const RenderScript = renderConfig.renderScript; const win = new custom_window_1.CustomWindow(startConfig.projects, store_1.$store, { render: { title: renderConfig.title, styles: renderConfig.styles, defaultPanelName: renderConfig.defaultPanelName, fontsize: RenderScript.cfg.fontsize, switchPoint: RenderScript.cfg.switchPoint, switchKey: "o" }, store: { getPosition: () => { return { x: RenderScript.cfg.x, y: RenderScript.cfg.y }; }, setPosition: (x, y) => { RenderScript.cfg.x = x; RenderScript.cfg.y = y; }, getVisual: () => { return RenderScript.cfg.visual; }, setVisual: (size) => { RenderScript.cfg.visual = size; }, getRenderURLs() { return __awaiter(this, void 0, void 0, function* () { return yield store_1.$store.getTab(const_1.$const.TAB_URLS); }); }, setRenderURLs(urls) { return __awaiter(this, void 0, void 0, function* () { return yield store_1.$store.setTab(const_1.$const.TAB_URLS, urls); }); }, getCurrentPanelName() { return __awaiter(this, void 0, void 0, function* () { return yield store_1.$store.getTab(const_1.$const.TAB_CURRENT_PANEL_NAME); }); }, setCurrentPanelName(name) { return __awaiter(this, void 0, void 0, function* () { return yield store_1.$store.setTab(const_1.$const.TAB_CURRENT_PANEL_NAME, name); }); } } }); RenderScript.onConfigChange("fontsize", (fs) => { win.setFontSize(fs); }); store_1.$store.addTabChangeListener(const_1.$const.TAB_URLS, (0, debounce_1.default)((curr, pre) => { if (JSON.stringify(curr) === JSON.stringify(pre)) return; win.changeRenderURLs(curr); }, 2e3)); store_1.$store.addTabChangeListener(const_1.$const.TAB_CURRENT_PANEL_NAME, (curr, pre) => { if (curr === pre) return; win.changePanel(curr); updateMenusState(win, curr); }); win.mount(startConfig.mountElement || document.body); elements_1.$elements.tooltipContainer && win.container.append(elements_1.$elements.tooltipContainer); exports.$win = win; } }); } function updateMenusState(win, name) { var _a; win.root.querySelectorAll(".extra-menu-bar .script-panel-link").forEach((el) => el.classList.remove("active")); (_a = win.root.querySelector(".extra-menu-bar [data-name=\"" + name.replace(/\s/g, "_") + "\"]")) === null || _a === void 0 || _a.classList.add("active"); } })); //#endregion //#region node_modules/easy-us/lib/render/render.js var require_render = /* @__PURE__ */ __commonJSMin(((exports) => { Object.defineProperty(exports, "__esModule", { value: true }); exports.$menu = exports.$message = exports.$modal = exports.createRenderScript = void 0; var script_1 = require_script(); var ui_1 = require_ui(); var dom_1 = require_dom(); var custom_window_1 = require_custom_window(); var start_1 = require_start(); var interfaces_1 = require_interfaces(); var createRenderScript = (config) => new script_1.Script({ name: (config === null || config === void 0 ? void 0 : config.name) || "窗口设置", matches: (config === null || config === void 0 ? void 0 : config.matches) || [["所有", /.*/]], namespace: "render.panel", configs: { notes: { defaultValue: ui_1.$ui.notes([ [ "如果需要隐藏整个窗口,可以点击下方隐藏按钮,", "隐藏后可以快速三击屏幕中的任意地方", "来重新在鼠标位置显示窗口。" ], "窗口连续点击显示的次数可以自定义,默认为三次", ["窗口快捷键列表:", "ctrl + o : 隐藏/打开 面板"] ]).outerHTML }, x: { defaultValue: window.innerWidth * .1 }, y: { defaultValue: window.innerWidth * .1 }, /** * - minimize: 最小化 * - hidden: 隐藏 * - normal: 正常 */ visual: { defaultValue: "normal" }, firstCloseAlert: { defaultValue: true }, fontsize: { label: "字体大小(像素)", attrs: { type: "number", min: 12, max: 24, step: 1 }, defaultValue: 14 }, switchPoint: { label: "窗口显示连点(次数)", attrs: { type: "number", min: 3, max: 10, step: 1, title: "设置当连续点击屏幕 N 次时,可以进行面板的 隐藏/显示 切换,默认连续点击屏幕三下" }, defaultValue: 3 } }, methods() { return { /** * 将当前的脚本置顶 * @param script 脚本 */ pin: (script) => start_1.$win === null || start_1.$win === void 0 ? void 0 : start_1.$win.pin(script), /** * 最小化窗口 */ minimize: () => start_1.$win === null || start_1.$win === void 0 ? void 0 : start_1.$win.minimize(), /** * 将窗口最小化,并移动至窗口边缘 */ setPosition: (x, y) => { if (start_1.$win) { start_1.$win.config.store.setPosition(x, y); start_1.$win.container.style.left = x + "px"; start_1.$win.container.style.top = y + "px"; } }, /** * 还原窗口 */ normal: () => { start_1.$win === null || start_1.$win === void 0 || start_1.$win.normal(); } }; }, onrender({ panel }) { const closeBtn = (0, dom_1.h)("button", { className: "base-style-button" }, "隐藏窗口"); closeBtn.onclick = () => { if (this.cfg.firstCloseAlert) exports.$modal.confirm({ content: ui_1.$ui.notes(["隐藏脚本页面后,快速点击页面三下(可以在悬浮窗设置中调整次数)即可重新显示脚本。如果三下无效,可以尝试删除脚本重新安装。", "请确认是否关闭。(此后不再显示此弹窗)"]), onConfirm: () => { start_1.$win === null || start_1.$win === void 0 || start_1.$win.hidden(); this.cfg.firstCloseAlert = false; } }); else start_1.$win === null || start_1.$win === void 0 || start_1.$win.hidden(); }; panel.body.replaceChildren((0, dom_1.h)("hr"), closeBtn); } }); exports.createRenderScript = createRenderScript; function _modal(type, attrs, parent) { if (self === top) return (0, custom_window_1.modal)(type, attrs, parent); else interfaces_1.cors.emit("modal", [type, attrs], (args) => { var _a, _b, _c; if (args) (_a = attrs.onConfirm) === null || _a === void 0 || _a.call(attrs, args); else (_b = attrs.onCancel) === null || _b === void 0 || _b.call(attrs); (_c = attrs.onClose) === null || _c === void 0 || _c.call(attrs, args); }); } /** * 打开弹窗,如果调用时不在顶级窗口,则会通过跨域通信发送消息 */ exports.$modal = { confirm: (attrs, parent) => _modal("confirm", attrs, parent), alert: (attrs, parent) => _modal("alert", attrs, parent), prompt: (attrs, parent) => _modal("prompt", attrs, parent), simple: (attrs, parent) => _modal("simple", attrs, parent) }; function _message(type, attrs) { if (self === top) return start_1.$win === null || start_1.$win === void 0 ? void 0 : start_1.$win.message(type, attrs); else { if (typeof attrs === "string") attrs = { content: attrs }; else if (typeof attrs.content !== "string") attrs.content = attrs.content.innerHTML; interfaces_1.cors.emit("message", [type, attrs]); } } /** * 消息提示,如果调用时不在顶级窗口,则会通过跨域通信发送消息 */ exports.$message = { info: (attrs) => _message("info", attrs), success: (attrs) => _message("success", attrs), warn: (attrs) => _message("warn", attrs), error: (attrs) => _message("error", attrs) }; /** * 注册菜单 * @param label 菜单名称 * @param config 菜单配置 */ function $menu(label, config) { if (self !== top) return; return start_1.$win === null || start_1.$win === void 0 ? void 0 : start_1.$win.menu(label, config); } exports.$menu = $menu; })); //#endregion //#region node_modules/@ai-sdk/provider/dist/index.js var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => { var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) { if (k2 === void 0) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) desc = { enumerable: true, get: function() { return m[k]; } }; Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === void 0) k2 = k; o[k2] = m[k]; })); var __exportStar = exports && exports.__exportStar || function(m, exports$1) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$1, p)) __createBinding(exports$1, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.start = void 0; var start_1 = require_start(); Object.defineProperty(exports, "start", { enumerable: true, get: function() { return start_1.start; } }); __exportStar(require_utils(), exports); __exportStar(require_render(), exports); __exportStar(require_elements(), exports); __exportStar(require_interfaces(), exports); })))(); var marker$2 = "vercel.ai.error"; var symbol$3 = Symbol.for(marker$2); var _a$5; var _b$3; var AISDKError = class _AISDKError extends (_b$3 = Error, _a$5 = symbol$3, _b$3) { /** * Creates an AI SDK Error. * * @param {Object} params - The parameters for creating the error. * @param {string} params.name - The name of the error. * @param {string} params.message - The error message. * @param {unknown} [params.cause] - The underlying cause of the error. */ constructor({ name: name16, message, cause }) { super(message); this[_a$5] = true; this.name = name16; this.cause = cause; } /** * Checks if the given error is an AI SDK Error. * @param {unknown} error - The error to check. * @returns {boolean} True if the error is an AI SDK Error, false otherwise. */ static isInstance(error) { return _AISDKError.hasMarker(error, marker$2); } static hasMarker(error, marker17) { const markerSymbol = Symbol.for(marker17); return error != null && typeof error === "object" && markerSymbol in error && typeof error[markerSymbol] === "boolean" && error[markerSymbol] === true; } }; var name$3 = "AI_APICallError"; var marker2$3 = `vercel.ai.error.${name$3}`; var symbol2$3 = Symbol.for(marker2$3); var _a2$3; var _b2$3; var APICallError = class extends (_b2$3 = AISDKError, _a2$3 = symbol2$3, _b2$3) { constructor({ message, url, requestBodyValues, statusCode, responseHeaders, responseBody, cause, isRetryable = statusCode != null && (statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500), data }) { super({ name: name$3, message, cause }); this[_a2$3] = true; this.url = url; this.requestBodyValues = requestBodyValues; this.statusCode = statusCode; this.responseHeaders = responseHeaders; this.responseBody = responseBody; this.isRetryable = isRetryable; this.data = data; } static isInstance(error) { return AISDKError.hasMarker(error, marker2$3); } }; var name2$3 = "AI_EmptyResponseBodyError"; var marker3$3 = `vercel.ai.error.${name2$3}`; var symbol3$2 = Symbol.for(marker3$3); var _a3$2; var _b3$2; var EmptyResponseBodyError = class extends (_b3$2 = AISDKError, _a3$2 = symbol3$2, _b3$2) { constructor({ message = "Empty response body" } = {}) { super({ name: name2$3, message }); this[_a3$2] = true; } static isInstance(error) { return AISDKError.hasMarker(error, marker3$3); } }; function getErrorMessage(error) { if (error == null) return "unknown error"; if (typeof error === "string") return error; if (error instanceof Error) return error.toString(); return JSON.stringify(error); } var name4$2 = "AI_InvalidArgumentError"; var marker5$2 = `vercel.ai.error.${name4$2}`; var symbol5$2 = Symbol.for(marker5$2); var _a5$2; var _b5$2; var InvalidArgumentError$1 = class extends (_b5$2 = AISDKError, _a5$2 = symbol5$2, _b5$2) { constructor({ message, cause, argument }) { super({ name: name4$2, message, cause }); this[_a5$2] = true; this.argument = argument; } static isInstance(error) { return AISDKError.hasMarker(error, marker5$2); } }; var name5$2 = "AI_InvalidPromptError"; var marker6$2 = `vercel.ai.error.${name5$2}`; var symbol6$2 = Symbol.for(marker6$2); var _a6$2; var _b6$2; var InvalidPromptError = class extends (_b6$2 = AISDKError, _a6$2 = symbol6$2, _b6$2) { constructor({ prompt, message, cause }) { super({ name: name5$2, message: `Invalid prompt: ${message}`, cause }); this[_a6$2] = true; this.prompt = prompt; } static isInstance(error) { return AISDKError.hasMarker(error, marker6$2); } }; var name6$2 = "AI_InvalidResponseDataError"; var marker7$2 = `vercel.ai.error.${name6$2}`; var symbol7$2 = Symbol.for(marker7$2); var _a7$2; var _b7$2; var InvalidResponseDataError = class extends (_b7$2 = AISDKError, _a7$2 = symbol7$2, _b7$2) { constructor({ data, message = `Invalid response data: ${JSON.stringify(data)}.` }) { super({ name: name6$2, message }); this[_a7$2] = true; this.data = data; } static isInstance(error) { return AISDKError.hasMarker(error, marker7$2); } }; var name7$2 = "AI_JSONParseError"; var marker8$2 = `vercel.ai.error.${name7$2}`; var symbol8$2 = Symbol.for(marker8$2); var _a8$2; var _b8$2; var JSONParseError = class extends (_b8$2 = AISDKError, _a8$2 = symbol8$2, _b8$2) { constructor({ text, cause }) { super({ name: name7$2, message: `JSON parsing failed: Text: ${text}. Error message: ${getErrorMessage(cause)}`, cause }); this[_a8$2] = true; this.text = text; } static isInstance(error) { return AISDKError.hasMarker(error, marker8$2); } }; var name13$1 = "AI_TooManyEmbeddingValuesForCallError"; var marker14$1 = `vercel.ai.error.${name13$1}`; var symbol14$1 = Symbol.for(marker14$1); var _a14$1; var _b14$1; var TooManyEmbeddingValuesForCallError = class extends (_b14$1 = AISDKError, _a14$1 = symbol14$1, _b14$1) { constructor(options) { super({ name: name13$1, message: `Too many values for a single embedding call. The ${options.provider} model "${options.modelId}" can only embed up to ${options.maxEmbeddingsPerCall} values per call, but ${options.values.length} values were provided.` }); this[_a14$1] = true; this.provider = options.provider; this.modelId = options.modelId; this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall; this.values = options.values; } static isInstance(error) { return AISDKError.hasMarker(error, marker14$1); } }; var name14$1 = "AI_TypeValidationError"; var marker15$1 = `vercel.ai.error.${name14$1}`; var symbol15$1 = Symbol.for(marker15$1); var _a15$1; var _b15$1; var TypeValidationError = class _TypeValidationError extends (_b15$1 = AISDKError, _a15$1 = symbol15$1, _b15$1) { constructor({ value, cause, context }) { let contextPrefix = "Type validation failed"; if (context == null ? void 0 : context.field) contextPrefix += ` for ${context.field}`; if ((context == null ? void 0 : context.entityName) || (context == null ? void 0 : context.entityId)) { contextPrefix += " ("; const parts = []; if (context.entityName) parts.push(context.entityName); if (context.entityId) parts.push(`id: "${context.entityId}"`); contextPrefix += parts.join(", "); contextPrefix += ")"; } super({ name: name14$1, message: `${contextPrefix}: Value: ${JSON.stringify(value)}. Error message: ${getErrorMessage(cause)}`, cause }); this[_a15$1] = true; this.value = value; this.context = context; } static isInstance(error) { return AISDKError.hasMarker(error, marker15$1); } /** * Wraps an error into a TypeValidationError. * If the cause is already a TypeValidationError with the same value and context, it returns the cause. * Otherwise, it creates a new TypeValidationError. * * @param {Object} params - The parameters for wrapping the error. * @param {unknown} params.value - The value that failed validation. * @param {unknown} params.cause - The original error or cause of the validation failure. * @param {TypeValidationContext} params.context - Optional context about what is being validated. * @returns {TypeValidationError} A TypeValidationError instance. */ static wrap({ value, cause, context }) { var _a17, _b17, _c; if (_TypeValidationError.isInstance(cause) && cause.value === value && ((_a17 = cause.context) == null ? void 0 : _a17.field) === (context == null ? void 0 : context.field) && ((_b17 = cause.context) == null ? void 0 : _b17.entityName) === (context == null ? void 0 : context.entityName) && ((_c = cause.context) == null ? void 0 : _c.entityId) === (context == null ? void 0 : context.entityId)) return cause; return new _TypeValidationError({ value, cause, context }); } }; var name15$1 = "AI_UnsupportedFunctionalityError"; var marker16$1 = `vercel.ai.error.${name15$1}`; var symbol16$1 = Symbol.for(marker16$1); var _a16$1; var _b16$1; var UnsupportedFunctionalityError = class extends (_b16$1 = AISDKError, _a16$1 = symbol16$1, _b16$1) { constructor({ functionality, message = `'${functionality}' functionality not supported.` }) { super({ name: name15$1, message }); this[_a16$1] = true; this.functionality = functionality; } static isInstance(error) { return AISDKError.hasMarker(error, marker16$1); } }; //#endregion //#region node_modules/zod/v4/core/util.js function getEnumValues(entries) { const numericValues = Object.values(entries).filter((v) => typeof v === "number"); return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v); } function joinValues(array, separator = "|") { return array.map((val) => stringifyPrimitive(val)).join(separator); } function jsonStringifyReplacer(_, value) { if (typeof value === "bigint") return value.toString(); return value; } var Cached = class { constructor(getter) { this._getter = getter; this._value = void 0; } get value() { const getter = this._getter; if (getter !== void 0) { this._value = getter(); this._getter = void 0; } return this._value; } }; function cached(getter) { return new Cached(getter); } function nullish(input) { return input === null || input === void 0; } function cleanRegex(source) { const start = source.startsWith("^") ? 1 : 0; const end = source.endsWith("$") ? source.length - 1 : source.length; return source.slice(start, end); } function floatSafeRemainder(val, step) { const ratio = val / step; const roundedRatio = Math.round(ratio); const tolerance = 4 * Number.EPSILON * Math.max(Math.abs(ratio), 1); if (Math.abs(ratio - roundedRatio) < tolerance) return 0; return ratio - roundedRatio; } var EVALUATING = /* @__PURE__*/ Symbol("evaluating"); function defineLazy(object, key, getter) { let value = void 0; Object.defineProperty(object, key, { get() { if (value === EVALUATING) return; if (value === void 0) { value = EVALUATING; value = getter(); } return value; }, set(v) { Object.defineProperty(object, key, { value: v }); }, configurable: true }); } function assignProp(target, prop, value) { Object.defineProperty(target, prop, { value, writable: true, enumerable: true, configurable: true }); } /** * Whichever object a def's `shape` currently answers from: the one the caller passed until the first read, the frozen copy after it. * * Its keys and descriptors read without invoking anything, which is what lets a discriminated union check its discriminator, and the cycle walk read a shape, without resolving a getter that references the schema being constructed. A def that answers `shape` from an accessor of its own has none. */ function rawShape(def) { const desc = Object.getOwnPropertyDescriptor(def, "shape"); return desc?.get ? desc.get.raw : desc?.value; } function sourceShape(schema) { return rawShape(schema._zod.def) ?? schema._zod.def.shape; } function deferProp(target, key, getter) { Object.defineProperty(target, key, { get() { const value = getter(); assignProp(this, key, value); return value; }, enumerable: true, configurable: true }); } function putProp(target, key, value) { if (key in target) assignProp(target, key, value); else target[key] = value; } /** * Copies `keys` of `source`'s shape onto `target`, each value passed through `wrap`. * * A key the source has resolved is copied through now, so the derived shape states it outright and nothing has to resolve it to learn what it holds. A key the source still defers stays deferred, and reads back through the source's own `shape`, so it resolves once and both shapes get that one schema. */ function mirrorShape(target, source, keys, wrap) { const raw = sourceShape(source); for (const key of keys) { const desc = Object.getOwnPropertyDescriptor(raw, key); if (!desc.enumerable) continue; if (desc.get) deferProp(target, key, () => { const value = source._zod.def.shape[key]; return wrap ? wrap(value, key) : value; }); else putProp(target, key, wrap ? wrap(desc.value, key) : desc.value); } } function mirrorProps(target, source) { for (const key of Reflect.ownKeys(source)) { const desc = Object.getOwnPropertyDescriptor(source, key); if (!desc.enumerable) continue; if (desc.get) deferProp(target, key, () => source[key]); else putProp(target, key, desc.value); } } function mergeDefs(...defs) { const mergedDescriptors = {}; for (const def of defs) { const descriptors = Object.getOwnPropertyDescriptors(def); Object.assign(mergedDescriptors, descriptors); } return Object.defineProperties({}, mergedDescriptors); } function esc(str) { return JSON.stringify(str); } function slugify(input) { return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, ""); } var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {}; function isObject(data) { return typeof data === "object" && data !== null && !Array.isArray(data); } var allowsEval = /* @__PURE__*/ cached(() => { if (globalConfig.jitless) return false; if (typeof navigator !== "undefined" && navigator?.userAgent?.includes("Cloudflare")) return false; try { new Function(""); return true; } catch (_) { return false; } }); function isPlainObject(o) { if (isObject(o) === false) return false; const ctor = o.constructor; if (ctor === void 0) return true; if (typeof ctor !== "function") return true; const prot = ctor.prototype; if (isObject(prot) === false) return false; if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) return false; return true; } function shallowClone(o) { if (isPlainObject(o)) return { ...o }; if (Array.isArray(o)) return [...o]; if (o instanceof Map) return new Map(o); if (o instanceof Set) return new Set(o); return o; } var propertyKeyTypes = /* @__PURE__*/ new Set([ "string", "number", "symbol" ]); function escapeRegex(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function clone(inst, def, params) { const cl = new inst._zod.constr(def ?? inst._zod.def); if (!def || params?.parent) cl._zod.parent = inst; return cl; } function normalizeParams(_params) { const params = _params; if (!params) return {}; if (typeof params === "string") return { error: () => params }; if (params?.message !== void 0) { if (params?.error !== void 0) throw new Error("Cannot specify both `message` and `error` params"); params.error = params.message; } delete params.message; if (typeof params.error === "string") return { ...params, error: () => params.error }; return params; } function stringifyPrimitive(value) { if (typeof value === "bigint") return value.toString() + "n"; if (typeof value === "string") return `"${value}"`; return `${value}`; } function optionalKeys(shape) { return Object.keys(shape).filter((k) => { return shape[k]._zod.optin !== void 0 && shape[k]._zod.optout === "optional"; }); } var NUMBER_FORMAT_RANGES = /*@__PURE__*/ (() => ({ safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER], int32: [-2147483648, 2147483647], uint32: [0, 4294967295], float32: [-34028234663852886e22, 34028234663852886e22], float64: [-Number.MAX_VALUE, Number.MAX_VALUE] }))(); var BIGINT_FORMAT_RANGES = { int64: [/* @__PURE__*/ BigInt("-9223372036854775808"), /* @__PURE__*/ BigInt("9223372036854775807")], uint64: [/* @__PURE__*/ BigInt(0), /* @__PURE__*/ BigInt("18446744073709551615")] }; function pick(schema, mask) { const currDef = schema._zod.def; const checks = currDef.checks; if (checks && checks.length > 0) throw new Error(".pick() cannot be used on object schemas containing refinements"); const newShape = {}; mirrorShape(newShape, schema, maskedKeys(schema, mask)); return clone(schema, mergeDefs(currDef, { shape: newShape, checks: [] })); } function maskedKeys(schema, mask) { const raw = sourceShape(schema); const keys = []; for (const key of Reflect.ownKeys(mask)) { if (!Object.getOwnPropertyDescriptor(raw, key)?.enumerable) throw new Error(`Unrecognized key: "${String(key)}"`); if (mask[key]) keys.push(key); } return keys; } function omit(schema, mask) { const currDef = schema._zod.def; const checks = currDef.checks; if (checks && checks.length > 0) throw new Error(".omit() cannot be used on object schemas containing refinements"); const omitted = new Set(maskedKeys(schema, mask)); const newShape = {}; mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)).filter((key) => !omitted.has(key))); return clone(schema, mergeDefs(currDef, { shape: newShape, checks: [] })); } function extend(schema, shape) { if (!isPlainObject(shape)) throw new Error("Invalid input to extend: expected a plain object"); const checks = schema._zod.def.checks; if (checks && checks.length > 0) { const existingShape = sourceShape(schema); for (const key of Reflect.ownKeys(shape)) if (Object.getOwnPropertyDescriptor(existingShape, key) !== void 0) throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead."); } return clone(schema, mergeDefs(schema._zod.def, { shape: extended(schema, shape) })); } function extended(schema, shape) { const newShape = {}; mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema))); mirrorProps(newShape, shape); return newShape; } function safeExtend(schema, shape) { if (!isPlainObject(shape)) throw new Error("Invalid input to safeExtend: expected a plain object"); return clone(schema, mergeDefs(schema._zod.def, { shape: extended(schema, shape) })); } function merge(a, b) { if (!b?._zod?.def) throw new Error("Invalid input to merge: expected an object schema. To merge a plain shape, use `.extend()`."); if (a._zod.def.checks?.length) throw new Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead."); const newShape = {}; mirrorShape(newShape, a, Reflect.ownKeys(sourceShape(a))); mirrorShape(newShape, b, Reflect.ownKeys(sourceShape(b))); return clone(a, mergeDefs(a._zod.def, { shape: newShape, get catchall() { return b._zod.def.catchall; }, checks: b._zod.def.checks ?? [] })); } function partial(Class, schema, mask, name = "partial") { const checks = schema._zod.def.checks; if (checks && checks.length > 0) throw new Error(`.${name}() cannot be used on object schemas containing refinements`); const selected = mask ? new Set(maskedKeys(schema, mask)) : void 0; const newShape = {}; mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)), Class && ((value, key) => selected && !selected.has(key) ? value : new Class({ type: "optional", innerType: value }))); return clone(schema, mergeDefs(schema._zod.def, { shape: newShape, checks: [] })); } function required(Class, schema, mask) { const selected = mask ? new Set(maskedKeys(schema, mask)) : void 0; const newShape = {}; mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)), (value, key) => selected && !selected.has(key) ? value : new Class({ type: "nonoptional", innerType: value })); return clone(schema, mergeDefs(schema._zod.def, { shape: newShape })); } function aborted(x, startIndex = 0) { if (x.aborted === true) return true; for (let i = startIndex; i < x.issues.length; i++) if (x.issues[i]?.continue !== true) return true; return false; } function explicitlyAborted(x, startIndex = 0) { if (x.aborted === true) return true; for (let i = startIndex; i < x.issues.length; i++) if (x.issues[i]?.continue === false) return true; return false; } function prefixIssues(path, issues) { return issues.map((iss) => { var _a; (_a = iss).path ?? (_a.path = []); iss.path.unshift(path); return iss; }); } function unwrapMessage(message) { return typeof message === "string" ? message : message?.message; } function attachSchema(issues, start, inst) { var _a; for (let i = start; i < issues.length; i++) (_a = issues[i]).schema ?? (_a.schema = inst); } function finalizeIssue(iss, ctx, config) { var _a; const traits = iss.inst?._zod?.traits; if (traits?.has("$ZodType")) { if (traits.has("$ZodCheck")) (_a = iss).schema ?? (_a.schema = iss.inst); else iss.schema = iss.inst; } const schemaError = iss.schema !== iss.inst ? iss.schema?._zod.def?.error : void 0; const message = iss.message ? iss.message : unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(schemaError?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config.customError?.(iss)) ?? unwrapMessage(config.localeError?.(iss)) ?? "Invalid input"; const full = {}; for (const k of Object.keys(iss)) { if (k === "inst" || k === "schema" || k === "continue" || k === "input" || k === "__proto__") continue; full[k] = iss[k]; } full.path ?? (full.path = []); full.message = message; if (ctx?.reportInput) full.input = iss.input; return full; } var highSurrogate = /[\uD800-\uDBFF]/; function codePointLength(str) { const units = str.length; if (!highSurrogate.test(str)) return units; let count = units; for (let i = 0; i < units - 1; i++) if ((str.charCodeAt(i) & 64512) === 55296 && (str.charCodeAt(i + 1) & 64512) === 56320) { count--; i++; } return count; } function getLengthableOrigin(input) { if (Array.isArray(input)) return "array"; if (typeof input === "string") return "string"; return "unknown"; } function parsedType(data) { const t = typeof data; switch (t) { case "number": return Number.isNaN(data) ? "nan" : "number"; case "object": { if (data === null) return "null"; if (Array.isArray(data)) return "array"; const obj = data; if (obj && Object.getPrototypeOf(obj) !== Object.prototype && "constructor" in obj && obj.constructor) return obj.constructor.name; } } return t; } function issue(...args) { const [iss, input, inst] = args; if (typeof iss === "string") return { message: iss, code: "custom", input, inst }; return { ...iss }; } /** * Installs a trait's members on its prototype. Each value builds that member for the instance on first read; the built value shadows the accessor as an own property, so a detached `const { parse } = schema` keeps working. * * Call this from a `proto` initializer, which runs once per prototype — never per instance. */ function members(proto, table) { for (const key in table) { const desc = Object.getOwnPropertyDescriptor(table, key); if (desc.get) Object.defineProperty(proto, key, { ...desc, enumerable: false }); else defineBound(proto, key, desc.value); } } /** Shadows a prototype member with an own value, so a getter that builds from the instance runs once. */ function own(inst, key, value, enumerable = true) { Object.defineProperty(inst, key, { configurable: true, writable: true, enumerable, value }); return value; } /** Like {@link own}, for a member that was never an own data property and has to stay out of `Object.keys`. */ function hide(inst, key, value) { return own(inst, key, value, false); } /** Adds members a table derives from the instance: each builds on first read and shadows as own data, and assignment shadows the same way, as when these were own properties. */ function derived(computes, table) { for (const key in computes) { const compute = computes[key]; Object.defineProperty(table, key, { configurable: true, enumerable: true, get() { return own(this, key, compute(this)); }, set(value) { own(this, key, value); } }); } return table; } function defineBound(proto, key, fn) { Object.defineProperty(proto, key, { configurable: true, get() { return this == null ? fn : own(this, key, fn.bind(this)); }, set(value) { own(this, key, value); } }); } /** Returns the prototype to install on, or `undefined` if this group is already installed on it. */ function claim(inst, sentinel) { const proto = Object.getPrototypeOf(inst); return sentinel in proto ? void 0 : proto; } var installing; var broke = false; var breaker = { configurable: true, get() { broke = true; } }; /** * Installs a lazily-derived internal on the `_zod` prototype of `inst`'s * constructor, computed from the internals object itself and cached there on * first read. One accessor per constructor rather than one per instance. */ function defineLazyInternal(inst, key, compute) { const proto = Object.getPrototypeOf(inst._zod); if (key in proto && installing !== inst._zod) { installing = void 0; return; } installing = inst._zod; Object.defineProperty(proto, key, { configurable: true, get() { Object.defineProperty(this, key, breaker); const outer = broke; broke = false; try { const value = compute(this); if (broke) delete this[key]; else Object.defineProperty(this, key, { configurable: true, writable: true, value }); broke = broke || outer; return value; } catch (err) { delete this[key]; broke = broke || outer; throw err; } }, set(value) { Object.defineProperty(this, key, { configurable: true, writable: true, value }); } }); } /** * Installs `key` on `inst`'s prototype, computed by `make` on first read and cached there as an own * data property. One accessor per constructor rather than one per instance, because an own accessor * puts every instance after the first into v8 dictionary mode. The key doubles as the sentinel. */ function installLazyProp(inst, key, make, enumerable) { const proto = claim(inst, key); if (!proto) return; Object.defineProperty(proto, key, { configurable: true, get() { const desc = { configurable: true, writable: true, enumerable, value: void 0 }; Object.defineProperty(this, key, desc); desc.value = make(this); Object.defineProperty(this, key, desc); return desc.value; }, set(value) { Object.defineProperty(this, key, { configurable: true, writable: true, enumerable, value }); } }); } /** Marks the thunk `_catch` synthesises for a constant catch value. `Function.length` cannot tell that thunk from a user callback — rest and defaulted parameters both report arity 0 — and a user callback reads `ctx.error`, whose issues only finalize correctly against the caller's per-parse error map. Provenance can say what arity cannot. A plain string key rather than `Symbol.for`, whose call at module scope no bundler can prove pure — the same shape that anchored `urlCanParse` into every build. */ var CONSTANT_CATCH = "~constantCatch"; /** Wraps a constant catch value in a thunk tagged with {@link CONSTANT_CATCH}. */ function constantCatch(value) { const fn = () => value; fn[CONSTANT_CATCH] = true; return fn; } //#endregion //#region node_modules/zod/v4/core/core.js var _a$4; var _zodDesc = { value: void 0, enumerable: false }; var _E = "captureStackTrace" in Error ? Error : null; function newError(Definition) { const E = _E; if (E) { const saved = E.stackTraceLimit; if (typeof saved === "number") { try { E.stackTraceLimit = 0; } catch { _E = null; return new Definition(); } try { return new Definition(); } finally { E.stackTraceLimit = saved; } } } return new Definition(); } function $constructor(name, initializer, proto, params) { const zodProto = {}; function Internals(def) { this.def = def; this.constr = _; this.traits = /* @__PURE__ */ new Set(); } Internals.prototype = zodProto; const protoMembers = proto; const initialized = protoMembers && /* @__PURE__ */ new WeakSet(); function init(inst, def) { if (!inst._zod) { _zodDesc.value = new Internals(def); try { Object.defineProperty(inst, "_zod", _zodDesc); } finally { _zodDesc.value = void 0; } } else if (inst._zod.traits.has(name)) return; inst._zod.traits.add(name); initializer(inst, def); if (initialized) { const own = Object.getPrototypeOf(inst); const ctorProto = inst._zod.constr.prototype; let up = own; while (up && up !== ctorProto) up = Object.getPrototypeOf(up); const target = up ?? own; if (!initialized.has(target)) { initialized.add(target); members(target, protoMembers); } } const proto = _.prototype; for (const k in proto) { if (!Object.prototype.hasOwnProperty.call(proto, k)) continue; if (!(k in inst)) inst[k] = proto[k].bind(inst); } } const Parent = params?.Parent ?? Object; class Definition extends Parent {} Object.defineProperty(Definition, "name", { value: name }); function _(def) { const inst = params?.Parent ? newError(Definition) : this; init(inst, def); const deferred = inst._zod.deferred; if (deferred) { for (const fn of deferred) fn(); inst._zod.deferred = void 0; } const pp = globalThis.__zod_globalConfig?.postProcessor; if (pp) pp(inst); return inst; } Object.defineProperty(_, "init", { value: init }); Object.defineProperty(_, Symbol.hasInstance, { value: (inst) => { if (params?.Parent && inst instanceof params.Parent) return true; return inst?._zod?.traits?.has(name); } }); Object.defineProperty(_, "name", { value: name }); return _; } var $ZodAsyncError = class extends Error { constructor() { super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`); } }; var $ZodEncodeError = class extends Error { constructor(name) { super(`Encountered unidirectional transform during encode: ${name}`); this.name = "ZodEncodeError"; } }; (_a$4 = globalThis).__zod_globalConfig ?? (_a$4.__zod_globalConfig = {}); var globalConfig = globalThis.__zod_globalConfig; function config(newConfig) { if (newConfig) Object.assign(globalConfig, newConfig); return globalConfig; } //#endregion //#region node_modules/zod/v4/core/errors.js function _getMessage() { const internals = this._zod; internals.message ?? (internals.message = JSON.stringify(internals.def, jsonStringifyReplacer, 2)); return internals.message; } function _setMessage(value) { this._zod.message = value; } var _messageDesc = { get: _getMessage, set: _setMessage, enumerable: true, configurable: true }; var _issuesDesc = { value: void 0, enumerable: false }; var _installedToString = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]); var initializer$1 = (inst, def) => { inst.name = "$ZodError"; _issuesDesc.value = def; Object.defineProperty(inst, "issues", _issuesDesc); _issuesDesc.value = void 0; Object.defineProperty(inst, "message", _messageDesc); const proto = Object.getPrototypeOf(inst); if (!_installedToString.has(proto)) { _installedToString.add(proto); Object.defineProperty(proto, "toString", { configurable: true, enumerable: false, get() { const value = () => this.message; Object.defineProperty(this, "toString", { value, configurable: true, writable: true }); return value; }, set(value) { Object.defineProperty(this, "toString", { value, configurable: true, writable: true }); } }); } }; var $ZodError = $constructor("$ZodError", initializer$1); $constructor("$ZodError", initializer$1, void 0, { Parent: Error }); /** Get-or-create `obj[key]` as an own data property. A path segment naming an inherited member * ("toString", "constructor") would otherwise read through to the prototype, and assigning * "__proto__" would hit the setter instead of creating a key. */ function node(obj, key, make) { if (!Object.prototype.hasOwnProperty.call(obj, key)) { if (key === "__proto__") Object.defineProperty(obj, key, { value: make(), writable: true, enumerable: true, configurable: true }); else obj[key] = make(); } return obj[key]; } function flattenError(error, mapper = (issue) => issue.message) { const fieldErrors = {}; const formErrors = []; for (const sub of error.issues) if (sub.path.length > 0) node(fieldErrors, sub.path[0], () => []).push(mapper(sub)); else formErrors.push(mapper(sub)); return { formErrors, fieldErrors }; } function formatError(error, mapper = (issue) => issue.message) { const fieldErrors = { _errors: [] }; const processError = (error, path = []) => { for (const issue of error.issues) if (issue.code === "invalid_union" && issue.errors.length) issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path])); else if (issue.code === "invalid_key") processError({ issues: issue.issues }, [...path, ...issue.path]); else if (issue.code === "invalid_element") processError({ issues: issue.issues }, [...path, ...issue.path]); else { const fullpath = [...path, ...issue.path]; if (fullpath.length === 0) fieldErrors._errors.push(mapper(issue)); else { let curr = fieldErrors; let i = 0; while (i < fullpath.length) { const el = fullpath[i]; const terminal = i === fullpath.length - 1; if (el === "_errors") { if (terminal) curr._errors.push(mapper(issue)); i++; continue; } if (!Object.prototype.hasOwnProperty.call(curr, el)) Object.defineProperty(curr, el, { value: { _errors: [] }, enumerable: true, writable: true, configurable: true }); const node = curr[el]; if (terminal) node._errors.push(mapper(issue)); curr = node; i++; } } } }; processError(error); return fieldErrors; } //#endregion //#region node_modules/zod/v4/core/parse.js function finalizeParams(callee, params) { return { callee: params?.callee ?? callee, Err: params?.Err }; } var _parse$1 = (_Err) => { const fn = (schema, value, _ctx, _params) => { const ctx = _ctx ? { ..._ctx, async: false } : { async: false }; const result = schema._zod.run({ value, issues: [] }, ctx); if (result instanceof Promise) throw new $ZodAsyncError(); if (result.issues.length) { const e = new ((_params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))); captureStackTrace(e, _params?.callee ?? fn); throw e; } return result.value; }; return fn; }; var _parseAsync = (_Err) => { const fn = async (schema, value, _ctx, params) => { const ctx = _ctx ? { ..._ctx, async: true } : { async: true }; let result = schema._zod.run({ value, issues: [] }, ctx); if (result instanceof Promise) result = await result; if (result.issues.length) { const e = new ((params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config()))); captureStackTrace(e, params?.callee ?? fn); throw e; } return result.value; }; return fn; }; var _safeParse = (_Err) => (schema, value, _ctx) => { const ctx = _ctx ? { ..._ctx, async: false } : { async: false }; const result = schema._zod.run({ value, issues: [] }, ctx); if (result instanceof Promise) throw new $ZodAsyncError(); return result.issues.length ? failure(_Err, result.issues, ctx) : { success: true, data: result.value }; }; function failure(Err, issues, ctx) { let error; return { success: false, get error() { if (!error) { error = new Err(issues.map((iss) => finalizeIssue(iss, ctx, config()))); issues = void 0; ctx = void 0; } return error; }, set error(e) { error = e; issues = void 0; ctx = void 0; } }; } var _safeParseAsync = (_Err) => async (schema, value, _ctx) => { const ctx = _ctx ? { ..._ctx, async: true } : { async: true }; let result = schema._zod.run({ value, issues: [] }, ctx); if (result instanceof Promise) result = await result; return result.issues.length ? failure(_Err, result.issues, ctx) : { success: true, data: result.value }; }; var COMPILE_INVALID = /* @__PURE__ */ Symbol.for("zod.compile.invalid"); var COMPILE_FALLBACK = /* @__PURE__ */ Symbol.for("zod.compile.fallback"); var validate = ((schema, value, _ctx) => { const validator = schema._zod.bag.validator; if (validator !== void 0) { if (validator(value) !== COMPILE_INVALID) return true; if (validator.definite === true && _ctx === void 0) return false; } return validateFallback(schema, value, _ctx); }); function validateFallback(schema, value, _ctx) { const ctx = _ctx ? { ..._ctx, async: false, abortEarly: true } : { async: false, abortEarly: true }; const fallbackRun = schema._zod.bag.fallbackRun; let result; if (fallbackRun) { ctx[COMPILE_FALLBACK] = true; result = fallbackRun({ value, issues: [] }, ctx); } else result = schema._zod.run({ value, issues: [] }, ctx); if (result instanceof Promise) throw new $ZodAsyncError(); return result.issues.length === 0; } var validateAsync$1 = async (schema, value, _ctx) => { const ctx = _ctx ? { ..._ctx, async: true, abortEarly: true } : { async: true, abortEarly: true }; let result = schema._zod.run({ value, issues: [] }, ctx); if (result instanceof Promise) result = await result; return result.issues.length === 0; }; var _encode = (_Err) => { const parse = _parse$1(_Err); const fn = (schema, value, _ctx, _params) => { const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" }; return parse(schema, value, ctx, finalizeParams(fn, _params)); }; return fn; }; var _decode = (_Err) => { const parse = _parse$1(_Err); const fn = (schema, value, _ctx, _params) => { return parse(schema, value, _ctx, finalizeParams(fn, _params)); }; return fn; }; var _encodeAsync = (_Err) => { const parseAsync = _parseAsync(_Err); const fn = async (schema, value, _ctx, _params) => { const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" }; return await parseAsync(schema, value, ctx, finalizeParams(fn, _params)); }; return fn; }; var _decodeAsync = (_Err) => { const parseAsync = _parseAsync(_Err); const fn = async (schema, value, _ctx, _params) => { return await parseAsync(schema, value, _ctx, finalizeParams(fn, _params)); }; return fn; }; var _safeEncode = (_Err) => (schema, value, _ctx) => { const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" }; return _safeParse(_Err)(schema, value, ctx); }; var _safeDecode = (_Err) => (schema, value, _ctx) => { return _safeParse(_Err)(schema, value, _ctx); }; var _safeEncodeAsync = (_Err) => async (schema, value, _ctx) => { const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" }; return _safeParseAsync(_Err)(schema, value, ctx); }; var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => { return _safeParseAsync(_Err)(schema, value, _ctx); }; //#endregion //#region node_modules/zod/v4/core/regexes.js /** * @deprecated CUID v1 is deprecated by its authors due to information leakage * (timestamps embedded in the id). Use {@link cuid2} instead. * See https://github.com/paralleldrive/cuid. */ var cuid = /^[cC][0-9a-z]{6,}$/; var cuid2 = /^[0-9a-z]+$/; var ulid = /^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$/; var xid = /^[0-9a-vA-V]{20}$/; var ksuid = /^[A-Za-z0-9]{27}$/; var nanoid = /^[a-zA-Z0-9_-]{21}$/; function nanoidOfLength(length) { return new RegExp(`^[a-zA-Z0-9_-]{${length}}$`); } /** ISO 8601-1 duration regex. Does not support the 8601-2 extensions like negative durations or fractional/negative components. */ var duration = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/; /** A regex for any UUID-like identifier: 8-4-4-4-12 hex pattern */ var guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/; /** Returns a regex for validating an RFC 9562/4122 UUID. * * @param version Optionally specify a version 1-8. If no version is specified, all versions are supported. */ var uuid = (version) => { if (!version) return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/; return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`); }; /** Practical email validation */ var email = /^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/; var _emoji$1 = `^(?=[\\s\\S]*[\\p{Extended_Pictographic}\\p{Regional_Indicator}\\u20E3])[\\p{Extended_Pictographic}\\p{Emoji_Component}]+$`; function emoji() { return new RegExp(_emoji$1, "u"); } var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/; var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/; var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/; var cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/; var base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/; var base64url = /^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$/; var httpProtocol = /^https?$/; var e164 = /^\+[1-9]\d{6,14}$/; var dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`; /** Anchors a pattern source. The interpolation lives here rather than at the call site because * esbuild will not drop a `@__PURE__` call whose own argument interpolates a variable, but it * will drop `anchor(dateSource)`. Keeping it inline pinned `date` into every bundle. */ function anchor(source) { return new RegExp(`^${source}$`); } var date = /*@__PURE__*/ anchor(dateSource); function timeSource(args) { const hhmm = `(?:[01]\\d|2[0-3]):[0-5]\\d`; return typeof args.precision === "number" ? args.precision === -1 ? `${hhmm}` : args.precision === 0 ? `${hhmm}:[0-5]\\d` : `${hhmm}:[0-5]\\d\\.\\d{${args.precision}}` : args.seconds ? `${hhmm}:[0-5]\\d(?:\\.\\d+)?` : `${hhmm}(?::[0-5]\\d(?:\\.\\d+)?)?`; } function time(args) { return new RegExp(`^${timeSource(args)}$`); } function datetime(args) { const opts = ["Z"]; if (args.offset) opts.push(`([+-](?:[01]\\d|2[0-3]):[0-5]\\d)`); const qualified = `${timeSource({ precision: args.precision, seconds: true })}(?:${opts.join("|")})`; const timeRegex = args.local ? `${qualified}|${timeSource({ precision: args.precision })}` : qualified; return new RegExp(`^${dateSource}T(?:${timeRegex})$`); } var anyString = /^[\s\S]{0,}$/; var integer = /^-?\d+$/; var number$1 = /^-?\d+(?:\.\d+)?$/; var boolean$1 = /^(?:true|false)$/i; var _null$2 = /^null$/i; var lowercase = /^[^A-Z]*$/; var uppercase = /^[^a-z]*$/; //#endregion //#region node_modules/zod/v4/core/checks.js var $ZodCheck = /*@__PURE__*/ $constructor("$ZodCheck", (inst, def) => { var _a; inst._zod ?? (inst._zod = {}); inst._zod.def = def; (_a = inst._zod).onattach ?? (_a.onattach = []); }); /** Default `when` for length-based checks: run only on non-nullish values with a `length`. */ var _whenHasLength = (payload) => { const val = payload.value; return !nullish(val) && val.length !== void 0; }; var numericOriginMap = { number: "number", bigint: "bigint", object: "date" }; var $ZodCheckLessThan = /*@__PURE__*/ $constructor("$ZodCheckLessThan", (inst, def) => { $ZodCheck.init(inst, def); const origin = numericOriginMap[typeof def.value]; inst._zod.check = (payload) => { if (def.inclusive ? payload.value <= def.value : payload.value < def.value) return; payload.issues.push({ origin: numericOriginMap[typeof payload.value] ?? origin, code: "too_big", maximum: typeof def.value === "object" ? def.value.getTime() : def.value, input: payload.value, inclusive: def.inclusive, inst, continue: !def.abort }); }; }); var $ZodCheckGreaterThan = /*@__PURE__*/ $constructor("$ZodCheckGreaterThan", (inst, def) => { $ZodCheck.init(inst, def); const origin = numericOriginMap[typeof def.value]; inst._zod.check = (payload) => { if (def.inclusive ? payload.value >= def.value : payload.value > def.value) return; payload.issues.push({ origin: numericOriginMap[typeof payload.value] ?? origin, code: "too_small", minimum: typeof def.value === "object" ? def.value.getTime() : def.value, input: payload.value, inclusive: def.inclusive, inst, continue: !def.abort }); }; }); var $ZodCheckMultipleOf = /*@__PURE__*/ $constructor("$ZodCheckMultipleOf", (inst, def) => { $ZodCheck.init(inst, def); inst._zod.check = (payload) => { if (typeof payload.value !== typeof def.value) throw new Error("Cannot mix number and bigint in multiple_of check."); if (typeof payload.value === "bigint" ? def.value !== BigInt(0) && payload.value % def.value === BigInt(0) : floatSafeRemainder(payload.value, def.value) === 0) return; payload.issues.push({ origin: typeof payload.value, code: "not_multiple_of", divisor: def.value, input: payload.value, inst, continue: !def.abort }); }; }); var $ZodCheckNumberFormat = /*@__PURE__*/ $constructor("$ZodCheckNumberFormat", (inst, def) => { $ZodCheck.init(inst, def); def.format = def.format || "float64"; const isInt = def.format?.includes("int"); const origin = isInt ? "int" : "number"; const [minimum, maximum] = NUMBER_FORMAT_RANGES[def.format]; inst._zod.check = (payload) => { const input = payload.value; if (isInt) { if (!Number.isInteger(input)) { payload.issues.push({ expected: origin, format: def.format, code: "invalid_type", continue: false, input, inst }); return; } if (!Number.isSafeInteger(input)) { if (input > 0) payload.issues.push({ input, code: "too_big", maximum: Number.MAX_SAFE_INTEGER, note: "Integers must be within the safe integer range.", inst, origin, inclusive: true, continue: !def.abort }); else payload.issues.push({ input, code: "too_small", minimum: Number.MIN_SAFE_INTEGER, note: "Integers must be within the safe integer range.", inst, origin, inclusive: true, continue: !def.abort }); return; } } if (input < minimum) payload.issues.push({ origin: "number", input, code: "too_small", minimum, inclusive: true, inst, continue: !def.abort }); if (input > maximum) payload.issues.push({ origin: "number", input, code: "too_big", maximum, inclusive: true, inst, continue: !def.abort }); }; }); var $ZodCheckMaxLength = /*@__PURE__*/ $constructor("$ZodCheckMaxLength", (inst, def) => { var _a; $ZodCheck.init(inst, def); (_a = inst._zod.def).when ?? (_a.when = _whenHasLength); inst._zod.check = (payload) => { const input = payload.value; const units = input.length; if ((typeof input === "string" && units > def.maximum ? codePointLength(input) : units) <= def.maximum) return; const origin = getLengthableOrigin(input); payload.issues.push({ origin, code: "too_big", maximum: def.maximum, inclusive: true, input, inst, continue: !def.abort }); }; }); var $ZodCheckMinLength = /*@__PURE__*/ $constructor("$ZodCheckMinLength", (inst, def) => { var _a; $ZodCheck.init(inst, def); (_a = inst._zod.def).when ?? (_a.when = _whenHasLength); inst._zod.check = (payload) => { const input = payload.value; const units = input.length; if ((typeof input === "string" && units >= def.minimum && units < def.minimum * 2 ? codePointLength(input) : units) >= def.minimum) return; const origin = getLengthableOrigin(input); payload.issues.push({ origin, code: "too_small", minimum: def.minimum, inclusive: true, input, inst, continue: !def.abort }); }; }); var $ZodCheckLengthEquals = /*@__PURE__*/ $constructor("$ZodCheckLengthEquals", (inst, def) => { var _a; $ZodCheck.init(inst, def); (_a = inst._zod.def).when ?? (_a.when = _whenHasLength); inst._zod.check = (payload) => { const input = payload.value; const units = input.length; const length = typeof input === "string" && units >= def.length && units <= def.length * 2 ? codePointLength(input) : units; if (length === def.length) return; const origin = getLengthableOrigin(input); const tooBig = length > def.length; payload.issues.push({ origin, ...tooBig ? { code: "too_big", maximum: def.length } : { code: "too_small", minimum: def.length }, inclusive: true, exact: true, input: payload.value, inst, continue: !def.abort }); }; }); var $ZodCheckStringFormat = /*@__PURE__*/ $constructor("$ZodCheckStringFormat", (inst, def) => { var _a, _b; $ZodCheck.init(inst, def); if (def.pattern) (_a = inst._zod).check ?? (_a.check = (payload) => { def.pattern.lastIndex = 0; if (def.pattern.test(payload.value)) return; payload.issues.push({ origin: "string", code: "invalid_format", format: def.format, input: payload.value, ...def.pattern ? { pattern: def.pattern.toString() } : {}, inst, continue: !def.abort }); }); else (_b = inst._zod).check ?? (_b.check = () => {}); }); var $ZodCheckRegex = /*@__PURE__*/ $constructor("$ZodCheckRegex", (inst, def) => { $ZodCheckStringFormat.init(inst, def); inst._zod.check = (payload) => { def.pattern.lastIndex = 0; if (def.pattern.test(payload.value)) return; payload.issues.push({ origin: "string", code: "invalid_format", format: "regex", input: payload.value, pattern: def.pattern.toString(), inst, continue: !def.abort }); }; }); var $ZodCheckLowerCase = /*@__PURE__*/ $constructor("$ZodCheckLowerCase", (inst, def) => { def.pattern ?? (def.pattern = lowercase); $ZodCheckStringFormat.init(inst, def); }); var $ZodCheckUpperCase = /*@__PURE__*/ $constructor("$ZodCheckUpperCase", (inst, def) => { def.pattern ?? (def.pattern = uppercase); $ZodCheckStringFormat.init(inst, def); }); var $ZodCheckIncludes = /*@__PURE__*/ $constructor("$ZodCheckIncludes", (inst, def) => { $ZodCheck.init(inst, def); const escapedRegex = escapeRegex(def.includes); def.pattern = new RegExp(typeof def.position === "number" ? `^.{${def.position},}${escapedRegex}` : escapedRegex); inst._zod.check = (payload) => { if (payload.value.includes(def.includes, def.position)) return; payload.issues.push({ origin: "string", code: "invalid_format", format: "includes", includes: def.includes, input: payload.value, inst, continue: !def.abort }); }; }); var $ZodCheckStartsWith = /*@__PURE__*/ $constructor("$ZodCheckStartsWith", (inst, def) => { $ZodCheck.init(inst, def); const pattern = new RegExp(`^${escapeRegex(def.prefix)}.*`); def.pattern ?? (def.pattern = pattern); inst._zod.check = (payload) => { if (payload.value.startsWith(def.prefix)) return; payload.issues.push({ origin: "string", code: "invalid_format", format: "starts_with", prefix: def.prefix, input: payload.value, inst, continue: !def.abort }); }; }); var $ZodCheckEndsWith = /*@__PURE__*/ $constructor("$ZodCheckEndsWith", (inst, def) => { $ZodCheck.init(inst, def); const pattern = new RegExp(`.*${escapeRegex(def.suffix)}$`); def.pattern ?? (def.pattern = pattern); inst._zod.check = (payload) => { if (payload.value.endsWith(def.suffix)) return; payload.issues.push({ origin: "string", code: "invalid_format", format: "ends_with", suffix: def.suffix, input: payload.value, inst, continue: !def.abort }); }; }); function handleCheckPropertyResult(result, payload, property) { if (result.issues.length) payload.issues.push(...prefixIssues(property, result.issues)); } var $ZodCheckProperties = /*@__PURE__*/ $constructor("$ZodCheckProperties", (inst, def) => { $ZodCheck.init(inst, def); hide(inst, Symbol.iterator, function* () { yield inst; }); let entries; inst._zod.check = (payload) => { if (payload.value == null) { payload.issues.push({ expected: "object", code: "invalid_type", input: payload.value, inst }); return; } entries ?? (entries = Reflect.ownKeys(def.shape).map((key) => [key, def.shape[key]])); const input = payload.value; let proms; for (const [key, schema] of entries) { const result = schema._zod.run({ value: input[key], issues: [] }, {}); if (result instanceof Promise) { proms ?? (proms = []); proms.push(result.then((result) => handleCheckPropertyResult(result, payload, key))); } else handleCheckPropertyResult(result, payload, key); } if (proms) return Promise.all(proms).then(() => void 0); }; }); var $ZodCheckOverwrite = /*@__PURE__*/ $constructor("$ZodCheckOverwrite", (inst, def) => { $ZodCheck.init(inst, def); inst._zod.check = (payload) => { payload.value = def.tx(payload.value); }; }); //#endregion //#region node_modules/zod/v4/core/doc.js var Doc = class { constructor(args = [], closed = {}) { this.content = []; this.indent = 0; this.args = args; this.closed = closed; } indented(fn) { this.indent += 1; try { fn(this); } finally { this.indent -= 1; } } write(arg) { if (typeof arg === "function") { arg(this, { execution: "sync" }); arg(this, { execution: "async" }); return; } const lines = arg.split("\n").filter((x) => x); const minIndent = Math.min(...lines.map((x) => x.length - x.trimStart().length)); const dedented = lines.map((x) => x.slice(minIndent)).map((x) => " ".repeat(this.indent * 2) + x); for (const line of dedented) this.content.push(line); } compile() { const F = Function; const content = this?.content ?? [``]; return new F(...Object.keys(this.closed), `return function (${this.args.join(", ")}) {\n${content.join("\n")}\n};`)(...Object.values(this.closed)); } }; //#endregion //#region node_modules/zod/v4/core/versions.js var version = { major: 4, minor: 6, patch: 5 }; //#endregion //#region node_modules/zod/v4/core/schemas.js var $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => { var _a; inst ?? (inst = {}); inst._zod.def = def; inst._zod.bag = inst._zod.bag || {}; inst._zod.version = version; const defChecks = inst._zod.def.checks; const checks = inst._zod.traits.has("$ZodCheck") ? [inst, ...defChecks ?? []] : defChecks?.length ? [...defChecks] : []; for (const ch of checks) for (const fn of ch._zod.onattach) fn(inst); if (checks.length === 0) { (_a = inst._zod).deferred ?? (_a.deferred = []); inst._zod.deferred?.push(() => { inst._zod.run = inst._zod.parse; }); } else { const runChecks = (payload, checks, ctx) => { if (payload.memo) return payload; let isAborted = aborted(payload); let asyncResult; for (const ch of checks) { if (ch._zod.def.when) { if (explicitlyAborted(payload)) continue; if (!ch._zod.def.when(payload)) continue; } else if (isAborted) continue; const currLen = payload.issues.length; const _ = ch._zod.check(payload); if (_ instanceof Promise && ctx?.async === false) throw new $ZodAsyncError(); if (asyncResult || _ instanceof Promise) asyncResult = (asyncResult ?? Promise.resolve()).then(async () => { await _; if (payload.issues.length === currLen) return; attachSchema(payload.issues, currLen, inst); if (!isAborted) isAborted = aborted(payload, currLen); }); else { if (payload.issues.length === currLen) continue; attachSchema(payload.issues, currLen, inst); if (!isAborted) isAborted = aborted(payload, currLen); } } if (asyncResult) return asyncResult.then(() => { return payload; }); return payload; }; const handleCanaryResult = (canary, payload, ctx) => { if (aborted(canary)) { canary.aborted = true; return canary; } const checkResult = runChecks(payload, checks, ctx); if (checkResult instanceof Promise) { if (ctx.async === false) throw new $ZodAsyncError(); return checkResult.then((checkResult) => inst._zod.parse(checkResult, ctx)); } return inst._zod.parse(checkResult, ctx); }; inst._zod.run = (payload, ctx) => { if (ctx.skipChecks) return inst._zod.parse(payload, ctx); if (ctx.direction === "backward") { const canary = inst._zod.parse({ value: payload.value, issues: [] }, { ...ctx, skipChecks: true }); if (canary instanceof Promise) return canary.then((canary) => { return handleCanaryResult(canary, payload, ctx); }); return handleCanaryResult(canary, payload, ctx); } const result = inst._zod.parse(payload, ctx); if (result instanceof Promise) { if (ctx.async === false) throw new $ZodAsyncError(); return result.then((result) => runChecks(result, checks, ctx)); } return runChecks(result, checks, ctx); }; } }, { get "~standard"() { return hide(this, "~standard", standardProps(this)); }, set "~standard"(value) { own(this, "~standard", value); } }); /** The Standard Schema surface for `inst`. Shared so wrappers can extend it without forcing it. */ var toStandardResult = (r, ctx) => r.issues.length ? { issues: r.issues.map((iss) => finalizeIssue(iss, ctx, config())) } : { value: r.value }; async function validateAsync(inst, value) { const ctx = { async: true }; return toStandardResult(await inst._zod.run({ value, issues: [] }, ctx), ctx); } function standardProps(inst) { return { validate: (value) => { const ctx = { async: false }; try { const r = inst._zod.run({ value, issues: [] }, ctx); if (!(r instanceof Promise)) return toStandardResult(r, ctx); } catch (_) {} return validateAsync(inst, value); }, vendor: "zod", version: 1 }; } var $ZodString = /*@__PURE__*/ $constructor("$ZodString", (inst, def) => { $ZodType.init(inst, def); inst._zod.pattern = def.pattern ?? anyString; inst._zod.parse = (payload, _) => { if (def.coerce) try { payload.value = String(payload.value); } catch (_) {} if (typeof payload.value === "string") return payload; payload.issues.push({ expected: "string", code: "invalid_type", input: payload.value, inst }); return payload; }; }); var $ZodStringFormat = /*@__PURE__*/ $constructor("$ZodStringFormat", (inst, def) => { $ZodCheckStringFormat.init(inst, def); $ZodString.init(inst, def); }); var $ZodGUID = /*@__PURE__*/ $constructor("$ZodGUID", (inst, def) => { def.pattern ?? (def.pattern = guid); $ZodStringFormat.init(inst, def); }); var $ZodUUID = /*@__PURE__*/ $constructor("$ZodUUID", (inst, def) => { if (def.version) { const v = { v1: 1, v2: 2, v3: 3, v4: 4, v5: 5, v6: 6, v7: 7, v8: 8 }[def.version]; if (v === void 0) throw new Error(`Invalid UUID version: "${def.version}"`); def.pattern ?? (def.pattern = uuid(v)); } else def.pattern ?? (def.pattern = uuid()); $ZodStringFormat.init(inst, def); }); var $ZodEmail = /*@__PURE__*/ $constructor("$ZodEmail", (inst, def) => { def.pattern ?? (def.pattern = email); $ZodStringFormat.init(inst, def); }); function canParseURL(input) { try { if (typeof URL !== "undefined" && typeof URL.canParse === "function") return URL.canParse(input); new URL(input); return true; } catch { return false; } } function validateURL(trimmed, def) { if (!("normalize" in def) && !("hostname" in def) && !("protocol" in def)) return canParseURL(trimmed) || 2; return parseURLObject(trimmed, def); } /** Parses a URL while preserving the non-normalizing HTTP guard. */ function parseURLObject(trimmed, def) { if (!def.normalize && def.protocol?.source === httpProtocol.source && !/^https?:\/\//i.test(trimmed)) return 1; try { if (typeof URL !== "undefined") { const URLStatic = URL; if (typeof URLStatic.parse === "function") return URLStatic.parse(trimmed) ?? 2; } return new URL(trimmed); } catch { return 2; } } var asciiTabOrNewline = /[\t\n\r]/g; /** The URL parser deletes every ASCII tab, LF and CR from its input before it parses, so `new URL("https://exa\nmple.com")` reports on `example.com`. Applying the same deletion to the returned value closes the half of that divergence which can move the host; the parser's other rewrite, stripping C0 controls at the edges, cannot. */ function stripTabAndNewline(value) { return value.replace(asciiTabOrNewline, ""); } function urlHostnameOk(url, hostname) { hostname.lastIndex = 0; return hostname.test(url.hostname); } function urlProtocolOk(url, protocol) { protocol.lastIndex = 0; return protocol.test(url.protocol.endsWith(":") ? url.protocol.slice(0, -1) : url.protocol); } var $ZodURL = /*@__PURE__*/ $constructor("$ZodURL", (inst, def) => { $ZodStringFormat.init(inst, def); inst._zod.check = (payload) => { try { const trimmed = payload.value.trim(); const url = validateURL(trimmed, def); if (url === 1) { payload.issues.push({ code: "invalid_format", format: "url", note: "Invalid URL format", input: payload.value, inst, continue: !def.abort }); return; } if (url === 2) { payload.issues.push({ code: "invalid_format", format: "url", input: payload.value, inst, continue: !def.abort }); return; } if (url === true) { payload.value = stripTabAndNewline(trimmed); return; } if (def.hostname && !urlHostnameOk(url, def.hostname)) payload.issues.push({ code: "invalid_format", format: "url", note: "Invalid hostname", pattern: def.hostname.source, input: payload.value, inst, continue: !def.abort }); if (def.protocol && !urlProtocolOk(url, def.protocol)) payload.issues.push({ code: "invalid_format", format: "url", note: "Invalid protocol", pattern: def.protocol.source, input: payload.value, inst, continue: !def.abort }); payload.value = def.normalize ? url.href : stripTabAndNewline(trimmed); return; } catch (_) { payload.issues.push({ code: "invalid_format", format: "url", input: payload.value, inst, continue: !def.abort }); } }; }); var $ZodEmoji = /*@__PURE__*/ $constructor("$ZodEmoji", (inst, def) => { def.pattern ?? (def.pattern = emoji()); $ZodStringFormat.init(inst, def); }); var $ZodNanoID = /*@__PURE__*/ $constructor("$ZodNanoID", (inst, def) => { if (def.length !== void 0 && (!Number.isInteger(def.length) || def.length < 1)) throw new Error(`Invalid nanoid length: ${def.length}`); def.pattern ?? (def.pattern = def.length === void 0 ? nanoid : nanoidOfLength(def.length)); $ZodStringFormat.init(inst, def); }); /** * @deprecated CUID v1 is deprecated by its authors due to information leakage * (timestamps embedded in the id). Use {@link $ZodCUID2} instead. * See https://github.com/paralleldrive/cuid. */ var $ZodCUID = /*@__PURE__*/ $constructor("$ZodCUID", (inst, def) => { def.pattern ?? (def.pattern = cuid); $ZodStringFormat.init(inst, def); }); var $ZodCUID2 = /*@__PURE__*/ $constructor("$ZodCUID2", (inst, def) => { def.pattern ?? (def.pattern = cuid2); $ZodStringFormat.init(inst, def); }); var $ZodULID = /*@__PURE__*/ $constructor("$ZodULID", (inst, def) => { def.pattern ?? (def.pattern = ulid); $ZodStringFormat.init(inst, def); }); var $ZodXID = /*@__PURE__*/ $constructor("$ZodXID", (inst, def) => { def.pattern ?? (def.pattern = xid); $ZodStringFormat.init(inst, def); }); var $ZodKSUID = /*@__PURE__*/ $constructor("$ZodKSUID", (inst, def) => { def.pattern ?? (def.pattern = ksuid); $ZodStringFormat.init(inst, def); }); var $ZodISODateTime = /*@__PURE__*/ $constructor("$ZodISODateTime", (inst, def) => { def.pattern ?? (def.pattern = datetime(def)); $ZodStringFormat.init(inst, def); }); var $ZodISODate = /*@__PURE__*/ $constructor("$ZodISODate", (inst, def) => { def.pattern ?? (def.pattern = date); $ZodStringFormat.init(inst, def); }); var $ZodISOTime = /*@__PURE__*/ $constructor("$ZodISOTime", (inst, def) => { def.pattern ?? (def.pattern = time(def)); $ZodStringFormat.init(inst, def); }); var $ZodISODuration = /*@__PURE__*/ $constructor("$ZodISODuration", (inst, def) => { def.pattern ?? (def.pattern = duration); $ZodStringFormat.init(inst, def); }); var $ZodIPv4 = /*@__PURE__*/ $constructor("$ZodIPv4", (inst, def) => { def.pattern ?? (def.pattern = ipv4); $ZodStringFormat.init(inst, def); }); /** An IPv6 address is written with hex digits, colons and dots, and nothing else. The guard is what makes the check below an IPv6 check: `new URL("http://[...]")` parses an authority, not an address, so `@` and `\` re-delimit it and `"::@1\\"` validates against the host `0.0.0.1`. The URL parser also deletes ASCII tab, LF and CR rather than failing, which is how `"::1\n"` validated as `::1`. */ var ipv6Alphabet = /^[0-9a-fA-F:.]+$/; function isValidIPv6(value) { if (!ipv6Alphabet.test(value)) return false; return canParseURL(`http://[${value}]`); } var $ZodIPv6 = /*@__PURE__*/ $constructor("$ZodIPv6", (inst, def) => { def.pattern ?? (def.pattern = ipv6); $ZodStringFormat.init(inst, def); inst._zod.check = (payload) => { if (!isValidIPv6(payload.value)) payload.issues.push({ code: "invalid_format", format: "ipv6", input: payload.value, inst, continue: !def.abort }); }; }); var $ZodCIDRv4 = /*@__PURE__*/ $constructor("$ZodCIDRv4", (inst, def) => { def.pattern ?? (def.pattern = cidrv4); $ZodStringFormat.init(inst, def); }); function isValidCIDRv6(value) { const parts = value.split("/"); if (parts.length !== 2) return false; const [address, prefix] = parts; if (!prefix) return false; const prefixNum = Number(prefix); if (`${prefixNum}` !== prefix) return false; if (prefixNum < 0 || prefixNum > 128) return false; return isValidIPv6(address); } var $ZodCIDRv6 = /*@__PURE__*/ $constructor("$ZodCIDRv6", (inst, def) => { def.pattern ?? (def.pattern = cidrv6); $ZodStringFormat.init(inst, def); inst._zod.check = (payload) => { if (!isValidCIDRv6(payload.value)) payload.issues.push({ code: "invalid_format", format: "cidrv6", input: payload.value, inst, continue: !def.abort }); }; }); function isValidBase64(data) { if (data === "") return true; if (/\s/.test(data)) return false; if (data.length % 4 !== 0) return false; try { atob(data); return true; } catch { return false; } } var base64Charset = /^[0-9a-zA-Z+/]*={0,2}$/; var $ZodBase64 = /*@__PURE__*/ $constructor("$ZodBase64", (inst, def) => { def.pattern ?? (def.pattern = base64Charset); $ZodStringFormat.init(inst, def); inst._zod.check = (payload) => { if (isValidBase64(payload.value)) return; payload.issues.push({ code: "invalid_format", format: "base64", input: payload.value, inst, continue: !def.abort }); }; }); var base64urlCharset = /^[A-Za-z0-9_-]*$/; function isValidBase64URL(data) { if (!base64urlCharset.test(data)) return false; const base64 = data.replace(/[-_]/g, (c) => c === "-" ? "+" : "/"); return isValidBase64(base64.padEnd(Math.ceil(base64.length / 4) * 4, "=")); } var $ZodBase64URL = /*@__PURE__*/ $constructor("$ZodBase64URL", (inst, def) => { def.pattern ?? (def.pattern = base64urlCharset); $ZodStringFormat.init(inst, def); inst._zod.check = (payload) => { if (isValidBase64URL(payload.value)) return; payload.issues.push({ code: "invalid_format", format: "base64url", input: payload.value, inst, continue: !def.abort }); }; }); var $ZodE164 = /*@__PURE__*/ $constructor("$ZodE164", (inst, def) => { def.pattern ?? (def.pattern = e164); $ZodStringFormat.init(inst, def); }); function isValidJWT(token, algorithm = null) { try { const tokensParts = token.split("."); if (tokensParts.length !== 3) return false; const [header] = tokensParts; if (!header) return false; const parsedHeader = JSON.parse(atob(header)); if ("typ" in parsedHeader && parsedHeader?.typ !== "JWT") return false; if (!parsedHeader.alg) return false; if (algorithm && (!("alg" in parsedHeader) || parsedHeader.alg !== algorithm)) return false; return true; } catch { return false; } } var $ZodJWT = /*@__PURE__*/ $constructor("$ZodJWT", (inst, def) => { $ZodStringFormat.init(inst, def); inst._zod.check = (payload) => { if (isValidJWT(payload.value, def.alg)) return; payload.issues.push({ code: "invalid_format", format: "jwt", input: payload.value, inst, continue: !def.abort }); }; }); var $ZodNumber = /*@__PURE__*/ $constructor("$ZodNumber", (inst, def) => { $ZodType.init(inst, def); inst._zod.pattern = number$1; inst._zod.parse = (payload, _ctx) => { if (def.coerce) try { payload.value = Number(payload.value); } catch (_) {} const input = payload.value; if (typeof input === "number" && !Number.isNaN(input) && Number.isFinite(input)) return payload; const received = typeof input === "number" ? Number.isNaN(input) ? "NaN" : !Number.isFinite(input) ? String(input) : void 0 : void 0; payload.issues.push({ expected: "number", code: "invalid_type", input, inst, ...received ? { received } : {} }); return payload; }; }); var $ZodNumberFormat = /*@__PURE__*/ $constructor("$ZodNumberFormat", (inst, def) => { $ZodCheckNumberFormat.init(inst, def); $ZodNumber.init(inst, def); }); var $ZodBoolean = /*@__PURE__*/ $constructor("$ZodBoolean", (inst, def) => { $ZodType.init(inst, def); inst._zod.pattern = boolean$1; inst._zod.parse = (payload, _ctx) => { if (def.coerce) try { payload.value = Boolean(payload.value); } catch (_) {} const input = payload.value; if (typeof input === "boolean") return payload; payload.issues.push({ expected: "boolean", code: "invalid_type", input, inst }); return payload; }; }); var $ZodNull = /*@__PURE__*/ $constructor("$ZodNull", (inst, def) => { $ZodType.init(inst, def); inst._zod.pattern = _null$2; inst._zod.values = /* @__PURE__ */ new Set([null]); inst._zod.parse = (payload, _ctx) => { const input = payload.value; if (input === null) return payload; payload.issues.push({ expected: "null", code: "invalid_type", input, inst }); return payload; }; }); var $ZodAny = /*@__PURE__*/ $constructor("$ZodAny", (inst, def) => { $ZodType.init(inst, def); inst._zod.parse = (payload) => payload; }); var $ZodUnknown = /*@__PURE__*/ $constructor("$ZodUnknown", (inst, def) => { $ZodType.init(inst, def); inst._zod.parse = (payload) => payload; }); var $ZodNever = /*@__PURE__*/ $constructor("$ZodNever", (inst, def) => { $ZodType.init(inst, def); inst._zod.parse = (payload, _ctx) => { payload.issues.push({ expected: "never", code: "invalid_type", input: payload.value, inst }); return payload; }; }); function handleArrayResult(result, final, index) { if (result.issues.length) final.issues.push(...prefixIssues(index, result.issues)); final.value[index] = result.value; } var $ZodArray = /*@__PURE__*/ $constructor("$ZodArray", (inst, def) => { $ZodType.init(inst, def); const memo = globalConfig.memoizer; memo?.attach(inst); inst._zod.parse = (payload, ctx) => { const input = payload.value; if (!Array.isArray(input)) { payload.issues.push({ expected: "array", code: "invalid_type", input, inst }); return payload; } payload.value = memo ? memo.alloc(inst, payload, Array(input.length), ctx) : Array(input.length); const proms = []; const abortEarly = ctx?.abortEarly; for (let i = 0; i < input.length; i++) { const item = input[i]; const result = def.element._zod.run({ value: item, issues: [] }, ctx); if (result instanceof Promise) proms.push(result.then((result) => handleArrayResult(result, payload, i))); else { handleArrayResult(result, payload, i); if (abortEarly && result.issues.length !== 0 && aborted(result)) break; } } if (proms.length) return Promise.all(proms).then(() => payload); return payload; }; }); function handlePropertyResult(result, final, key, input, optin, optout) { const isPresent = key in input; const isOptionalOut = optout === "optional"; if (!isPresent && isOptionalOut && optin === "optional") return; if (result.issues.length) { if (optin !== void 0 && isOptionalOut && !isPresent) return; final.issues.push(...prefixIssues(key, result.issues)); } if (!isPresent && optin === void 0) { if (!result.issues.length) final.issues.push({ code: "invalid_type", expected: "nonoptional", input: void 0, path: [key] }); return; } if (result.value === void 0) { if (isPresent || optin === "defaulted" && !isOptionalOut) final.value[key] = void 0; } else final.value[key] = result.value; } var NO_SYMBOL_KEYS = []; function normalizeDef(def) { const keys = Object.keys(def.shape); const ownSymbols = Object.getOwnPropertySymbols(def.shape); const symbolKeys = ownSymbols.length ? ownSymbols : NO_SYMBOL_KEYS; const allKeys = symbolKeys.length ? [...keys, ...symbolKeys] : keys; for (const k of allKeys) if (!def.shape?.[k]?._zod?.traits?.has("$ZodType")) throw new Error(`Invalid element at key "${String(k)}": expected a Zod schema`); const okeys = optionalKeys(def.shape); return { ...def, allKeys, symbolKeys, keySet: new Set(keys), numKeys: keys.length, optionalKeys: new Set(okeys) }; } function handleCatchall(proms, input, payload, ctx, def, inst, abortEarly) { const unrecognized = []; const keySet = def.keySet; const _catchall = def.catchall._zod; const t = _catchall.def.type; const optin = _catchall.optin; const optout = _catchall.optout; let seen = 0; for (const key in input) { if (abortEarly && payload.issues.length !== seen) { if (aborted(payload, seen)) break; seen = payload.issues.length; } if (keySet.has(key)) continue; if (key === "__proto__") { if (t === "never") unrecognized.push(key); continue; } if (t === "never") { unrecognized.push(key); continue; } const r = _catchall.run({ value: input[key], issues: [] }, ctx); if (r instanceof Promise) proms.push(r.then((r) => handlePropertyResult(r, payload, key, input, optin, optout))); else handlePropertyResult(r, payload, key, input, optin, optout); } if (unrecognized.length) payload.issues.push({ code: "unrecognized_keys", keys: unrecognized, input, inst, continue: true }); if (!proms.length) return payload; return Promise.all(proms).then(() => { return payload; }); } var $ZodObject = /*@__PURE__*/ $constructor("$ZodObject", (inst, def) => { $ZodType.init(inst, def); const desc = Object.getOwnPropertyDescriptor(def, "shape"); const sh = desc?.get ? desc.get.raw : def.shape ?? {}; if (sh) { const get = () => { const newSh = { ...sh }; Object.defineProperty(def, "shape", { value: newSh }); get.raw = newSh; return newSh; }; get.raw = sh; Object.defineProperty(def, "shape", { get }); } const _normalized = cached(() => normalizeDef(def)); defineLazyInternal(inst, "propValues", (zod) => { const shape = zod.def.shape; const propValues = {}; for (const key in shape) { const field = shape[key]._zod; if (field.values) { if (!Object.prototype.hasOwnProperty.call(propValues, key)) assignProp(propValues, key, /* @__PURE__ */ new Set()); for (const v of field.values) propValues[key].add(v); if (field.optin !== void 0) propValues[key].add(void 0); } } return propValues; }); const isObject$2 = isObject; const catchall = def.catchall; let value; const memo = globalConfig.memoizer; memo?.attach(inst); inst._zod.parse = (payload, ctx) => { value ?? (value = _normalized.value); const input = payload.value; if (!isObject$2(input)) { payload.issues.push({ expected: "object", code: "invalid_type", input, inst }); return payload; } payload.value = memo ? memo.alloc(inst, payload, {}, ctx) : {}; const proms = []; const shape = value.shape; const abortEarly = ctx?.abortEarly; let seen = payload.issues.length; for (const key of value.allKeys) { if (abortEarly && payload.issues.length !== seen) { if (aborted(payload, seen)) break; seen = payload.issues.length; } if (key === "__proto__") continue; const el = shape[key]; const optin = el._zod.optin; const optout = el._zod.optout; const r = el._zod.run({ value: input[key], issues: [] }, ctx); if (r instanceof Promise) proms.push(r.then((r) => handlePropertyResult(r, payload, key, input, optin, optout))); else handlePropertyResult(r, payload, key, input, optin, optout); } if (!catchall) return proms.length ? Promise.all(proms).then(() => payload) : payload; return handleCatchall(proms, input, payload, ctx, _normalized.value, inst, abortEarly === true); }; }); var $ZodObjectJIT = /*@__PURE__*/ $constructor("$ZodObjectJIT", (inst, def) => { $ZodObject.init(inst, def); const superParse = inst._zod.parse; const _normalized = cached(() => normalizeDef(def)); const memo = globalConfig.memoizer; const generateFastpass = (shape) => { const normalized = _normalized.value; const syms = normalized.symbolKeys; const doc = new Doc(["payload", "ctx"], { shape, inst, memo, syms }); const parseStr = (k) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`; const prefixStr = (id, k) => ` let ${id}_ab = false; for (let i = 0; i < ${id}.issues.length; i++) { const iss = ${id}.issues[i]; iss.path = iss.path ? [${k}, ...iss.path] : [${k}]; payload.issues.push(iss); if (iss.continue !== true) ${id}_ab = true; } if (${id}_ab && ctx && ctx.abortEarly) { payload.value = newResult; return payload; }`; doc.write(`const input = payload.value;`); const ids = Object.create(null); let counter = 0; for (const key of normalized.allKeys) ids[key] = `key_${counter++}`; doc.write(memo ? `const newResult = memo.alloc(inst, payload, {}, ctx);` : `const newResult = {};`); for (const key of normalized.allKeys) { if (key === "__proto__") continue; const id = ids[key]; const k = typeof key === "symbol" ? `syms[${syms.indexOf(key)}]` : esc(key); const isPresent = `${k} in input`; const schema = shape[key]; const optin = schema?._zod?.optin; const isOptionalIn = optin !== void 0; const isOptionalOut = schema?._zod?.optout === "optional"; doc.write(`const ${id} = ${parseStr(k)};`); if (isOptionalIn && isOptionalOut) { const assign = optin === "optional" ? `${id}_present` : `${id}.value !== undefined || ${id}_present`; doc.write(` const ${id}_present = ${isPresent}; if (!${id}.issues.length || ${id}_present) { if (${id}.issues.length) {${prefixStr(id, k)} } if (${assign}) { newResult[${k}] = ${id}.value; } } `); } else if (!isOptionalIn) doc.write(` const ${id}_present = ${isPresent}; if (${id}.issues.length) {${prefixStr(id, k)} } if (!${id}_present && !${id}.issues.length) { payload.issues.push({ code: "invalid_type", expected: "nonoptional", input: undefined, path: [${k}] }); if (ctx && ctx.abortEarly) { payload.value = newResult; return payload; } } if (${id}_present) { newResult[${k}] = ${id}.value; } `); else { doc.write(` if (${id}.issues.length) {${prefixStr(id, k)} } `); if (optin === "defaulted") doc.write(`newResult[${k}] = ${id}.value;`); else doc.write(` if (${id}.value !== undefined || ${isPresent}) { newResult[${k}] = ${id}.value; } `); } } doc.write(`payload.value = newResult;`); doc.write(`return payload;`); return doc.compile(); }; let fastpass; const isObject$1 = isObject; const jit = !globalConfig.jitless; const fastEnabled = jit && allowsEval.value; const catchall = def.catchall; let value; inst._zod.parse = (payload, ctx) => { value ?? (value = _normalized.value); const input = payload.value; if (!isObject$1(input)) { payload.issues.push({ expected: "object", code: "invalid_type", input, inst }); return payload; } if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) { if (!fastpass) fastpass = generateFastpass(def.shape); payload = fastpass(payload, ctx); if (!catchall) return payload; return handleCatchall([], input, payload, ctx, value, inst, ctx?.abortEarly === true); } return superParse(payload, ctx); }; }); function handleUnionResults(results, final, inst, ctx) { for (const result of results) if (result.issues.length === 0) { final.value = result.value; return final; } const nonaborted = results.filter((r) => !aborted(r)); if (nonaborted.length === 1) { final.value = nonaborted[0].value; return nonaborted[0]; } final.issues.push({ code: "invalid_union", input: final.value, inst, errors: results.map((result) => result.issues.map((iss) => finalizeIssue(iss, ctx, config()))) }); return final; } var $ZodUnion = /*@__PURE__*/ $constructor("$ZodUnion", (inst, def) => { $ZodType.init(inst, def); defineLazyInternal(inst, "optin", (zod) => zod.def.options.some((o) => o._zod.optin === "defaulted") ? "defaulted" : zod.def.options.some((o) => o._zod.optin !== void 0) ? "optional" : void 0); defineLazyInternal(inst, "optout", (zod) => zod.def.options.some((o) => o._zod.optout === "optional") ? "optional" : void 0); defineLazyInternal(inst, "values", (zod) => { if (zod.def.options.every((o) => o._zod.values)) return new Set(zod.def.options.flatMap((option) => Array.from(option._zod.values))); }); defineLazyInternal(inst, "pattern", (zod) => { if (zod.def.options.every((o) => o._zod.pattern)) { const patterns = zod.def.options.map((o) => o._zod.pattern); return new RegExp(`^(${patterns.map((p) => cleanRegex(p.source)).join("|")})$`); } }); const first = def.options.length === 1 ? def.options[0]._zod.run : null; inst._zod.parse = (payload, ctx) => { if (first) return first(payload, ctx); let async = false; const results = []; for (const option of def.options) { const result = option._zod.run({ value: payload.value, issues: [] }, ctx); if (result instanceof Promise) { results.push(result); async = true; } else { if (result.issues.length === 0) return result; results.push(result); } } if (!async) return handleUnionResults(results, payload, inst, ctx); return Promise.all(results).then((results) => { return handleUnionResults(results, payload, inst, ctx); }); }; }); function discriminatorMap(def) { const map = /* @__PURE__ */ new Map(); for (const option of def.options) { const values = option._zod.propValues?.[def.discriminator]; if (!values || values.size === 0) throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`); for (const value of values) if (map.has(value)) { if (value !== void 0) throw new Error(`Duplicate discriminator value "${String(value)}"`); map.set(value, null); } else map.set(value, option); } return map; } var $ZodDiscriminatedUnion = /*@__PURE__*/ $constructor("$ZodDiscriminatedUnion", (inst, def) => { def.inclusive = false; $ZodUnion.init(inst, def); const _super = inst._zod.parse; defineLazyInternal(inst, "propValues", (zod) => { const propValues = {}; let undefinedCount = 0; for (const option of zod.def.options) { const pv = option._zod.propValues; if (!pv || Object.keys(pv).length === 0) throw new Error(`Invalid discriminated union option at index "${zod.def.options.indexOf(option)}"`); if (pv[zod.def.discriminator]?.has(void 0)) undefinedCount++; for (const [k, v] of Object.entries(pv)) { if (!Object.prototype.hasOwnProperty.call(propValues, k)) assignProp(propValues, k, /* @__PURE__ */ new Set()); for (const val of v) propValues[k].add(val); } } if (!zod.def.unionFallback && undefinedCount > 1) propValues[zod.def.discriminator]?.delete(void 0); return propValues; }); def.options.forEach((option, i) => { const propShape = rawShape(option._zod.def); if (propShape && !Object.prototype.hasOwnProperty.call(propShape, def.discriminator)) throw new Error(`Invalid discriminated union option at index "${i}"`); }); const disc = cached(() => discriminatorMap(def)); inst._zod.parse = (payload, ctx) => { const input = payload.value; if (!isObject(input)) { payload.issues.push({ code: "invalid_type", expected: "object", input, inst }); return payload; } const value = input?.[def.discriminator]; const opt = disc.value.get(value); if (opt && (value !== void 0 || ctx.direction !== "backward")) return opt._zod.run(payload, ctx); if (def.unionFallback || ctx.direction === "backward") return _super(payload, ctx); payload.issues.push({ code: "invalid_union", errors: [], note: "No matching discriminator", discriminator: def.discriminator, options: Array.from(disc.value.keys()).filter((value) => disc.value.get(value) !== null), input, path: [def.discriminator], inst }); return payload; }; }); var $ZodIntersection = /*@__PURE__*/ $constructor("$ZodIntersection", (inst, def) => { $ZodType.init(inst, def); inst._zod.parse = (payload, ctx) => { const input = payload.value; const left = def.left._zod.run({ value: input, issues: [] }, ctx); const right = def.right._zod.run({ value: input, issues: [] }, ctx); if (left instanceof Promise || right instanceof Promise) return Promise.all([left, right]).then(([left, right]) => { return handleIntersectionResults(payload, left, right); }); return handleIntersectionResults(payload, left, right); }; }); function mergeValues(a, b) { if (a === b) return { valid: true, data: a }; if (a instanceof Date && b instanceof Date && +a === +b) return { valid: true, data: a }; if (isPlainObject(a) && isPlainObject(b)) { const bKeys = Object.keys(b); const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1); const newObj = { ...a, ...b }; if (Object.prototype.hasOwnProperty.call(newObj, "__proto__")) delete newObj.__proto__; for (const key of sharedKeys) { if (key === "__proto__") continue; const sharedValue = mergeValues(a[key], b[key]); if (!sharedValue.valid) return { valid: false, mergeErrorPath: [key, ...sharedValue.mergeErrorPath] }; newObj[key] = sharedValue.data; } return { valid: true, data: newObj }; } if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return { valid: false, mergeErrorPath: [] }; const newArray = []; for (let index = 0; index < a.length; index++) { const itemA = a[index]; const itemB = b[index]; const sharedValue = mergeValues(itemA, itemB); if (!sharedValue.valid) return { valid: false, mergeErrorPath: [index, ...sharedValue.mergeErrorPath] }; newArray.push(sharedValue.data); } return { valid: true, data: newArray }; } return { valid: false, mergeErrorPath: [] }; } function handleIntersectionResults(result, left, right) { const unrecKeys = /* @__PURE__ */ new Map(); let unrecIssue; const keyIssues = /* @__PURE__ */ new Map(); const collect = (iss, side) => { let keys; if (iss.code === "unrecognized_keys" && !iss.path?.length) { unrecIssue ?? (unrecIssue = iss); keys = iss.keys; } else if (iss.code === "invalid_key" && iss.origin === "record" && iss.path?.length === 1) { const k = String(iss.path[0]); if (!keyIssues.has(k)) keyIssues.set(k, iss); keys = [k]; } else return false; for (const k of keys) { if (!unrecKeys.has(k)) unrecKeys.set(k, {}); unrecKeys.get(k)[side] = true; } return true; }; for (const iss of left.issues) if (!collect(iss, "l")) result.issues.push(iss); for (const iss of right.issues) if (!collect(iss, "r")) result.issues.push(iss); const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k); if (bothKeys.length) { const aggregated = unrecIssue ? bothKeys.filter((k) => unrecIssue.keys.includes(k)) : []; if (aggregated.length) result.issues.push({ ...unrecIssue, keys: aggregated }); for (const k of bothKeys) if (!aggregated.includes(k) && keyIssues.has(k)) result.issues.push(keyIssues.get(k)); } const merged = mergeValues(left.value, right.value); if (!merged.valid) { if (aborted(result)) return result; throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(merged.mergeErrorPath)}`); } result.value = merged.data; return result; } var $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => { $ZodType.init(inst, def); const memo = globalConfig.memoizer; memo?.attach(inst); inst._zod.parse = (payload, ctx) => { const input = payload.value; if (!isPlainObject(input)) { payload.issues.push({ expected: "record", code: "invalid_type", input, inst }); return payload; } const proms = []; const values = def.keyType._zod.values; if (values && !def.partial) { payload.value = memo ? memo.alloc(inst, payload, {}, ctx) : {}; const recordKeys = /* @__PURE__ */ new Set(); for (const key of values) if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") { recordKeys.add(typeof key === "number" ? key.toString() : key); if (key === "__proto__") continue; const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx); if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently"); if (keyResult.issues.length) { payload.issues.push({ code: "invalid_key", origin: "record", issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())), input: key, path: [key], inst }); continue; } const outKey = keyResult.value; if (outKey === "__proto__") continue; const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx); if (result instanceof Promise) proms.push(result.then((result) => { if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues)); payload.value[outKey] = result.value; })); else { if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues)); payload.value[outKey] = result.value; } } let unrecognized; for (const key in input) if (!recordKeys.has(key)) { if (def.mode === "loose") { if (key === "__proto__") continue; payload.value[key] = input[key]; } else { unrecognized = unrecognized ?? []; unrecognized.push(key); } } if (unrecognized && unrecognized.length > 0) payload.issues.push({ code: "unrecognized_keys", input, inst, keys: unrecognized, continue: true }); } else { payload.value = memo ? memo.alloc(inst, payload, {}, ctx) : {}; let unrecognized; for (const key of Reflect.ownKeys(input)) { if (key === "__proto__") continue; if (!Object.prototype.propertyIsEnumerable.call(input, key)) continue; let keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx); if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently"); if (typeof key === "string" && number$1.test(key) && keyResult.issues.length) { const retryResult = def.keyType._zod.run({ value: Number(key), issues: [] }, ctx); if (retryResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently"); if (retryResult.issues.length === 0) keyResult = retryResult; } if (keyResult.issues.length) { if (def.mode === "loose") payload.value[key] = input[key]; else if (values) { unrecognized = unrecognized ?? []; unrecognized.push(key); } else payload.issues.push({ code: "invalid_key", origin: "record", issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())), input: key, path: [key], inst }); continue; } const outKey = keyResult.value; if (outKey === "__proto__") continue; const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx); if (result instanceof Promise) proms.push(result.then((result) => { if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues)); payload.value[outKey] = result.value; })); else { if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues)); payload.value[outKey] = result.value; } } if (unrecognized && unrecognized.length > 0) payload.issues.push({ code: "unrecognized_keys", input, inst, keys: unrecognized, continue: true }); } if (proms.length) return Promise.all(proms).then(() => payload); return payload; }; }); var $ZodEnum = /*@__PURE__*/ $constructor("$ZodEnum", (inst, def) => { $ZodType.init(inst, def); const values = getEnumValues(def.entries); const valuesSet = new Set(values); inst._zod.values = valuesSet; defineLazyInternal(inst, "pattern", (zod) => { const patternValues = getEnumValues(zod.def.entries).filter((k) => propertyKeyTypes.has(typeof k)); return new RegExp(patternValues.length ? `^(${patternValues.map((o) => escapeRegex(o.toString())).join("|")})$` : "^[^\\s\\S]$"); }); inst._zod.parse = (payload, _ctx) => { const input = payload.value; if (valuesSet.has(input)) return payload; payload.issues.push({ code: "invalid_value", values, input, inst }); return payload; }; }); var $ZodLiteral = /*@__PURE__*/ $constructor("$ZodLiteral", (inst, def) => { $ZodType.init(inst, def); const values = new Set(def.values); inst._zod.values = values; defineLazyInternal(inst, "pattern", (zod) => { const vals = zod.def.values; return new RegExp(vals.length ? `^(${vals.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})$` : "^[^\\s\\S]$"); }); inst._zod.parse = (payload, _ctx) => { const input = payload.value; if (values.has(input)) return payload; payload.issues.push({ code: "invalid_value", values: def.values, input, inst }); return payload; }; }); var $ZodTransform = /*@__PURE__*/ $constructor("$ZodTransform", (inst, def) => { $ZodType.init(inst, def); inst._zod.optin = "optional"; globalConfig.memoizer?.guard(inst); inst._zod.parse = (payload, ctx) => { if (ctx.direction === "backward") throw new $ZodEncodeError(inst.constructor.name); const _out = def.transform(payload.value, payload); if (ctx.async) return (_out instanceof Promise ? _out : Promise.resolve(_out)).then((output) => { payload.value = output; return payload; }); if (_out instanceof Promise) throw new $ZodAsyncError(); payload.value = _out; return payload; }; }); function handleOptionalResult(payload, result) { payload.value = result.issues.length ? void 0 : result.value; return payload; } var $ZodOptional = /*@__PURE__*/ $constructor("$ZodOptional", (inst, def) => { $ZodType.init(inst, def); defineLazyInternal(inst, "optin", (zod) => zod.def.innerType._zod.optin === "defaulted" ? "defaulted" : "optional"); inst._zod.optout = "optional"; defineLazyInternal(inst, "values", (zod) => { const values = zod.def.innerType._zod.values; return values ? /* @__PURE__ */ new Set([...values, void 0]) : void 0; }); defineLazyInternal(inst, "pattern", (zod) => { const pattern = zod.def.innerType._zod.pattern; return pattern ? new RegExp(`^(${cleanRegex(pattern.source)})?$`) : void 0; }); inst._zod.parse = (payload, ctx) => { if (payload.value === void 0) { if (def.innerType._zod.optin !== "defaulted") return payload; const result = def.innerType._zod.run({ value: payload.value, issues: [] }, ctx); if (result instanceof Promise) return result.then((result) => handleOptionalResult(payload, result)); return handleOptionalResult(payload, result); } return def.innerType._zod.run(payload, ctx); }; }); var $ZodExactOptional = /*@__PURE__*/ $constructor("$ZodExactOptional", (inst, def) => { $ZodOptional.init(inst, def); defineLazyInternal(inst, "values", (zod) => zod.def.innerType._zod.values); defineLazyInternal(inst, "pattern", (zod) => zod.def.innerType._zod.pattern); inst._zod.parse = (payload, ctx) => { return def.innerType._zod.run(payload, ctx); }; }); var $ZodNullable = /*@__PURE__*/ $constructor("$ZodNullable", (inst, def) => { $ZodType.init(inst, def); defineLazyInternal(inst, "optin", (zod) => zod.def.innerType._zod.optin); defineLazyInternal(inst, "optout", (zod) => zod.def.innerType._zod.optout); defineLazyInternal(inst, "pattern", (zod) => { const pattern = zod.def.innerType._zod.pattern; return pattern ? new RegExp(`^(${cleanRegex(pattern.source)}|null)$`) : void 0; }); defineLazyInternal(inst, "values", (zod) => { return zod.def.innerType._zod.values ? /* @__PURE__ */ new Set([...zod.def.innerType._zod.values, null]) : void 0; }); inst._zod.parse = (payload, ctx) => { if (payload.value === null) return payload; return def.innerType._zod.run(payload, ctx); }; }); var $ZodDefault = /*@__PURE__*/ $constructor("$ZodDefault", (inst, def) => { $ZodType.init(inst, def); inst._zod.optin = "defaulted"; defineLazyInternal(inst, "values", (zod) => zod.def.innerType._zod.values); inst._zod.parse = (payload, ctx) => { if (ctx.direction === "backward") return def.innerType._zod.run(payload, ctx); if (payload.value === void 0) { payload.value = def.defaultValue; /** * $ZodDefault returns the default value immediately in forward direction. * It doesn't pass the default value into the validator ("prefault"). There's no reason to pass the default value through validation. The validity of the default is enforced by TypeScript statically. Otherwise, it's the responsibility of the user to ensure the default is valid. In the case of pipes with divergent in/out types, you can specify the default on the `in` schema of your ZodPipe to set a "prefault" for the pipe. */ return payload; } const result = def.innerType._zod.run(payload, ctx); if (result instanceof Promise) return result.then((result) => handleDefaultResult(result, def)); return handleDefaultResult(result, def); }; }); function handleDefaultResult(payload, def) { if (payload.value === void 0) payload.value = def.defaultValue; return payload; } var $ZodPrefault = /*@__PURE__*/ $constructor("$ZodPrefault", (inst, def) => { $ZodType.init(inst, def); inst._zod.optin = "defaulted"; defineLazyInternal(inst, "values", (zod) => zod.def.innerType._zod.values); inst._zod.parse = (payload, ctx) => { if (ctx.direction === "backward") return def.innerType._zod.run(payload, ctx); if (payload.value === void 0) payload.value = def.defaultValue; return def.innerType._zod.run(payload, ctx); }; }); var $ZodNonOptional = /*@__PURE__*/ $constructor("$ZodNonOptional", (inst, def) => { $ZodType.init(inst, def); defineLazyInternal(inst, "values", (zod) => { const v = zod.def.innerType._zod.values; return v ? new Set([...v].filter((x) => x !== void 0)) : void 0; }); inst._zod.parse = (payload, ctx) => { const result = def.innerType._zod.run(payload, ctx); if (result instanceof Promise) return result.then((result) => handleNonOptionalResult(result, inst)); return handleNonOptionalResult(result, inst); }; }); function handleNonOptionalResult(payload, inst) { if (!payload.issues.length && payload.value === void 0) payload.issues.push({ code: "invalid_type", expected: "nonoptional", input: payload.value, inst }); return payload; } function handleCatchResult(payload, result, def, ctx) { if (!result.issues.length) { payload.value = result.value; if (result.memo) payload.memo = true; return payload; } payload.value = def.catchValue({ ...result, value: payload.value, error: { issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config())) }, input: payload.value }); return payload; } var $ZodCatch = /*@__PURE__*/ $constructor("$ZodCatch", (inst, def) => { $ZodType.init(inst, def); defineLazyInternal(inst, "optin", (zod) => zod.def.innerType._zod.optin === "defaulted" ? "defaulted" : "optional"); defineLazyInternal(inst, "optout", (zod) => zod.def.innerType._zod.optout); defineLazyInternal(inst, "values", (zod) => zod.def.innerType._zod.values); inst._zod.parse = (payload, ctx) => { if (ctx.direction === "backward") return def.innerType._zod.run(payload, ctx); const result = def.innerType._zod.run({ value: payload.value, issues: [] }, ctx); if (result instanceof Promise) return result.then((result) => handleCatchResult(payload, result, def, ctx)); return handleCatchResult(payload, result, def, ctx); }; }); var $ZodPipe = /*@__PURE__*/ $constructor("$ZodPipe", (inst, def) => { $ZodType.init(inst, def); defineLazyInternal(inst, "values", (zod) => zod.def.in._zod.values); defineLazyInternal(inst, "optin", (zod) => zod.def.in._zod.optin); defineLazyInternal(inst, "optout", (zod) => zod.def.out._zod.optout); defineLazyInternal(inst, "propValues", (zod) => zod.def.in._zod.propValues); inst._zod.parse = (payload, ctx) => { if (ctx.direction === "backward") { const right = def.out._zod.run(payload, ctx); if (right instanceof Promise) return right.then((right) => handlePipeResult(right, def.in, ctx)); return handlePipeResult(right, def.in, ctx); } const left = def.in._zod.run(payload, ctx); if (left instanceof Promise) return left.then((left) => handlePipeResult(left, def.out, ctx)); return handlePipeResult(left, def.out, ctx); }; }); function handlePipeResult(left, next, ctx) { if (left.issues.some((iss) => iss.code !== "unrecognized_keys")) { left.aborted = true; return left; } return next._zod.run({ value: left.value, issues: left.issues }, ctx); } var $ZodReadonly = /*@__PURE__*/ $constructor("$ZodReadonly", (inst, def) => { $ZodType.init(inst, def); defineLazyInternal(inst, "propValues", (zod) => zod.def.innerType._zod.propValues); defineLazyInternal(inst, "values", (zod) => zod.def.innerType._zod.values); defineLazyInternal(inst, "optin", (zod) => zod.def.innerType?._zod?.optin); defineLazyInternal(inst, "optout", (zod) => zod.def.innerType?._zod?.optout); inst._zod.parse = (payload, ctx) => { if (ctx.direction === "backward") return def.innerType._zod.run(payload, ctx); const result = def.innerType._zod.run(payload, ctx); if (result instanceof Promise) return result.then(handleReadonlyResult); return handleReadonlyResult(result); }; }); function handleReadonlyResult(payload) { if (!payload.memo) payload.value = Object.freeze(payload.value); return payload; } var $ZodLazy = /*@__PURE__*/ $constructor("$ZodLazy", (inst, def) => { $ZodType.init(inst, def); defineLazy(inst._zod, "innerType", () => { const d = def; if (!d._cachedInner) d._cachedInner = def.getter(); return d._cachedInner; }); defineLazyInternal(inst, "pattern", (zod) => zod.innerType?._zod?.pattern); defineLazyInternal(inst, "propValues", (zod) => zod.innerType?._zod?.propValues); defineLazyInternal(inst, "optin", (zod) => zod.innerType?._zod?.optin ?? void 0); defineLazyInternal(inst, "optout", (zod) => zod.innerType?._zod?.optout ?? void 0); inst._zod.parse = (payload, ctx) => { return inst._zod.innerType._zod.run(payload, ctx); }; }); var $ZodCustom = /*@__PURE__*/ $constructor("$ZodCustom", (inst, def) => { $ZodCheck.init(inst, def); $ZodType.init(inst, def); inst._zod.parse = (payload, _) => { return payload; }; inst._zod.check = (payload) => { const input = payload.value; const r = def.fn(input); if (r instanceof Promise) return r.then((r) => handleRefineResult(r, payload, input, inst)); handleRefineResult(r, payload, input, inst); }; }); function handleRefineResult(result, payload, input, inst) { if (!result) { const _iss = { code: "custom", input, inst, path: [...inst._zod.def.path ?? []], continue: !inst._zod.def.abort }; if (inst._zod.def.params) _iss.params = inst._zod.def.params; payload.issues.push(issue(_iss)); } } //#endregion //#region node_modules/zod/v4/core/memoizer.js var $ZodCyclicError = class extends Error { constructor() { super(`Cannot parse a reference cycle that closes through a transform`); this.name = "ZodCyclicError"; } }; /** Keyed off the context object every schema in one parse call already shares. */ var STATE = "~memo"; var NO_ISSUES = []; function isRef(value) { return value !== null && typeof value === "object"; } function cloneIssues(issues) { return issues.map((iss) => iss.path ? { ...iss, path: iss.path.slice() } : { ...iss }); } var recursive = /*@__PURE__*/ new WeakMap(); /** What the walk established, in order of certainty: ordered so the strongest answer among children wins. */ var NONE = 0; var ASSUMED = 1; var PROVEN = 2; /** Whether this schema's subtree contains a cycle, so one parse can re-enter it. */ function isRecursive(inst, stack, resolve) { const cached = recursive.get(inst); if (cached !== void 0) return cached ? PROVEN : NONE; if (stack.has(inst)) return PROVEN; stack.add(inst); let result = NONE; const check = (child) => { if (result !== PROVEN && child?._zod) { const answer = isRecursive(child, stack, resolve); if (answer > result) result = answer; } }; const shape = (sh, spread) => { let answer = NONE; for (const key of Reflect.ownKeys(sh)) { const desc = Object.getOwnPropertyDescriptor(sh, key); if (spread && !desc.enumerable) continue; const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve) : NONE; if (child > answer) answer = child; } return answer; }; const merge = (answer) => { if (answer > result) result = answer; }; const def = inst._zod.def; switch (def.type) { case "object": { const raw = rawShape(def); merge(raw ? shape(raw, true) : ASSUMED); check(def.catchall); break; } case "array": check(def.element); break; case "tuple": for (const el of def.items) check(el); check(def.rest); break; case "record": case "map": check(def.keyType); check(def.valueType); break; case "set": check(def.valueType); break; case "union": for (const el of def.options) check(el); break; case "intersection": check(def.left); check(def.right); break; case "optional": case "nullable": case "default": case "prefault": case "catch": case "readonly": case "nonoptional": case "promise": case "success": check(def.innerType); break; case "pipe": check(def.in); check(def.out); break; case "function": check(def.input); check(def.output); break; case "lazy": { const inner = def._cachedInner ?? (resolve ? inst._zod.innerType : void 0); merge(inner ? isRecursive(inner, stack, false) : ASSUMED); break; } case "template_literal": case "string": case "number": case "int": case "boolean": case "bigint": case "symbol": case "undefined": case "null": case "void": case "never": case "any": case "unknown": case "date": case "nan": case "enum": case "literal": case "file": case "transform": case "custom": break; default: for (const key in def) { const desc = Object.getOwnPropertyDescriptor(def, key); if (!desc || desc.get) continue; const value = desc.value; if (!value || typeof value !== "object") continue; if (value._zod) check(value); else if (Array.isArray(value)) for (const el of value) check(el); } } stack.delete(inst); return settle(inst, result); } /** An assumed answer must not outlive the resolution that settles it, so only a certain one is cached. */ function settle(inst, answer) { if (answer !== ASSUMED) recursive.set(inst, answer === PROVEN); return answer; } function bucketFor(state, inst) { let bucket = state.buckets.get(inst); if (!bucket) { bucket = /* @__PURE__ */ new WeakMap(); state.buckets.set(inst, bucket); } return bucket; } var handoff; var open = []; var memo = { alloc(_inst, payload, empty) { const bucket = handoff; if (!bucket) return empty; handoff = void 0; const entry = { value: empty, issues: null }; bucket.set(payload.value, entry); open.push(entry); return empty; }, guard(inst) { var _a; (_a = inst._zod).deferred ?? (_a.deferred = []); inst._zod.deferred.push(() => { const base = inst._zod.parse; const wrapped = (payload, ctx) => { if (ctx.direction !== "backward" && isBackEdge(ctx, payload.value)) throw new $ZodCyclicError(); return base(payload, ctx); }; inst._zod.parse = wrapped; if (inst._zod.run === base) inst._zod.run = wrapped; }); }, attach(inst) { var _a; let isRecursiveInst; let rechecked = false; let lastCtx; let lastBucket; (_a = inst._zod).deferred ?? (_a.deferred = []); inst._zod.deferred.push(() => { const base = inst._zod.parse; const wrapped = (payload, ctx) => { if (isRecursiveInst === void 0) { const walked = isRecursive(inst, /* @__PURE__ */ new Set(), false); if (walked === NONE) { inst._zod.parse = base; if (inst._zod.run === wrapped) inst._zod.run = base; return base(payload, ctx); } if (walked === PROVEN || rechecked) isRecursiveInst = true; else rechecked = true; } const input = payload.value; if (!isRef(input)) return base(payload, ctx); let state = ctx[STATE]; if (!state) { state = { buckets: /* @__PURE__ */ new WeakMap(), backEdges: void 0 }; ctx[STATE] = state; } let bucket; if (lastCtx === ctx) bucket = lastBucket; else { bucket = bucketFor(state, inst); lastCtx = ctx; lastBucket = bucket; } const hit = bucket.get(input); if (hit) { payload.value = hit.value; if (hit.issues) { if (hit.issues.length) payload.issues.push(...cloneIssues(hit.issues)); } else { payload.memo = true; state.backEdges ?? (state.backEdges = /* @__PURE__ */ new WeakSet()); state.backEdges.add(hit.value); } return payload; } handoff = bucket; const depth = open.length; const result = base(payload, ctx); handoff = void 0; const entry = open.length > depth ? open.pop() : void 0; if (result instanceof Promise) return result.then((r) => { if (entry) entry.issues = r.issues.length ? cloneIssues(r.issues) : NO_ISSUES; return r; }); if (entry) entry.issues = result.issues.length ? cloneIssues(result.issues) : NO_ISSUES; return result; }; inst._zod.parse = wrapped; if (inst._zod.run === base) inst._zod.run = wrapped; }); } }; /** The memoizer that gives containers cycle support. `zod` installs it by default; `zod/mini` opts in with `config({ memoizer: memoizer() })`. */ function memoizer() { return memo; } /** Whether this value is a node a back-edge resolved to before it finished. */ function isBackEdge(ctx, value) { const backEdges = ctx[STATE]?.backEdges; return backEdges !== void 0 && isRef(value) && backEdges.has(value); } //#endregion //#region node_modules/zod/v4/locales/en.js var error = () => { const Sizable = { string: { unit: "characters", verb: "to have" }, file: { unit: "bytes", verb: "to have" }, array: { unit: "items", verb: "to have" }, set: { unit: "items", verb: "to have" }, map: { unit: "entries", verb: "to have" } }; function getSizing(origin) { return Sizable[origin] ?? null; } const FormatDictionary = { regex: "input", email: "email address", url: "URL", emoji: "emoji", uuid: "UUID", uuidv4: "UUIDv4", uuidv6: "UUIDv6", nanoid: "nanoid", guid: "GUID", cuid: "cuid", cuid2: "cuid2", ulid: "ULID", xid: "XID", ksuid: "KSUID", datetime: "ISO datetime", date: "ISO date", time: "ISO time", duration: "ISO duration", ipv4: "IPv4 address", ipv6: "IPv6 address", mac: "MAC address", cidrv4: "IPv4 range", cidrv6: "IPv6 range", base64: "base64-encoded string", base64url: "base64url-encoded string", json_string: "JSON string", e164: "E.164 number", currency_code: "currency code", credit_card: "credit card number", iban: "IBAN", jwt: "JWT", template_literal: "input" }; const TypeDictionary = { nan: "NaN" }; function getTypeName(type, input) { if (type === "number" && typeof input === "number" && !Number.isFinite(input)) return String(input); return TypeDictionary[type] ?? type; } return (issue) => { switch (issue.code) { case "invalid_type": return `Invalid input: expected ${getTypeName(issue.expected)}, received ${getTypeName(parsedType(issue.input), issue.input)}`; case "invalid_value": if (issue.values.length === 1) return `Invalid input: expected ${stringifyPrimitive(issue.values[0])}`; return `Invalid option: expected one of ${joinValues(issue.values, "|")}`; case "too_big": { const adj = issue.exact ? "exactly " : issue.inclusive ? "<=" : "<"; const sizing = getSizing(issue.origin); if (sizing) return `Too big: expected ${issue.origin ?? "value"} to have ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elements"}`; return `Too big: expected ${issue.origin ?? "value"} to be ${adj}${issue.maximum.toString()}`; } case "too_small": { const adj = issue.exact ? "exactly " : issue.inclusive ? ">=" : ">"; const sizing = getSizing(issue.origin); if (sizing) return `Too small: expected ${issue.origin} to have ${adj}${issue.minimum.toString()} ${sizing.unit}`; return `Too small: expected ${issue.origin} to be ${adj}${issue.minimum.toString()}`; } case "invalid_format": { const _issue = issue; if (_issue.format === "starts_with") return `Invalid string: must start with "${_issue.prefix}"`; if (_issue.format === "ends_with") return `Invalid string: must end with "${_issue.suffix}"`; if (_issue.format === "includes") return `Invalid string: must include "${_issue.includes}"`; if (_issue.format === "regex") return `Invalid string: must match pattern ${_issue.pattern}`; return `Invalid ${FormatDictionary[_issue.format] ?? issue.format}`; } case "not_multiple_of": return `Invalid number: must be a multiple of ${issue.divisor}`; case "unrecognized_keys": return `Unrecognized key${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`; case "invalid_key": return `Invalid key in ${issue.origin}`; case "invalid_union": if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) return `Invalid discriminator value. Expected ${issue.options.map((o) => `'${o}'`).join(" | ")}`; if (issue.inclusive === false) return "Invalid input: more than one option matched"; return "Invalid input"; case "invalid_element": return `Invalid value in ${issue.origin}`; default: return `Invalid input`; } }; }; function en_default() { return { localeError: error() }; } //#endregion //#region node_modules/zod/v4/core/registries.js var _a$3; var $ZodRegistry = class { constructor() { this._map = /* @__PURE__ */ new WeakMap(); this._idmap = /* @__PURE__ */ new Map(); } add(schema, ..._meta) { const meta = _meta[0]; this._map.set(schema, meta); if (meta && typeof meta === "object" && "id" in meta) this._idmap.set(meta.id, schema); return this; } clear() { this._map = /* @__PURE__ */ new WeakMap(); this._idmap = /* @__PURE__ */ new Map(); return this; } remove(schema) { const meta = this._map.get(schema); if (meta && typeof meta === "object" && "id" in meta) this._idmap.delete(meta.id); this._map.delete(schema); return this; } get(schema) { const p = schema._zod.parent; if (p) { const pm = { ...this.get(p) ?? {} }; delete pm.id; const f = { ...pm, ...this._map.get(schema) }; return Object.keys(f).length ? f : void 0; } return this._map.get(schema); } has(schema) { return this._map.has(schema); } }; function registry() { return new $ZodRegistry(); } (_a$3 = globalThis).__zod_globalRegistry ?? (_a$3.__zod_globalRegistry = registry()); var globalRegistry = globalThis.__zod_globalRegistry; //#endregion //#region node_modules/zod/v4/core/api.js function snapshotChecks(def) { if (def.checks) def.checks = [...def.checks]; return def; } // @__NO_SIDE_EFFECTS__ function _string(Class, params) { return new Class(snapshotChecks({ type: "string", ...normalizeParams(params) })); } // @__NO_SIDE_EFFECTS__ function _email(Class, params) { return new Class({ type: "string", format: "email", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _guid(Class, params) { return new Class({ type: "string", format: "guid", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _uuid(Class, params) { return new Class({ type: "string", format: "uuid", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _uuidv4(Class, params) { return new Class({ type: "string", format: "uuid", check: "string_format", abort: false, version: "v4", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _uuidv6(Class, params) { return new Class({ type: "string", format: "uuid", check: "string_format", abort: false, version: "v6", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _uuidv7(Class, params) { return new Class({ type: "string", format: "uuid", check: "string_format", abort: false, version: "v7", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _url(Class, params) { return new Class({ type: "string", format: "url", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _emoji(Class, params) { return new Class({ type: "string", format: "emoji", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _nanoid(Class, params) { return new Class({ type: "string", format: "nanoid", check: "string_format", abort: false, ...normalizeParams(params) }); } /** * @deprecated CUID v1 is deprecated by its authors due to information leakage * (timestamps embedded in the id). Use {@link _cuid2} instead. * See https://github.com/paralleldrive/cuid. */ // @__NO_SIDE_EFFECTS__ function _cuid(Class, params) { return new Class({ type: "string", format: "cuid", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _cuid2(Class, params) { return new Class({ type: "string", format: "cuid2", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _ulid(Class, params) { return new Class({ type: "string", format: "ulid", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _xid(Class, params) { return new Class({ type: "string", format: "xid", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _ksuid(Class, params) { return new Class({ type: "string", format: "ksuid", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _ipv4(Class, params) { return new Class({ type: "string", format: "ipv4", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _ipv6(Class, params) { return new Class({ type: "string", format: "ipv6", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _cidrv4(Class, params) { return new Class({ type: "string", format: "cidrv4", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _cidrv6(Class, params) { return new Class({ type: "string", format: "cidrv6", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _base64(Class, params) { return new Class({ type: "string", format: "base64", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _base64url(Class, params) { return new Class({ type: "string", format: "base64url", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _e164(Class, params) { return new Class({ type: "string", format: "e164", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _jwt(Class, params) { return new Class({ type: "string", format: "jwt", check: "string_format", abort: false, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _isoDateTime(Class, params) { return new Class({ type: "string", format: "datetime", check: "string_format", offset: false, local: false, precision: null, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _isoDate(Class, params) { return new Class({ type: "string", format: "date", check: "string_format", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _isoTime(Class, params) { return new Class({ type: "string", format: "time", check: "string_format", precision: null, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _isoDuration(Class, params) { return new Class({ type: "string", format: "duration", check: "string_format", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _number(Class, params) { return new Class(snapshotChecks({ type: "number", checks: [], ...normalizeParams(params) })); } // @__NO_SIDE_EFFECTS__ function _int(Class, params) { return new Class({ type: "number", check: "number_format", abort: false, format: "safeint", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _boolean(Class, params) { return new Class({ type: "boolean", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _null$1(Class, params) { return new Class({ type: "null", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _any(Class) { return new Class({ type: "any" }); } // @__NO_SIDE_EFFECTS__ function _unknown(Class) { return new Class({ type: "unknown" }); } // @__NO_SIDE_EFFECTS__ function _never(Class, params) { return new Class({ type: "never", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _lt(value, params) { return new $ZodCheckLessThan({ check: "less_than", ...normalizeParams(params), value, inclusive: false }); } // @__NO_SIDE_EFFECTS__ function _lte(value, params) { return new $ZodCheckLessThan({ check: "less_than", ...normalizeParams(params), value, inclusive: true }); } // @__NO_SIDE_EFFECTS__ function _gt(value, params) { return new $ZodCheckGreaterThan({ check: "greater_than", ...normalizeParams(params), value, inclusive: false }); } // @__NO_SIDE_EFFECTS__ function _gte(value, params) { return new $ZodCheckGreaterThan({ check: "greater_than", ...normalizeParams(params), value, inclusive: true }); } // @__NO_SIDE_EFFECTS__ function _multipleOf(value, params) { return new $ZodCheckMultipleOf({ check: "multiple_of", ...normalizeParams(params), value }); } // @__NO_SIDE_EFFECTS__ function _maxLength(maximum, params) { return new $ZodCheckMaxLength({ check: "max_length", ...normalizeParams(params), maximum }); } // @__NO_SIDE_EFFECTS__ function _minLength(minimum, params) { return new $ZodCheckMinLength({ check: "min_length", ...normalizeParams(params), minimum }); } // @__NO_SIDE_EFFECTS__ function _length(length, params) { return new $ZodCheckLengthEquals({ check: "length_equals", ...normalizeParams(params), length }); } // @__NO_SIDE_EFFECTS__ function _regex(pattern, params) { return new $ZodCheckRegex({ check: "string_format", format: "regex", ...normalizeParams(params), pattern }); } // @__NO_SIDE_EFFECTS__ function _lowercase(params) { return new $ZodCheckLowerCase({ check: "string_format", format: "lowercase", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _uppercase(params) { return new $ZodCheckUpperCase({ check: "string_format", format: "uppercase", ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _includes(includes, params) { return new $ZodCheckIncludes({ check: "string_format", format: "includes", ...normalizeParams(params), includes }); } // @__NO_SIDE_EFFECTS__ function _startsWith(prefix, params) { return new $ZodCheckStartsWith({ check: "string_format", format: "starts_with", ...normalizeParams(params), prefix }); } // @__NO_SIDE_EFFECTS__ function _endsWith(suffix, params) { return new $ZodCheckEndsWith({ check: "string_format", format: "ends_with", ...normalizeParams(params), suffix }); } // @__NO_SIDE_EFFECTS__ function _properties(shape, params) { return new $ZodCheckProperties({ check: "properties", shape, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _overwrite(tx) { return new $ZodCheckOverwrite({ check: "overwrite", tx }); } // @__NO_SIDE_EFFECTS__ function _normalize(form) { return /* @__PURE__ */ _overwrite((input) => input.normalize(form)); } // @__NO_SIDE_EFFECTS__ function _trim() { return /* @__PURE__ */ _overwrite((input) => input.trim()); } // @__NO_SIDE_EFFECTS__ function _toLowerCase() { return /* @__PURE__ */ _overwrite((input) => input.toLowerCase()); } // @__NO_SIDE_EFFECTS__ function _toUpperCase() { return /* @__PURE__ */ _overwrite((input) => input.toUpperCase()); } // @__NO_SIDE_EFFECTS__ function _slugify() { return /* @__PURE__ */ _overwrite((input) => slugify(input)); } // @__NO_SIDE_EFFECTS__ function _array(Class, element, params) { return new Class({ type: "array", element, ...normalizeParams(params) }); } // @__NO_SIDE_EFFECTS__ function _custom(Class, fn, _params) { const norm = normalizeParams(_params); norm.abort ?? (norm.abort = true); return new Class({ type: "custom", check: "custom", fn, ...norm }); } // @__NO_SIDE_EFFECTS__ function _refine(Class, fn, _params) { return new Class({ type: "custom", check: "custom", fn, ...normalizeParams(_params) }); } // @__NO_SIDE_EFFECTS__ function _superRefine(fn, params) { const ch = /* @__PURE__ */ _check((payload) => { payload.addIssue = (issue$2) => { if (typeof issue$2 === "string") payload.issues.push(issue(issue$2, payload.value, ch._zod.def)); else { const _issue = issue$2; if (_issue.fatal) _issue.continue = false; _issue.code ?? (_issue.code = "custom"); if (!("input" in _issue)) _issue.input = payload.value; _issue.inst ?? (_issue.inst = ch); _issue.continue ?? (_issue.continue = !ch._zod.def.abort); payload.issues.push(issue(_issue)); } }; return fn(payload.value, payload); }, params); return ch; } // @__NO_SIDE_EFFECTS__ function _check(fn, params) { const ch = new $ZodCheck({ check: "custom", ...normalizeParams(params) }); ch._zod.check = fn; return ch; } //#endregion //#region node_modules/zod/v4/core/to-json-schema.js function assignProps(target, ...sources) { for (const source of sources) for (const key of Reflect.ownKeys(source)) if (Object.prototype.propertyIsEnumerable.call(source, key)) assignProp(target, key, source[key]); return target; } function initializeContext(params) { let target = params?.target ?? "draft-2020-12"; if (target === "draft-4") target = "draft-04"; if (target === "draft-7") target = "draft-07"; return { processors: params.processors ?? {}, metadataRegistry: params?.metadata ?? globalRegistry, target, unrepresentable: params?.unrepresentable ?? "throw", override: params?.override ?? (() => {}), io: params?.io ?? "output", counter: 0, seen: /* @__PURE__ */ new Map(), sharedDefsExtractedFor: void 0, sharedEmitDoneFor: void 0, cycles: params?.cycles ?? "ref", reused: params?.reused ?? "inline", intersections: [], deferred: [], external: params?.external ?? void 0 }; } /** * Applies the `unrepresentable` setting at a site that has no JSON Schema equivalent. Throws * `message` unless the setting (or the handler's return value) says otherwise. Returns `true` if a * custom JSON Schema was written into `json`, in which case the caller must not write its own. */ function handleUnrepresentable(schema, ctx, json, params, message) { const result = typeof ctx.unrepresentable === "function" ? ctx.unrepresentable({ zodSchema: schema, path: params.path, message }) : ctx.unrepresentable; if (result === "any") return false; if (result === void 0 || result === "throw") throw new Error(message); Object.assign(json, result); return true; } function processSchema(schema, ctx, _params = { path: [], schemaPath: [] }) { var _a; const def = schema._zod.def; const seen = ctx.seen.get(schema); if (seen) { seen.count++; if (_params.schemaPath.includes(schema)) seen.cycle = _params.path; return seen.schema; } const result = { schema: {}, count: 1, cycle: void 0, path: _params.path }; ctx.seen.set(schema, result); ctx.sharedDefsExtractedFor = void 0; ctx.sharedEmitDoneFor = void 0; const overrideSchema = schema._zod.toJSONSchema?.(); if (overrideSchema) result.schema = overrideSchema; else { const params = { ..._params, schemaPath: [..._params.schemaPath, schema], path: _params.path }; if (schema._zod.processJSONSchema) schema._zod.processJSONSchema(ctx, result.schema, params); else { const _json = result.schema; const processor = ctx.processors[def.type]; if (!processor) throw new Error(`[toJSONSchema]: Non-representable type encountered: ${def.type}`); processor(schema, ctx, _json, params); } const parent = schema._zod.parent; if (parent) { if (!result.ref) result.ref = parent; processSchema(parent, ctx, params); ctx.seen.get(parent).isParent = true; } } const meta = ctx.metadataRegistry.get(schema); if (meta) assignProps(result.schema, meta); if (ctx.io === "input" && isTransforming(schema)) { delete result.schema.examples; delete result.schema.default; } if (ctx.io === "input" && "_prefault" in result.schema) (_a = result.schema).default ?? (_a.default = result.schema._prefault); delete result.schema._prefault; return ctx.seen.get(schema).schema; } function encodeJSONPointerSegment(segment) { return segment.replace(/~/g, "~0").replace(/\//g, "~1"); } function extractDefs(ctx, schema) { const root = ctx.seen.get(schema); if (!root) throw new Error("Unprocessed schema. This is a bug in Zod."); if (ctx.external && ctx.sharedDefsExtractedFor === ctx.external) return; const idToSchema = /* @__PURE__ */ new Map(); for (const entry of ctx.seen.entries()) { const id = ctx.metadataRegistry.get(entry[0])?.id; if (id) { const existing = idToSchema.get(id); if (existing && existing !== entry[0]) throw new Error(`Duplicate schema id "${id}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`); idToSchema.set(id, entry[0]); } } const makeURI = (entry) => { const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions"; if (ctx.external) { const externalId = ctx.external.registry.get(entry[0])?.id; const uriGenerator = ctx.external.uri ?? ((id) => id); if (externalId) return { ref: uriGenerator(externalId) }; const id = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`; entry[1].defId = id; return { defId: id, ref: `${uriGenerator("__shared")}#/${defsSegment}/${encodeJSONPointerSegment(id)}` }; } const uriPrefix = `#`; const defUriPrefix = `${uriPrefix}/${defsSegment}/`; if (entry[1] === root && !entry[1].schema.id) return { ref: uriPrefix }; const defId = entry[1].schema.id ?? `__schema${ctx.counter++}`; return { defId, ref: defUriPrefix + encodeJSONPointerSegment(defId) }; }; const extractToDef = (entry) => { if (entry[1].schema.$ref) return; const seen = entry[1]; const { ref, defId } = makeURI(entry); seen.def = { ...seen.schema }; if (defId) seen.defId = defId; const schema = seen.schema; for (const key in schema) delete schema[key]; schema.$ref = ref; }; if (ctx.cycles === "throw") for (const entry of ctx.seen.entries()) { const seen = entry[1]; if (seen.cycle) throw new Error(`Cycle detected: #/${seen.cycle?.join("/")}/ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`); } for (const entry of ctx.seen.entries()) { const seen = entry[1]; if (schema === entry[0]) { extractToDef(entry); continue; } if (ctx.external) { const ext = ctx.external.registry.get(entry[0])?.id; if (schema !== entry[0] && ext) { extractToDef(entry); continue; } } if (ctx.metadataRegistry.get(entry[0])?.id) { extractToDef(entry); continue; } if (seen.cycle) { extractToDef(entry); continue; } if (seen.count > 1) { if (ctx.reused === "ref") extractToDef(entry); } } if (ctx.external) ctx.sharedDefsExtractedFor = ctx.external; } /** Rewrites `anyOf: [{type: "a"}, {type: "b"}]` to `type: ["a", "b"]`, which every JSON Schema draft treats as equivalent and most consumers render far better for the nullable case. Only branches that are a bare type assertion qualify — anything carrying a constraint, `$ref`, `const` or metadata is left alone. Runs after `flattenRef`, so a branch an override decorated or `$defs` extraction turned into a `$ref` is no longer bare and correctly stays in `anyOf`. `oneOf` is excluded: `integer` and `number` overlap, so "exactly one" and "at least one" are not the same there. OpenAPI 3.0 is excluded: its `type` must be a single string. */ function compactTypeUnion(schema) { const options = schema.anyOf; if (!Array.isArray(options) || options.length === 0 || schema.type !== void 0) return; const types = []; for (const option of options) { if (!option || typeof option !== "object") return; compactTypeUnion(option); const keys = Object.keys(option); if (keys.length !== 1 || keys[0] !== "type") return; const type = option.type; for (const member of Array.isArray(type) ? type : [type]) { if (typeof member !== "string") return; if (!types.includes(member)) types.push(member); } } delete schema.anyOf; schema.type = types.length === 1 ? types[0] : types; } /** Keywords `foldIntersection` knows how to combine. Anything else — `$ref`, `patternProperties`, * an annotation like `description` — makes a member unfoldable, so a constraint this does not * understand leaves the `allOf` alone instead of being silently dropped or misattributed. */ var FOLDABLE_KEYS = /* @__PURE__ */ new Set([ "type", "properties", "required", "additionalProperties" ]); var UNION_KEYS = ["oneOf", "anyOf"]; /** A member's constraint on a key it does not declare itself. A `catchall` states one; `false`, an absent `additionalProperties`, and the empty schema a loose object emits state nothing. */ function undeclaredConstraint(member) { const extra = member.additionalProperties; if (extra === void 0 || extra === false || typeof extra !== "object" || extra === null) return null; return Object.keys(extra).length ? extra : null; } /** Combines object members into the single object they describe together, or returns `null` if any of them carries a keyword outside {@link FOLDABLE_KEYS}. */ function foldObjects(members) { const objects = []; for (const member of members) { if (typeof member !== "object" || member.type !== "object") return null; for (const key in member) if (!FOLDABLE_KEYS.has(key)) return null; objects.push(member); } const properties = {}; const required = /* @__PURE__ */ new Set(); for (const object of objects) { for (const key in object.properties) { if (Object.prototype.hasOwnProperty.call(properties, key)) continue; const parts = []; for (const other of objects) { const part = other.properties?.[key] ?? undeclaredConstraint(other); if (part === null || part === void 0) continue; if (!parts.some((seen) => JSON.stringify(seen) === JSON.stringify(part))) parts.push(part); } assignProp(properties, key, parts.length === 1 ? parts[0] : foldObjects(parts) ?? { allOf: parts }); } for (const key of object.required ?? []) required.add(key); } const folded = { type: "object", properties }; if (required.size) folded.required = [...required]; if (objects.every((object) => object.additionalProperties === false)) folded.additionalProperties = false; else { const constraints = []; for (const object of objects) { const constraint = undeclaredConstraint(object); if (constraint && !constraints.some((seen) => JSON.stringify(seen) === JSON.stringify(constraint))) constraints.push(constraint); } if (constraints.length === 1) folded.additionalProperties = constraints[0]; else if (constraints.length > 1) folded.additionalProperties = { allOf: constraints }; } return folded; } /** `additionalProperties` in an `allOf` member sees only that member's own `properties`, so two * closed object members reject each other's keys and the schema validates nothing. Zod's parser * pools the key sets instead — `handleIntersectionResults` reports a key as unrecognized only when * *every* side rejects it — so the emitted schema has to pool them too, and folding the members * into one object is the encoding that says so on every target. * * This runs from `finalize`, after `extractDefs`, which is what keeps it clear of the `$ref` * machinery: a member extracted into `$defs` is already a `$ref` by now and declines to fold, so it * keeps its reference and its own closedness rather than being inlined as a stale copy. */ function foldIntersection(json) { const allOf = json.allOf; if (!Array.isArray(allOf) || allOf.length < 2) return; for (const key of FOLDABLE_KEYS) if (key in json) return; const unions = allOf.filter((m) => UNION_KEYS.some((k) => Array.isArray(m[k]))); let folded = null; if (!unions.length) folded = foldObjects(allOf); else { const union = unions[0]; const keyword = UNION_KEYS.find((k) => Array.isArray(union[k])); if (Object.keys(union).length !== 1) return; const rest = allOf.filter((m) => m !== union); const branches = union[keyword].map((branch) => foldObjects([...rest, branch])); if (branches.some((b) => !b)) return; folded = { [keyword]: branches }; } if (!folded) return; delete json.allOf; assignProps(json, folded); } function finalize(ctx, schema) { const root = ctx.seen.get(schema); if (!root) throw new Error("Unprocessed schema. This is a bug in Zod."); const flattenRef = (zodSchema) => { const seen = ctx.seen.get(zodSchema); if (seen.ref === null) return; const schema = seen.def ?? seen.schema; const _cached = { ...schema }; const ref = seen.ref; seen.ref = null; if (ref) { flattenRef(ref); const refSeen = ctx.seen.get(ref); const refSchema = refSeen.schema; if (refSchema.$ref && (ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0")) { schema.allOf = schema.allOf ?? []; schema.allOf.push(refSchema); } else assignProps(schema, refSchema); assignProps(schema, _cached); if (zodSchema._zod.parent === ref) for (const key in schema) { if (key === "$ref" || key === "allOf") continue; if (!(key in _cached)) delete schema[key]; } if (refSchema.$ref && refSeen.def) for (const key in schema) { if (key === "$ref" || key === "allOf") continue; if (key in refSeen.def && JSON.stringify(schema[key]) === JSON.stringify(refSeen.def[key])) delete schema[key]; } } const parent = zodSchema._zod.parent; if (parent && parent !== ref) { flattenRef(parent); const parentSeen = ctx.seen.get(parent); if (parentSeen?.schema.$ref) { schema.$ref = parentSeen.schema.$ref; if (parentSeen.def) for (const key in schema) { if (key === "$ref" || key === "allOf") continue; if (key in parentSeen.def && JSON.stringify(schema[key]) === JSON.stringify(parentSeen.def[key])) delete schema[key]; } } } ctx.override({ zodSchema, jsonSchema: schema, path: seen.path ?? [] }); }; if (!ctx.external || ctx.sharedEmitDoneFor !== ctx.external) { for (const entry of [...ctx.seen.entries()].reverse()) flattenRef(entry[0]); if (ctx.target !== "openapi-3.0") for (const entry of ctx.seen.entries()) compactTypeUnion(entry[1].def ?? entry[1].schema); for (const rewrite of ctx.deferred) rewrite(); if (ctx.intersections.length) { const carriers = /* @__PURE__ */ new Map(); for (const seen of ctx.seen.values()) for (const json of [seen.schema, seen.def]) { const allOf = json?.allOf; if (!Array.isArray(allOf)) continue; const existing = carriers.get(allOf); if (existing) existing.push(json); else carriers.set(allOf, [json]); } for (const allOf of ctx.intersections) for (const json of carriers.get(allOf) ?? []) foldIntersection(json); } } const result = {}; if (ctx.target === "draft-2020-12") result.$schema = "https://json-schema.org/draft/2020-12/schema"; else if (ctx.target === "draft-07") result.$schema = "http://json-schema.org/draft-07/schema#"; else if (ctx.target === "draft-04") result.$schema = "http://json-schema.org/draft-04/schema#"; else if (ctx.target === "openapi-3.0") {} if (ctx.external?.uri) { const id = ctx.external.registry.get(schema)?.id; if (!id) throw new Error("Schema is missing an `id` property"); result.$id = ctx.external.uri(id); } assignProps(result, root.defId ? root.schema : root.def ?? root.schema); const rootMetaId = ctx.metadataRegistry.get(schema)?.id; if (rootMetaId !== void 0 && result.id === rootMetaId) delete result.id; const defs = ctx.external?.defs ?? {}; if (!ctx.external || ctx.sharedEmitDoneFor !== ctx.external) for (const entry of ctx.seen.entries()) { const seen = entry[1]; if (seen.def && seen.defId) { if (seen.def.id === seen.defId) delete seen.def.id; assignProp(defs, seen.defId, seen.def); } } if (ctx.external) ctx.sharedEmitDoneFor = ctx.external; if (ctx.external) {} else if (Object.keys(defs).length > 0) { if (ctx.target === "draft-2020-12") result.$defs = defs; else result.definitions = defs; } try { const finalized = JSON.parse(JSON.stringify(result)); Object.defineProperty(finalized, "~standard", { value: { ...schema["~standard"], jsonSchema: { input: createStandardJSONSchemaMethod(schema, "input", ctx.processors), output: createStandardJSONSchemaMethod(schema, "output", ctx.processors) } }, enumerable: false, writable: false }); return finalized; } catch (_err) { throw new Error("Error converting schema to JSON."); } } function isTransforming(_schema, _ctx) { const ctx = _ctx ?? { seen: /* @__PURE__ */ new Set() }; if (ctx.seen.has(_schema)) return false; ctx.seen.add(_schema); const def = _schema._zod.def; if (def.type === "transform") return true; if (def.type === "array") return isTransforming(def.element, ctx); if (def.type === "set") return isTransforming(def.valueType, ctx); if (def.type === "lazy") return isTransforming(def.getter(), ctx); if (def.type === "promise" || def.type === "optional" || def.type === "nonoptional" || def.type === "nullable" || def.type === "readonly" || def.type === "default" || def.type === "prefault" || def.type === "catch") return isTransforming(def.innerType, ctx); if (def.type === "intersection") return isTransforming(def.left, ctx) || isTransforming(def.right, ctx); if (def.type === "record" || def.type === "map") return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx); if (def.type === "pipe") { if (_schema._zod.traits.has("$ZodCodec")) return true; return isTransforming(def.in, ctx) || isTransforming(def.out, ctx); } if (def.type === "object") { for (const key in def.shape) if (isTransforming(def.shape[key], ctx)) return true; return false; } if (def.type === "union") { for (const option of def.options) if (isTransforming(option, ctx)) return true; return false; } if (def.type === "tuple") { for (const item of def.items) if (isTransforming(item, ctx)) return true; if (def.rest && isTransforming(def.rest, ctx)) return true; return false; } return false; } /** * Creates a toJSONSchema method for a schema instance. * This encapsulates the logic of initializing context, processing, extracting defs, and finalizing. */ var createToJSONSchemaMethod = (schema, processors = {}) => (params) => { const ctx = initializeContext({ ...params, processors }); processSchema(schema, ctx); extractDefs(ctx, schema); return finalize(ctx, schema); }; var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => { const { libraryOptions, target } = params ?? {}; const ctx = initializeContext({ ...libraryOptions ?? {}, target, io, processors }); processSchema(schema, ctx); extractDefs(ctx, schema); return finalize(ctx, schema); }; //#endregion //#region node_modules/zod/v4/core/json-schema-processors.js var narrowMin = (agg, key, value) => { if (agg[key] === void 0 || value > agg[key]) agg[key] = value; }; var narrowMax = (agg, key, value) => { if (agg[key] === void 0 || value < agg[key]) agg[key] = value; }; var narrowBoth = (agg, value) => { narrowMin(agg, "minimum", value); narrowMax(agg, "maximum", value); }; var addDivisor = (agg, value) => { agg.multipleOf ?? (agg.multipleOf = []); if (!agg.multipleOf.includes(value)) agg.multipleOf.push(value); }; var addPattern$1 = (agg, pattern) => { agg.patterns ?? (agg.patterns = /* @__PURE__ */ new Set()); agg.patterns.add(pattern); }; var intersectMime = (agg, mime) => { agg.mime = agg.mime ? agg.mime.filter((m) => mime.includes(m)) : [...mime]; }; var setFormat = (agg, format) => { agg.format = format; if (format.includes("int")) agg.isInt = true; }; var minContributor = (agg, def) => narrowMin(agg, "minimum", def.minimum); var maxContributor = (agg, def) => narrowMax(agg, "maximum", def.maximum); var formatContributor = (ranges) => (agg, def) => { setFormat(agg, def.format); const [minimum, maximum] = ranges[def.format]; narrowMin(agg, "minimum", minimum); narrowMax(agg, "maximum", maximum); }; var contributors = { greater_than: (agg, def) => narrowMin(agg, def.inclusive ? "minimum" : "exclusiveMinimum", def.value), less_than: (agg, def) => narrowMax(agg, def.inclusive ? "maximum" : "exclusiveMaximum", def.value), multiple_of: (agg, def) => addDivisor(agg, def.value), number_format: formatContributor(NUMBER_FORMAT_RANGES), bigint_format: formatContributor(BIGINT_FORMAT_RANGES), min_length: minContributor, max_length: maxContributor, length_equals: (agg, def) => narrowBoth(agg, def.length), min_size: minContributor, max_size: maxContributor, size_equals: (agg, def) => narrowBoth(agg, def.size), string_format: (agg, def) => { setFormat(agg, def.format); if (def.pattern) addPattern$1(agg, def.pattern); if (def.format === "base64" || def.format === "base64url") agg.contentEncoding = def.format; if (def.local || def.precision === -1) agg.laxFormat = true; }, mime_type: (agg, def) => intersectMime(agg, def.mime) }; function aggregateChecks(schema) { const agg = {}; const def = schema._zod.def; const list = schema._zod.traits.has("$ZodCheck") ? [schema, ...def.checks ?? []] : def.checks ?? []; for (const ch of list) contributors[ch._zod.def.check]?.(agg, ch._zod.def); const bag = schema._zod.bag; if (bag.minimum !== void 0) narrowMin(agg, "minimum", bag.minimum); if (bag.exclusiveMinimum !== void 0) narrowMin(agg, "exclusiveMinimum", bag.exclusiveMinimum); if (bag.maximum !== void 0) narrowMax(agg, "maximum", bag.maximum); if (bag.exclusiveMaximum !== void 0) narrowMax(agg, "exclusiveMaximum", bag.exclusiveMaximum); if (bag.multipleOf !== void 0) addDivisor(agg, bag.multipleOf); if (bag.format !== void 0) { agg.format ?? (agg.format = bag.format); if (bag.format.includes("int")) agg.isInt = true; } if (bag.mime) intersectMime(agg, bag.mime); for (const pattern of bag.patterns ?? []) addPattern$1(agg, pattern); return agg; } var formatMap = { guid: "uuid", url: "uri", datetime: "date-time", json_string: "json-string", regex: "" }; var exactPatterns = /* @__PURE__ */ new Map([[base64Charset, base64], [base64urlCharset, base64url]]); var exactPattern = (p) => exactPatterns.get(p) ?? p; var stringProcessor = (schema, ctx, _json, _params) => { const json = _json; json.type = "string"; const { minimum, maximum, format, patterns, contentEncoding, laxFormat } = aggregateChecks(schema); if (typeof minimum === "number") json.minLength = minimum; if (typeof maximum === "number") json.maxLength = maximum; if (format) { json.format = formatMap[format] ?? format; if (json.format === "") delete json.format; if (format === "time" || laxFormat) delete json.format; } if (contentEncoding) json.contentEncoding = contentEncoding; if (patterns && patterns.size > 0) { const patternList = [...patterns].map(exactPattern); if (patternList.length === 1) json.pattern = patternList[0].source; else if (patternList.length > 1) json.allOf = [...patternList.map((regex) => ({ ...ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0" ? { type: "string" } : {}, pattern: regex.source }))]; } }; var numberProcessor = (schema, ctx, _json, params) => { const json = _json; const { minimum, maximum, multipleOf, exclusiveMaximum, exclusiveMinimum, isInt } = aggregateChecks(schema); json.type = isInt ? "integer" : "number"; const exMin = typeof exclusiveMinimum === "number" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY); const exMax = typeof exclusiveMaximum === "number" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY); const legacy = ctx.target === "draft-04" || ctx.target === "openapi-3.0"; if (exMin) { if (legacy) { json.minimum = exclusiveMinimum; json.exclusiveMinimum = true; } else json.exclusiveMinimum = exclusiveMinimum; } else if (typeof minimum === "number") json.minimum = minimum; if (exMax) { if (legacy) { json.maximum = exclusiveMaximum; json.exclusiveMaximum = true; } else json.exclusiveMaximum = exclusiveMaximum; } else if (typeof maximum === "number") json.maximum = maximum; if (multipleOf) { const divisors = /* @__PURE__ */ new Set(); for (const divisor of multipleOf) if (Number.isFinite(divisor) && divisor !== 0) divisors.add(Math.abs(divisor)); else handleUnrepresentable(schema, ctx, json, params, `A multipleOf divisor of ${divisor} cannot be represented in JSON Schema`); const [first, ...rest] = divisors; if (first !== void 0) json.multipleOf = first; if (rest.length) json.allOf = [...json.allOf ?? [], ...rest.map((m) => ({ multipleOf: m }))]; } }; var booleanProcessor = (_schema, _ctx, json, _params) => { json.type = "boolean"; }; var bigintProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "BigInt cannot be represented in JSON Schema"); }; var symbolProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "Symbols cannot be represented in JSON Schema"); }; var nullProcessor = (_schema, ctx, json, _params) => { if (ctx.target === "openapi-3.0") { json.type = "string"; json.nullable = true; json.enum = [null]; } else json.type = "null"; }; var undefinedProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "Undefined cannot be represented in JSON Schema"); }; var voidProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "Void cannot be represented in JSON Schema"); }; var neverProcessor = (_schema, _ctx, json, _params) => { json.not = {}; }; var anyProcessor = (_schema, _ctx, _json, _params) => {}; var unknownProcessor = (_schema, _ctx, _json, _params) => {}; var dateProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "Date cannot be represented in JSON Schema"); }; var enumProcessor = (schema, _ctx, json, _params) => { const def = schema._zod.def; const values = getEnumValues(def.entries); if (values.length === 0) { json.not = {}; return; } if (values.every((v) => typeof v === "number")) json.type = "number"; if (values.every((v) => typeof v === "string")) json.type = "string"; json.enum = values; }; var literalProcessor = (schema, ctx, json, params) => { const def = schema._zod.def; if (def.values.length === 0) { json.not = {}; return; } const vals = []; for (const val of def.values) if (val === void 0) { if (handleUnrepresentable(schema, ctx, json, params, "Literal `undefined` cannot be represented in JSON Schema")) return; } else if (typeof val === "bigint") { if (handleUnrepresentable(schema, ctx, json, params, "BigInt literals cannot be represented in JSON Schema")) return; vals.push(Number(val)); } else vals.push(val); if (vals.length === 0) {} else if (vals.length === 1) { const val = vals[0]; json.type = val === null ? "null" : typeof val; if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") json.enum = [val]; else json.const = val; } else { if (vals.every((v) => typeof v === "number")) json.type = "number"; if (vals.every((v) => typeof v === "string")) json.type = "string"; if (vals.every((v) => typeof v === "boolean")) json.type = "boolean"; if (vals.every((v) => v === null)) json.type = "null"; json.enum = vals; } }; var nanProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "NaN cannot be represented in JSON Schema"); }; var templateLiteralProcessor = (schema, _ctx, json, _params) => { const _json = json; const pattern = schema._zod.pattern; if (!pattern) throw new Error("Pattern not found in template literal"); _json.type = "string"; _json.pattern = pattern.source; }; var fileProcessor = (schema, _ctx, json, _params) => { const _json = json; _json.type = "string"; _json.format = "binary"; _json.contentEncoding = "binary"; const { minimum, maximum, mime } = aggregateChecks(schema); if (minimum !== void 0) _json.minLength = minimum; if (maximum !== void 0) _json.maxLength = maximum; if (!mime) return; if (mime.length === 0) _json.not = {}; else if (mime.length === 1) _json.contentMediaType = mime[0]; else _json.anyOf = mime.map((m) => ({ contentMediaType: m })); }; var successProcessor = (_schema, _ctx, json, _params) => { json.type = "boolean"; }; var customProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "Custom types cannot be represented in JSON Schema"); }; var functionProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "Function types cannot be represented in JSON Schema"); }; var transformProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "Transforms cannot be represented in JSON Schema"); }; var mapProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "Map cannot be represented in JSON Schema"); }; var setProcessor = (schema, ctx, json, params) => { handleUnrepresentable(schema, ctx, json, params, "Set cannot be represented in JSON Schema"); }; var arrayProcessor = (schema, ctx, _json, params) => { const json = _json; const def = schema._zod.def; const { minimum, maximum } = aggregateChecks(schema); if (typeof minimum === "number") json.minItems = minimum; if (typeof maximum === "number") json.maxItems = maximum; json.type = "array"; json.items = processSchema(def.element, ctx, { ...params, path: [...params.path, "items"] }); }; function inputOptin(schema) { const def = schema._zod.def; if (def.type === "pipe" && def.in._zod.traits.has("$ZodTransform")) return inputOptin(def.out); if (def.type === "catch") return inputOptin(def.innerType); return schema._zod.optin; } var objectProcessor = (schema, ctx, _json, params) => { const json = _json; const def = schema._zod.def; const shape = def.shape; if (Object.getOwnPropertySymbols(shape).length && handleUnrepresentable(schema, ctx, json, params, "Symbol keys cannot be represented in JSON Schema")) return; json.type = "object"; json.properties = {}; for (const key in shape) assignProp(json.properties, key, processSchema(shape[key], ctx, { ...params, path: [ ...params.path, "properties", key ] })); const requiredKeys = []; for (const key of Object.keys(shape)) { const field = def.shape[key]; if (ctx.io === "input" ? inputOptin(field) === void 0 : field._zod.optout === void 0) requiredKeys.push(key); } if (requiredKeys.length > 0) json.required = requiredKeys; if (def.catchall?._zod.def.type === "never") json.additionalProperties = false; else if (!def.catchall) { if (ctx.io === "output") json.additionalProperties = false; } else if (def.catchall) json.additionalProperties = processSchema(def.catchall, ctx, { ...params, path: [...params.path, "additionalProperties"] }); }; var unionProcessor = (schema, ctx, json, params) => { const def = schema._zod.def; const isExclusive = def.inclusive === false; const options = def.options.map((x, i) => processSchema(x, ctx, { ...params, path: [ ...params.path, isExclusive ? "oneOf" : "anyOf", i ] })); if (isExclusive) json.oneOf = options; else json.anyOf = options; }; var intersectionProcessor = (schema, ctx, json, params) => { const def = schema._zod.def; const a = processSchema(def.left, ctx, { ...params, path: [ ...params.path, "allOf", 0 ] }); const b = processSchema(def.right, ctx, { ...params, path: [ ...params.path, "allOf", 1 ] }); const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1; const allOf = [...isSimpleIntersection(a) ? a.allOf : [a], ...isSimpleIntersection(b) ? b.allOf : [b]]; json.allOf = allOf; ctx.intersections.push(allOf); }; var tupleProcessor = (schema, ctx, _json, params) => { const json = _json; const def = schema._zod.def; json.type = "array"; const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items"; const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems"; const prefixItems = def.items.map((x, i) => processSchema(x, ctx, { ...params, path: [ ...params.path, prefixPath, i ] })); const rest = def.rest ? processSchema(def.rest, ctx, { ...params, path: [ ...params.path, restPath, ...ctx.target === "openapi-3.0" ? [def.items.length] : [] ] }) : null; let minItems = def.items.length; while (minItems > 0) { const item = def.items[minItems - 1]; if (!(ctx.io === "input" ? inputOptin(item) !== void 0 : item._zod.optout === "optional")) break; minItems--; } const maxItems = def.items.length; const isClosed = !def.rest; if (ctx.target === "draft-2020-12") { json.prefixItems = prefixItems; if (isClosed) json.items = false; else if (rest) json.items = rest; if (minItems > 0) json.minItems = minItems; if (isClosed) json.maxItems = maxItems; } else if (ctx.target === "openapi-3.0") { json.items = { anyOf: prefixItems }; if (rest) json.items.anyOf.push(rest); if (minItems > 0) json.minItems = minItems; if (isClosed) json.maxItems = maxItems; } else { json.items = prefixItems; if (isClosed) json.additionalItems = false; else if (rest) json.additionalItems = rest; if (minItems > 0) json.minItems = minItems; if (isClosed) json.maxItems = maxItems; } const { minimum, maximum } = aggregateChecks(schema); if (typeof minimum === "number") json.minItems = minimum; if (typeof maximum === "number") json.maxItems = maximum; }; /** JSON object keys are always strings, so a numeric record key schema is re-expressed over the * numeric-string form the record parser matches. Deferred to `finalize`, after the flatten: a key * behind a wrapper only carries its own `type` before then, and a union key only has its branches. * * A numeric bound cannot apply to a property name, so `minimum` and its siblings are dropped rather * than carried over: keeping them beside `type: "string"` reproduces the match-nothing schema this * exists to fix. A key that carries one therefore emits wider than the record parses — `z.record(z.number().min(5), V)` * accepts `"3"` — which is the deliberate trade, since throwing on it would reject an ordinary schema * outright. */ function stringifyKeyNames(bySchema, json, visited) { if (json.$ref) { if (visited.has(json)) return json; visited.add(json); const def = bySchema.get(json)?.def; if (!def) return json; const inlined = stringifyKeyNames(bySchema, def, visited); return inlined === def ? json : inlined; } for (const keyword of ["anyOf", "oneOf"]) { const branches = json[keyword]; if (!Array.isArray(branches)) continue; const mapped = branches.map((branch) => stringifyKeyNames(bySchema, branch, visited)); if (mapped.some((branch, i) => branch !== branches[i])) json = { ...json, [keyword]: mapped }; } const types = Array.isArray(json.type) ? json.type : [json.type]; const numericType = !types.includes("string") && types.some((t) => t === "number" || t === "integer"); const values = json.enum ?? (json.const !== void 0 ? [json.const] : void 0); if (!numericType && !values?.some((v) => typeof v === "number")) return json; const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } = json; if (rest.enum) rest.enum = rest.enum.map((v) => typeof v === "number" ? String(v) : v); else if (typeof rest.const === "number") rest.const = String(rest.const); if (!numericType) return rest; rest.type = "string"; if (!values) rest.pattern = (types.includes("number") ? number$1 : integer).source; return rest; } /** Every record of one conversion, so the carriers are found in a single pass rather than once per record. */ var pendingRecords = /* @__PURE__ */ new WeakMap(); function rewriteKeyNames(ctx) { const bySchema = /* @__PURE__ */ new Map(); for (const entry of ctx.seen.values()) if (entry.def && !bySchema.has(entry.schema)) bySchema.set(entry.schema, entry); const rewrites = /* @__PURE__ */ new Map(); for (const record of pendingRecords.get(ctx) ?? []) { const seen = ctx.seen.get(record); const names = (seen?.def ?? seen?.schema)?.propertyNames; if (!names || names === true || rewrites.has(names)) continue; const rewritten = stringifyKeyNames(bySchema, names, /* @__PURE__ */ new Set()); if (rewritten !== names) rewrites.set(names, rewritten); } if (!rewrites.size) return; for (const entry of ctx.seen.values()) for (const carrier of [entry.schema, entry.def]) { const rewritten = carrier && rewrites.get(carrier.propertyNames); if (rewritten) carrier.propertyNames = rewritten; } } var recordProcessor = (schema, ctx, _json, params) => { const json = _json; const def = schema._zod.def; json.type = "object"; const keyType = def.keyType; const patterns = aggregateChecks(keyType).patterns; if (def.mode === "loose" && patterns && patterns.size > 0) { const valueSchema = processSchema(def.valueType, ctx, { ...params, path: [ ...params.path, "patternProperties", "*" ] }); json.patternProperties = {}; for (const pattern of patterns) assignProp(json.patternProperties, exactPattern(pattern).source, valueSchema); } else { if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") { json.propertyNames = processSchema(def.keyType, ctx, { ...params, path: [...params.path, "propertyNames"] }); let pending = pendingRecords.get(ctx); if (!pending) { pending = []; pendingRecords.set(ctx, pending); ctx.deferred.push(() => rewriteKeyNames(ctx)); } pending.push(schema); } json.additionalProperties = processSchema(def.valueType, ctx, { ...params, path: [...params.path, "additionalProperties"] }); } const keyValues = keyType._zod.values; const omittableOnInput = ctx.io === "input" && inputOptin(def.valueType) !== void 0; if (keyValues && !def.partial && !omittableOnInput) { const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number"); if (validKeyValues.length > 0) json.required = validKeyValues.map(String); } }; var nullableProcessor = (schema, ctx, json, params) => { const def = schema._zod.def; const inner = processSchema(def.innerType, ctx, params); const seen = ctx.seen.get(schema); if (ctx.target === "openapi-3.0") { seen.ref = def.innerType; json.nullable = true; } else json.anyOf = [inner, { type: "null" }]; }; var nonoptionalProcessor = (schema, ctx, _json, params) => { const def = schema._zod.def; processSchema(def.innerType, ctx, params); const seen = ctx.seen.get(schema); seen.ref = def.innerType; }; /** Round-trips a default value through JSON so the emitted schema is guaranteed to be valid JSON. * A BigInt has no reliable encoding, so it goes through `unrepresentable` like any other * unrepresentable value. Returns a sentinel when the caller must not write a default of its own. */ var UNREPRESENTABLE_DEFAULT = Symbol(); function serializeDefaultValue(value, schema, ctx, json, params) { let unrepresentable = false; const serialized = JSON.stringify(value, (_, val) => { if (typeof val !== "bigint") return val; unrepresentable = true; return null; }); if (!unrepresentable) return JSON.parse(serialized); handleUnrepresentable(schema, ctx, json, params, "BigInt defaults cannot be represented in JSON Schema"); return UNREPRESENTABLE_DEFAULT; } var defaultProcessor = (schema, ctx, json, params) => { const def = schema._zod.def; processSchema(def.innerType, ctx, params); const seen = ctx.seen.get(schema); seen.ref = def.innerType; const value = serializeDefaultValue(def.defaultValue, schema, ctx, json, params); if (value !== UNREPRESENTABLE_DEFAULT) json.default = value; }; var prefaultProcessor = (schema, ctx, json, params) => { const def = schema._zod.def; processSchema(def.innerType, ctx, params); const seen = ctx.seen.get(schema); seen.ref = def.innerType; if (ctx.io !== "input") return; const value = serializeDefaultValue(def.defaultValue, schema, ctx, json, params); if (value !== UNREPRESENTABLE_DEFAULT) json._prefault = value; }; var catchProcessor = (schema, ctx, json, params) => { const def = schema._zod.def; processSchema(def.innerType, ctx, params); const seen = ctx.seen.get(schema); seen.ref = def.innerType; let catchValue; try { catchValue = def.catchValue(void 0); } catch { handleUnrepresentable(schema, ctx, json, params, "Dynamic catch values are not supported in JSON Schema"); return; } json.default = catchValue; }; var pipeProcessor = (schema, ctx, _json, params) => { const def = schema._zod.def; const inIsTransform = def.in._zod.traits.has("$ZodTransform"); const innerType = ctx.io === "input" ? inIsTransform ? def.out : def.in : def.out; processSchema(innerType, ctx, params); const seen = ctx.seen.get(schema); seen.ref = innerType; }; var readonlyProcessor = (schema, ctx, json, params) => { const def = schema._zod.def; processSchema(def.innerType, ctx, params); const seen = ctx.seen.get(schema); seen.ref = def.innerType; json.readOnly = true; }; var promiseProcessor = (schema, ctx, _json, params) => { const def = schema._zod.def; processSchema(def.innerType, ctx, params); const seen = ctx.seen.get(schema); seen.ref = def.innerType; }; var optionalProcessor = (schema, ctx, _json, params) => { const def = schema._zod.def; processSchema(def.innerType, ctx, params); const seen = ctx.seen.get(schema); seen.ref = def.innerType; }; var lazyProcessor = (schema, ctx, _json, params) => { const innerType = schema._zod.innerType; processSchema(innerType, ctx, params); const seen = ctx.seen.get(schema); seen.ref = innerType; }; var allProcessors = { string: stringProcessor, number: numberProcessor, boolean: booleanProcessor, bigint: bigintProcessor, symbol: symbolProcessor, null: nullProcessor, undefined: undefinedProcessor, void: voidProcessor, never: neverProcessor, any: anyProcessor, unknown: unknownProcessor, date: dateProcessor, enum: enumProcessor, literal: literalProcessor, nan: nanProcessor, template_literal: templateLiteralProcessor, file: fileProcessor, success: successProcessor, custom: customProcessor, function: functionProcessor, transform: transformProcessor, map: mapProcessor, set: setProcessor, array: arrayProcessor, object: objectProcessor, union: unionProcessor, intersection: intersectionProcessor, tuple: tupleProcessor, record: recordProcessor, nullable: nullableProcessor, nonoptional: nonoptionalProcessor, default: defaultProcessor, prefault: prefaultProcessor, catch: catchProcessor, pipe: pipeProcessor, readonly: readonlyProcessor, promise: promiseProcessor, optional: optionalProcessor, lazy: lazyProcessor }; function toJSONSchema(input, params) { if ("_idmap" in input) { const registry = input; const ctx = initializeContext({ ...params, processors: allProcessors }); const defs = {}; for (const entry of registry._idmap.entries()) { const [_, schema] = entry; processSchema(schema, ctx); } const schemas = {}; ctx.external = { registry, uri: params?.uri, defs }; for (const entry of registry._idmap.entries()) { const [key, schema] = entry; extractDefs(ctx, schema); assignProp(schemas, key, finalize(ctx, schema)); } if (Object.keys(defs).length > 0) schemas.__shared = { [ctx.target === "draft-2020-12" ? "$defs" : "definitions"]: defs }; return { schemas }; } const ctx = initializeContext({ ...params, processors: allProcessors }); processSchema(input, ctx); extractDefs(ctx, input); return finalize(ctx, input); } //#endregion //#region node_modules/zod/v4/classic/errors.js var _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]); function _lazyMethod(proto, key, make) { Object.defineProperty(proto, key, { configurable: true, enumerable: false, get() { const value = make(this); Object.defineProperty(this, key, { value, configurable: true, writable: true }); return value; }, set(value) { Object.defineProperty(this, key, { value, configurable: true, writable: true }); } }); } var initializer = (inst, issues) => { $ZodError.init(inst, issues); inst.name = "ZodError"; const proto = Object.getPrototypeOf(inst); if (_installedErrorProtos.has(proto)) return; _installedErrorProtos.add(proto); _lazyMethod(proto, "format", (self) => (mapper) => formatError(self, mapper)); _lazyMethod(proto, "flatten", (self) => (mapper) => flattenError(self, mapper)); _lazyMethod(proto, "addIssue", (self) => (issue) => { self.issues.push(issue); self.message = JSON.stringify(self.issues, jsonStringifyReplacer, 2); }); _lazyMethod(proto, "addIssues", (self) => (issues) => { self.issues.push(...issues); self.message = JSON.stringify(self.issues, jsonStringifyReplacer, 2); }); Object.defineProperty(proto, "isEmpty", { configurable: true, enumerable: false, get() { return this.issues.length === 0; } }); }; var ZodRealError = /*@__PURE__*/ $constructor("ZodError", initializer, void 0, { Parent: Error }); //#endregion //#region node_modules/zod/v4/classic/parse.js var parse = /* @__PURE__ */ _parse$1(ZodRealError); var parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError); var safeParse = /* @__PURE__ */ _safeParse(ZodRealError); var safeParseAsync = /* @__PURE__ */ _safeParseAsync(ZodRealError); var encode = /* @__PURE__ */ _encode(ZodRealError); var decode = /* @__PURE__ */ _decode(ZodRealError); var encodeAsync = /* @__PURE__ */ _encodeAsync(ZodRealError); var decodeAsync = /* @__PURE__ */ _decodeAsync(ZodRealError); var safeEncode = /* @__PURE__ */ _safeEncode(ZodRealError); var safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError); var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError); var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError); //#endregion //#region node_modules/zod/v4/classic/schemas.js function _ensureDefaultLocale() { if (!globalConfig.localeError) config(en_default()); } function _ensureDefaultMemoizer() { if (!globalConfig.memoizer) config({ memoizer: memoizer() }); } var ZodType = /*@__PURE__*/ $constructor("ZodType", (inst, def) => { _ensureDefaultLocale(); $ZodType.init(inst, def); inst.def = def; inst.type = def.type; return inst; }, { check(...chks) { const def = this.def; return this.clone(mergeDefs(def, { checks: [...def.checks ?? [], ...chks.map((ch) => typeof ch === "function" ? { _zod: { check: ch, def: { check: "custom" }, onattach: [] } } : ch)] }), { parent: true }); }, with(...chks) { return this.check(...chks); }, clone(def, params) { return clone(this, def, params); }, brand() { return this; }, register(reg, meta) { reg.add(this, meta); return this; }, refine(check, params) { return this.check(refine(check, params)); }, superRefine(refinement, params) { return this.check(superRefine(refinement, params)); }, overwrite(fn) { return this.check(/* @__PURE__ */ _overwrite(fn)); }, optional() { return optional(this); }, exactOptional() { return exactOptional(this); }, nullable() { return nullable(this); }, nullish() { return optional(nullable(this)); }, nonoptional(params) { return nonoptional(this, params); }, array() { return array(this); }, or(arg) { return union([this, arg]); }, and(arg) { return intersection(this, arg); }, transform(tx) { return pipe(this, transform(tx)); }, default(d) { return _default(this, d); }, prefault(d) { return prefault(this, d); }, catch(params) { return _catch(this, params); }, pipe(target) { return pipe(this, target); }, readonly() { return readonly(this); }, describe(description) { const cl = this.clone(); globalRegistry.add(cl, { description }); return cl; }, meta(...args) { if (args.length === 0) return globalRegistry.get(this); const cl = this.clone(); globalRegistry.add(cl, args[0]); return cl; }, isOptional() { return this.safeParse(void 0).success; }, isNullable() { return this.safeParse(null).success; }, apply(fn, ...args) { return args.length === 0 ? fn(this) : fn(this, ...args); }, get "~standard"() { return hide(this, "~standard", { ...standardProps(this), jsonSchema: { input: createStandardJSONSchemaMethod(this, "input"), output: createStandardJSONSchemaMethod(this, "output") } }); }, set "~standard"(value) { own(this, "~standard", value); }, parse: function _parse(data, params) { return parse(this, data, params, { callee: _parse }); }, parseAsync: async function _parseAsync(data, params) { return await parseAsync(this, data, params, { callee: _parseAsync }); }, safeParse(data, params) { return safeParse(this, data, params); }, async safeParseAsync(data, params) { return safeParseAsync(this, data, params); }, get spa() { return this?.safeParseAsync; }, set spa(value) { own(this, "spa", value); }, validate(data, params) { return validate(this, data, params); }, validateAsync(data, params) { return validateAsync$1(this, data, params); }, encode: function _encode(data, params) { return encode(this, data, params, { callee: _encode }); }, decode: function _decode(data, params) { return decode(this, data, params, { callee: _decode }); }, encodeAsync: async function _encodeAsync(data, params) { return await encodeAsync(this, data, params, { callee: _encodeAsync }); }, decodeAsync: async function _decodeAsync(data, params) { return await decodeAsync(this, data, params, { callee: _decodeAsync }); }, safeEncode(data, params) { return safeEncode(this, data, params); }, safeDecode(data, params) { return safeDecode(this, data, params); }, async safeEncodeAsync(data, params) { return safeEncodeAsync(this, data, params); }, async safeDecodeAsync(data, params) { return safeDecodeAsync(this, data, params); }, toJSONSchema(params) { return createToJSONSchemaMethod(this, {})(params); }, get description() { return globalRegistry.get(this)?.description; }, get _def() { return this._zod.def; } }); /** @internal */ var _ZodString = /*@__PURE__*/ $constructor("_ZodString", (inst, def) => { $ZodString.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => stringProcessor(inst, ctx, json, params); }, /*@__PURE__*/ derived({ format: (inst) => aggregateChecks(inst).format ?? null, minLength: (inst) => aggregateChecks(inst).minimum ?? null, maxLength: (inst) => aggregateChecks(inst).maximum ?? null }, { regex(...args) { return this.check(/* @__PURE__ */ _regex(...args)); }, includes(...args) { return this.check(/* @__PURE__ */ _includes(...args)); }, startsWith(...args) { return this.check(/* @__PURE__ */ _startsWith(...args)); }, endsWith(...args) { return this.check(/* @__PURE__ */ _endsWith(...args)); }, min(...args) { return this.check(/* @__PURE__ */ _minLength(...args)); }, max(...args) { return this.check(/* @__PURE__ */ _maxLength(...args)); }, length(...args) { return this.check(/* @__PURE__ */ _length(...args)); }, nonempty(...args) { return this.check(/* @__PURE__ */ _minLength(1, ...args)); }, lowercase(params) { return this.check(/* @__PURE__ */ _lowercase(params)); }, uppercase(params) { return this.check(/* @__PURE__ */ _uppercase(params)); }, trim() { return this.check(/* @__PURE__ */ _trim()); }, normalize(...args) { return this.check(/* @__PURE__ */ _normalize(...args)); }, toLowerCase() { return this.check(/* @__PURE__ */ _toLowerCase()); }, toUpperCase() { return this.check(/* @__PURE__ */ _toUpperCase()); }, slugify() { return this.check(/* @__PURE__ */ _slugify()); } })); var ZodString = /*@__PURE__*/ $constructor("ZodString", (inst, def) => { $ZodString.init(inst, def); _ZodString.init(inst, def); }, { email(params) { return this.check(/* @__PURE__ */ _email(ZodEmail, params)); }, url(params) { return this.check(/* @__PURE__ */ _url(ZodURL, params)); }, jwt(params) { return this.check(/* @__PURE__ */ _jwt(ZodJWT, params)); }, emoji(params) { return this.check(/* @__PURE__ */ _emoji(ZodEmoji, params)); }, guid(params) { return this.check(/* @__PURE__ */ _guid(ZodGUID, params)); }, uuid(params) { return this.check(/* @__PURE__ */ _uuid(ZodUUID, params)); }, uuidv4(params) { return this.check(/* @__PURE__ */ _uuidv4(ZodUUID, params)); }, uuidv6(params) { return this.check(/* @__PURE__ */ _uuidv6(ZodUUID, params)); }, uuidv7(params) { return this.check(/* @__PURE__ */ _uuidv7(ZodUUID, params)); }, nanoid(params) { return this.check(/* @__PURE__ */ _nanoid(ZodNanoID, params)); }, cuid(params) { return this.check(/* @__PURE__ */ _cuid(ZodCUID, params)); }, cuid2(params) { return this.check(/* @__PURE__ */ _cuid2(ZodCUID2, params)); }, ulid(params) { return this.check(/* @__PURE__ */ _ulid(ZodULID, params)); }, base64(params) { return this.check(/* @__PURE__ */ _base64(ZodBase64, params)); }, base64url(params) { return this.check(/* @__PURE__ */ _base64url(ZodBase64URL, params)); }, xid(params) { return this.check(/* @__PURE__ */ _xid(ZodXID, params)); }, ksuid(params) { return this.check(/* @__PURE__ */ _ksuid(ZodKSUID, params)); }, ipv4(params) { return this.check(/* @__PURE__ */ _ipv4(ZodIPv4, params)); }, ipv6(params) { return this.check(/* @__PURE__ */ _ipv6(ZodIPv6, params)); }, cidrv4(params) { return this.check(/* @__PURE__ */ _cidrv4(ZodCIDRv4, params)); }, cidrv6(params) { return this.check(/* @__PURE__ */ _cidrv6(ZodCIDRv6, params)); }, e164(params) { return this.check(/* @__PURE__ */ _e164(ZodE164, params)); }, datetime(params) { return this.check(/* @__PURE__ */ _isoDateTime(ZodISODateTime, params)); }, date(params) { return this.check(/* @__PURE__ */ _isoDate(ZodISODate, params)); }, time(params) { return this.check(/* @__PURE__ */ _isoTime(ZodISOTime, params)); }, duration(params) { return this.check(/* @__PURE__ */ _isoDuration(ZodISODuration, params)); } }); function string(params) { return /* @__PURE__ */ _string(ZodString, params); } var ZodStringFormat = /*@__PURE__*/ $constructor("ZodStringFormat", (inst, def) => { $ZodStringFormat.init(inst, def); _ZodString.init(inst, def); }); var ZodISODateTime = /*@__PURE__*/ $constructor("ZodISODateTime", (inst, def) => { $ZodISODateTime.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodISODate = /*@__PURE__*/ $constructor("ZodISODate", (inst, def) => { $ZodISODate.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodISOTime = /*@__PURE__*/ $constructor("ZodISOTime", (inst, def) => { $ZodISOTime.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodISODuration = /*@__PURE__*/ $constructor("ZodISODuration", (inst, def) => { $ZodISODuration.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodEmail = /*@__PURE__*/ $constructor("ZodEmail", (inst, def) => { $ZodEmail.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodGUID = /*@__PURE__*/ $constructor("ZodGUID", (inst, def) => { $ZodGUID.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodUUID = /*@__PURE__*/ $constructor("ZodUUID", (inst, def) => { $ZodUUID.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodURL = /*@__PURE__*/ $constructor("ZodURL", (inst, def) => { $ZodURL.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodEmoji = /*@__PURE__*/ $constructor("ZodEmoji", (inst, def) => { $ZodEmoji.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodNanoID = /*@__PURE__*/ $constructor("ZodNanoID", (inst, def) => { $ZodNanoID.init(inst, def); ZodStringFormat.init(inst, def); }); /** * @deprecated CUID v1 is deprecated by its authors due to information leakage * (timestamps embedded in the id). Use {@link ZodCUID2} instead. * See https://github.com/paralleldrive/cuid. */ var ZodCUID = /*@__PURE__*/ $constructor("ZodCUID", (inst, def) => { $ZodCUID.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodCUID2 = /*@__PURE__*/ $constructor("ZodCUID2", (inst, def) => { $ZodCUID2.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodULID = /*@__PURE__*/ $constructor("ZodULID", (inst, def) => { $ZodULID.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodXID = /*@__PURE__*/ $constructor("ZodXID", (inst, def) => { $ZodXID.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodKSUID = /*@__PURE__*/ $constructor("ZodKSUID", (inst, def) => { $ZodKSUID.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodIPv4 = /*@__PURE__*/ $constructor("ZodIPv4", (inst, def) => { $ZodIPv4.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodIPv6 = /*@__PURE__*/ $constructor("ZodIPv6", (inst, def) => { $ZodIPv6.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodCIDRv4 = /*@__PURE__*/ $constructor("ZodCIDRv4", (inst, def) => { $ZodCIDRv4.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodCIDRv6 = /*@__PURE__*/ $constructor("ZodCIDRv6", (inst, def) => { $ZodCIDRv6.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodBase64 = /*@__PURE__*/ $constructor("ZodBase64", (inst, def) => { $ZodBase64.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodBase64URL = /*@__PURE__*/ $constructor("ZodBase64URL", (inst, def) => { $ZodBase64URL.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodE164 = /*@__PURE__*/ $constructor("ZodE164", (inst, def) => { $ZodE164.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodJWT = /*@__PURE__*/ $constructor("ZodJWT", (inst, def) => { $ZodJWT.init(inst, def); ZodStringFormat.init(inst, def); }); var ZodNumber = /*@__PURE__*/ $constructor("ZodNumber", (inst, def) => { $ZodNumber.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => numberProcessor(inst, ctx, json, params); inst.isFinite = true; }, /*@__PURE__*/ derived({ minValue: (inst) => { const { minimum, exclusiveMinimum } = aggregateChecks(inst); return Math.max(minimum ?? Number.NEGATIVE_INFINITY, exclusiveMinimum ?? Number.NEGATIVE_INFINITY); }, maxValue: (inst) => { const { maximum, exclusiveMaximum } = aggregateChecks(inst); return Math.min(maximum ?? Number.POSITIVE_INFINITY, exclusiveMaximum ?? Number.POSITIVE_INFINITY); }, isInt: (inst) => { const { isInt, multipleOf } = aggregateChecks(inst); return !!isInt || !!multipleOf?.some(Number.isSafeInteger); }, format: (inst) => aggregateChecks(inst).format ?? null }, { gt(value, params) { return this.check(/* @__PURE__ */ _gt(value, params)); }, gte(value, params) { return this.check(/* @__PURE__ */ _gte(value, params)); }, min(value, params) { return this.check(/* @__PURE__ */ _gte(value, params)); }, lt(value, params) { return this.check(/* @__PURE__ */ _lt(value, params)); }, lte(value, params) { return this.check(/* @__PURE__ */ _lte(value, params)); }, max(value, params) { return this.check(/* @__PURE__ */ _lte(value, params)); }, int(params) { return this.check(int(params)); }, safe(params) { return this.check(int(params)); }, positive(params) { return this.check(/* @__PURE__ */ _gt(0, params)); }, nonnegative(params) { return this.check(/* @__PURE__ */ _gte(0, params)); }, negative(params) { return this.check(/* @__PURE__ */ _lt(0, params)); }, nonpositive(params) { return this.check(/* @__PURE__ */ _lte(0, params)); }, multipleOf(value, params) { return this.check(/* @__PURE__ */ _multipleOf(value, params)); }, step(value, params) { return this.check(/* @__PURE__ */ _multipleOf(value, params)); }, finite() { return this; } })); function number(params) { return /* @__PURE__ */ _number(ZodNumber, params); } var ZodNumberFormat = /*@__PURE__*/ $constructor("ZodNumberFormat", (inst, def) => { $ZodNumberFormat.init(inst, def); ZodNumber.init(inst, def); }); function int(params) { return /* @__PURE__ */ _int(ZodNumberFormat, params); } var ZodBoolean = /*@__PURE__*/ $constructor("ZodBoolean", (inst, def) => { $ZodBoolean.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => booleanProcessor(inst, ctx, json, params); }); function boolean(params) { return /* @__PURE__ */ _boolean(ZodBoolean, params); } var ZodNull = /*@__PURE__*/ $constructor("ZodNull", (inst, def) => { $ZodNull.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => nullProcessor(inst, ctx, json, params); }); function _null(params) { return /* @__PURE__ */ _null$1(ZodNull, params); } var ZodAny = /*@__PURE__*/ $constructor("ZodAny", (inst, def) => { $ZodAny.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => void 0; }); function any() { return /* @__PURE__ */ _any(ZodAny); } var ZodUnknown = /*@__PURE__*/ $constructor("ZodUnknown", (inst, def) => { $ZodUnknown.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => void 0; }); function unknown() { return /* @__PURE__ */ _unknown(ZodUnknown); } var ZodNever = /*@__PURE__*/ $constructor("ZodNever", (inst, def) => { $ZodNever.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => neverProcessor(inst, ctx, json, params); }); function never(params) { return /* @__PURE__ */ _never(ZodNever, params); } var ZodArray = /*@__PURE__*/ $constructor("ZodArray", (inst, def) => { _ensureDefaultMemoizer(); $ZodArray.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => arrayProcessor(inst, ctx, json, params); inst.element = def.element; }, { min(n, params) { return this.check(/* @__PURE__ */ _minLength(n, params)); }, nonempty(params) { return this.check(/* @__PURE__ */ _minLength(1, params)); }, max(n, params) { return this.check(/* @__PURE__ */ _maxLength(n, params)); }, length(n, params) { return this.check(/* @__PURE__ */ _length(n, params)); }, unwrap() { return this.element; } }); function array(element, params) { return /* @__PURE__ */ _array(ZodArray, element, params); } var ZodObject = /*@__PURE__*/ $constructor("ZodObject", (inst, def) => { _ensureDefaultMemoizer(); $ZodObjectJIT.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => objectProcessor(inst, ctx, json, params); installLazyProp(inst, "shape", (self) => self._zod.def.shape, false); }, { keyof() { return _enum(Object.keys(this._zod.def.shape)); }, catchall(catchall) { return this.clone(mergeDefs(this._zod.def, { catchall })); }, passthrough() { return this.clone(mergeDefs(this._zod.def, { catchall: unknown() })); }, loose() { return this.clone(mergeDefs(this._zod.def, { catchall: unknown() })); }, strict() { return this.clone(mergeDefs(this._zod.def, { catchall: never() })); }, strip() { return this.clone(mergeDefs(this._zod.def, { catchall: void 0 })); }, extend(incoming) { return extend(this, incoming); }, safeExtend(incoming) { return safeExtend(this, incoming); }, merge(other) { return merge(this, other); }, pick(mask) { return pick(this, mask); }, omit(mask) { return omit(this, mask); }, partial(...args) { return partial(ZodOptional, this, args[0]); }, exactPartial(...args) { return partial(ZodExactOptional, this, args[0], "exactPartial"); }, required(...args) { return required(ZodNonOptional, this, args[0]); } }); function object(shape, params) { return new ZodObject({ type: "object", shape: shape ?? {}, ...normalizeParams(params) }); } function looseObject(shape, params) { return new ZodObject({ type: "object", shape, catchall: unknown(), ...normalizeParams(params) }); } var ZodUnion = /*@__PURE__*/ $constructor("ZodUnion", (inst, def) => { $ZodUnion.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => unionProcessor(inst, ctx, json, params); inst.options = def.options; }); function union(options, params) { return new ZodUnion({ type: "union", options, ...normalizeParams(params) }); } var ZodDiscriminatedUnion = /*@__PURE__*/ $constructor("ZodDiscriminatedUnion", (inst, def) => { ZodUnion.init(inst, def); $ZodDiscriminatedUnion.init(inst, def); }); function discriminatedUnion(discriminator, options, params) { return new ZodDiscriminatedUnion({ type: "union", options, discriminator, ...normalizeParams(params) }); } var ZodIntersection = /*@__PURE__*/ $constructor("ZodIntersection", (inst, def) => { $ZodIntersection.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => intersectionProcessor(inst, ctx, json, params); }); function intersection(left, right) { return new ZodIntersection({ type: "intersection", left, right }); } var ZodRecord = /*@__PURE__*/ $constructor("ZodRecord", (inst, def) => { _ensureDefaultMemoizer(); $ZodRecord.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params); inst.keyType = def.keyType; inst.valueType = def.valueType; }); function record(keyType, valueType, params) { if (!valueType || !valueType._zod) return new ZodRecord({ type: "record", keyType: string(), valueType: keyType, ...normalizeParams(valueType) }); return new ZodRecord({ type: "record", keyType, valueType, ...normalizeParams(params) }); } var ZodEnum = /*@__PURE__*/ $constructor("ZodEnum", (inst, def) => { $ZodEnum.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => enumProcessor(inst, ctx, json, params); inst.enum = def.entries; inst.options = [...inst._zod.values]; const keys = new Set(Object.keys(def.entries)); inst.extract = (values, params) => { const newEntries = {}; for (const value of values) if (keys.has(value)) newEntries[value] = def.entries[value]; else throw new Error(`Key ${value} not found in enum`); return new ZodEnum({ ...def, checks: [], ...normalizeParams(params), entries: newEntries }); }; inst.exclude = (values, params) => { const newEntries = { ...def.entries }; for (const value of values) if (keys.has(value)) delete newEntries[value]; else throw new Error(`Key ${value} not found in enum`); return new ZodEnum({ ...def, checks: [], ...normalizeParams(params), entries: newEntries }); }; }); function _enum(values, params) { return new ZodEnum({ type: "enum", entries: Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values, ...normalizeParams(params) }); } var ZodLiteral = /*@__PURE__*/ $constructor("ZodLiteral", (inst, def) => { $ZodLiteral.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => literalProcessor(inst, ctx, json, params); inst.values = new Set(def.values); Object.defineProperty(inst, "value", { get() { if (def.values.length > 1) throw new Error("This schema contains multiple valid literal values. Use `.values` instead."); return def.values[0]; } }); }); function literal(value, params) { return new ZodLiteral({ type: "literal", values: Array.isArray(value) ? value : [value], ...normalizeParams(params) }); } var ZodTransform = /*@__PURE__*/ $constructor("ZodTransform", (inst, def) => { _ensureDefaultMemoizer(); $ZodTransform.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => transformProcessor(inst, ctx, json, params); inst._zod.parse = (payload, _ctx) => { if (_ctx.direction === "backward") throw new $ZodEncodeError(inst.constructor.name); payload.addIssue = (issue$1) => { if (typeof issue$1 === "string") payload.issues.push(issue(issue$1, payload.value, def)); else { const _issue = issue$1; if (_issue.fatal) _issue.continue = false; _issue.code ?? (_issue.code = "custom"); if (!("input" in _issue)) _issue.input = payload.value; _issue.inst ?? (_issue.inst = inst); payload.issues.push(issue(_issue)); } }; const output = def.transform(payload.value, payload); if (output instanceof Promise) return output.then((output) => { payload.value = output; return payload; }); payload.value = output; return payload; }; }); function transform(fn) { return new ZodTransform({ type: "transform", transform: fn }); } var ZodOptional = /*@__PURE__*/ $constructor("ZodOptional", (inst, def) => { $ZodOptional.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => optionalProcessor(inst, ctx, json, params); inst.unwrap = () => inst._zod.def.innerType; }); function optional(innerType) { return new ZodOptional({ type: "optional", innerType }); } var ZodExactOptional = /*@__PURE__*/ $constructor("ZodExactOptional", (inst, def) => { $ZodExactOptional.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => optionalProcessor(inst, ctx, json, params); inst.unwrap = () => inst._zod.def.innerType; }); function exactOptional(innerType) { return new ZodExactOptional({ type: "optional", innerType }); } var ZodNullable = /*@__PURE__*/ $constructor("ZodNullable", (inst, def) => { $ZodNullable.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => nullableProcessor(inst, ctx, json, params); inst.unwrap = () => inst._zod.def.innerType; }); function nullable(innerType) { return new ZodNullable({ type: "nullable", innerType }); } var ZodDefault = /*@__PURE__*/ $constructor("ZodDefault", (inst, def) => { $ZodDefault.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => defaultProcessor(inst, ctx, json, params); inst.unwrap = () => inst._zod.def.innerType; inst.removeDefault = inst.unwrap; }); function _default(innerType, defaultValue) { return new ZodDefault({ type: "default", innerType, get defaultValue() { return typeof defaultValue === "function" ? defaultValue() : shallowClone(defaultValue); } }); } var ZodPrefault = /*@__PURE__*/ $constructor("ZodPrefault", (inst, def) => { $ZodPrefault.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => prefaultProcessor(inst, ctx, json, params); inst.unwrap = () => inst._zod.def.innerType; }); function prefault(innerType, defaultValue) { return new ZodPrefault({ type: "prefault", innerType, get defaultValue() { return typeof defaultValue === "function" ? defaultValue() : shallowClone(defaultValue); } }); } var ZodNonOptional = /*@__PURE__*/ $constructor("ZodNonOptional", (inst, def) => { $ZodNonOptional.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => nonoptionalProcessor(inst, ctx, json, params); inst.unwrap = () => inst._zod.def.innerType; }); function nonoptional(innerType, params) { return new ZodNonOptional({ type: "nonoptional", innerType, ...normalizeParams(params) }); } var ZodCatch = /*@__PURE__*/ $constructor("ZodCatch", (inst, def) => { $ZodCatch.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => catchProcessor(inst, ctx, json, params); inst.unwrap = () => inst._zod.def.innerType; inst.removeCatch = inst.unwrap; }); function _catch(innerType, catchValue) { return new ZodCatch({ type: "catch", innerType, catchValue: typeof catchValue === "function" ? catchValue : constantCatch(catchValue) }); } var ZodPipe = /*@__PURE__*/ $constructor("ZodPipe", (inst, def) => { $ZodPipe.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => pipeProcessor(inst, ctx, json, params); inst.in = def.in; inst.out = def.out; }); function pipe(in_, out) { return new ZodPipe({ type: "pipe", in: in_, out }); } var ZodReadonly = /*@__PURE__*/ $constructor("ZodReadonly", (inst, def) => { $ZodReadonly.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => readonlyProcessor(inst, ctx, json, params); inst.unwrap = () => inst._zod.def.innerType; }); function readonly(innerType) { return new ZodReadonly({ type: "readonly", innerType }); } var ZodLazy = /*@__PURE__*/ $constructor("ZodLazy", (inst, def) => { $ZodLazy.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => lazyProcessor(inst, ctx, json, params); inst.unwrap = () => inst._zod.def.getter(); }); function lazy(getter) { return new ZodLazy({ type: "lazy", getter }); } var ZodCustom = /*@__PURE__*/ $constructor("ZodCustom", (inst, def) => { $ZodCustom.init(inst, def); ZodType.init(inst, def); inst._zod.processJSONSchema = (ctx, json, params) => customProcessor(inst, ctx, json, params); }); function custom(fn, _params) { return /* @__PURE__ */ _custom(ZodCustom, fn ?? (() => true), _params); } function refine(fn, _params = {}) { return /* @__PURE__ */ _refine(ZodCustom, fn, _params); } function superRefine(fn, params) { return /* @__PURE__ */ _superRefine(fn, params); } var ZodInstanceOf = /*@__PURE__*/ $constructor("ZodInstanceOf", (inst, def) => { ZodCustom.init(inst, def); }, { properties(shape, params) { return this.check(/* @__PURE__ */ _properties(shape, params)); } }); function _instanceof(cls, params = {}) { const inst = new ZodInstanceOf({ type: "custom", check: "custom", fn: (data) => data instanceof cls, abort: true, ...normalizeParams(params) }); inst._zod.bag.Class = cls; inst._zod.check = (payload) => { if (!(payload.value instanceof cls)) payload.issues.push({ code: "invalid_type", expected: cls.name, input: payload.value, inst, path: [...inst._zod.def.path ?? []] }); }; return inst; } //#endregion //#region node_modules/eventsource-parser/dist/index.js var ParseError = class extends Error { constructor(message, options) { super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line; } }; var LF = 10; var CR = 13; var SPACE = 32; function noop(_arg) {} function createParser(config) { if (typeof config == "function") throw new TypeError("`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?"); const { onEvent = noop, onError = noop, onRetry = noop, onComment, maxBufferSize } = config, pendingFragments = []; let pendingFragmentsLength = 0, isFirstChunk = !0, id, data = "", dataLines = 0, eventType, terminated = !1; function feed(chunk) { if (terminated) throw new Error("Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing."); if (isFirstChunk && (isFirstChunk = !1, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) { const trailing2 = processLines(chunk); trailing2 !== "" && (pendingFragments.push(trailing2), pendingFragmentsLength = trailing2.length), checkBufferSize(); return; } if (chunk.indexOf(` `) === -1 && chunk.indexOf("\r") === -1) { pendingFragments.push(chunk), pendingFragmentsLength += chunk.length, checkBufferSize(); return; } pendingFragments.push(chunk); const input = pendingFragments.join(""); pendingFragments.length = 0, pendingFragmentsLength = 0; const trailing = processLines(input); trailing !== "" && (pendingFragments.push(trailing), pendingFragmentsLength = trailing.length), checkBufferSize(); } function checkBufferSize() { maxBufferSize !== void 0 && (pendingFragmentsLength + data.length <= maxBufferSize || (terminated = !0, pendingFragments.length = 0, pendingFragmentsLength = 0, id = void 0, data = "", dataLines = 0, eventType = void 0, onError(new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, { type: "max-buffer-size-exceeded" })))); } function processLines(chunk) { let searchIndex = 0; if (chunk.indexOf("\r") === -1) { let lfIndex = chunk.indexOf(` `, searchIndex); for (; lfIndex !== -1;) { if (searchIndex === lfIndex) { dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = "", dataLines = 0, eventType = void 0, searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(` `, searchIndex); continue; } const firstCharCode = chunk.charCodeAt(searchIndex); if (isDataPrefix(chunk, searchIndex, firstCharCode)) { const valueStart = chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5, value = chunk.slice(valueStart, lfIndex); if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) { onEvent({ id, event: eventType, data: value }), id = void 0, data = "", eventType = void 0, searchIndex = lfIndex + 2, lfIndex = chunk.indexOf(` `, searchIndex); continue; } data = dataLines === 0 ? value : `${data} ${value}`, dataLines++; } else isEventPrefix(chunk, searchIndex, firstCharCode) ? eventType = chunk.slice(chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6, lfIndex) || void 0 : parseLine(chunk, searchIndex, lfIndex); searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(` `, searchIndex); } return chunk.slice(searchIndex); } for (; searchIndex < chunk.length;) { const crIndex = chunk.indexOf("\r", searchIndex), lfIndex = chunk.indexOf(` `, searchIndex); let lineEnd = -1; if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = crIndex < lfIndex ? crIndex : lfIndex : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1) break; parseLine(chunk, searchIndex, lineEnd), searchIndex = lineEnd + 1, chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF && searchIndex++; } return chunk.slice(searchIndex); } function parseLine(chunk, start, end) { if (start === end) { dispatchEvent(); return; } const firstCharCode = chunk.charCodeAt(start); if (isDataPrefix(chunk, start, firstCharCode)) { const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5, value2 = chunk.slice(valueStart, end); data = dataLines === 0 ? value2 : `${data} ${value2}`, dataLines++; return; } if (isEventPrefix(chunk, start, firstCharCode)) { eventType = chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || void 0; return; } if (firstCharCode === 105 && chunk.charCodeAt(start + 1) === 100 && chunk.charCodeAt(start + 2) === 58) { const value2 = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end); value2.includes("\0") || (id = value2); return; } if (firstCharCode === 58) { if (onComment) { const line2 = chunk.slice(start, end); onComment(line2.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1)); } return; } const line = chunk.slice(start, end), fieldSeparatorIndex = line.indexOf(":"); if (fieldSeparatorIndex === -1) { processField(line, "", line); return; } const field = line.slice(0, fieldSeparatorIndex), offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1; processField(field, line.slice(fieldSeparatorIndex + offset), line); } function processField(field, value, line) { switch (field) { case "event": eventType = value || void 0; break; case "data": data = dataLines === 0 ? value : `${data} ${value}`, dataLines++; break; case "id": value.includes("\0") || (id = value); break; case "retry": /^\d+$/.test(value) ? onRetry(parseInt(value, 10)) : onError(new ParseError(`Invalid \`retry\` value: "${value}"`, { type: "invalid-retry", value, line })); break; default: onError(new ParseError(`Unknown field "${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}"`, { type: "unknown-field", field, value, line })); } } function dispatchEvent() { dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = "", dataLines = 0, eventType = void 0; } function reset(options = {}) { if (options.consume && pendingFragments.length > 0) { const incompleteLine = pendingFragments.join(""); parseLine(incompleteLine, 0, incompleteLine.length); } isFirstChunk = !0, id = void 0, data = "", dataLines = 0, eventType = void 0, pendingFragments.length = 0, pendingFragmentsLength = 0, terminated = !1; } return { feed, reset }; } function isDataPrefix(chunk, i, firstCharCode) { return firstCharCode === 100 && chunk.charCodeAt(i + 1) === 97 && chunk.charCodeAt(i + 2) === 116 && chunk.charCodeAt(i + 3) === 97 && chunk.charCodeAt(i + 4) === 58; } function isEventPrefix(chunk, i, firstCharCode) { return firstCharCode === 101 && chunk.charCodeAt(i + 1) === 118 && chunk.charCodeAt(i + 2) === 101 && chunk.charCodeAt(i + 3) === 110 && chunk.charCodeAt(i + 4) === 116 && chunk.charCodeAt(i + 5) === 58; } //#endregion //#region node_modules/eventsource-parser/dist/stream.js var EventSourceParserStream = class extends TransformStream { constructor({ onError, onRetry, onComment, maxBufferSize } = {}) { let parser; super({ start(controller) { parser = createParser({ onEvent: (event) => { controller.enqueue(event); }, onError(error) { typeof onError == "function" && onError(error), (onError === "terminate" || error.type === "max-buffer-size-exceeded") && controller.error(error); }, onRetry, onComment, maxBufferSize }); }, transform(chunk) { parser.feed(chunk); } }); } }; //#endregion //#region node_modules/@workflow/serde/dist/index.js /** * Symbol used to define custom serialization for user-defined class instances. * The static method should accept an instance and return serializable data. * * @example * ```ts * import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde'; * * class MyClass { * constructor(public value: string) {} * * static [WORKFLOW_SERIALIZE](instance: MyClass) { * return { value: instance.value }; * } * * static [WORKFLOW_DESERIALIZE](data: { value: string }) { * return new MyClass(data.value); * } * } * ``` */ var WORKFLOW_SERIALIZE = Symbol.for("workflow-serialize"); /** * Symbol used to define custom deserialization for user-defined class instances. * The static method should accept serialized data and return a class instance. * * @see WORKFLOW_SERIALIZE for usage example */ var WORKFLOW_DESERIALIZE = Symbol.for("workflow-deserialize"); //#endregion //#region node_modules/@ai-sdk/provider-utils/dist/index.js function asArray(value) { return value === void 0 ? [] : Array.isArray(value) ? value : [value]; } function combineHeaders(...headers) { return headers.reduce((combinedHeaders, currentHeaders) => ({ ...combinedHeaders, ...currentHeaders != null ? currentHeaders : {} }), {}); } function removeUndefinedEntries(record) { return Object.fromEntries(Object.entries(record).filter(([_key, value]) => value != null)); } async function delay(delayInMs, options) { if (delayInMs == null) return Promise.resolve(); const signal = options == null ? void 0 : options.abortSignal; return new Promise((resolve2, reject) => { if (signal == null ? void 0 : signal.aborted) { reject(createAbortError()); return; } const timeoutId = setTimeout(() => { cleanup(); resolve2(); }, delayInMs); const cleanup = () => { clearTimeout(timeoutId); signal?.removeEventListener("abort", onAbort); }; const onAbort = () => { cleanup(); reject(createAbortError()); }; signal?.addEventListener("abort", onAbort); }); } function createAbortError() { return new DOMException("Delay was aborted", "AbortError"); } function getWebSocketConstructor(webSocket) { const WebSocketConstructor = webSocket != null ? webSocket : globalThis.WebSocket; if (WebSocketConstructor == null) throw new Error("No WebSocket implementation available."); return WebSocketConstructor; } var textDecoder = new TextDecoder(); async function readWebSocketMessageText(data) { if (typeof data === "string") return data; if (data instanceof ArrayBuffer) return textDecoder.decode(data); if (ArrayBuffer.isView(data)) return textDecoder.decode(data); if (typeof Blob !== "undefined" && data instanceof Blob) return data.text(); return String(data); } var WEBSOCKET_OPEN_STATE = 1; async function waitForWebSocketBufferDrain(socket, { highWaterMark = 1048576, pollIntervalMs = 20, abortSignal } = {}) { var _a3; while (socket.readyState === WEBSOCKET_OPEN_STATE && ((_a3 = socket.bufferedAmount) != null ? _a3 : 0) > highWaterMark) { if ((abortSignal == null ? void 0 : abortSignal.aborted) === true) return; await delay(pollIntervalMs); } } function connectToWebSocket({ url, protocols, headers, webSocket, abortSignal, onOpen, onMessageText, onProcessingError, onSocketError, onClose, onAbort }) { var _a3; let socket; let abortListener; const close = (code) => { if (abortListener != null) { abortSignal?.removeEventListener("abort", abortListener); abortListener = void 0; } try { socket?.close(code); } catch (e) {} }; if (abortSignal == null ? void 0 : abortSignal.aborted) { onAbort?.((_a3 = abortSignal.reason) != null ? _a3 : /* @__PURE__ */ new Error("Aborted")); return { socket: void 0, close }; } try { socket = new (getWebSocketConstructor(webSocket))(url, protocols, { headers: removeUndefinedEntries(headers != null ? headers : {}) }); } catch (error) { onProcessingError(error); return { socket: void 0, close }; } if (abortSignal != null && onAbort != null) { abortListener = () => { var _a4; return onAbort((_a4 = abortSignal.reason) != null ? _a4 : /* @__PURE__ */ new Error("Aborted")); }; abortSignal.addEventListener("abort", abortListener, { once: true }); } const openedSocket = socket; socket.onopen = () => { try { onOpen?.(openedSocket); } catch (error) { onProcessingError(error); } }; let tail = Promise.resolve(); socket.onmessage = (event) => { tail = tail.then(() => readWebSocketMessageText(event.data)).then((text) => onMessageText(text)).catch(onProcessingError); }; socket.onerror = () => { tail = tail.then(() => onSocketError == null ? void 0 : onSocketError()).catch(onProcessingError); }; socket.onclose = (event) => { const closeEvent = event; const code = typeof (closeEvent == null ? void 0 : closeEvent.code) === "number" ? closeEvent.code : void 0; const reason = typeof (closeEvent == null ? void 0 : closeEvent.reason) === "string" ? closeEvent.reason : void 0; tail = tail.then(() => onClose == null ? void 0 : onClose({ code, reason })).catch(onProcessingError); }; return { socket, close }; } function convertAsyncIteratorToReadableStream(iterator) { let cancelled = false; return new ReadableStream({ /** * Called when the consumer wants to pull more data from the stream. * * @param {ReadableStreamDefaultController} controller - The controller to enqueue data into the stream. * @returns {Promise} */ async pull(controller) { if (cancelled) return; try { const { value, done } = await iterator.next(); if (done) controller.close(); else controller.enqueue(value); } catch (error) { controller.error(error); } }, /** * Called when the consumer cancels the stream. */ async cancel(reason) { cancelled = true; if (iterator.return) try { await iterator.return(reason); } catch (e) {} } }); } var { btoa: btoa$1, atob: atob$1 } = globalThis; function convertBase64ToUint8Array(base64String) { const latin1string = atob$1(base64String.replace(/-/g, "+").replace(/_/g, "/")); return Uint8Array.from(latin1string, (byte) => byte.codePointAt(0)); } function convertUint8ArrayToBase64(array) { const chunks = []; const chunkSize = 4096; for (let i = 0; i < array.length; i += chunkSize) chunks.push(String.fromCodePoint(...array.subarray(i, i + chunkSize))); return btoa$1(chunks.join("")); } function convertToBase64(value) { return value instanceof Uint8Array ? convertUint8ArrayToBase64(value) : value; } function convertToFormData(input, options = {}) { const { useArrayBrackets = true } = options; const formData = new FormData(); for (const [key, value] of Object.entries(input)) { if (value == null) continue; if (Array.isArray(value)) { if (value.length === 1) { formData.append(key, value[0]); continue; } const arrayKey = useArrayBrackets ? `${key}[]` : key; for (const item of value) formData.append(arrayKey, item); continue; } formData.append(key, value); } return formData; } function createLanguageModelResponseMetadata({ id, model, created }) { return { id: id != null ? id : void 0, modelId: model != null ? model : void 0, timestamp: created != null ? /* @__PURE__ */ new Date(created * 1e3) : void 0 }; } function createNullLanguageModelUsage$1() { return { inputTokens: { total: void 0, noCache: void 0, cacheRead: void 0, cacheWrite: void 0 }, outputTokens: { total: void 0, text: void 0, reasoning: void 0 }, raw: void 0 }; } var marker$1 = /* @__PURE__ */ Symbol.for("vercel.ai.providerStreamError"); function isProviderStreamError(error) { return typeof error === "object" && error != null && error[marker$1] === true; } var DelayedPromise = class { constructor() { this.status = { type: "pending" }; this._resolve = void 0; this._reject = void 0; } get promise() { if (this._promise) return this._promise; this._promise = new Promise((resolve2, reject) => { if (this.status.type === "resolved") resolve2(this.status.value); else if (this.status.type === "rejected") reject(this.status.error); this._resolve = resolve2; this._reject = reject; }); return this._promise; } resolve(value) { var _a3; this.status = { type: "resolved", value }; if (this._promise) (_a3 = this._resolve) == null || _a3.call(this, value); } reject(error) { var _a3; this.status = { type: "rejected", error }; if (this._promise) (_a3 = this._reject) == null || _a3.call(this, error); } isResolved() { return this.status.type === "resolved"; } isRejected() { return this.status.type === "rejected"; } isPending() { return this.status.type === "pending"; } }; function extractResponseHeaders(response) { return Object.fromEntries([...response.headers]); } function getRuntimeEnvironmentUserAgent(globalThisAny = globalThis) { var _a3, _b3, _c; if (globalThisAny.window) return `runtime/browser`; if ((_a3 = globalThisAny.navigator) == null ? void 0 : _a3.userAgent) return `runtime/${globalThisAny.navigator.userAgent.toLowerCase()}`; if ((_c = (_b3 = globalThisAny.process) == null ? void 0 : _b3.versions) == null ? void 0 : _c.node) return `runtime/node.js/${globalThisAny.process.version.substring(0)}`; if (globalThisAny.EdgeRuntime) return `runtime/vercel-edge`; return "runtime/unknown"; } function isAbortError(error) { return (error instanceof Error || typeof DOMException === "function" && error instanceof DOMException) && (error.name === "AbortError" || error.name === "ResponseAborted" || error.name === "TimeoutError"); } var FETCH_FAILED_ERROR_MESSAGES = ["fetch failed", "failed to fetch"]; var RETRYABLE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([ "ConnectionRefused", "ConnectionClosed", "FailedToOpenSocket", "ECONNRESET", "ECONNREFUSED", "ETIMEDOUT", "EPIPE", "UND_ERR_SOCKET", "UND_ERR_HEADERS_TIMEOUT", "UND_ERR_BODY_TIMEOUT", "UND_ERR_CONNECT_TIMEOUT" ]); function findNetworkError(error) { const visited = /* @__PURE__ */ new Set(); let current = error; while (current instanceof Error && !visited.has(current)) { visited.add(current); const errorWithCode = current; if (typeof errorWithCode.code === "string" && RETRYABLE_NETWORK_ERROR_CODES.has(errorWithCode.code)) return errorWithCode; current = current.cause; } } function handleFetchError({ error, url, requestBodyValues }) { if (isAbortError(error)) return error; if (error instanceof TypeError && FETCH_FAILED_ERROR_MESSAGES.includes(error.message.toLowerCase())) { const cause = error.cause; if (cause != null) return new APICallError({ message: `Cannot connect to API: ${cause.message}`, cause, url, requestBodyValues, isRetryable: true }); } const networkError = findNetworkError(error); if (networkError != null) { if (APICallError.isInstance(error)) return new APICallError({ message: error.message, cause: error.cause, url: error.url, requestBodyValues: error.requestBodyValues, statusCode: error.statusCode, responseHeaders: error.responseHeaders, responseBody: error.responseBody, data: error.data, isRetryable: true }); return new APICallError({ message: `Cannot connect to API: ${error instanceof Error ? error.message : networkError.message}`, cause: error, url, requestBodyValues, isRetryable: true }); } return error; } var VERSION$3 = "5.0.45"; function normalizeHeaders(headers) { if (headers == null) return {}; const normalized = {}; if (headers instanceof Headers) headers.forEach((value, key) => { normalized[key.toLowerCase()] = value; }); else { if (!Array.isArray(headers)) headers = Object.entries(headers); for (const [key, value] of headers) if (value != null) normalized[key.toLowerCase()] = value; } return normalized; } function withUserAgentSuffix(headers, ...userAgentSuffixParts) { const normalizedHeaders = new Headers(normalizeHeaders(headers)); const currentUserAgentHeader = normalizedHeaders.get("user-agent") || ""; normalizedHeaders.set("user-agent", [currentUserAgentHeader, ...userAgentSuffixParts].filter(Boolean).join(" ")); return Object.fromEntries(normalizedHeaders.entries()); } var imageMediaTypeSignatures = [ { mediaType: "image/gif", bytesPrefix: [ 71, 73, 70, 56, 55, 97 ] }, { mediaType: "image/gif", bytesPrefix: [ 71, 73, 70, 56, 57, 97 ] }, { mediaType: "image/png", bytesPrefix: [ 137, 80, 78, 71 ] }, { mediaType: "image/jpeg", bytesPrefix: [255, 216] }, { mediaType: "image/webp", bytesPrefix: [ 82, 73, 70, 70, null, null, null, null, 87, 69, 66, 80 ] }, { mediaType: "image/bmp", bytesPrefix: [ 66, 77, null, null, null, null, 0, 0, 0, 0 ] }, { mediaType: "image/tiff", bytesPrefix: [ 73, 73, 42, 0 ] }, { mediaType: "image/tiff", bytesPrefix: [ 77, 77, 0, 42 ] }, { mediaType: "image/avif", bytesPrefix: [ 0, 0, 0, null, 102, 116, 121, 112, 97, 118, 105, 102 ] }, { mediaType: "image/heic", bytesPrefix: [ 0, 0, 0, null, 102, 116, 121, 112, 104, 101, 105, 99 ] } ]; var documentMediaTypeSignatures = [{ mediaType: "application/pdf", bytesPrefix: [ 37, 80, 68, 70 ] }]; var audioMediaTypeSignaturesWithoutMp4 = [ { mediaType: "audio/aac", bytesPrefix: [255, 240] }, { mediaType: "audio/aac", bytesPrefix: [255, 241] }, { mediaType: "audio/aac", bytesPrefix: [255, 248] }, { mediaType: "audio/aac", bytesPrefix: [255, 249] }, { mediaType: "audio/mpeg", bytesPrefix: [255, 251] }, { mediaType: "audio/mpeg", bytesPrefix: [255, 250] }, { mediaType: "audio/mpeg", bytesPrefix: [255, 243] }, { mediaType: "audio/mpeg", bytesPrefix: [255, 242] }, { mediaType: "audio/mpeg", bytesPrefix: [255, 227] }, { mediaType: "audio/mpeg", bytesPrefix: [255, 226] }, { mediaType: "audio/wav", bytesPrefix: [ 82, 73, 70, 70, null, null, null, null, 87, 65, 86, 69 ] }, { mediaType: "audio/ogg", bytesPrefix: [ 79, 103, 103, 83 ] }, { mediaType: "audio/flac", bytesPrefix: [ 102, 76, 97, 67 ] }, { mediaType: "audio/aac", bytesPrefix: [ 64, 21, 0, 0 ] }, { mediaType: "audio/webm", bytesPrefix: [ 26, 69, 223, 163 ] } ]; var audioMediaTypeSignatures = [...audioMediaTypeSignaturesWithoutMp4, { mediaType: "audio/mp4", bytesPrefix: [ 0, 0, 0, null, 102, 116, 121, 112 ] }]; var videoMediaTypeSignatures = [ { mediaType: "video/mp4", bytesPrefix: [ 0, 0, 0, null, 102, 116, 121, 112 ] }, { mediaType: "video/webm", bytesPrefix: [ 26, 69, 223, 163 ] }, { mediaType: "video/quicktime", bytesPrefix: [ 0, 0, 0, 20, 102, 116, 121, 112, 113, 116 ] }, { mediaType: "video/x-msvideo", bytesPrefix: [ 82, 73, 70, 70 ] } ]; var DEFAULT_SNIFF_BYTES = 18; var ID3_SCAN_BYTES = 131084; function decodePrefix(data, maxBytes) { if (typeof data !== "string") return data.length > maxBytes ? data.subarray(0, maxBytes) : data; const maxChars = Math.ceil(maxBytes / 3) * 4; const bytes = convertBase64ToUint8Array(data.substring(0, Math.min(data.length, maxChars))); return bytes.length > maxBytes ? bytes.subarray(0, maxBytes) : bytes; } function hasID3(bytes) { return bytes.length > 10 && bytes[0] === 73 && bytes[1] === 68 && bytes[2] === 51; } var stripID3 = (bytes) => { const id3Size = (bytes[6] & 127) << 21 | (bytes[7] & 127) << 14 | (bytes[8] & 127) << 7 | bytes[9] & 127; return bytes.subarray(id3Size + 10); }; function detectMediaTypeBySignatures({ data, signatures }) { let bytes = decodePrefix(data, DEFAULT_SNIFF_BYTES); if (hasID3(bytes)) bytes = stripID3(decodePrefix(data, ID3_SCAN_BYTES)); for (const signature of signatures) if (bytes.length >= signature.bytesPrefix.length && signature.bytesPrefix.every((byte, index) => byte === null || bytes[index] === byte)) return signature.mediaType; } var topLevelSignatureTables = { image: imageMediaTypeSignatures, audio: audioMediaTypeSignatures, video: videoMediaTypeSignatures, application: documentMediaTypeSignatures }; function detectMediaType({ data, topLevelType }) { if (topLevelType === void 0) return detectMediaTypeBySignatures({ data, signatures: [ ...imageMediaTypeSignatures, ...documentMediaTypeSignatures, ...audioMediaTypeSignaturesWithoutMp4, ...videoMediaTypeSignatures ] }); const signatures = topLevelSignatureTables[topLevelType]; if (signatures === void 0) return; return detectMediaTypeBySignatures({ data, signatures }); } function getTopLevelMediaType(mediaType) { const slashIndex = mediaType.indexOf("/"); return slashIndex === -1 ? mediaType : mediaType.substring(0, slashIndex); } function isFullMediaType(mediaType) { const slashIndex = mediaType.indexOf("/"); if (slashIndex === -1) return false; const subtype = mediaType.substring(slashIndex + 1); return subtype.length > 0 && subtype !== "*"; } async function cancelResponseBody(response) { var _a3; try { await ((_a3 = response.body) == null ? void 0 : _a3.cancel()); } catch (e) {} } var name$2 = "AI_DownloadError"; var marker2$2 = `vercel.ai.error.${name$2}`; var symbol$2 = Symbol.for(marker2$2); var _a$2; var _b$2; var DownloadError = class extends (_b$2 = AISDKError, _a$2 = symbol$2, _b$2) { constructor({ url, statusCode, statusText, cause, message = cause == null ? `Failed to download ${url}: ${statusCode} ${statusText}` : `Failed to download ${url}: ${cause}` }) { super({ name: name$2, message, cause }); this[_a$2] = true; this.url = url; this.statusCode = statusCode; this.statusText = statusText; } static isInstance(error) { return AISDKError.hasMarker(error, marker2$2); } }; function isBrowserRuntime(globalThisAny = globalThis) { return globalThisAny.window != null; } function isSameOrigin(url, baseUrl) { try { return new URL(url).origin === new URL(baseUrl).origin; } catch (e) { return false; } } function validateDownloadUrl(url) { let parsed; try { parsed = new URL(url); } catch (e) { throw new DownloadError({ url, message: `Invalid URL: ${url}` }); } if (parsed.protocol === "data:") return; if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new DownloadError({ url, message: `URL scheme must be http, https, or data, got ${parsed.protocol}` }); const hostname = parsed.hostname.toLowerCase().replace(/\.+$/, ""); if (!hostname) throw new DownloadError({ url, message: `URL must have a hostname` }); if (hostname === "localhost" || hostname.endsWith(".local") || hostname.endsWith(".localhost")) throw new DownloadError({ url, message: `URL with hostname ${hostname} is not allowed` }); if (hostname.startsWith("[") && hostname.endsWith("]")) { if (isPrivateIPv6(hostname.slice(1, -1))) throw new DownloadError({ url, message: `URL with IPv6 address ${hostname} is not allowed` }); return; } if (isIPv4(hostname)) { if (isPrivateIPv4(hostname)) throw new DownloadError({ url, message: `URL with IP address ${hostname} is not allowed` }); return; } } function validateDownloadAddress({ address, family, hostname }) { if (family === 4 ? !isIPv4(address) || isPrivateIPv4(address) : family === 6 ? isPrivateIPv6(address) : true) throw new DownloadError({ url: hostname, message: `Hostname ${hostname} resolved to disallowed IP address ${address}` }); } function isIPv4(hostname) { const parts = hostname.split("."); if (parts.length !== 4) return false; return parts.every((part) => { const num = Number(part); return Number.isInteger(num) && num >= 0 && num <= 255 && String(num) === part; }); } function isPrivateIPv4(ip) { const [a, b, c] = ip.split(".").map(Number); if (a === 0) return true; if (a === 10) return true; if (a === 100 && b >= 64 && b <= 127) return true; if (a === 127) return true; if (a === 169 && b === 254) return true; if (a === 172 && b >= 16 && b <= 31) return true; if (a === 192 && b === 0 && c === 0) return true; if (a === 192 && b === 0 && c === 2) return true; if (a === 192 && b === 168) return true; if (a === 198 && (b === 18 || b === 19)) return true; if (a === 198 && b === 51 && c === 100) return true; if (a === 203 && b === 0 && c === 113) return true; if (a >= 224) return true; return false; } function parseIPv6(ip) { let address = ip.toLowerCase(); const zoneIndex = address.indexOf("%"); if (zoneIndex !== -1) address = address.slice(0, zoneIndex); const halves = address.split("::"); if (halves.length > 2) return null; const toGroups = (segment) => { if (segment === "") return []; const groups = []; const parts = segment.split(":"); for (let i = 0; i < parts.length; i++) { const part = parts[i]; if (part.includes(".")) { if (i !== parts.length - 1 || !isIPv4(part)) return null; const [a, b, c, d] = part.split(".").map(Number); groups.push(a << 8 | b, c << 8 | d); continue; } if (!/^[0-9a-f]{1,4}$/.test(part)) return null; groups.push(parseInt(part, 16)); } return groups; }; const head = toGroups(halves[0]); if (head === null) return null; if (halves.length === 2) { const tail = toGroups(halves[1]); if (tail === null) return null; const fill = 8 - head.length - tail.length; if (fill < 0) return null; return [ ...head, ...new Array(fill).fill(0), ...tail ]; } return head.length === 8 ? head : null; } function isPrivateIPv6(ip) { const groups = parseIPv6(ip); if (groups === null) return true; const topZero = (count) => groups.slice(0, count).every((group) => group === 0); if (topZero(7) && (groups[7] === 0 || groups[7] === 1)) return true; if ((groups[0] & 65024) === 64512) return true; if ((groups[0] & 65472) === 65152) return true; if ((groups[0] & 65472) === 65216) return true; if ((groups[0] & 65280) === 65280) return true; if (groups[0] === 8193 && groups[1] === 3512) return true; if (groups[0] === 16383 && (groups[1] & 61440) === 0) return true; if (topZero(6) || topZero(5) && groups[5] === 65535 || topZero(4) && groups[4] === 65535 && groups[5] === 0 || groups[0] === 100 && groups[1] === 65435 && groups[2] === 0 && groups[3] === 0 && groups[4] === 0 && groups[5] === 0 || groups[0] === 100 && groups[1] === 65435 && groups[2] === 1) return isPrivateIPv4(`${groups[6] >> 8 & 255}.${groups[6] & 255}.${groups[7] >> 8 & 255}.${groups[7] & 255}`); return false; } function createSafeLookup(lookup) { return ((hostname, options, callback) => { lookup(hostname, { ...options, all: true }, (error, addresses) => { if (error) { callback(error); return; } try { const [firstAddress] = addresses; if (firstAddress == null) throw new Error(`Hostname ${hostname} did not resolve to an address`); for (const { address, family } of addresses) validateDownloadAddress({ address, family, hostname }); if (options.all === true) callback(null, addresses); else callback(null, firstAddress.address, firstAddress.family); } catch (error2) { callback(error2 instanceof Error ? error2 : new Error(String(error2))); } }); }); } var safeNodeFetchPromise; function isNodeRuntime$1() { var _a3, _b3, _c; const runtimeProcess = globalThis.process; return ((_a3 = runtimeProcess == null ? void 0 : runtimeProcess.release) == null ? void 0 : _a3.name) === "node" && ((_b3 = runtimeProcess.versions) == null ? void 0 : _b3.bun) == null && ((_c = runtimeProcess.versions) == null ? void 0 : _c.deno) == null && runtimeProcess.title !== "workerd" && globalThis.EdgeRuntime == null; } async function getDefaultDownloadFetch() { if (!isNodeRuntime$1()) return globalThis.fetch; return safeNodeFetchPromise != null ? safeNodeFetchPromise : safeNodeFetchPromise = Promise.resolve().then(createSafeNodeFetch); } function createSafeNodeFetch() { const module = loadBuiltinModule$1("node:module"); const { lookup } = loadBuiltinModule$1("node:dns"); const { Agent, fetch } = module.createRequire(getCurrentModulePath())("undici"); const dispatcher = new Agent({ connect: { lookup: createSafeLookup(lookup) } }); return ((input, init) => fetch(input, { ...init, dispatcher })); } function loadBuiltinModule$1(id) { var _a3; const processWithBuiltins = globalThis.process; const builtinModule = (_a3 = processWithBuiltins == null ? void 0 : processWithBuiltins.getBuiltinModule) == null ? void 0 : _a3.call(processWithBuiltins, id); if (builtinModule == null) throw new Error(`Node.js built-in module ${id} is unavailable`); return builtinModule; } function getCurrentModulePath() { const originalPrepareStackTrace = Error.prepareStackTrace; try { Error.prepareStackTrace = (_error, callSites) => callSites; const error = /* @__PURE__ */ new Error("Capture current module path"); Error.captureStackTrace(error, getCurrentModulePath); const [caller] = error.stack; const fileName = caller == null ? void 0 : caller.getFileName(); if (fileName == null) throw new Error("Unable to determine the current module path"); return fileName; } finally { Error.prepareStackTrace = originalPrepareStackTrace; } } var BLOCKED_REQUEST_HEADERS = [ "connection", "keep-alive", "te", "trailer", "transfer-encoding", "upgrade", "host", "forwarded", "proxy-authorization", "via", "x-forwarded-for", "x-forwarded-host", "x-forwarded-proto", "x-real-ip", "metadata", "metadata-flavor", "x-aws-ec2-metadata-token", "x-metadata-token", "cookie", "set-cookie" ]; function sanitizeRequestHeaders(input) { const headers = new Headers(input); for (const name3 of BLOCKED_REQUEST_HEADERS) headers.delete(name3); return headers; } var MAX_DOWNLOAD_REDIRECTS = 10; var REDIRECT_STATUS_CODES = /* @__PURE__ */ new Set([ 301, 302, 303, 307, 308 ]); async function getValidatedFetch(customFetch) { return customFetch == null || customFetch === globalThis.fetch ? await getDefaultDownloadFetch() : customFetch; } async function fetchWithValidatedRedirects({ url, headers, abortSignal, maxRedirects = MAX_DOWNLOAD_REDIRECTS, fetch: customFetch, trustedOrigin }) { var _a3; let currentHeaders = headers === void 0 ? void 0 : sanitizeRequestHeaders(headers); const perHopInit = (redirect) => { const init = { signal: abortSignal, redirect }; if (currentHeaders !== void 0) init.headers = new Headers(currentHeaders); return init; }; let currentUrl = url; for (let redirectCount = 0; redirectCount <= maxRedirects; redirectCount++) { const isTrustedHop = trustedOrigin !== void 0 && isSameOrigin(currentUrl, trustedOrigin); if (!isTrustedHop) validateDownloadUrl(currentUrl); const fetch = isTrustedHop && customFetch != null ? customFetch : isTrustedHop ? globalThis.fetch : await getValidatedFetch(customFetch); const response = await fetch(currentUrl, perHopInit("manual")); if (response.type === "opaqueredirect") { if (!isBrowserRuntime()) throw new DownloadError({ url, message: `Redirect from ${currentUrl} could not be validated and was blocked` }); return await fetch(currentUrl, perHopInit("follow")); } const location = (_a3 = response.headers) == null ? void 0 : _a3.get("location"); if (REDIRECT_STATUS_CODES.has(response.status) && location) { cancelResponseBody(response); const nextUrl = new URL(location, currentUrl).toString(); if (currentHeaders !== void 0 && !isSameOrigin(nextUrl, currentUrl)) { const userAgent = currentHeaders.get("user-agent"); currentHeaders = new Headers(userAgent == null ? void 0 : { "user-agent": userAgent }); } currentUrl = nextUrl; continue; } return response; } throw new DownloadError({ url, message: `Too many redirects (max ${maxRedirects})` }); } var DEFAULT_MAX_DOWNLOAD_SIZE = 2147483648; async function readResponseWithSizeLimit({ response, url, maxBytes = DEFAULT_MAX_DOWNLOAD_SIZE }) { const contentLength = response.headers.get("content-length"); if (contentLength != null) { const length = parseInt(contentLength, 10); if (!isNaN(length) && length > maxBytes) { await cancelResponseBody(response); throw new DownloadError({ url, message: `Download of ${url} exceeded maximum size of ${maxBytes} bytes (Content-Length: ${length}).` }); } } const body = response.body; if (body == null) return /* @__PURE__ */ new Uint8Array(0); const reader = body.getReader(); const chunks = []; let totalBytes = 0; try { while (true) { const { done, value } = await reader.read(); if (done) break; totalBytes += value.length; if (totalBytes > maxBytes) throw new DownloadError({ url, message: `Download of ${url} exceeded maximum size of ${maxBytes} bytes.` }); chunks.push(value); } } finally { try { await reader.cancel(); } catch (e) {} finally { reader.releaseLock(); } } const result = new Uint8Array(totalBytes); let offset = 0; for (const chunk of chunks) { result.set(chunk, offset); offset += chunk.length; } return result; } async function downloadBlob(url, options) { var _a3, _b3; try { const response = await fetchWithValidatedRedirects({ url, abortSignal: options == null ? void 0 : options.abortSignal }); if (!response.ok) { await cancelResponseBody(response); throw new DownloadError({ url, statusCode: response.status, statusText: response.statusText }); } const data = await readResponseWithSizeLimit({ response, url, maxBytes: (_a3 = options == null ? void 0 : options.maxBytes) != null ? _a3 : DEFAULT_MAX_DOWNLOAD_SIZE }); const contentType = (_b3 = response.headers.get("content-type")) != null ? _b3 : void 0; return new Blob([data], contentType ? { type: contentType } : void 0); } catch (error) { if (DownloadError.isInstance(error)) throw error; throw new DownloadError({ url, cause: error }); } } function filterNullable(...values) { return values.filter((value) => value != null); } var createIdGenerator = ({ prefix, size = 16, alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", separator = "-" } = {}) => { const generator = () => { const alphabetLength = alphabet.length; const chars = new Array(size); for (let i = 0; i < size; i++) chars[i] = alphabet[Math.random() * alphabetLength | 0]; return chars.join(""); }; if (prefix == null) return generator; if (alphabet.includes(separator)) throw new InvalidArgumentError$1({ argument: "separator", message: `The separator "${separator}" must not be part of the alphabet "${alphabet}".` }); return () => `${prefix}${separator}${generator()}`; }; var generateId = createIdGenerator(); var getOriginalFetch2 = () => globalThis.fetch; var getFromApi = async ({ url, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch, validateUrl, credentialedOrigin, trustedOrigin }) => { try { const requestFetch = fetch != null ? fetch : getOriginalFetch2(); const requestHeaders = withUserAgentSuffix(credentialedOrigin !== void 0 && !isSameOrigin(url, credentialedOrigin) ? {} : headers, `ai-sdk/provider-utils/${VERSION$3}`, getRuntimeEnvironmentUserAgent()); const response = validateUrl ? await fetchWithValidatedRedirects({ url, headers: requestHeaders, abortSignal, fetch, trustedOrigin }) : await requestFetch(url, { method: "GET", headers: requestHeaders, signal: abortSignal }); const responseHeaders = extractResponseHeaders(response); if (!response.ok) { let errorInformation; try { errorInformation = await failedResponseHandler({ response, url, requestBodyValues: {} }); } catch (error) { if (isAbortError(error) || APICallError.isInstance(error)) throw error; throw new APICallError({ message: "Failed to process error response", cause: error, statusCode: response.status, url, responseHeaders, requestBodyValues: {} }); } throw errorInformation.value; } try { return await successfulResponseHandler({ response, url, requestBodyValues: {} }); } catch (error) { if (error instanceof Error) { if (isAbortError(error) || APICallError.isInstance(error)) throw error; } throw new APICallError({ message: "Failed to process successful response", cause: error, statusCode: response.status, url, responseHeaders, requestBodyValues: {} }); } } catch (error) { throw handleFetchError({ error, url, requestBodyValues: {} }); } }; function isBuffer(value) { var _a3, _b3; return (_b3 = (_a3 = globalThis.Buffer) == null ? void 0 : _a3.isBuffer(value)) != null ? _b3 : false; } function isProviderReference(data) { return typeof data === "object" && data !== null && !(data instanceof Uint8Array) && !(data instanceof URL) && !(data instanceof ArrayBuffer) && !isBuffer(data) && !("type" in data); } function isRecord$1(value) { return value != null && typeof value === "object" && !Array.isArray(value); } function isUrlSupported({ mediaType, url, supportedUrls }) { url = url.toLowerCase(); mediaType = mediaType.toLowerCase(); const isTopLevelOnly = !mediaType.includes("/"); return Object.entries(supportedUrls).map(([key, value]) => { const mediaType2 = key.toLowerCase(); return mediaType2 === "*" || mediaType2 === "*/*" ? { mediaTypePrefix: "", regexes: value } : { mediaTypePrefix: mediaType2.replace(/\*/, ""), regexes: value }; }).filter(({ mediaTypePrefix }) => { if (mediaTypePrefix === "") return true; if (isTopLevelOnly) return `${mediaType}/` === mediaTypePrefix; return mediaType.startsWith(mediaTypePrefix); }).flatMap(({ regexes }) => regexes).some((pattern) => testRegExpFromStart(pattern, url)); } function testRegExpFromStart(pattern, value) { if (!pattern.global && !pattern.sticky) return pattern.test(value); const lastIndex = pattern.lastIndex; pattern.lastIndex = 0; try { return pattern.test(value); } finally { pattern.lastIndex = lastIndex; } } function loadOptionalSetting({ settingValue, environmentVariableName }) { if (typeof settingValue === "string") return settingValue; if (settingValue != null || typeof process === "undefined") return; settingValue = {}[environmentVariableName]; if (settingValue == null || typeof settingValue !== "string") return; return settingValue; } function isCustomReasoning(reasoning) { return reasoning !== void 0 && reasoning !== "provider-default"; } function normalizeBatchRequestCounts({ total, pending, completed, failed }) { if (isNonNegativeSafeInteger(total) && isNonNegativeSafeInteger(pending) && isNonNegativeSafeInteger(completed) && isNonNegativeSafeInteger(failed) && pending + completed + failed === total) return { total, pending, completed, failed }; } function isNonNegativeSafeInteger(value) { return value != null && Number.isSafeInteger(value) && value >= 0; } var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/; var suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/; function _parse(text) { const obj = JSON.parse(text); if (obj === null || typeof obj !== "object") return obj; if (suspectProtoRx.test(text) === false && suspectConstructorRx.test(text) === false) return obj; return filter(obj); } function filter(obj) { let next = [obj]; while (next.length) { const nodes = next; next = []; for (const node of nodes) { if (Object.prototype.hasOwnProperty.call(node, "__proto__")) throw new SyntaxError("Object contains forbidden prototype property"); if (Object.prototype.hasOwnProperty.call(node, "constructor") && node.constructor !== null && typeof node.constructor === "object" && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) throw new SyntaxError("Object contains forbidden prototype property"); for (const key in node) { const value = node[key]; if (value && typeof value === "object") next.push(value); } } } return obj; } function secureJsonParse(text) { const { stackTraceLimit } = Error; try { Error.stackTraceLimit = 0; } catch (e) { return _parse(text); } try { return _parse(text); } finally { Error.stackTraceLimit = stackTraceLimit; } } function addAdditionalPropertiesToJsonSchema(jsonSchema2) { if (jsonSchema2.type === "object" || Array.isArray(jsonSchema2.type) && jsonSchema2.type.includes("object")) { const { additionalProperties } = jsonSchema2; jsonSchema2.additionalProperties = additionalProperties != null && typeof additionalProperties !== "boolean" ? visit(additionalProperties) : false; const { properties } = jsonSchema2; if (properties != null) for (const key of Object.keys(properties)) properties[key] = visit(properties[key]); } if (jsonSchema2.items != null) jsonSchema2.items = Array.isArray(jsonSchema2.items) ? jsonSchema2.items.map(visit) : visit(jsonSchema2.items); if (jsonSchema2.anyOf != null) jsonSchema2.anyOf = jsonSchema2.anyOf.map(visit); if (jsonSchema2.allOf != null) jsonSchema2.allOf = jsonSchema2.allOf.map(visit); if (jsonSchema2.oneOf != null) jsonSchema2.oneOf = jsonSchema2.oneOf.map(visit); const { definitions } = jsonSchema2; if (definitions != null) for (const key of Object.keys(definitions)) definitions[key] = visit(definitions[key]); return jsonSchema2; } function visit(def) { if (typeof def === "boolean") return def; return addAdditionalPropertiesToJsonSchema(def); } var ignoreOverride = /* @__PURE__ */ Symbol("Let zodToJsonSchema decide on which parser to use"); var defaultOptions = { name: void 0, $refStrategy: "root", basePath: ["#"], effectStrategy: "input", pipeStrategy: "all", dateStrategy: "format:date-time", mapStrategy: "entries", removeAdditionalStrategy: "passthrough", allowedAdditionalProperties: true, rejectedAdditionalProperties: false, definitionPath: "definitions", strictUnions: false, definitions: {}, errorMessages: false, patternStrategy: "escape", applyRegexFlags: false, emailStrategy: "format:email", base64Strategy: "contentEncoding:base64", nameStrategy: "ref" }; var getDefaultOptions = (options) => typeof options === "string" ? { ...defaultOptions, name: options } : { ...defaultOptions, ...options }; function parseAnyDef() { return {}; } function parseArrayDef(def, refs) { var _a3, _b3, _c; const res = { type: "array" }; if (((_a3 = def.type) == null ? void 0 : _a3._def) && ((_c = (_b3 = def.type) == null ? void 0 : _b3._def) == null ? void 0 : _c.typeName) !== "ZodAny") res.items = parseDef(def.type._def, { ...refs, currentPath: [...refs.currentPath, "items"] }); if (def.minLength) res.minItems = def.minLength.value; if (def.maxLength) res.maxItems = def.maxLength.value; if (def.exactLength) { res.minItems = def.exactLength.value; res.maxItems = def.exactLength.value; } return res; } function parseBigintDef(def) { const res = { type: "integer", format: "int64" }; if (!def.checks) return res; for (const check of def.checks) switch (check.kind) { case "min": if (check.inclusive) res.minimum = check.value; else res.exclusiveMinimum = check.value; break; case "max": if (check.inclusive) res.maximum = check.value; else res.exclusiveMaximum = check.value; break; case "multipleOf": res.multipleOf = check.value; } return res; } function parseBooleanDef() { return { type: "boolean" }; } function parseBrandedDef(_def, refs) { return parseDef(_def.type._def, refs); } var parseCatchDef = (def, refs) => { return parseDef(def.innerType._def, refs); }; function parseDateDef(def, refs, overrideDateStrategy) { const strategy = overrideDateStrategy != null ? overrideDateStrategy : refs.dateStrategy; if (Array.isArray(strategy)) return { anyOf: strategy.map((item) => parseDateDef(def, refs, item)) }; switch (strategy) { case "string": case "format:date-time": return { type: "string", format: "date-time" }; case "format:date": return { type: "string", format: "date" }; case "integer": return integerDateParser(def); } } var integerDateParser = (def) => { const res = { type: "integer", format: "unix-time" }; for (const check of def.checks) switch (check.kind) { case "min": res.minimum = check.value; break; case "max": res.maximum = check.value; } return res; }; function parseDefaultDef(_def, refs) { return { ...parseDef(_def.innerType._def, refs), default: _def.defaultValue() }; } function parseEffectsDef(_def, refs) { return refs.effectStrategy === "input" ? parseDef(_def.schema._def, refs) : parseAnyDef(); } function parseEnumDef(def) { return { type: "string", enum: Array.from(def.values) }; } var isJsonSchema7AllOfType = (type) => { if ("type" in type && type.type === "string") return false; return "allOf" in type; }; function parseIntersectionDef(def, refs) { const allOf = [parseDef(def.left._def, { ...refs, currentPath: [ ...refs.currentPath, "allOf", "0" ] }), parseDef(def.right._def, { ...refs, currentPath: [ ...refs.currentPath, "allOf", "1" ] })].filter((x) => !!x); const mergedAllOf = []; allOf.forEach((schema) => { if (isJsonSchema7AllOfType(schema)) mergedAllOf.push(...schema.allOf); else { let nestedSchema = schema; if ("additionalProperties" in schema && schema.additionalProperties === false) { const { additionalProperties: _additionalProperties, ...rest } = schema; nestedSchema = rest; } mergedAllOf.push(nestedSchema); } }); return mergedAllOf.length ? { allOf: mergedAllOf } : void 0; } function parseLiteralDef(def) { const parsedType = typeof def.value; if (parsedType !== "bigint" && parsedType !== "number" && parsedType !== "boolean" && parsedType !== "string") return { type: Array.isArray(def.value) ? "array" : "object" }; return { type: parsedType === "bigint" ? "integer" : parsedType, const: def.value }; } var emojiRegex = void 0; var zodPatterns = { /** * `c` was changed to `[cC]` to replicate /i flag */ cuid: /^[cC][^\s-]{8,}$/, cuid2: /^[0-9a-z]+$/, ulid: /^[0-9A-HJKMNP-TV-Z]{26}$/, /** * `a-z` was added to replicate /i flag */ email: /^(?!\.)(?!.*\.\.)([a-zA-Z0-9_'+\-\.]*)[a-zA-Z0-9_+-]@([a-zA-Z0-9][a-zA-Z0-9\-]*\.)+[a-zA-Z]{2,}$/, /** * Constructed a valid Unicode RegExp * * Lazily instantiate since this type of regex isn't supported * in all envs (e.g. React Native). * * See: * https://github.com/colinhacks/zod/issues/2433 * Fix in Zod: * https://github.com/colinhacks/zod/commit/9340fd51e48576a75adc919bff65dbc4a5d4c99b */ emoji: () => { if (emojiRegex === void 0) emojiRegex = RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$", "u"); return emojiRegex; }, /** * Unused */ uuid: /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/, /** * Unused */ ipv4: /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/, ipv4Cidr: /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/, /** * Unused */ ipv6: /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/, ipv6Cidr: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/, base64: /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/, base64url: /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/, nanoid: /^[a-zA-Z0-9_-]{21}$/, jwt: /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/ }; function parseStringDef(def, refs) { const res = { type: "string" }; if (def.checks) for (const check of def.checks) switch (check.kind) { case "min": res.minLength = typeof res.minLength === "number" ? Math.max(res.minLength, check.value) : check.value; break; case "max": res.maxLength = typeof res.maxLength === "number" ? Math.min(res.maxLength, check.value) : check.value; break; case "email": switch (refs.emailStrategy) { case "format:email": addFormat(res, "email", check.message, refs); break; case "format:idn-email": addFormat(res, "idn-email", check.message, refs); break; case "pattern:zod": addPattern(res, zodPatterns.email, check.message, refs); } break; case "url": addFormat(res, "uri", check.message, refs); break; case "uuid": addFormat(res, "uuid", check.message, refs); break; case "regex": addPattern(res, check.regex, check.message, refs); break; case "cuid": addPattern(res, zodPatterns.cuid, check.message, refs); break; case "cuid2": addPattern(res, zodPatterns.cuid2, check.message, refs); break; case "startsWith": addPattern(res, RegExp(`^${escapeLiteralCheckValue(check.value, refs)}`), check.message, refs); break; case "endsWith": addPattern(res, RegExp(`${escapeLiteralCheckValue(check.value, refs)}$`), check.message, refs); break; case "datetime": addFormat(res, "date-time", check.message, refs); break; case "date": addFormat(res, "date", check.message, refs); break; case "time": addFormat(res, "time", check.message, refs); break; case "duration": addFormat(res, "duration", check.message, refs); break; case "length": res.minLength = typeof res.minLength === "number" ? Math.max(res.minLength, check.value) : check.value; res.maxLength = typeof res.maxLength === "number" ? Math.min(res.maxLength, check.value) : check.value; break; case "includes": addPattern(res, RegExp(escapeLiteralCheckValue(check.value, refs)), check.message, refs); break; case "ip": if (check.version !== "v6") addFormat(res, "ipv4", check.message, refs); if (check.version !== "v4") addFormat(res, "ipv6", check.message, refs); break; case "base64url": addPattern(res, zodPatterns.base64url, check.message, refs); break; case "jwt": addPattern(res, zodPatterns.jwt, check.message, refs); break; case "cidr": if (check.version !== "v6") addPattern(res, zodPatterns.ipv4Cidr, check.message, refs); if (check.version !== "v4") addPattern(res, zodPatterns.ipv6Cidr, check.message, refs); break; case "emoji": addPattern(res, zodPatterns.emoji(), check.message, refs); break; case "ulid": addPattern(res, zodPatterns.ulid, check.message, refs); break; case "base64": switch (refs.base64Strategy) { case "format:binary": addFormat(res, "binary", check.message, refs); break; case "contentEncoding:base64": res.contentEncoding = "base64"; break; case "pattern:zod": addPattern(res, zodPatterns.base64, check.message, refs); } break; case "nanoid": addPattern(res, zodPatterns.nanoid, check.message, refs); } return res; } function escapeLiteralCheckValue(literal, refs) { return refs.patternStrategy === "escape" ? escapeNonAlphaNumeric(literal) : literal; } var ALPHA_NUMERIC = /* @__PURE__ */ new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789"); function escapeNonAlphaNumeric(source) { let result = ""; for (let i = 0; i < source.length; i++) { if (!ALPHA_NUMERIC.has(source[i])) result += "\\"; result += source[i]; } return result; } function addFormat(schema, value, message, refs) { var _a3; if (schema.format || ((_a3 = schema.anyOf) == null ? void 0 : _a3.some((x) => x.format))) { if (!schema.anyOf) schema.anyOf = []; if (schema.format) { schema.anyOf.push({ format: schema.format }); delete schema.format; } schema.anyOf.push({ format: value, ...message && refs.errorMessages && { errorMessage: { format: message } } }); } else schema.format = value; } function addPattern(schema, regex, message, refs) { var _a3; if (schema.pattern || ((_a3 = schema.allOf) == null ? void 0 : _a3.some((x) => x.pattern))) { if (!schema.allOf) schema.allOf = []; if (schema.pattern) { schema.allOf.push({ pattern: schema.pattern }); delete schema.pattern; } schema.allOf.push({ pattern: stringifyRegExpWithFlags(regex, refs), ...message && refs.errorMessages && { errorMessage: { pattern: message } } }); } else schema.pattern = stringifyRegExpWithFlags(regex, refs); } function stringifyRegExpWithFlags(regex, refs) { var _a3; if (!refs.applyRegexFlags || !regex.flags) return regex.source; const flags = { i: regex.flags.includes("i"), m: regex.flags.includes("m"), s: regex.flags.includes("s") }; const source = flags.i ? regex.source.toLowerCase() : regex.source; let pattern = ""; let isEscaped = false; let inCharGroup = false; let inCharRange = false; for (let i = 0; i < source.length; i++) { if (isEscaped) { pattern += source[i]; isEscaped = false; continue; } if (flags.i) { if (inCharGroup) { if (source[i].match(/[a-z]/)) { if (inCharRange) { pattern += source[i]; pattern += `${source[i - 2]}-${source[i]}`.toUpperCase(); inCharRange = false; } else if (source[i + 1] === "-" && ((_a3 = source[i + 2]) == null ? void 0 : _a3.match(/[a-z]/))) { pattern += source[i]; inCharRange = true; } else pattern += `${source[i]}${source[i].toUpperCase()}`; continue; } } else if (source[i].match(/[a-z]/)) { pattern += `[${source[i]}${source[i].toUpperCase()}]`; continue; } } if (flags.m) { if (source[i] === "^") { pattern += `(^|(?<=[\r ]))`; continue; } else if (source[i] === "$") { pattern += `($|(?=[\r ]))`; continue; } } if (flags.s && source[i] === ".") { pattern += inCharGroup ? `${source[i]}\r ` : `[${source[i]}\r ]`; continue; } pattern += source[i]; if (source[i] === "\\") isEscaped = true; else if (inCharGroup && source[i] === "]") inCharGroup = false; else if (!inCharGroup && source[i] === "[") inCharGroup = true; } try { new RegExp(pattern); } catch (e) { console.warn(`Could not convert regex pattern at ${refs.currentPath.join("/")} to a flag-independent form! Falling back to the flag-ignorant source`); return regex.source; } return pattern; } function parseRecordDef(def, refs) { var _a3, _b3, _c, _d, _e, _f; const schema = { type: "object", additionalProperties: (_a3 = parseDef(def.valueType._def, { ...refs, currentPath: [...refs.currentPath, "additionalProperties"] })) != null ? _a3 : refs.allowedAdditionalProperties }; if (((_b3 = def.keyType) == null ? void 0 : _b3._def.typeName) === "ZodString" && ((_c = def.keyType._def.checks) == null ? void 0 : _c.length)) { const { type: _type, ...keyType } = parseStringDef(def.keyType._def, refs); return { ...schema, propertyNames: keyType }; } else if (((_d = def.keyType) == null ? void 0 : _d._def.typeName) === "ZodEnum") return { ...schema, propertyNames: { enum: def.keyType._def.values } }; else if (((_e = def.keyType) == null ? void 0 : _e._def.typeName) === "ZodBranded" && def.keyType._def.type._def.typeName === "ZodString" && ((_f = def.keyType._def.type._def.checks) == null ? void 0 : _f.length)) { const { type: _type, ...keyType } = parseBrandedDef(def.keyType._def, refs); return { ...schema, propertyNames: keyType }; } return schema; } function parseMapDef(def, refs) { if (refs.mapStrategy === "record") return parseRecordDef(def, refs); return { type: "array", maxItems: 125, items: { type: "array", items: [parseDef(def.keyType._def, { ...refs, currentPath: [ ...refs.currentPath, "items", "items", "0" ] }) || parseAnyDef(), parseDef(def.valueType._def, { ...refs, currentPath: [ ...refs.currentPath, "items", "items", "1" ] }) || parseAnyDef()], minItems: 2, maxItems: 2 } }; } function parseNativeEnumDef(def) { const object = def.values; const actualValues = Object.keys(def.values).filter((key) => { return typeof object[object[key]] !== "number"; }).map((key) => object[key]); const parsedTypes = Array.from(new Set(actualValues.map((values) => typeof values))); return { type: parsedTypes.length === 1 ? parsedTypes[0] === "string" ? "string" : "number" : ["string", "number"], enum: actualValues }; } function parseNeverDef() { return { not: parseAnyDef() }; } function parseNullDef() { return { type: "null" }; } var primitiveMappings = { ZodString: "string", ZodNumber: "number", ZodBigInt: "integer", ZodBoolean: "boolean", ZodNull: "null" }; function parseUnionDef(def, refs) { const options = def.options instanceof Map ? Array.from(def.options.values()) : def.options; if (options.every((x) => x._def.typeName in primitiveMappings && (!x._def.checks || !x._def.checks.length))) { const types = options.reduce((types2, x) => { const type = primitiveMappings[x._def.typeName]; return type && !types2.includes(type) ? [...types2, type] : types2; }, []); return { type: types.length > 1 ? types : types[0] }; } else if (options.every((x) => x._def.typeName === "ZodLiteral" && !x.description)) { const types = options.reduce((acc, x) => { const type = typeof x._def.value; switch (type) { case "string": case "number": case "boolean": return [...acc, type]; case "bigint": return [...acc, "integer"]; case "object": if (x._def.value === null) return [...acc, "null"]; default: return acc; } }, []); if (types.length === options.length) { const uniqueTypes = types.filter((x, i, a) => a.indexOf(x) === i); return { type: uniqueTypes.length > 1 ? uniqueTypes : uniqueTypes[0], enum: options.reduce((acc, x) => { return acc.includes(x._def.value) ? acc : [...acc, x._def.value]; }, []) }; } } else if (options.every((x) => x._def.typeName === "ZodEnum")) return { type: "string", enum: options.reduce((acc, x) => [...acc, ...x._def.values.filter((x2) => !acc.includes(x2))], []) }; return asAnyOf(def, refs); } var asAnyOf = (def, refs) => { const anyOf = (def.options instanceof Map ? Array.from(def.options.values()) : def.options).map((x, i) => parseDef(x._def, { ...refs, currentPath: [ ...refs.currentPath, "anyOf", `${i}` ] })).filter((x) => !!x && (!refs.strictUnions || typeof x === "object" && Object.keys(x).length > 0)); return anyOf.length ? { anyOf } : void 0; }; function parseNullableDef(def, refs) { if ([ "ZodString", "ZodNumber", "ZodBigInt", "ZodBoolean", "ZodNull" ].includes(def.innerType._def.typeName) && (!def.innerType._def.checks || !def.innerType._def.checks.length)) return { type: [primitiveMappings[def.innerType._def.typeName], "null"] }; const base = parseDef(def.innerType._def, { ...refs, currentPath: [ ...refs.currentPath, "anyOf", "0" ] }); return base && { anyOf: [base, { type: "null" }] }; } function parseNumberDef(def) { const res = { type: "number" }; if (!def.checks) return res; for (const check of def.checks) switch (check.kind) { case "int": res.type = "integer"; break; case "min": if (check.inclusive) res.minimum = check.value; else res.exclusiveMinimum = check.value; break; case "max": if (check.inclusive) res.maximum = check.value; else res.exclusiveMaximum = check.value; break; case "multipleOf": res.multipleOf = check.value; } return res; } function parseObjectDef(def, refs) { const result = { type: "object", properties: {} }; const required = []; const shape = def.shape(); for (const propName in shape) { let propDef = shape[propName]; if (propDef === void 0 || propDef._def === void 0) continue; const propOptional = safeIsOptional(propDef); const parsedDef = parseDef(propDef._def, { ...refs, currentPath: [ ...refs.currentPath, "properties", propName ], propertyPath: [ ...refs.currentPath, "properties", propName ] }); if (parsedDef === void 0) continue; result.properties[propName] = parsedDef; if (!propOptional) required.push(propName); } if (required.length) result.required = required; const additionalProperties = decideAdditionalProperties(def, refs); if (additionalProperties !== void 0) result.additionalProperties = additionalProperties; return result; } function decideAdditionalProperties(def, refs) { if (def.catchall._def.typeName !== "ZodNever") return parseDef(def.catchall._def, { ...refs, currentPath: [...refs.currentPath, "additionalProperties"] }); switch (def.unknownKeys) { case "passthrough": return refs.allowedAdditionalProperties; case "strict": return refs.rejectedAdditionalProperties; case "strip": return refs.removeAdditionalStrategy === "strict" ? refs.allowedAdditionalProperties : refs.rejectedAdditionalProperties; } } function safeIsOptional(schema) { try { return schema.isOptional(); } catch (e) { return true; } } var parseOptionalDef = (def, refs) => { var _a3; if (refs.currentPath.toString() === ((_a3 = refs.propertyPath) == null ? void 0 : _a3.toString())) return parseDef(def.innerType._def, refs); const innerSchema = parseDef(def.innerType._def, { ...refs, currentPath: [ ...refs.currentPath, "anyOf", "1" ] }); return innerSchema ? { anyOf: [{ not: parseAnyDef() }, innerSchema] } : parseAnyDef(); }; var parsePipelineDef = (def, refs) => { if (refs.pipeStrategy === "input") return parseDef(def.in._def, refs); else if (refs.pipeStrategy === "output") return parseDef(def.out._def, refs); const inputSchema = parseDef(def.in._def, { ...refs, currentPath: [ ...refs.currentPath, "allOf", "0" ] }); return { allOf: [inputSchema, parseDef(def.out._def, { ...refs, currentPath: [ ...refs.currentPath, "allOf", inputSchema ? "1" : "0" ] })].filter((schema) => schema !== void 0) }; }; function parsePromiseDef(def, refs) { return parseDef(def.type._def, refs); } function parseSetDef(def, refs) { const schema = { type: "array", uniqueItems: true, items: parseDef(def.valueType._def, { ...refs, currentPath: [...refs.currentPath, "items"] }) }; if (def.minSize) schema.minItems = def.minSize.value; if (def.maxSize) schema.maxItems = def.maxSize.value; return schema; } function parseTupleDef(def, refs) { if (def.rest) return { type: "array", minItems: def.items.length, items: def.items.map((x, i) => parseDef(x._def, { ...refs, currentPath: [ ...refs.currentPath, "items", `${i}` ] })).reduce((acc, x) => x === void 0 ? acc : [...acc, x], []), additionalItems: parseDef(def.rest._def, { ...refs, currentPath: [...refs.currentPath, "additionalItems"] }) }; else return { type: "array", minItems: def.items.length, maxItems: def.items.length, items: def.items.map((x, i) => parseDef(x._def, { ...refs, currentPath: [ ...refs.currentPath, "items", `${i}` ] })).reduce((acc, x) => x === void 0 ? acc : [...acc, x], []) }; } function parseUndefinedDef() { return { not: parseAnyDef() }; } function parseUnknownDef() { return parseAnyDef(); } var parseReadonlyDef = (def, refs) => { return parseDef(def.innerType._def, refs); }; var selectParser = (def, typeName, refs) => { switch (typeName) { case "ZodString": return parseStringDef(def, refs); case "ZodNumber": return parseNumberDef(def); case "ZodObject": return parseObjectDef(def, refs); case "ZodBigInt": return parseBigintDef(def); case "ZodBoolean": return parseBooleanDef(); case "ZodDate": return parseDateDef(def, refs); case "ZodUndefined": return parseUndefinedDef(); case "ZodNull": return parseNullDef(); case "ZodArray": return parseArrayDef(def, refs); case "ZodUnion": case "ZodDiscriminatedUnion": return parseUnionDef(def, refs); case "ZodIntersection": return parseIntersectionDef(def, refs); case "ZodTuple": return parseTupleDef(def, refs); case "ZodRecord": return parseRecordDef(def, refs); case "ZodLiteral": return parseLiteralDef(def); case "ZodEnum": return parseEnumDef(def); case "ZodNativeEnum": return parseNativeEnumDef(def); case "ZodNullable": return parseNullableDef(def, refs); case "ZodOptional": return parseOptionalDef(def, refs); case "ZodMap": return parseMapDef(def, refs); case "ZodSet": return parseSetDef(def, refs); case "ZodLazy": return () => def.getter()._def; case "ZodPromise": return parsePromiseDef(def, refs); case "ZodNaN": case "ZodNever": return parseNeverDef(); case "ZodEffects": return parseEffectsDef(def, refs); case "ZodAny": return parseAnyDef(); case "ZodUnknown": return parseUnknownDef(); case "ZodDefault": return parseDefaultDef(def, refs); case "ZodBranded": return parseBrandedDef(def, refs); case "ZodReadonly": return parseReadonlyDef(def, refs); case "ZodCatch": return parseCatchDef(def, refs); case "ZodPipeline": return parsePipelineDef(def, refs); case "ZodFunction": case "ZodVoid": case "ZodSymbol": return; default: return /* @__PURE__ */ ((_) => void 0)(typeName); } }; var getRelativePath = (pathA, pathB) => { let i = 0; for (; i < pathA.length && i < pathB.length; i++) if (pathA[i] !== pathB[i]) break; return [(pathA.length - i).toString(), ...pathB.slice(i)].join("/"); }; function parseDef(def, refs, forceResolution = false) { var _a3; const seenItem = refs.seen.get(def); if (refs.override) { const overrideResult = (_a3 = refs.override) == null ? void 0 : _a3.call(refs, def, refs, seenItem, forceResolution); if (overrideResult !== ignoreOverride) return overrideResult; } if (seenItem && !forceResolution) { const seenSchema = get$ref(seenItem, refs); if (seenSchema !== void 0) return seenSchema; } const newItem = { def, path: refs.currentPath, jsonSchema: void 0 }; refs.seen.set(def, newItem); const jsonSchemaOrGetter = selectParser(def, def.typeName, refs); const jsonSchema2 = typeof jsonSchemaOrGetter === "function" ? parseDef(jsonSchemaOrGetter(), refs) : jsonSchemaOrGetter; if (jsonSchema2) addMeta(def, refs, jsonSchema2); if (refs.postProcess) { const postProcessResult = refs.postProcess(jsonSchema2, def, refs); newItem.jsonSchema = jsonSchema2; return postProcessResult; } newItem.jsonSchema = jsonSchema2; return jsonSchema2; } var get$ref = (item, refs) => { switch (refs.$refStrategy) { case "root": return { $ref: item.path.join("/") }; case "relative": return { $ref: getRelativePath(refs.currentPath, item.path) }; case "none": case "seen": if (item.path.length < refs.currentPath.length && item.path.every((value, index) => refs.currentPath[index] === value)) { console.warn(`Recursive reference detected at ${refs.currentPath.join("/")}! Defaulting to any`); return parseAnyDef(); } return refs.$refStrategy === "seen" ? parseAnyDef() : void 0; } }; var addMeta = (def, refs, jsonSchema2) => { if (def.description) jsonSchema2.description = def.description; return jsonSchema2; }; var getRefs = (options) => { const _options = getDefaultOptions(options); const currentPath = _options.name !== void 0 ? [ ..._options.basePath, _options.definitionPath, _options.name ] : _options.basePath; return { ..._options, currentPath, propertyPath: void 0, seen: new Map(Object.entries(_options.definitions).map(([name3, def]) => [def._def, { def: def._def, path: [ ..._options.basePath, _options.definitionPath, name3 ], jsonSchema: void 0 }])) }; }; var zod3ToJsonSchema = (schema, options) => { var _a3; const refs = getRefs(options); let definitions = typeof options === "object" && options.definitions ? Object.entries(options.definitions).reduce((acc, [name4, schema2]) => { var _a4; return { ...acc, [name4]: (_a4 = parseDef(schema2._def, { ...refs, currentPath: [ ...refs.basePath, refs.definitionPath, name4 ] }, true)) != null ? _a4 : parseAnyDef() }; }, {}) : void 0; const name3 = typeof options === "string" ? options : (options == null ? void 0 : options.nameStrategy) === "title" ? void 0 : options == null ? void 0 : options.name; const main = (_a3 = parseDef(schema._def, name3 === void 0 ? refs : { ...refs, currentPath: [ ...refs.basePath, refs.definitionPath, name3 ] }, false)) != null ? _a3 : parseAnyDef(); const title = typeof options === "object" && options.name !== void 0 && options.nameStrategy === "title" ? options.name : void 0; if (title !== void 0) main.title = title; const combined = name3 === void 0 ? definitions ? { ...main, [refs.definitionPath]: definitions } : main : { $ref: [ ...refs.$refStrategy === "relative" ? [] : refs.basePath, refs.definitionPath, name3 ].join("/"), [refs.definitionPath]: { ...definitions, [name3]: main } }; combined.$schema = "http://json-schema.org/draft-07/schema#"; return combined; }; var schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema"); function lazySchema(createSchema) { let schema; return () => { if (schema == null) schema = createSchema(); return schema; }; } function jsonSchema(jsonSchema2, { validate } = {}) { return { [schemaSymbol]: true, _type: void 0, get jsonSchema() { if (typeof jsonSchema2 === "function") jsonSchema2 = jsonSchema2(); return jsonSchema2; }, validate }; } function isSchema(value) { return typeof value === "object" && value !== null && schemaSymbol in value && value[schemaSymbol] === true && "jsonSchema" in value && "validate" in value; } function asSchema(schema) { return schema == null ? jsonSchema({ type: "object", properties: {}, additionalProperties: false }) : isSchema(schema) ? schema : "~standard" in schema ? schema["~standard"].vendor === "zod" ? zodSchema(schema) : standardSchema(schema) : schema(); } function standardSchema(standardSchema2) { return jsonSchema(() => { if (!hasStandardJsonSchema(standardSchema2)) throw new Error(`Standard schema vendor '${standardSchema2["~standard"].vendor}' does not support JSON Schema conversion.`); return addAdditionalPropertiesToJsonSchema(standardSchema2["~standard"].jsonSchema.input({ target: "draft-07" })); }, { validate: async (value) => { const result = await standardSchema2["~standard"].validate(value); return "value" in result ? { success: true, value: result.value } : { success: false, error: new TypeValidationError({ value, cause: result.issues }) }; } }); } function hasStandardJsonSchema(schema) { return schema["~standard"].jsonSchema != null; } function zod3Schema(zodSchema2, options) { var _a3; const useReferences = (_a3 = options == null ? void 0 : options.useReferences) != null ? _a3 : false; return jsonSchema(() => zod3ToJsonSchema(zodSchema2, { $refStrategy: useReferences ? "root" : "none" }), { validate: async (value) => { const result = await zodSchema2.safeParseAsync(value); return result.success ? { success: true, value: result.data } : { success: false, error: result.error }; } }); } function zod4Schema(zodSchema2, options) { var _a3; const useReferences = (_a3 = options == null ? void 0 : options.useReferences) != null ? _a3 : false; return jsonSchema(() => addAdditionalPropertiesToJsonSchema(toJSONSchema(zodSchema2, { target: "draft-7", io: "input", reused: useReferences ? "ref" : "inline" })), { validate: async (value) => { const result = await safeParseAsync(zodSchema2, value); return result.success ? { success: true, value: result.data } : { success: false, error: result.error }; } }); } function isZod4Schema(zodSchema2) { return "_zod" in zodSchema2; } function zodSchema(zodSchema2, options) { if (isZod4Schema(zodSchema2)) return zod4Schema(zodSchema2, options); else return zod3Schema(zodSchema2, options); } async function validateTypes({ value, schema, context }) { const result = await safeValidateTypes({ value, schema, context }); if (!result.success) throw TypeValidationError.wrap({ value, cause: result.error, context }); return result.value; } async function safeValidateTypes({ value, schema, context }) { const actualSchema = asSchema(schema); try { if (actualSchema.validate == null) return { success: true, value, rawValue: value }; const result = await actualSchema.validate(value); if (result.success) return { success: true, value: result.value, rawValue: value }; return { success: false, error: TypeValidationError.wrap({ value, cause: result.error, context }), rawValue: value }; } catch (error) { return { success: false, error: TypeValidationError.wrap({ value, cause: error, context }), rawValue: value }; } } async function parseJSON({ text, schema }) { try { const value = secureJsonParse(text); if (schema == null) return value; return await validateTypes({ value, schema }); } catch (error) { if (JSONParseError.isInstance(error) || TypeValidationError.isInstance(error)) throw error; throw new JSONParseError({ text, cause: error }); } } async function safeParseJSON({ text, schema }) { try { const value = secureJsonParse(text); if (schema == null) return { success: true, value, rawValue: value }; return await safeValidateTypes({ value, schema }); } catch (error) { return { success: false, error: JSONParseError.isInstance(error) ? error : new JSONParseError({ text, cause: error }), rawValue: void 0 }; } } function parseJsonEventStream({ stream, schema }) { return stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream()).pipeThrough(new TransformStream({ async transform({ data }, controller) { if (data === "[DONE]") return; controller.enqueue(await safeParseJSON({ text: data, schema })); } })); } async function parseProviderOptions({ provider, providerOptions, schema }) { if ((providerOptions == null ? void 0 : providerOptions[provider]) == null) return; const parsedProviderOptions = await safeValidateTypes({ value: providerOptions[provider], schema }); if (!parsedProviderOptions.success) throw new InvalidArgumentError$1({ argument: "providerOptions", message: `invalid ${provider} provider options`, cause: parsedProviderOptions.error }); return parsedProviderOptions.value; } var getOriginalFetch4 = () => globalThis.fetch; var postJsonToApi = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch }) => await postToApi({ url, headers: { "Content-Type": "application/json", ...headers }, body: { content: JSON.stringify(body), values: body }, failedResponseHandler, successfulResponseHandler, abortSignal, fetch }); var postFormDataToApi = async ({ url, headers, formData, failedResponseHandler, successfulResponseHandler, abortSignal, fetch }) => await postToApi({ url, headers, body: { content: formData, values: Object.fromEntries(formData.entries()) }, failedResponseHandler, successfulResponseHandler, abortSignal, fetch }); var postToApi = async ({ url, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch = getOriginalFetch4() }) => { try { const response = await fetch(url, { method: "POST", headers: withUserAgentSuffix(headers, `ai-sdk/provider-utils/${VERSION$3}`, getRuntimeEnvironmentUserAgent()), body: body.content, signal: abortSignal }); const responseHeaders = extractResponseHeaders(response); if (!response.ok) { let errorInformation; try { errorInformation = await failedResponseHandler({ response, url, requestBodyValues: body.values }); } catch (error) { if (isAbortError(error) || APICallError.isInstance(error)) throw error; throw new APICallError({ message: "Failed to process error response", cause: error, statusCode: response.status, url, responseHeaders, requestBodyValues: body.values }); } throw errorInformation.value; } try { return await successfulResponseHandler({ response, url, requestBodyValues: body.values }); } catch (error) { if (error instanceof Error) { if (isAbortError(error) || APICallError.isInstance(error)) throw error; } throw new APICallError({ message: "Failed to process successful response", cause: error, statusCode: response.status, url, responseHeaders, requestBodyValues: body.values }); } } catch (error) { throw handleFetchError({ error, url, requestBodyValues: body.values }); } }; function tool(tool2) { return tool2; } function createProviderExecutedToolFactory({ id, inputSchema, outputSchema, supportsDeferredResults }) { return ({ onInputStart, onInputDelta, onInputAvailable, ...args }) => tool({ type: "provider", isProviderExecuted: true, id, args, inputSchema, outputSchema, onInputStart, onInputDelta, onInputAvailable, supportsDeferredResults }); } async function resolve(value) { if (typeof value === "function") value = value(); return Promise.resolve(value); } function resolveFullMediaType({ part }) { if (isFullMediaType(part.mediaType)) return part.mediaType; if (part.data.type === "data") { const detected = detectMediaType({ data: part.data.data, topLevelType: getTopLevelMediaType(part.mediaType) }); if (detected) return detected; throw new UnsupportedFunctionalityError({ functionality: `file of media type "${part.mediaType}" must specify subtype since it could not be auto-detected` }); } throw new UnsupportedFunctionalityError({ functionality: `file of media type "${part.mediaType}" must specify subtype since it is not passed as inline bytes` }); } var retryWithExponentialBackoff = ({ maxRetries = 2, initialDelayInMs = 2e3, backoffFactor = 2, abortSignal, shouldRetry, getDelayInMs = ({ exponentialBackoffDelay }) => exponentialBackoffDelay, createRetryError = ({ message }) => new Error(message) }) => async (f) => retryWithExponentialBackoffInternal(f, { maxRetries, delayInMs: initialDelayInMs, backoffFactor, abortSignal, shouldRetry, getDelayInMs, createRetryError }); async function retryWithExponentialBackoffInternal(f, { maxRetries, delayInMs, backoffFactor, abortSignal, shouldRetry, getDelayInMs, createRetryError }, errors = []) { try { return await f(); } catch (error) { if (isAbortError(error)) throw error; if (maxRetries === 0) throw error; const errorMessage = getErrorMessage(error); const newErrors = [...errors, error]; const tryNumber = newErrors.length; if (tryNumber > maxRetries) throw createRetryError({ message: `Failed after ${tryNumber} attempts. Last error: ${errorMessage}`, reason: "maxRetriesExceeded", errors: newErrors }); if (await shouldRetry(error) && tryNumber <= maxRetries) { await delay(getDelayInMs({ error, exponentialBackoffDelay: delayInMs }), { abortSignal }); return retryWithExponentialBackoffInternal(f, { maxRetries, delayInMs: backoffFactor * delayInMs, backoffFactor, abortSignal, shouldRetry, getDelayInMs, createRetryError }, newErrors); } if (tryNumber === 1) throw error; throw createRetryError({ message: `Failed after ${tryNumber} attempts with non-retryable error: '${errorMessage}'`, reason: "errorNotRetryable", errors: newErrors }); } } var textDecoder2 = new TextDecoder(); function wrapResponseBodyStream({ stream, url, requestBodyValues, statusCode, responseHeaders }) { const reader = stream.getReader(); let readerReleased = false; const releaseReader = () => { if (!readerReleased) { reader.releaseLock(); readerReleased = true; } }; return new ReadableStream({ async pull(controller) { try { const { done, value } = await reader.read(); if (done) { releaseReader(); controller.close(); } else controller.enqueue(value); } catch (error) { releaseReader(); if (isAbortError(error)) { controller.error(error); return; } controller.error(handleFetchError({ error: new APICallError({ message: "Failed to process successful response", cause: error, statusCode, url, responseHeaders, requestBodyValues }), url, requestBodyValues })); } }, async cancel(reason) { try { await reader.cancel(reason); } finally { releaseReader(); } } }); } async function readResponseBodyAsText({ response, url }) { return textDecoder2.decode(await readResponseWithSizeLimit({ response, url })); } var createJsonErrorResponseHandler = ({ errorSchema, errorToMessage, isRetryable }) => async ({ response, url, requestBodyValues }) => { const responseBody = await readResponseBodyAsText({ response, url }); const responseHeaders = extractResponseHeaders(response); if (responseBody.trim() === "") return { responseHeaders, value: new APICallError({ message: response.statusText, url, requestBodyValues, statusCode: response.status, responseHeaders, responseBody, isRetryable: isRetryable == null ? void 0 : isRetryable(response) }) }; try { const parsedError = await parseJSON({ text: responseBody, schema: errorSchema }); return { responseHeaders, value: new APICallError({ message: errorToMessage(parsedError), url, requestBodyValues, statusCode: response.status, responseHeaders, responseBody, data: parsedError, isRetryable: isRetryable == null ? void 0 : isRetryable(response, parsedError) }) }; } catch (e) { return { responseHeaders, value: new APICallError({ message: response.statusText, url, requestBodyValues, statusCode: response.status, responseHeaders, responseBody, isRetryable: isRetryable == null ? void 0 : isRetryable(response) }) }; } }; var createEventSourceResponseHandler = (chunkSchema) => async ({ response, url, requestBodyValues }) => { const responseHeaders = extractResponseHeaders(response); if (response.body == null) throw new EmptyResponseBodyError({}); return { responseHeaders, value: parseJsonEventStream({ stream: wrapResponseBodyStream({ stream: response.body, url, requestBodyValues, statusCode: response.status, responseHeaders }), schema: chunkSchema }) }; }; var createJsonResponseHandler = (responseSchema) => async ({ response, url, requestBodyValues }) => { const responseBody = await readResponseBodyAsText({ response, url }); const parsedResult = await safeParseJSON({ text: responseBody, schema: responseSchema }); const responseHeaders = extractResponseHeaders(response); if (!parsedResult.success) throw new APICallError({ message: "Invalid JSON response", cause: parsedResult.error, statusCode: response.status, responseHeaders, responseBody, url, requestBodyValues }); return { responseHeaders, value: parsedResult.value, rawValue: parsedResult.rawValue }; }; var createJsonLinesResponseHandler = (responseSchema) => async ({ response }) => { const responseHeaders = extractResponseHeaders(response); if (response.body == null) throw new EmptyResponseBodyError({}); return { responseHeaders, value: parseJsonLines({ stream: response.body, schema: responseSchema }) }; }; async function* parseJsonLines({ stream, schema }) { const reader = stream.getReader(); const decoder = new TextDecoder(); let buffer = ""; let finished = false; try { while (true) { const { done, value } = await reader.read(); if (done) { finished = true; buffer += decoder.decode(); break; } buffer += decoder.decode(value, { stream: true }); let lineEnd = buffer.indexOf("\n"); while (lineEnd !== -1) { const line = buffer.slice(0, lineEnd).replace(/\r$/, ""); buffer = buffer.slice(lineEnd + 1); if (line.trim().length > 0) yield await parseJSON({ text: line, schema }); lineEnd = buffer.indexOf("\n"); } } const finalLine = buffer.replace(/\r$/, ""); if (finalLine.trim().length > 0) yield await parseJSON({ text: finalLine, schema }); } finally { if (!finished) await reader.cancel().catch(() => {}); reader.releaseLock(); } } function isJSONSerializable(value) { if (value === null || value === void 0) return true; const type = typeof value; if (type === "string" || type === "number" || type === "boolean") return true; if (type === "function" || type === "symbol" || type === "bigint") return false; if (Array.isArray(value)) return value.every(isJSONSerializable); if (Object.getPrototypeOf(value) === Object.prototype) return Object.values(value).every(isJSONSerializable); return false; } var name2$2 = "AI_SerializationError"; var marker3$2 = `vercel.ai.error.${name2$2}`; var symbol2$2 = Symbol.for(marker3$2); var _a2$2; var _b2$2; var SerializationError = class extends (_b2$2 = AISDKError, _a2$2 = symbol2$2, _b2$2) { constructor({ message = "Failed to serialize value.", cause } = {}) { super({ name: name2$2, message, cause }); this[_a2$2] = true; } static isInstance(error) { return AISDKError.hasMarker(error, marker3$2); } }; function serializeModelOptions(options) { const serializableConfig = {}; for (const [key, value] of Object.entries(options.config)) if (key === "headers") { const resolvedHeaders = resolveSync(value); if (isJSONSerializable(resolvedHeaders)) serializableConfig[key] = resolvedHeaders; } else if (isJSONSerializable(value)) serializableConfig[key] = value; return { modelId: options.modelId, config: serializableConfig }; } function resolveSync(value) { let next = value; if (typeof value === "function") next = value(); if (next instanceof Promise) throw new SerializationError({ message: "Cannot serialize asynchronous model options." }); return next; } var StreamingToolCallTracker = class { constructor(controller, options = {}) { this.toolCalls = /* @__PURE__ */ new Set(); this.toolCallsById = /* @__PURE__ */ new Map(); this.toolCallsByIndex = /* @__PURE__ */ new Map(); var _a3, _b3; this.controller = controller; this._generateId = (_a3 = options.generateId) != null ? _a3 : generateId; this.typeValidation = (_b3 = options.typeValidation) != null ? _b3 : "none"; this.extractMetadata = options.extractMetadata; this.buildToolCallProviderMetadata = options.buildToolCallProviderMetadata; } /** * Process a tool call delta from a streaming response chunk. * Emits tool-input-start, tool-input-delta, tool-input-end, and tool-call * events as appropriate. */ processDelta(toolCallDelta) { const { id, index } = toolCallDelta; let toolCall = id != null && id.length > 0 ? this.toolCallsById.get(id) : index != null ? this.toolCallsByIndex.get(index) : this.latestToolCall; if (toolCall == null) toolCall = this.processNewToolCall(toolCallDelta); else this.processExistingToolCall(toolCall, toolCallDelta); if (index != null) this.toolCallsByIndex.set(index, toolCall); this.latestToolCall = toolCall; } /** * Finalize any unfinished tool calls. Should be called during the stream's * flush handler to ensure all tool calls are properly completed. */ flush() { for (const toolCall of this.toolCalls) if (!toolCall.hasFinished) this.finishToolCall(toolCall); } processNewToolCall(toolCallDelta) { var _a3, _b3, _c; if (this.typeValidation === "required") { if (toolCallDelta.type !== "function") throw new InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'function' type.` }); } else if (this.typeValidation === "if-present") { if (toolCallDelta.type != null && toolCallDelta.type !== "function") throw new InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'function' type.` }); } if (toolCallDelta.id == null) throw new InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'id' to be a string.` }); if (((_a3 = toolCallDelta.function) == null ? void 0 : _a3.name) == null) throw new InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'function.name' to be a string.` }); this.controller.enqueue({ type: "tool-input-start", id: toolCallDelta.id, toolName: toolCallDelta.function.name }); const metadata = (_b3 = this.extractMetadata) == null ? void 0 : _b3.call(this, toolCallDelta); const toolCall = { id: toolCallDelta.id, type: "function", function: { name: toolCallDelta.function.name, arguments: (_c = toolCallDelta.function.arguments) != null ? _c : "" }, hasFinished: false, metadata }; this.toolCalls.add(toolCall); if (toolCall.id.length > 0) this.toolCallsById.set(toolCall.id, toolCall); if (toolCall.function.arguments.length > 0) this.controller.enqueue({ type: "tool-input-delta", id: toolCall.id, delta: toolCall.function.arguments }); return toolCall; } processExistingToolCall(toolCall, toolCallDelta) { var _a3; if (toolCall.hasFinished) return; if (((_a3 = toolCallDelta.function) == null ? void 0 : _a3.arguments) != null) { toolCall.function.arguments += toolCallDelta.function.arguments; this.controller.enqueue({ type: "tool-input-delta", id: toolCall.id, delta: toolCallDelta.function.arguments }); } } finishToolCall(toolCall) { var _a3, _b3; this.controller.enqueue({ type: "tool-input-end", id: toolCall.id }); const providerMetadata = (_a3 = this.buildToolCallProviderMetadata) == null ? void 0 : _a3.call(this, toolCall.metadata); this.controller.enqueue({ type: "tool-call", toolCallId: (_b3 = toolCall.id) != null ? _b3 : this._generateId(), toolName: toolCall.function.name, input: toolCall.function.arguments, ...providerMetadata ? { providerMetadata } : {} }); toolCall.hasFinished = true; } }; var TRANSCRIPTION_STREAM_START_FRAME_TYPE = "transcription-stream.start"; var TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE = "transcription-stream.audio-done"; function parseTranscriptionStreamPart(text) { let value; try { value = secureJsonParse(text); } catch (e) { return; } if (value == null || typeof value !== "object" || Array.isArray(value)) return; const part = value; switch (part.type) { case "stream-start": return Array.isArray(part.warnings) && part.warnings.every(isWarning) ? part : void 0; case "transcript-delta": return isString(part.delta) && isOptional(part.id, isString) && isOptional(part.providerMetadata, isRecord$1) ? part : void 0; case "transcript-partial": return isString(part.text) && isOptional(part.id, isString) && isOptional(part.startSecond, isNumber) && isOptional(part.durationInSeconds, isNumber) && isOptional(part.channelIndex, isNumber) && isOptional(part.providerMetadata, isRecord$1) ? part : void 0; case "transcript-final": return isString(part.text) && isOptional(part.id, isString) && isOptional(part.startSecond, isNumber) && isOptional(part.endSecond, isNumber) && isOptional(part.channelIndex, isNumber) && isOptional(part.providerMetadata, isRecord$1) ? part : void 0; case "finish": return isString(part.text) && Array.isArray(part.segments) && part.segments.every(isSegment) && isOptional(part.language, isString) && isOptional(part.durationInSeconds, isNumber) && isOptional(part.providerMetadata, isRecord$1) ? part : void 0; case "response-metadata": { if (!(isOptional(part.modelId, isString) && isOptional(part.headers, isRecord$1))) return; const timestamp = part.timestamp; if (timestamp == null) return { ...part, timestamp: void 0 }; if (typeof timestamp !== "string") return; const revived = new Date(timestamp); return Number.isNaN(revived.getTime()) ? void 0 : { ...part, timestamp: revived }; } case "raw": return "rawValue" in part ? part : void 0; case "error": return "error" in part ? part : void 0; default: return; } } function isString(value) { return typeof value === "string"; } function isNumber(value) { return typeof value === "number"; } function isOptional(value, check) { return value === void 0 || check(value); } function isWarning(value) { return isRecord$1(value) && isString(value.type); } function isSegment(value) { return isRecord$1(value) && isString(value.text) && isNumber(value.startSecond) && isNumber(value.endSecond); } function withoutTrailingSlash(url) { return url == null ? void 0 : url.replace(/\/$/, ""); } function isExecutableTool(tool2) { return tool2 != null && typeof tool2.execute === "function"; } function isAsyncIterable(obj) { return obj != null && typeof obj[Symbol.asyncIterator] === "function"; } async function* executeTool({ tool: tool2, input, options }) { const result = tool2.execute(input, options); if (isAsyncIterable(result)) { let lastOutput; for await (const output of result) { lastOutput = output; yield { type: "preliminary", output }; } yield { type: "final", output: lastOutput }; } else yield { type: "final", output: await result }; } function getToolCaller(tool2) { return tool2 == null ? void 0 : tool2.experimental_toolCaller; } //#endregion //#region node_modules/@vercel/oidc/dist/get-context.js var require_get_context = /* @__PURE__ */ __commonJSMin(((exports, module) => { var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var get_context_exports = {}; __export(get_context_exports, { SYMBOL_FOR_REQ_CONTEXT: () => SYMBOL_FOR_REQ_CONTEXT, getContext: () => getContext }); module.exports = __toCommonJS(get_context_exports); var SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context"); function getContext() { return globalThis[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {}; } 0 && (module.exports = { SYMBOL_FOR_REQ_CONTEXT, getContext }); })); //#endregion //#region node_modules/@vercel/oidc/dist/auth-errors.js var require_auth_errors = /* @__PURE__ */ __commonJSMin(((exports, module) => { var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var auth_errors_exports = {}; __export(auth_errors_exports, { AccessTokenMissingError: () => AccessTokenMissingError, RefreshAccessTokenFailedError: () => RefreshAccessTokenFailedError }); module.exports = __toCommonJS(auth_errors_exports); var AccessTokenMissingError = class extends Error { constructor() { super("No authentication found. Please log in with the Vercel CLI (vercel login)."); this.name = "AccessTokenMissingError"; } }; var RefreshAccessTokenFailedError = class extends Error { constructor(cause) { super("Failed to refresh authentication token.", { cause }); this.name = "RefreshAccessTokenFailedError"; } }; 0 && (module.exports = { AccessTokenMissingError, RefreshAccessTokenFailedError }); })); //#endregion //#region node_modules/@ai-sdk/gateway/dist/index.js var import_index_browser = (/* @__PURE__ */ __commonJSMin(((exports, module) => { var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var index_browser_exports = {}; __export(index_browser_exports, { AccessTokenMissingError: () => import_auth_errors.AccessTokenMissingError, RefreshAccessTokenFailedError: () => import_auth_errors.RefreshAccessTokenFailedError, getContext: () => import_get_context.getContext, getVercelOidcToken: () => getVercelOidcToken, getVercelOidcTokenSync: () => getVercelOidcTokenSync, getVercelToken: () => getVercelToken }); module.exports = __toCommonJS(index_browser_exports); var import_get_context = require_get_context(); var import_auth_errors = require_auth_errors(); async function getVercelOidcToken() { return ""; } function getVercelOidcTokenSync() { return ""; } async function getVercelToken() { throw new Error("getVercelToken is not supported in browser environments"); } 0 && (module.exports = { AccessTokenMissingError, RefreshAccessTokenFailedError, getContext, getVercelOidcToken, getVercelOidcTokenSync, getVercelToken }); })))(); var GATEWAY_REALTIME_SUBPROTOCOL = "ai-gateway-realtime.v1"; var GATEWAY_TRANSCRIPTION_SUBPROTOCOL = "ai-gateway-transcription.v1"; var GATEWAY_AUTH_SUBPROTOCOL_PREFIX = "ai-gateway-auth."; var GATEWAY_TEAM_SUBPROTOCOL_PREFIX = "ai-gateway-team."; function getGatewayRealtimeProtocols(token, options) { return buildGatewayProtocols(GATEWAY_REALTIME_SUBPROTOCOL, token, options); } function getGatewayTranscriptionProtocols(token, options) { return buildGatewayProtocols(GATEWAY_TRANSCRIPTION_SUBPROTOCOL, token, options); } function buildGatewayProtocols(marker12, token, options) { const protocols = [marker12, `${GATEWAY_AUTH_SUBPROTOCOL_PREFIX}${token}`]; if (options == null ? void 0 : options.teamIdOrSlug) protocols.push(`${GATEWAY_TEAM_SUBPROTOCOL_PREFIX}${encodeSubprotocolValue(options.teamIdOrSlug)}`); return protocols; } function encodeSubprotocolValue(value) { const bytes = new TextEncoder().encode(value); let binary = ""; for (const byte of bytes) binary += String.fromCharCode(byte); return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/u, ""); } var z$1 = { any, array, boolean, discriminatedUnion, enum: _enum, literal, number, object, record, string, union, unknown }; var symbol$1 = Symbol.for("vercel.ai.gateway.error"); var _a$1; var _b$1; var GatewayError = class _GatewayError extends (_b$1 = Error, _a$1 = symbol$1, _b$1) { constructor({ message, statusCode = 500, cause, generationId, isRetryable = statusCode != null && (statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500) }) { super(generationId ? `${message} [${generationId}]` : message); this[_a$1] = true; this.statusCode = statusCode; this.cause = cause; this.generationId = generationId; this.isRetryable = isRetryable; } /** * Checks if the given error is a Gateway Error. * @param {unknown} error - The error to check. * @returns {boolean} True if the error is a Gateway Error, false otherwise. */ static isInstance(error) { return _GatewayError.hasMarker(error); } static hasMarker(error) { return typeof error === "object" && error !== null && symbol$1 in error && error[symbol$1] === true; } }; var name$1 = "GatewayAuthenticationError"; var marker2$1 = `vercel.ai.gateway.error.${name$1}`; var symbol2$1 = Symbol.for(marker2$1); var _a2$1; var _b2$1; var GatewayAuthenticationError = class _GatewayAuthenticationError extends (_b2$1 = GatewayError, _a2$1 = symbol2$1, _b2$1) { constructor({ message = "Authentication failed", statusCode = 401, cause, generationId } = {}) { super({ message, statusCode, cause, generationId }); this[_a2$1] = true; this.name = name$1; this.type = "authentication_error"; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol2$1 in error; } /** * Creates a contextual error message when authentication fails */ static createContextualError({ apiKeyProvided, oidcTokenProvided, statusCode = 401, cause, generationId }) { let contextualMessage; if (apiKeyProvided) contextualMessage = `AI Gateway authentication failed: Invalid API key or token. Create a new API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys Provide an API key or Vercel access token via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable.`; else if (oidcTokenProvided) contextualMessage = `AI Gateway authentication failed: Invalid OIDC token. Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token. Alternatively, use an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys or pass a Vercel access token via the 'apiKey' option.`; else contextualMessage = `AI Gateway authentication failed: No authentication provided. Option 1 - API key: Create an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys Provide via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable. Option 2 - Vercel access token: Pass a Vercel personal access token or Vercel app access token via the 'apiKey' option. Option 3 - OIDC token: Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token.`; return new _GatewayAuthenticationError({ message: contextualMessage, statusCode, cause, generationId }); } }; var name2$1 = "GatewayInvalidRequestError"; var marker3$1 = `vercel.ai.gateway.error.${name2$1}`; var symbol3$1 = Symbol.for(marker3$1); var _a3$1; var _b3$1; var GatewayInvalidRequestError = class extends (_b3$1 = GatewayError, _a3$1 = symbol3$1, _b3$1) { constructor({ message = "Invalid request", statusCode = 400, cause, generationId } = {}) { super({ message, statusCode, cause, generationId }); this[_a3$1] = true; this.name = name2$1; this.type = "invalid_request_error"; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol3$1 in error; } }; var name3$1 = "GatewayRateLimitError"; var marker4$1 = `vercel.ai.gateway.error.${name3$1}`; var symbol4$1 = Symbol.for(marker4$1); var _a4$1; var _b4$1; var GatewayRateLimitError = class extends (_b4$1 = GatewayError, _a4$1 = symbol4$1, _b4$1) { constructor({ message = "Rate limit exceeded", statusCode = 429, cause, generationId } = {}) { super({ message, statusCode, cause, generationId }); this[_a4$1] = true; this.name = name3$1; this.type = "rate_limit_exceeded"; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol4$1 in error; } }; var name4$1 = "GatewayModelNotFoundError"; var marker5$1 = `vercel.ai.gateway.error.${name4$1}`; var symbol5$1 = Symbol.for(marker5$1); var modelNotFoundParamSchema = lazySchema(() => zodSchema(z$1.object({ modelId: z$1.string() }))); var _a5$1; var _b5$1; var GatewayModelNotFoundError = class extends (_b5$1 = GatewayError, _a5$1 = symbol5$1, _b5$1) { constructor({ message = "Model not found", statusCode = 404, modelId, cause, generationId } = {}) { super({ message, statusCode, cause, generationId }); this[_a5$1] = true; this.name = name4$1; this.type = "model_not_found"; this.modelId = modelId; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol5$1 in error; } }; var name5$1 = "GatewayNotFoundError"; var marker6$1 = `vercel.ai.gateway.error.${name5$1}`; var symbol6$1 = Symbol.for(marker6$1); var _a6$1; var _b6$1; var GatewayNotFoundError = class extends (_b6$1 = GatewayError, _a6$1 = symbol6$1, _b6$1) { constructor({ message = "Resource not found", statusCode = 404, cause, generationId } = {}) { super({ message, statusCode, cause, generationId }); this[_a6$1] = true; this.name = name5$1; this.type = "not_found"; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol6$1 in error; } }; var name6$1 = "GatewayInternalServerError"; var marker7$1 = `vercel.ai.gateway.error.${name6$1}`; var symbol7$1 = Symbol.for(marker7$1); var _a7$1; var _b7$1; var GatewayInternalServerError = class extends (_b7$1 = GatewayError, _a7$1 = symbol7$1, _b7$1) { constructor({ message = "Internal server error", statusCode = 500, cause, generationId } = {}) { super({ message, statusCode, cause, generationId }); this[_a7$1] = true; this.name = name6$1; this.type = "internal_server_error"; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol7$1 in error; } }; var name7$1 = "GatewayFailedDependencyError"; var marker8$1 = `vercel.ai.gateway.error.${name7$1}`; var symbol8$1 = Symbol.for(marker8$1); var _a8$1; var _b8$1; var GatewayFailedDependencyError = class extends (_b8$1 = GatewayError, _a8$1 = symbol8$1, _b8$1) { constructor({ message = "Failed dependency", statusCode = 424, cause, generationId } = {}) { super({ message, statusCode, cause, generationId }); this[_a8$1] = true; this.name = name7$1; this.type = "failed_dependency"; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol8$1 in error; } }; var name8$1 = "GatewayForbiddenError"; var marker9$1 = `vercel.ai.gateway.error.${name8$1}`; var symbol9$1 = Symbol.for(marker9$1); var forbiddenParamSchema = lazySchema(() => zodSchema(z$1.object({ ruleId: z$1.string() }))); var _a9$1; var _b9$1; var GatewayForbiddenError = class extends (_b9$1 = GatewayError, _a9$1 = symbol9$1, _b9$1) { constructor({ message = "Forbidden", statusCode = 403, cause, generationId, ruleId } = {}) { super({ message, statusCode, cause, generationId }); this[_a9$1] = true; this.name = name8$1; this.type = "forbidden"; this.ruleId = ruleId; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol9$1 in error; } }; var name9$1 = "GatewayResponseError"; var marker10$1 = `vercel.ai.gateway.error.${name9$1}`; var symbol10$1 = Symbol.for(marker10$1); var _a10$1; var _b10$1; var GatewayResponseError = class extends (_b10$1 = GatewayError, _a10$1 = symbol10$1, _b10$1) { constructor({ message = "Invalid response from Gateway", statusCode = 502, response, validationError, cause, generationId, isRetryable } = {}) { super({ message, statusCode, cause, generationId, isRetryable }); this[_a10$1] = true; this.name = name9$1; this.type = "response_error"; this.response = response; this.validationError = validationError; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol10$1 in error; } }; async function createGatewayErrorFromResponse({ response, statusCode, defaultMessage = "Gateway request failed", cause, authMethod, isRetryable }) { var _a12; const parseResult = await safeValidateTypes({ value: response, schema: gatewayErrorResponseSchema }); if (!parseResult.success) { const rawGenerationId = typeof response === "object" && response !== null && "generationId" in response ? response.generationId : void 0; return new GatewayResponseError({ message: `Invalid error response format: ${defaultMessage}`, statusCode, response, validationError: parseResult.error, cause, generationId: rawGenerationId, isRetryable }); } const validatedResponse = parseResult.value; const errorType = validatedResponse.error.type; const message = validatedResponse.error.message; const generationId = (_a12 = validatedResponse.generationId) != null ? _a12 : void 0; switch (errorType) { case "authentication_error": return GatewayAuthenticationError.createContextualError({ apiKeyProvided: authMethod === "api-key", oidcTokenProvided: authMethod === "oidc", statusCode, cause, generationId }); case "invalid_request_error": return new GatewayInvalidRequestError({ message, statusCode, cause, generationId }); case "rate_limit_exceeded": return new GatewayRateLimitError({ message, statusCode, cause, generationId }); case "model_not_found": { const modelResult = await safeValidateTypes({ value: validatedResponse.error.param, schema: modelNotFoundParamSchema }); return new GatewayModelNotFoundError({ message, statusCode, modelId: modelResult.success ? modelResult.value.modelId : void 0, cause, generationId }); } case "not_found": return new GatewayNotFoundError({ message, statusCode, cause, generationId }); case "internal_server_error": return new GatewayInternalServerError({ message, statusCode, cause, generationId }); case "failed_dependency": return new GatewayFailedDependencyError({ message, statusCode, cause, generationId }); case "forbidden": { const ruleResult = await safeValidateTypes({ value: validatedResponse.error.param, schema: forbiddenParamSchema }); return new GatewayForbiddenError({ message, statusCode, cause, generationId, ruleId: ruleResult.success ? ruleResult.value.ruleId : void 0 }); } default: return new GatewayInternalServerError({ message, statusCode, cause, generationId }); } } var gatewayErrorResponseSchema = lazySchema(() => zodSchema(z$1.object({ error: z$1.object({ message: z$1.string(), type: z$1.string().nullish(), param: z$1.unknown().nullish(), code: z$1.union([z$1.string(), z$1.number()]).nullish() }), generationId: z$1.string().nullish() }))); function extractApiCallResponse(error) { if (error.data !== void 0) return error.data; if (error.responseBody != null) try { return secureJsonParse(error.responseBody); } catch (e) { return error.responseBody; } return {}; } var name10$1 = "GatewayTimeoutError"; var marker11$1 = `vercel.ai.gateway.error.${name10$1}`; var symbol11$1 = Symbol.for(marker11$1); var _a11$1; var _b11$1; var GatewayTimeoutError = class _GatewayTimeoutError extends (_b11$1 = GatewayError, _a11$1 = symbol11$1, _b11$1) { constructor({ message = "Request timed out", statusCode = 408, cause, generationId } = {}) { super({ message, statusCode, cause, generationId }); this[_a11$1] = true; this.name = name10$1; this.type = "timeout_error"; } static isInstance(error) { return GatewayError.hasMarker(error) && symbol11$1 in error; } /** * Creates a helpful timeout error message with troubleshooting guidance */ static createTimeoutError({ originalMessage, statusCode = 408, cause, generationId }) { const message = `Gateway request timed out: ${originalMessage} This is a client-side timeout. To resolve this, increase your timeout configuration: https://vercel.com/docs/ai-gateway/capabilities/video-generation#extending-timeouts-for-node.js`; return new _GatewayTimeoutError({ message, statusCode, cause, generationId }); } }; function isTimeoutError(error) { if (!(error instanceof Error)) return false; const errorCode = error.code; if (typeof errorCode === "string") return [ "UND_ERR_HEADERS_TIMEOUT", "UND_ERR_BODY_TIMEOUT", "UND_ERR_CONNECT_TIMEOUT" ].includes(errorCode); return false; } async function asGatewayError(error, authMethod) { var _a12; if (GatewayError.isInstance(error)) return error; if (isTimeoutError(error)) return GatewayTimeoutError.createTimeoutError({ originalMessage: error instanceof Error ? error.message : "Unknown error", cause: error }); if (APICallError.isInstance(error)) { if (error.cause && isTimeoutError(error.cause)) return GatewayTimeoutError.createTimeoutError({ originalMessage: error.message, cause: error }); return await createGatewayErrorFromResponse({ response: extractApiCallResponse(error), statusCode: (_a12 = error.statusCode) != null ? _a12 : 500, defaultMessage: "Gateway request failed", cause: error, authMethod, isRetryable: error.isRetryable && (error.statusCode == null || error.statusCode < 400) ? true : void 0 }); } return await createGatewayErrorFromResponse({ response: {}, statusCode: 500, defaultMessage: error instanceof Error ? `Gateway request failed: ${error.message}` : "Unknown Gateway error", cause: error, authMethod }); } var GATEWAY_AUTH_METHOD_HEADER = "ai-gateway-auth-method"; var VERCEL_AI_GATEWAY_TEAM_HEADER = "x-vercel-ai-gateway-team"; async function parseAuthMethod(headers) { const result = await safeValidateTypes({ value: headers[GATEWAY_AUTH_METHOD_HEADER], schema: gatewayAuthMethodSchema }); return result.success ? result.value : void 0; } var gatewayAuthMethodSchema = lazySchema(() => zodSchema(z$1.union([z$1.literal("api-key"), z$1.literal("oidc")]))); var KNOWN_MODEL_TYPES = [ "embedding", "evaluation", "image", "language", "realtime", "reranking", "speech", "transcription", "video" ]; var GatewayFetchMetadata = class { constructor(config) { this.config = config; } async getAvailableModels() { try { const { value } = await getFromApi({ url: `${this.config.baseURL}/config`, validateUrl: false, headers: this.config.headers ? await resolve(this.config.headers) : void 0, successfulResponseHandler: createJsonResponseHandler(gatewayAvailableModelsResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a12; return (_a12 = getErrorMessage(data)) != null ? _a12 : "unknown error"; } }), fetch: this.config.fetch }); return value; } catch (error) { throw await asGatewayError(error); } } async getCredits() { try { const { value } = await getFromApi({ url: `${new URL(this.config.baseURL).origin}/v1/credits`, validateUrl: false, headers: this.config.headers ? await resolve(this.config.headers) : void 0, successfulResponseHandler: createJsonResponseHandler(gatewayCreditsResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a12; return (_a12 = getErrorMessage(data)) != null ? _a12 : "unknown error"; } }), fetch: this.config.fetch }); return value; } catch (error) { throw await asGatewayError(error); } } }; var gatewayAvailableModelsResponseSchema = lazySchema(() => zodSchema(z$1.object({ models: z$1.array(z$1.object({ id: z$1.string(), name: z$1.string(), description: z$1.string().nullish(), pricing: z$1.object({ input: z$1.string(), output: z$1.string(), input_cache_read: z$1.string().nullish(), input_cache_write: z$1.string().nullish() }).transform(({ input, output, input_cache_read, input_cache_write }) => ({ input, output, ...input_cache_read ? { cachedInputTokens: input_cache_read } : {}, ...input_cache_write ? { cacheCreationInputTokens: input_cache_write } : {} })).nullish(), specification: z$1.object({ specificationVersion: z$1.literal("v4"), provider: z$1.string(), modelId: z$1.string() }), modelType: z$1.string().nullish() })).transform((models) => models.filter((m) => m.modelType == null || KNOWN_MODEL_TYPES.includes(m.modelType))) }))); var gatewayCreditsResponseSchema = lazySchema(() => zodSchema(z$1.object({ balance: z$1.string(), total_used: z$1.string() }).transform(({ balance, total_used }) => ({ balance, totalUsed: total_used })))); var GatewaySpendReport = class { constructor(config) { this.config = config; } async getSpendReport(params) { try { const baseUrl = new URL(this.config.baseURL); const searchParams = new URLSearchParams(); searchParams.set("start_date", params.startDate); searchParams.set("end_date", params.endDate); if (params.groupBy) searchParams.set("group_by", params.groupBy); if (params.datePart) searchParams.set("date_part", params.datePart); if (params.userId) searchParams.set("user_id", params.userId); if (params.model) searchParams.set("model", params.model); if (params.provider) searchParams.set("provider", params.provider); if (params.credentialType) searchParams.set("credential_type", params.credentialType); if (params.tags && params.tags.length > 0) searchParams.set("tags", params.tags.join(",")); const { value } = await getFromApi({ url: `${baseUrl.origin}/v1/report?${searchParams.toString()}`, validateUrl: false, headers: this.config.headers ? await resolve(this.config.headers) : void 0, successfulResponseHandler: createJsonResponseHandler(gatewaySpendReportResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a12; return (_a12 = getErrorMessage(data)) != null ? _a12 : "unknown error"; } }), fetch: this.config.fetch }); return value; } catch (error) { throw await asGatewayError(error); } } }; var gatewaySpendReportResponseSchema = lazySchema(() => zodSchema(z$1.object({ results: z$1.array(z$1.object({ day: z$1.string().optional(), hour: z$1.string().optional(), user: z$1.string().optional(), model: z$1.string().optional(), tag: z$1.string().optional(), provider: z$1.string().optional(), credential_type: z$1.enum(["byok", "system"]).optional(), total_cost: z$1.number(), market_cost: z$1.number().optional(), input_tokens: z$1.number().optional(), output_tokens: z$1.number().optional(), cached_input_tokens: z$1.number().optional(), cache_creation_input_tokens: z$1.number().optional(), reasoning_tokens: z$1.number().optional(), request_count: z$1.number().optional() }).transform(({ credential_type, total_cost, market_cost, input_tokens, output_tokens, cached_input_tokens, cache_creation_input_tokens, reasoning_tokens, request_count, ...rest }) => ({ ...rest, ...credential_type !== void 0 ? { credentialType: credential_type } : {}, totalCost: total_cost, ...market_cost !== void 0 ? { marketCost: market_cost } : {}, ...input_tokens !== void 0 ? { inputTokens: input_tokens } : {}, ...output_tokens !== void 0 ? { outputTokens: output_tokens } : {}, ...cached_input_tokens !== void 0 ? { cachedInputTokens: cached_input_tokens } : {}, ...cache_creation_input_tokens !== void 0 ? { cacheCreationInputTokens: cache_creation_input_tokens } : {}, ...reasoning_tokens !== void 0 ? { reasoningTokens: reasoning_tokens } : {}, ...request_count !== void 0 ? { requestCount: request_count } : {} }))) }))); var GatewayGenerationInfoFetcher = class { constructor(config) { this.config = config; } async getGenerationInfo(params) { try { const { value } = await getFromApi({ url: `${new URL(this.config.baseURL).origin}/v1/generation?id=${encodeURIComponent(params.id)}`, validateUrl: false, headers: this.config.headers ? await resolve(this.config.headers) : void 0, successfulResponseHandler: createJsonResponseHandler(gatewayGenerationInfoResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a12; return (_a12 = getErrorMessage(data)) != null ? _a12 : "unknown error"; } }), fetch: this.config.fetch }); return value; } catch (error) { throw await asGatewayError(error); } } }; var gatewayGenerationInfoResponseSchema = lazySchema(() => zodSchema(z$1.object({ data: z$1.object({ id: z$1.string(), total_cost: z$1.number(), upstream_inference_cost: z$1.number(), usage: z$1.number(), created_at: z$1.string(), model: z$1.string(), is_byok: z$1.boolean(), provider_name: z$1.string(), streamed: z$1.boolean(), finish_reason: z$1.string(), latency: z$1.number(), generation_time: z$1.number(), native_tokens_prompt: z$1.number(), native_tokens_completion: z$1.number(), native_tokens_reasoning: z$1.number(), native_tokens_cached: z$1.number(), native_tokens_cache_creation: z$1.number(), billable_web_search_calls: z$1.number() }).transform(({ total_cost, upstream_inference_cost, created_at, is_byok, provider_name, finish_reason, generation_time, native_tokens_prompt, native_tokens_completion, native_tokens_reasoning, native_tokens_cached, native_tokens_cache_creation, billable_web_search_calls, ...rest }) => ({ ...rest, totalCost: total_cost, upstreamInferenceCost: upstream_inference_cost, createdAt: created_at, isByok: is_byok, providerName: provider_name, finishReason: finish_reason, generationTime: generation_time, promptTokens: native_tokens_prompt, completionTokens: native_tokens_completion, reasoningTokens: native_tokens_reasoning, cachedTokens: native_tokens_cached, cacheCreationTokens: native_tokens_cache_creation, billableWebSearchCalls: billable_web_search_calls })) }).transform(({ data }) => data))); var GatewayBatch = class { constructor(config) { this.config = config; this.specificationVersion = "v4"; this.supportedUrls = { "*/*": [/.*/] }; this.provider = `${config.provider}.batch`; } /** * Starts a durable batch of text-generation requests through the Gateway's * async batch surface (`POST {baseURL}/batch/start`). The returned * `batchId` is the Gateway job id — provider-native batch ids stay * server-side, so status and results always route back through the * Gateway job. */ async doStartBatch({ requests, providerOptions, headers, abortSignal, webhookUrl }) { var _a12; assertTextBatchRequests(requests); const modelId = validateSingleModel(requests); const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; const idempotencyKey = getGatewayBatchIdempotencyKey(providerOptions); const forwardedProviderOptions = omitGatewayIdempotencyKey(providerOptions); try { const { value: responseBody } = await postJsonToApi({ url: this.getBatchUrl("start"), headers: combineHeaders(resolvedHeaders, headers, { "ai-model-id": modelId }, await resolve(this.config.o11yHeaders), idempotencyKey != null ? { "idempotency-key": idempotencyKey } : void 0), body: { ...webhookUrl != null && { callbackUrl: webhookUrl }, requests: requests.map((request) => ({ id: request.id, type: request.type, modelId: request.modelId, options: maybeEncodeBatchFileParts(request.options) })), ...forwardedProviderOptions != null && { providerOptions: forwardedProviderOptions } }, successfulResponseHandler: createJsonResponseHandler(gatewayBatchStartResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { batchId: responseBody.batchId, ...convertGatewayBatchStatus(responseBody), warnings: (_a12 = responseBody.warnings) != null ? _a12 : [] }; } catch (error) { if (isAbortOrTimeoutError(error)) throw error; throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } /** * Retrieves the lifecycle status of a Gateway batch job * (`POST {baseURL}/batch/status`). */ async doGetBatchStatus({ batchId, headers, abortSignal }) { const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { value: responseBody } = await postJsonToApi({ url: this.getBatchUrl("status"), headers: combineHeaders(resolvedHeaders, headers, await resolve(this.config.o11yHeaders)), body: { batchId }, successfulResponseHandler: createJsonResponseHandler(gatewayBatchStatusResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a12; return (_a12 = getErrorMessage(data)) != null ? _a12 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return convertGatewayBatchStatus(responseBody); } catch (error) { if (isAbortOrTimeoutError(error)) throw error; throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } /** * Streams the per-request results of a terminal Gateway batch job * (`POST {baseURL}/batch/results`, `application/x-ndjson`: one * `BatchV4ItemResult` JSON object per line). Items are validated minimally * (id + status) and passed through — the Gateway sanitizes them * server-side. The route responds 400 while the batch is non-terminal. */ async doGetBatchResults({ batchId, headers, abortSignal }) { const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { value: lines } = await postJsonToApi({ url: this.getBatchUrl("results"), headers: combineHeaders(resolvedHeaders, headers, await resolve(this.config.o11yHeaders)), body: { batchId }, successfulResponseHandler: createJsonLinesResponseHandler(gatewayBatchItemResultLineSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a12; return (_a12 = getErrorMessage(data)) != null ? _a12 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return convertAsyncIteratorToReadableStream(convertGatewayBatchResultLines(lines)); } catch (error) { if (isAbortOrTimeoutError(error)) throw error; throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } getBatchUrl(path) { return `${this.config.baseURL}/batch/${path}`; } }; function maybeEncodeBatchFileParts(options) { for (const message of options.prompt) { if (!Array.isArray(message.content)) continue; for (const part of message.content) if (part.type === "file" || part.type === "reasoning-file") part.data = maybeBase64EncodeFileData(part.data); else if (part.type === "tool-result" && part.output.type === "content") { for (const contentPart of part.output.value) if (contentPart.type === "file") contentPart.data = maybeBase64EncodeFileData(contentPart.data); } } return options; } function maybeBase64EncodeFileData(data) { if (data.type === "data") { const bytes = data.data; if (bytes instanceof Uint8Array) return { ...data, data: Buffer.from(bytes).toString("base64") }; } return data; } function validateSingleModel(requests) { var _a12; const modelId = (_a12 = requests[0]) == null ? void 0 : _a12.modelId; if (modelId == null) throw new InvalidArgumentError$1({ argument: "requests", message: "The AI Gateway Batch API requires at least one request." }); for (const request of requests) if (request.modelId !== modelId) throw new InvalidArgumentError$1({ argument: "requests", message: `The AI Gateway Batch API requires all requests in a batch to use the same model. Found "${modelId}" and "${request.modelId}".` }); return modelId; } function assertTextBatchRequests(requests) { for (const request of requests) { const requestType = request.type; if (requestType !== "text") throw new UnsupportedFunctionalityError({ functionality: `batch request type: ${requestType}`, message: `The AI Gateway Batch API does not support batch requests with type "${requestType}".` }); } } function getGatewayBatchIdempotencyKey(providerOptions) { const gatewayOptions = providerOptions == null ? void 0 : providerOptions.gateway; if (gatewayOptions == null || typeof gatewayOptions !== "object" || Array.isArray(gatewayOptions)) return; const key = gatewayOptions.idempotencyKey; return typeof key === "string" && key.length > 0 ? key : void 0; } function omitGatewayIdempotencyKey(providerOptions) { const gatewayOptions = providerOptions == null ? void 0 : providerOptions.gateway; if (gatewayOptions == null || typeof gatewayOptions !== "object" || Array.isArray(gatewayOptions) || !("idempotencyKey" in gatewayOptions)) return providerOptions; const { idempotencyKey: _idempotencyKey, ...restGatewayOptions } = gatewayOptions; const restProviderOptions = { ...providerOptions }; if (Object.keys(restGatewayOptions).length === 0) delete restProviderOptions.gateway; else restProviderOptions.gateway = restGatewayOptions; if (Object.keys(restProviderOptions).length === 0) return; return restProviderOptions; } function isAbortOrTimeoutError(error) { if (!(error instanceof Error || error instanceof DOMException)) return false; return error.name === "AbortError" || error.name === "TimeoutError"; } function convertGatewayBatchStatus(body) { var _a12, _b12, _c, _d; const requestCounts = normalizeBatchRequestCounts({ total: (_a12 = body.requestCounts) == null ? void 0 : _a12.total, pending: (_b12 = body.requestCounts) == null ? void 0 : _b12.pending, completed: (_c = body.requestCounts) == null ? void 0 : _c.completed, failed: (_d = body.requestCounts) == null ? void 0 : _d.failed }); return { status: body.status, ...body.rawStatus != null && { rawStatus: body.rawStatus }, ...requestCounts != null && { requestCounts }, ...body.error != null && { error: { message: body.error.message, ...body.error.type != null && { type: body.error.type }, ...body.error.code != null && { code: body.error.code }, ...body.error.statusCode != null && { statusCode: body.error.statusCode } } }, ...body.createdAt != null && { createdAt: body.createdAt }, ...body.expiresAt != null && { expiresAt: body.expiresAt }, ...body.providerMetadata != null && { providerMetadata: body.providerMetadata } }; } async function* convertGatewayBatchResultLines(lines) { var _a12; for await (const line of lines) { const item = line; if (item.status === "succeeded") { const response = (_a12 = item.result) == null ? void 0 : _a12.response; if (response !== void 0 && typeof response.timestamp === "string") response.timestamp = new Date(response.timestamp); } yield item; } } var gatewayBatchItemResultLineSchema = z$1.object({ type: z$1.literal("text"), id: z$1.string(), status: z$1.enum([ "cancelled", "expired", "failed", "succeeded" ]) }).catchall(z$1.unknown()); var gatewayBatchErrorSchema = z$1.object({ message: z$1.string(), type: z$1.string().nullish(), code: z$1.string().nullish(), statusCode: z$1.number().nullish() }); var gatewayBatchRequestCountsSchema = z$1.object({ total: z$1.number().nullish(), pending: z$1.number().nullish(), completed: z$1.number().nullish(), failed: z$1.number().nullish() }); var gatewayBatchProviderMetadataSchema = z$1.record(z$1.string(), z$1.record(z$1.string(), z$1.unknown())); var gatewayBatchStatusFieldsSchema = z$1.object({ status: z$1.enum([ "completed", "failed", "pending" ]), rawStatus: z$1.string().nullish(), requestCounts: gatewayBatchRequestCountsSchema.nullish(), error: gatewayBatchErrorSchema.nullish(), createdAt: z$1.string().nullish(), expiresAt: z$1.string().nullish(), providerMetadata: gatewayBatchProviderMetadataSchema.nullish() }); var gatewayBatchStartResponseSchema = gatewayBatchStatusFieldsSchema.extend({ batchId: z$1.string(), warnings: z$1.array(z$1.object({ requestId: z$1.string().nullish(), warning: z$1.unknown() }).catchall(z$1.unknown())).nullish() }); var gatewayBatchStatusResponseSchema = gatewayBatchStatusFieldsSchema; var GatewayLanguageModel = class _GatewayLanguageModel { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v4"; this.supportedUrls = { "*/*": [/.*/] }; } static [WORKFLOW_SERIALIZE](model) { return serializeModelOptions({ modelId: model.modelId, config: model.config }); } static [WORKFLOW_DESERIALIZE](options) { return new _GatewayLanguageModel(options.modelId, options.config); } get provider() { return this.config.provider; } async getArgs(options) { const { abortSignal: _abortSignal, ...optionsWithoutSignal } = options; return { args: this.maybeEncodeFileParts(optionsWithoutSignal), warnings: [] }; } async doGenerate(options) { var _a12; const { args, warnings } = await this.getArgs(options); const { abortSignal } = options; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody, rawValue: rawResponse } = await postJsonToApi({ url: this.getUrl(), headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, false), await resolve(this.config.o11yHeaders)), body: args, successfulResponseHandler: createJsonResponseHandler(z$1.any()), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { ...responseBody, request: { body: args }, response: { headers: responseHeaders, body: rawResponse }, warnings: [...(_a12 = responseBody.warnings) != null ? _a12 : [], ...warnings] }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } async doStream(options) { const { args, warnings } = await this.getArgs(options); const { abortSignal } = options; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { value: response, responseHeaders } = await postJsonToApi({ url: this.getUrl(), headers: combineHeaders(resolvedHeaders, options.headers, this.getModelConfigHeaders(this.modelId, true), await resolve(this.config.o11yHeaders)), body: args, successfulResponseHandler: createEventSourceResponseHandler(z$1.any()), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a12; return (_a12 = getErrorMessage(data)) != null ? _a12 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { stream: response.pipeThrough(new TransformStream({ start(controller) { if (warnings.length > 0) controller.enqueue({ type: "stream-start", warnings }); }, transform(chunk, controller) { if (chunk.success) { const streamPart = chunk.value; if (streamPart.type === "raw" && !options.includeRawChunks) return; if (streamPart.type === "response-metadata" && streamPart.timestamp && typeof streamPart.timestamp === "string") streamPart.timestamp = new Date(streamPart.timestamp); controller.enqueue(streamPart); } else controller.error(chunk.error); } })), request: { body: args }, response: { headers: responseHeaders } }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } /** * Encodes inline `Uint8Array` file data to a base64 string in place. * @param options - The options to encode. * @returns The options with the file data encoded. */ maybeEncodeFileParts(options) { for (const message of options.prompt) { if (!Array.isArray(message.content)) continue; for (const part of message.content) if (part.type === "file" || part.type === "reasoning-file") part.data = maybeBase64EncodeFileData2(part.data); else if (part.type === "tool-result" && part.output.type === "content") { for (const contentPart of part.output.value) if (contentPart.type === "file") contentPart.data = maybeBase64EncodeFileData2(contentPart.data); } } return options; } getUrl() { return `${this.config.baseURL}/language-model`; } getModelConfigHeaders(modelId, streaming) { return { "ai-language-model-specification-version": "4", "ai-language-model-id": modelId, "ai-language-model-streaming": String(streaming) }; } }; function maybeBase64EncodeFileData2(data) { if (data.type === "data") { const bytes = data.data; if (bytes instanceof Uint8Array) return { ...data, data: Buffer.from(bytes).toString("base64") }; } return data; } var GatewayEmbeddingModel = class _GatewayEmbeddingModel { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v4"; this.maxEmbeddingsPerCall = 2048; this.supportsParallelCalls = true; } static [WORKFLOW_SERIALIZE](model) { return serializeModelOptions({ modelId: model.modelId, config: model.config }); } static [WORKFLOW_DESERIALIZE](options) { return new _GatewayEmbeddingModel(options.modelId, options.config); } get provider() { return this.config.provider; } async doEmbed({ values, headers, abortSignal, providerOptions }) { var _a12, _b12; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody, rawValue } = await postJsonToApi({ url: this.getUrl(), headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), body: { values, ...providerOptions ? { providerOptions } : {} }, successfulResponseHandler: createJsonResponseHandler(gatewayEmbeddingResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { embeddings: responseBody.embeddings, usage: (_a12 = responseBody.usage) != null ? _a12 : void 0, providerMetadata: responseBody.providerMetadata, response: { headers: responseHeaders, body: rawValue }, warnings: (_b12 = responseBody.warnings) != null ? _b12 : [] }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } getUrl() { return `${this.config.baseURL}/embedding-model`; } getModelConfigHeaders() { return { "ai-embedding-model-specification-version": "4", "ai-model-id": this.modelId }; } }; var gatewayEmbeddingWarningSchema = z$1.discriminatedUnion("type", [ z$1.object({ type: z$1.literal("unsupported"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("compatibility"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("deprecated"), setting: z$1.string(), message: z$1.string() }), z$1.object({ type: z$1.literal("other"), message: z$1.string() }) ]); var gatewayEmbeddingResponseSchema = lazySchema(() => zodSchema(z$1.object({ embeddings: z$1.array(z$1.array(z$1.number())), usage: z$1.object({ tokens: z$1.number() }).nullish(), warnings: z$1.array(gatewayEmbeddingWarningSchema).optional(), providerMetadata: z$1.record(z$1.string(), z$1.record(z$1.string(), z$1.unknown())).optional() }))); var GatewayImageModel = class _GatewayImageModel { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v4"; this.maxImagesPerCall = Number.MAX_SAFE_INTEGER; } static [WORKFLOW_SERIALIZE](model) { return serializeModelOptions({ modelId: model.modelId, config: model.config }); } static [WORKFLOW_DESERIALIZE](options) { return new _GatewayImageModel(options.modelId, options.config); } get provider() { return this.config.provider; } async doGenerate({ prompt, n, size, aspectRatio, seed, files, mask, providerOptions, headers, abortSignal }) { var _a12, _b12, _c, _d; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody } = await postJsonToApi({ url: this.getUrl(), headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), body: { prompt, n, ...size && { size }, ...aspectRatio && { aspectRatio }, ...seed && { seed }, ...providerOptions && { providerOptions }, ...files && { files: files.map((file) => maybeEncodeImageFile(file)) }, ...mask && { mask: maybeEncodeImageFile(mask) } }, successfulResponseHandler: createJsonResponseHandler(gatewayImageResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { images: responseBody.images, ...responseBody.isRetryable != null && { isRetryable: responseBody.isRetryable }, warnings: (_a12 = responseBody.warnings) != null ? _a12 : [], providerMetadata: responseBody.providerMetadata, response: { timestamp: /* @__PURE__ */ new Date(), modelId: this.modelId, headers: responseHeaders }, ...responseBody.usage != null && { usage: { inputTokens: (_b12 = responseBody.usage.inputTokens) != null ? _b12 : void 0, outputTokens: (_c = responseBody.usage.outputTokens) != null ? _c : void 0, totalTokens: (_d = responseBody.usage.totalTokens) != null ? _d : void 0 } } }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } getUrl() { return `${this.config.baseURL}/image-model`; } getModelConfigHeaders() { return { "ai-image-model-specification-version": "4", "ai-model-id": this.modelId }; } }; function maybeEncodeImageFile(file) { if (file.type === "file" && file.data instanceof Uint8Array) return { ...file, data: convertUint8ArrayToBase64(file.data) }; return file; } var providerMetadataEntrySchema = z$1.object({ images: z$1.array(z$1.unknown()).optional() }).catchall(z$1.unknown()); var gatewayImageWarningSchema = z$1.discriminatedUnion("type", [ z$1.object({ type: z$1.literal("unsupported"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("compatibility"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("deprecated"), setting: z$1.string(), message: z$1.string() }), z$1.object({ type: z$1.literal("other"), message: z$1.string() }) ]); var gatewayImageUsageSchema = z$1.object({ inputTokens: z$1.number().nullish(), outputTokens: z$1.number().nullish(), totalTokens: z$1.number().nullish() }); var gatewayImageResponseSchema = z$1.object({ images: z$1.array(z$1.string()), isRetryable: z$1.boolean().optional(), warnings: z$1.array(gatewayImageWarningSchema).optional(), providerMetadata: z$1.record(z$1.string(), providerMetadataEntrySchema).optional(), usage: gatewayImageUsageSchema.optional() }); var GatewayVideoModel = class { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v4"; this.maxVideosPerCall = Number.MAX_SAFE_INTEGER; } get provider() { return this.config.provider; } async doGenerate(options) { var _a12, _b12; const { headers, abortSignal } = options; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody } = await postJsonToApi({ url: this.getUrl(), headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders), { accept: "text/event-stream" }), body: this.buildRequestBody(options), successfulResponseHandler: async ({ response, url, requestBodyValues }) => { if (response.body == null) throw new APICallError({ message: "SSE response body is empty", url, requestBodyValues, statusCode: response.status }); const reader = parseJsonEventStream({ stream: response.body, schema: gatewayVideoEventSchema }).getReader(); const { done, value: parseResult } = await reader.read(); reader.releaseLock(); if (done || !parseResult) throw new APICallError({ message: "SSE stream ended without a data event", url, requestBodyValues, statusCode: response.status }); if (!parseResult.success) throw new APICallError({ message: "Failed to parse video SSE event", cause: parseResult.error, url, requestBodyValues, statusCode: response.status }); const event = parseResult.value; if (event.type === "error") throw new APICallError({ message: event.message, statusCode: event.statusCode, url, requestBodyValues, responseHeaders: Object.fromEntries([...response.headers]), responseBody: JSON.stringify(event), data: { error: { message: event.message, type: event.errorType, param: event.param } } }); return { value: { videos: event.videos, warnings: event.warnings, providerMetadata: event.providerMetadata }, responseHeaders: Object.fromEntries([...response.headers]) }; }, failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { videos: responseBody.videos, warnings: (_a12 = responseBody.warnings) != null ? _a12 : [], providerMetadata: (_b12 = responseBody.providerMetadata) != null ? _b12 : void 0, response: { timestamp: /* @__PURE__ */ new Date(), modelId: this.modelId, headers: responseHeaders } }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } async handleWebhookOption({ webhook }) { const { url, received } = await webhook(); return { webhookUrl: url, received }; } async doStart(options) { var _a12, _b12; const { headers, abortSignal, webhookUrl } = options; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody } = await postJsonToApi({ url: this.getStartUrl(), headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), body: { ...this.buildRequestBody(options), ...webhookUrl && { callbackUrl: webhookUrl } }, successfulResponseHandler: createJsonResponseHandler(gatewayVideoStartResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { operation: responseBody.operation, warnings: (_a12 = responseBody.warnings) != null ? _a12 : [], providerMetadata: (_b12 = responseBody.providerMetadata) != null ? _b12 : void 0, response: { timestamp: /* @__PURE__ */ new Date(), modelId: this.modelId, headers: responseHeaders } }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } async doStatus({ operation, abortSignal, headers }) { var _a12, _b12, _c, _d, _e, _f; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody } = await postJsonToApi({ url: this.getStatusUrl(), headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), body: { operation }, successfulResponseHandler: createJsonResponseHandler(gatewayVideoStatusResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); const response = { timestamp: /* @__PURE__ */ new Date(), modelId: this.modelId, headers: responseHeaders }; if (responseBody.status === "completed") return { status: "completed", videos: responseBody.videos, warnings: (_a12 = responseBody.warnings) != null ? _a12 : [], providerMetadata: (_b12 = responseBody.providerMetadata) != null ? _b12 : void 0, response }; if (responseBody.status === "error") return { status: "error", error: responseBody.error, providerMetadata: (_c = responseBody.providerMetadata) != null ? _c : void 0, response }; if (responseBody.status === "cancelled") return { status: "error", error: "Video generation was cancelled.", providerMetadata: (_d = responseBody.providerMetadata) != null ? _d : void 0, response }; return { status: "pending", warnings: (_e = responseBody.warnings) != null ? _e : [], providerMetadata: (_f = responseBody.providerMetadata) != null ? _f : void 0, response }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } buildRequestBody({ prompt, n, aspectRatio, resolution, duration, fps, seed, generateAudio, image, frameImages, inputReferences, providerOptions }) { return { prompt, n, ...aspectRatio && { aspectRatio }, ...resolution && { resolution }, ...duration && { duration }, ...fps && { fps }, ...seed && { seed }, ...generateAudio !== void 0 && { generateAudio }, ...providerOptions && { providerOptions }, ...image && { image: maybeEncodeVideoFile(image) }, ...frameImages && { frameImages: frameImages.map((frame) => ({ ...frame, image: maybeEncodeVideoFile(frame.image) })) }, ...inputReferences && { inputReferences: inputReferences.map((reference) => maybeEncodeVideoFile(reference)) } }; } getUrl() { return `${this.config.baseURL}/video-model`; } getStartUrl() { return `${this.config.baseURL}/video-model/start`; } getStatusUrl() { return `${this.config.baseURL}/video-model/status`; } getModelConfigHeaders() { return { "ai-video-model-specification-version": "4", "ai-model-id": this.modelId }; } }; function maybeEncodeVideoFile(file) { if (file.type === "file" && file.data instanceof Uint8Array) return { ...file, data: convertUint8ArrayToBase64(file.data) }; return file; } var providerMetadataEntrySchema2 = z$1.object({ videos: z$1.array(z$1.unknown()).optional() }).catchall(z$1.unknown()); var gatewayVideoDataSchema = z$1.union([z$1.object({ type: z$1.literal("url"), url: z$1.string(), mediaType: z$1.string() }), z$1.object({ type: z$1.literal("base64"), data: z$1.string(), mediaType: z$1.string() })]); var gatewayVideoWarningSchema = z$1.discriminatedUnion("type", [ z$1.object({ type: z$1.literal("unsupported"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("compatibility"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("deprecated"), setting: z$1.string(), message: z$1.string() }), z$1.object({ type: z$1.literal("other"), message: z$1.string() }) ]); var gatewayVideoEventSchema = z$1.discriminatedUnion("type", [z$1.object({ type: z$1.literal("result"), videos: z$1.array(gatewayVideoDataSchema), warnings: z$1.array(gatewayVideoWarningSchema).optional(), providerMetadata: z$1.record(z$1.string(), providerMetadataEntrySchema2).optional() }), z$1.object({ type: z$1.literal("error"), message: z$1.string(), errorType: z$1.string(), statusCode: z$1.number(), param: z$1.unknown().nullable() })]); var gatewayVideoStartResponseSchema = z$1.object({ operation: z$1.unknown(), warnings: z$1.array(gatewayVideoWarningSchema).nullish(), providerMetadata: z$1.record(z$1.string(), providerMetadataEntrySchema2).nullish() }); var gatewayVideoStatusResponseSchema = z$1.discriminatedUnion("status", [ z$1.object({ status: z$1.literal("pending"), warnings: z$1.array(gatewayVideoWarningSchema).nullish(), providerMetadata: z$1.record(z$1.string(), providerMetadataEntrySchema2).nullish() }), z$1.object({ status: z$1.literal("completed"), videos: z$1.array(gatewayVideoDataSchema), warnings: z$1.array(gatewayVideoWarningSchema).nullish(), providerMetadata: z$1.record(z$1.string(), providerMetadataEntrySchema2).nullish() }), z$1.object({ status: z$1.literal("error"), error: z$1.string(), providerMetadata: z$1.record(z$1.string(), providerMetadataEntrySchema2).nullish() }), z$1.object({ status: z$1.literal("cancelled"), providerMetadata: z$1.record(z$1.string(), providerMetadataEntrySchema2).nullish() }) ]); var GatewayEvaluationModel = class { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v4"; this.supportedQuestionTypes = [ "choice", "score", "boolean" ]; } get provider() { return this.config.provider; } async doEvaluate({ state, questions, headers, abortSignal, providerOptions }) { var _a12; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody, rawValue } = await postJsonToApi({ url: this.getUrl(), headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), body: { state, questions, ...providerOptions ? { providerOptions } : {} }, successfulResponseHandler: createJsonResponseHandler(gatewayEvaluationResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { answers: responseBody.answers, ...responseBody.rounding ? { rounding: responseBody.rounding } : {}, ...responseBody.usage ? { usage: responseBody.usage } : {}, warnings: (_a12 = responseBody.warnings) != null ? _a12 : [], providerMetadata: responseBody.providerMetadata, response: { modelId: this.modelId, headers: responseHeaders, body: rawValue } }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } getUrl() { return `${this.config.baseURL}/evaluation-model`; } getModelConfigHeaders() { return { "ai-evaluation-model-specification-version": "4", "ai-model-id": this.modelId }; } }; var gatewayEvaluationAnswerSchema = z$1.discriminatedUnion("type", [ z$1.object({ type: z$1.literal("choice"), choice: z$1.string(), probabilities: z$1.record(z$1.string(), z$1.number()).optional() }), z$1.object({ type: z$1.literal("score"), score: z$1.number(), probabilities: z$1.record(z$1.string(), z$1.number()).optional() }), z$1.object({ type: z$1.literal("boolean"), probability: z$1.number() }) ]); var gatewayEvaluationWarningSchema = z$1.discriminatedUnion("type", [ z$1.object({ type: z$1.literal("unsupported"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("compatibility"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("deprecated"), setting: z$1.string(), message: z$1.string() }), z$1.object({ type: z$1.literal("other"), message: z$1.string() }) ]); var gatewayEvaluationResponseSchema = lazySchema(() => zodSchema(z$1.object({ answers: z$1.record(z$1.string(), gatewayEvaluationAnswerSchema), rounding: z$1.object({ probabilityDecimals: z$1.number().optional(), scoreDecimals: z$1.number().optional() }).optional(), usage: z$1.object({ inputTokens: z$1.number().optional(), outputTokens: z$1.number().optional() }).optional(), warnings: z$1.array(gatewayEvaluationWarningSchema).optional(), providerMetadata: z$1.record(z$1.string(), z$1.record(z$1.string(), z$1.unknown())).optional() }))); var GatewayRerankingModel = class { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v4"; } get provider() { return this.config.provider; } async doRerank({ documents, query, topN, headers, abortSignal, providerOptions }) { var _a12; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody, rawValue } = await postJsonToApi({ url: this.getUrl(), headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), body: { documents, query, ...topN != null ? { topN } : {}, ...providerOptions ? { providerOptions } : {} }, successfulResponseHandler: createJsonResponseHandler(gatewayRerankingResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { ranking: responseBody.ranking, providerMetadata: responseBody.providerMetadata, response: { headers: responseHeaders, body: rawValue }, warnings: (_a12 = responseBody.warnings) != null ? _a12 : [] }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } getUrl() { return `${this.config.baseURL}/reranking-model`; } getModelConfigHeaders() { return { "ai-reranking-model-specification-version": "4", "ai-model-id": this.modelId }; } }; var gatewayRerankingWarningSchema = z$1.discriminatedUnion("type", [ z$1.object({ type: z$1.literal("unsupported"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("compatibility"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("deprecated"), setting: z$1.string(), message: z$1.string() }), z$1.object({ type: z$1.literal("other"), message: z$1.string() }) ]); var gatewayRerankingResponseSchema = lazySchema(() => zodSchema(z$1.object({ ranking: z$1.array(z$1.object({ index: z$1.number(), relevanceScore: z$1.number() })), warnings: z$1.array(gatewayRerankingWarningSchema).optional(), providerMetadata: z$1.record(z$1.string(), z$1.record(z$1.string(), z$1.unknown())).optional() }))); var GatewaySpeechModel = class { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v4"; } get provider() { return this.config.provider; } async doGenerate({ text, voice, outputFormat, instructions, speed, language, providerOptions, headers, abortSignal }) { var _a12; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody, rawValue } = await postJsonToApi({ url: this.getUrl(), headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), body: { text, ...voice && { voice }, ...outputFormat && { outputFormat }, ...instructions && { instructions }, ...speed != null && { speed }, ...language && { language }, ...providerOptions && { providerOptions } }, successfulResponseHandler: createJsonResponseHandler(gatewaySpeechResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { audio: responseBody.audio, warnings: (_a12 = responseBody.warnings) != null ? _a12 : [], providerMetadata: responseBody.providerMetadata, response: { timestamp: /* @__PURE__ */ new Date(), modelId: this.modelId, headers: responseHeaders, body: rawValue } }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } getUrl() { return `${this.config.baseURL}/speech-model`; } getModelConfigHeaders() { return { "ai-speech-model-specification-version": "4", "ai-model-id": this.modelId }; } }; var providerMetadataEntrySchema3 = z$1.object({}).catchall(z$1.unknown()); var gatewaySpeechWarningSchema = z$1.discriminatedUnion("type", [ z$1.object({ type: z$1.literal("unsupported"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("compatibility"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("deprecated"), setting: z$1.string(), message: z$1.string() }), z$1.object({ type: z$1.literal("other"), message: z$1.string() }) ]); var gatewaySpeechResponseSchema = z$1.object({ audio: z$1.string(), warnings: z$1.array(gatewaySpeechWarningSchema).optional(), providerMetadata: z$1.record(z$1.string(), providerMetadataEntrySchema3).optional() }); var GatewayTranscriptionModel = class { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v4"; } get provider() { return this.config.provider; } async doGenerate({ audio, mediaType, providerOptions, headers, abortSignal }) { var _a12, _b12, _c, _d; const resolvedHeaders = this.config.headers ? await resolve(this.config.headers) : void 0; try { const { responseHeaders, value: responseBody, rawValue } = await postJsonToApi({ url: this.getUrl(), headers: combineHeaders(resolvedHeaders, headers != null ? headers : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)), body: { audio: audio instanceof Uint8Array ? convertUint8ArrayToBase64(audio) : audio, mediaType, ...providerOptions && { providerOptions } }, successfulResponseHandler: createJsonResponseHandler(gatewayTranscriptionResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), ...abortSignal && { abortSignal }, fetch: this.config.fetch }); return { text: responseBody.text, segments: (_a12 = responseBody.segments) != null ? _a12 : [], language: (_b12 = responseBody.language) != null ? _b12 : void 0, durationInSeconds: (_c = responseBody.durationInSeconds) != null ? _c : void 0, warnings: (_d = responseBody.warnings) != null ? _d : [], providerMetadata: responseBody.providerMetadata, response: { timestamp: /* @__PURE__ */ new Date(), modelId: this.modelId, headers: responseHeaders, body: rawValue } }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders != null ? resolvedHeaders : {})); } } async doStream(options) { var _a12, _b12, _c, _d, _e; const currentDate = (_c = (_b12 = (_a12 = this.config._internal) == null ? void 0 : _a12.currentDate) == null ? void 0 : _b12.call(_a12)) != null ? _c : /* @__PURE__ */ new Date(); const headers = combineHeaders(await resolve((_d = this.config.headers) != null ? _d : {}), (_e = options.headers) != null ? _e : {}, this.getModelConfigHeaders(), await resolve(this.config.o11yHeaders)); const authMethod = await parseAuthMethod(headers); const startFrame = { type: TRANSCRIPTION_STREAM_START_FRAME_TYPE, inputAudioFormat: options.inputAudioFormat, ...options.providerOptions != null && { providerOptions: options.providerOptions }, ...options.includeRawChunks != null && { includeRawChunks: options.includeRawChunks } }; return { stream: createGatewayTranscriptionStream({ webSocket: this.config.webSocket, url: toGatewayTranscriptionUrl(this.config.baseURL, this.modelId), protocols: getProtocolsFromHeaders(headers), headers, startFrame, audio: options.audio, abortSignal: options.abortSignal, authMethod }), request: { body: startFrame }, response: { timestamp: currentDate, modelId: this.modelId } }; } getUrl() { return `${this.config.baseURL}/transcription-model`; } getModelConfigHeaders() { return { "ai-transcription-model-specification-version": "4", "ai-model-id": this.modelId }; } }; function toGatewayTranscriptionUrl(baseURL, modelId) { const url = new URL(`${baseURL.replace(/^http/, "ws")}/transcription-model`); url.searchParams.set("ai-model-id", modelId); return url.toString(); } function getProtocolsFromHeaders(headers) { const normalizedHeaders = normalizeHeaders(headers); const authorization = normalizedHeaders.authorization; const token = (authorization == null ? void 0 : authorization.startsWith("Bearer ")) ? authorization.slice(7) : void 0; return token == null ? [GATEWAY_TRANSCRIPTION_SUBPROTOCOL] : getGatewayTranscriptionProtocols(token, { teamIdOrSlug: normalizedHeaders[VERCEL_AI_GATEWAY_TEAM_HEADER] }); } var MAX_AUDIO_FRAME_BYTES = 65536; function createGatewayTranscriptionStream({ webSocket, url, protocols, headers, startFrame, audio, abortSignal, authMethod }) { let finished = false; let cleanup = () => {}; return new ReadableStream({ start: (controller) => { let audioReader; let hasServerErrorPart = false; let lastServerError; let audioStopped = false; let connection; cleanup = (closeCode) => { if (audioReader != null) audioReader.cancel().catch(() => {}); else audio.cancel().catch(() => {}); connection?.close(closeCode); }; const stopAudio = () => { audioStopped = true; if (audioReader != null) { audioReader.cancel().catch(() => {}); audioReader = void 0; } else audio.cancel().catch(() => {}); }; const finishWithError = (error) => { if (finished) return; finished = true; cleanup(); errorControllerWithGatewayError(controller, error, authMethod); }; const sendAudio = async (socket) => { const reader = audio.getReader(); audioReader = reader; try { while (true) { const { done, value } = await reader.read(); if (done || finished) break; const bytes = typeof value === "string" ? convertBase64ToUint8Array(value) : value; for (let offset = 0; offset < bytes.length; offset += MAX_AUDIO_FRAME_BYTES) { if (finished) break; socket.send(bytes.subarray(offset, offset + MAX_AUDIO_FRAME_BYTES)); await waitForWebSocketBufferDrain(socket); } } } finally { reader.releaseLock(); if (audioReader === reader) audioReader = void 0; } if (!finished && !audioStopped) socket.send(JSON.stringify({ type: TRANSCRIPTION_STREAM_AUDIO_DONE_FRAME_TYPE })); }; connection = connectToWebSocket({ url, protocols, headers, webSocket, abortSignal, onAbort: (reason) => { if (finished) return; finished = true; cleanup(); controller.error(reason); }, onProcessingError: finishWithError, onOpen: (socket) => { socket.send(JSON.stringify(startFrame)); sendAudio(socket).catch(finishWithError); }, onMessageText: (text) => { if (finished) return; const part = parseTranscriptionStreamPart(text); if (part == null) return; if (part.type === "finish") { finished = true; controller.enqueue(part); controller.close(); cleanup(1e3); return; } if (part.type === "error") { hasServerErrorPart = true; lastServerError = part.error; stopAudio(); } controller.enqueue(part); }, onSocketError: () => { finishWithError(/* @__PURE__ */ new Error("Connection error on AI Gateway transcription stream")); }, onClose: () => { if (hasServerErrorPart) { if (finished) return; createErrorFromServerErrorPart(lastServerError, authMethod).then(finishWithError); return; } finishWithError(/* @__PURE__ */ new Error("AI Gateway transcription stream closed before a finish part was received")); } }); }, cancel: () => { if (finished) return; finished = true; cleanup(); } }); } var providerMetadataEntrySchema4 = z$1.object({}).catchall(z$1.unknown()); var gatewayTranscriptionWarningSchema = z$1.discriminatedUnion("type", [ z$1.object({ type: z$1.literal("unsupported"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("compatibility"), feature: z$1.string(), details: z$1.string().optional() }), z$1.object({ type: z$1.literal("deprecated"), setting: z$1.string(), message: z$1.string() }), z$1.object({ type: z$1.literal("other"), message: z$1.string() }) ]); var gatewayTranscriptionResponseSchema = z$1.object({ text: z$1.string(), segments: z$1.array(z$1.object({ text: z$1.string(), startSecond: z$1.number(), endSecond: z$1.number() })).optional(), language: z$1.string().nullish(), durationInSeconds: z$1.number().nullish(), warnings: z$1.array(gatewayTranscriptionWarningSchema).optional(), providerMetadata: z$1.record(z$1.string(), providerMetadataEntrySchema4).optional() }); async function errorControllerWithGatewayError(controller, error, authMethod) { controller.error(await asGatewayError(error, authMethod)); } function getServerErrorMessage(error) { if (error != null && typeof error === "object" && "message" in error && typeof error.message === "string") return error.message; return getErrorMessage(error); } var SERVER_ERROR_STATUS_CODES = { authentication_error: 401, failed_dependency: 424, forbidden: 403, internal_server_error: 500, invalid_request_error: 400, model_not_found: 404, rate_limit_exceeded: 429 }; async function createErrorFromServerErrorPart(error, authMethod) { if (typeof error === "object" && error != null && "message" in error && typeof error.message === "string" && "type" in error && typeof error.type === "string" && error.type in SERVER_ERROR_STATUS_CODES) return createGatewayErrorFromResponse({ response: { error: { message: error.message, type: error.type } }, statusCode: SERVER_ERROR_STATUS_CODES[error.type], authMethod }); return /* @__PURE__ */ new Error(`AI Gateway transcription stream failed: ${getServerErrorMessage(error)}`); } var GatewayRealtimeModel = class { constructor(modelId, config) { this.specificationVersion = "v4"; this.modelId = modelId; this.provider = config.provider; this.config = config; } /** * Mints a single-use, short-lived client secret (`vcst_`) the browser uses to * open the realtime WebSocket without ever holding the long-lived Gateway * credential. The customer's server calls this (via * `gateway.experimental_realtime.getToken`) and hands the returned token to * the browser, which connects with it through the `ai-gateway-auth.` * subprotocol. `expiresAfterSeconds` is forwarded to the mint endpoint; * `sessionConfig` is intentionally unused here — it is applied later via the * normalized `session-update` event. */ async doCreateClientSecret(options) { const secret = await this.config.createClientSecret({ modelId: this.modelId, ...(options == null ? void 0 : options.expiresAfterSeconds) != null && { expiresAfterSeconds: options.expiresAfterSeconds } }); return { token: secret.token, url: toGatewayRealtimeUrl(this.config.baseURL, this.modelId), ...secret.expiresAt != null && { expiresAt: secret.expiresAt } }; } getWebSocketConfig(options) { return { url: options.url, protocols: getGatewayRealtimeProtocols(options.token, { teamIdOrSlug: this.config.teamIdOrSlug }) }; } parseServerEvent(raw) { return raw; } serializeClientEvent(event) { return event; } buildSessionConfig(config) { return config; } }; function toGatewayRealtimeUrl(baseURL, modelId) { const url = new URL(`${baseURL.replace(/^http/, "ws")}/realtime-model`); url.searchParams.set("ai-model-id", modelId); return url.toString(); } var exaSearchToolFactory = createProviderExecutedToolFactory({ id: "gateway.exa_search", inputSchema: lazySchema(() => zodSchema(z$1.object({ query: z$1.string().describe("Natural-language web search query. This is required."), type: z$1.enum([ "auto", "fast", "instant" ]).optional().describe("Search method. Use auto for the default balance of speed and quality."), num_results: z$1.number().optional().describe("Maximum number of results to return (1-100, default: 10)."), category: z$1.enum([ "company", "people", "research paper", "news", "personal site", "financial report" ]).optional().describe("Optional content category to focus results."), user_location: z$1.string().optional().describe("Two-letter ISO country code such as 'US'."), include_domains: z$1.array(z$1.string()).optional().describe("Only return results from these domains."), exclude_domains: z$1.array(z$1.string()).optional().describe("Exclude results from these domains."), start_published_date: z$1.string().optional().describe("Only return links published after this ISO 8601 date."), end_published_date: z$1.string().optional().describe("Only return links published before this ISO 8601 date."), contents: z$1.object({ text: z$1.union([z$1.boolean(), z$1.object({ max_characters: z$1.number().optional(), include_html_tags: z$1.boolean().optional(), verbosity: z$1.enum([ "compact", "standard", "full" ]).optional(), include_sections: z$1.array(z$1.enum([ "header", "navigation", "banner", "body", "sidebar", "footer", "metadata" ])).optional(), exclude_sections: z$1.array(z$1.enum([ "header", "navigation", "banner", "body", "sidebar", "footer", "metadata" ])).optional() })]).optional(), highlights: z$1.union([z$1.boolean(), z$1.object({ query: z$1.string().optional(), max_characters: z$1.number().optional() })]).optional(), max_age_hours: z$1.number().optional(), livecrawl_timeout: z$1.number().optional(), subpages: z$1.number().optional(), subpage_target: z$1.union([z$1.string(), z$1.array(z$1.string())]).optional(), extras: z$1.object({ links: z$1.number().optional(), image_links: z$1.number().optional() }).optional() }).optional().describe("Controls extracted page content and freshness.") }))), outputSchema: lazySchema(() => zodSchema(z$1.union([z$1.object({ requestId: z$1.string(), searchType: z$1.string().optional(), resolvedSearchType: z$1.string().optional(), results: z$1.array(z$1.object({ title: z$1.string(), url: z$1.string(), id: z$1.string(), publishedDate: z$1.string().nullable().optional(), author: z$1.string().nullable().optional(), image: z$1.string().nullable().optional(), favicon: z$1.string().nullable().optional(), text: z$1.string().optional(), highlights: z$1.array(z$1.string()).optional(), highlightScores: z$1.array(z$1.number()).optional(), summary: z$1.string().optional(), subpages: z$1.array(z$1.any()).optional(), extras: z$1.object({ links: z$1.array(z$1.string()).optional(), imageLinks: z$1.array(z$1.string()).optional() }).optional() })), costDollars: z$1.object({ total: z$1.number().optional(), search: z$1.record(z$1.string(), z$1.number()).optional() }).optional() }), z$1.object({ error: z$1.enum([ "api_error", "rate_limit", "timeout", "invalid_input", "configuration_error", "execution_error", "unknown" ]), statusCode: z$1.number().optional(), message: z$1.string() })]))) }); var exaSearch = (config = {}) => exaSearchToolFactory(config); var parallelSearchToolFactory = createProviderExecutedToolFactory({ id: "gateway.parallel_search", inputSchema: lazySchema(() => zodSchema(z$1.object({ objective: z$1.string().describe("Natural-language description of the web research goal, including source or freshness guidance and broader context from the task. Maximum 5000 characters."), search_queries: z$1.array(z$1.string()).optional().describe("Optional search queries to supplement the objective. Maximum 200 characters per query."), mode: z$1.enum(["one-shot", "agentic"]).optional().describe("Mode preset: \"one-shot\" for comprehensive results with longer excerpts (default), \"agentic\" for concise, token-efficient results for multi-step workflows."), max_results: z$1.number().optional().describe("Maximum number of results to return (1-20). Defaults to 10 if not specified."), source_policy: z$1.object({ include_domains: z$1.array(z$1.string()).optional().describe("Limit results to these domains. Use plain domain names only — e.g. example.com or sub.example.gov, or a bare extension like .edu. Do not include a scheme, path, or port (e.g. not https://example.com/page)."), exclude_domains: z$1.array(z$1.string()).optional().describe("Exclude results from these domains. Use plain domain names only — e.g. example.com or sub.example.gov, or a bare extension like .edu. Do not include a scheme, path, or port (e.g. not https://example.com/page)."), after_date: z$1.string().optional().describe("Only include results published after this date. Use an ISO 8601 calendar date formatted YYYY-MM-DD (e.g. 2025-01-01); do not include a time.") }).optional().describe("Source policy for controlling which domains to include/exclude and freshness."), excerpts: z$1.object({ max_chars_per_result: z$1.number().optional().describe("Maximum characters per result."), max_chars_total: z$1.number().optional().describe("Maximum total characters across all results.") }).optional().describe("Excerpt configuration for controlling result length."), fetch_policy: z$1.object({ max_age_seconds: z$1.number().optional().describe("Maximum age in seconds for cached content. Set to 0 to always fetch fresh content.") }).optional().describe("Fetch policy for controlling content freshness.") }))), outputSchema: lazySchema(() => zodSchema(z$1.union([z$1.object({ searchId: z$1.string(), results: z$1.array(z$1.object({ url: z$1.string(), title: z$1.string(), excerpt: z$1.string(), publishDate: z$1.string().nullable().optional(), relevanceScore: z$1.number().optional() })) }), z$1.object({ error: z$1.enum([ "api_error", "rate_limit", "timeout", "invalid_input", "configuration_error", "unknown" ]), statusCode: z$1.number().optional(), message: z$1.string() })]))) }); var parallelSearch = (config = {}) => parallelSearchToolFactory(config); var perplexitySearchToolFactory = createProviderExecutedToolFactory({ id: "gateway.perplexity_search", inputSchema: lazySchema(() => zodSchema(z$1.object({ query: z$1.union([z$1.string(), z$1.array(z$1.string())]).describe("Search query (string) or multiple queries (array of up to 5 strings). Multi-query searches return combined results from all queries."), max_results: z$1.number().optional().describe("Maximum number of search results to return (1-20, default: 10)"), max_tokens_per_page: z$1.number().optional().describe("Maximum number of tokens to extract per search result page (256-2048, default: 2048)"), max_tokens: z$1.number().optional().describe("Maximum total tokens across all search results (default: 25000, max: 1000000)"), country: z$1.string().optional().describe("Two-letter ISO 3166-1 alpha-2 country code for regional search results (e.g., 'US', 'GB', 'FR')"), search_domain_filter: z$1.array(z$1.string()).optional().describe("List of domains to include or exclude from search results (max 20). To include: ['nature.com', 'science.org']. To exclude: ['-example.com', '-spam.net']"), search_language_filter: z$1.array(z$1.string()).optional().describe("List of ISO 639-1 language codes to filter results (max 10, lowercase). Examples: ['en', 'fr', 'de']"), search_after_date: z$1.string().optional().describe("Include only results published after this date. Format: 'MM/DD/YYYY' (e.g., '3/1/2025'). Cannot be used with search_recency_filter."), search_before_date: z$1.string().optional().describe("Include only results published before this date. Format: 'MM/DD/YYYY' (e.g., '3/15/2025'). Cannot be used with search_recency_filter."), last_updated_after_filter: z$1.string().optional().describe("Include only results last updated after this date. Format: 'MM/DD/YYYY' (e.g., '3/1/2025'). Cannot be used with search_recency_filter."), last_updated_before_filter: z$1.string().optional().describe("Include only results last updated before this date. Format: 'MM/DD/YYYY' (e.g., '3/15/2025'). Cannot be used with search_recency_filter."), search_recency_filter: z$1.enum([ "day", "week", "month", "year" ]).optional().describe("Filter results by relative time period. Cannot be used with search_after_date or search_before_date.") }))), outputSchema: lazySchema(() => zodSchema(z$1.union([z$1.object({ results: z$1.array(z$1.object({ title: z$1.string(), url: z$1.string(), snippet: z$1.string(), date: z$1.string().optional(), lastUpdated: z$1.string().optional() })), id: z$1.string() }), z$1.object({ error: z$1.enum([ "api_error", "rate_limit", "timeout", "invalid_input", "unknown" ]), statusCode: z$1.number().optional(), message: z$1.string() })]))) }); var perplexitySearch = (config = {}) => perplexitySearchToolFactory(config); var takoDataSourceInputSchema = z$1.object({ count: z$1.number().optional().describe("Maximum number of data results to return (1-20). When include_contents is true, each additional result adds its own data surcharge."), include_contents: z$1.boolean().optional().describe("Inline rows for each data result. This adds a data surcharge based on row count and dataset source. To estimate cost, search with include_contents disabled and inspect cards.content.export_pricing. This applies to every returned card; limit sources.data.count and sources.data.max_rows to control cost."), mode: z$1.enum(["inline", "url"]).optional().describe("Requested data delivery mode. Search card data is always inline."), content_format: z$1.enum([ "card_json", "csv", "json_compact", "json_records" ]).optional().describe("Serialization for inlined card data."), max_rows: z$1.number().optional().describe("Maximum rows to inline per result. Omit to use the allowance in cards.content.export_pricing. A data surcharge applies per 1,000 exported rows; lower values reduce cost."), node_ids: z$1.array(z$1.string()).optional().describe("Data Graph node IDs to prioritize. Maximum 20."), strict: z$1.boolean().optional().describe("Only return cards matching node_ids. Requires a non-empty node_ids.") }); var takoWebSourceInputSchema = z$1.object({ count: z$1.number().optional().describe("Maximum number of web results to return (1-20)."), include_contents: z$1.boolean().optional().describe("Inline extracted web page text. This can add a data charge."), category: z$1.enum([ "finance", "news", "sports" ]).optional().describe("Optional web-result category filter."), include_domains: z$1.array(z$1.string()).optional().describe("Only return results from these bare domains."), exclude_domains: z$1.array(z$1.string()).optional().describe("Exclude results from these bare domains."), snippet_max_chars: z$1.number().optional().describe("Maximum characters in each web-result snippet."), highlights: z$1.boolean().optional().describe("Include highlighted passages in web results. Defaults to true in AI Gateway."), article_content_max_chars: z$1.number().optional().describe("Maximum extracted characters per web page when including contents."), published_after: z$1.string().optional().describe("Keep results published on or after this ISO date (YYYY-MM-DD)."), published_before: z$1.string().optional().describe("Keep results published on or before this ISO date (YYYY-MM-DD).") }); var takoSearchInputSchema = lazySchema(() => zodSchema(z$1.object({ query: z$1.string().describe("Natural-language search query. Include the entity, metric, and time period. Quote a phrase to force it to one entity, for example \"Tesla\":PRODUCT price."), effort: z$1.enum([ "deep", "fast", "instant" ]).optional().describe("Search effort. fast is the balanced default, instant favors cached results and low latency, and deep broadens retrieval with reranking at higher cost and latency."), sources: z$1.object({ data: takoDataSourceInputSchema.optional(), web: takoWebSourceInputSchema.optional() }).optional().describe("Sources to search. Omit to search both curated data and the web. When provided, only keys present are searched."), location: z$1.object({ latitude: z$1.number().describe("Latitude between -90 and 90."), longitude: z$1.number().describe("Longitude between -180 and 180.") }).optional().describe("End-user coordinates for localized results."), country_code: z$1.string().optional().describe("Two-letter ISO 3166-1 country code, such as 'US'."), locale: z$1.string().optional().describe("BCP-47 locale, such as 'en-US'."), timezone: z$1.string().optional().describe("IANA timezone, such as 'America/New_York'."), output_settings: z$1.object({ image_dark_mode: z$1.boolean().optional().describe("Render card preview images in dark mode."), force_refresh: z$1.boolean().optional().describe("Instant-effort only. Request a refreshed instant result.") }).optional().describe("Controls card rendering in the search response."), include_related: z$1.number().optional().describe("Maximum related search suggestions to include (1-20).") }))); var takoDatasetCellSchema = z$1.union([ z$1.boolean(), z$1.number(), z$1.string() ]).nullable(); var takoResultContentSchema = z$1.object({ content_format: z$1.enum([ "card_json", "csv", "json_compact", "json_records" ]).nullish(), cost: z$1.number().optional(), data: z$1.string().nullish(), records: z$1.array(z$1.record(z$1.string(), takoDatasetCellSchema)).nullish(), dataset: z$1.object({ columns: z$1.array(z$1.object({ name: z$1.string(), type: z$1.enum([ "boolean", "date", "datetime", "number", "string" ]), unit: z$1.string().nullish() })), rows: z$1.array(z$1.array(takoDatasetCellSchema)), total_rows: z$1.number(), truncated: z$1.boolean(), ref: z$1.string(), sources: z$1.array(z$1.object({ name: z$1.string(), index: z$1.enum(["data", "web"]).optional() })), provenance: z$1.enum(["query", "web_extraction"]).optional() }).nullish(), card_data: z$1.object({}).passthrough().nullish(), card_data_schema: z$1.object({}).passthrough().nullish(), url: z$1.string().nullish(), expires_at: z$1.string().nullish(), total_rows: z$1.number().nullish(), truncated: z$1.boolean().optional(), export_pricing: z$1.object({ baseline_usd: z$1.number(), free_rows: z$1.number(), max_rows_ceiling: z$1.number(), row_cpm_usd: z$1.number() }).nullish(), manifest: z$1.array(z$1.object({ dtype: z$1.enum([ "boolean", "date", "datetime", "number", "string" ]).nullish(), entity: z$1.string().nullish(), metric: z$1.string().nullish(), name: z$1.string().nullish(), unit: z$1.string().nullish() })).nullish() }).passthrough(); var takoCardSchema = z$1.object({ card_id: z$1.string().nullish(), title: z$1.string().nullish(), description: z$1.string().nullish(), semantic_description: z$1.string().nullish(), webpage_url: z$1.string().nullish(), image_url: z$1.string().nullish(), embed_url: z$1.string().nullish(), sources: z$1.array(z$1.object({ source_name: z$1.string().nullish(), source_description: z$1.string().nullish(), source_index: z$1.enum(["data", "web"]), source_text: z$1.string().nullish(), url: z$1.string().nullish() })).nullish(), methodologies: z$1.array(z$1.object({ methodology_name: z$1.string().nullable(), methodology_description: z$1.string().nullable() })).nullish(), source_indexes: z$1.array(z$1.enum(["data", "web"])).nullish(), card_type: z$1.string().nullish(), relevance: z$1.enum([ "High", "Low", "Medium" ]).nullish(), content: takoResultContentSchema.nullish(), exportable: z$1.boolean().optional(), nodes: z$1.array(z$1.object({ id: z$1.string(), type: z$1.enum(["entity", "metric"]), name: z$1.string(), description: z$1.string().nullish() })).nullish(), metric_definitions: z$1.array(z$1.object({ name: z$1.string(), definition: z$1.string() })).nullish(), data_freshness: z$1.object({ coverage_end: z$1.string().nullish(), data_as_of: z$1.string().nullish(), last_updated: z$1.string().nullish() }).nullish() }).passthrough(); var takoWebResultSchema = z$1.object({ title: z$1.string(), url: z$1.string(), snippet: z$1.string().nullish(), source_name: z$1.string().nullish(), publish_date: z$1.string().nullish(), content: takoResultContentSchema.nullish() }).passthrough(); var takoSearchToolFactory = createProviderExecutedToolFactory({ id: "gateway.tako_search", inputSchema: takoSearchInputSchema, outputSchema: lazySchema(() => zodSchema(z$1.union([z$1.object({ request_id: z$1.string(), cards: z$1.array(takoCardSchema).optional(), web_results: z$1.array(takoWebResultSchema).optional(), usage: z$1.object({ total_cost_usd: z$1.number(), compute: z$1.object({ cost_usd: z$1.number() }).nullish(), data: z$1.object({ cost_usd: z$1.number(), datasets: z$1.number() }).nullish() }).nullish(), related: z$1.array(z$1.object({}).passthrough()).nullish() }).passthrough(), z$1.object({ error: z$1.enum([ "api_error", "configuration_error", "execution_error", "invalid_input", "rate_limit", "timeout", "unknown_tool" ]), statusCode: z$1.number().optional(), message: z$1.string() })]))) }); var takoSearch = (config = {}) => takoSearchToolFactory(config); var gatewayTools = { /** * Search the web using Exa for current information and token-efficient * excerpts optimized for agent workflows. * * Supports search type, category, domain, date, location, and content * extraction controls. */ exaSearch, /** * Search the web using Parallel AI's Search API for LLM-optimized excerpts. * * Takes a natural language objective and returns relevant excerpts, * replacing multiple keyword searches with a single call for broad * or complex queries. Supports different search types for depth vs * breadth tradeoffs. */ parallelSearch, /** * Search the web using Perplexity's Search API for real-time information, * news, research papers, and articles. * * Provides ranked search results with advanced filtering options including * domain, language, date range, and recency filters. */ perplexitySearch, /** * Search the web and Tako's curated knowledge graph in one call for * token-efficient web excerpts and structured data results grounded in * premium sources, each with an embed-ready visualization. * * Supports effort, per-source web and data controls, localization, and inline * contents for agents that need to reason over underlying data. */ takoSearch }; async function getVercelRequestId() { var _a12; return (_a12 = (0, import_index_browser.getContext)().headers) == null ? void 0 : _a12["x-vercel-id"]; } var VERSION$2 = "4.0.87"; var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1"; var gatewayClientSecretResponseSchema = z$1.object({ token: z$1.string(), expiresAt: z$1.number().nullish() }); function createGateway(options = {}) { var _a12, _b12; let pendingMetadata = null; let metadataCache = null; const cacheRefreshMillis = (_a12 = options.metadataCacheRefreshMillis) != null ? _a12 : 3e5; let lastFetchTime = 0; const baseURL = (_b12 = withoutTrailingSlash(options.baseURL)) != null ? _b12 : "https://ai-gateway.vercel.sh/v4/ai"; const createAuthHeaders = (auth) => withUserAgentSuffix({ Authorization: `Bearer ${auth.token}`, "ai-gateway-protocol-version": AI_GATEWAY_PROTOCOL_VERSION, [GATEWAY_AUTH_METHOD_HEADER]: auth.authMethod, ...options.teamIdOrSlug != null ? { [VERCEL_AI_GATEWAY_TEAM_HEADER]: options.teamIdOrSlug } : {}, ...options.headers }, `ai-sdk/gateway/${VERSION$2}`); const getHeaders = async () => { try { return createAuthHeaders(await getGatewayAuthToken(options)); } catch (error) { throw GatewayAuthenticationError.createContextualError({ apiKeyProvided: false, oidcTokenProvided: false, statusCode: 401, cause: error }); } }; const getRealtimeAuthToken = async () => { try { return await getGatewayAuthToken(options); } catch (error) { throw GatewayAuthenticationError.createContextualError({ apiKeyProvided: false, oidcTokenProvided: false, statusCode: 401, cause: error }); } }; const mintClientSecret = async (params) => { assertGatewayClientSecretServerEnvironment(); const auth = await getRealtimeAuthToken(); const headers = createAuthHeaders(auth); const url = new URL("/v1/realtime/client-secrets", baseURL).toString(); try { const { value } = await postJsonToApi({ url, headers, body: { model: params.modelId, ...params.routeKind != null && { routeKind: params.routeKind }, ...params.expiresAfterSeconds != null && { expiresIn: params.expiresAfterSeconds } }, successfulResponseHandler: createJsonResponseHandler(gatewayClientSecretResponseSchema), failedResponseHandler: createJsonErrorResponseHandler({ errorSchema: z$1.any(), errorToMessage: (data) => { var _a13; return (_a13 = getErrorMessage(data)) != null ? _a13 : "unknown error"; } }), fetch: options.fetch }); return { token: value.token, ...value.expiresAt != null && { expiresAt: value.expiresAt } }; } catch (error) { throw await asGatewayError(error, await parseAuthMethod(headers)); } }; const createO11yHeaders = () => { const deploymentId = loadOptionalSetting({ settingValue: void 0, environmentVariableName: "VERCEL_DEPLOYMENT_ID" }); const environment = loadOptionalSetting({ settingValue: void 0, environmentVariableName: "VERCEL_ENV" }); const region = loadOptionalSetting({ settingValue: void 0, environmentVariableName: "VERCEL_REGION" }); const projectId = loadOptionalSetting({ settingValue: void 0, environmentVariableName: "VERCEL_PROJECT_ID" }); return async () => { const requestId = await getVercelRequestId(); return { ...deploymentId && { "ai-o11y-deployment-id": deploymentId }, ...environment && { "ai-o11y-environment": environment }, ...region && { "ai-o11y-region": region }, ...requestId && { "ai-o11y-request-id": requestId }, ...projectId && { "ai-o11y-project-id": projectId } }; }; }; const createLanguageModel = (modelId) => { return new GatewayLanguageModel(modelId, { provider: "gateway", baseURL, headers: getHeaders, fetch: options.fetch, o11yHeaders: createO11yHeaders() }); }; const createBatch = () => new GatewayBatch({ provider: "gateway", baseURL, headers: getHeaders, fetch: options.fetch, o11yHeaders: createO11yHeaders() }); const getAvailableModels = async () => { var _a13, _b13, _c; const now = (_c = (_b13 = (_a13 = options._internal) == null ? void 0 : _a13.currentDate) == null ? void 0 : _b13.call(_a13).getTime()) != null ? _c : Date.now(); if (!pendingMetadata || now - lastFetchTime > cacheRefreshMillis) { lastFetchTime = now; pendingMetadata = new GatewayFetchMetadata({ baseURL, headers: getHeaders, fetch: options.fetch }).getAvailableModels().then((metadata) => { metadataCache = metadata; return metadata; }).catch(async (error) => { throw await asGatewayError(error, await parseAuthMethod(await getHeaders())); }); } return metadataCache ? Promise.resolve(metadataCache) : pendingMetadata; }; const getCredits = async () => { return new GatewayFetchMetadata({ baseURL, headers: getHeaders, fetch: options.fetch }).getCredits().catch(async (error) => { throw await asGatewayError(error, await parseAuthMethod(await getHeaders())); }); }; const getSpendReport = async (params) => { return new GatewaySpendReport({ baseURL, headers: getHeaders, fetch: options.fetch }).getSpendReport(params).catch(async (error) => { throw await asGatewayError(error, await parseAuthMethod(await getHeaders())); }); }; const getGenerationInfo = async (params) => { return new GatewayGenerationInfoFetcher({ baseURL, headers: getHeaders, fetch: options.fetch }).getGenerationInfo(params).catch(async (error) => { throw await asGatewayError(error, await parseAuthMethod(await getHeaders())); }); }; const provider = function(modelId) { if (new.target) throw new Error("The Gateway Provider model function cannot be called with the new keyword."); return createLanguageModel(modelId); }; provider.specificationVersion = "v4"; provider.getAvailableModels = getAvailableModels; provider.getCredits = getCredits; provider.getSpendReport = getSpendReport; provider.getGenerationInfo = getGenerationInfo; provider.imageModel = (modelId) => { return new GatewayImageModel(modelId, { provider: "gateway", baseURL, headers: getHeaders, fetch: options.fetch, o11yHeaders: createO11yHeaders() }); }; provider.languageModel = createLanguageModel; provider.experimental_batch = createBatch; const createEmbeddingModel = (modelId) => { return new GatewayEmbeddingModel(modelId, { provider: "gateway", baseURL, headers: getHeaders, fetch: options.fetch, o11yHeaders: createO11yHeaders() }); }; provider.embeddingModel = createEmbeddingModel; provider.textEmbeddingModel = createEmbeddingModel; provider.videoModel = (modelId) => { return new GatewayVideoModel(modelId, { provider: "gateway", baseURL, headers: getHeaders, fetch: options.fetch, o11yHeaders: createO11yHeaders() }); }; const createRerankingModel = (modelId) => { return new GatewayRerankingModel(modelId, { provider: "gateway", baseURL, headers: getHeaders, fetch: options.fetch, o11yHeaders: createO11yHeaders() }); }; provider.rerankingModel = createRerankingModel; provider.reranking = createRerankingModel; const createEvaluationModel = (modelId) => { return new GatewayEvaluationModel(modelId, { provider: "gateway", baseURL, headers: getHeaders, fetch: options.fetch, o11yHeaders: createO11yHeaders() }); }; provider.evaluationModel = createEvaluationModel; provider.evaluation = createEvaluationModel; const createSpeechModel = (modelId) => { return new GatewaySpeechModel(modelId, { provider: "gateway", baseURL, headers: getHeaders, fetch: options.fetch, o11yHeaders: createO11yHeaders() }); }; provider.speechModel = createSpeechModel; provider.speech = createSpeechModel; const createTranscriptionModel = (modelId) => { return new GatewayTranscriptionModel(modelId, { provider: "gateway", baseURL, headers: getHeaders, fetch: options.fetch, o11yHeaders: createO11yHeaders(), webSocket: options.webSocket }); }; provider.transcriptionModel = createTranscriptionModel; provider.transcription = createTranscriptionModel; provider.experimental_transcription = Object.assign((modelId) => createTranscriptionModel(modelId), { getToken: async (tokenOptions) => { const secret = await mintClientSecret({ modelId: tokenOptions.model, routeKind: "transcription", ...tokenOptions.expiresAfterSeconds != null && { expiresAfterSeconds: tokenOptions.expiresAfterSeconds } }); return { token: secret.token, url: toGatewayTranscriptionUrl(baseURL, tokenOptions.model), ...secret.expiresAt != null && { expiresAt: secret.expiresAt } }; } }); const createRealtimeModel = (modelId) => new GatewayRealtimeModel(modelId, { provider: "gateway.realtime", baseURL, teamIdOrSlug: options.teamIdOrSlug, createClientSecret: mintClientSecret }); provider.experimental_realtime = Object.assign((modelId) => createRealtimeModel(modelId), { getToken: async (tokenOptions) => { const { model: modelId, ...secretOptions } = tokenOptions; const secret = await createRealtimeModel(modelId).doCreateClientSecret(secretOptions); return { token: secret.token, url: secret.url, ...secret.expiresAt != null && { expiresAt: secret.expiresAt } }; } }); provider.chat = provider.languageModel; provider.embedding = provider.embeddingModel; provider.image = provider.imageModel; provider.video = provider.videoModel; provider.tools = gatewayTools; return provider; } var gateway = createGateway(); async function getGatewayAuthToken(options) { const apiKey = loadOptionalSetting({ settingValue: options.apiKey, environmentVariableName: "AI_GATEWAY_API_KEY" }); if (apiKey) return { token: apiKey, authMethod: "api-key" }; return { token: await (0, import_index_browser.getVercelOidcToken)(), authMethod: "oidc" }; } function assertGatewayClientSecretServerEnvironment() { if (typeof globalThis.window !== "undefined") throw new Error("AI Gateway client secrets must be minted server-side: minting needs your Gateway credential, which must never reach the browser. Call gateway.experimental_realtime.getToken() or gateway.experimental_transcription.getToken() from your server and pass the returned token to the client."); } //#endregion //#region node_modules/ai/dist/index.js var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name25 in all) __defProp(target, name25, { get: all[name25], enumerable: true }); }; var name = "AI_InvalidArgumentError"; var marker = `vercel.ai.error.${name}`; var symbol = Symbol.for(marker); var _a; var _b; var InvalidArgumentError = class extends (_b = AISDKError, _a = symbol, _b) { constructor({ parameter, value, message }) { super({ name, message: `Invalid argument for parameter ${parameter}: ${message}` }); this[_a] = true; this.parameter = parameter; this.value = value; } static isInstance(error) { return AISDKError.hasMarker(error, marker); } }; var name3 = "AI_InvalidToolApprovalError"; var marker3 = `vercel.ai.error.${name3}`; var symbol3 = Symbol.for(marker3); var _a3; var _b3; var InvalidToolApprovalError = class extends (_b3 = AISDKError, _a3 = symbol3, _b3) { constructor({ approvalId }) { super({ name: name3, message: `Tool approval response references unknown approvalId: "${approvalId}". No matching tool-approval-request found in message history.` }); this[_a3] = true; this.approvalId = approvalId; } static isInstance(error) { return AISDKError.hasMarker(error, marker3); } }; var name4 = "AI_InvalidToolApprovalSignatureError"; var marker4 = `vercel.ai.error.${name4}`; var symbol4 = Symbol.for(marker4); var _a4; var _b4; var InvalidToolApprovalSignatureError = class extends (_b4 = AISDKError, _a4 = symbol4, _b4) { constructor({ approvalId, toolCallId, reason }) { super({ name: name4, message: `Tool approval signature verification failed for approval "${approvalId}" (tool call "${toolCallId}"): ${reason}` }); this[_a4] = true; this.approvalId = approvalId; this.toolCallId = toolCallId; } static isInstance(error) { return AISDKError.hasMarker(error, marker4); } }; var name5 = "AI_InvalidToolInputError"; var marker5 = `vercel.ai.error.${name5}`; var symbol5 = Symbol.for(marker5); var _a5; var _b5; var InvalidToolInputError = class extends (_b5 = AISDKError, _a5 = symbol5, _b5) { constructor({ toolInput, toolName, cause, message = `Invalid input for tool ${toolName}: ${getErrorMessage(cause)}` }) { super({ name: name5, message, cause }); this[_a5] = true; this.toolInput = toolInput; this.toolName = toolName; } static isInstance(error) { return AISDKError.hasMarker(error, marker5); } }; var name6 = "AI_ToolCallNotFoundForApprovalError"; var marker6 = `vercel.ai.error.${name6}`; var symbol6 = Symbol.for(marker6); var _a6; var _b6; var ToolCallNotFoundForApprovalError = class extends (_b6 = AISDKError, _a6 = symbol6, _b6) { constructor({ toolCallId, approvalId }) { super({ name: name6, message: `Tool call "${toolCallId}" not found for approval request "${approvalId}".` }); this[_a6] = true; this.toolCallId = toolCallId; this.approvalId = approvalId; } static isInstance(error) { return AISDKError.hasMarker(error, marker6); } }; var name7 = "AI_MissingToolResultsError"; var marker7 = `vercel.ai.error.${name7}`; var symbol7 = Symbol.for(marker7); var _a7; var _b7; var MissingToolResultsError = class extends (_b7 = AISDKError, _a7 = symbol7, _b7) { constructor({ toolCallIds }) { super({ name: name7, message: `Tool result${toolCallIds.length > 1 ? "s are" : " is"} missing for tool call${toolCallIds.length > 1 ? "s" : ""} ${toolCallIds.join(", ")}.` }); this[_a7] = true; this.toolCallIds = toolCallIds; } static isInstance(error) { return AISDKError.hasMarker(error, marker7); } }; var name9 = "AI_NoObjectGeneratedError"; var marker9 = `vercel.ai.error.${name9}`; var symbol9 = Symbol.for(marker9); var _a9; var _b9; var NoObjectGeneratedError = class extends (_b9 = AISDKError, _a9 = symbol9, _b9) { constructor({ message = "No object generated.", cause, text: text2, response, usage, finishReason }) { super({ name: name9, message, cause }); this[_a9] = true; this.text = text2; this.response = response; this.usage = usage; this.finishReason = finishReason; } static isInstance(error) { return AISDKError.hasMarker(error, marker9); } }; var name10 = "AI_NoOutputGeneratedError"; var marker10 = `vercel.ai.error.${name10}`; var symbol10 = Symbol.for(marker10); var _a10; var _b10; var NoOutputGeneratedError = class extends (_b10 = AISDKError, _a10 = symbol10, _b10) { constructor({ message = "No output generated.", cause } = {}) { super({ name: name10, message, cause }); this[_a10] = true; } static isInstance(error) { return AISDKError.hasMarker(error, marker10); } }; var name15 = "AI_NoSuchToolError"; var marker15 = `vercel.ai.error.${name15}`; var symbol15 = Symbol.for(marker15); var _a15; var _b15; var NoSuchToolError = class extends (_b15 = AISDKError, _a15 = symbol15, _b15) { constructor({ toolName, availableTools = void 0, message = `Model tried to call unavailable tool '${toolName}'. ${availableTools === void 0 ? "No tools are available." : `Available tools: ${availableTools.join(", ")}.`}` }) { super({ name: name15, message }); this[_a15] = true; this.toolName = toolName; this.availableTools = availableTools; } static isInstance(error) { return AISDKError.hasMarker(error, marker15); } }; var name16 = "AI_StreamProviderError"; var marker16 = `vercel.ai.error.${name16}`; var symbol16 = Symbol.for(marker16); var _a16; var _b16; var StreamProviderError = class extends (_b16 = AISDKError, _a16 = symbol16, _b16) { constructor({ message, type, code, statusCode, isRetryable = isRetryableStatusCode(statusCode), data, cause }) { super({ name: name16, message, cause }); this[_a16] = true; this.type = type; this.code = code; this.statusCode = statusCode; this.isRetryable = isRetryable; this.data = data; } static isInstance(error) { return AISDKError.hasMarker(error, marker16); } }; function isRetryableStatusCode(statusCode) { return statusCode != null && (statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500); } var name17 = "AI_ToolCallRepairError"; var marker17 = `vercel.ai.error.${name17}`; var symbol17 = Symbol.for(marker17); var _a17; var _b17; var ToolCallRepairError = class extends (_b17 = AISDKError, _a17 = symbol17, _b17) { constructor({ cause, originalError, message = `Error repairing tool call: ${getErrorMessage(cause)}` }) { super({ name: name17, message, cause }); this[_a17] = true; this.originalError = originalError; } static isInstance(error) { return AISDKError.hasMarker(error, marker17); } }; var name18 = "AI_ToolChoiceViolationError"; var marker18 = `vercel.ai.error.${name18}`; var symbol18 = Symbol.for(marker18); var _a18; var _b18; var ToolChoiceViolationError = class extends (_b18 = AISDKError, _a18 = symbol18, _b18) { constructor({ toolChoice, finishReason, provider, modelId, content, message = toolChoice.type === "required" ? "Model response did not contain a tool call even though tool choice was required." : `Model response did not contain a call to the required tool '${toolChoice.toolName}'.` }) { super({ name: name18, message }); this[_a18] = true; this.toolChoice = toolChoice; this.finishReason = finishReason; this.provider = provider; this.modelId = modelId; this.content = content; } static isInstance(error) { return AISDKError.hasMarker(error, marker18); } }; var UnsupportedModelVersionError = class extends AISDKError { constructor(options) { super({ name: "AI_UnsupportedModelVersionError", message: `Unsupported model version ${options.version} for provider "${options.provider}" and model "${options.modelId}". AI SDK 5 only supports models that implement specification version "v2".` }); this.version = options.version; this.provider = options.provider; this.modelId = options.modelId; } }; var name19 = "AI_UIMessageStreamError"; var marker19 = `vercel.ai.error.${name19}`; var symbol19 = Symbol.for(marker19); var _a19; var _b19; var UIMessageStreamError = class extends (_b19 = AISDKError, _a19 = symbol19, _b19) { constructor({ chunkType, chunkId, message }) { super({ name: name19, message }); this[_a19] = true; this.chunkType = chunkType; this.chunkId = chunkId; } static isInstance(error) { return AISDKError.hasMarker(error, marker19); } }; var name20 = "AI_InvalidDataContentError"; var marker20 = `vercel.ai.error.${name20}`; var symbol20 = Symbol.for(marker20); var _a20; var _b20; var InvalidDataContentError = class extends (_b20 = AISDKError, _a20 = symbol20, _b20) { constructor({ content, cause, message = `Invalid data content. Expected a base64 string, Uint8Array, ArrayBuffer, or Buffer, but got ${typeof content}.` }) { super({ name: name20, message, cause }); this[_a20] = true; this.content = content; } static isInstance(error) { return AISDKError.hasMarker(error, marker20); } }; var name21 = "AI_InvalidMessageRoleError"; var marker21 = `vercel.ai.error.${name21}`; var symbol21 = Symbol.for(marker21); var _a21; var _b21; var InvalidMessageRoleError = class extends (_b21 = AISDKError, _a21 = symbol21, _b21) { constructor({ role, message = `Invalid message role: '${role}'. Must be one of: "system", "user", "assistant", "tool".` }) { super({ name: name21, message }); this[_a21] = true; this.role = role; } static isInstance(error) { return AISDKError.hasMarker(error, marker21); } }; var name23 = "AI_RetryError"; var marker23 = `vercel.ai.error.${name23}`; var symbol23 = Symbol.for(marker23); var _a23; var _b23; var RetryError = class extends (_b23 = AISDKError, _a23 = symbol23, _b23) { constructor({ message, reason, errors }) { super({ name: name23, message }); this[_a23] = true; this.reason = reason; this.errors = errors; this.lastError = errors[errors.length - 1]; } static isInstance(error) { return AISDKError.hasMarker(error, marker23); } }; function formatWarning({ warning, provider, model }) { const prefix = `AI SDK Warning${provider != null && model != null ? ` (${provider} / ${model})` : ""}:`; switch (warning.type) { case "unsupported": { let message = `${prefix} The feature "${warning.feature}" is not supported.`; if (warning.details) message += ` ${warning.details}`; return message; } case "compatibility": { let message = `${prefix} The feature "${warning.feature}" is used in a compatibility mode.`; if (warning.details) message += ` ${warning.details}`; return message; } case "deprecated": return `${prefix} Deprecated: "${warning.setting}". ${warning.message}`; case "other": return `${prefix} ${warning.message}`; default: return `${prefix} ${JSON.stringify(warning, null, 2)}`; } } var FIRST_WARNING_INFO_MESSAGE = "AI SDK Warning System: To turn off warning logging, set the AI_SDK_LOG_WARNINGS global to false."; var hasLoggedBefore = false; function emitWarning({ message, type }) { if (typeof process !== "undefined" && typeof process.emitWarning === "function") process.emitWarning(message, { type }); else console.warn(message); } var logWarnings = (options) => { if (options.warnings.length === 0) return; const logger = globalThis.AI_SDK_LOG_WARNINGS; if (logger === false) return; if (typeof logger === "function") { logger(options); return; } if (!hasLoggedBefore) { hasLoggedBefore = true; emitWarning({ message: FIRST_WARNING_INFO_MESSAGE, type: "Warning" }); } for (const warning of options.warnings) emitWarning({ message: formatWarning({ warning, provider: options.provider, model: options.model }), type: warning.type === "deprecated" ? "DeprecationWarning" : "Warning" }); }; function logV2CompatibilityWarning({ provider, modelId }) { logWarnings({ warnings: [{ type: "compatibility", feature: "specificationVersion", details: `Using v2 specification compatibility mode. Some features may not be available.` }], provider, model: modelId }); } function asEmbeddingModelV3(model) { if (model.specificationVersion === "v3") return model; logV2CompatibilityWarning({ provider: model.provider, modelId: model.modelId }); return new Proxy(model, { get(target, prop) { if (prop === "specificationVersion") return "v3"; return target[prop]; } }); } function asEmbeddingModelV4(model) { if (model.specificationVersion === "v4") return model; const v3Model = model.specificationVersion === "v2" ? asEmbeddingModelV3(model) : model; return new Proxy(v3Model, { get(target, prop) { if (prop === "specificationVersion") return "v4"; return target[prop]; } }); } function asImageModelV3(model) { if (model.specificationVersion === "v3") return model; logV2CompatibilityWarning({ provider: model.provider, modelId: model.modelId }); return new Proxy(model, { get(target, prop) { if (prop === "specificationVersion") return "v3"; return target[prop]; } }); } function asImageModelV4(model) { if (model.specificationVersion === "v4") return model; const v3Model = model.specificationVersion === "v2" ? asImageModelV3(model) : model; return new Proxy(v3Model, { get(target, prop) { if (prop === "specificationVersion") return "v4"; return target[prop]; } }); } function asLanguageModelV3(model) { if (model.specificationVersion === "v3") return model; logV2CompatibilityWarning({ provider: model.provider, modelId: model.modelId }); return new Proxy(model, { get(target, prop) { switch (prop) { case "specificationVersion": return "v3"; case "doGenerate": return async (...args) => { const result = await target.doGenerate(...args); return { ...result, finishReason: convertV2FinishReasonToV3(result.finishReason), usage: convertV2UsageToV3(result.usage) }; }; case "doStream": return async (...args) => { const result = await target.doStream(...args); return { ...result, stream: convertV2StreamToV3(result.stream) }; }; default: return target[prop]; } } }); } function convertV2StreamToV3(stream) { return stream.pipeThrough(new TransformStream({ transform(chunk, controller) { switch (chunk.type) { case "finish": controller.enqueue({ ...chunk, finishReason: convertV2FinishReasonToV3(chunk.finishReason), usage: convertV2UsageToV3(chunk.usage) }); break; default: controller.enqueue(chunk); } } })); } function convertV2FinishReasonToV3(finishReason) { return { unified: finishReason === "unknown" ? "other" : finishReason, raw: void 0 }; } function convertV2UsageToV3(usage) { return { inputTokens: { total: usage.inputTokens, noCache: void 0, cacheRead: usage.cachedInputTokens, cacheWrite: void 0 }, outputTokens: { total: usage.outputTokens, text: void 0, reasoning: usage.reasoningTokens } }; } function asLanguageModelV4(model) { if (model.specificationVersion === "v4") return model; const v3Model = model.specificationVersion === "v2" ? asLanguageModelV3(model) : model; return new Proxy(v3Model, { get(target, prop) { if (prop === "specificationVersion") return "v4"; return target[prop]; } }); } function asRerankingModelV4(model) { if (model.specificationVersion === "v4") return model; return new Proxy(model, { get(target, prop) { if (prop === "specificationVersion") return "v4"; return target[prop]; } }); } function asSpeechModelV3(model) { if (model.specificationVersion === "v3") return model; logV2CompatibilityWarning({ provider: model.provider, modelId: model.modelId }); return new Proxy(model, { get(target, prop) { if (prop === "specificationVersion") return "v3"; return target[prop]; } }); } function asSpeechModelV4(model) { if (model.specificationVersion === "v4") return model; const v3Model = model.specificationVersion === "v2" ? asSpeechModelV3(model) : model; return new Proxy(v3Model, { get(target, prop) { if (prop === "specificationVersion") return "v4"; return target[prop]; } }); } function asTranscriptionModelV3(model) { if (model.specificationVersion === "v3") return model; logV2CompatibilityWarning({ provider: model.provider, modelId: model.modelId }); return new Proxy(model, { get(target, prop) { if (prop === "specificationVersion") return "v3"; return target[prop]; } }); } function asTranscriptionModelV4(model) { if (model.specificationVersion === "v4") return model; const v3Model = model.specificationVersion === "v2" ? asTranscriptionModelV3(model) : model; return new Proxy(v3Model, { get(target, prop) { if (prop === "specificationVersion") return "v4"; return target[prop]; } }); } function asProviderV3(provider) { if ("specificationVersion" in provider && provider.specificationVersion === "v3") return provider; const v2Provider = provider; return { specificationVersion: "v3", languageModel: (modelId) => asLanguageModelV3(v2Provider.languageModel(modelId)), embeddingModel: (modelId) => asEmbeddingModelV3(v2Provider.textEmbeddingModel(modelId)), imageModel: (modelId) => asImageModelV3(v2Provider.imageModel(modelId)), transcriptionModel: v2Provider.transcriptionModel ? (modelId) => asTranscriptionModelV3(v2Provider.transcriptionModel(modelId)) : void 0, speechModel: v2Provider.speechModel ? (modelId) => asSpeechModelV3(v2Provider.speechModel(modelId)) : void 0, rerankingModel: void 0 }; } function asProviderV4(provider) { if ("specificationVersion" in provider && provider.specificationVersion === "v4") return provider; const v3Provider = !("specificationVersion" in provider) || provider.specificationVersion !== "v3" ? asProviderV3(provider) : provider; return { specificationVersion: "v4", languageModel: (modelId) => asLanguageModelV4(v3Provider.languageModel(modelId)), embeddingModel: (modelId) => asEmbeddingModelV4(v3Provider.embeddingModel(modelId)), imageModel: (modelId) => asImageModelV4(v3Provider.imageModel(modelId)), transcriptionModel: v3Provider.transcriptionModel ? (modelId) => asTranscriptionModelV4(v3Provider.transcriptionModel(modelId)) : void 0, speechModel: v3Provider.speechModel ? (modelId) => asSpeechModelV4(v3Provider.speechModel(modelId)) : void 0, rerankingModel: v3Provider.rerankingModel ? (modelId) => asRerankingModelV4(v3Provider.rerankingModel(modelId)) : void 0 }; } function resolveLanguageModel(model) { if (typeof model === "string") return getGlobalProvider().languageModel(model); if (![ "v4", "v3", "v2" ].includes(model.specificationVersion)) { const unsupportedModel = model; throw new UnsupportedModelVersionError({ version: unsupportedModel.specificationVersion, provider: unsupportedModel.provider, modelId: unsupportedModel.modelId }); } return asLanguageModelV4(model); } function getGlobalProvider() { var _a25; return asProviderV4((_a25 = globalThis.AI_SDK_DEFAULT_PROVIDER) != null ? _a25 : gateway); } function cloneModelMessages(messages) { return messages.map((message) => cloneValue(message)); } function cloneValue(value) { if (value instanceof URL) return new URL(value.href); if (Array.isArray(value)) return value.map((item) => cloneValue(item)); if (value instanceof Uint8Array) return new Uint8Array(value); if (value instanceof ArrayBuffer) return value.slice(0); if (value instanceof Date) return new Date(value); if (value != null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, value2]) => [key, cloneValue(value2)])); return value; } var VERSION$1 = "7.0.107"; var download = async ({ url, maxBytes, abortSignal }) => { var _a25; const urlText = url.toString(); try { const response = await fetchWithValidatedRedirects({ url: urlText, headers: withUserAgentSuffix({}, `ai-sdk/${VERSION$1}`, getRuntimeEnvironmentUserAgent()), abortSignal }); if (!response.ok) { await cancelResponseBody(response); throw new DownloadError({ url: urlText, statusCode: response.status, statusText: response.statusText }); } return { data: await readResponseWithSizeLimit({ response, url: urlText, maxBytes: maxBytes != null ? maxBytes : DEFAULT_MAX_DOWNLOAD_SIZE }), mediaType: (_a25 = response.headers.get("content-type")) != null ? _a25 : void 0 }; } catch (error) { if (DownloadError.isInstance(error)) throw error; throw new DownloadError({ url: urlText, cause: error }); } }; var createDefaultDownloadFunction = (download2 = download, abortSignal) => (requestedDownloads) => Promise.all(requestedDownloads.map(async (requestedDownload) => requestedDownload.isUrlSupportedByModel ? null : await download2({ ...requestedDownload, abortSignal }))); function mergeObjects(base, overrides) { if (base === void 0 && overrides === void 0) return; if (base === void 0) return overrides; if (overrides === void 0) return base; const result = { ...base }; for (const key in overrides) { if (key === "__proto__" || key === "constructor" || key === "prototype") continue; if (Object.prototype.hasOwnProperty.call(overrides, key)) { const overridesValue = overrides[key]; if (overridesValue === void 0) continue; const baseValue = key in base ? base[key] : void 0; const isSourceObject = overridesValue !== null && typeof overridesValue === "object" && !Array.isArray(overridesValue) && !(overridesValue instanceof Date) && !(overridesValue instanceof RegExp); const isTargetObject = baseValue !== null && baseValue !== void 0 && typeof baseValue === "object" && !Array.isArray(baseValue) && !(baseValue instanceof Date) && !(baseValue instanceof RegExp); if (isSourceObject && isTargetObject) result[key] = mergeObjects(baseValue, overridesValue); else result[key] = overridesValue; } } return result; } function splitDataUrl(dataUrl) { try { const [header, base64Content] = dataUrl.split(","); return { mediaType: header.split(";")[0].split(":")[1], base64Content }; } catch (e) { return { mediaType: void 0, base64Content: void 0 }; } } function isTaggedFileData(value) { if (typeof value !== "object" || value === null) return false; const type = value.type; return type === "data" || type === "url" || type === "reference" || type === "text"; } function convertUrlToFilePartData(url) { if (url.protocol === "data:") { const { mediaType, base64Content } = splitDataUrl(url.toString()); if (mediaType == null || base64Content == null) throw new InvalidDataContentError({ content: url, message: `Invalid data URL format in content ${url.toString()}` }); return { data: { type: "data", data: base64Content }, mediaType }; } return { data: { type: "url", url }, mediaType: void 0 }; } function convertInlineDataToFilePartData(content) { if (content instanceof Uint8Array) return { data: { type: "data", data: content }, mediaType: void 0 }; if (content instanceof ArrayBuffer) return { data: { type: "data", data: new Uint8Array(content) }, mediaType: void 0 }; if (isBuffer(content)) return { data: { type: "data", data: new Uint8Array(content) }, mediaType: void 0 }; return { data: { type: "data", data: content }, mediaType: void 0 }; } function convertToLanguageModelV4FilePart(content) { if (isTaggedFileData(content)) switch (content.type) { case "data": if (typeof content.data === "string" && content.data.startsWith("data:")) throw new InvalidDataContentError({ content: content.data, message: "Data URLs are not valid inline data. Pass them as { type: \"url\", url } instead." }); return convertInlineDataToFilePartData(content.data); case "url": return convertUrlToFilePartData(content.url); case "reference": return { data: { type: "reference", reference: content.reference }, mediaType: void 0 }; case "text": return { data: { type: "text", text: content.text }, mediaType: void 0 }; } if (content instanceof URL) return convertUrlToFilePartData(content); if (typeof content === "string") try { return convertUrlToFilePartData(new URL(content)); } catch (e) { return convertInlineDataToFilePartData(content); } if (isProviderReference(content)) return { data: { type: "reference", reference: content }, mediaType: void 0 }; return convertInlineDataToFilePartData(content); } async function convertToLanguageModelPrompt({ prompt, supportedUrls, download: download2, abortSignal, provider }) { const downloadedAssets = await downloadAssets(prompt.messages, download2 != null ? download2 : createDefaultDownloadFunction(void 0, abortSignal), supportedUrls); const approvalIdToToolCallId = /* @__PURE__ */ new Map(); for (const message of prompt.messages) if (message.role === "assistant" && Array.isArray(message.content)) { for (const part of message.content) if (part.type === "tool-approval-request" && "approvalId" in part && "toolCallId" in part) approvalIdToToolCallId.set(part.approvalId, part.toolCallId); } const approvedToolCallIds = /* @__PURE__ */ new Set(); for (const message of prompt.messages) if (message.role === "tool") { for (const part of message.content) if (part.type === "tool-approval-response") { const toolCallId = approvalIdToToolCallId.get(part.approvalId); if (toolCallId) approvedToolCallIds.add(toolCallId); } } const messages = [...prompt.instructions != null ? typeof prompt.instructions === "string" ? [{ role: "system", content: prompt.instructions }] : asArray(prompt.instructions).map((message) => ({ role: "system", content: message.content, providerOptions: message.providerOptions })) : [], ...prompt.messages.map((message) => convertToLanguageModelMessage({ message, downloadedAssets, provider }))]; const combinedMessages = []; for (const message of messages) { if (message.role !== "tool") { combinedMessages.push(message); continue; } const lastCombinedMessage = combinedMessages.at(-1); if ((lastCombinedMessage == null ? void 0 : lastCombinedMessage.role) === "tool") { const lastContentPart = lastCombinedMessage.content.at(-1); if (lastContentPart != null && lastCombinedMessage.providerOptions != null) lastContentPart.providerOptions = mergeObjects(lastCombinedMessage.providerOptions, lastContentPart.providerOptions); lastCombinedMessage.content.push(...message.content); lastCombinedMessage.providerOptions = message.providerOptions; } else combinedMessages.push(message); } const toolCallIds = /* @__PURE__ */ new Set(); for (const message of combinedMessages) switch (message.role) { case "assistant": for (const content of message.content) if (content.type === "tool-call" && !content.providerExecuted) toolCallIds.add(content.toolCallId); break; case "tool": for (const content of message.content) if (content.type === "tool-result") toolCallIds.delete(content.toolCallId); break; case "user": case "system": for (const id of approvedToolCallIds) toolCallIds.delete(id); if (toolCallIds.size > 0) throw new MissingToolResultsError({ toolCallIds: Array.from(toolCallIds) }); } for (const id of approvedToolCallIds) toolCallIds.delete(id); if (toolCallIds.size > 0) throw new MissingToolResultsError({ toolCallIds: Array.from(toolCallIds) }); return combinedMessages.filter((message) => message.role !== "tool" || message.content.length > 0); } function convertToLanguageModelMessage({ message, downloadedAssets, provider }) { const warnings = []; const role = message.role; switch (role) { case "system": return { role: "system", content: message.content, providerOptions: message.providerOptions }; case "user": { if (typeof message.content === "string") return { role: "user", content: [{ type: "text", text: message.content }], providerOptions: message.providerOptions }; const converted = { role: "user", content: message.content.map((part) => { if (part.type === "image") warnings.push({ type: "deprecated", setting: "\"image\" content part", message: `The "image" content part type is deprecated. Use a "file" part with mediaType: 'image' (or a more specific image/* subtype) instead.` }); return convertImagePartToFilePart(part); }).map((part) => convertPartToLanguageModelPart(part, downloadedAssets)).filter((part) => part.type !== "text" || part.text !== ""), providerOptions: message.providerOptions }; if (warnings.length > 0) logWarnings({ warnings }); return converted; } case "assistant": { if (typeof message.content === "string") return { role: "assistant", content: [{ type: "text", text: message.content }], providerOptions: message.providerOptions }; const converted = { role: "assistant", content: message.content.filter((part) => part.type !== "text" || part.text !== "" || part.providerOptions != null).filter((part) => part.type !== "tool-approval-request").map((part) => { const providerOptions = part.providerOptions; switch (part.type) { case "custom": return { type: "custom", kind: part.kind, providerOptions }; case "file": { const { data, mediaType } = convertToLanguageModelV4FilePart(part.data); return { type: "file", data, filename: part.filename, mediaType: mediaType != null ? mediaType : part.mediaType, providerOptions }; } case "reasoning": return { type: "reasoning", text: part.text, providerOptions }; case "reasoning-file": { const { data, mediaType } = convertToLanguageModelV4FilePart(part.data); if (data.type !== "data" && data.type !== "url") throw new Error(`Unsupported reasoning-file data type: ${data.type}`); return { type: "reasoning-file", data, mediaType: mediaType != null ? mediaType : part.mediaType, providerOptions }; } case "text": return { type: "text", text: part.text, providerOptions }; case "tool-call": return { type: "tool-call", toolCallId: part.toolCallId, toolName: part.toolName, input: part.input, providerExecuted: part.providerExecuted, providerOptions }; case "tool-result": return { type: "tool-result", toolCallId: part.toolCallId, toolName: part.toolName, output: mapToolResultOutput({ output: part.output, provider, warnings, downloadedAssets }), providerOptions }; } }), providerOptions: message.providerOptions }; if (warnings.length > 0) logWarnings({ warnings }); return converted; } case "tool": { const converted = { role: "tool", content: message.content.filter((part) => part.type !== "tool-approval-response" || part.providerExecuted).map((part) => { switch (part.type) { case "tool-result": return { type: "tool-result", toolCallId: part.toolCallId, toolName: part.toolName, output: mapToolResultOutput({ output: part.output, provider, warnings, downloadedAssets }), providerOptions: part.providerOptions }; case "tool-approval-response": return { type: "tool-approval-response", approvalId: part.approvalId, approved: part.approved, reason: part.reason }; } }), providerOptions: message.providerOptions }; if (warnings.length > 0) logWarnings({ warnings }); return converted; } default: throw new InvalidMessageRoleError({ role }); } } function convertImagePartToFilePart(part) { var _a25; if (part.type !== "image") return part; return { type: "file", data: part.image, mediaType: (_a25 = part.mediaType) != null ? _a25 : "image", providerOptions: part.providerOptions }; } async function downloadAssets(messages, download2, supportedUrls) { const downloadableFiles = []; for (const message of messages) { if (message.role === "user" && Array.isArray(message.content)) for (const part of message.content) { const filePart = convertImagePartToFilePart(part); if (filePart.type === "file") downloadableFiles.push(filePart); } if (message.role === "tool") for (const part of message.content) { if (part.type !== "tool-result") continue; if (part.output.type !== "content") continue; for (const contentPart of part.output.value) if (contentPart.type === "file") downloadableFiles.push(contentPart); } if (message.role === "assistant" && Array.isArray(message.content)) for (const part of message.content) { if (part.type !== "tool-result") continue; if (part.output.type !== "content") continue; for (const contentPart of part.output.value) if (contentPart.type === "file") downloadableFiles.push(contentPart); } } const plannedDownloads = downloadableFiles.map((part) => { const mediaType = part.mediaType; const { data } = convertToLanguageModelV4FilePart(part.data); return { mediaType, data }; }).filter((part) => part.data.type === "url").map((part) => ({ url: part.data.url, isUrlSupportedByModel: part.mediaType != null && isUrlSupported({ url: part.data.url.toString(), mediaType: part.mediaType, supportedUrls }) })); const downloadedFiles = await download2(plannedDownloads); return Object.fromEntries(downloadedFiles.map((file, index) => file == null ? null : [plannedDownloads[index].url.toString(), { data: file.data, mediaType: file.mediaType }]).filter((file) => file != null)); } function convertPartToLanguageModelPart(part, downloadedAssets) { if (part.type === "text") return { type: "text", text: part.text, providerOptions: part.providerOptions }; const { data: normalizedData, mediaType: dataUrlMediaType } = convertToLanguageModelV4FilePart(part.data); let mediaType = dataUrlMediaType != null ? dataUrlMediaType : part.mediaType; let data = normalizedData; if (data.type === "url") { const downloadedFile = downloadedAssets[data.url.toString()]; if (downloadedFile) { data = { type: "data", data: downloadedFile.data }; if (downloadedFile.mediaType != null && (mediaType == null || !isFullMediaType(mediaType))) mediaType = downloadedFile.mediaType; } } if (data.type === "data" && (data.data instanceof Uint8Array || typeof data.data === "string")) { const imageMediaType = detectMediaType({ data: data.data, topLevelType: "image" }); if (imageMediaType != null) mediaType = imageMediaType; } if (mediaType == null) throw new Error(`Media type is missing for file part`); return { type: "file", mediaType, filename: part.filename, data, providerOptions: part.providerOptions }; } function mapToolResultOutput({ output, provider, warnings = [], downloadedAssets }) { if (output.type !== "content") return output; return { type: "content", value: output.value.map((item) => { var _a25; switch (item.type) { case "file": { const convertedPart = convertPartToLanguageModelPart(item, downloadedAssets); if (convertedPart.type !== "file") throw new Error("Expected tool result file content to convert to file."); return convertedPart; } case "file-data": warnings.push({ type: "deprecated", setting: "\"tool-result\" content of type \"file-data\"", message: `The "file-data" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'data', data } instead.` }); return { type: "file", data: { type: "data", data: item.data }, filename: item.filename, mediaType: item.mediaType, providerOptions: item.providerOptions }; case "file-url": { const mediaType = (_a25 = item.mediaType) != null ? _a25 : getMediaTypeFromUrl(item.url); let message = `The "file-url" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'url', url } instead.`; if (!item.mediaType) { const inferenceSuffix = mediaType === "application/octet-stream" ? `Unable to infer media type from URL. Defaulting to 'application/octet-stream'.` : `Inferred media type '${mediaType}' from URL.`; message = `The "file-url" tool result content part with URL "${item.url}" is missing a "mediaType". ${inferenceSuffix} ${message}`; } warnings.push({ type: "deprecated", setting: "\"tool-result\" content of type \"file-url\"", message }); return { type: "file", data: { type: "url", url: new URL(item.url) }, mediaType, providerOptions: item.providerOptions }; } case "file-id": warnings.push({ type: "deprecated", setting: "\"tool-result\" content of type \"file-id\"", message: `The "file-id" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'reference', reference } instead.` }); return { type: "file", data: { type: "reference", reference: convertFileIdToProviderReference({ fileId: item.fileId, provider }) }, mediaType: "application", providerOptions: item.providerOptions }; case "file-reference": warnings.push({ type: "deprecated", setting: "\"tool-result\" content of type \"file-reference\"", message: `The "file-reference" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'reference', reference } instead.` }); return { type: "file", data: { type: "reference", reference: item.providerReference }, mediaType: "application", providerOptions: item.providerOptions }; case "image-data": warnings.push({ type: "deprecated", setting: "\"tool-result\" content of type \"image-data\"", message: `The "image-data" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'data', data } instead.` }); return { type: "file", data: { type: "data", data: item.data }, mediaType: item.mediaType, providerOptions: item.providerOptions }; case "image-url": warnings.push({ type: "deprecated", setting: "\"tool-result\" content of type \"image-url\"", message: `The "image-url" type for tool result content is deprecated. Use the "file" type with mediaType 'image' (or a specific image/* subtype) and { type: 'url', url } instead.` }); return { type: "file", data: { type: "url", url: new URL(item.url) }, mediaType: "image", providerOptions: item.providerOptions }; case "image-file-id": warnings.push({ type: "deprecated", setting: "\"tool-result\" content of type \"image-file-id\"", message: `The "image-file-id" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'reference', reference } instead.` }); return { type: "file", data: { type: "reference", reference: convertFileIdToProviderReference({ fileId: item.fileId, provider }) }, mediaType: "image", providerOptions: item.providerOptions }; case "image-file-reference": warnings.push({ type: "deprecated", setting: "\"tool-result\" content of type \"image-file-reference\"", message: `The "image-file-reference" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'reference', reference } instead.` }); return { type: "file", data: { type: "reference", reference: item.providerReference }, mediaType: "image", providerOptions: item.providerOptions }; default: return item; } }) }; } function convertFileIdToProviderReference({ fileId, provider }) { if (typeof fileId === "object") return fileId; if (provider == null) throw new Error("Cannot convert string fileId to provider reference without a provider ID. Use a Record fileId or switch to the file-reference type."); return { [provider]: fileId }; } var URL_EXTENSION_TO_MEDIA_TYPE = { jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png", gif: "image/gif", webp: "image/webp", svg: "image/svg+xml", avif: "image/avif", heic: "image/heic", bmp: "image/bmp", tiff: "image/tiff", tif: "image/tiff", pdf: "application/pdf", mp4: "video/mp4", webm: "video/webm", mp3: "audio/mpeg", wav: "audio/wav", ogg: "audio/ogg" }; function getMediaTypeFromUrl(url, fallbackMediaType = "application/octet-stream") { var _a25; try { const fileExtension = (_a25 = new URL(url).pathname.split(".").pop()) == null ? void 0 : _a25.toLowerCase(); if (fileExtension && Object.hasOwn(URL_EXTENSION_TO_MEDIA_TYPE, fileExtension)) return URL_EXTENSION_TO_MEDIA_TYPE[fileExtension]; } catch (e) {} return fallbackMediaType; } async function createToolModelOutput({ toolCallId, input, output, tool: tool3, errorMode }) { if (errorMode === "text") return { type: "error-text", value: getErrorMessage(output) }; else if (errorMode === "json") return { type: "error-json", value: toJSONValue(output) }; if (tool3 == null ? void 0 : tool3.toModelOutput) return await tool3.toModelOutput({ toolCallId, input, output }); return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: toJSONValue(output) }; } function toJSONValue(value) { if (value === void 0) return null; const serialized = JSON.stringify(value); return serialized === void 0 ? null : JSON.parse(serialized); } function prepareLanguageModelCallOptions({ maxOutputTokens, temperature, topP, topK, presencePenalty, frequencyPenalty, seed, stopSequences, reasoning }) { if (maxOutputTokens != null) { if (!Number.isInteger(maxOutputTokens)) throw new InvalidArgumentError({ parameter: "maxOutputTokens", value: maxOutputTokens, message: "maxOutputTokens must be an integer" }); if (maxOutputTokens < 1) throw new InvalidArgumentError({ parameter: "maxOutputTokens", value: maxOutputTokens, message: "maxOutputTokens must be >= 1" }); } if (temperature != null) { if (typeof temperature !== "number") throw new InvalidArgumentError({ parameter: "temperature", value: temperature, message: "temperature must be a number" }); } if (topP != null) { if (typeof topP !== "number") throw new InvalidArgumentError({ parameter: "topP", value: topP, message: "topP must be a number" }); } if (topK != null) { if (typeof topK !== "number") throw new InvalidArgumentError({ parameter: "topK", value: topK, message: "topK must be a number" }); } if (presencePenalty != null) { if (typeof presencePenalty !== "number") throw new InvalidArgumentError({ parameter: "presencePenalty", value: presencePenalty, message: "presencePenalty must be a number" }); } if (frequencyPenalty != null) { if (typeof frequencyPenalty !== "number") throw new InvalidArgumentError({ parameter: "frequencyPenalty", value: frequencyPenalty, message: "frequencyPenalty must be a number" }); } if (seed != null) { if (!Number.isInteger(seed)) throw new InvalidArgumentError({ parameter: "seed", value: seed, message: "seed must be an integer" }); } return { maxOutputTokens, temperature, topP, topK, presencePenalty, frequencyPenalty, stopSequences, seed, reasoning }; } function prepareToolChoice({ toolChoice }) { return toolChoice == null ? { type: "auto" } : typeof toolChoice === "string" ? { type: toolChoice } : { type: "tool", toolName: toolChoice.toolName }; } function isNonEmptyObject(object3) { return object3 != null && Object.keys(object3).length > 0; } async function prepareTools$1({ tools, toolOrder, toolsContext = {}, experimental_sandbox: sandbox }) { if (!isNonEmptyObject(tools)) return; const languageModelTools = []; for (const [name25, tool3] of orderToolEntries({ tools, toolOrder })) { const toolType = tool3.type; switch (toolType) { case void 0: case "dynamic": case "function": { const description = resolveToolDescription({ tool: tool3, toolName: name25, toolsContext, experimental_sandbox: sandbox }); const providerOptions = tool3.providerOptions; const inputExamples = tool3.inputExamples; const strict = tool3.strict; languageModelTools.push({ type: "function", name: name25, inputSchema: await asSchema(tool3.inputSchema).jsonSchema, ...description != null ? { description } : {}, ...inputExamples != null ? { inputExamples } : {}, ...providerOptions != null ? { providerOptions } : {}, ...strict != null ? { strict } : {} }); break; } case "provider": languageModelTools.push({ type: "provider", name: name25, id: tool3.id, args: tool3.args }); break; default: throw new Error(`Unsupported tool type: ${toolType}`); } } return languageModelTools; } function orderToolEntries({ tools, toolOrder }) { if (toolOrder == null) return Object.entries(tools); const toolEntries = Object.entries(tools); const orderedTools = toolEntries.filter(([name25]) => toolOrder.includes(name25)).sort(([nameA], [nameB]) => toolOrder.indexOf(nameA) - toolOrder.indexOf(nameB)); const unorderedTools = toolEntries.filter(([name25]) => !toolOrder.includes(name25)).sort(([nameA], [nameB]) => nameA < nameB ? -1 : nameA > nameB ? 1 : 0); return [...orderedTools, ...unorderedTools]; } function resolveToolDescription({ tool: tool3, toolName, toolsContext, experimental_sandbox: sandbox }) { return tool3.description === void 0 ? void 0 : typeof tool3.description === "string" ? tool3.description : tool3.description({ context: toolsContext[toolName], experimental_sandbox: sandbox }); } function getTotalTimeoutMs(timeout) { if (timeout == null) return; if (typeof timeout === "number") return timeout; return timeout.totalMs; } function getStepTimeoutMs(timeout) { if (timeout == null || typeof timeout === "number") return; return timeout.stepMs; } function getFirstChunkTimeoutMs(timeout) { if (timeout == null || typeof timeout === "number") return; return timeout.firstChunkMs; } function getChunkTimeoutMs(timeout) { if (timeout == null || typeof timeout === "number") return; return timeout.chunkMs; } function getToolTimeoutMs(timeout, toolName) { var _a25, _b25; if (timeout == null || typeof timeout === "number") return; return (_b25 = (_a25 = timeout.tools) == null ? void 0 : _a25[`${toolName}Ms`]) != null ? _b25 : timeout.toolMs; } var z = { array, boolean, custom, discriminatedUnion, enum: _enum, instanceof: _instanceof, lazy, literal, looseObject, never, null: _null, number, object, record, string, union, unknown }; var jsonValueSchema = z.lazy(() => z.union([ z.null(), z.string(), z.number(), z.boolean(), z.record(z.string(), jsonValueSchema.optional()), z.array(jsonValueSchema) ])); var providerMetadataSchema = z.record(z.string(), z.record(z.string(), jsonValueSchema.optional())); var fileInlineDataSchema = z.union([ z.string(), z.instanceof(Uint8Array), z.instanceof(ArrayBuffer), z.custom(isBuffer, { message: "Must be a Buffer" }) ]); var providerReferenceSchema = z.record(z.string(), z.string()); var textPartSchema = z.object({ type: z.literal("text"), text: z.string(), providerOptions: providerMetadataSchema.optional() }); var imagePartSchema = z.object({ type: z.literal("image"), image: z.union([ fileInlineDataSchema, z.instanceof(URL), providerReferenceSchema ]), mediaType: z.string().optional(), providerOptions: providerMetadataSchema.optional() }); var taggedFileDataSchema = z.discriminatedUnion("type", [ z.object({ type: z.literal("data"), data: fileInlineDataSchema }), z.object({ type: z.literal("url"), url: z.instanceof(URL) }), z.object({ type: z.literal("reference"), reference: providerReferenceSchema }), z.object({ type: z.literal("text"), text: z.string() }) ]); var taggedReasoningFileDataSchema = z.discriminatedUnion("type", [z.object({ type: z.literal("data"), data: fileInlineDataSchema }), z.object({ type: z.literal("url"), url: z.instanceof(URL) })]); var filePartSchema = z.object({ type: z.literal("file"), data: z.union([ taggedFileDataSchema, fileInlineDataSchema, z.instanceof(URL), providerReferenceSchema ]), filename: z.string().optional(), mediaType: z.string(), providerOptions: providerMetadataSchema.optional() }); var reasoningPartSchema = z.object({ type: z.literal("reasoning"), text: z.string(), providerOptions: providerMetadataSchema.optional() }); var customPartSchema = z.object({ type: z.literal("custom"), kind: z.string().transform((value) => value), providerOptions: providerMetadataSchema.optional() }); var reasoningFilePartSchema = z.object({ type: z.literal("reasoning-file"), data: z.union([ taggedReasoningFileDataSchema, fileInlineDataSchema, z.instanceof(URL) ]), mediaType: z.string(), providerOptions: providerMetadataSchema.optional() }); var toolCallPartSchema = z.object({ type: z.literal("tool-call"), toolCallId: z.string(), toolName: z.string(), input: z.unknown(), providerOptions: providerMetadataSchema.optional(), providerExecuted: z.boolean().optional() }); var outputSchema = z.discriminatedUnion("type", [ z.object({ type: z.literal("text"), value: z.string(), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("json"), value: jsonValueSchema, providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("execution-denied"), reason: z.string().optional(), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("error-text"), value: z.string(), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("error-json"), value: jsonValueSchema, providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("content"), value: z.array(z.union([ z.object({ type: z.literal("text"), text: z.string(), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("file"), data: taggedFileDataSchema, mediaType: z.string(), filename: z.string().optional(), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("file-data"), data: z.string(), mediaType: z.string(), filename: z.string().optional(), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("file-url"), url: z.string(), mediaType: z.string().optional(), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("file-id"), fileId: z.union([z.string(), z.record(z.string(), z.string())]), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("file-reference"), providerReference: z.record(z.string(), z.string()), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("image-data"), data: z.string(), mediaType: z.string(), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("image-url"), url: z.string(), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("image-file-id"), fileId: z.union([z.string(), z.record(z.string(), z.string())]), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("image-file-reference"), providerReference: z.record(z.string(), z.string()), providerOptions: providerMetadataSchema.optional() }), z.object({ type: z.literal("custom"), providerOptions: providerMetadataSchema.optional() }) ])) }) ]); var toolResultPartSchema = z.object({ type: z.literal("tool-result"), toolCallId: z.string(), toolName: z.string(), output: outputSchema, providerOptions: providerMetadataSchema.optional() }); var toolApprovalRequestSchema = z.object({ type: z.literal("tool-approval-request"), approvalId: z.string(), toolCallId: z.string(), reason: z.string().optional() }); var toolApprovalResponseSchema = z.object({ type: z.literal("tool-approval-response"), approvalId: z.string(), approved: z.boolean(), reason: z.string().optional() }); var systemModelMessageSchema = z.object({ role: z.literal("system"), content: z.string(), providerOptions: providerMetadataSchema.optional() }); var userModelMessageSchema = z.object({ role: z.literal("user"), content: z.union([z.string(), z.array(z.union([ textPartSchema, imagePartSchema, filePartSchema ]))]), providerOptions: providerMetadataSchema.optional() }); var assistantModelMessageSchema = z.object({ role: z.literal("assistant"), content: z.union([z.string(), z.array(z.union([ textPartSchema, customPartSchema, filePartSchema, reasoningPartSchema, reasoningFilePartSchema, toolCallPartSchema, toolResultPartSchema, toolApprovalRequestSchema ]))]), providerOptions: providerMetadataSchema.optional() }); var toolModelMessageSchema = z.object({ role: z.literal("tool"), content: z.array(z.union([toolResultPartSchema, toolApprovalResponseSchema])), providerOptions: providerMetadataSchema.optional() }); var modelMessageSchema = z.union([ systemModelMessageSchema, userModelMessageSchema, assistantModelMessageSchema, toolModelMessageSchema ]); async function standardizePrompt({ allowSystemInMessages = false, system, instructions = system, prompt, messages }) { if (prompt == null && messages == null) throw new InvalidPromptError({ prompt, message: "prompt or messages must be defined" }); if (prompt != null && messages != null) throw new InvalidPromptError({ prompt, message: "prompt and messages cannot be defined at the same time" }); if (typeof instructions !== "string" && !asArray(instructions).every((message) => message.role === "system")) throw new InvalidPromptError({ prompt, message: "instructions must be a string, SystemModelMessage, or array of SystemModelMessage" }); if (prompt != null && typeof prompt === "string") messages = [{ role: "user", content: prompt }]; else if (prompt != null && Array.isArray(prompt)) messages = prompt; else if (messages == null) throw new InvalidPromptError({ prompt, message: "prompt or messages must be defined" }); if (messages.length === 0) throw new InvalidPromptError({ prompt, message: "messages must not be empty" }); if (!allowSystemInMessages && messages.some((message) => message.role === "system")) throw new InvalidPromptError({ prompt, message: "System messages are not allowed in the prompt or messages fields. Use the instructions option instead." }); const validationResult = await safeValidateTypes({ value: messages, schema: z.array(modelMessageSchema) }); if (!validationResult.success) throw new InvalidPromptError({ prompt, message: "The messages do not match the ModelMessage[] schema.", cause: validationResult.error }); return { messages, instructions }; } function wrapGatewayError(error) { if (!GatewayAuthenticationError.isInstance(error)) return error; const isProductionEnv = (process == null ? void 0 : "production") === "production"; const moreInfoURL = "https://ai-sdk.dev/unauthenticated-ai-gateway"; if (isProductionEnv) return new AISDKError({ name: "GatewayError", message: `Unauthenticated. Configure AI_GATEWAY_API_KEY or use a provider module. Learn more: ${moreInfoURL}` }); return Object.assign(/* @__PURE__ */ new Error(`\x1B[1m\x1B[31mUnauthenticated request to AI Gateway.\x1B[0m To authenticate, set the \x1B[33mAI_GATEWAY_API_KEY\x1B[0m environment variable with your API key. Alternatively, you can use a provider module instead of the AI Gateway. Learn more: \x1B[34m${moreInfoURL}\x1B[0m `), { name: "GatewayAuthenticationError" }); } function asLanguageModelUsage(usage) { return { inputTokens: usage.inputTokens.total, inputTokenDetails: { noCacheTokens: usage.inputTokens.noCache, cacheReadTokens: usage.inputTokens.cacheRead, cacheWriteTokens: usage.inputTokens.cacheWrite }, outputTokens: usage.outputTokens.total, outputTokenDetails: { textTokens: usage.outputTokens.text, reasoningTokens: usage.outputTokens.reasoning }, totalTokens: addTokenCounts(usage.inputTokens.total, usage.outputTokens.total), raw: usage.raw }; } function createNullLanguageModelUsage() { return { inputTokens: void 0, inputTokenDetails: { noCacheTokens: void 0, cacheReadTokens: void 0, cacheWriteTokens: void 0 }, outputTokens: void 0, outputTokenDetails: { textTokens: void 0, reasoningTokens: void 0 }, totalTokens: void 0, raw: void 0 }; } function addLanguageModelUsage(usage1, usage2) { var _a25, _b25, _c, _d, _e, _f, _g, _h, _i, _j; return { inputTokens: addTokenCounts(usage1.inputTokens, usage2.inputTokens), inputTokenDetails: { noCacheTokens: addTokenCounts((_a25 = usage1.inputTokenDetails) == null ? void 0 : _a25.noCacheTokens, (_b25 = usage2.inputTokenDetails) == null ? void 0 : _b25.noCacheTokens), cacheReadTokens: addTokenCounts((_c = usage1.inputTokenDetails) == null ? void 0 : _c.cacheReadTokens, (_d = usage2.inputTokenDetails) == null ? void 0 : _d.cacheReadTokens), cacheWriteTokens: addTokenCounts((_e = usage1.inputTokenDetails) == null ? void 0 : _e.cacheWriteTokens, (_f = usage2.inputTokenDetails) == null ? void 0 : _f.cacheWriteTokens) }, outputTokens: addTokenCounts(usage1.outputTokens, usage2.outputTokens), outputTokenDetails: { textTokens: addTokenCounts((_g = usage1.outputTokenDetails) == null ? void 0 : _g.textTokens, (_h = usage2.outputTokenDetails) == null ? void 0 : _h.textTokens), reasoningTokens: addTokenCounts((_i = usage1.outputTokenDetails) == null ? void 0 : _i.reasoningTokens, (_j = usage2.outputTokenDetails) == null ? void 0 : _j.reasoningTokens) }, totalTokens: addTokenCounts(usage1.totalTokens, usage2.totalTokens) }; } function addTokenCounts(tokenCount1, tokenCount2) { return tokenCount1 == null && tokenCount2 == null ? void 0 : (tokenCount1 != null ? tokenCount1 : 0) + (tokenCount2 != null ? tokenCount2 : 0); } function getOwn(obj, key) { return obj != null && Object.hasOwn(obj, key) ? obj[key] : void 0; } function mergeAbortSignals(...signals) { const validSignals = filterNullable(...signals).map((signal) => typeof signal === "number" ? AbortSignal.timeout(signal) : signal); return validSignals.length === 0 ? void 0 : validSignals.length === 1 ? validSignals[0] : AbortSignal.any(validSignals); } function now() { var _a25, _b25; return (_b25 = (_a25 = globalThis == null ? void 0 : globalThis.performance) == null ? void 0 : _a25.now()) != null ? _b25 : Date.now(); } async function notify(options) { await Promise.all(asArray(options.callbacks).map(async (callback) => { try { await (callback == null ? void 0 : callback(options.event)); } catch (e) {} })); } function getRetryDelayInMs({ error, exponentialBackoffDelay }) { const headers = APICallError.isInstance(error) ? error.responseHeaders : APICallError.isInstance(error.cause) ? error.cause.responseHeaders : void 0; if (!headers) return exponentialBackoffDelay; let ms; const retryAfterMs = headers["retry-after-ms"]; if (retryAfterMs) { const timeoutMs = parseFloat(retryAfterMs); if (!Number.isNaN(timeoutMs)) ms = timeoutMs; } const retryAfter = headers["retry-after"]; if (retryAfter && ms === void 0) { const timeoutSeconds = parseFloat(retryAfter); if (!Number.isNaN(timeoutSeconds)) ms = timeoutSeconds * 1e3; else ms = Date.parse(retryAfter) - Date.now(); } if (ms != null && !Number.isNaN(ms) && 0 <= ms && (ms < 6e4 || ms < exponentialBackoffDelay)) return ms; return exponentialBackoffDelay; } var retryWithExponentialBackoffRespectingRetryHeaders = ({ maxRetries = 2, initialDelayInMs = 2e3, backoffFactor = 2, abortSignal, additionalRetryableError } = {}) => retryWithExponentialBackoff({ maxRetries, initialDelayInMs, backoffFactor, abortSignal, shouldRetry: async (error) => error instanceof Error && (APICallError.isInstance(error) && error.isRetryable === true || GatewayError.isInstance(error) && error.isRetryable === true) || additionalRetryableError != null && await additionalRetryableError(error), getDelayInMs: ({ error, exponentialBackoffDelay }) => getRetryDelayInMs({ error, exponentialBackoffDelay }), createRetryError: ({ message, reason, errors }) => new RetryError({ message, reason, errors }) }); function prepareRetries({ maxRetries, abortSignal, additionalRetryableError, parameter = "maxRetries", defaultMaxRetries = 2 }) { if (maxRetries != null) { if (!Number.isInteger(maxRetries)) throw new InvalidArgumentError({ parameter, value: maxRetries, message: `${parameter} must be an integer` }); if (maxRetries < 0) throw new InvalidArgumentError({ parameter, value: maxRetries, message: `${parameter} must be >= 0` }); } const maxRetriesResult = maxRetries != null ? maxRetries : defaultMaxRetries; return { maxRetries: maxRetriesResult, retry: retryWithExponentialBackoffRespectingRetryHeaders({ maxRetries: maxRetriesResult, abortSignal, additionalRetryableError }) }; } function setAbortTimeout({ abortController, label, timeoutMs }) { if (abortController == null || timeoutMs == null) return; return setTimeout(() => abortController.abort(new DOMException(`${label} timeout of ${timeoutMs}ms exceeded`, "TimeoutError")), timeoutMs); } function calculateTokensPerSecond({ tokens, durationMs }) { const tokenRate = 1e3 * (tokens != null ? tokens : 0) / (durationMs != null ? durationMs : 0); return Number.isFinite(tokenRate) ? tokenRate : 0; } function collectToolApprovals({ messages }) { const lastMessage = messages.at(-1); if ((lastMessage == null ? void 0 : lastMessage.role) != "tool") return { approvedToolApprovals: [], deniedToolApprovals: [] }; const toolCallsByToolCallId = /* @__PURE__ */ Object.create(null); for (const message of messages) if (message.role === "assistant" && typeof message.content !== "string") { const content = message.content; for (const part of content) if (part.type === "tool-call") toolCallsByToolCallId[part.toolCallId] = part; } const toolApprovalRequestsByApprovalId = /* @__PURE__ */ Object.create(null); for (const message of messages) if (message.role === "assistant" && typeof message.content !== "string") { const content = message.content; for (const part of content) if (part.type === "tool-approval-request") toolApprovalRequestsByApprovalId[part.approvalId] = part; } const toolResults = /* @__PURE__ */ Object.create(null); for (const part of lastMessage.content) if (part.type === "tool-result") toolResults[part.toolCallId] = part; const approvedToolApprovals = []; const deniedToolApprovals = []; const approvalResponses = lastMessage.content.filter((part) => part.type === "tool-approval-response"); for (const approvalResponse of approvalResponses) { const approvalRequest = toolApprovalRequestsByApprovalId[approvalResponse.approvalId]; if (approvalRequest == null) throw new InvalidToolApprovalError({ approvalId: approvalResponse.approvalId }); const existingToolResult = toolResults[approvalRequest.toolCallId]; if (existingToolResult != null && (approvalResponse.approved || existingToolResult.output.type !== "execution-denied")) continue; const toolCall = toolCallsByToolCallId[approvalRequest.toolCallId]; if (toolCall == null) throw new ToolCallNotFoundForApprovalError({ toolCallId: approvalRequest.toolCallId, approvalId: approvalRequest.approvalId }); const approval = { approvalRequest, approvalResponse, toolCall, ...existingToolResult != null ? { existingToolResult } : {} }; if (approvalResponse.approved) approvedToolApprovals.push(approval); else deniedToolApprovals.push(approval); } return { approvedToolApprovals, deniedToolApprovals }; } var DefaultGeneratedFile = class { constructor({ data, mediaType, providerMetadata }) { const isUint8Array = data instanceof Uint8Array; this.base64Data = isUint8Array ? void 0 : data; this.uint8ArrayData = isUint8Array ? data : void 0; this.mediaType = mediaType; this.providerMetadata = providerMetadata; } get base64() { if (this.base64Data == null) this.base64Data = convertUint8ArrayToBase64(this.uint8ArrayData); return this.base64Data; } get uint8Array() { if (this.uint8ArrayData == null) this.uint8ArrayData = convertBase64ToUint8Array(this.base64Data); return this.uint8ArrayData; } }; var DefaultGeneratedFileWithType = class extends DefaultGeneratedFile { constructor(options) { super(options); this.type = "file"; } }; var DIRECT_TOOL_CALL = "AI_SDK_DIRECT_TOOL_CALL"; function resolveToolCallerConfiguration({ tools, toolCallers }) { if (tools == null || toolCallers == null) return; const resolved = {}; for (const [toolName, callers] of Object.entries(toolCallers)) { if (!Object.prototype.hasOwnProperty.call(tools, toolName)) throw new InvalidArgumentError({ parameter: "experimental_toolCallers", value: toolCallers, message: `unknown tool "${toolName}".` }); if (!Array.isArray(callers)) throw new InvalidArgumentError({ parameter: "experimental_toolCallers", value: toolCallers, message: `callers for tool "${toolName}" must be an array.` }); resolved[toolName] = callers.map((caller) => { if (caller === DIRECT_TOOL_CALL) return caller; if (typeof caller !== "string" || !Object.prototype.hasOwnProperty.call(tools, caller) || getToolCaller(tools[caller]) == null) throw new InvalidArgumentError({ parameter: "experimental_toolCallers", value: toolCallers, message: `tool "${toolName}" contains an invalid caller.` }); return caller; }); } return resolved; } function prepareToolsForToolCallers({ tools, toolCallers }) { var _a25, _b25; if (tools == null || toolCallers == null) return { executionTools: tools, modelTools: tools, toolCallerMessages: [] }; const executionTools = { ...tools }; const modelTools = { ...tools }; const localToolsByCaller = /* @__PURE__ */ new Map(); const toolCallerMessages = []; for (const [toolName, callerNames] of Object.entries(toolCallers)) { const tool3 = executionTools[toolName]; if (tool3 == null) continue; let availableDirectly = false; let availableToProvider = false; let preparedTool = tool3; for (const callerName of callerNames) { if (callerName === DIRECT_TOOL_CALL) { availableDirectly = true; continue; } const caller = getToolCaller(executionTools[callerName]); if (caller == null) continue; if (caller.type === "provider") { availableToProvider = true; preparedTool = { ...preparedTool, providerOptions: caller.prepareProviderOptions(preparedTool.providerOptions) }; } else { const localTools = (_a25 = localToolsByCaller.get(callerName)) != null ? _a25 : {}; localTools[toolName] = preparedTool; localToolsByCaller.set(callerName, localTools); } } executionTools[toolName] = preparedTool; if (availableDirectly || availableToProvider) modelTools[toolName] = preparedTool; else delete modelTools[toolName]; } for (const [callerName, callerTool] of Object.entries(executionTools)) { const caller = getToolCaller(callerTool); if ((caller == null ? void 0 : caller.type) !== "local") continue; const callerTools = (_b25 = localToolsByCaller.get(callerName)) != null ? _b25 : {}; const boundCaller = caller.bind(callerTools); executionTools[callerName] = boundCaller; if (Object.prototype.hasOwnProperty.call(modelTools, callerName)) { if (caller.prepareModelMessage == null) modelTools[callerName] = boundCaller; else { const content = caller.prepareModelMessage(callerTools); if (content != null) toolCallerMessages.push({ role: "user", content }); } } } return { executionTools, modelTools, toolCallerMessages }; } function appendToolCallerMessages({ messages, toolCallerMessages }) { var _a25; if (toolCallerMessages.length === 0) return messages; const latestUserText = (_a25 = messages.findLast((message) => message.role === "user" && typeof message.content === "string")) == null ? void 0 : _a25.content; const existingUserText = new Set(latestUserText == null ? [] : [latestUserText]); const additions = toolCallerMessages.filter((message) => { if (typeof message.content !== "string" || existingUserText.has(message.content)) return false; existingUserText.add(message.content); return true; }); return additions.length === 0 ? messages : [...messages, ...additions]; } var toolSearchSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.toolSearch"); function isToolSearch(tool3) { return tool3[toolSearchSymbol] === true; } function createToolSearchState({ tools, toolCallers }) { const searchTools = Object.entries(tools != null ? tools : {}).filter(([, tool3]) => tool3.deferLoading || isToolSearch(tool3)); if (searchTools.length === 0) return (activeTools) => activeTools; const discovered = /* @__PURE__ */ new Set(); const getCallers = (name25) => { var _a25; return (_a25 = getOwn(toolCallers, name25)) != null ? _a25 : [DIRECT_TOOL_CALL]; }; for (const [name25, tool3] of searchTools) if (getCallers(name25).some((name26) => { if (name26 === DIRECT_TOOL_CALL) return false; const caller = getToolCaller(tools == null ? void 0 : tools[name26]); return (caller == null ? void 0 : caller.type) !== "local" || caller.prepareModelMessage == null; }) || isToolSearch(tool3) && tool3.deferLoading) throw new InvalidArgumentError({ parameter: "tools", value: name25, message: `tool "${name25}" must be callable directly or through code mode with toolDiscovery: 'conversation'. The search tool itself must not defer loading.` }); return (activeTools, { toolsContext = {}, experimental_sandbox } = {}) => { if (activeTools == null) return; const entries = Object.entries(activeTools); return Object.fromEntries(entries.filter(([name25, tool3]) => !tool3.deferLoading || discovered.has(name25)).map(([searchName, tool3]) => { if (!isToolSearch(tool3)) return [searchName, tool3]; const callers = getCallers(searchName).filter((name25) => name25 === DIRECT_TOOL_CALL || Object.hasOwn(activeTools, name25)); const candidates = entries.filter(([name25, candidate]) => candidate.deferLoading && !isToolSearch(candidate) && callers.some((caller) => getCallers(name25).includes(caller))); return [searchName, { ...tool3, execute: ({ query }) => { const terms = [...new Set(tokenize(query))]; const matches = candidates.map(([name25, candidate]) => { const description = resolveToolDescription({ tool: candidate, toolName: name25, toolsContext, experimental_sandbox }); const nameTerms = tokenize(name25); const descriptionTerms = tokenize(description != null ? description : ""); return { name: name25, description, score: terms.reduce((score2, term) => score2 + (nameTerms.includes(term) ? 2 : 0) + (descriptionTerms.includes(term) ? 1 : 0), 0) }; }).filter((match) => match.score > 0).sort((a, b) => b.score - a.score).slice(0, 5); for (const { name: name25 } of matches) discovered.add(name25); return { tools: matches.map(({ name: name25, description }) => ({ name: name25, ...description == null ? {} : { description } })) }; } }]; })); }; } function tokenize(text2) { var _a25; return (_a25 = text2.replace(/([a-z\d])([A-Z])/g, "$1 $2").toLowerCase().match(/[\p{L}\p{N}]+/gu)) != null ? _a25 : []; } async function validateToolContext({ toolName, context, contextSchema }) { if (contextSchema == null) return context; return await validateTypes({ value: context, schema: contextSchema, context: { field: "tool context", entityName: toolName } }); } async function executeToolCall({ toolCall, tools, toolsContext, callId, messages, abortSignal, timeout, experimental_sandbox: sandbox, onPreliminaryToolResult, onToolExecutionStart, onToolExecutionEnd, executeToolInTelemetryContext = async ({ execute }) => await execute(), runInTracingChannelSpan = async ({ execute }) => await execute() }) { const { toolName, toolCallId, input } = toolCall; const tool3 = getOwn(tools, toolName); if (!isExecutableTool(tool3)) return; const context = await validateToolContext({ toolName, context: getOwn(toolsContext, toolName), contextSchema: tool3.contextSchema }); const toolExecutionContext = { toolCall, messages, toolContext: context }; const baseCallbackEvent = { callId, ...toolExecutionContext }; return await runInTracingChannelSpan({ type: "executeTool", event: baseCallbackEvent, execute: async () => { let output; await notify({ event: baseCallbackEvent, callbacks: onToolExecutionStart }); const toolAbortSignal = mergeAbortSignals(abortSignal, getToolTimeoutMs(timeout, toolName)); let toolExecutionMs = 0; try { await executeToolInTelemetryContext({ callId, toolCallId, ...toolExecutionContext, execute: async () => { const startTime = now(); try { const stream = executeTool({ tool: tool3, input, options: { toolCallId, messages, abortSignal: toolAbortSignal, context, experimental_sandbox: sandbox } }); for await (const part of stream) if (part.type === "preliminary") onPreliminaryToolResult?.({ ...toolCall, type: "tool-result", output: part.output, preliminary: true }); else output = part.output; } finally { toolExecutionMs = now() - startTime; } } }); } catch (error) { const toolError = { type: "tool-error", toolCallId, toolName, input, error, dynamic: tool3.type === "dynamic", ...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {}, ...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {} }; await notify({ event: { ...baseCallbackEvent, toolOutput: toolError, toolExecutionMs }, callbacks: onToolExecutionEnd }); return { output: toolError, toolExecutionMs }; } const toolResult = { type: "tool-result", toolCallId, toolName, input, output, dynamic: tool3.type === "dynamic", ...toolCall.providerMetadata != null ? { providerMetadata: toolCall.providerMetadata } : {}, ...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {} }; await notify({ event: { ...baseCallbackEvent, toolOutput: toolResult, toolExecutionMs }, callbacks: onToolExecutionEnd }); return { output: toolResult, toolExecutionMs }; } }); } function filterActiveTools({ tools, activeTools }) { if (tools == null || activeTools == null) return tools; return Object.fromEntries(Object.entries(tools).filter(([name25]) => activeTools.includes(name25))); } function isToolExecutionAllowedFinishReason(finishReason) { return finishReason === "stop" || finishReason === "tool-calls"; } __export({}, { array: () => array2, choice: () => choice, json: () => json, object: () => object2, text: () => text }); function fixJson(input) { const stack = ["ROOT"]; let lastValidIndex = -1; let literalStart = null; let unicodeEscapeDigits = 0; function isHexDigit(char) { return char >= "0" && char <= "9" || char >= "A" && char <= "F" || char >= "a" && char <= "f"; } function processValueStart(char, i, swapState) { switch (char) { case "\"": lastValidIndex = i; stack.pop(); stack.push(swapState); stack.push("INSIDE_STRING"); break; case "f": case "t": case "n": lastValidIndex = i; literalStart = i; stack.pop(); stack.push(swapState); stack.push("INSIDE_LITERAL"); break; case "-": stack.pop(); stack.push(swapState); stack.push("INSIDE_NUMBER"); break; case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": lastValidIndex = i; stack.pop(); stack.push(swapState); stack.push("INSIDE_NUMBER"); break; case "{": lastValidIndex = i; stack.pop(); stack.push(swapState); stack.push("INSIDE_OBJECT_START"); break; case "[": lastValidIndex = i; stack.pop(); stack.push(swapState); stack.push("INSIDE_ARRAY_START"); } } function processAfterObjectValue(char, i) { switch (char) { case ",": stack.pop(); stack.push("INSIDE_OBJECT_AFTER_COMMA"); break; case "}": lastValidIndex = i; stack.pop(); } } function processAfterArrayValue(char, i) { switch (char) { case ",": stack.pop(); stack.push("INSIDE_ARRAY_AFTER_COMMA"); break; case "]": lastValidIndex = i; stack.pop(); } } for (let i = 0; i < input.length; i++) { const char = input[i]; switch (stack[stack.length - 1]) { case "ROOT": processValueStart(char, i, "FINISH"); break; case "INSIDE_OBJECT_START": switch (char) { case "\"": stack.pop(); stack.push("INSIDE_OBJECT_KEY"); break; case "}": lastValidIndex = i; stack.pop(); } break; case "INSIDE_OBJECT_AFTER_COMMA": switch (char) { case "\"": stack.pop(); stack.push("INSIDE_OBJECT_KEY"); } break; case "INSIDE_OBJECT_KEY": switch (char) { case "\"": stack.pop(); stack.push("INSIDE_OBJECT_AFTER_KEY"); } break; case "INSIDE_OBJECT_AFTER_KEY": switch (char) { case ":": stack.pop(); stack.push("INSIDE_OBJECT_BEFORE_VALUE"); } break; case "INSIDE_OBJECT_BEFORE_VALUE": processValueStart(char, i, "INSIDE_OBJECT_AFTER_VALUE"); break; case "INSIDE_OBJECT_AFTER_VALUE": processAfterObjectValue(char, i); break; case "INSIDE_STRING": switch (char) { case "\"": stack.pop(); lastValidIndex = i; break; case "\\": stack.push("INSIDE_STRING_ESCAPE"); break; default: lastValidIndex = i; } break; case "INSIDE_ARRAY_START": switch (char) { case "]": lastValidIndex = i; stack.pop(); break; default: lastValidIndex = i; processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE"); } break; case "INSIDE_ARRAY_AFTER_VALUE": switch (char) { case ",": stack.pop(); stack.push("INSIDE_ARRAY_AFTER_COMMA"); break; case "]": lastValidIndex = i; stack.pop(); break; default: lastValidIndex = i; } break; case "INSIDE_ARRAY_AFTER_COMMA": processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE"); break; case "INSIDE_STRING_ESCAPE": stack.pop(); if (char === "u") { unicodeEscapeDigits = 0; stack.push("INSIDE_STRING_UNICODE_ESCAPE"); } else lastValidIndex = i; break; case "INSIDE_STRING_UNICODE_ESCAPE": if (isHexDigit(char)) { unicodeEscapeDigits++; if (unicodeEscapeDigits === 4) { stack.pop(); lastValidIndex = i; } } break; case "INSIDE_NUMBER": switch (char) { case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": lastValidIndex = i; break; case "e": case "E": case "-": case ".": break; case ",": stack.pop(); if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i); if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i); break; case "}": stack.pop(); if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i); break; case "]": stack.pop(); if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i); break; default: stack.pop(); } break; case "INSIDE_LITERAL": { const partialLiteral = input.substring(literalStart, i + 1); if (!"false".startsWith(partialLiteral) && !"true".startsWith(partialLiteral) && !"null".startsWith(partialLiteral)) { stack.pop(); if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") processAfterObjectValue(char, i); else if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i); } else lastValidIndex = i; break; } } } let result = input.slice(0, lastValidIndex + 1); for (let i = stack.length - 1; i >= 0; i--) switch (stack[i]) { case "INSIDE_STRING": result += "\""; break; case "INSIDE_OBJECT_KEY": case "INSIDE_OBJECT_AFTER_KEY": case "INSIDE_OBJECT_AFTER_COMMA": case "INSIDE_OBJECT_START": case "INSIDE_OBJECT_BEFORE_VALUE": case "INSIDE_OBJECT_AFTER_VALUE": result += "}"; break; case "INSIDE_ARRAY_START": case "INSIDE_ARRAY_AFTER_COMMA": case "INSIDE_ARRAY_AFTER_VALUE": result += "]"; break; case "INSIDE_LITERAL": { const partialLiteral = input.substring(literalStart, input.length); if ("true".startsWith(partialLiteral)) result += "true".slice(partialLiteral.length); else if ("false".startsWith(partialLiteral)) result += "false".slice(partialLiteral.length); else if ("null".startsWith(partialLiteral)) result += "null".slice(partialLiteral.length); } } return result; } async function parsePartialJson(jsonText) { if (jsonText === void 0) return { value: void 0, state: "undefined-input" }; let result = await safeParseJSON({ text: jsonText }); if (result.success) return { value: result.value, state: "successful-parse" }; result = await safeParseJSON({ text: fixJson(jsonText) }); if (result.success) return { value: result.value, state: "repaired-parse" }; return { value: void 0, state: "failed-parse" }; } var text = () => ({ name: "text", responseFormat: Promise.resolve({ type: "text" }), async parseCompleteOutput({ text: text2 }) { return text2; }, async parsePartialOutput({ text: text2 }) { return { partial: text2 }; }, createElementStreamTransform() {} }); var object2 = ({ schema: inputSchema, name: name25, description }) => { const schema = asSchema(inputSchema); return { name: "object", responseFormat: resolve(schema.jsonSchema).then((jsonSchema3) => ({ type: "json", schema: jsonSchema3, ...name25 != null && { name: name25 }, ...description != null && { description } })), async parseCompleteOutput({ text: text2 }, context) { const parseResult = await safeParseJSON({ text: text2 }); if (!parseResult.success) throw new NoObjectGeneratedError({ message: "No object generated: could not parse the response.", cause: parseResult.error, text: text2, response: context.response, usage: context.usage, finishReason: context.finishReason }); const validationResult = await safeValidateTypes({ value: parseResult.value, schema }); if (!validationResult.success) throw new NoObjectGeneratedError({ message: "No object generated: response did not match schema.", cause: validationResult.error, text: text2, response: context.response, usage: context.usage, finishReason: context.finishReason }); return validationResult.value; }, async parsePartialOutput({ text: text2 }) { const result = await parsePartialJson(text2); switch (result.state) { case "failed-parse": case "undefined-input": return; case "repaired-parse": case "successful-parse": return { partial: result.value }; } }, createElementStreamTransform() {} }; }; var array2 = ({ element: inputElementSchema, minItems, maxItems, name: name25, description }) => { validateArrayBound({ name: "minItems", value: minItems }); validateArrayBound({ name: "maxItems", value: maxItems }); if (minItems != null && maxItems != null && minItems > maxItems) throw new InvalidArgumentError({ parameter: "minItems", value: minItems, message: "minItems must be less than or equal to maxItems" }); const elementSchema = asSchema(inputElementSchema); return { name: "array", responseFormat: resolve(elementSchema.jsonSchema).then((jsonSchema3) => { const { $schema: _$schema, definitions, $defs, ...itemSchema } = jsonSchema3; return { type: "json", schema: { $schema: "http://json-schema.org/draft-07/schema#", ...definitions != null && { definitions }, ...$defs != null && { $defs }, type: "object", properties: { elements: { type: "array", items: itemSchema, ...minItems != null && { minItems }, ...maxItems != null && { maxItems } } }, required: ["elements"], additionalProperties: false }, ...name25 != null && { name: name25 }, ...description != null && { description } }; }), async parseCompleteOutput({ text: text2 }, context) { const parseResult = await safeParseJSON({ text: text2 }); if (!parseResult.success) throw new NoObjectGeneratedError({ message: "No object generated: could not parse the response.", cause: parseResult.error, text: text2, response: context.response, usage: context.usage, finishReason: context.finishReason }); const outerValue = parseResult.value; if (outerValue == null || typeof outerValue !== "object" || !("elements" in outerValue) || !Array.isArray(outerValue.elements)) throw new NoObjectGeneratedError({ message: "No object generated: response did not match schema.", cause: new TypeValidationError({ value: outerValue, cause: "response must be an object with an elements array" }), text: text2, response: context.response, usage: context.usage, finishReason: context.finishReason }); const lengthValidationError = getArrayLengthValidationError({ value: outerValue.elements, minItems, maxItems }); if (lengthValidationError != null) throw new NoObjectGeneratedError({ message: "No object generated: response did not match schema.", cause: lengthValidationError, text: text2, response: context.response, usage: context.usage, finishReason: context.finishReason }); const validatedElements = []; for (const element of outerValue.elements) { const validationResult = await safeValidateTypes({ value: element, schema: elementSchema }); if (!validationResult.success) throw new NoObjectGeneratedError({ message: "No object generated: response did not match schema.", cause: validationResult.error, text: text2, response: context.response, usage: context.usage, finishReason: context.finishReason }); validatedElements.push(validationResult.value); } return validatedElements; }, async parsePartialOutput({ text: text2 }) { const result = await parsePartialJson(text2); switch (result.state) { case "failed-parse": case "undefined-input": return; case "repaired-parse": case "successful-parse": { const outerValue = result.value; if (outerValue == null || typeof outerValue !== "object" || !("elements" in outerValue) || !Array.isArray(outerValue.elements)) return; const rawElements = result.state === "repaired-parse" && outerValue.elements.length > 0 ? outerValue.elements.slice(0, -1) : outerValue.elements; const parsedElements = []; for (const rawElement of rawElements) { const validationResult = await safeValidateTypes({ value: rawElement, schema: elementSchema }); if (validationResult.success) parsedElements.push(validationResult.value); } return { partial: parsedElements }; } } }, createElementStreamTransform() { let publishedElements = 0; return new TransformStream({ transform({ partialOutput }, controller) { if (partialOutput != null) for (; publishedElements < partialOutput.length; publishedElements++) { if (maxItems != null && publishedElements >= maxItems) { controller.error(getArrayLengthValidationError({ value: partialOutput, maxItems })); return; } controller.enqueue(partialOutput[publishedElements]); } } }); } }; }; function validateArrayBound({ name: name25, value }) { if (value == null) return; if (!Number.isInteger(value)) throw new InvalidArgumentError({ parameter: name25, value, message: `${name25} must be an integer` }); if (value < 0) throw new InvalidArgumentError({ parameter: name25, value, message: `${name25} must be greater than or equal to 0` }); } function getArrayLengthValidationError({ value, minItems, maxItems }) { if (minItems != null && value.length < minItems) return new TypeValidationError({ value, cause: `elements array must contain at least ${minItems} items` }); if (maxItems != null && value.length > maxItems) return new TypeValidationError({ value, cause: `elements array must contain at most ${maxItems} items` }); } var choice = ({ options: choiceOptions, name: name25, description }) => { return { name: "choice", responseFormat: Promise.resolve({ type: "json", schema: { $schema: "http://json-schema.org/draft-07/schema#", type: "object", properties: { result: { type: "string", enum: choiceOptions } }, required: ["result"], additionalProperties: false }, ...name25 != null && { name: name25 }, ...description != null && { description } }), async parseCompleteOutput({ text: text2 }, context) { const parseResult = await safeParseJSON({ text: text2 }); if (!parseResult.success) throw new NoObjectGeneratedError({ message: "No object generated: could not parse the response.", cause: parseResult.error, text: text2, response: context.response, usage: context.usage, finishReason: context.finishReason }); const outerValue = parseResult.value; if (outerValue == null || typeof outerValue !== "object" || !("result" in outerValue) || typeof outerValue.result !== "string" || !choiceOptions.includes(outerValue.result)) throw new NoObjectGeneratedError({ message: "No object generated: response did not match schema.", cause: new TypeValidationError({ value: outerValue, cause: "response must be an object that contains a choice value." }), text: text2, response: context.response, usage: context.usage, finishReason: context.finishReason }); return outerValue.result; }, async parsePartialOutput({ text: text2 }) { const result = await parsePartialJson(text2); switch (result.state) { case "failed-parse": case "undefined-input": return; case "repaired-parse": case "successful-parse": { const outerValue = result.value; if (outerValue == null || typeof outerValue !== "object" || !("result" in outerValue) || typeof outerValue.result !== "string") return; const potentialMatches = choiceOptions.filter((choiceOption) => choiceOption.startsWith(outerValue.result)); if (result.state === "successful-parse") return potentialMatches.includes(outerValue.result) ? { partial: outerValue.result } : void 0; else return potentialMatches.length === 1 ? { partial: potentialMatches[0] } : void 0; } } }, createElementStreamTransform() {} }; }; var json = ({ name: name25, description } = {}) => { return { name: "json", responseFormat: Promise.resolve({ type: "json", ...name25 != null && { name: name25 }, ...description != null && { description } }), async parseCompleteOutput({ text: text2 }, context) { const parseResult = await safeParseJSON({ text: text2 }); if (!parseResult.success) throw new NoObjectGeneratedError({ message: "No object generated: could not parse the response.", cause: parseResult.error, text: text2, response: context.response, usage: context.usage, finishReason: context.finishReason }); return parseResult.value; }, async parsePartialOutput({ text: text2 }) { const result = await parsePartialJson(text2); switch (result.state) { case "failed-parse": case "undefined-input": return; case "repaired-parse": case "successful-parse": return result.value === void 0 ? void 0 : { partial: result.value }; } }, createElementStreamTransform() {} }; }; async function parseToolCall({ toolCall, tools, repairToolCall, refineToolInput, messages, instructions }) { try { if (tools == null) { if (toolCall.providerExecuted && toolCall.dynamic) return await refineParsedToolCallInput({ toolCall: await parseProviderExecutedDynamicToolCall(toolCall), refineToolInput }); throw new NoSuchToolError({ toolName: toolCall.toolName }); } try { return await refineParsedToolCallInput({ toolCall: await doParseToolCall({ toolCall, tools }), refineToolInput }); } catch (error) { if (repairToolCall == null || !(NoSuchToolError.isInstance(error) || InvalidToolInputError.isInstance(error))) throw error; let repairedToolCall = null; try { repairedToolCall = await repairToolCall({ toolCall, tools, inputSchema: async ({ toolName }) => { var _a25; return await asSchema((_a25 = getOwn(tools, toolName)) == null ? void 0 : _a25.inputSchema).jsonSchema; }, instructions, system: instructions, messages, error }); } catch (repairError) { throw new ToolCallRepairError({ cause: repairError, originalError: error }); } if (repairedToolCall == null) throw error; return await refineParsedToolCallInput({ toolCall: await doParseToolCall({ toolCall: repairedToolCall, tools }), refineToolInput }); } } catch (error) { const parsedInput = await safeParseJSON({ text: toolCall.input }); const input = parsedInput.success ? parsedInput.value : toolCall.input; const tool3 = getOwn(tools, toolCall.toolName); return { type: "tool-call", toolCallId: toolCall.toolCallId, toolName: toolCall.toolName, input, dynamic: true, invalid: true, error, title: tool3 == null ? void 0 : tool3.title, providerExecuted: toolCall.providerExecuted, providerMetadata: toolCall.providerMetadata, ...(tool3 == null ? void 0 : tool3.metadata) != null ? { toolMetadata: tool3.metadata } : {} }; } } async function refineParsedToolCallInput({ toolCall, refineToolInput }) { const refine = getOwn(refineToolInput, toolCall.toolName); if (refine == null) return toolCall; return { ...toolCall, input: await refine(toolCall.input) }; } async function parseProviderExecutedDynamicToolCall(toolCall) { const parseResult = toolCall.input.trim() === "" ? { success: true, value: {} } : await safeParseJSON({ text: toolCall.input }); if (parseResult.success === false) throw new InvalidToolInputError({ toolName: toolCall.toolName, toolInput: toolCall.input, cause: parseResult.error }); return { type: "tool-call", toolCallId: toolCall.toolCallId, toolName: toolCall.toolName, input: parseResult.value, providerExecuted: true, dynamic: true, providerMetadata: toolCall.providerMetadata }; } async function doParseToolCall({ toolCall, tools }) { const toolName = toolCall.toolName; const tool3 = getOwn(tools, toolName); if (tool3 == null) { if (toolCall.providerExecuted && toolCall.dynamic) return await parseProviderExecutedDynamicToolCall(toolCall); throw new NoSuchToolError({ toolName: toolCall.toolName, availableTools: Object.keys(tools) }); } const schema = asSchema(tool3.inputSchema); const parseResult = toolCall.input.trim() === "" ? await safeValidateTypes({ value: {}, schema }) : await safeParseJSON({ text: toolCall.input, schema }); if (parseResult.success === false) throw new InvalidToolInputError({ toolName, toolInput: toolCall.input, cause: parseResult.error }); return tool3.type === "dynamic" ? { type: "tool-call", toolCallId: toolCall.toolCallId, toolName: toolCall.toolName, input: parseResult.value, providerExecuted: toolCall.providerExecuted, providerMetadata: toolCall.providerMetadata, ...tool3.metadata != null ? { toolMetadata: tool3.metadata } : {}, dynamic: true, title: tool3.title } : { type: "tool-call", toolCallId: toolCall.toolCallId, toolName, input: parseResult.value, providerExecuted: toolCall.providerExecuted, providerMetadata: toolCall.providerMetadata, ...tool3.metadata != null ? { toolMetadata: tool3.metadata } : {}, title: tool3.title }; } function prepareStepCallSettings({ callSettings, stepSettings }) { var _a25, _b25, _c, _d, _e, _f, _g, _h, _i; return prepareLanguageModelCallOptions({ maxOutputTokens: (_a25 = stepSettings == null ? void 0 : stepSettings.maxOutputTokens) != null ? _a25 : callSettings.maxOutputTokens, temperature: (_b25 = stepSettings == null ? void 0 : stepSettings.temperature) != null ? _b25 : callSettings.temperature, topP: (_c = stepSettings == null ? void 0 : stepSettings.topP) != null ? _c : callSettings.topP, topK: (_d = stepSettings == null ? void 0 : stepSettings.topK) != null ? _d : callSettings.topK, presencePenalty: (_e = stepSettings == null ? void 0 : stepSettings.presencePenalty) != null ? _e : callSettings.presencePenalty, frequencyPenalty: (_f = stepSettings == null ? void 0 : stepSettings.frequencyPenalty) != null ? _f : callSettings.frequencyPenalty, stopSequences: (_g = stepSettings == null ? void 0 : stepSettings.stopSequences) != null ? _g : callSettings.stopSequences, seed: (_h = stepSettings == null ? void 0 : stepSettings.seed) != null ? _h : callSettings.seed, reasoning: (_i = stepSettings == null ? void 0 : stepSettings.reasoning) != null ? _i : callSettings.reasoning }); } function unwrapReasoningFileData(data) { if (typeof data === "object" && data !== null && "type" in data) return data.type === "data" ? data.data : data.url; return data; } function convertFromReasoningOutputs(parts) { return parts.map((part) => { if (part.type === "reasoning") return { type: "reasoning", text: part.text, ...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {} }; return { type: "reasoning-file", data: part.file.base64, mediaType: part.file.mediaType, ...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {} }; }); } function convertToReasoningOutputs(parts) { return parts.map((part) => { if (part.type === "reasoning") return { type: "reasoning", text: part.text, ...part.providerOptions != null ? { providerMetadata: part.providerOptions } : {} }; const rawData = unwrapReasoningFileData(part.data); return { type: "reasoning-file", file: new DefaultGeneratedFile({ data: rawData instanceof ArrayBuffer ? new Uint8Array(rawData) : rawData instanceof URL ? rawData.toString() : rawData, mediaType: part.mediaType }), ...part.providerOptions != null ? { providerMetadata: part.providerOptions } : {} }; }); } async function resolveToolApproval({ tools, toolCall, toolApproval, messages, toolsContext, runtimeContext }) { if (toolApproval != null && typeof toolApproval === "function") return normalizeToolApprovalStatus(await toolApproval({ toolCall, tools, toolsContext, messages, runtimeContext })); const toolName = toolCall.toolName; const tool3 = getOwn(tools, toolName); const input = toolCall.input; const userDefinedToolApprovalStatus = getOwn(toolApproval, toolName); if (userDefinedToolApprovalStatus != null) return normalizeToolApprovalStatus(typeof userDefinedToolApprovalStatus === "function" ? await userDefinedToolApprovalStatus(input, { toolCallId: toolCall.toolCallId, messages, toolContext: await validateToolContext({ toolName, context: getOwn(toolsContext, toolName), contextSchema: tool3 == null ? void 0 : tool3.contextSchema }), runtimeContext }) : userDefinedToolApprovalStatus); if ((tool3 == null ? void 0 : tool3.needsApproval) == null) return { type: "not-applicable" }; return (typeof tool3.needsApproval === "function" ? await tool3.needsApproval(input, { toolCallId: toolCall.toolCallId, messages, context: await validateToolContext({ toolName, context: getOwn(toolsContext, toolName), contextSchema: tool3 == null ? void 0 : tool3.contextSchema }) }) : tool3.needsApproval) ? { type: "user-approval" } : { type: "not-applicable" }; } function normalizeToolApprovalStatus(status) { return status === void 0 ? { type: "not-applicable" } : typeof status === "string" ? { type: status } : status; } function filterIncludedContext({ context, includeContext }) { if (context == null) return {}; return Object.fromEntries(Object.entries(context).filter(([key]) => (includeContext == null ? void 0 : includeContext[key]) === true)); } function mergeCallbacks(...callbacks) { return async (event) => { await Promise.allSettled(callbacks.map(async (callback) => { await (callback == null ? void 0 : callback(event)); })); }; } var AI_SDK_TELEMETRY_TRACING_CHANNEL = "ai:telemetry"; function isNodeRuntime() { var _a25; return typeof process !== "undefined" && ((_a25 = process.release) == null ? void 0 : _a25.name) === "node"; } var diagnosticsChannelPromise; async function loadDiagnosticsChannel() { if (!isNodeRuntime()) return; if (diagnosticsChannelPromise == null) diagnosticsChannelPromise = Promise.resolve(loadBuiltinModule("node:diagnostics_channel")); return diagnosticsChannelPromise; } function loadBuiltinModule(id) { var _a25; const processWithBuiltins = globalThis.process; try { return (_a25 = processWithBuiltins == null ? void 0 : processWithBuiltins.getBuiltinModule) == null ? void 0 : _a25.call(processWithBuiltins, id); } catch (e) { return; } } async function runWithTracingChannelSpan(message, execute) { var _a25; const diagnosticsChannel = await loadDiagnosticsChannel(); const tracingChannel = (_a25 = diagnosticsChannel == null ? void 0 : diagnosticsChannel.tracingChannel) == null ? void 0 : _a25.call(diagnosticsChannel, AI_SDK_TELEMETRY_TRACING_CHANNEL); if (tracingChannel == null || tracingChannel.hasSubscribers === false) return await execute(); let executePromise; let executionResult; let executionError; let hasExecutionResult = false; let hasExecutionError = false; const tracedExecute = () => { try { executePromise = Promise.resolve(execute()); } catch (error) { executePromise = Promise.reject(error); } executePromise = executePromise.then((result) => { executionResult = result; hasExecutionResult = true; return result; }, (error) => { executionError = error; hasExecutionError = true; throw error; }); return executePromise; }; try { return await tracingChannel.tracePromise(tracedExecute, message); } catch (e) { if (hasExecutionError) throw executionError; if (hasExecutionResult) return executionResult; if (executePromise != null) return await executePromise; return await execute(); } } function openTelemetryChannelSpanContext({ message, completion }) { var _a25; if (!isNodeRuntime()) return; const diagnosticsChannel = loadBuiltinModule("node:diagnostics_channel"); const asyncHooks = loadBuiltinModule("node:async_hooks"); const tracingChannel = (_a25 = diagnosticsChannel == null ? void 0 : diagnosticsChannel.tracingChannel) == null ? void 0 : _a25.call(diagnosticsChannel, AI_SDK_TELEMETRY_TRACING_CHANNEL); if (tracingChannel == null || tracingChannel.hasSubscribers === false || asyncHooks == null) { Promise.resolve(completion).catch(() => {}); return; } const context = message; let asyncResource; let asyncEndPublished = false; const safePublish = (publish) => { try { publish(); } catch (e) {} }; const publishAsyncEnd = ({ result, error }) => { if (asyncEndPublished) return; asyncEndPublished = true; if (error !== void 0) { context.error = error; safePublish(() => tracingChannel.error.publish(context)); } if (result !== void 0) context.result = result; safePublish(() => tracingChannel.asyncEnd.publish(context)); }; safePublish(() => { tracingChannel.start.runStores(context, () => { asyncResource = new asyncHooks.AsyncResource("ai.telemetry"); }); }); safePublish(() => tracingChannel.end.publish(context)); Promise.resolve(completion).then((result) => publishAsyncEnd({ result }), (error) => publishAsyncEnd({ error })); return { run: (execute) => asyncResource == null ? execute() : asyncResource.runInAsyncScope(execute) }; } function getGlobalTelemetryIntegrations() { var _a25; return (_a25 = globalThis.AI_SDK_TELEMETRY_INTEGRATIONS) != null ? _a25 : []; } function augmentEvent(event, telemetry) { return Object.assign(Object.create(Object.getPrototypeOf(event)), event, telemetry); } function createTelemetryDispatcher({ telemetry }) { if ((telemetry == null ? void 0 : telemetry.isEnabled) === false) return {}; const localIntegrations = telemetry == null ? void 0 : telemetry.integrations; const integrations = localIntegrations != null ? asArray(localIntegrations) : getGlobalTelemetryIntegrations(); const telemetryMetadata = { recordInputs: telemetry == null ? void 0 : telemetry.recordInputs, recordOutputs: telemetry == null ? void 0 : telemetry.recordOutputs, functionId: telemetry == null ? void 0 : telemetry.functionId }; const mergeTelemetryCallback = (key) => { const mergedIntegrationCallback = mergeCallbacks(...integrations.map((integration) => { var _a25; return (_a25 = integration[key]) == null ? void 0 : _a25.bind(integration); }).filter(Boolean).map((callback) => ((event) => callback(augmentEvent(event, telemetryMetadata))))); return async (event) => { await mergedIntegrationCallback(event); }; }; const executeLanguageModelCallWrappers = integrations.map((integration) => { var _a25; return (_a25 = integration.executeLanguageModelCall) == null ? void 0 : _a25.bind(integration); }).filter(Boolean); const executeToolWrappers = integrations.map((integration) => { var _a25; return (_a25 = integration.executeTool) == null ? void 0 : _a25.bind(integration); }).filter(Boolean); return { runInTracingChannelSpan: async ({ type, event, execute }) => await runWithTracingChannelSpan({ type, event: augmentEvent(event, telemetryMetadata) }, execute), startTracingChannelContext: ({ type, event, completion }) => openTelemetryChannelSpanContext({ message: { type, event: augmentEvent(event, telemetryMetadata) }, completion }), onStart: mergeTelemetryCallback("onStart"), onStepStart: mergeTelemetryCallback("onStepStart"), onLanguageModelCallStart: mergeTelemetryCallback("onLanguageModelCallStart"), onLanguageModelCallEnd: mergeTelemetryCallback("onLanguageModelCallEnd"), onToolExecutionStart: mergeTelemetryCallback("onToolExecutionStart"), onToolExecutionEnd: mergeTelemetryCallback("onToolExecutionEnd"), onStepEnd: mergeCallbacks(mergeTelemetryCallback("onStepEnd"), mergeTelemetryCallback("onStepFinish")), onObjectStepStart: mergeTelemetryCallback("onObjectStepStart"), onObjectStepEnd: mergeTelemetryCallback("onObjectStepEnd"), onEmbedStart: mergeTelemetryCallback("onEmbedStart"), onEmbedEnd: mergeTelemetryCallback("onEmbedEnd"), onRerankStart: mergeTelemetryCallback("onRerankStart"), onRerankEnd: mergeTelemetryCallback("onRerankEnd"), onEnd: mergeTelemetryCallback("onEnd"), onAbort: mergeTelemetryCallback("onAbort"), onError: mergeTelemetryCallback("onError"), /** * Runs provider calls inside integration-specific context so * auto-instrumented provider requests can be associated with model work. */ executeLanguageModelCall: async ({ execute, ...event }) => { const augmentedEvent = augmentEvent(event, telemetryMetadata); let wrappedExecute = execute; for (const executeWrapper of executeLanguageModelCallWrappers) { const innerExecute = wrappedExecute; wrappedExecute = () => executeWrapper({ ...augmentedEvent, execute: innerExecute }); } return await runWithTracingChannelSpan({ type: "languageModelCall", event: augmentedEvent }, wrappedExecute); }, /** * Composes all `executeTool` wrappers around the original tool execution. * Each wrapper receives an `execute` function that calls the next wrapper in * the chain, so integrations can establish nested telemetry context before * delegating to the underlying tool. */ executeTool: async ({ execute, ...event }) => { const augmentedEvent = augmentEvent(event, telemetryMetadata); let wrappedExecute = execute; for (const executeWrapper of executeToolWrappers) { const innerExecute = wrappedExecute; wrappedExecute = () => executeWrapper({ ...augmentedEvent, execute: innerExecute }); } return await wrappedExecute(); } }; } function asReasoningText(reasoningParts) { const reasoningText = reasoningParts.map((part) => "text" in part ? part.text : "").join(""); return reasoningText.length > 0 ? reasoningText : void 0; } var DefaultStepResult = class { constructor({ callId, stepNumber, provider, modelId, runtimeContext, toolsContext, content, finishReason, rawFinishReason, usage, performance, warnings, request, response, providerMetadata }) { this.callId = callId; this.stepNumber = stepNumber; this.model = { provider, modelId }; this.runtimeContext = runtimeContext; this.toolsContext = toolsContext; this.content = content; this.finishReason = finishReason; this.rawFinishReason = rawFinishReason; this.usage = usage; this.performance = performance; this.warnings = warnings; this.request = request; this.response = response; this.providerMetadata = providerMetadata; } get text() { return this.content.filter((part) => part.type === "text").map((part) => part.text).join(""); } get reasoning() { return convertFromReasoningOutputs(this.content.filter((part) => part.type === "reasoning" || part.type === "reasoning-file")); } get reasoningText() { return asReasoningText(this.reasoning); } get files() { return this.content.filter((part) => part.type === "file").map((part) => part.file); } get sources() { return this.content.filter((part) => part.type === "source"); } get toolCalls() { return this.content.filter((part) => part.type === "tool-call"); } get staticToolCalls() { return this.toolCalls.filter((toolCall) => toolCall.dynamic !== true); } get dynamicToolCalls() { return this.toolCalls.filter((toolCall) => toolCall.dynamic === true); } get toolResults() { return this.content.filter((part) => part.type === "tool-result"); } get staticToolResults() { return this.toolResults.filter((toolResult) => toolResult.dynamic !== true); } get dynamicToolResults() { return this.toolResults.filter((toolResult) => toolResult.dynamic === true); } }; function restrictStepResult({ step, includeRuntimeContext, includeToolsContext }) { return new DefaultStepResult({ callId: step.callId, stepNumber: step.stepNumber, provider: step.model.provider, modelId: step.model.modelId, runtimeContext: filterIncludedContext({ context: step.runtimeContext, includeContext: includeRuntimeContext }), toolsContext: filterToolsContext({ toolsContext: step.toolsContext, includeToolsContext }), content: step.content, finishReason: step.finishReason, rawFinishReason: step.rawFinishReason, usage: step.usage, performance: step.performance, warnings: step.warnings, request: step.request, response: step.response, providerMetadata: step.providerMetadata }); } function filterToolsContext({ toolsContext, includeToolsContext }) { if (includeToolsContext == null) return {}; return Object.fromEntries(Object.entries(toolsContext).map(([toolName, toolContext]) => [toolName, filterToolContext({ toolName, toolContext, includeToolsContext })])); } function filterToolContext({ toolName, toolContext, includeToolsContext }) { return filterIncludedContext({ context: toolContext, includeContext: includeToolsContext == null ? void 0 : includeToolsContext[toolName] }); } function createRestrictedTelemetryDispatcher({ telemetry, includeRuntimeContext, includeToolsContext }) { const telemetryDispatcher = createTelemetryDispatcher({ telemetry }); return { ...telemetryDispatcher, onStart: (event) => { var _a25; return (_a25 = telemetryDispatcher.onStart) == null ? void 0 : _a25.call(telemetryDispatcher, { ...event, runtimeContext: filterIncludedContext({ context: event.runtimeContext, includeContext: includeRuntimeContext }), toolsContext: filterToolsContext({ toolsContext: event.toolsContext, includeToolsContext }) }); }, onStepStart: (event) => { var _a25; return (_a25 = telemetryDispatcher.onStepStart) == null ? void 0 : _a25.call(telemetryDispatcher, { ...event, runtimeContext: filterIncludedContext({ context: event.runtimeContext, includeContext: includeRuntimeContext }), steps: event.steps.map((step) => restrictStepResult({ step, includeRuntimeContext, includeToolsContext })), toolsContext: filterToolsContext({ toolsContext: event.toolsContext, includeToolsContext }) }); }, onStepEnd: (event) => { var _a25; return (_a25 = telemetryDispatcher.onStepEnd) == null ? void 0 : _a25.call(telemetryDispatcher, restrictStepResult({ step: event, includeRuntimeContext, includeToolsContext })); }, onStepFinish: (event) => { var _a25; return (_a25 = telemetryDispatcher.onStepEnd) == null ? void 0 : _a25.call(telemetryDispatcher, restrictStepResult({ step: event, includeRuntimeContext, includeToolsContext })); }, onEnd: (event) => { var _a25; return (_a25 = telemetryDispatcher.onEnd) == null ? void 0 : _a25.call(telemetryDispatcher, ((restrictedSteps) => { return { ...event, runtimeContext: filterIncludedContext({ context: event.runtimeContext, includeContext: includeRuntimeContext }), steps: restrictedSteps, finalStep: restrictedSteps.at(-1), toolsContext: filterToolsContext({ toolsContext: event.toolsContext, includeToolsContext }) }; })(event.steps.map((step) => restrictStepResult({ step, includeRuntimeContext, includeToolsContext })))); }, onAbort: (event) => { var _a25; return (_a25 = telemetryDispatcher.onAbort) == null ? void 0 : _a25.call(telemetryDispatcher, { ...event, steps: event.steps.map((step) => restrictStepResult({ step, includeRuntimeContext, includeToolsContext })) }); }, onToolExecutionStart: (event) => { var _a25; return (_a25 = telemetryDispatcher.onToolExecutionStart) == null ? void 0 : _a25.call(telemetryDispatcher, { ...event, toolContext: filterToolContext({ toolName: event.toolCall.toolName, toolContext: event.toolContext, includeToolsContext }) }); }, onToolExecutionEnd: (event) => { var _a25; return (_a25 = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _a25.call(telemetryDispatcher, { ...event, toolContext: filterToolContext({ toolName: event.toolCall.toolName, toolContext: event.toolContext, includeToolsContext }) }); } }; } function isStepCount(stepCount) { return ({ steps }) => steps.length === stepCount; } async function isStopConditionMet({ stopConditions, steps }) { return (await Promise.all(stopConditions.map((condition) => condition({ steps })))).some((result) => result); } function sumTokenCounts(tokenCount1, tokenCount2) { return tokenCount1 == null && tokenCount2 == null ? void 0 : (tokenCount1 != null ? tokenCount1 : 0) + (tokenCount2 != null ? tokenCount2 : 0); } async function toResponseMessages({ content: inputContent, tools }) { const responseMessages = []; const toolCallOrder = /* @__PURE__ */ new Map(); const content = []; for (const part of inputContent) { if (part.type === "source") continue; if ((part.type === "tool-result" || part.type === "tool-error") && !part.providerExecuted) continue; if (part.type === "text" && part.text.length === 0) continue; switch (part.type) { case "text": content.push({ type: "text", text: part.text, providerOptions: part.providerMetadata }); break; case "custom": content.push({ type: "custom", kind: part.kind, providerOptions: part.providerMetadata }); break; case "reasoning": content.push({ type: "reasoning", text: part.text, providerOptions: part.providerMetadata }); break; case "file": content.push({ type: "file", data: part.file.base64, mediaType: part.file.mediaType, providerOptions: part.providerMetadata }); break; case "reasoning-file": content.push({ type: "reasoning-file", data: part.file.base64, mediaType: part.file.mediaType, providerOptions: part.providerMetadata }); break; case "tool-call": if (!toolCallOrder.has(part.toolCallId)) toolCallOrder.set(part.toolCallId, toolCallOrder.size); content.push({ type: "tool-call", toolCallId: part.toolCallId, toolName: part.toolName, input: part.invalid && typeof part.input !== "object" ? {} : part.input, providerExecuted: part.providerExecuted, providerOptions: part.providerMetadata }); break; case "tool-result": { const output = await createToolModelOutput({ toolCallId: part.toolCallId, input: part.input, tool: getOwn(tools, part.toolName), output: part.output, errorMode: "none" }); content.push({ type: "tool-result", toolCallId: part.toolCallId, toolName: part.toolName, output, providerOptions: part.providerMetadata }); break; } case "tool-error": { const output = await createToolModelOutput({ toolCallId: part.toolCallId, input: part.input, tool: getOwn(tools, part.toolName), output: part.error, errorMode: "json" }); content.push({ type: "tool-result", toolCallId: part.toolCallId, toolName: part.toolName, output, providerOptions: part.providerMetadata }); break; } case "tool-approval-request": content.push({ type: "tool-approval-request", approvalId: part.approvalId, toolCallId: part.toolCall.toolCallId, ...part.reason != null ? { reason: part.reason } : {}, isAutomatic: part.isAutomatic, ...part.signature != null ? { signature: part.signature } : {} }); } } if (content.length > 0) responseMessages.push({ role: "assistant", content }); const toolResultContent = []; for (const part of inputContent) { if (part.type !== "tool-approval-response" && part.type !== "tool-result" && part.type !== "tool-error") continue; if (part.type === "tool-approval-response") { toolResultContent.push({ type: "tool-approval-response", approvalId: part.approvalId, approved: part.approved, reason: part.reason, providerExecuted: part.providerExecuted }); if (part.approved === false) toolResultContent.push({ type: "tool-result", toolCallId: part.toolCall.toolCallId, toolName: part.toolCall.toolName, output: { type: "execution-denied", reason: part.reason } }); continue; } if (part.providerExecuted) continue; const output = await createToolModelOutput({ toolCallId: part.toolCallId, input: part.input, tool: getOwn(tools, part.toolName), output: part.type === "tool-result" ? part.output : part.error, errorMode: part.type === "tool-error" ? "text" : "none" }); toolResultContent.push({ type: "tool-result", toolCallId: part.toolCallId, toolName: part.toolName, output, ...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {} }); } if (toolResultContent.length > 0) responseMessages.push({ role: "tool", content: sortToolResultContentByToolCallOrder({ toolResultContent, toolCallOrder }) }); return responseMessages; } function sortToolResultContentByToolCallOrder({ toolResultContent, toolCallOrder }) { const sortedToolResults = toolResultContent.filter((part) => part.type === "tool-result").map((part, index) => ({ part, index })).sort((a, b) => { const aOrder = toolCallOrder.get(a.part.toolCallId); const bOrder = toolCallOrder.get(b.part.toolCallId); if (aOrder == null && bOrder == null) return a.index - b.index; if (aOrder == null) return 1; if (bOrder == null) return -1; return aOrder - bOrder || a.index - b.index; }).map(({ part }) => part); let toolResultIndex = 0; return toolResultContent.map((part) => part.type === "tool-result" ? sortedToolResults[toolResultIndex++] : part); } var encoder = new TextEncoder(); function canonicalJSON(value) { if (value === null || value === void 0) return JSON.stringify(value); if (typeof value !== "object") return JSON.stringify(value); if (Array.isArray(value)) return `[${value.map((element) => element === void 0 ? "null" : canonicalJSON(element)).join(",")}]`; return `{${Object.keys(value).sort().map((k) => `${JSON.stringify(k)}:${canonicalJSON(value[k])}`).join(",")}}`; } function toBase64url(bytes) { return convertUint8ArrayToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); } async function hashCanonical(value) { const digest = await crypto.subtle.digest("SHA-256", encoder.encode(canonicalJSON(value))); return toBase64url(new Uint8Array(digest)); } var encoder2 = new TextEncoder(); function fromBase64url(str) { return convertBase64ToUint8Array(str); } async function importKey(secret) { const keyData = typeof secret === "string" ? encoder2.encode(secret) : secret; return crypto.subtle.importKey("raw", keyData, { name: "HMAC", hash: "SHA-256" }, false, ["sign", "verify"]); } function buildPayload(approvalId, toolCallId, toolName, inputDigest) { return encoder2.encode(JSON.stringify([ "ai-sdk-tool-approval-v1", approvalId, toolCallId, toolName, inputDigest ])); } function buildLegacyPayload(approvalId, toolCallId, toolName, inputDigest) { return encoder2.encode(`${approvalId} ${toolCallId} ${toolName} ${inputDigest}`); } async function signToolApproval({ secret, approvalId, toolCallId, toolName, input }) { const key = await importKey(secret); const payload = buildPayload(approvalId, toolCallId, toolName, await hashCanonical(input)); const sig = await crypto.subtle.sign("HMAC", key, payload); return toBase64url(new Uint8Array(sig)); } async function verifyToolApprovalSignature({ secret, signature, approvalId, toolCallId, toolName, input }) { const key = await importKey(secret); const inputDigest = await hashCanonical(input); const sigBytes = fromBase64url(signature); const payload = buildPayload(approvalId, toolCallId, toolName, inputDigest); if (await crypto.subtle.verify("HMAC", key, sigBytes, payload)) return true; if (!approvalId.includes("\n") && !toolCallId.includes("\n") && !toolName.includes("\n")) { const legacyPayload = buildLegacyPayload(approvalId, toolCallId, toolName, inputDigest); return crypto.subtle.verify("HMAC", key, sigBytes, legacyPayload); } return false; } async function maybeSignApproval({ secret, approvalId, toolCallId, toolName, input }) { if (secret == null) return void 0; return signToolApproval({ secret, approvalId, toolCallId, toolName, input }); } async function validateApprovedToolApprovals({ approvedToolApprovals, tools, toolApproval, messages, toolsContext, runtimeContext, toolApprovalSecret }) { var _a25; const approved = []; const denied = []; const invalid = []; for (const approval of approvedToolApprovals) { const { toolCall, approvalRequest } = approval; const tool3 = getOwn(tools, toolCall.toolName); if (toolApprovalSecret != null) { if (approvalRequest.signature == null) throw new InvalidToolApprovalSignatureError({ approvalId: approvalRequest.approvalId, toolCallId: toolCall.toolCallId, reason: "missing signature" }); if (!await verifyToolApprovalSignature({ secret: toolApprovalSecret, signature: approvalRequest.signature, approvalId: approvalRequest.approvalId, toolCallId: toolCall.toolCallId, toolName: toolCall.toolName, input: toolCall.input })) throw new InvalidToolApprovalSignatureError({ approvalId: approvalRequest.approvalId, toolCallId: toolCall.toolCallId, reason: "invalid signature" }); } if (isExecutableTool(tool3) && tool3.inputSchema != null) { const validation = await safeValidateTypes({ value: toolCall.input, schema: asSchema(tool3.inputSchema) }); if (!validation.success) { invalid.push({ ...approval, error: new InvalidToolInputError({ toolName: toolCall.toolName, toolInput: JSON.stringify(toolCall.input), cause: validation.error }) }); continue; } } const approvalStatus = await resolveToolApproval({ tools, toolApproval, toolCall, messages, toolsContext, runtimeContext }); if (approvalStatus.type === "denied") denied.push({ ...approval, approvalResponse: { ...approval.approvalResponse, approved: false, reason: (_a25 = approvalStatus.reason) != null ? _a25 : approval.approvalResponse.reason } }); else approved.push(approval); } return { approvedToolApprovals: approved, deniedToolApprovals: denied, invalidToolApprovals: invalid }; } createIdGenerator({ prefix: "aitxt", size: 24 }); createIdGenerator({ prefix: "call", size: 24 }); function prepareHeaders(headers, defaultHeaders) { const responseHeaders = new Headers(headers != null ? headers : {}); for (const [key, value] of Object.entries(defaultHeaders)) if (!responseHeaders.has(key)) responseHeaders.set(key, value); return responseHeaders; } function createTextStreamResponse({ status, statusText, headers, stream }) { return new Response(stream.pipeThrough(new TextEncoderStream()), { status: status != null ? status : 200, statusText, headers: prepareHeaders(headers, { "content-type": "text/plain; charset=utf-8" }) }); } function writeToServerResponse({ response, status, statusText, headers, stream }) { const statusCode = status != null ? status : 200; if (headers != null) response.setHeaders(headers); if (statusText !== void 0) response.writeHead(statusCode, statusText); else response.writeHead(statusCode); const reader = stream.getReader(); const read = async () => { try { while (true) { const { done, value } = await reader.read(); if (done) break; const canContinue = response.write(value); const flush = response.flush; if (typeof flush === "function") flush.call(response); if (!canContinue) await new Promise((resolve3) => { response.once("drain", resolve3); }); } } catch (error) { throw error; } finally { response.end(); } }; return read(); } function pipeTextStreamToResponse({ response, status, statusText, headers, stream }) { return writeToServerResponse({ response, status, statusText, headers: prepareHeaders(headers, { "content-type": "text/plain; charset=utf-8" }), stream: stream.pipeThrough(new TextEncoderStream()) }); } function toTextStream({ stream }) { return stream.pipeThrough(new TransformStream({ transform(part, controller) { if (part.type === "text-delta") controller.enqueue(part.text); } })); } var JsonToSseTransformStream = class extends TransformStream { constructor() { super({ transform(part, controller) { controller.enqueue(`data: ${JSON.stringify(part)} `); }, flush(controller) { controller.enqueue("data: [DONE]\n\n"); } }); } }; var UI_MESSAGE_STREAM_HEADERS = { "content-type": "text/event-stream", "cache-control": "no-cache", connection: "keep-alive", "x-vercel-ai-ui-message-stream": "v1", "x-accel-buffering": "no" }; function createUIMessageStreamResponse({ status, statusText, headers, stream, consumeSseStream }) { let sseStream = stream.pipeThrough(new JsonToSseTransformStream()); if (consumeSseStream) { const [stream1, stream2] = sseStream.tee(); sseStream = stream1; consumeSseStream({ stream: stream2 }); } return new Response(sseStream.pipeThrough(new TextEncoderStream()), { status, statusText, headers: prepareHeaders(headers, UI_MESSAGE_STREAM_HEADERS) }); } function pipeUIMessageStreamToResponse({ response, status, statusText, headers, stream, consumeSseStream }) { let sseStream = stream.pipeThrough(new JsonToSseTransformStream()); if (consumeSseStream) { const [stream1, stream2] = sseStream.tee(); sseStream = stream1; consumeSseStream({ stream: stream2 }); } return writeToServerResponse({ response, status, statusText, headers: prepareHeaders(headers, UI_MESSAGE_STREAM_HEADERS), stream: sseStream.pipeThrough(new TextEncoderStream()) }); } function getResponseUIMessageId({ originalMessages, responseMessageId }) { if (originalMessages == null) return; const lastMessage = originalMessages[originalMessages.length - 1]; return (lastMessage == null ? void 0 : lastMessage.role) === "assistant" ? lastMessage.id : typeof responseMessageId === "function" ? responseMessageId() : responseMessageId; } z.record(z.string(), jsonValueSchema.optional()); function isDataUIMessageChunk(chunk) { return chunk.type.startsWith("data-"); } function createIdMap() { return /* @__PURE__ */ Object.create(null); } function isStaticToolUIPart(part) { return part.type.startsWith("tool-"); } function isDynamicToolUIPart(part) { return part.type === "dynamic-tool"; } function isToolUIPart(part) { return isStaticToolUIPart(part) || isDynamicToolUIPart(part); } function getStaticToolName(part) { return part.type.split("-").slice(1).join("-"); } var rawInputDeprecationWarning = { type: "deprecated", setting: "rawInput in output-error UI message parts", message: "Use the \"input\" field instead. The \"rawInput\" field will be removed in the next major version." }; function warnIfUIMessageHasDeprecatedRawInput(messages) { if (messages.some((message) => message.parts.some((part) => part != null && typeof part === "object" && "type" in part && typeof part.type === "string" && (part.type === "dynamic-tool" || part.type.startsWith("tool-")) && "state" in part && part.state === "output-error" && Object.prototype.hasOwnProperty.call(part, "rawInput") && "rawInput" in part && part.rawInput !== void 0))) logWarnings({ warnings: [rawInputDeprecationWarning] }); } function createStreamingUIMessageState({ lastMessage, messageId }) { return { message: (lastMessage == null ? void 0 : lastMessage.role) === "assistant" ? lastMessage : { id: messageId, metadata: void 0, role: "assistant", parts: [] }, activeTextParts: createIdMap(), activeReasoningParts: createIdMap(), partialToolCalls: createIdMap() }; } function processUIMessageStream({ stream, messageMetadataSchema, dataPartSchemas, runUpdateMessageJob, onError, onToolCall, onData }) { return stream.pipeThrough(new TransformStream({ async transform(chunk, controller) { await runUpdateMessageJob(async ({ state, write }) => { var _a25, _b25, _c, _d; function getCurrentStepParts() { const parts = state.message.parts; let currentStepStartIndex = parts.length - 1; while (currentStepStartIndex >= 0 && parts[currentStepStartIndex].type !== "step-start") currentStepStartIndex--; return parts.slice(currentStepStartIndex + 1); } function getCurrentStepToolInvocations() { return getCurrentStepParts().filter(isToolUIPart); } function getToolInvocation(toolCallId) { let toolInvocation = getCurrentStepToolInvocations().find((invocation) => invocation.toolCallId === toolCallId); if (toolInvocation == null) { const parts = state.message.parts; for (let i = parts.length - 1; i >= 0; i--) { const part = parts[i]; if (isToolUIPart(part) && part.toolCallId === toolCallId) { toolInvocation = part; break; } } } if (toolInvocation == null) throw new UIMessageStreamError({ chunkType: "tool-invocation", chunkId: toolCallId, message: `No tool invocation found for tool call ID "${toolCallId}".` }); return toolInvocation; } function getToolInvocationByApprovalId(approvalId) { const toolInvocation = state.message.parts.filter(isToolUIPart).find((invocation) => { var _a26; return ((_a26 = invocation.approval) == null ? void 0 : _a26.id) === approvalId; }); if (toolInvocation == null) throw new UIMessageStreamError({ chunkType: "tool-approval-response", chunkId: approvalId, message: `No tool invocation found for approval ID "${approvalId}".` }); return toolInvocation; } function updateToolPart(options, existingPart) { var _a26; const part = existingPart != null ? existingPart : getCurrentStepParts().find((part2) => isStaticToolUIPart(part2) && part2.toolCallId === options.toolCallId); const anyOptions = options; const anyPart = part; if (part != null) { part.state = options.state; anyPart.input = anyOptions.input; anyPart.output = anyOptions.output; anyPart.errorText = anyOptions.errorText; anyPart.rawInput = anyOptions.rawInput; anyPart.preliminary = anyOptions.preliminary; if (options.title !== void 0) anyPart.title = options.title; if (options.toolMetadata !== void 0) anyPart.toolMetadata = options.toolMetadata; anyPart.providerExecuted = (_a26 = anyOptions.providerExecuted) != null ? _a26 : part.providerExecuted; const providerMetadata = anyOptions.providerMetadata; if (providerMetadata != null) { if (options.state === "output-available" || options.state === "output-error") { const resultPart = part; resultPart.resultProviderMetadata = providerMetadata; } else part.callProviderMetadata = providerMetadata; } } else state.message.parts.push({ type: `tool-${options.toolName}`, toolCallId: options.toolCallId, state: options.state, title: options.title, ...options.toolMetadata !== void 0 ? { toolMetadata: options.toolMetadata } : {}, input: anyOptions.input, output: anyOptions.output, rawInput: anyOptions.rawInput, errorText: anyOptions.errorText, providerExecuted: anyOptions.providerExecuted, preliminary: anyOptions.preliminary, ...anyOptions.providerMetadata != null && (options.state === "output-available" || options.state === "output-error") ? { resultProviderMetadata: anyOptions.providerMetadata } : {}, ...anyOptions.providerMetadata != null && !(options.state === "output-available" || options.state === "output-error") ? { callProviderMetadata: anyOptions.providerMetadata } : {} }); } function updateDynamicToolPart(options, existingPart) { var _a26, _b26; const part = existingPart != null ? existingPart : getCurrentStepParts().find((part2) => part2.type === "dynamic-tool" && part2.toolCallId === options.toolCallId); const anyOptions = options; const anyPart = part; if (part != null) { part.state = options.state; anyPart.toolName = options.toolName; anyPart.input = anyOptions.input; anyPart.output = anyOptions.output; anyPart.errorText = anyOptions.errorText; anyPart.rawInput = (_a26 = anyOptions.rawInput) != null ? _a26 : anyPart.rawInput; anyPart.preliminary = anyOptions.preliminary; if (options.title !== void 0) anyPart.title = options.title; if (options.toolMetadata !== void 0) anyPart.toolMetadata = options.toolMetadata; anyPart.providerExecuted = (_b26 = anyOptions.providerExecuted) != null ? _b26 : part.providerExecuted; const providerMetadata = anyOptions.providerMetadata; if (providerMetadata != null) { if (options.state === "output-available" || options.state === "output-error") { const resultPart = part; resultPart.resultProviderMetadata = providerMetadata; } else part.callProviderMetadata = providerMetadata; } } else state.message.parts.push({ type: "dynamic-tool", toolName: options.toolName, toolCallId: options.toolCallId, state: options.state, input: anyOptions.input, output: anyOptions.output, errorText: anyOptions.errorText, preliminary: anyOptions.preliminary, providerExecuted: anyOptions.providerExecuted, title: options.title, ...options.toolMetadata !== void 0 ? { toolMetadata: options.toolMetadata } : {}, ...anyOptions.providerMetadata != null && (options.state === "output-available" || options.state === "output-error") ? { resultProviderMetadata: anyOptions.providerMetadata } : {}, ...anyOptions.providerMetadata != null && !(options.state === "output-available" || options.state === "output-error") ? { callProviderMetadata: anyOptions.providerMetadata } : {} }); } async function updateMessageMetadata(metadata) { if (metadata != null) { const mergedMetadata = state.message.metadata != null ? mergeObjects(state.message.metadata, metadata) : metadata; if (messageMetadataSchema != null) await validateTypes({ value: mergedMetadata, schema: messageMetadataSchema, context: { field: "message.metadata", entityId: state.message.id } }); state.message.metadata = mergedMetadata; } } switch (chunk.type) { case "text-start": { const textPart = { type: "text", text: "", providerMetadata: chunk.providerMetadata, state: "streaming" }; state.activeTextParts[chunk.id] = textPart; state.message.parts.push(textPart); write(); break; } case "text-delta": { const textPart = state.activeTextParts[chunk.id]; if (textPart == null) throw new UIMessageStreamError({ chunkType: "text-delta", chunkId: chunk.id, message: `Received text-delta for missing text part with ID "${chunk.id}". Ensure a "text-start" chunk is sent before any "text-delta" chunks.` }); textPart.text += chunk.delta; textPart.providerMetadata = (_a25 = chunk.providerMetadata) != null ? _a25 : textPart.providerMetadata; write(); break; } case "text-end": { const textPart = state.activeTextParts[chunk.id]; if (textPart == null) throw new UIMessageStreamError({ chunkType: "text-end", chunkId: chunk.id, message: `Received text-end for missing text part with ID "${chunk.id}". Ensure a "text-start" chunk is sent before any "text-end" chunks.` }); textPart.state = "done"; textPart.providerMetadata = (_b25 = chunk.providerMetadata) != null ? _b25 : textPart.providerMetadata; delete state.activeTextParts[chunk.id]; write(); break; } case "custom": { const customPart = { type: "custom", kind: chunk.kind, providerMetadata: chunk.providerMetadata }; state.message.parts.push(customPart); write(); break; } case "reasoning-start": { const reasoningPart = { type: "reasoning", id: chunk.id, text: "", providerMetadata: chunk.providerMetadata, state: "streaming" }; state.activeReasoningParts[chunk.id] = reasoningPart; state.message.parts.push(reasoningPart); write(); break; } case "reasoning-delta": { const reasoningPart = state.activeReasoningParts[chunk.id]; if (reasoningPart == null) throw new UIMessageStreamError({ chunkType: "reasoning-delta", chunkId: chunk.id, message: `Received reasoning-delta for missing reasoning part with ID "${chunk.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-delta" chunks.` }); reasoningPart.text += chunk.delta; reasoningPart.providerMetadata = (_c = chunk.providerMetadata) != null ? _c : reasoningPart.providerMetadata; write(); break; } case "reasoning-end": { const reasoningPart = state.activeReasoningParts[chunk.id]; if (reasoningPart == null) throw new UIMessageStreamError({ chunkType: "reasoning-end", chunkId: chunk.id, message: `Received reasoning-end for missing reasoning part with ID "${chunk.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-end" chunks.` }); reasoningPart.providerMetadata = (_d = chunk.providerMetadata) != null ? _d : reasoningPart.providerMetadata; reasoningPart.state = "done"; delete state.activeReasoningParts[chunk.id]; write(); break; } case "file": case "reasoning-file": state.message.parts.push({ type: chunk.type, mediaType: chunk.mediaType, url: chunk.url, ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {} }); write(); break; case "source-url": state.message.parts.push({ type: "source-url", sourceId: chunk.sourceId, url: chunk.url, title: chunk.title, providerMetadata: chunk.providerMetadata }); write(); break; case "source-document": state.message.parts.push({ type: "source-document", sourceId: chunk.sourceId, mediaType: chunk.mediaType, title: chunk.title, filename: chunk.filename, providerMetadata: chunk.providerMetadata }); write(); break; case "tool-input-start": { const toolInvocations = getCurrentStepParts().filter(isStaticToolUIPart); state.partialToolCalls[chunk.toolCallId] = { text: "", toolName: chunk.toolName, index: toolInvocations.length, dynamic: chunk.dynamic, title: chunk.title, toolMetadata: chunk.toolMetadata }; if (chunk.dynamic) updateDynamicToolPart({ toolCallId: chunk.toolCallId, toolName: chunk.toolName, state: "input-streaming", input: void 0, providerExecuted: chunk.providerExecuted, title: chunk.title, toolMetadata: chunk.toolMetadata, providerMetadata: chunk.providerMetadata }); else updateToolPart({ toolCallId: chunk.toolCallId, toolName: chunk.toolName, state: "input-streaming", input: void 0, providerExecuted: chunk.providerExecuted, title: chunk.title, toolMetadata: chunk.toolMetadata, providerMetadata: chunk.providerMetadata }); write(); break; } case "tool-input-delta": { const partialToolCall = state.partialToolCalls[chunk.toolCallId]; if (partialToolCall == null) throw new UIMessageStreamError({ chunkType: "tool-input-delta", chunkId: chunk.toolCallId, message: `Received tool-input-delta for missing tool call with ID "${chunk.toolCallId}". Ensure a "tool-input-start" chunk is sent before any "tool-input-delta" chunks.` }); partialToolCall.text += chunk.inputTextDelta; const { value: partialArgs } = await parsePartialJson(partialToolCall.text); if (partialToolCall.dynamic) updateDynamicToolPart({ toolCallId: chunk.toolCallId, toolName: partialToolCall.toolName, state: "input-streaming", input: partialArgs, title: partialToolCall.title, toolMetadata: partialToolCall.toolMetadata }); else updateToolPart({ toolCallId: chunk.toolCallId, toolName: partialToolCall.toolName, state: "input-streaming", input: partialArgs, title: partialToolCall.title, toolMetadata: partialToolCall.toolMetadata }); write(); break; } case "tool-input-available": if (chunk.dynamic) updateDynamicToolPart({ toolCallId: chunk.toolCallId, toolName: chunk.toolName, state: "input-available", input: chunk.input, providerExecuted: chunk.providerExecuted, providerMetadata: chunk.providerMetadata, title: chunk.title, toolMetadata: chunk.toolMetadata }); else updateToolPart({ toolCallId: chunk.toolCallId, toolName: chunk.toolName, state: "input-available", input: chunk.input, providerExecuted: chunk.providerExecuted, providerMetadata: chunk.providerMetadata, title: chunk.title, toolMetadata: chunk.toolMetadata }); write(); if (onToolCall && !chunk.providerExecuted) await onToolCall({ toolCall: chunk }); break; case "tool-input-error": { const existingPart = getCurrentStepParts().filter(isToolUIPart).find((p) => p.toolCallId === chunk.toolCallId); if (existingPart != null ? existingPart.type === "dynamic-tool" : !!chunk.dynamic) updateDynamicToolPart({ toolCallId: chunk.toolCallId, toolName: chunk.toolName, state: "output-error", input: chunk.input, errorText: chunk.errorText, providerExecuted: chunk.providerExecuted, providerMetadata: chunk.providerMetadata, toolMetadata: chunk.toolMetadata }); else { updateToolPart({ toolCallId: chunk.toolCallId, toolName: chunk.toolName, state: "output-error", input: void 0, rawInput: chunk.input, errorText: chunk.errorText, providerExecuted: chunk.providerExecuted, providerMetadata: chunk.providerMetadata, toolMetadata: chunk.toolMetadata }); warnIfUIMessageHasDeprecatedRawInput([state.message]); } write(); break; } case "tool-approval-request": { const toolInvocation = getToolInvocation(chunk.toolCallId); toolInvocation.state = "approval-requested"; toolInvocation.approval = { id: chunk.approvalId, ...chunk.approvalDescriptor != null ? { descriptor: chunk.approvalDescriptor } : {}, ...chunk.reason != null ? { requestReason: chunk.reason } : {}, ...chunk.isAutomatic === true ? { isAutomatic: true } : {}, ...chunk.signature != null ? { signature: chunk.signature } : {} }; write(); break; } case "tool-approval-response": { const toolInvocation = getToolInvocationByApprovalId(chunk.approvalId); const approval = toolInvocation.approval == null ? { id: chunk.approvalId } : toolInvocation.approval; toolInvocation.state = "approval-responded"; toolInvocation.approval = { ...approval, id: chunk.approvalId, approved: chunk.approved, ...chunk.reason != null ? { reason: chunk.reason } : {} }; if (chunk.providerExecuted != null) toolInvocation.providerExecuted = chunk.providerExecuted; if (chunk.providerMetadata != null) toolInvocation.callProviderMetadata = chunk.providerMetadata; write(); break; } case "tool-output-denied": { const toolInvocation = getToolInvocation(chunk.toolCallId); toolInvocation.state = "output-denied"; write(); break; } case "tool-output-available": { const toolInvocation = getToolInvocation(chunk.toolCallId); if (toolInvocation.type === "dynamic-tool") updateDynamicToolPart({ toolCallId: chunk.toolCallId, toolName: toolInvocation.toolName, state: "output-available", input: toolInvocation.input, output: chunk.output, preliminary: chunk.preliminary, providerExecuted: chunk.providerExecuted, providerMetadata: chunk.providerMetadata, title: toolInvocation.title, toolMetadata: toolInvocation.toolMetadata }, toolInvocation); else updateToolPart({ toolCallId: chunk.toolCallId, toolName: getStaticToolName(toolInvocation), state: "output-available", input: toolInvocation.input, output: chunk.output, providerExecuted: chunk.providerExecuted, preliminary: chunk.preliminary, providerMetadata: chunk.providerMetadata, title: toolInvocation.title, toolMetadata: toolInvocation.toolMetadata }, toolInvocation); write(); break; } case "tool-output-error": { const toolInvocation = getToolInvocation(chunk.toolCallId); if (toolInvocation.type === "dynamic-tool") updateDynamicToolPart({ toolCallId: chunk.toolCallId, toolName: toolInvocation.toolName, state: "output-error", input: toolInvocation.input, errorText: chunk.errorText, providerExecuted: chunk.providerExecuted, providerMetadata: chunk.providerMetadata, title: toolInvocation.title, toolMetadata: toolInvocation.toolMetadata }, toolInvocation); else updateToolPart({ toolCallId: chunk.toolCallId, toolName: getStaticToolName(toolInvocation), state: "output-error", input: toolInvocation.input, rawInput: toolInvocation.rawInput, errorText: chunk.errorText, providerExecuted: chunk.providerExecuted, providerMetadata: chunk.providerMetadata, title: toolInvocation.title, toolMetadata: toolInvocation.toolMetadata }, toolInvocation); write(); break; } case "start-step": state.message.parts.push({ type: "step-start" }); break; case "finish-step": break; case "reset-step": { const currentStepParts = getCurrentStepParts(); state.activeTextParts = createIdMap(); state.activeReasoningParts = createIdMap(); state.partialToolCalls = createIdMap(); if (currentStepParts.length > 0) { state.message.parts.splice(state.message.parts.length - currentStepParts.length, currentStepParts.length); write(); } break; } case "start": if (chunk.messageId != null) state.message.id = chunk.messageId; await updateMessageMetadata(chunk.messageMetadata); if (chunk.messageId != null || chunk.messageMetadata != null) write({ updateStatus: false }); break; case "finish": if (chunk.finishReason != null) state.finishReason = chunk.finishReason; await updateMessageMetadata(chunk.messageMetadata); if (chunk.messageMetadata != null) write(); break; case "message-metadata": await updateMessageMetadata(chunk.messageMetadata); if (chunk.messageMetadata != null) write(); break; case "error": onError?.(new Error(chunk.errorText)); break; default: if (isDataUIMessageChunk(chunk)) { if ((dataPartSchemas == null ? void 0 : dataPartSchemas[chunk.type]) != null) { const partIdx = state.message.parts.findIndex((p) => "id" in p && "data" in p && p.id === chunk.id && p.type === chunk.type); const actualPartIdx = partIdx >= 0 ? partIdx : state.message.parts.length; await validateTypes({ value: chunk.data, schema: dataPartSchemas[chunk.type], context: { field: `message.parts[${actualPartIdx}].data`, entityName: chunk.type, entityId: chunk.id } }); } const dataChunk = chunk; if (dataChunk.transient) { onData?.(dataChunk); break; } const existingUIPart = dataChunk.id != null ? state.message.parts.find((chunkArg) => dataChunk.type === chunkArg.type && dataChunk.id === chunkArg.id) : void 0; if (existingUIPart != null) existingUIPart.data = dataChunk.data; else state.message.parts.push(dataChunk); onData?.(dataChunk); write(); } } controller.enqueue(chunk); }); } })); } function handleUIMessageStreamFinish({ messageId, originalMessages = [], onStepEnd, onStepFinish, onEnd, onFinish, onError, stream, getOutcome }) { let lastMessage = originalMessages == null ? void 0 : originalMessages[originalMessages.length - 1]; if ((lastMessage == null ? void 0 : lastMessage.role) !== "assistant") lastMessage = void 0; else messageId = lastMessage.id; let isAborted = false; let hasProcessingFailure = false; let processingError; const recordProcessingFailure = (error) => { hasProcessingFailure = true; processingError = error; }; const idInjectedStream = stream.pipeThrough(new TransformStream({ transform(chunk, controller) { try { let outputChunk = chunk; if (chunk.type === "start") { const startChunk = chunk; if (startChunk.messageId == null && messageId != null) outputChunk = { ...startChunk, messageId }; } if (chunk.type === "abort") isAborted = true; controller.enqueue(outputChunk); } catch (error) { recordProcessingFailure(error); throw error; } } })); const resolvedOnStepEnd = onStepEnd != null ? onStepEnd : onStepFinish; const resolvedOnEnd = onEnd != null ? onEnd : onFinish; if (resolvedOnEnd == null && resolvedOnStepEnd == null) return idInjectedStream; const state = createStreamingUIMessageState({ lastMessage: lastMessage ? structuredClone(lastMessage) : void 0, messageId: messageId != null ? messageId : "" }); const runUpdateMessageJob = async (job) => { try { await job({ state, write: () => {} }); } catch (error) { recordProcessingFailure(error); throw error; } }; let finishCalled = false; const callOnEnd = async () => { var _a25; if (finishCalled || !resolvedOnEnd) return; finishCalled = true; const isContinuation = state.message.id === (lastMessage == null ? void 0 : lastMessage.id); const declaredOutcome = (_a25 = getOutcome == null ? void 0 : getOutcome()) != null ? _a25 : { status: "unknown" }; const outcome = hasProcessingFailure ? { status: "failed", error: processingError } : declaredOutcome.status === "unknown" && isAborted ? { status: "aborted" } : declaredOutcome; await resolvedOnEnd({ isAborted: isAborted || outcome.status === "aborted", isContinuation, outcome, responseMessage: state.message, messages: [...isContinuation ? originalMessages.slice(0, -1) : originalMessages, state.message], finishReason: state.finishReason }); }; const callOnStepFinish = async () => { if (!resolvedOnStepEnd) return; const isContinuation = state.message.id === (lastMessage == null ? void 0 : lastMessage.id); try { await resolvedOnStepEnd({ isContinuation, responseMessage: structuredClone(state.message), messages: [...isContinuation ? originalMessages.slice(0, -1) : originalMessages, structuredClone(state.message)] }); } catch (error) { onError(error); } }; return processUIMessageStream({ stream: idInjectedStream, runUpdateMessageJob, onError }).pipeThrough(new TransformStream({ async transform(chunk, controller) { if (chunk.type === "finish-step") await callOnStepFinish(); controller.enqueue(chunk); }, async cancel() { await callOnEnd(); }, async flush() { await callOnEnd(); } })); } function toUIMessageChunk(part, { tools, sendReasoning = true, sendSources = false, sendStart = true, sendFinish = true, onError = () => "An error occurred.", messageMetadata, responseMessageId } = {}) { const isDynamic = (toolPart) => { const tool3 = tools == null ? void 0 : tools[toolPart.toolName]; if (tool3 == null) return toolPart.dynamic; return (tool3 == null ? void 0 : tool3.type) === "dynamic" ? true : void 0; }; const partType = part.type; switch (partType) { case "text-start": return { type: "text-start", id: part.id, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; case "text-delta": return { type: "text-delta", id: part.id, delta: part.text, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; case "text-end": return { type: "text-end", id: part.id, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; case "reasoning-start": case "reasoning-end": if (!sendReasoning) return; return { type: partType, id: part.id, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; case "reasoning-delta": if (!sendReasoning) return; return { type: "reasoning-delta", id: part.id, delta: part.text, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; case "file": case "reasoning-file": if (partType === "reasoning-file" && !sendReasoning) return; return { type: part.type, mediaType: part.file.mediaType, url: `data:${part.file.mediaType};base64,${part.file.base64}`, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; case "source": if (!sendSources) return; if (part.sourceType === "url") return { type: "source-url", sourceId: part.id, url: part.url, title: part.title, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; if (part.sourceType === "document") return { type: "source-document", sourceId: part.id, mediaType: part.mediaType, title: part.title, filename: part.filename, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; return; case "custom": return { type: "custom", kind: part.kind, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }; case "tool-input-start": { const dynamic = isDynamic(part); return { type: "tool-input-start", toolCallId: part.id, toolName: part.toolName, ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {}, ...dynamic != null ? { dynamic } : {}, ...part.title != null ? { title: part.title } : {} }; } case "tool-input-delta": return { type: "tool-input-delta", toolCallId: part.id, inputTextDelta: part.delta }; case "tool-call": { const dynamic = isDynamic(part); if (part.invalid) return { type: "tool-input-error", toolCallId: part.toolCallId, toolName: part.toolName, input: part.input, ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {}, ...dynamic != null ? { dynamic } : {}, errorText: onError(part.error), ...part.title != null ? { title: part.title } : {} }; return { type: "tool-input-available", toolCallId: part.toolCallId, toolName: part.toolName, input: part.input, ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {}, ...dynamic != null ? { dynamic } : {}, ...part.title != null ? { title: part.title } : {} }; } case "tool-approval-request": return { type: "tool-approval-request", approvalId: part.approvalId, toolCallId: part.toolCall.toolCallId, ...part.reason != null ? { reason: part.reason } : {}, ...part.isAutomatic != null ? { isAutomatic: part.isAutomatic } : {}, ...part.signature != null ? { signature: part.signature } : {} }; case "tool-approval-response": return { type: "tool-approval-response", approvalId: part.approvalId, approved: part.approved, ...part.reason != null ? { reason: part.reason } : {}, ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {} }; case "tool-result": { const dynamic = isDynamic(part); return { type: "tool-output-available", toolCallId: part.toolCallId, output: part.output === void 0 ? null : part.output, ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {}, ...part.preliminary != null ? { preliminary: part.preliminary } : {}, ...dynamic != null ? { dynamic } : {} }; } case "tool-error": { const dynamic = isDynamic(part); return { type: "tool-output-error", toolCallId: part.toolCallId, errorText: part.providerExecuted ? typeof part.error === "string" ? part.error : JSON.stringify(part.error) : onError(part.error), ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}, ...part.toolMetadata != null ? { toolMetadata: part.toolMetadata } : {}, ...dynamic != null ? { dynamic } : {} }; } case "tool-output-denied": return { type: "tool-output-denied", toolCallId: part.toolCallId }; case "error": return { type: "error", errorText: onError(part.error) }; case "start-step": return { type: "start-step" }; case "finish-step": return { type: "finish-step" }; case "start": if (!sendStart) return; return { type: "start", ...messageMetadata != null ? { messageMetadata } : {}, ...responseMessageId != null ? { messageId: responseMessageId } : {} }; case "finish": if (!sendFinish) return; return { type: "finish", finishReason: part.finishReason, ...messageMetadata != null ? { messageMetadata } : {} }; case "abort": return part; case "tool-input-end": case "raw": return; default: throw new Error(`Unknown chunk type: ${partType}`); } } function toUIMessageStream({ stream, tools, sendReasoning = true, sendSources = false, sendStart = true, sendFinish = true, onError = () => "An error occurred.", messageMetadata, originalMessages, generateMessageId, onEnd, onFinish }) { let outcome = { status: "unknown" }; let hasFatalFailure = false; const setSourceOutcome = (newOutcome) => { if (!hasFatalFailure && outcome.status !== "completed" && outcome.status !== "aborted" && newOutcome.status !== "unknown" && (outcome.status === "unknown" || newOutcome.status !== "failed")) outcome = newOutcome; }; const failOutcome = (error) => { hasFatalFailure = true; outcome = { status: "failed", error }; }; const responseMessageId = generateMessageId != null ? getResponseUIMessageId({ originalMessages, responseMessageId: generateMessageId }) : void 0; const sourceReader = stream.getReader(); let sourceReaderReleased = false; let sourceStreamCancelled = false; const releaseSourceReader = () => { if (!sourceReaderReleased) { sourceReader.releaseLock(); sourceReaderReleased = true; } }; return handleUIMessageStreamFinish({ stream: new ReadableStream({ async pull(controller) { try { const { done, value } = await sourceReader.read(); if (done) { releaseSourceReader(); if (!sourceStreamCancelled) controller.close(); } else controller.enqueue(value); } catch (error) { releaseSourceReader(); if (!sourceStreamCancelled) { failOutcome(error); controller.error(error); } } }, async cancel(reason) { sourceStreamCancelled = true; if (sourceReaderReleased) return; try { await sourceReader.cancel(reason); } finally { releaseSourceReader(); } } }).pipeThrough(new TransformStream({ transform: async (part, controller) => { try { const messageMetadataValue = messageMetadata == null ? void 0 : messageMetadata({ part }); const uiMessageChunk = toUIMessageChunk(part, { tools, sendReasoning, sendSources, sendStart, sendFinish, onError, messageMetadata: messageMetadataValue, responseMessageId }); if (uiMessageChunk != null) controller.enqueue(uiMessageChunk); if (messageMetadataValue != null && part.type !== "start" && part.type !== "finish") controller.enqueue({ type: "message-metadata", messageMetadata: messageMetadataValue }); if (part.type === "finish") setSourceOutcome({ status: "completed" }); else if (part.type === "abort") setSourceOutcome({ status: "aborted" }); else if (part.type === "error") setSourceOutcome({ status: "failed", error: part.error }); } catch (error) { failOutcome(error); throw error; } } })), messageId: responseMessageId != null ? responseMessageId : generateMessageId == null ? void 0 : generateMessageId(), originalMessages, onEnd: onEnd != null ? onEnd : onFinish, onError, getOutcome: () => outcome }); } function createAsyncIterableStream(source) { return asAsyncIterableStream(source.pipeThrough(new TransformStream())); } function asAsyncIterableStream(stream) { stream[Symbol.asyncIterator] = function() { const reader = this.getReader(); let finished = false; async function cleanup(cancelStream) { var _a25; if (finished) return; finished = true; try { if (cancelStream) await ((_a25 = reader.cancel) == null ? void 0 : _a25.call(reader)); } finally { try { reader.releaseLock(); } catch (e) {} } } return { /** * Reads the next chunk from the stream. * @returns A promise resolving to the next IteratorResult. */ async next() { if (finished) return { done: true, value: void 0 }; let result; try { result = await reader.read(); } catch (error) { await cleanup(false); throw error; } const { done, value } = result; if (done) { await cleanup(true); return { done: true, value: void 0 }; } return { done: false, value }; }, /** * May be called on early exit (e.g., break from for-await) or after completion. * Ensures the stream is cancelled and resources are released. * @returns A promise resolving to a completed IteratorResult. */ async return() { await cleanup(true); return { done: true, value: void 0 }; }, /** * Called on early exit with error. * Ensures the stream is cancelled and resources are released, then rethrows the error. * @param err The error to throw. * @returns A promise that rejects with the provided error. */ async throw(err) { await cleanup(true); throw err; } }; }; return stream; } async function consumeStream({ stream, onError, abortSignal }) { const reader = stream.getReader(); const cancelOnAbort = () => { reader.cancel().catch(() => {}); }; if (abortSignal == null ? void 0 : abortSignal.aborted) cancelOnAbort(); else abortSignal?.addEventListener("abort", cancelOnAbort, { once: true }); try { while (true) { const { done } = await reader.read(); if (done) break; } } catch (error) { onError?.(error); } finally { abortSignal?.removeEventListener("abort", cancelOnAbort); reader.releaseLock(); } } function createResolvablePromise() { let resolve3; let reject; return { promise: new Promise((res, rej) => { resolve3 = res; reject = rej; }), resolve: resolve3, reject }; } function createStitchableStream() { let innerStreams = []; let controller = null; let isClosed = false; let isCancelled = false; let waitForNewStream = createResolvablePromise(); const terminate = () => { if (isCancelled) return; isClosed = true; waitForNewStream.resolve(); innerStreams.forEach(({ reader, onCancel }) => { onCancel?.(); reader.cancel(); }); innerStreams = []; controller?.close(); }; const processPull = async () => { var _a25; if (isCancelled) return; if (isClosed && innerStreams.length === 0) { controller?.close(); return; } if (innerStreams.length === 0) { waitForNewStream = createResolvablePromise(); await waitForNewStream.promise; return await processPull(); } const currentStream = innerStreams[0]; try { const { value, done } = await currentStream.reader.read(); if (isCancelled) return; if (done) { innerStreams.shift(); if (innerStreams.length === 0 && isClosed) controller?.close(); else await processPull(); } else controller?.enqueue(value); } catch (error) { if (isCancelled) return; (_a25 = currentStream.onError) == null || _a25.call(currentStream, error); controller?.error(error); innerStreams.shift(); terminate(); } }; return { stream: new ReadableStream({ start(controllerParam) { controller = controllerParam; }, pull: processPull, async cancel() { isCancelled = true; isClosed = true; waitForNewStream.resolve(); for (const { reader, onCancel } of innerStreams) { onCancel?.(); await reader.cancel(); } innerStreams = []; } }), addStream: (innerStream, callbacks) => { var _a25; if (isCancelled) { (_a25 = callbacks == null ? void 0 : callbacks.onCancel) == null || _a25.call(callbacks); innerStream.cancel().catch(() => {}); return; } if (isClosed) throw new Error("Cannot add inner stream: outer stream is closed"); innerStreams.push({ reader: innerStream.getReader(), ...callbacks }); waitForNewStream.resolve(); }, /** * Gracefully close the outer stream. This will let the inner streams * finish processing and then close the outer stream. */ close: () => { if (isCancelled) return; isClosed = true; waitForNewStream.resolve(); if (innerStreams.length === 0) controller?.close(); }, /** * Immediately close the outer stream. This will cancel all inner streams * and close the outer stream. */ terminate }; } var streamRetryAttemptBoundarySymbol = /* @__PURE__ */ Symbol("streamRetryAttemptBoundary"); function createStreamRetryAttemptBoundaryPart({ warnings }) { return { [streamRetryAttemptBoundarySymbol]: true, warnings }; } function isStreamRetryAttemptBoundaryPart(part) { return typeof part === "object" && part != null && streamRetryAttemptBoundarySymbol in part; } function executeToolsFromStream({ stream, tools, callId, messages, abortSignal, timeout, experimental_sandbox: sandbox, toolsContext, toolApproval, runtimeContext, toolApprovalSecret, generateId: generateId5, onToolExecutionStart, onToolExecutionEnd, executeToolInTelemetryContext, runInTracingChannelSpan }) { const toolCallsToExecute = []; return stream.pipeThrough(new TransformStream({ async transform(chunk, controller) { controller.enqueue(chunk); if (isStreamRetryAttemptBoundaryPart(chunk)) { toolCallsToExecute.length = 0; return; } switch (chunk.type) { case "tool-call": { if (chunk.invalid) return; const tool3 = getOwn(tools, chunk.toolName); if (tool3 == null) return; const toolApprovalStatus = await resolveToolApproval({ tools, toolCall: chunk, toolApproval, messages, toolsContext, runtimeContext }); if (toolApprovalStatus.type === "not-applicable") { if (tool3.execute != null && chunk.providerExecuted !== true) toolCallsToExecute.push(chunk); return; } const approvalId = generateId5(); const signature = await maybeSignApproval({ secret: toolApprovalSecret, approvalId, toolCallId: chunk.toolCallId, toolName: chunk.toolName, input: chunk.input }); switch (toolApprovalStatus.type) { case "user-approval": controller.enqueue({ type: "tool-approval-request", approvalId, toolCall: chunk, ...toolApprovalStatus.reason != null ? { reason: toolApprovalStatus.reason } : {}, ...signature != null ? { signature } : {} }); return; case "denied": controller.enqueue({ type: "tool-approval-request", approvalId, toolCall: chunk, isAutomatic: true, ...signature != null ? { signature } : {} }); controller.enqueue({ type: "tool-approval-response", approvalId, approved: false, toolCall: chunk, reason: toolApprovalStatus.reason, providerExecuted: chunk.providerExecuted }); controller.enqueue({ type: "tool-output-denied", toolCallId: chunk.toolCallId, toolName: chunk.toolName }); return; case "approved": controller.enqueue({ type: "tool-approval-request", approvalId, toolCall: chunk, isAutomatic: true, ...signature != null ? { signature } : {} }); controller.enqueue({ type: "tool-approval-response", approvalId, approved: true, toolCall: chunk, reason: toolApprovalStatus.reason, providerExecuted: chunk.providerExecuted }); } if (tool3.execute != null && chunk.providerExecuted !== true) toolCallsToExecute.push(chunk); return; } case "model-call-end": if (!isToolExecutionAllowedFinishReason(chunk.finishReason)) return; await Promise.all(toolCallsToExecute.map(async (toolCall) => { try { const result = await executeToolCall({ toolCall, tools, callId, messages, abortSignal, timeout, experimental_sandbox: sandbox, toolsContext, onToolExecutionStart, onToolExecutionEnd, executeToolInTelemetryContext, runInTracingChannelSpan, onPreliminaryToolResult: (result2) => { controller.enqueue(result2); } }); if (result != null) { controller.enqueue({ type: "tool-execution-end", toolCallId: result.output.toolCallId, toolExecutionMs: result.toolExecutionMs }); controller.enqueue(result.output); } } catch (error) { controller.enqueue({ type: "error", error }); } })); return; } } })); } function invokeToolCallbacksFromStream({ stream, tools, stepInputMessages, abortSignal, toolsContext }) { if (tools == null) return stream; let ongoingToolCalls = createIdMap(); const getValidatedContext = ({ toolCallId, toolName }) => { const ongoingToolCall = ongoingToolCalls[toolCallId]; if ((ongoingToolCall == null ? void 0 : ongoingToolCall.validatedContext) != null) return ongoingToolCall.validatedContext; const tool3 = getOwn(tools, toolName); const validatedContext = validateToolContext({ toolName, context: getOwn(toolsContext, toolName), contextSchema: tool3 == null ? void 0 : tool3.contextSchema }); if (ongoingToolCall != null) ongoingToolCall.validatedContext = validatedContext; return validatedContext; }; return stream.pipeThrough(new TransformStream({ async transform(chunk, controller) { var _a25, _b25; controller.enqueue(chunk); if (isStreamRetryAttemptBoundaryPart(chunk)) { ongoingToolCalls = createIdMap(); return; } switch (chunk.type) { case "tool-input-start": { ongoingToolCalls[chunk.id] = { toolName: chunk.toolName, validatedContext: void 0 }; const tool3 = getOwn(tools, chunk.toolName); if ((tool3 == null ? void 0 : tool3.onInputStart) != null) await tool3.onInputStart({ toolCallId: chunk.id, messages: stepInputMessages, abortSignal, context: await getValidatedContext({ toolCallId: chunk.id, toolName: chunk.toolName }) }); break; } case "tool-input-delta": { const toolName = (_a25 = ongoingToolCalls[chunk.id]) == null ? void 0 : _a25.toolName; const tool3 = getOwn(tools, toolName); if ((tool3 == null ? void 0 : tool3.onInputDelta) != null) await tool3.onInputDelta({ inputTextDelta: chunk.delta, toolCallId: chunk.id, messages: stepInputMessages, abortSignal, context: await getValidatedContext({ toolCallId: chunk.id, toolName }) }); break; } case "tool-call": { const toolName = (_b25 = ongoingToolCalls[chunk.toolCallId]) == null ? void 0 : _b25.toolName; const tool3 = getOwn(tools, toolName); if (!chunk.invalid && (tool3 == null ? void 0 : tool3.onInputAvailable) != null) { const validatedContext = getValidatedContext({ toolCallId: chunk.toolCallId, toolName }); delete ongoingToolCalls[chunk.toolCallId]; await tool3.onInputAvailable({ input: chunk.input, toolCallId: chunk.toolCallId, messages: stepInputMessages, abortSignal, context: await validatedContext }); } else delete ongoingToolCalls[chunk.toolCallId]; } } } })); } function normalizeStreamProviderError(error) { var _a25, _b25, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p; if (isError(error) || AISDKError.isInstance(error) || StreamProviderError.isInstance(error)) return error; const outer = asRecord(error); if (outer == null) return error; const providerStreamError = isProviderStreamError(error); const details = providerStreamError ? outer : (_c = (_b25 = asRecord((_a25 = asRecord(outer.response)) == null ? void 0 : _a25.error)) != null ? _b25 : asRecord(outer.error)) != null ? _c : outer; if (typeof details.message !== "string") return error; const type = (_d = getString(details.type)) != null ? _d : getString(outer.type); const code = (_e = getStringOrNumber(details.code)) != null ? _e : getStringOrNumber(outer.code); const explicitStatusCode = (_l = (_k = (_j = (_i = (_h = (_g = (_f = getHttpStatusCode(details.statusCode)) != null ? _f : getHttpStatusCode(outer.statusCode)) != null ? _g : getHttpStatusCode(details.status_code)) != null ? _h : getHttpStatusCode(outer.status_code)) != null ? _i : getHttpStatusCode(details.status)) != null ? _j : getHttpStatusCode(outer.status)) != null ? _k : getHttpStatusCode(details.code)) != null ? _l : getHttpStatusCode(outer.code); const messageMetadata = inferExactMessageMetadata(details.message); const statusCode = explicitStatusCode != null ? explicitStatusCode : messageMetadata == null ? void 0 : messageMetadata.statusCode; const explicitRetryability = (_o = (_n = (_m = getBoolean(details.isRetryable)) != null ? _m : getBoolean(outer.isRetryable)) != null ? _n : getBoolean(details.is_retryable)) != null ? _o : getBoolean(outer.is_retryable); return new StreamProviderError({ message: details.message, type, code, statusCode, isRetryable: (_p = explicitRetryability != null ? explicitRetryability : messageMetadata == null ? void 0 : messageMetadata.isRetryable) != null ? _p : isRetryableStatusCode2(statusCode), data: providerStreamError ? error.data : error }); } function inferExactMessageMetadata(message) { switch (message.trim().toLowerCase()) { case "overloaded": case "overloaded error": case "model overloaded": return { statusCode: 503, isRetryable: true }; case "internal server error": return { statusCode: 500, isRetryable: true }; case "service unavailable": return { statusCode: 503, isRetryable: true }; default: return; } } function isRetryableStatusCode2(statusCode) { return statusCode != null && (statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500); } function asRecord(value) { return typeof value === "object" && value != null ? value : void 0; } function isError(value) { return value instanceof Error || Object.prototype.toString.call(value) === "[object Error]"; } function getString(value) { return typeof value === "string" ? value : void 0; } function getStringOrNumber(value) { return typeof value === "string" || typeof value === "number" ? value : void 0; } function getBoolean(value) { return typeof value === "boolean" ? value : void 0; } function getHttpStatusCode(value) { const statusCode = typeof value === "string" && /^\d{3}$/.test(value) ? Number(value) : value; return typeof statusCode === "number" && Number.isInteger(statusCode) && statusCode >= 400 && statusCode <= 599 ? statusCode : void 0; } var originalGenerateId2 = createIdGenerator({ prefix: "aitxt", size: 24 }); var originalGenerateCallId2 = createIdGenerator({ prefix: "call", size: 24 }); async function streamLanguageModelCall({ model, tools, toolOrder, output, toolChoice, prompt, system, instructions, messages, allowSystemInMessages, download: download2, abortSignal, headers, includeRawChunks, providerOptions, repairToolCall, refineToolInput, executeLanguageModelCallInTelemetryContext = async ({ execute }) => await execute(), callId, toolsContext, experimental_sandbox: sandbox, _internal: { generateId: generateId5 = originalGenerateId2, generateCallId = originalGenerateCallId2, now: now2 = now } = {}, onStart, onLanguageModelCallStart, onLanguageModelCallEnd, ...callSettings }) { const resolvedModel = resolveLanguageModel(model); const effectiveCallId = callId != null ? callId : generateCallId(); const standardizedPrompt = await standardizePrompt({ instructions, system, prompt, messages, allowSystemInMessages }); const promptMessages = await convertToLanguageModelPrompt({ prompt: { instructions: standardizedPrompt.instructions, messages: standardizedPrompt.messages }, supportedUrls: await resolvedModel.supportedUrls, download: download2, abortSignal, provider: resolvedModel.provider.split(".")[0] }); const stepTools = await prepareTools$1({ tools, toolOrder, toolsContext, experimental_sandbox: sandbox }); const stepToolChoice = prepareToolChoice({ toolChoice }); await notify({ event: { promptMessages }, callbacks: onStart }); const languageModelCallStartEvent = { callId: effectiveCallId, provider: resolvedModel.provider, modelId: resolvedModel.modelId, instructions: standardizedPrompt.instructions, messages: standardizedPrompt.messages, tools: stepTools, ...callSettings }; await notify({ event: languageModelCallStartEvent, callbacks: onLanguageModelCallStart }); const callStartTimestampMs = now2(); const { stream: languageModelStream, response, request } = await executeLanguageModelCallInTelemetryContext({ ...languageModelCallStartEvent, execute: async () => await resolvedModel.doStream({ ...callSettings, tools: stepTools, toolChoice: stepToolChoice, responseFormat: await (output == null ? void 0 : output.responseFormat), prompt: promptMessages, providerOptions, abortSignal, headers, includeRawChunks }) }); return { stream: createAsyncIterableStream(languageModelStream.pipeThrough(createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({ tools, instructions: standardizedPrompt.instructions, messages: standardizedPrompt.messages, repairToolCall, refineToolInput, callId: effectiveCallId, provider: resolvedModel.provider, modelId: resolvedModel.modelId, toolChoice: stepToolChoice, generateId: generateId5, now: now2, callStartTimestampMs, onLanguageModelCallEnd }))), response, request }; } function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({ tools, instructions, messages, repairToolCall, refineToolInput, callId, provider, modelId, toolChoice, generateId: generateId5, now: now2, callStartTimestampMs, onLanguageModelCallEnd }) { const toolCallsByToolCallId = /* @__PURE__ */ new Map(); const modelCallContent = []; const rawModelCallContent = []; const textPartIndexes = /* @__PURE__ */ new Map(); const reasoningPartIndexes = /* @__PURE__ */ new Map(); const rawTextPartIndexes = /* @__PURE__ */ new Map(); const rawReasoningPartIndexes = /* @__PURE__ */ new Map(); let responseId = generateId5(); let responseModelId = modelId; let timeToFirstOutputMs; let previousOutputChunkTimestampMs; const timeBetweenOutputChunksMs = []; return new TransformStream({ async transform(chunk, controller) { var _a25, _b25, _c; if (isOutputChunk(chunk)) { const outputChunkTimestampMs = now2(); if (timeToFirstOutputMs == null) timeToFirstOutputMs = outputChunkTimestampMs - callStartTimestampMs; else if (previousOutputChunkTimestampMs != null) timeBetweenOutputChunksMs.push(outputChunkTimestampMs - previousOutputChunkTimestampMs); previousOutputChunkTimestampMs = outputChunkTimestampMs; } switch (chunk.type) { case "error": controller.enqueue({ type: "error", error: normalizeStreamProviderError(chunk.error) }); break; case "text-start": upsertTextContentPart({ content: modelCallContent, rawContent: rawModelCallContent, partIndexes: textPartIndexes, rawPartIndexes: rawTextPartIndexes, id: chunk.id, type: "text", providerMetadata: chunk.providerMetadata }); controller.enqueue(chunk); break; case "text-delta": upsertTextContentPart({ content: modelCallContent, rawContent: rawModelCallContent, partIndexes: textPartIndexes, rawPartIndexes: rawTextPartIndexes, id: chunk.id, type: "text", textDelta: chunk.delta, providerMetadata: chunk.providerMetadata }); controller.enqueue({ type: "text-delta", id: chunk.id, text: chunk.delta, providerMetadata: chunk.providerMetadata }); break; case "text-end": upsertTextContentPart({ content: modelCallContent, rawContent: rawModelCallContent, partIndexes: textPartIndexes, rawPartIndexes: rawTextPartIndexes, id: chunk.id, type: "text", providerMetadata: chunk.providerMetadata }); textPartIndexes.delete(chunk.id); rawTextPartIndexes.delete(chunk.id); controller.enqueue(chunk); break; case "reasoning-start": upsertTextContentPart({ content: modelCallContent, rawContent: rawModelCallContent, partIndexes: reasoningPartIndexes, rawPartIndexes: rawReasoningPartIndexes, id: chunk.id, type: "reasoning", providerMetadata: chunk.providerMetadata }); controller.enqueue(chunk); break; case "reasoning-delta": upsertTextContentPart({ content: modelCallContent, rawContent: rawModelCallContent, partIndexes: reasoningPartIndexes, rawPartIndexes: rawReasoningPartIndexes, id: chunk.id, type: "reasoning", textDelta: chunk.delta, providerMetadata: chunk.providerMetadata }); controller.enqueue({ type: "reasoning-delta", id: chunk.id, text: chunk.delta, providerMetadata: chunk.providerMetadata }); break; case "reasoning-end": upsertTextContentPart({ content: modelCallContent, rawContent: rawModelCallContent, partIndexes: reasoningPartIndexes, rawPartIndexes: rawReasoningPartIndexes, id: chunk.id, type: "reasoning", providerMetadata: chunk.providerMetadata }); reasoningPartIndexes.delete(chunk.id); rawReasoningPartIndexes.delete(chunk.id); controller.enqueue(chunk); break; case "file": case "reasoning-file": { const file = new DefaultGeneratedFileWithType({ data: chunk.data.type === "data" ? chunk.data.data : chunk.data.url.toString(), mediaType: chunk.mediaType }); modelCallContent.push({ type: chunk.type, file, ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {} }); rawModelCallContent.push(chunk); controller.enqueue({ type: chunk.type, file, providerMetadata: chunk.providerMetadata }); break; } case "finish": { const usage = asLanguageModelUsage(chunk.usage); const responseTimeMs = now2() - callStartTimestampMs; const performance = { responseTimeMs, effectiveOutputTokensPerSecond: calculateTokensPerSecond({ tokens: usage.outputTokens, durationMs: responseTimeMs }), outputTokensPerSecond: timeToFirstOutputMs == null ? void 0 : calculateTokensPerSecond({ tokens: usage.outputTokens, durationMs: responseTimeMs - timeToFirstOutputMs }), inputTokensPerSecond: timeToFirstOutputMs == null ? void 0 : calculateTokensPerSecond({ tokens: usage.inputTokens, durationMs: timeToFirstOutputMs }), effectiveTotalTokensPerSecond: calculateTokensPerSecond({ tokens: sumTokenCounts(usage.inputTokens, usage.outputTokens), durationMs: responseTimeMs }), timeToFirstOutputMs, timeBetweenOutputChunksMs: timeBetweenOutputChunksMs.length > 0 ? calculateOutputChunkTimingStats(timeBetweenOutputChunksMs) : void 0 }; await notify({ event: { callId, provider, modelId: responseModelId, finishReason: chunk.finishReason.unified, usage, content: modelCallContent, responseId, ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}, performance }, callbacks: onLanguageModelCallEnd }); controller.enqueue({ type: "model-call-end", finishReason: chunk.finishReason.unified, rawFinishReason: chunk.finishReason.raw, usage, providerMetadata: chunk.providerMetadata, performance }); const enforcedToolChoice = toolChoice.type === "required" || toolChoice.type === "tool" ? toolChoice : void 0; if (enforcedToolChoice != null && ![...toolCallsByToolCallId.values()].some((toolCall) => enforcedToolChoice.type === "required" || toolCall.toolName === enforcedToolChoice.toolName)) { controller.enqueue({ type: "error", error: new ToolChoiceViolationError({ toolChoice: enforcedToolChoice, finishReason: chunk.finishReason.unified, provider, modelId, content: rawModelCallContent }) }); break; } break; } case "tool-call": rawModelCallContent.push(chunk); try { const toolCall = await parseToolCall({ toolCall: chunk, tools, repairToolCall, refineToolInput, instructions, messages }); toolCallsByToolCallId.set(toolCall.toolCallId, toolCall); controller.enqueue(toolCall); modelCallContent.push(toolCall); if (toolCall.invalid) { if (!toolCall.providerExecuted) controller.enqueue({ type: "tool-error", toolCallId: toolCall.toolCallId, toolName: toolCall.toolName, input: toolCall.input, error: getErrorMessage(toolCall.error), dynamic: true, title: toolCall.title, ...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {} }); break; } } catch (error) { controller.enqueue({ type: "error", error }); } break; case "tool-approval-request": { rawModelCallContent.push(chunk); const toolCall = toolCallsByToolCallId.get(chunk.toolCallId); if (toolCall == null) { controller.enqueue({ type: "error", error: new ToolCallNotFoundForApprovalError({ toolCallId: chunk.toolCallId, approvalId: chunk.approvalId }) }); break; } const toolApprovalRequest = { type: "tool-approval-request", approvalId: chunk.approvalId, toolCall }; controller.enqueue(toolApprovalRequest); modelCallContent.push(toolApprovalRequest); break; } case "tool-result": { rawModelCallContent.push(chunk); const toolName = chunk.toolName; const toolCall = toolCallsByToolCallId.get(chunk.toolCallId); const toolResultPart = chunk.isError ? { type: "tool-error", toolCallId: chunk.toolCallId, toolName, input: toolCall == null ? void 0 : toolCall.input, providerExecuted: true, error: chunk.result, dynamic: chunk.dynamic, ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}, ...(toolCall == null ? void 0 : toolCall.toolMetadata) != null ? { toolMetadata: toolCall.toolMetadata } : {} } : { type: "tool-result", toolCallId: chunk.toolCallId, toolName, input: toolCall == null ? void 0 : toolCall.input, output: chunk.result, providerExecuted: true, dynamic: chunk.dynamic, ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}, ...(toolCall == null ? void 0 : toolCall.toolMetadata) != null ? { toolMetadata: toolCall.toolMetadata } : {} }; controller.enqueue(toolResultPart); modelCallContent.push(toolResultPart); break; } case "tool-input-start": { const tool3 = getOwn(tools, chunk.toolName); controller.enqueue({ ...chunk, dynamic: (_a25 = chunk.dynamic) != null ? _a25 : (tool3 == null ? void 0 : tool3.type) === "dynamic", title: tool3 == null ? void 0 : tool3.title, ...(tool3 == null ? void 0 : tool3.metadata) != null ? { toolMetadata: tool3.metadata } : {} }); break; } case "stream-start": controller.enqueue({ type: "model-call-start", warnings: chunk.warnings }); break; case "response-metadata": responseId = (_b25 = chunk.id) != null ? _b25 : responseId; responseModelId = (_c = chunk.modelId) != null ? _c : responseModelId; controller.enqueue({ type: "model-call-response-metadata", id: chunk.id, timestamp: chunk.timestamp, modelId: chunk.modelId }); break; default: if (chunk.type === "custom" || chunk.type === "source") { modelCallContent.push(chunk); rawModelCallContent.push(chunk); } controller.enqueue(chunk); } } }); } function isOutputChunk(chunk) { return chunk.type === "text-delta" && chunk.delta.length > 0 || chunk.type === "reasoning-delta" && chunk.delta.length > 0 || chunk.type === "tool-input-delta" && chunk.delta.length > 0 || chunk.type === "file" || chunk.type === "reasoning-file" || chunk.type === "tool-call"; } function calculateOutputChunkTimingStats(timingsMs) { const sortedTimingsMs = [...timingsMs].sort((a, b) => a - b); const sum = timingsMs.reduce((sum2, timingMs) => sum2 + timingMs, 0); return { min: sortedTimingsMs[0], p10: calculateNearestRankPercentile(sortedTimingsMs, .1), median: calculateNearestRankPercentile(sortedTimingsMs, .5), avg: sum / timingsMs.length, p90: calculateNearestRankPercentile(sortedTimingsMs, .9), max: sortedTimingsMs[sortedTimingsMs.length - 1] }; } function calculateNearestRankPercentile(sortedValues, percentile) { return sortedValues[Math.ceil(percentile * sortedValues.length) - 1]; } function upsertTextContentPart({ content, rawContent, partIndexes, rawPartIndexes, id, type, textDelta, providerMetadata }) { let partIndex = partIndexes.get(id); if (partIndex == null) { partIndex = content.push({ type, text: "", ...providerMetadata != null ? { providerMetadata } : {} }) - 1; partIndexes.set(id, partIndex); } let rawPartIndex = rawPartIndexes.get(id); if (rawPartIndex == null) { rawPartIndex = rawContent.push({ type, text: "", ...providerMetadata != null ? { providerMetadata } : {} }) - 1; rawPartIndexes.set(id, rawPartIndex); } const part = content[partIndex]; const rawPart = rawContent[rawPartIndex]; if (textDelta != null) { part.text += textDelta; rawPart.text += textDelta; } if (providerMetadata != null) { part.providerMetadata = providerMetadata; rawPart.providerMetadata = providerMetadata; } } var originalGenerateId3 = createIdGenerator({ prefix: "aitxt", size: 24 }); var originalGenerateCallId3 = createIdGenerator({ prefix: "call", size: 24 }); var isOutputChunkType = { file: true, custom: false, source: false, "text-start": false, "text-end": false, "text-delta": true, "reasoning-start": false, "reasoning-end": false, "reasoning-delta": true, "reasoning-file": true, "tool-input-start": false, "tool-input-end": false, "tool-input-delta": true, "tool-approval-request": false, "tool-approval-response": false, "tool-call": true, "tool-result": false, "tool-error": false, "tool-output-denied": false, "tool-execution-end": false, "model-call-start": false, "model-call-response-metadata": false, "model-call-end": false, error: false, raw: false }; function isOutputChunk2(chunk) { if (!isOutputChunkType[chunk.type]) return false; switch (chunk.type) { case "text-delta": case "reasoning-delta": return chunk.text.length > 0; case "tool-input-delta": return chunk.delta.length > 0; case "file": case "reasoning-file": case "tool-call": return true; default: return false; } } function streamText({ model, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries, streamRetries, abortSignal, timeout, headers, stopWhen = isStepCount(1), experimental_sandbox: sandbox, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, experimental_telemetry, telemetry = experimental_telemetry, prepareStep, providerOptions, activeTools, toolOrder, experimental_repairToolCall, repairToolCall = experimental_repairToolCall, experimental_refineToolInput: refineToolInput, experimental_transform: transform, experimental_download: download2, includeRawChunks, onChunk, onError: onErrorArg, onFinish, onEnd = onFinish, onAbort, onStepEnd, onStepFinish, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onLanguageModelCallStart, experimental_onLanguageModelCallStart, onLanguageModelCallEnd, experimental_onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, experimental_onToolCallStart, experimental_onToolCallFinish, runtimeContext = {}, toolsContext = {}, experimental_include, include = experimental_include, _internal: { now: now2 = now, generateId: generateId5 = originalGenerateId3, generateCallId = originalGenerateCallId3 } = {}, ...settings }) { var _a25, _b25, _c, _d; const totalTimeoutMs = getTotalTimeoutMs(timeout); const stepTimeoutMs = getStepTimeoutMs(timeout); const firstChunkTimeoutMs = getFirstChunkTimeoutMs(timeout); const chunkTimeoutMs = getChunkTimeoutMs(timeout); const stepAbortController = stepTimeoutMs != null ? new AbortController() : void 0; const firstChunkAbortController = firstChunkTimeoutMs != null ? new AbortController() : void 0; const chunkAbortController = chunkTimeoutMs != null ? new AbortController() : void 0; const onError = onErrorArg != null ? onErrorArg : (({ error }) => { console.error(error); }); const resolvedOnStart = onStart != null ? onStart : experimental_onStart; const resolvedOnStepStart = onStepStart != null ? onStepStart : experimental_onStepStart; const resolvedOnLanguageModelCallStart = onLanguageModelCallStart != null ? onLanguageModelCallStart : experimental_onLanguageModelCallStart; const resolvedOnLanguageModelCallEnd = onLanguageModelCallEnd != null ? onLanguageModelCallEnd : experimental_onLanguageModelCallEnd; const resolvedOnToolExecutionStart = onToolExecutionStart != null ? onToolExecutionStart : experimental_onToolCallStart; const resolvedOnToolExecutionEnd = onToolExecutionEnd != null ? onToolExecutionEnd : experimental_onToolCallFinish; const resolvedOnStepEnd = onStepEnd != null ? onStepEnd : onStepFinish; return new DefaultStreamTextResult({ model: resolveLanguageModel(model), telemetry, headers, settings, maxRetries, streamRetries, abortSignal: mergeAbortSignals(abortSignal, totalTimeoutMs, stepAbortController == null ? void 0 : stepAbortController.signal, firstChunkAbortController == null ? void 0 : firstChunkAbortController.signal, chunkAbortController == null ? void 0 : chunkAbortController.signal), stepTimeoutMs, stepAbortController, firstChunkTimeoutMs, firstChunkAbortController, chunkTimeoutMs, chunkAbortController, instructions, system, prompt, messages, allowSystemInMessages, experimental_sandbox: sandbox, tools, toolsContext, runtimeContext, toolChoice, transforms: asArray(transform), activeTools, toolOrder, repairToolCall, refineToolInput, stopConditions: asArray(stopWhen), output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, providerOptions, prepareStep, timeout, onChunk, onError, canRetryStreamViaOnError: streamRetries !== void 0 && onErrorArg != null, onEnd, onAbort, onStepFinish: resolvedOnStepEnd, onStart: resolvedOnStart, onStepStart: resolvedOnStepStart, onLanguageModelCallStart: resolvedOnLanguageModelCallStart, onLanguageModelCallEnd: resolvedOnLanguageModelCallEnd, onToolExecutionStart: resolvedOnToolExecutionStart, onToolExecutionEnd: resolvedOnToolExecutionEnd, now: now2, generateId: generateId5, generateCallId, download: download2, include: { requestBody: (_a25 = include == null ? void 0 : include.requestBody) != null ? _a25 : false, requestMessages: (_b25 = include == null ? void 0 : include.requestMessages) != null ? _b25 : false, rawChunks: (_d = (_c = include == null ? void 0 : include.rawChunks) != null ? _c : includeRawChunks) != null ? _d : false } }); } var streamRetryBoundarySymbol = /* @__PURE__ */ Symbol("streamRetryBoundary"); function isStreamRetryBoundaryPart(part) { return streamRetryBoundarySymbol in part; } async function markPromiseAsHandled(promise) { try { await promise; } catch (e) {} } function createOutputTransformStream(output) { let firstTextChunkId = void 0; let text2 = ""; let textChunk = ""; let textProviderMetadata = void 0; let lastPublishedValue = void 0; let hasPublishedValue = false; function resetOutputState() { firstTextChunkId = void 0; text2 = ""; textChunk = ""; textProviderMetadata = void 0; lastPublishedValue = void 0; hasPublishedValue = false; } function enqueueChunk({ controller, chunk }) { controller.enqueue(chunk); } function publishTextChunk({ controller, partialOutput = void 0 }) { enqueueChunk({ controller, chunk: { part: { type: "text-delta", id: firstTextChunkId, text: textChunk, providerMetadata: textProviderMetadata }, partialOutput } }); textChunk = ""; } return new TransformStream({ async transform(chunk, controller) { var _a25; if (isStreamRetryBoundaryPart(chunk)) { resetOutputState(); controller.enqueue(chunk); return; } if (chunk.type === "start-step") resetOutputState(); if (chunk.type === "finish-step" && textChunk.length > 0) publishTextChunk({ controller }); if (chunk.type !== "text-delta" && chunk.type !== "text-start" && chunk.type !== "text-end") { enqueueChunk({ controller, chunk: { part: chunk, partialOutput: void 0 } }); return; } if (firstTextChunkId == null) firstTextChunkId = chunk.id; else if (chunk.id !== firstTextChunkId) { enqueueChunk({ controller, chunk: { part: chunk, partialOutput: void 0 } }); return; } if (chunk.type === "text-start") { enqueueChunk({ controller, chunk: { part: chunk, partialOutput: void 0 } }); return; } if (chunk.type === "text-end") { if (textChunk.length > 0) publishTextChunk({ controller }); enqueueChunk({ controller, chunk: { part: chunk, partialOutput: void 0 } }); return; } text2 += chunk.text; textChunk += chunk.text; textProviderMetadata = (_a25 = chunk.providerMetadata) != null ? _a25 : textProviderMetadata; if (chunk.text.length === 0 && chunk.providerMetadata != null) { enqueueChunk({ controller, chunk: { part: chunk, partialOutput: void 0 } }); return; } const result = await output.parsePartialOutput({ text: text2 }); if (result !== void 0) { const currentValue = typeof result.partial === "string" ? result.partial : JSON.stringify(result.partial); if (!hasPublishedValue || currentValue !== lastPublishedValue) { publishTextChunk({ controller, partialOutput: result.partial }); lastPublishedValue = currentValue; hasPublishedValue = true; } } } }); } function applyStreamTextTransforms({ stream, transforms, tools, stopStream }) { const sourceReader = stream.getReader(); let sourceDone = false; let pendingBoundary; let transformedSegmentReader; const createTransformedSegmentReader = () => { let segment = new ReadableStream({ async pull(controller) { const { done, value } = await sourceReader.read(); if (done) { sourceDone = true; controller.close(); return; } if (isStreamRetryBoundaryPart(value)) { pendingBoundary = value; controller.close(); return; } controller.enqueue(value); }, cancel(reason) { return sourceReader.cancel(reason); } }, { highWaterMark: 0 }); for (const transform of transforms) segment = segment.pipeThrough(transform({ tools, stopStream })); return segment.getReader(); }; return new ReadableStream({ async pull(controller) { transformedSegmentReader ??= createTransformedSegmentReader(); const { done, value } = await transformedSegmentReader.read(); if (!done) { controller.enqueue(value); return; } transformedSegmentReader = void 0; if (pendingBoundary != null) { controller.enqueue(pendingBoundary); pendingBoundary = void 0; return; } if (sourceDone) controller.close(); }, async cancel(reason) { await (transformedSegmentReader == null ? void 0 : transformedSegmentReader.cancel(reason)); await sourceReader.cancel(reason); } }); } var DefaultStreamTextResult = class { constructor({ model, telemetry, headers, settings, maxRetries: maxRetriesArg, streamRetries: streamRetriesArg, abortSignal, stepTimeoutMs, stepAbortController, firstChunkTimeoutMs, firstChunkAbortController, chunkTimeoutMs, chunkAbortController, instructions, system, prompt, messages, allowSystemInMessages, experimental_sandbox: sandbox, tools, toolChoice, transforms, activeTools, toolOrder, repairToolCall, refineToolInput, stopConditions, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, providerOptions, prepareStep, now: now2, generateId: generateId5, generateCallId, timeout, onChunk, onError, canRetryStreamViaOnError, onEnd, onAbort, onStepFinish, onStart, onStepStart, onLanguageModelCallStart, onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, runtimeContext, toolsContext, download: download2, include }) { this._totalUsage = new DelayedPromise(); this._finishReason = new DelayedPromise(); this._rawFinishReason = new DelayedPromise(); this._steps = new DelayedPromise(); this._initialResponseMessages = new DelayedPromise(); this.outputSpecification = output; this.tools = tools; const resolvedToolCallers = resolveToolCallerConfiguration({ tools, toolCallers: experimental_toolCallers }); const prepareToolSearch = createToolSearchState({ tools, toolCallers: resolvedToolCallers }); const telemetryDispatcher = createRestrictedTelemetryDispatcher({ telemetry, includeRuntimeContext: telemetry == null ? void 0 : telemetry.includeRuntimeContext, includeToolsContext: telemetry == null ? void 0 : telemetry.includeToolsContext }); let stepFinish; let recordedContent = []; let recordedFinishReason = void 0; let recordedRawFinishReason = void 0; let recordedTotalUsage = void 0; let recordedRequest = {}; let recordedRequestMessages = []; let recordedWarnings = []; const recordedSteps = []; const initialResponseMessages = []; let stepMessagesForNextStep; let currentStepMessages = []; let isAborted = false; let currentStepModel = model; const createPartIdReserver = () => { const usedIds = /* @__PURE__ */ new Set(); return (id) => { if (!usedIds.has(id)) { usedIds.add(id); return id; } const generatedId = generateId5(); let uniqueId = generatedId; let suffix = 0; while (usedIds.has(uniqueId)) uniqueId = `${generatedId}-${++suffix}`; usedIds.add(uniqueId); return uniqueId; }; }; const reserveTextPartId = createPartIdReserver(); const reserveReasoningPartId = createPartIdReserver(); const pendingDeferredToolCalls = /* @__PURE__ */ new Map(); let activeTextContent = createIdMap(); let activeReasoningContent = createIdMap(); let recordedNoOutputError; const errorsHandledForStreamRetry = /* @__PURE__ */ new Set(); const eventProcessor = new TransformStream({ async transform(chunk, controller) { var _a25, _b25, _c, _d, _e; if (isStreamRetryBoundaryPart(chunk)) { const retryBoundary = chunk[streamRetryBoundarySymbol]; recordedContent = []; activeReasoningContent = createIdMap(); activeTextContent = createIdMap(); recordedRequest = retryBoundary.request; recordedRequestMessages = (_a25 = retryBoundary.request.messages) != null ? _a25 : []; recordedWarnings = retryBoundary.warnings; return; } const { part } = chunk; controller.enqueue(chunk); const callbacksHandledForStreamRetry = part.type === "error" && errorsHandledForStreamRetry.has(part.error); if (!callbacksHandledForStreamRetry) await notify({ event: { chunk: part }, callbacks: onChunk }); if (part.type === "error") { const error = wrapGatewayError(part.error); if (NoOutputGeneratedError.isInstance(error)) recordedNoOutputError = error; if (callbacksHandledForStreamRetry) errorsHandledForStreamRetry.delete(part.error); else await notify({ event: { error }, callbacks: async (event) => { await onError(event); } }); } if (part.type === "custom" || part.type === "source" || part.type === "tool-call" || part.type === "tool-approval-request" || part.type === "tool-approval-response" || part.type === "tool-error") recordedContent.push(part); if (part.type === "text-start") { activeTextContent[part.id] = { type: "text", text: "", providerMetadata: part.providerMetadata }; recordedContent.push(activeTextContent[part.id]); } if (part.type === "text-delta") { const activeText = activeTextContent[part.id]; if (activeText == null) { controller.enqueue({ part: { type: "error", error: `text part ${part.id} not found` }, partialOutput: void 0 }); return; } activeText.text += part.text; activeText.providerMetadata = (_b25 = part.providerMetadata) != null ? _b25 : activeText.providerMetadata; } if (part.type === "text-end") { const activeText = activeTextContent[part.id]; if (activeText == null) { controller.enqueue({ part: { type: "error", error: `text part ${part.id} not found` }, partialOutput: void 0 }); return; } activeText.providerMetadata = (_c = part.providerMetadata) != null ? _c : activeText.providerMetadata; delete activeTextContent[part.id]; } if (part.type === "reasoning-start") { activeReasoningContent[part.id] = { type: "reasoning", text: "", providerMetadata: part.providerMetadata }; recordedContent.push(activeReasoningContent[part.id]); } if (part.type === "reasoning-delta") { const activeReasoning = activeReasoningContent[part.id]; if (activeReasoning == null) { controller.enqueue({ part: { type: "error", error: `reasoning part ${part.id} not found` }, partialOutput: void 0 }); return; } activeReasoning.text += part.text; activeReasoning.providerMetadata = (_d = part.providerMetadata) != null ? _d : activeReasoning.providerMetadata; } if (part.type === "reasoning-end") { const activeReasoning = activeReasoningContent[part.id]; if (activeReasoning == null) { controller.enqueue({ part: { type: "error", error: `reasoning part ${part.id} not found` }, partialOutput: void 0 }); return; } activeReasoning.providerMetadata = (_e = part.providerMetadata) != null ? _e : activeReasoning.providerMetadata; delete activeReasoningContent[part.id]; } if (part.type === "file" || part.type === "reasoning-file") recordedContent.push({ type: part.type, file: part.file, ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {} }); if (part.type === "tool-result" && !part.preliminary) recordedContent.push(part); if (part.type === "start-step") { recordedContent = []; activeReasoningContent = createIdMap(); activeTextContent = createIdMap(); recordedRequest = part.request; recordedWarnings = part.warnings; } if (part.type === "finish-step") { const stepResponseMessages = await toResponseMessages({ content: recordedContent, tools }); const currentStepResult = new DefaultStepResult({ callId, stepNumber: recordedSteps.length, provider: currentStepModel.provider, modelId: currentStepModel.modelId, runtimeContext, toolsContext, content: recordedContent, finishReason: part.finishReason, rawFinishReason: part.rawFinishReason, usage: part.usage, performance: part.performance, warnings: recordedWarnings, request: { ...recordedRequest, messages: include.requestMessages ? cloneModelMessages(recordedRequestMessages) : void 0 }, response: { ...part.response, messages: cloneModelMessages(stepResponseMessages) }, providerMetadata: part.providerMetadata }); await notify({ event: currentStepResult, callbacks: [onStepFinish, telemetryDispatcher.onStepEnd] }); logWarnings({ warnings: recordedWarnings, provider: currentStepModel.provider, model: currentStepModel.modelId }); recordedSteps.push(currentStepResult); stepMessagesForNextStep = [...currentStepMessages, ...stepResponseMessages]; stepFinish.resolve(); } if (part.type === "finish") { recordedTotalUsage = part.totalUsage; recordedFinishReason = part.finishReason; recordedRawFinishReason = part.rawFinishReason; } }, async flush(controller) { try { if (recordedSteps.length === 0 || recordedNoOutputError != null) { const error = (abortSignal == null ? void 0 : abortSignal.aborted) ? abortSignal.reason : recordedNoOutputError != null ? recordedNoOutputError : new NoOutputGeneratedError({ message: "No output generated. Check the stream for errors." }); self.rejectResultPromises(error); return; } const finishReason = recordedFinishReason != null ? recordedFinishReason : "other"; const totalUsage = recordedTotalUsage != null ? recordedTotalUsage : createNullLanguageModelUsage(); self._finishReason.resolve(finishReason); self._rawFinishReason.resolve(recordedRawFinishReason); self._totalUsage.resolve(totalUsage); self._steps.resolve(recordedSteps); if (isAborted) return; const finalStep = recordedSteps[recordedSteps.length - 1]; const content = recordedSteps.flatMap((step) => step.content); const files = recordedSteps.flatMap((step) => step.files); const sources = recordedSteps.flatMap((step) => step.sources); const toolCalls = recordedSteps.flatMap((step) => step.toolCalls); const staticToolCalls = recordedSteps.flatMap((step) => step.staticToolCalls); const dynamicToolCalls = recordedSteps.flatMap((step) => step.dynamicToolCalls); const toolResults = recordedSteps.flatMap((step) => step.toolResults); const staticToolResults = recordedSteps.flatMap((step) => step.staticToolResults); const dynamicToolResults = recordedSteps.flatMap((step) => step.dynamicToolResults); const warnings = recordedSteps.flatMap((step) => { var _a25; return (_a25 = step.warnings) != null ? _a25 : []; }); const onEndWithOutput = onEnd == null ? void 0 : async (event) => { const parsedOutput = output == null ? void 0 : await self.getOutputPromise().catch(() => void 0); await onEnd({ ...event, ...output != null ? { output: parsedOutput } : {} }); }; const onEndEvent = { callId, toolsContext: finalStep.toolsContext, stepNumber: finalStep.stepNumber, model: finalStep.model, runtimeContext: finalStep.runtimeContext, finishReason: finalStep.finishReason, rawFinishReason: finalStep.rawFinishReason, usage: totalUsage, totalUsage, content, text: finalStep.text, reasoning: finalStep.reasoning, reasoningText: finalStep.reasoningText, files, sources, toolCalls, staticToolCalls, dynamicToolCalls, toolResults, staticToolResults, dynamicToolResults, responseMessages: [...initialResponseMessages, ...recordedSteps.flatMap((step) => step.response.messages)], warnings, request: finalStep.request, response: finalStep.response, providerMetadata: finalStep.providerMetadata, steps: recordedSteps, finalStep }; await Promise.all([notify({ event: onEndEvent, callbacks: onEndWithOutput }), notify({ event: onEndEvent, callbacks: telemetryDispatcher.onEnd })]); } catch (error) { controller.error(error); } } }); const stitchableStream = createStitchableStream(); this.addStream = stitchableStream.addStream; this.closeStream = stitchableStream.close; const reader = stitchableStream.stream.getReader(); let stream = new ReadableStream({ async start(controller) { controller.enqueue({ type: "start" }); }, async pull(controller) { var _a25; async function abort() { isAborted = true; await notify({ event: { callId, steps: recordedSteps, ...(abortSignal == null ? void 0 : abortSignal.reason) !== void 0 ? { reason: abortSignal.reason } : {} }, callbacks: [onAbort, telemetryDispatcher.onAbort] }); controller.enqueue({ type: "abort", ...(abortSignal == null ? void 0 : abortSignal.reason) !== void 0 ? { reason: getErrorMessage(abortSignal.reason) } : {} }); controller.close(); } try { const { done, value } = await reader.read(); if (done) { controller.close(); return; } if (abortSignal == null ? void 0 : abortSignal.aborted) { await abort(); return; } controller.enqueue(value); } catch (error) { if (isAbortError(error) && (abortSignal == null ? void 0 : abortSignal.aborted)) await abort(); else { await ((_a25 = telemetryDispatcher.onError) == null ? void 0 : _a25.call(telemetryDispatcher, { callId, error })); controller.error(error); } } }, cancel(reason) { return stitchableStream.stream.cancel(reason); } }); let isRunning = true; stream = stream.pipeThrough(new TransformStream({ async transform(chunk, controller) { if (isRunning) controller.enqueue(chunk); } })); stream = applyStreamTextTransforms({ stream, transforms, tools, stopStream() { stitchableStream.terminate(); isRunning = false; } }); this.baseStream = stream.pipeThrough(createOutputTransformStream(output != null ? output : text())).pipeThrough(eventProcessor); const { maxRetries } = prepareRetries({ maxRetries: maxRetriesArg, abortSignal }); const { maxRetries: streamRetries } = prepareRetries({ maxRetries: streamRetriesArg, abortSignal, parameter: "streamRetries", defaultMaxRetries: 0 }); const callSettings = prepareLanguageModelCallOptions(settings); const self = this; const callId = generateCallId(); (async () => { var _a25; const initialPrompt = await standardizePrompt({ instructions, system, prompt, messages, allowSystemInMessages }); const startEvent = { callId, operationId: "ai.streamText", provider: model.provider, modelId: model.modelId, instructions: initialPrompt.instructions, messages: initialPrompt.messages, tools, toolChoice, activeTools, toolOrder, maxOutputTokens: callSettings.maxOutputTokens, temperature: callSettings.temperature, topP: callSettings.topP, topK: callSettings.topK, presencePenalty: callSettings.presencePenalty, frequencyPenalty: callSettings.frequencyPenalty, stopSequences: callSettings.stopSequences, seed: callSettings.seed, reasoning: callSettings.reasoning, maxRetries, timeout, headers, providerOptions, output, runtimeContext, toolsContext }; const streamTextTracingChannelContext = (_a25 = telemetryDispatcher.startTracingChannelContext) == null ? void 0 : _a25.call(telemetryDispatcher, { type: "streamText", event: startEvent, completion: self._totalUsage.promise.then(() => void 0) }); const runInStreamTextTracingChannelContext = (execute) => { var _a26; return (_a26 = streamTextTracingChannelContext == null ? void 0 : streamTextTracingChannelContext.run(execute)) != null ? _a26 : execute(); }; const runInTracingChannelSpanInStreamText = telemetryDispatcher.runInTracingChannelSpan == null ? void 0 : (options) => runInStreamTextTracingChannelContext(() => telemetryDispatcher.runInTracingChannelSpan(options)); await notify({ event: startEvent, callbacks: [onStart, telemetryDispatcher.onStart] }); const initialMessages = initialPrompt.messages; let instructionsForNextStep = initialPrompt.instructions; const { approvedToolApprovals, deniedToolApprovals } = collectToolApprovals({ messages: initialMessages }); if (deniedToolApprovals.length > 0 || approvedToolApprovals.length > 0) { const { approvedToolApprovals: localApprovedToolApprovals, deniedToolApprovals: revalidationDeniedToolApprovals, invalidToolApprovals } = await validateApprovedToolApprovals({ approvedToolApprovals: approvedToolApprovals.filter((toolApproval2) => !toolApproval2.toolCall.providerExecuted), tools, toolApproval, messages: initialMessages, toolsContext, runtimeContext, toolApprovalSecret: experimental_toolApprovalSecret }); const localDeniedToolApprovals = [...deniedToolApprovals.filter((toolApproval2) => !toolApproval2.toolCall.providerExecuted), ...revalidationDeniedToolApprovals]; const localDeniedToolApprovalsWithoutResults = localDeniedToolApprovals.filter((toolApproval2) => toolApproval2.existingToolResult == null); const deniedProviderExecutedToolApprovals = deniedToolApprovals.filter((toolApproval2) => toolApproval2.toolCall.providerExecuted); let toolExecutionStepStreamController; const toolExecutionStepStream = new ReadableStream({ start(controller) { toolExecutionStepStreamController = controller; } }); self.addStream(toolExecutionStepStream); try { for (const toolApproval2 of [...localDeniedToolApprovals, ...deniedProviderExecutedToolApprovals]) toolExecutionStepStreamController?.enqueue({ type: "tool-output-denied", toolCallId: toolApproval2.toolCall.toolCallId, toolName: toolApproval2.toolCall.toolName }); for (const toolApproval2 of invalidToolApprovals) toolExecutionStepStreamController?.enqueue({ type: "tool-error", toolCallId: toolApproval2.toolCall.toolCallId, toolName: toolApproval2.toolCall.toolName, input: toolApproval2.toolCall.input, error: getErrorMessage(toolApproval2.error), title: toolApproval2.toolCall.title, ...toolApproval2.toolCall.dynamic === true ? { dynamic: true } : {}, ...toolApproval2.toolCall.toolMetadata != null ? { toolMetadata: toolApproval2.toolCall.toolMetadata } : {} }); const toolOutputs = []; await Promise.all(localApprovedToolApprovals.map(async (toolApproval2) => { const result = await executeToolCall({ toolCall: toolApproval2.toolCall, tools, callId, messages: initialMessages, abortSignal, timeout, experimental_sandbox: sandbox, toolsContext, onToolExecutionStart: filterNullable(onToolExecutionStart, telemetryDispatcher.onToolExecutionStart), onToolExecutionEnd: filterNullable(onToolExecutionEnd, telemetryDispatcher.onToolExecutionEnd), executeToolInTelemetryContext: telemetryDispatcher.executeTool, runInTracingChannelSpan: runInTracingChannelSpanInStreamText, onPreliminaryToolResult: (result2) => { toolExecutionStepStreamController?.enqueue(result2); } }); if (result != null) { toolExecutionStepStreamController?.enqueue(result.output); toolOutputs.push(result.output); } })); if (toolOutputs.length > 0 || localDeniedToolApprovalsWithoutResults.length > 0 || invalidToolApprovals.length > 0) { const localToolContent = []; for (const output2 of toolOutputs) localToolContent.push({ type: "tool-result", toolCallId: output2.toolCallId, toolName: output2.toolName, output: await createToolModelOutput({ toolCallId: output2.toolCallId, input: output2.input, tool: getOwn(tools, output2.toolName), output: output2.type === "tool-result" ? output2.output : output2.error, errorMode: output2.type === "tool-error" ? "text" : "none" }) }); for (const toolApproval2 of invalidToolApprovals) localToolContent.push({ type: "tool-result", toolCallId: toolApproval2.toolCall.toolCallId, toolName: toolApproval2.toolCall.toolName, output: await createToolModelOutput({ toolCallId: toolApproval2.toolCall.toolCallId, input: toolApproval2.toolCall.input, tool: getOwn(tools, toolApproval2.toolCall.toolName), output: toolApproval2.error, errorMode: "text" }) }); for (const toolApproval2 of localDeniedToolApprovalsWithoutResults) localToolContent.push({ type: "tool-result", toolCallId: toolApproval2.toolCall.toolCallId, toolName: toolApproval2.toolCall.toolName, output: { type: "execution-denied", reason: toolApproval2.approvalResponse.reason } }); initialResponseMessages.push({ role: "tool", content: localToolContent }); } } finally { toolExecutionStepStreamController?.close(); } } self._initialResponseMessages.resolve(initialResponseMessages); async function streamStep({ currentStep, usage }) { var _a26, _b25, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l; const stepTimeoutId = setAbortTimeout({ abortController: stepAbortController, label: "Step", timeoutMs: stepTimeoutMs }); let firstChunkTimeoutId = void 0; function startFirstChunkTimeout() { if (abortSignal == null ? void 0 : abortSignal.aborted) return; firstChunkTimeoutId = setAbortTimeout({ abortController: firstChunkAbortController, label: "First chunk", timeoutMs: firstChunkTimeoutMs }); } function clearFirstChunkTimeout() { if (firstChunkTimeoutId != null) { clearTimeout(firstChunkTimeoutId); firstChunkTimeoutId = void 0; } } let chunkTimeoutId = void 0; function resetChunkTimeout() { if (chunkTimeoutId != null) clearTimeout(chunkTimeoutId); chunkTimeoutId = setAbortTimeout({ abortController: chunkAbortController, label: "Chunk", timeoutMs: chunkTimeoutMs }); } function clearChunkTimeout() { if (chunkTimeoutId != null) { clearTimeout(chunkTimeoutId); chunkTimeoutId = void 0; } } function clearStepTimeout() { if (stepTimeoutId != null) clearTimeout(stepTimeoutId); } function clearStepTimeouts() { clearStepTimeout(); clearFirstChunkTimeout(); clearChunkTimeout(); } function cleanupStepTimeouts() { abortSignal?.removeEventListener("abort", cleanupStepTimeouts); clearStepTimeouts(); } abortSignal?.addEventListener("abort", cleanupStepTimeouts, { once: true }); try { stepFinish = new DelayedPromise(); const stepTracingChannelContext = (_a26 = telemetryDispatcher.startTracingChannelContext) == null ? void 0 : _a26.call(telemetryDispatcher, { type: "step", event: { callId, stepNumber: currentStep }, completion: stepFinish.promise }); const runInStepTracingChannelContext = (execute) => { var _a27; return (_a27 = stepTracingChannelContext == null ? void 0 : stepTracingChannelContext.run(execute)) != null ? _a27 : execute(); }; const responseMessagesFromPreviousSteps = recordedSteps.flatMap((step) => step.response.messages); const accumulatedResponseMessages = [...initialResponseMessages, ...responseMessagesFromPreviousSteps]; const stepInputMessages = stepMessagesForNextStep != null ? stepMessagesForNextStep : [...initialMessages, ...initialResponseMessages]; const prepareStepResult = await (prepareStep == null ? void 0 : prepareStep({ model, steps: recordedSteps, stepNumber: recordedSteps.length, instructions: instructionsForNextStep, initialInstructions: initialPrompt.instructions, messages: stepInputMessages, initialMessages, responseMessages: accumulatedResponseMessages, toolsContext, runtimeContext, experimental_sandbox: sandbox })); const stepSandbox = (_b25 = prepareStepResult == null ? void 0 : prepareStepResult.experimental_sandbox) != null ? _b25 : sandbox; runtimeContext = (_c = prepareStepResult == null ? void 0 : prepareStepResult.runtimeContext) != null ? _c : runtimeContext; toolsContext = (_d = prepareStepResult == null ? void 0 : prepareStepResult.toolsContext) != null ? _d : toolsContext; const stepModel = resolveLanguageModel((_e = prepareStepResult == null ? void 0 : prepareStepResult.model) != null ? _e : model); currentStepModel = stepModel; const stepActiveTools = filterActiveTools({ tools, activeTools: (_f = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _f : activeTools }); const { executionTools: stepExecutionTools, modelTools: stepModelTools, toolCallerMessages } = prepareToolsForToolCallers({ tools: prepareToolSearch(stepActiveTools, { toolsContext, experimental_sandbox: stepSandbox }), toolCallers: resolvedToolCallers }); const stepToolOrder = (_g = prepareStepResult == null ? void 0 : prepareStepResult.toolOrder) != null ? _g : toolOrder; const stepTools = await prepareTools$1({ tools: stepModelTools, toolOrder: stepToolOrder, toolsContext, experimental_sandbox: stepSandbox }); const stepToolChoice = prepareToolChoice({ toolChoice: (_h = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _h : toolChoice }); const stepMessages = appendToolCallerMessages({ messages: (_i = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _i : stepInputMessages, toolCallerMessages }); currentStepMessages = stepMessages; const stepInstructions = (_k = (_j = prepareStepResult == null ? void 0 : prepareStepResult.instructions) != null ? _j : prepareStepResult == null ? void 0 : prepareStepResult.system) != null ? _k : instructionsForNextStep; instructionsForNextStep = stepInstructions; const stepProviderOptions = mergeObjects(providerOptions, prepareStepResult == null ? void 0 : prepareStepResult.providerOptions); const stepCallSettings = prepareStepCallSettings({ callSettings, stepSettings: prepareStepResult }); const stepStartTimestampMs = now2(); const { retry } = prepareRetries({ maxRetries, abortSignal }); let hasNotifiedStepStart = false; const callLanguageModel = () => runInStepTracingChannelContext(() => retry(async () => { var _a27, _b26; return streamLanguageModelCall({ model: (_a27 = prepareStepResult == null ? void 0 : prepareStepResult.model) != null ? _a27 : model, tools: stepModelTools, toolOrder: stepToolOrder, toolChoice: (_b26 = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _b26 : toolChoice, instructions: stepInstructions, messages: stepMessages, allowSystemInMessages, repairToolCall, refineToolInput, abortSignal, headers, includeRawChunks: include.rawChunks, providerOptions: stepProviderOptions, download: download2, output, callId, executeLanguageModelCallInTelemetryContext: telemetryDispatcher.executeLanguageModelCall, toolsContext, experimental_sandbox: stepSandbox, onLanguageModelCallStart: filterNullable(onLanguageModelCallStart, telemetryDispatcher.onLanguageModelCallStart), onLanguageModelCallEnd: filterNullable(onLanguageModelCallEnd, telemetryDispatcher.onLanguageModelCallEnd), onStart: async ({ promptMessages }) => { var _a28, _b27; if (hasNotifiedStepStart) return; hasNotifiedStepStart = true; await notify({ event: { callId, provider: stepModel.provider, modelId: stepModel.modelId, stepNumber: recordedSteps.length, instructions: stepInstructions, messages: stepMessages, tools, toolChoice: (_a28 = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _a28 : toolChoice, activeTools: (_b27 = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _b27 : activeTools, toolOrder: stepToolOrder, steps: [...recordedSteps], providerOptions: stepProviderOptions, runtimeContext, toolsContext, output, promptMessages, stepTools, stepToolChoice }, callbacks: [onStepStart, telemetryDispatcher.onStepStart] }); }, _internal: { now: now2 }, ...stepCallSettings }); })); const initialLanguageModelCall = await callLanguageModel(); let request = initialLanguageModelCall.request; let response = initialLanguageModelCall.response; let languageModelStreamReader = initialLanguageModelCall.stream.getReader(); let automaticStreamRetryCount = 0; let callbackStreamRetryCount = 0; let bufferedAttemptParts = []; const outputChunksHandledBeforeBuffering = /* @__PURE__ */ new WeakSet(); const openTextParts = /* @__PURE__ */ new Set(); const openReasoningParts = /* @__PURE__ */ new Set(); let enqueueStreamRetryAttemptBoundary = false; const shouldBufferToolParts = streamRetries > 0 || canRetryStreamViaOnError; const languageModelStream = new ReadableStream({ async pull(controller) { const enqueueAttemptPart = (part) => { switch (part.type) { case "text-start": openTextParts.add(part.id); break; case "text-end": openTextParts.delete(part.id); break; case "reasoning-start": openReasoningParts.add(part.id); break; case "reasoning-end": openReasoningParts.delete(part.id); } controller.enqueue(part); }; const flushBufferedAttemptParts = () => { for (const part of bufferedAttemptParts) enqueueAttemptPart(part); bufferedAttemptParts = []; }; const closeOpenAttemptParts = () => { for (const id of openTextParts) controller.enqueue({ type: "text-end", id }); openTextParts.clear(); for (const id of openReasoningParts) controller.enqueue({ type: "reasoning-end", id }); openReasoningParts.clear(); }; while (true) { const { done, value } = await languageModelStreamReader.read(); if (enqueueStreamRetryAttemptBoundary) { controller.enqueue(createStreamRetryAttemptBoundaryPart({ warnings: !done && value.type === "model-call-start" ? value.warnings : [] })); enqueueStreamRetryAttemptBoundary = false; } if (done) { flushBufferedAttemptParts(); controller.close(); return; } const isToolPart = value.type === "tool-input-start" || value.type === "tool-input-delta" || value.type === "tool-input-end" || value.type === "tool-call" || value.type === "tool-approval-request" || value.type === "tool-approval-response" || value.type === "tool-result" || value.type === "tool-error"; if (value.type === "model-call-end") { flushBufferedAttemptParts(); enqueueAttemptPart(value); return; } if (shouldBufferToolParts && value.type !== "error" && (isToolPart || bufferedAttemptParts.length > 0)) { if (isOutputChunk2(value)) { clearFirstChunkTimeout(); resetChunkTimeout(); outputChunksHandledBeforeBuffering.add(value); } bufferedAttemptParts.push(value); continue; } if (value.type !== "error") { enqueueAttemptPart(value); return; } await notify({ event: { chunk: value }, callbacks: onChunk }); const error = wrapGatewayError(value.error); const isToolChoiceViolation = ToolChoiceViolationError.isInstance(error); let onErrorResult; try { onErrorResult = await onError({ error }); } catch (e) {} const callbackRequestedRetry = canRetryStreamViaOnError && typeof onErrorResult === "object" && onErrorResult != null && "retry" in onErrorResult && onErrorResult.retry === true; const automaticRetry = !isToolChoiceViolation && automaticStreamRetryCount < streamRetries; if (!automaticRetry && !(!isToolChoiceViolation && !automaticRetry && callbackRequestedRetry && callbackStreamRetryCount < 1)) { flushBufferedAttemptParts(); errorsHandledForStreamRetry.add(value.error); controller.enqueue(value); return; } if (automaticRetry) automaticStreamRetryCount++; else callbackStreamRetryCount++; await languageModelStreamReader.cancel(error); bufferedAttemptParts = []; closeOpenAttemptParts(); let retryLanguageModelCall; try { retryLanguageModelCall = await callLanguageModel(); } catch (retryError) { controller.enqueue({ type: "error", error: retryError }); controller.close(); return; } request = retryLanguageModelCall.request; response = retryLanguageModelCall.response; languageModelStreamReader = retryLanguageModelCall.stream.getReader(); enqueueStreamRetryAttemptBoundary = true; } }, cancel(reason) { return languageModelStreamReader.cancel(reason); } }); startFirstChunkTimeout(); const streamAfterToolCallbackInvocation = invokeToolCallbacksFromStream({ stream: languageModelStream, tools: stepExecutionTools, stepInputMessages: stepMessages, abortSignal, toolsContext }); const runInTracingChannelSpanInStep = telemetryDispatcher.runInTracingChannelSpan == null ? void 0 : (options) => runInStepTracingChannelContext(() => telemetryDispatcher.runInTracingChannelSpan(options)); const streamWithToolResults = executeToolsFromStream({ stream: streamAfterToolCallbackInvocation, tools: stepExecutionTools, callId, messages: stepMessages, abortSignal, timeout, experimental_sandbox: stepSandbox, toolsContext, toolApproval, runtimeContext, toolApprovalSecret: experimental_toolApprovalSecret, generateId: generateId5, onToolExecutionStart: filterNullable(onToolExecutionStart, telemetryDispatcher.onToolExecutionStart), onToolExecutionEnd: filterNullable(onToolExecutionEnd, telemetryDispatcher.onToolExecutionEnd), executeToolInTelemetryContext: telemetryDispatcher.executeTool, runInTracingChannelSpan: runInTracingChannelSpanInStep }); const getStepRequest = () => ({ ...request, body: include.requestBody ? request == null ? void 0 : request.body : void 0, messages: include.requestMessages ? cloneModelMessages(stepMessages) : void 0 }); recordedRequestMessages = (_l = getStepRequest().messages) != null ? _l : []; const stepToolCalls = []; const stepToolOutputs = []; const stepToolApprovalResponses = []; let warnings; let stepFinishReason = "other"; let stepRawFinishReason = void 0; let hasReceivedTerminalChunk = false; let hasReceivedOutputChunk = false; let stepUsage = createNullLanguageModelUsage(); let stepProviderMetadata; let stepFirstChunk = true; const createModelCallPerformance = () => ({ responseTimeMs: 0, effectiveOutputTokensPerSecond: 0, outputTokensPerSecond: void 0, inputTokensPerSecond: void 0, effectiveTotalTokensPerSecond: 0, timeToFirstOutputMs: void 0, timeBetweenOutputChunksMs: void 0 }); let modelCallPerformance = createModelCallPerformance(); const toolExecutionMs = {}; const createStepResponse = () => ({ id: generateId5(), timestamp: /* @__PURE__ */ new Date(), modelId: stepModel.modelId }); let stepResponse = createStepResponse(); const textPartIds = /* @__PURE__ */ new Map(); const reasoningPartIds = /* @__PURE__ */ new Map(); const enqueueStepPart = (controller, part) => { controller.enqueue(part); }; self.addStream(streamWithToolResults.pipeThrough(new TransformStream({ async transform(chunk, controller) { var _a27, _b26, _c2, _d2, _e2, _f2, _g2; if (isStreamRetryAttemptBoundaryPart(chunk)) { warnings = chunk.warnings; stepFinishReason = "other"; stepRawFinishReason = void 0; hasReceivedTerminalChunk = false; hasReceivedOutputChunk = false; stepUsage = createNullLanguageModelUsage(); stepProviderMetadata = void 0; modelCallPerformance = createModelCallPerformance(); stepResponse = createStepResponse(); textPartIds.clear(); reasoningPartIds.clear(); controller.enqueue({ [streamRetryBoundarySymbol]: { request: getStepRequest(), warnings } }); return; } if (chunk.type === "model-call-start") { warnings = chunk.warnings; return; } if (stepFirstChunk) { stepFirstChunk = false; enqueueStepPart(controller, { type: "start-step", request: getStepRequest(), warnings: warnings != null ? warnings : [] }); } const chunkType = chunk.type; if (isOutputChunk2(chunk)) { const timeoutHandledBeforeBuffering = outputChunksHandledBeforeBuffering.has(chunk); if (!hasReceivedOutputChunk && !timeoutHandledBeforeBuffering) clearFirstChunkTimeout(); hasReceivedOutputChunk = true; if (!timeoutHandledBeforeBuffering) resetChunkTimeout(); } switch (chunkType) { case "file": case "custom": case "source": case "reasoning-file": case "tool-input-start": case "tool-input-end": case "tool-input-delta": case "tool-approval-request": case "tool-output-denied": enqueueStepPart(controller, chunk); break; case "text-start": { const id = reserveTextPartId(chunk.id); textPartIds.set(chunk.id, id); enqueueStepPart(controller, { ...chunk, id }); break; } case "text-delta": if (chunk.text.length > 0 || chunk.providerMetadata != null) enqueueStepPart(controller, { ...chunk, id: (_a27 = textPartIds.get(chunk.id)) != null ? _a27 : chunk.id }); break; case "text-end": enqueueStepPart(controller, { ...chunk, id: (_b26 = textPartIds.get(chunk.id)) != null ? _b26 : chunk.id }); textPartIds.delete(chunk.id); break; case "reasoning-start": { const id = reserveReasoningPartId(chunk.id); reasoningPartIds.set(chunk.id, id); enqueueStepPart(controller, { ...chunk, id }); break; } case "reasoning-delta": enqueueStepPart(controller, { ...chunk, id: (_c2 = reasoningPartIds.get(chunk.id)) != null ? _c2 : chunk.id }); break; case "reasoning-end": enqueueStepPart(controller, { ...chunk, id: (_d2 = reasoningPartIds.get(chunk.id)) != null ? _d2 : chunk.id }); reasoningPartIds.delete(chunk.id); break; case "tool-call": enqueueStepPart(controller, chunk); stepToolCalls.push(chunk); break; case "tool-approval-response": enqueueStepPart(controller, chunk); stepToolApprovalResponses.push(chunk); break; case "tool-result": enqueueStepPart(controller, chunk); if (!chunk.preliminary) stepToolOutputs.push(chunk); break; case "tool-error": enqueueStepPart(controller, chunk); stepToolOutputs.push(chunk); break; case "tool-execution-end": toolExecutionMs[chunk.toolCallId] = chunk.toolExecutionMs; break; case "model-call-response-metadata": stepResponse = { id: (_e2 = chunk.id) != null ? _e2 : stepResponse.id, timestamp: (_f2 = chunk.timestamp) != null ? _f2 : stepResponse.timestamp, modelId: (_g2 = chunk.modelId) != null ? _g2 : stepResponse.modelId }; break; case "model-call-end": hasReceivedTerminalChunk = true; stepUsage = chunk.usage; stepFinishReason = chunk.finishReason; stepRawFinishReason = chunk.rawFinishReason; stepProviderMetadata = chunk.providerMetadata; modelCallPerformance = chunk.performance; break; case "error": hasReceivedTerminalChunk = true; enqueueStepPart(controller, chunk); stepFinishReason = "error"; break; case "raw": if (include.rawChunks) enqueueStepPart(controller, chunk); break; default: throw new Error(`Unknown chunk type: ${chunkType}`); } }, async flush(controller) { if (!hasReceivedTerminalChunk && !hasReceivedOutputChunk) { enqueueStepPart(controller, { type: "error", error: new NoOutputGeneratedError({ message: "No output generated. The model stream ended without a finish chunk." }) }); cleanupStepTimeouts(); self.closeStream(); return; } const stepTimeMs = now2() - stepStartTimestampMs; const finishStepPart = { type: "finish-step", finishReason: stepFinishReason, rawFinishReason: stepRawFinishReason, usage: stepUsage, performance: { stepTimeMs, toolExecutionMs, ...modelCallPerformance }, providerMetadata: stepProviderMetadata, response: { ...stepResponse, headers: response == null ? void 0 : response.headers } }; enqueueStepPart(controller, finishStepPart); const combinedUsage = addLanguageModelUsage(usage, stepUsage); await stepFinish.promise; const clientToolCalls = stepToolCalls.filter((toolCall) => toolCall.providerExecuted !== true); const clientToolOutputs = stepToolOutputs.filter((toolOutput) => toolOutput.providerExecuted !== true); const deniedToolApprovalResponses = stepToolApprovalResponses.filter((toolApprovalResponse) => toolApprovalResponse.approved === false); for (const toolCall of stepToolCalls) { if (toolCall.providerExecuted !== true) continue; const tool3 = getOwn(stepExecutionTools, toolCall.toolName); if ((tool3 == null ? void 0 : tool3.type) === "provider" && tool3.supportsDeferredResults) { if (!stepToolOutputs.some((output2) => (output2.type === "tool-result" || output2.type === "tool-error") && output2.toolCallId === toolCall.toolCallId)) pendingDeferredToolCalls.set(toolCall.toolCallId, { toolName: toolCall.toolName }); } } for (const output2 of stepToolOutputs) if (output2.type === "tool-result" || output2.type === "tool-error") pendingDeferredToolCalls.delete(output2.toolCallId); cleanupStepTimeouts(); if (clientToolCalls.length === clientToolOutputs.length + deniedToolApprovalResponses.length && (clientToolCalls.length > 0 || pendingDeferredToolCalls.size > 0) && !await isStopConditionMet({ stopConditions, steps: recordedSteps })) try { await runInStreamTextTracingChannelContext(() => streamStep({ currentStep: currentStep + 1, usage: combinedUsage })); } catch (error) { enqueueStepPart(controller, { type: "error", error }); self.closeStream(); } else { enqueueStepPart(controller, { type: "finish", finishReason: stepFinishReason, rawFinishReason: stepRawFinishReason, totalUsage: combinedUsage }); self.closeStream(); } } })), { onError: cleanupStepTimeouts, onCancel: cleanupStepTimeouts }); } catch (error) { cleanupStepTimeouts(); throw error; } } await runInStreamTextTracingChannelContext(() => streamStep({ currentStep: 0, usage: createNullLanguageModelUsage() })); })().catch(async (error) => { var _a25; await ((_a25 = telemetryDispatcher.onError) == null ? void 0 : _a25.call(telemetryDispatcher, { callId, error })); self._initialResponseMessages.reject(error); markPromiseAsHandled(self._initialResponseMessages.promise); self.addStream(new ReadableStream({ start(controller) { controller.enqueue({ type: "error", error }); controller.close(); } })); self.closeStream(); }); } get steps() { this.consumeStream(); return this._steps.promise; } get finalStep() { return this.steps.then((steps) => steps.at(-1)); } get content() { return this.steps.then((steps) => steps.flatMap((step) => step.content)); } get warnings() { return this.steps.then((steps) => steps.flatMap((step) => { var _a25; return (_a25 = step.warnings) != null ? _a25 : []; })); } get providerMetadata() { return this.finalStep.then((step) => step.providerMetadata); } get text() { return this.finalStep.then((step) => step.text); } get reasoningText() { return this.finalStep.then((step) => step.reasoningText); } get reasoning() { return this.finalStep.then((step) => convertToReasoningOutputs(step.reasoning)); } get sources() { return this.steps.then((steps) => steps.flatMap((step) => step.sources)); } get files() { return this.steps.then((steps) => steps.flatMap((step) => step.files)); } get toolCalls() { return this.steps.then((steps) => steps.flatMap((step) => step.toolCalls)); } get staticToolCalls() { return this.steps.then((steps) => steps.flatMap((step) => step.staticToolCalls)); } get dynamicToolCalls() { return this.steps.then((steps) => steps.flatMap((step) => step.dynamicToolCalls)); } get toolResults() { return this.steps.then((steps) => steps.flatMap((step) => step.toolResults)); } get staticToolResults() { return this.steps.then((steps) => steps.flatMap((step) => step.staticToolResults)); } get dynamicToolResults() { return this.steps.then((steps) => steps.flatMap((step) => step.dynamicToolResults)); } get usage() { return this.totalUsage; } get request() { return this.finalStep.then((step) => step.request); } get response() { return this.finalStep.then((step) => step.response); } get responseMessages() { return Promise.all([this._initialResponseMessages.promise, this.steps]).then(([initialResponseMessages, steps]) => [...initialResponseMessages, ...steps.flatMap((step) => step.response.messages)]); } get totalUsage() { this.consumeStream(); return this._totalUsage.promise; } get finishReason() { this.consumeStream(); return this._finishReason.promise; } get rawFinishReason() { this.consumeStream(); return this._rawFinishReason.promise; } /** * Split out a new stream from the original stream. * The original stream is replaced to allow for further splitting, * since we do not know how many times the stream will be split. * * Note: this leads to buffering the stream content on the server. * However, the LLM results are expected to be small enough to not cause issues. */ teeStream() { const [stream1, stream2] = this.baseStream.tee(); this.baseStream = stream2; return stream1; } get textStream() { return createAsyncIterableStream(toTextStream({ stream: this.stream })); } get stream() { return createAsyncIterableStream(this.teeStream().pipeThrough(new TransformStream({ transform({ part }, controller) { controller.enqueue(part); } }))); } get fullStream() { return this.stream; } rejectResultPromises(error) { this.rejectResultPromise({ delayedPromise: this._finishReason, error }); this.rejectResultPromise({ delayedPromise: this._rawFinishReason, error }); this.rejectResultPromise({ delayedPromise: this._totalUsage, error }); this.rejectResultPromise({ delayedPromise: this._steps, error }); this.rejectResultPromise({ delayedPromise: this._initialResponseMessages, error }); } rejectResultPromise({ delayedPromise, error }) { if (delayedPromise.isPending()) { delayedPromise.reject(error); markPromiseAsHandled(delayedPromise.promise); } } async consumeStream(options) { var _a25; try { await consumeStream({ stream: this.stream, onError: (error) => { var _a26; this.rejectResultPromises(error); (_a26 = options == null ? void 0 : options.onError) == null || _a26.call(options, error); } }); } catch (error) { this.rejectResultPromises(error); (_a25 = options == null ? void 0 : options.onError) == null || _a25.call(options, error); } } get experimental_partialOutputStream() { return this.partialOutputStream; } get partialOutputStream() { return createAsyncIterableStream(this.teeStream().pipeThrough(new TransformStream({ transform({ partialOutput }, controller) { if (partialOutput !== void 0) controller.enqueue(partialOutput); } }))); } get elementStream() { var _a25, _b25, _c; const transform = (_a25 = this.outputSpecification) == null ? void 0 : _a25.createElementStreamTransform(); if (transform == null) throw new UnsupportedFunctionalityError({ functionality: `element streams in ${(_c = (_b25 = this.outputSpecification) == null ? void 0 : _b25.name) != null ? _c : "text"} mode` }); return createAsyncIterableStream(this.teeStream().pipeThrough(transform)); } getOutputPromise() { if (this.outputPromise == null) this.outputPromise = this.finalStep.then((step) => { var _a25; return ((_a25 = this.outputSpecification) != null ? _a25 : text()).parseCompleteOutput({ text: step.text }, { response: step.response, usage: step.usage, finishReason: step.finishReason }); }); return this.outputPromise; } get output() { return this.getOutputPromise(); } toUIMessageStream({ originalMessages, generateMessageId, onEnd, onFinish, messageMetadata, sendReasoning, sendSources, sendStart, sendFinish, onError } = {}) { return createAsyncIterableStream(toUIMessageStream({ stream: this.stream, tools: this.tools, originalMessages, generateMessageId, onEnd: onEnd != null ? onEnd : onFinish, messageMetadata, sendReasoning, sendSources, sendStart, sendFinish, onError })); } pipeUIMessageStreamToResponse(response, { originalMessages, generateMessageId, onEnd, onFinish, messageMetadata, sendReasoning, sendSources, sendFinish, sendStart, onError, ...init } = {}) { return pipeUIMessageStreamToResponse({ response, stream: this.toUIMessageStream({ originalMessages, generateMessageId, onEnd: onEnd != null ? onEnd : onFinish, messageMetadata, sendReasoning, sendSources, sendFinish, sendStart, onError }), ...init }); } pipeTextStreamToResponse(response, init) { return pipeTextStreamToResponse({ response, stream: this.textStream, ...init }); } toUIMessageStreamResponse({ originalMessages, generateMessageId, onEnd, onFinish, messageMetadata, sendReasoning, sendSources, sendFinish, sendStart, onError, ...init } = {}) { return createUIMessageStreamResponse({ stream: this.toUIMessageStream({ originalMessages, generateMessageId, onEnd: onEnd != null ? onEnd : onFinish, messageMetadata, sendReasoning, sendSources, sendFinish, sendStart, onError }), ...init }); } toTextStreamResponse(init) { return createTextStreamResponse({ stream: this.textStream, ...init }); } }; z.record(z.string(), jsonValueSchema.optional()); z.record(z.string(), z.string()); createIdGenerator({ prefix: "call", size: 24 }); createIdGenerator({ prefix: "call", size: 24 }); new TextEncoder(); createIdGenerator({ prefix: "aiobj", size: 24 }); var { atob: atob2 } = globalThis; createIdGenerator({ prefix: "aiobj", size: 24 }); z.object({ token: z.string().refine((value) => value.trim().length > 0), url: z.string().refine((value) => { try { const url = new URL(value); return (url.protocol === "ws:" || url.protocol === "wss:") && url.hostname !== ""; } catch (e) { return false; } }), expiresAt: z.number().positive().max(Number.MAX_SAFE_INTEGER).optional(), tools: z.array(z.object({ type: z.literal("function"), name: z.string().min(1), description: z.string().optional(), parameters: z.record(z.string(), z.unknown()) })).optional() }); createIdGenerator({ prefix: "call", size: 24 }); //#endregion //#region node_modules/@ai-sdk/openai-compatible/dist/index.js function toCamelCase(str) { return str.replace(/[_-]([a-z])/g, (g) => g[1].toUpperCase()); } function resolveProviderOptionsKey(rawName, providerOptions) { const camelName = toCamelCase(rawName); if (camelName !== rawName && (providerOptions == null ? void 0 : providerOptions[camelName]) != null) return camelName; return rawName; } function warnIfDeprecatedProviderOptionsKey({ rawName, providerOptions, warnings }) { const camelName = toCamelCase(rawName); if (camelName !== rawName && (providerOptions == null ? void 0 : providerOptions[rawName]) != null) warnings.push({ type: "deprecated", setting: `providerOptions key '${rawName}'`, message: `Use '${camelName}' instead.` }); } var defaultOpenAICompatibleErrorStructure = { errorSchema: object({ error: object({ message: string(), type: string().nullish(), param: any().nullish(), code: union([string(), number()]).nullish() }) }), errorToMessage: (data) => data.error.message }; function convertOpenAICompatibleChatUsage(usage) { var _a, _b, _c, _d, _e, _f; if (usage == null) return createNullLanguageModelUsage$1(); const promptTokens = (_a = usage.prompt_tokens) != null ? _a : 0; const completionTokens = (_b = usage.completion_tokens) != null ? _b : 0; const cacheReadTokens = (_d = (_c = usage.prompt_tokens_details) == null ? void 0 : _c.cached_tokens) != null ? _d : 0; const reasoningTokens = (_f = (_e = usage.completion_tokens_details) == null ? void 0 : _e.reasoning_tokens) != null ? _f : 0; return { inputTokens: { total: promptTokens, noCache: promptTokens - cacheReadTokens, cacheRead: cacheReadTokens, cacheWrite: void 0 }, outputTokens: { total: completionTokens, text: Math.max(0, completionTokens - reasoningTokens), reasoning: reasoningTokens }, raw: usage }; } function getOpenAIMetadata(message) { var _a, _b; return (_b = (_a = message == null ? void 0 : message.providerOptions) == null ? void 0 : _a.openaiCompatible) != null ? _b : {}; } function getAudioFormat(mediaType) { switch (mediaType) { case "audio/wav": return "wav"; case "audio/mp3": case "audio/mpeg": return "mp3"; default: return null; } } function convertToOpenAICompatibleChatMessages(prompt, { providerOptionsKey = "google" } = {}) { var _a, _b, _c, _d, _e, _f; const messages = []; for (const { role, content, ...message } of prompt) { const metadata = getOpenAIMetadata({ ...message }); switch (role) { case "system": messages.push({ role: "system", content, ...metadata }); break; case "user": if (content.length === 1 && content[0].type === "text") { messages.push({ role: "user", content: content[0].text, ...getOpenAIMetadata(content[0]) }); break; } messages.push({ role: "user", content: content.map((part) => { var _a2; const partMetadata = getOpenAIMetadata(part); switch (part.type) { case "text": return { type: "text", text: part.text, ...partMetadata }; case "file": switch (part.data.type) { case "reference": throw new UnsupportedFunctionalityError({ functionality: "file parts with provider references" }); case "text": throw new UnsupportedFunctionalityError({ functionality: "text file parts" }); case "url": case "data": { const topLevel = getTopLevelMediaType(part.mediaType); if (topLevel === "image") return { type: "image_url", image_url: { url: part.data.type === "url" ? part.data.url.toString() : `data:${resolveFullMediaType({ part })};base64,${convertToBase64(part.data.data)}` }, ...partMetadata }; if (topLevel === "video") return { type: "video_url", video_url: { url: part.data.type === "url" ? part.data.url.toString() : `data:${resolveFullMediaType({ part })};base64,${convertToBase64(part.data.data)}` }, ...partMetadata }; if (topLevel === "audio") { if (part.data.type === "url") throw new UnsupportedFunctionalityError({ functionality: "audio file parts with URLs" }); const fullMediaType = resolveFullMediaType({ part }); const format = getAudioFormat(fullMediaType); if (format === null) throw new UnsupportedFunctionalityError({ functionality: `audio media type ${fullMediaType}` }); return { type: "input_audio", input_audio: { data: convertToBase64(part.data.data), format }, ...partMetadata }; } if (topLevel === "application") { if (part.data.type === "url") throw new UnsupportedFunctionalityError({ functionality: "PDF file parts with URLs" }); const fullMediaType = resolveFullMediaType({ part }); if (fullMediaType !== "application/pdf") throw new UnsupportedFunctionalityError({ functionality: `file part media type ${fullMediaType}` }); return { type: "file", file: { filename: (_a2 = part.filename) != null ? _a2 : "document.pdf", file_data: `data:application/pdf;base64,${convertToBase64(part.data.data)}` }, ...partMetadata }; } if (topLevel === "text") return { type: "text", text: part.data.type === "url" ? part.data.url.toString() : typeof part.data.data === "string" ? new TextDecoder().decode(convertBase64ToUint8Array(part.data.data)) : new TextDecoder().decode(part.data.data), ...partMetadata }; throw new UnsupportedFunctionalityError({ functionality: `file part media type ${part.mediaType}` }); } } } }), ...metadata }); break; case "assistant": { let text = ""; let reasoning = ""; const toolCalls = []; for (const part of content) { const partMetadata = getOpenAIMetadata(part); switch (part.type) { case "text": text += part.text; break; case "reasoning": reasoning += part.text; break; case "tool-call": { const thoughtSignature = (_e = (_b = (_a = part.providerOptions) == null ? void 0 : _a[providerOptionsKey]) == null ? void 0 : _b.thoughtSignature) != null ? _e : (_d = (_c = part.providerOptions) == null ? void 0 : _c.google) == null ? void 0 : _d.thoughtSignature; toolCalls.push({ id: part.toolCallId, type: "function", function: { name: part.toolName, arguments: JSON.stringify(part.input) }, ...partMetadata, ...thoughtSignature ? { extra_content: { google: { thought_signature: String(thoughtSignature) } } } : {} }); break; } } } messages.push({ role: "assistant", content: toolCalls.length > 0 ? text || null : text, ...reasoning.length > 0 ? { reasoning_content: reasoning } : {}, tool_calls: toolCalls.length > 0 ? toolCalls : void 0, ...metadata }); break; } case "tool": for (const toolResponse of content) { if (toolResponse.type === "tool-approval-response") continue; const output = toolResponse.output; let contentValue; switch (output.type) { case "text": case "error-text": contentValue = output.value; break; case "execution-denied": contentValue = (_f = output.reason) != null ? _f : "Tool call execution denied."; break; case "content": case "json": case "error-json": contentValue = JSON.stringify(output.value); } const toolResponseMetadata = getOpenAIMetadata(toolResponse); messages.push({ role: "tool", tool_call_id: toolResponse.toolCallId, content: contentValue, ...toolResponseMetadata }); } break; default: throw new Error(`Unsupported role: ${role}`); } } return messages; } function getResponseMetadata({ id, model, created }) { return createLanguageModelResponseMetadata({ id, model, created: created || void 0 }); } function mapOpenAICompatibleFinishReason(finishReason) { switch (finishReason) { case "stop": return "stop"; case "length": return "length"; case "content_filter": return "content-filter"; case "function_call": case "tool_calls": return "tool-calls"; default: return "other"; } } var openaiCompatibleLanguageModelChatOptions = object({ /** * A unique identifier representing your end-user, which can help the provider to * monitor and detect abuse. */ user: string().optional(), /** * Reasoning effort for reasoning models. Defaults to `medium`. */ reasoningEffort: string().optional(), /** * Controls the verbosity of the generated text. Defaults to `medium`. */ textVerbosity: string().optional(), /** * Whether to use strict JSON schema validation. * When true, the model uses constrained decoding to guarantee schema compliance. * Only used when the provider supports structured outputs and a schema is provided. * * @default true */ strictJsonSchema: boolean().optional() }); function prepareTools({ tools, toolChoice }) { tools = (tools == null ? void 0 : tools.length) ? tools : void 0; const toolWarnings = []; if (tools == null) return { tools: void 0, toolChoice: void 0, toolWarnings }; const openaiCompatTools = []; for (const tool of tools) if (tool.type === "provider") toolWarnings.push({ type: "unsupported", feature: `provider-defined tool ${tool.id}` }); else openaiCompatTools.push({ type: "function", function: { name: tool.name, description: tool.description, parameters: tool.inputSchema, ...tool.strict != null ? { strict: tool.strict } : {} } }); if (toolChoice == null) return { tools: openaiCompatTools, toolChoice: void 0, toolWarnings }; const type = toolChoice.type; switch (type) { case "auto": case "none": case "required": return { tools: openaiCompatTools, toolChoice: type, toolWarnings }; case "tool": return { tools: openaiCompatTools, toolChoice: { type: "function", function: { name: toolChoice.toolName } }, toolWarnings }; default: throw new UnsupportedFunctionalityError({ functionality: `tool choice type: ${type}` }); } } var OpenAICompatibleChatLanguageModel = class _OpenAICompatibleChatLanguageModel { constructor(modelId, config) { this.specificationVersion = "v4"; var _a, _b; this.modelId = modelId; this.config = config; const errorStructure = (_a = config.errorStructure) != null ? _a : defaultOpenAICompatibleErrorStructure; this.chunkSchema = createOpenAICompatibleChatChunkSchema(errorStructure.errorSchema); this.failedResponseHandler = createJsonErrorResponseHandler(errorStructure); this.supportsStructuredOutputs = (_b = config.supportsStructuredOutputs) != null ? _b : false; } static [WORKFLOW_SERIALIZE](model) { return serializeModelOptions({ modelId: model.modelId, config: model.config }); } static [WORKFLOW_DESERIALIZE](options) { return new _OpenAICompatibleChatLanguageModel(options.modelId, options.config); } get provider() { return this.config.provider; } get providerOptionsName() { return this.config.provider.split(".")[0].trim(); } get supportedUrls() { var _a, _b, _c; return (_c = (_b = (_a = this.config).supportedUrls) == null ? void 0 : _b.call(_a)) != null ? _c : {}; } transformRequestBody(args) { var _a, _b, _c; return (_c = (_b = (_a = this.config).transformRequestBody) == null ? void 0 : _b.call(_a, args)) != null ? _c : args; } convertUsage(usage) { var _a, _b, _c; return (_c = (_b = (_a = this.config).convertUsage) == null ? void 0 : _b.call(_a, usage)) != null ? _c : convertOpenAICompatibleChatUsage(usage); } async getArgs({ prompt, maxOutputTokens, temperature, topP, topK, frequencyPenalty, presencePenalty, reasoning, providerOptions, stopSequences, responseFormat, seed, toolChoice, tools }) { var _a, _b, _c, _d, _e, _f; const warnings = []; const deprecatedOptions = await parseProviderOptions({ provider: "openai-compatible", providerOptions, schema: openaiCompatibleLanguageModelChatOptions }); if (deprecatedOptions != null) warnings.push({ type: "deprecated", setting: "providerOptions key 'openai-compatible'", message: "Use 'openaiCompatible' instead." }); warnIfDeprecatedProviderOptionsKey({ rawName: this.providerOptionsName, providerOptions, warnings }); const compatibleOptions = Object.assign(deprecatedOptions != null ? deprecatedOptions : {}, (_a = await parseProviderOptions({ provider: "openaiCompatible", providerOptions, schema: openaiCompatibleLanguageModelChatOptions })) != null ? _a : {}, (_b = await parseProviderOptions({ provider: this.providerOptionsName, providerOptions, schema: openaiCompatibleLanguageModelChatOptions })) != null ? _b : {}, (_c = await parseProviderOptions({ provider: toCamelCase(this.providerOptionsName), providerOptions, schema: openaiCompatibleLanguageModelChatOptions })) != null ? _c : {}); const strictJsonSchema = (_d = compatibleOptions == null ? void 0 : compatibleOptions.strictJsonSchema) != null ? _d : true; if (topK != null) warnings.push({ type: "unsupported", feature: "topK" }); if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !this.supportsStructuredOutputs) warnings.push({ type: "unsupported", feature: "responseFormat", details: "JSON response format schema is only supported with structuredOutputs" }); const { tools: openaiTools, toolChoice: openaiToolChoice, toolWarnings } = prepareTools({ tools, toolChoice }); const metadataKey = resolveProviderOptionsKey(this.providerOptionsName, providerOptions); return { metadataKey, args: { model: this.modelId, user: compatibleOptions.user, max_tokens: maxOutputTokens, temperature, top_p: topP, frequency_penalty: frequencyPenalty, presence_penalty: presencePenalty, response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? this.supportsStructuredOutputs === true && responseFormat.schema != null ? { type: "json_schema", json_schema: { schema: responseFormat.schema, strict: strictJsonSchema, name: (_e = responseFormat.name) != null ? _e : "response", description: responseFormat.description } } : { type: "json_object" } : void 0, stop: stopSequences, seed, ...Object.fromEntries(Object.entries({ ...providerOptions == null ? void 0 : providerOptions[this.providerOptionsName], ...providerOptions == null ? void 0 : providerOptions[toCamelCase(this.providerOptionsName)] }).filter(([key]) => !Object.keys(openaiCompatibleLanguageModelChatOptions.shape).includes(key))), reasoning_effort: (_f = compatibleOptions.reasoningEffort) != null ? _f : isCustomReasoning(reasoning) ? reasoning : void 0, verbosity: compatibleOptions.textVerbosity, messages: convertToOpenAICompatibleChatMessages(prompt, { providerOptionsKey: metadataKey }), tools: openaiTools, tool_choice: openaiToolChoice }, warnings: [...warnings, ...toolWarnings] }; } async doGenerate(options) { var _a, _b, _c, _d, _e, _f, _g, _h, _i; const { args, warnings, metadataKey } = await this.getArgs({ ...options }); const transformedBody = this.transformRequestBody(args); const body = JSON.stringify(transformedBody); const { responseHeaders, value: responseBody, rawValue: rawResponse } = await postJsonToApi({ url: this.config.url({ path: "/chat/completions", modelId: this.modelId }), headers: combineHeaders((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers), body: transformedBody, failedResponseHandler: this.failedResponseHandler, successfulResponseHandler: createJsonResponseHandler(OpenAICompatibleChatResponseSchema), abortSignal: options.abortSignal, fetch: this.config.fetch }); const choice = responseBody.choices[0]; if (choice == null) throw new InvalidResponseDataError({ data: rawResponse, message: "Response did not contain any choices." }); const content = []; content.push(...convertOpenAICompatibleContent(choice.message.content)); const reasoning = (_c = choice.message.reasoning_content) != null ? _c : choice.message.reasoning; if (reasoning != null && reasoning.length > 0) content.push({ type: "reasoning", text: reasoning }); if (choice.message.tool_calls != null) for (const toolCall of choice.message.tool_calls) { const thoughtSignature = (_e = (_d = toolCall.extra_content) == null ? void 0 : _d.google) == null ? void 0 : _e.thought_signature; content.push({ type: "tool-call", toolCallId: toolCall.id || generateId(), toolName: toolCall.function.name, input: toolCall.function.arguments, ...thoughtSignature ? { providerMetadata: { [metadataKey]: { thoughtSignature } } } : {} }); } const providerMetadata = { [metadataKey]: {}, ...await ((_g = (_f = this.config.metadataExtractor) == null ? void 0 : _f.extractMetadata) == null ? void 0 : _g.call(_f, { parsedBody: rawResponse })) }; const completionTokenDetails = (_h = responseBody.usage) == null ? void 0 : _h.completion_tokens_details; if ((completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens) != null) providerMetadata[metadataKey].acceptedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens; if ((completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens) != null) providerMetadata[metadataKey].rejectedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens; return { content, finishReason: { unified: mapOpenAICompatibleFinishReason(choice.finish_reason), raw: (_i = choice.finish_reason) != null ? _i : void 0 }, usage: this.convertUsage(responseBody.usage), providerMetadata, request: { body }, response: { ...getResponseMetadata(responseBody), headers: responseHeaders, body: rawResponse }, warnings }; } async doStream(options) { var _a, _b, _c; const { args, warnings, metadataKey } = await this.getArgs({ ...options }); const body = this.transformRequestBody({ ...args, stream: true, stream_options: this.config.includeUsage ? { include_usage: true } : void 0 }); const metadataExtractor = (_a = this.config.metadataExtractor) == null ? void 0 : _a.createStreamExtractor(); const { responseHeaders, value: response } = await postJsonToApi({ url: this.config.url({ path: "/chat/completions", modelId: this.modelId }), headers: combineHeaders((_c = (_b = this.config).headers) == null ? void 0 : _c.call(_b), options.headers), body, failedResponseHandler: this.failedResponseHandler, successfulResponseHandler: createEventSourceResponseHandler(this.chunkSchema), abortSignal: options.abortSignal, fetch: this.config.fetch }); const providerOptionsName = metadataKey; let toolCallTracker; const pendingToolCalls = /* @__PURE__ */ new Map(); const forwardedToolCallIndices = /* @__PURE__ */ new Set(); const processToolCallDelta = (toolCallDelta) => { var _a2, _b2, _c2, _d, _e; const index = toolCallDelta.index; if (index == null || forwardedToolCallIndices.has(index)) { toolCallTracker.processDelta(toolCallDelta); return; } let pending = pendingToolCalls.get(index); if (pending == null) { pending = { id: (_a2 = toolCallDelta.id) != null ? _a2 : null, bufferedArguments: "", extraContent: (_b2 = toolCallDelta.extra_content) != null ? _b2 : null }; pendingToolCalls.set(index, pending); } else { if (pending.id == null && toolCallDelta.id != null) pending.id = toolCallDelta.id; if (pending.extraContent == null && toolCallDelta.extra_content != null) pending.extraContent = toolCallDelta.extra_content; } const argumentsDelta = (_c2 = toolCallDelta.function) == null ? void 0 : _c2.arguments; if (argumentsDelta != null) pending.bufferedArguments += argumentsDelta; const name = (_d = toolCallDelta.function) == null ? void 0 : _d.name; if (name != null) { const forwardDelta = { index, id: pending.id, function: { name, arguments: pending.bufferedArguments }, extra_content: (_e = pending.extraContent) != null ? _e : void 0 }; toolCallTracker.processDelta(forwardDelta); pendingToolCalls.delete(index); forwardedToolCallIndices.add(index); } }; let finishReason; let usage = void 0; let metadataExtracted = false; let isActiveReasoning = false; let isActiveText = false; const convertUsage = (usage2) => this.convertUsage(usage2); return { stream: response.pipeThrough(new TransformStream({ start(controller) { toolCallTracker = new StreamingToolCallTracker(controller, { generateId, extractMetadata: (delta) => { var _a2, _b2; const thoughtSignature = (_b2 = (_a2 = delta.extra_content) == null ? void 0 : _a2.google) == null ? void 0 : _b2.thought_signature; return thoughtSignature ? { [providerOptionsName]: { thoughtSignature } } : void 0; }, buildToolCallProviderMetadata: (metadata) => metadata }); controller.enqueue({ type: "stream-start", warnings }); }, transform(chunk, controller) { var _a2, _b2; if (options.includeRawChunks) controller.enqueue({ type: "raw", rawValue: chunk.rawValue }); if (!chunk.success) { finishReason = { unified: "error", raw: void 0 }; controller.enqueue({ type: "error", error: chunk.error }); return; } metadataExtractor?.processChunk(chunk.rawValue); if ("error" in chunk.value) { finishReason = { unified: "error", raw: void 0 }; controller.enqueue({ type: "error", error: chunk.value.error }); return; } const value = chunk.value; if (!metadataExtracted) { const metadata = getResponseMetadata(value); if (Object.values(metadata).some(Boolean)) { metadataExtracted = true; controller.enqueue({ type: "response-metadata", ...metadata }); } } if (value.usage != null) usage = value.usage; const choice = value.choices[0]; if ((choice == null ? void 0 : choice.finish_reason) != null) finishReason = { unified: mapOpenAICompatibleFinishReason(choice.finish_reason), raw: (_a2 = choice.finish_reason) != null ? _a2 : void 0 }; if ((choice == null ? void 0 : choice.delta) == null) return; const delta = choice.delta; const enqueueReasoningDelta = (reasoningDelta) => { if (isActiveText) { controller.enqueue({ type: "text-end", id: "txt-0" }); isActiveText = false; } if (!isActiveReasoning) { controller.enqueue({ type: "reasoning-start", id: "reasoning-0" }); isActiveReasoning = true; } controller.enqueue({ type: "reasoning-delta", id: "reasoning-0", delta: reasoningDelta }); }; const enqueueTextDelta = (textDelta) => { if (isActiveReasoning) { controller.enqueue({ type: "reasoning-end", id: "reasoning-0" }); isActiveReasoning = false; } if (!isActiveText) { controller.enqueue({ type: "text-start", id: "txt-0" }); isActiveText = true; } controller.enqueue({ type: "text-delta", id: "txt-0", delta: textDelta }); }; const reasoningContent = (_b2 = delta.reasoning_content) != null ? _b2 : delta.reasoning; if (reasoningContent) enqueueReasoningDelta(reasoningContent); for (const contentPart of convertOpenAICompatibleContent(delta.content)) if (contentPart.type === "reasoning") enqueueReasoningDelta(contentPart.text); else enqueueTextDelta(contentPart.text); if (delta.tool_calls != null && delta.tool_calls.length > 0) { if (isActiveReasoning) { controller.enqueue({ type: "reasoning-end", id: "reasoning-0" }); isActiveReasoning = false; } for (const toolCallDelta of delta.tool_calls) processToolCallDelta(toolCallDelta); } }, flush(controller) { var _a2, _b2, _c2, _d; if (isActiveReasoning) controller.enqueue({ type: "reasoning-end", id: "reasoning-0" }); if (isActiveText) controller.enqueue({ type: "text-end", id: "txt-0" }); for (const [index, pending] of pendingToolCalls) toolCallTracker.processDelta({ index, id: pending.id, function: { arguments: pending.bufferedArguments } }); pendingToolCalls.clear(); toolCallTracker.flush(); if (finishReason == null) { finishReason = { unified: "error", raw: void 0 }; controller.enqueue({ type: "error", error: new InvalidResponseDataError({ data: void 0, message: "Response stream ended without a finish reason." }) }); } const providerMetadata = { [providerOptionsName]: {}, ...metadataExtractor == null ? void 0 : metadataExtractor.buildMetadata() }; if (((_a2 = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _a2.accepted_prediction_tokens) != null) providerMetadata[providerOptionsName].acceptedPredictionTokens = (_b2 = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _b2.accepted_prediction_tokens; if (((_c2 = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _c2.rejected_prediction_tokens) != null) providerMetadata[providerOptionsName].rejectedPredictionTokens = (_d = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _d.rejected_prediction_tokens; controller.enqueue({ type: "finish", finishReason, usage: convertUsage(usage), providerMetadata }); } })), request: { body }, response: { headers: responseHeaders } }; } }; var openaiCompatibleTokenUsageSchema = looseObject({ prompt_tokens: number().nullish(), completion_tokens: number().nullish(), total_tokens: number().nullish(), prompt_tokens_details: looseObject({ cached_tokens: number().nullish() }).nullish(), completion_tokens_details: looseObject({ reasoning_tokens: number().nullish(), accepted_prediction_tokens: number().nullish(), rejected_prediction_tokens: number().nullish() }).nullish() }).nullish(); var openAICompatibleContentSchema = union([string(), array(looseObject({ type: string() }))]).nullish(); function convertOpenAICompatibleContent(content) { if (content == null) return []; if (typeof content === "string") return content.length > 0 ? [{ type: "text", text: content }] : []; const result = []; for (const part of content) if (part.type === "text" && typeof part.text === "string") { if (part.text.length > 0) result.push({ type: "text", text: part.text }); } else if (part.type === "thinking" && Array.isArray(part.thinking)) { const reasoningText = part.thinking.filter((chunk) => chunk != null && typeof chunk === "object" && "type" in chunk && chunk.type === "text" && "text" in chunk && typeof chunk.text === "string").map((chunk) => chunk.text).join(""); if (reasoningText.length > 0) result.push({ type: "reasoning", text: reasoningText }); } return result; } var OpenAICompatibleChatResponseSchema = looseObject({ id: string().nullish(), created: number().nullish(), model: string().nullish(), choices: array(object({ message: object({ role: literal("assistant").nullish(), content: openAICompatibleContentSchema, reasoning_content: string().nullish(), reasoning: string().nullish(), tool_calls: array(object({ id: string().nullish(), function: object({ name: string(), arguments: string() }), extra_content: object({ google: object({ thought_signature: string().nullish() }).nullish() }).nullish() })).nullish() }), finish_reason: string().nullish() })), usage: openaiCompatibleTokenUsageSchema }); var chunkBaseSchema = looseObject({ id: string().nullish(), created: number().nullish(), model: string().nullish(), choices: array(object({ delta: object({ role: _enum(["assistant", ""]).nullish(), content: openAICompatibleContentSchema, reasoning_content: string().nullish(), reasoning: string().nullish(), tool_calls: array(object({ index: number().nullish(), id: string().nullish(), function: object({ name: string().nullish(), arguments: string().nullish() }), extra_content: object({ google: object({ thought_signature: string().nullish() }).nullish() }).nullish() })).nullish() }).nullish(), finish_reason: string().nullish() })), usage: openaiCompatibleTokenUsageSchema }); var createOpenAICompatibleChatChunkSchema = (errorSchema) => union([chunkBaseSchema, errorSchema]); function convertOpenAICompatibleCompletionUsage(usage) { var _a, _b; if (usage == null) return createNullLanguageModelUsage$1(); const promptTokens = (_a = usage.prompt_tokens) != null ? _a : 0; const completionTokens = (_b = usage.completion_tokens) != null ? _b : 0; return { inputTokens: { total: promptTokens, noCache: promptTokens, cacheRead: void 0, cacheWrite: void 0 }, outputTokens: { total: completionTokens, text: completionTokens, reasoning: void 0 }, raw: usage }; } function convertToOpenAICompatibleCompletionPrompt({ prompt, user = "user", assistant = "assistant" }) { let text = ""; if (prompt[0].role === "system") { text += `${prompt[0].content} `; prompt = prompt.slice(1); } for (const { role, content } of prompt) switch (role) { case "system": throw new InvalidPromptError({ message: "Unexpected system message in prompt: ${content}", prompt }); case "user": { const userMessage = content.map((part) => { switch (part.type) { case "text": return part.text; } }).filter(Boolean).join(""); text += `${user}: ${userMessage} `; break; } case "assistant": { const assistantMessage = content.map((part) => { switch (part.type) { case "text": return part.text; case "tool-call": throw new UnsupportedFunctionalityError({ functionality: "tool-call messages" }); } }).join(""); text += `${assistant}: ${assistantMessage} `; break; } case "tool": throw new UnsupportedFunctionalityError({ functionality: "tool messages" }); default: throw new Error(`Unsupported role: ${role}`); } text += `${assistant}: `; return { prompt: text, stopSequences: [` ${user}:`] }; } function mapOpenAICompatibleFinishReason2(finishReason) { switch (finishReason) { case "stop": return "stop"; case "length": return "length"; case "content_filter": return "content-filter"; case "function_call": case "tool_calls": return "tool-calls"; default: return "other"; } } var openaiCompatibleLanguageModelCompletionOptions = object({ /** * Echo back the prompt in addition to the completion. */ echo: boolean().optional(), /** * Modify the likelihood of specified tokens appearing in the completion. * * Accepts a JSON object that maps tokens (specified by their token ID in * the GPT tokenizer) to an associated bias value from -100 to 100. */ logitBias: record(string(), number()).optional(), /** * The suffix that comes after a completion of inserted text. */ suffix: string().optional(), /** * A unique identifier representing your end-user, which can help providers to * monitor and detect abuse. */ user: string().optional() }); var OpenAICompatibleCompletionLanguageModel = class _OpenAICompatibleCompletionLanguageModel { constructor(modelId, config) { this.specificationVersion = "v4"; var _a; this.modelId = modelId; this.config = config; const errorStructure = (_a = config.errorStructure) != null ? _a : defaultOpenAICompatibleErrorStructure; this.chunkSchema = createOpenAICompatibleCompletionChunkSchema(errorStructure.errorSchema); this.failedResponseHandler = createJsonErrorResponseHandler(errorStructure); } static [WORKFLOW_SERIALIZE](model) { return serializeModelOptions({ modelId: model.modelId, config: model.config }); } static [WORKFLOW_DESERIALIZE](options) { return new _OpenAICompatibleCompletionLanguageModel(options.modelId, options.config); } get provider() { return this.config.provider; } get providerOptionsName() { return this.config.provider.split(".")[0].trim(); } get supportedUrls() { var _a, _b, _c; return (_c = (_b = (_a = this.config).supportedUrls) == null ? void 0 : _b.call(_a)) != null ? _c : {}; } async getArgs({ prompt, maxOutputTokens, temperature, topP, topK, frequencyPenalty, presencePenalty, stopSequences: userStopSequences, responseFormat, seed, providerOptions, tools, toolChoice }) { var _a, _b; const warnings = []; warnIfDeprecatedProviderOptionsKey({ rawName: this.providerOptionsName, providerOptions, warnings }); const completionOptions = Object.assign((_a = await parseProviderOptions({ provider: this.providerOptionsName, providerOptions, schema: openaiCompatibleLanguageModelCompletionOptions })) != null ? _a : {}, (_b = await parseProviderOptions({ provider: toCamelCase(this.providerOptionsName), providerOptions, schema: openaiCompatibleLanguageModelCompletionOptions })) != null ? _b : {}); if (topK != null) warnings.push({ type: "unsupported", feature: "topK" }); if (tools == null ? void 0 : tools.length) warnings.push({ type: "unsupported", feature: "tools" }); if (toolChoice != null) warnings.push({ type: "unsupported", feature: "toolChoice" }); if (responseFormat != null && responseFormat.type !== "text") warnings.push({ type: "unsupported", feature: "responseFormat", details: "JSON response format is not supported." }); const { prompt: completionPrompt, stopSequences } = convertToOpenAICompatibleCompletionPrompt({ prompt }); const stop = [...stopSequences != null ? stopSequences : [], ...userStopSequences != null ? userStopSequences : []]; return { args: { model: this.modelId, echo: completionOptions.echo, logit_bias: completionOptions.logitBias, suffix: completionOptions.suffix, user: completionOptions.user, max_tokens: maxOutputTokens, temperature, top_p: topP, frequency_penalty: frequencyPenalty, presence_penalty: presencePenalty, seed, ...providerOptions == null ? void 0 : providerOptions[this.providerOptionsName], ...providerOptions == null ? void 0 : providerOptions[toCamelCase(this.providerOptionsName)], prompt: completionPrompt, stop: stop.length > 0 ? stop : void 0 }, warnings }; } async doGenerate(options) { var _a, _b; const { args, warnings } = await this.getArgs(options); const { responseHeaders, value: response, rawValue: rawResponse } = await postJsonToApi({ url: this.config.url({ path: "/completions", modelId: this.modelId }), headers: combineHeaders((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers), body: args, failedResponseHandler: this.failedResponseHandler, successfulResponseHandler: createJsonResponseHandler(openaiCompatibleCompletionResponseSchema), abortSignal: options.abortSignal, fetch: this.config.fetch }); const choice = response.choices[0]; const content = []; if (choice.text != null && choice.text.length > 0) content.push({ type: "text", text: choice.text }); return { content, usage: convertOpenAICompatibleCompletionUsage(response.usage), finishReason: { unified: mapOpenAICompatibleFinishReason2(choice.finish_reason), raw: choice.finish_reason }, request: { body: args }, response: { ...createLanguageModelResponseMetadata(response), headers: responseHeaders, body: rawResponse }, warnings }; } async doStream(options) { var _a, _b; const { args, warnings } = await this.getArgs(options); const body = { ...args, stream: true, stream_options: this.config.includeUsage ? { include_usage: true } : void 0 }; const { responseHeaders, value: response } = await postJsonToApi({ url: this.config.url({ path: "/completions", modelId: this.modelId }), headers: combineHeaders((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers), body, failedResponseHandler: this.failedResponseHandler, successfulResponseHandler: createEventSourceResponseHandler(this.chunkSchema), abortSignal: options.abortSignal, fetch: this.config.fetch }); let finishReason = { unified: "other", raw: void 0 }; let usage = void 0; let isFirstChunk = true; return { stream: response.pipeThrough(new TransformStream({ start(controller) { controller.enqueue({ type: "stream-start", warnings }); }, transform(chunk, controller) { var _a2; if (options.includeRawChunks) controller.enqueue({ type: "raw", rawValue: chunk.rawValue }); if (!chunk.success) { finishReason = { unified: "error", raw: void 0 }; controller.enqueue({ type: "error", error: chunk.error }); return; } const value = chunk.value; if ("error" in value) { finishReason = { unified: "error", raw: void 0 }; controller.enqueue({ type: "error", error: value.error }); return; } if (isFirstChunk) { isFirstChunk = false; controller.enqueue({ type: "response-metadata", ...createLanguageModelResponseMetadata(value) }); controller.enqueue({ type: "text-start", id: "0" }); } if (value.usage != null) usage = value.usage; const choice = value.choices[0]; if ((choice == null ? void 0 : choice.finish_reason) != null) finishReason = { unified: mapOpenAICompatibleFinishReason2(choice.finish_reason), raw: (_a2 = choice.finish_reason) != null ? _a2 : void 0 }; if ((choice == null ? void 0 : choice.text) != null) controller.enqueue({ type: "text-delta", id: "0", delta: choice.text }); }, flush(controller) { if (!isFirstChunk) controller.enqueue({ type: "text-end", id: "0" }); controller.enqueue({ type: "finish", finishReason, usage: convertOpenAICompatibleCompletionUsage(usage) }); } })), request: { body }, response: { headers: responseHeaders } }; } }; var usageSchema = looseObject({ prompt_tokens: number(), completion_tokens: number(), total_tokens: number() }); var openaiCompatibleCompletionResponseSchema = object({ id: string().nullish(), created: number().nullish(), model: string().nullish(), choices: array(object({ text: string(), finish_reason: string() })), usage: usageSchema.nullish() }); var createOpenAICompatibleCompletionChunkSchema = (errorSchema) => union([object({ id: string().nullish(), created: number().nullish(), model: string().nullish(), choices: array(object({ text: string(), finish_reason: string().nullish(), index: number() })), usage: usageSchema.nullish() }), errorSchema]); var openaiCompatibleEmbeddingModelOptions = object({ /** * The number of dimensions the resulting output embeddings should have. * Only supported in text-embedding-3 and later models. */ dimensions: number().optional(), /** * A unique identifier representing your end-user, which can help providers to * monitor and detect abuse. */ user: string().optional() }); var OpenAICompatibleEmbeddingModel = class _OpenAICompatibleEmbeddingModel { constructor(modelId, config) { this.specificationVersion = "v4"; this.modelId = modelId; this.config = config; } get provider() { return this.config.provider; } get maxEmbeddingsPerCall() { var _a; return (_a = this.config.maxEmbeddingsPerCall) != null ? _a : 2048; } get supportsParallelCalls() { var _a; return (_a = this.config.supportsParallelCalls) != null ? _a : true; } static [WORKFLOW_SERIALIZE](model) { return serializeModelOptions({ modelId: model.modelId, config: model.config }); } static [WORKFLOW_DESERIALIZE](options) { return new _OpenAICompatibleEmbeddingModel(options.modelId, options.config); } get providerOptionsName() { return this.config.provider.split(".")[0].trim(); } async doEmbed({ values, headers, abortSignal, providerOptions }) { var _a, _b, _c, _d, _e; const warnings = []; const deprecatedOptions = await parseProviderOptions({ provider: "openai-compatible", providerOptions, schema: openaiCompatibleEmbeddingModelOptions }); if (deprecatedOptions != null) warnings.push({ type: "deprecated", setting: "providerOptions key 'openai-compatible'", message: "Use 'openaiCompatible' instead." }); warnIfDeprecatedProviderOptionsKey({ rawName: this.providerOptionsName, providerOptions, warnings }); const compatibleOptions = Object.assign(deprecatedOptions != null ? deprecatedOptions : {}, (_a = await parseProviderOptions({ provider: "openaiCompatible", providerOptions, schema: openaiCompatibleEmbeddingModelOptions })) != null ? _a : {}, (_b = await parseProviderOptions({ provider: this.providerOptionsName, providerOptions, schema: openaiCompatibleEmbeddingModelOptions })) != null ? _b : {}); if (values.length > this.maxEmbeddingsPerCall) throw new TooManyEmbeddingValuesForCallError({ provider: this.provider, modelId: this.modelId, maxEmbeddingsPerCall: this.maxEmbeddingsPerCall, values }); const { responseHeaders, value: response, rawValue } = await postJsonToApi({ url: this.config.url({ path: "/embeddings", modelId: this.modelId }), headers: combineHeaders((_d = (_c = this.config).headers) == null ? void 0 : _d.call(_c), headers), body: { model: this.modelId, input: values, encoding_format: "float", dimensions: compatibleOptions.dimensions, user: compatibleOptions.user }, failedResponseHandler: createJsonErrorResponseHandler((_e = this.config.errorStructure) != null ? _e : defaultOpenAICompatibleErrorStructure), successfulResponseHandler: createJsonResponseHandler(openaiTextEmbeddingResponseSchema), abortSignal, fetch: this.config.fetch }); return { warnings, embeddings: response.data.map((item) => item.embedding), usage: response.usage ? { tokens: response.usage.prompt_tokens } : void 0, providerMetadata: response.providerMetadata, response: { headers: responseHeaders, body: rawValue } }; } }; var openaiTextEmbeddingResponseSchema = object({ data: array(object({ embedding: array(number()) })), usage: object({ prompt_tokens: number() }).nullish(), providerMetadata: record(string(), record(string(), any())).optional() }); var OpenAICompatibleImageModel = class _OpenAICompatibleImageModel { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v4"; this.maxImagesPerCall = 10; } get provider() { return this.config.provider; } /** * The provider options key used to extract provider-specific options. */ get providerOptionsKey() { return this.config.provider.split(".")[0].trim(); } static [WORKFLOW_SERIALIZE](model) { return serializeModelOptions({ modelId: model.modelId, config: model.config }); } static [WORKFLOW_DESERIALIZE](options) { return new _OpenAICompatibleImageModel(options.modelId, options.config); } getArgs(providerOptions, warnings) { warnIfDeprecatedProviderOptionsKey({ rawName: this.providerOptionsKey, providerOptions, warnings }); return { ...providerOptions[this.providerOptionsKey], ...providerOptions[toCamelCase(this.providerOptionsKey)] }; } async doGenerate({ prompt, n, size, aspectRatio, seed, providerOptions, headers, abortSignal, files, mask }) { var _a, _b, _c, _d, _e, _f, _g, _h, _i; const warnings = []; if (aspectRatio != null) warnings.push({ type: "unsupported", feature: "aspectRatio", details: "This model does not support aspect ratio. Use `size` instead." }); if (seed != null) warnings.push({ type: "unsupported", feature: "seed" }); const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date(); const args = this.getArgs(providerOptions, warnings); if (files != null && files.length > 0) { const { value: response2, responseHeaders: responseHeaders2 } = await postFormDataToApi({ url: this.config.url({ path: "/images/edits", modelId: this.modelId }), headers: combineHeaders((_e = (_d = this.config).headers) == null ? void 0 : _e.call(_d), headers), formData: convertToFormData({ model: this.modelId, prompt, image: await Promise.all(files.map((file) => fileToBlob(file))), mask: mask != null ? await fileToBlob(mask) : void 0, n, size, ...args }), failedResponseHandler: createJsonErrorResponseHandler((_f = this.config.errorStructure) != null ? _f : defaultOpenAICompatibleErrorStructure), successfulResponseHandler: createJsonResponseHandler(openaiCompatibleImageResponseSchema), abortSignal, fetch: this.config.fetch }); return { images: response2.data.map((item) => item.b64_json), warnings, usage: mapImageUsage(response2.usage), response: { timestamp: currentDate, modelId: this.modelId, headers: responseHeaders2 } }; } const { value: response, responseHeaders } = await postJsonToApi({ url: this.config.url({ path: "/images/generations", modelId: this.modelId }), headers: combineHeaders((_h = (_g = this.config).headers) == null ? void 0 : _h.call(_g), headers), body: { model: this.modelId, prompt, n, size, ...args }, failedResponseHandler: createJsonErrorResponseHandler((_i = this.config.errorStructure) != null ? _i : defaultOpenAICompatibleErrorStructure), successfulResponseHandler: createJsonResponseHandler(openaiCompatibleImageResponseSchema), abortSignal, fetch: this.config.fetch }); return { images: response.data.map((item) => item.b64_json), warnings, usage: mapImageUsage(response.usage), response: { timestamp: currentDate, modelId: this.modelId, headers: responseHeaders } }; } }; function mapImageUsage(usage) { var _a, _b, _c; return usage == null ? void 0 : { inputTokens: (_a = usage.input_tokens) != null ? _a : void 0, outputTokens: (_b = usage.output_tokens) != null ? _b : void 0, totalTokens: (_c = usage.total_tokens) != null ? _c : void 0 }; } var openaiCompatibleImageResponseSchema = object({ data: array(object({ b64_json: string() })), usage: object({ input_tokens: number().nullish(), output_tokens: number().nullish(), total_tokens: number().nullish() }).nullish() }); async function fileToBlob(file) { if (file.type === "url") return downloadBlob(file.url); const data = file.data instanceof Uint8Array ? file.data : convertBase64ToUint8Array(file.data); return new Blob([data], { type: file.mediaType }); } var VERSION = "3.0.53"; function createOpenAICompatible(options) { const baseURL = withoutTrailingSlash(options.baseURL); const providerName = options.name; const headers = { ...options.apiKey && { Authorization: `Bearer ${options.apiKey}` }, ...options.headers }; const getHeaders = () => withUserAgentSuffix(headers, `ai-sdk/openai-compatible/${VERSION}`); const getCommonModelConfig = (modelType) => ({ provider: `${providerName}.${modelType}`, url: ({ path }) => { const url = new URL(`${baseURL}${path}`); if (options.queryParams) url.search = new URLSearchParams(options.queryParams).toString(); return url.toString(); }, headers: getHeaders, fetch: options.fetch }); const createLanguageModel = (modelId) => createChatModel(modelId); const createChatModel = (modelId) => new OpenAICompatibleChatLanguageModel(modelId, { ...getCommonModelConfig("chat"), includeUsage: options.includeUsage, supportsStructuredOutputs: options.supportsStructuredOutputs, supportedUrls: options.supportedUrls, transformRequestBody: options.transformRequestBody, metadataExtractor: options.metadataExtractor, convertUsage: options.convertUsage }); const createCompletionModel = (modelId) => new OpenAICompatibleCompletionLanguageModel(modelId, { ...getCommonModelConfig("completion"), includeUsage: options.includeUsage }); const createEmbeddingModel = (modelId) => new OpenAICompatibleEmbeddingModel(modelId, { ...getCommonModelConfig("embedding") }); const createImageModel = (modelId) => new OpenAICompatibleImageModel(modelId, getCommonModelConfig("image")); const provider = (modelId) => createLanguageModel(modelId); provider.specificationVersion = "v4"; provider.languageModel = createLanguageModel; provider.chatModel = createChatModel; provider.completionModel = createCompletionModel; provider.embeddingModel = createEmbeddingModel; provider.textEmbeddingModel = createEmbeddingModel; provider.imageModel = createImageModel; return provider; } /** * 四家服务商。**全部走标准 chat/completions**。 * * 以前 ark 和 kimi 走 Responses API,为的是用它们服务端执行的联网搜索。 * 现在搜索改成客户端工具(ai/search.ts),Responses API 那套就没必要了 —— * 它换来的只有两份额外的 wire 方言和一堆 round-trip 的坑。 */ var PROVIDERS = { deepseek: { id: "deepseek", name: "DeepSeek 官方", baseURL: "https://api.deepseek.com", model: "deepseek-chat", canThink: true, think: "deepseek-reasoner", note: "推理强,配上联网搜索可用", apply: "platform.deepseek.com", zeroTemp: true }, glm: { id: "glm", name: "智谱 GLM", baseURL: "https://open.bigmodel.cn/api/paas/v4", model: "glm-5.3-flash", canThink: false, think: "glm-5.3-flash", note: "便宜、快,不开推理", apply: "bigmodel.cn", transform: function(body, think) { body.thinking = { type: think ? "enabled" : "disabled" }; return body; } }, ark: { id: "ark", name: "火山方舟 DeepSeek", baseURL: "https://ark.cn-beijing.volces.com/api/v3", model: "deepseek-v4-1-flash-260910", canThink: true, think: "deepseek-v4-1-flash-260910", note: "国内直连,速度稳", apply: "console.volcengine.com/ark", transform: function(body, think) { body.thinking = { type: think ? "enabled" : "disabled" }; return body; } }, kimi: { id: "kimi", name: "Kimi K3", baseURL: "https://api.moonshot.cn/v1", model: "kimi-k3", canThink: true, think: "kimi-k3", note: "1M 上下文,自带缓存;联网搜索也是它家的", apply: "platform.kimi.com", effort: { on: "high", off: "low" } } }; var PROV_ORDER = [ "deepseek", "glm", "ark", "kimi" ]; function pk(id, base) { return id === "deepseek" ? base : base + "_" + id; } /** * 把用户填的地址削成 baseURL。 * * 老版本这里存的是完整接口地址(`…/chat/completions`、`…/responses`), * 升级后这些值还在 GM 存储里躺着。不削掉后缀的话 AI SDK 会再接一次, * 变成 `/chat/completions/chat/completions`,一律 404,而且报错里看不出为什么。 */ function toBaseURL(url) { return url.replace(/\/+$/, "").replace(/\/(chat\/completions|responses|completions)$/, ""); } function str(read, key, dflt) { const v = read(key); return typeof v === "string" ? v : dflt; } function bool(read, key, dflt) { const v = read(key); return typeof v === "boolean" ? v : dflt; } function isProviderId(id) { return Object.prototype.hasOwnProperty.call(PROVIDERS, id); } function provId(read) { const id = str(read, "ai_provider", "deepseek"); return isProviderId(id) ? id : "deepseek"; } function aiConf(read) { const id = provId(read), P = PROVIDERS[id]; const think = bool(read, "ai_think", true); const kimiKey = str(read, pk("kimi", "ai_key"), ""); return { id, P, url: toBaseURL(str(read, pk(id, "ai_url"), "") || P.baseURL), key: str(read, pk(id, "ai_key"), "") || "", think: !!(think && P.canThink), model: str(read, pk(id, "ai_model"), "") || (think && P.canThink ? P.think : P.model), searchKey: str(read, "ai_search_key", "") || kimiKey, searchSites: str(read, "ai_search_sites", "").split(/[,,\s]+/).map(function(s) { return s.trim(); }).filter(Boolean).slice(0, 5) }; } //#endregion //#region src/env.ts /** * 宿主环境适配层。 * * 存在的理由只有一个:让业务代码永远不要直接摸全局。 * 生产环境这里转发给 easy-us 的 $gm / 页面全局,测试里整个模块被 vi.mock 掉换成假的。 * * 两条硬规矩: * 1. 一律做成函数,不要做成模块顶层求值的常量 —— * 脚本是 document-start 注入的,模块求值那一刻 document.body 还不存在; * vitest 里 import 顺序也会咬人。 * 2. hook ajax 必须打在 unsafeWindow 上。带 @grant 时脚本跑在沙箱里, * 改沙箱的 fetch / XMLHttpRequest 影响不到页面本身。 */ /** 页面真正的 window(不是沙箱里那个) */ function win() { return import_lib.$gm.unsafeWindow; } /** 当前帧的 document。每次现取,不缓存 */ function doc() { return document; } /** * 脚本管理器有没有给跨域请求权限。 * 业务代码不要直接写 `typeof GM_xmlhttpRequest !== 'function'` —— * 那样就绕过了这一层,测试里没法替换。 */ function hasXhr() { return typeof GM_xmlhttpRequest === "function"; } /** 跨域请求。走油猴通道,绕过页面 CSP 和同源限制 */ function xhr(options) { return GM_xmlhttpRequest(options) || {}; } var LOG = "[雨课堂助手]"; //#endregion //#region src/ai/fetch-gm.ts /** * 把 GM_xmlhttpRequest 包成一个 WHATWG `fetch`,好让 AI SDK 直接用。 * * 为什么非要这一层:AI SDK 的 provider 只认 `fetch`,而油猴脚本里 * 页面自带的 `fetch` 过不了跨域(雨课堂的 CSP + 三方 API 没有 CORS 头)。 * 只有 GM 通道能出去。两边接口差得远,中间得有个翻译。 * * ⚠️ 四条硬规矩,改这个文件之前先看完: * * 1. **`responseText` 是累积全文,不是增量。** * GM_xmlhttpRequest 每次 onprogress 给的都是「到目前为止的全部正文」。 * 所以要自己记 cursor,只把新长出来的那截推进流里。 * 忘了这条的话,SSE 会被重复解析几十遍。 * * 2. **onprogress 只是「提前拿到」,不是数据来源。** * 给不给部分正文取决于脚本管理器(Tampermonkey 给,别家不一定)。 * onload 里必须把完整的 responseText 再走一遍 cursor 补完 —— * 一个字都没 onprogress 过的管理器上,整套逻辑退化成「收完一次性给」, * 功能不变,只是没有滚动的思考过程。 * * 3. **Response 必须在拿到 header 的那一刻就 resolve,不能等收完。** * 等收完就不叫流式了。所以 body 是一个先建好的 ReadableStream, * resolve 在先,数据在后慢慢灌。 * * 4. **不走 Tampermonkey 的 `responseType:'stream'`。** * 它只有 Tampermonkey 有,等于要维护两条路径、两套测试, * 而上面这条 cursor 路径在本项目生产环境已经跑了几个版本。 * 我们的响应体只有几 KB,累积文本的开销可以忽略。 */ /** 把 GM 给的那坨 CRLF 分隔的头文本解析成 Headers */ function parseHeaders(raw) { const h = new Headers(); if (!raw) return h; const lines = raw.split(/\r?\n/); for (let i = 0; i < lines.length; i++) { const line = lines[i]; const at = line.indexOf(":"); if (at <= 0) continue; const name = line.slice(0, at).trim(); const value = line.slice(at + 1).trim(); if (!name) continue; try { h.append(name, value); } catch (e) {} } return h; } /** init.headers 可能是 Headers、二元组数组或普通对象,统一成普通对象 */ function toHeaderRecord(src) { const out = {}; if (!src) return out; if (typeof src.forEach === "function" && !(src instanceof Array)) { src.forEach(function(v, k) { out[k] = v; }); return out; } if (src instanceof Array) { for (let i = 0; i < src.length; i++) out[src[i][0]] = src[i][1]; return out; } const rec = src; const keys = Object.keys(rec); for (let i = 0; i < keys.length; i++) { const v = rec[keys[i]]; if (v !== void 0 && v !== null) out[keys[i]] = String(v); } return out; } /** * 切掉末尾落单的高代理位。 * * responseText 是管理器按字符解码好的,理论上不会把一个 UTF-16 代理对劈开, * 但 emoji 恰好压在分块边界上时个别管理器会。真劈开了再 encode 就成了 U+FFFD, * JSON.parse 直接炸。留到下一块再拼。 */ function trimDangling(s) { if (!s) return s; const last = s.charCodeAt(s.length - 1); return last >= 55296 && last <= 56319 ? s.slice(0, -1) : s; } /** * fetch over GM_xmlhttpRequest。 * * 只实现 AI SDK 真正会用到的那一小块:method / headers / body(string) / signal, * 返回的 Response 带正确的 status、headers 和流式 body。 * 不支持 FormData、Blob、redirect 控制这些 —— 用不到,也没法用 GM 通道实现。 */ function createGmFetch(opts) { const timeout = opts && opts.timeout || 3e5; return function gmFetch(input, init) { const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url; const method = init && init.method || "GET"; const headers = toHeaderRecord(init && init.headers); const data = init && typeof init.body === "string" ? init.body : void 0; const signal = init && init.signal; return new Promise(function(resolve, reject) { let cursor = 0; let settled = false; let closed = false; let controller = null; const enc = new TextEncoder(); const body = new ReadableStream({ start: function(c) { controller = c; }, cancel: function() { closed = true; if (handle && handle.abort) handle.abort(); } }); function pump(text) { if (closed || !controller) return; if (text.length <= cursor) return; const chunk = trimDangling(text.slice(cursor)); if (!chunk) return; cursor += chunk.length; try { controller.enqueue(enc.encode(chunk)); } catch (e) { closed = true; } } function close() { if (closed || !controller) return; closed = true; try { controller.close(); } catch (e) {} } function fail(err) { if (controller && !closed) { closed = true; try { controller.error(err); } catch (e) {} } if (!settled) { settled = true; reject(err); } } function settle(res) { if (settled) return; settled = true; resolve(new Response(body, { status: res.status || 200, statusText: "", headers: parseHeaders(res.responseHeaders) })); } let handle; if (signal) { if (signal.aborted) { fail(signal.reason || new DOMException("Aborted", "AbortError")); return; } signal.addEventListener("abort", function() { if (handle && handle.abort) handle.abort(); fail(signal.reason || new DOMException("Aborted", "AbortError")); }); } handle = xhr({ method, url, headers, data, timeout, onprogress: function(res) { settle(res); pump(res.responseText || ""); }, onload: function(res) { settle(res); pump(res.responseText || ""); close(); }, onerror: function(err) { const why = err && (err.error || err.statusText) || "unknown"; fail(/* @__PURE__ */ new TypeError("网络请求失败:" + why)); }, ontimeout: function() { fail(/* @__PURE__ */ new TypeError("请求超时(" + Math.round(timeout / 1e3) + " 秒)")); } }); }); }; } //#endregion //#region src/ai/search.ts /** * 联网搜索工具:Kimi 的 `/v1/tools/search_pro`,包成一个**普通的客户端 function tool**。 * * ⚠️ 为什么是独立接口,不是模型自带的联网搜索 —— 三个理由,缺一条都不够: * * 1. **Kimi 的 `$web_search` 内置工具官方宣布 2026-10-20 前后下线**, * 并且 kimi-k3 的文档页明写「联网搜索正在更新,近期不建议用于生产流程」。 * 我们生产日志里那些怪事(工具调用被吞、模型自称 "simulated web_search"、 * 结果全无用)跟这句话完全对得上。 * * 2. **服务端执行的搜索,AI SDK 根本接不上 Kimi。** * Moonshot 的 Responses API 要求「把上一轮的 output 原样追加到 input」, * 它没有 store / previous_response_id / item_reference。 * 而 @ai-sdk/openai 的 responses 实现只认 OpenAI 那两种模式: * store:true 会把工具调用换成 item_reference(Moonshot 不认), * store:false 直接丢掉 web_search_call、并过滤掉没有 encrypted_content 的 * reasoning 项(Moonshot 从不带这个字段)。两条路都会让模型断定自己没有联网能力。 * 做成**普通 tool** 就完全绕开了这一整片雷区 —— 普通 tool 的一问一答 * 在任何 provider 里都是原样 round-trip 的。 * * 3. **四家模型都能用了。** 以前只有 Kimi / GLM / 方舟能联网,DeepSeek 只能靠记忆。 * 现在搜索和模型解耦,选谁都能查题库。 * * 额外白赚的一条:search_pro 收 `sites`(最多 5 个,OR 关系), * 可以把检索钉死在题库站上 —— 这正是 prompt 里「第一次搜的必须是题库」 * 一直靠嘴说、一直说不动的那条规则。 */ /** 官方接口地址。用户改不了,这个不是「服务商」而是一个固定的工具 */ var SEARCH_URL = "https://api.moonshot.cn/v1/tools/search_pro"; /** 一次返回几条。1-20,接口限制 */ var LIMIT = 5; /** 每条正文片段留几段。超过纯属灌上下文 */ var CHUNKS_PER_RESULT = 2; /** 单段正文截断长度。6 道题 × 5 条结果 × 2 段,不截会把上下文撑爆 */ var CHUNK_CHARS = 400; var SNIPPET_CHARS = 200; function cut(s, n) { const t = typeof s === "string" ? s.trim() : ""; return t.length > n ? t.slice(0, n) + "…" : t; } /** * 把接口返回的一坨 JSON 压成给模型看的文本。 * * 返回字符串而不是对象:一样好用,但省 token,而且截断逻辑只有一处。 * chunks 按 score 取最高的两段 —— 这些才是页面正文,snippet 往往只是标题的复读。 */ function formatResults(results) { const out = []; for (let i = 0; i < results.length; i++) { const r = results[i] || {}; const head = [ cut(r.title, 120) || "(无标题)", r.site_name ? "|" + cut(r.site_name, 40) : "", r.date ? "|" + cut(r.date, 20) : "" ].join(""); const lines = ["[" + (i + 1) + "] " + head]; if (r.url) lines.push(" " + cut(r.url, 200)); const snip = cut(r.snippet, SNIPPET_CHARS); if (snip) lines.push(" 摘要:" + snip); const chunks = (r.chunks || []).slice().sort(function(a, b) { return (b.score || 0) - (a.score || 0); }).slice(0, CHUNKS_PER_RESULT); for (let j = 0; j < chunks.length; j++) { const t = cut(chunks[j].text, CHUNK_CHARS); if (t) lines.push(" 正文:" + t); } out.push(lines.join("\n")); } return out.join("\n\n"); } /** * 出错时返回给模型一句人话,**不要抛异常**。 * * 抛出去的话 AI SDK 会中断整轮,一道题都答不出来; * 返回一句「这次没搜到,换个词再试」模型会自己重试,代价小得多。 */ function excuse(why) { return "本次检索失败:" + why + "。请换一个更短的搜索词再试一次;连续失败两次就不要再搜这道题了,用你已经查到的内容作答。"; } function createSearchTool(d) { return tool({ description: "联网搜索。一次只能搜一个查询词、一道题。搜索词放这道题的题干那一句话,末尾跟上「答案」两个字;不要带选项、不要带换行、不要把几道题拼在一起。", inputSchema: object({ text_query: string().describe("搜索词。一句话,30 字以内,不含选项和换行"), sites: array(string()).max(5).optional().describe("可选:把结果限定在这几个站点内(最多 5 个,域名形式,如 \"chaoxing.com\")") }), execute: async function({ text_query, sites }) { const query = (text_query || "").trim(); if (!query) return excuse("搜索词是空的"); if (d.log) d.log("🔍 " + cut(query, 60)); const use = (sites && sites.length ? sites : d.sites || []).slice(0, 5); const body = { text_query: query, limit: LIMIT, timeout_seconds: 30 }; if (use.length) body.sites = use; let res; try { res = await d.fetchImpl(SEARCH_URL, { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + d.key }, body: JSON.stringify(body) }); } catch (e) { return excuse("网络不通(" + String(e && e.message) + ")"); } if (res.status === 429) return excuse("触发了搜索接口的频率限制,请稍等一下再搜"); if (res.status === 401 || res.status === 403) return excuse("搜索接口的 Key 无效或未激活,本次作业请不要再联网检索了"); if (!res.ok) { const t = await res.text().catch(function() { return ""; }); return excuse("接口返回 HTTP " + res.status + " " + cut(t, 120)); } let json; try { json = await res.json(); } catch (e) { return excuse("返回的不是合法 JSON"); } const list = json.search_results || []; if (!list.length) return "这个搜索词没有搜到任何结果。换一组关键词再试:可以去掉题干末尾几个字,或者只用题干里最长的那个专有短语。"; return formatResults(list); } }); } //#endregion //#region src/ai/ticker.ts /** * 进度条用的滚动字幕。 * * 思考过程是拿来当进度条的,不是拿来读的 —— 所以这里 **只保留当前这一行的尾巴**, * 上限写死 CAP 个字符。模型想几万字,这里占的内存永远是常数。 * * 「一行结束就清空」正好对上 prompt 的排版:第一轮是逐题一行 * (第N题|搜索词:…|题库命中:…),所以每做完一道题,字幕自然翻篇, * 不会把上一道题的残尾拖在屏幕上。 * * 节流是必须的,不是优化:题目帧里的字幕要隔着 iframe 送到顶层面板, * 而跨帧通道底层是 GM_setValue(见 lms/bridge.ts)。不节流就是每秒上百次 * 写脚本管理器的存储,页面会肉眼可见地卡。 */ /** 字幕最多显示多少个字符 —— 再长也塞不进面板那一行 */ var CAP = 56; /** 两次刷新之间至少隔多久(毫秒)。2 次/秒,看着是在动,又不会把 GM 存储写爆 */ var MIN_MS = 500; function createTicker() { return { line: "", last: 0, shown: "" }; } /** * 喂一小段增量进来,需要刷新时返回该显示的字符串,否则返回 null。 * * now 由调用方传(Date.now()),不在这里取 —— 测试要能精确控制节流边界。 */ function pushTicker(t, s, now) { if (s) { t.line += s; const nl = t.line.lastIndexOf("\n"); if (nl >= 0) t.line = t.line.slice(nl + 1); if (t.line.length > CAP) t.line = t.line.slice(-56); } if (now - t.last < MIN_MS) return null; const out = t.line.trim(); if (out === t.shown) return null; t.last = now; t.shown = out; return out; } /** 一轮结束,把字幕清掉。返回 true 表示确实需要通知界面清空 */ function clearTicker(t) { t.line = ""; t.last = 0; if (!t.shown) return false; t.shown = ""; return true; } //#endregion //#region src/ai/prompt.ts var ANS_MARK = "===答案==="; /** * 拼题目正文。 * * 用模板字符串而不是 '\n' 拼接:这段文字本身就是给人看的排版, * 源码里长什么样、发出去就是什么样,改起来不用数换行符。 */ function formatQuestions(ex) { return ex.list.map((q) => { const opts = q.options.map((o) => `${o.key}. ${o.text}`).join("\n"); return `【第${q.index}题】${q.type}\n${q.body}\n${opts}`; }).join("\n\n"); } /** * 三轮协议:检索 → 复核 → 定稿。**这一段必须逐字不变。** * * ⚠️ 为什么规则写在题目前面,而不是像人说话那样「题目 → 要求」: * 这是给 KV cache 让路。Kimi(≥256 token 自动缓存)、DeepSeek、方舟 * 都是 **前缀匹配** 命中缓存 —— 只有从第一个 token 起完全一致的那一段才算数。 * 题目每份作业都不一样,规则却是死的;规则放后面的话, * 可缓存的前缀就只剩一条 system 消息,这一千来字每次都要重新算。 * 所以顺序固定成:system(不变)→ 规则(不变)→ 题目(每次不同)。 * 改这一段的任何一个字,都会让所有老用户的缓存失效一次 —— 改可以,别反复改。 * * 为什么要把轮次写死在 prompt 里,而不是只说一句「仔细一点」: * - 只嘱咐「小心」的话模型会一轮出完答案,根本不会回头再搜第二次; * - 把「复核:」做成一个必须出现的段落标题,它就得真的再看一遍 —— * 这是逼出第二次检索最省事的办法; * - 答案段永远在最后,而 parseAnswers 只取 **最后一个** ===答案=== 之后的内容, * 所以前面写多少轮分析都不会污染解析。 * * 下面这几条是按「实际错在哪」一条一条加上去的,别当成啰嗦话删掉: * * - **逐题一行的检索台账**(第N题|搜索词|题库命中|…)。 * 只说「每道题都要搜」的话,模型会搜两三道有代表性的,剩下的一并「推断」过去, * 而且它写出来的分析读着还挺像真搜过。逼它对每道题各写一行、且必须填进 * 自己实际用的搜索词,才能把这种批量糊弄变成看得见的空白。 * - **题库命中的题,复核只能确认、不许改**。这是掉分最快的一条路: * 第一轮搜到了题库的正确答案,第二轮模型一「深入思考」, * 用自己那套(往往事实上也没错的)推理把它改掉了。判分的是题库,不是事实。 * - **多选题至少两项**。模型在多选题上系统性地少选,经常只给一个字母; * 而「只想选一个」这件事本身就是「没搜到题库答案」的可靠信号,所以直接让它回去重搜。 * - **定稿前先数一遍**(自检行)。漏题是第二常见的错:10 题的作业只给 8 行答案, * 剩下两题 fillCurrent 填不上、直接卡住。先写「共N题」这一行,能把漏的逼出来。 * - **字母只能从该题自己列出的选项里选**。模型偶尔会给出 E,而题目只有 A-D。 * - **必须在这一次回复里做完**。K3 是按 agent 循环训练的:搜一次没命中就回一句 * 「第一次题库检索未命中,继续换关键词搜题库。」然后 status 直接 completed, * 它默认有人会再叫它一次。ask.ts 的续写循环是兜底,但先在 prompt 里堵一道更省钱。 * - **至少换三组关键词才准说「没命中」**。实测它搜一次没命中就回一句 * 「第一次题库检索未命中,继续换关键词搜题库。」然后收尾 —— 一次都没换过关键词。 * - **搜索词只许放题干那一句,不许带选项**。这条是拿真 Key 打出来的: * 只说「把题干原文当作一整句去搜」,它会把整块题目连选项一起粘进搜索框, * 还重复一遍、再带上下一道题,最后被截断 —— * 「当代国家安全基本构成要素共有( )。 A. 10个 B. 11个… 核安全是当代国家安全的( )。 A」。 * 更早一次(开着并行工具调用时)是把六个查询用分号拼成一句。两种都零结果, * 然后它就以「题库未命中」为由放弃。并行那一头在 PROVIDERS.kimi 里用 * parallel_tool_calls:false 关掉了,这一头只能在 prompt 里堵。 */ var RULES = `这是中国高校的课程章节测验,考的是教材原文和具体事实。题目在本条消息的末尾。 先说四条不许犯的错 —— 这四条是历次做错最多的地方: 一、不许凭记忆作答。没有检索依据就写答案,一律算错。 二、题库搜到的答案就是标准答案,不许用自己的推理去推翻它。判分依据是这门课的题库,不是客观事实;你的推理再严密,和题库不一致,在这门课里就是错的。 三、不许漏题。最后必须每一道题都给出答案,一道不少。 四、必须在这一次回复里做完。不许写「继续搜」「下一步再看」这类话就收尾 —— 没做完就一直做下去,直到写出答案段为止。 按下面三轮来做,三轮都要写出来: 【第一轮 · 检索】 必须联网检索。逐题来,一道都不许跳,每道题写成这样一行: 第N题|搜索词:<你实际搜的那一句>|题库命中:是/否|题库答案:<字母,没命中写「无」>|来源:<站点名或文献名> 这一行写不出来,就说明你根本没搜这道题,回去搜。 检索方法按这个顺序来: · 第一次搜的必须是题库:搜索词只放**这一道题的题干原文**,当作一整句去搜,末尾跟上「答案」两个字。三个不许:不许带选项(A. B. C. D. 那几行)、不许带别的题、不许带换行。括号、空格、题号也去掉。整条搜索词控制在 30 字以内; · 这样搜不到,就去掉题干末尾几个字再搜一次,或者只用题干里最长的那个专有短语去搜; · 题库确实搜不到(命中写「否」),才用题干里的专有名词(文件名、机构名称、会议届次、年份、法条序号)分别检索,核实事实之后再推断。 · 一次只发一个搜索词,一次只搜一道题。不许把几个查询用分号或逗号拼成一句,也不许把整段题目原样粘进搜索框 —— 那样一条结果都搜不到。 · 一道题至少换三组不同的关键词搜过,才准写「题库命中:否」。搜一次没搜到就下结论,是这里最常犯的错。 【第二轮 · 复核】 这一段必须以「复核:」开头,不许省略。 · 题库命中的题:复核只能确认,不许改。唯一能推翻它的情况是你找到了**另一个题库站给出不同答案**,那才算矛盾 —— 这时写明两边各是什么、你信哪一边、为什么。自己觉得题库错了不算理由。 · 题库没命中的题:逐题换一组关键词再搜一次。年份、机构名称、文件名、会议届次这几类最容易记混,把候选逐个和检索到的原文对照,确认之后写明你排除了谁、为什么。 · 多选题再单独过一遍:多选题至少选两项。如果你只想给一个字母,那就是还没搜到题库答案,回去重搜。 · 全部确凿无疑的话就写「复核:无存疑」,不要为了凑字数编内容。 【第三轮 · 定稿】 先写一行自检:「自检:共N题,题库命中K题,存疑M题」,N 必须等于上面给出的题目总数。 然后另起一行只写 ${ANS_MARK} 这一行之后每题一行,格式「题号. 答案字母 | 不超过25字的依据」。 · 题号从 1 连续写到最后一题,一道不许少,不许合并、不许写「同上」; · 字母只能从那道题自己列出的选项里选,没列出来的字母不许出现; · 多选题把字母按 A B C D 的顺序连写(如 ABD),中间不要加逗号或空格; · 依据要来自检索到的内容,别写「根据常识」「凭印象」;来自题库的就写「题库」; · 每题都必须给出一个确定的字母,不许空着、不许写「无法确定」;两轮检索之后仍然没把握的,选最可能的一个,并在依据里以「存疑:」开头标出来; · ${ANS_MARK} 之后不要再写任何别的内容。`; /** * system 消息。**这段必须逐字不变。** * * 它和下面的 RULES 一起构成可缓存的前缀: * 每次请求只有末尾的题目不同,前面这一千来字才能命中各家的上下文缓存。 * (原本在 ai/body.ts 里;那个文件随着 AI SDK 接管请求整形一起删了, * 搬到这里是让整个可缓存前缀待在同一个文件里。) */ var SYSTEM = "你是严谨的中文做题助手,面对的是中国高校思政 / 国家安全教育一类的课程章节测验。这类题考的是教材原文和具体事实(年份、文件名、机构名称、会议届次、法条序号),凭印象极易出错。硬规矩一:每道题都要先联网检索核实,再下结论;没有检索依据就不要给判断。硬规矩二:每道题的第一次检索必须是拿题干原文去搜题库;题库答案和你自己的推断冲突时,以题库答案为准 —— 判分的是课程题库,不是客观事实。检索结果互相矛盾或者含糊的时候,换关键词再搜一轮,不许把第一条搜索结果当定论。"; /** * 一次问整份作业的对话开头。顺序固定: * instructions(不变)→ RULES(不变)→ 题目(每次不同)。 * * ⚠️ system 要单独拿出来放进 streamText 的 `instructions`: * AI SDK v7 不允许 messages 里出现 system 角色(直接报 * "System messages are not allowed in the prompt or messages fields")。 * 发出去的请求体里它仍然是 messages[0] 的 system,缓存前缀不受影响。 */ function buildMessages(ex) { return { instructions: SYSTEM, messages: [{ role: "user", content: buildPrompt(ex) }] }; } /** * 规则在前、题目在后。顺序别调回来,理由见 RULES 上面那段注释。 */ function buildPrompt(ex) { return `${RULES} ———————————————— 下面是《${ex.name || "练习"}》的全部 ${ex.list.length} 道题: ${formatQuestions(ex)}`; } /** * 从 AI 回复里解析答案。legacy 里这段在 askAll 的 onload 中,抽出来是为了能单测。 * 解析不出来时返回两个空对象,由调用方判断 Object.keys(answers).length。 */ function parseAnswers(text) { const cut = text.lastIndexOf(ANS_MARK); const tail = cut === -1 ? text : text.slice(cut + 8); const ans = {}, why = {}; let mm; const re = /^\s*(\d+)\s*[.、).]\s*([A-Za-z]+)\s*(?:[||::-]\s*(.*))?$/gm; while ((mm = re.exec(tail)) !== null) { const n = parseInt(mm[1], 10); ans[n] = mm[2].toUpperCase(); if (mm[3]) why[n] = mm[3].trim(); } return { answers: ans, why }; } //#endregion //#region src/ai/ask.ts /** * 问 AI:整份作业一次问完。 * * 相对 legacy 的三处解耦(其余逻辑一行没动): * 1. 面板日志 say() 改成注入的 log 回调 —— 这里绝不 import UI 模块; * 2. 模块级的 EX / busy 不在这里持有,题目当参数进来,答案当回调出去; * 3. 网络请求走 src/env.ts 的 xhr(),不直接调 GM_xmlhttpRequest * (现在隔了一层:ai/fetch-gm.ts 把它包成 fetch 交给 AI SDK)。 * * 「一次问完」不是一个 HTTP 请求 —— 模型每搜一次就是一轮,一份作业可能十几轮。 * 所以 busy 标志的生命周期是整条链路,不是单个请求。 * * ⚠️ **这个文件以前自己解 SSE、自己接力工具调用、自己降级重试,现在都不做了。** * 那一整套换成了 AI SDK 的 streamText:SSE 解析、工具循环、重试、 * 把模型回复原样追回对话,全是它的事。这里只剩三件 SDK 管不了的: * 1. 催它接着做(见 MAX_CONTINUE / NUDGE)—— 模型自己收尾了,SDK 认为正常结束; * 2. didWork 判定 —— 区分「没写完」和「真的空回复」; * 3. 答案解析和面板文案。 */ /** * 一次 streamText 里允许模型走多少步(每次工具调用算一步)。 * * 一份 10 题的作业,一题搜一两次,正常在 10 步以内收尾。 * 给到 24 是留余量;超过就是它卡在「搜 → 再搜」的循环里出不来了, * 这时候必须硬停 —— 每一步都是一次真实计费的请求,放任下去能烧掉一整份额度。 */ var MAX_STEPS = 24; /** * 催它接着写的次数上限。 * * 每催一次都要把整段对话重发一遍,越往后越贵(前缀缓存能省下大头,但输出照付)。 * 6 次足够把一份十来道题的作业搜完;还不收口就是它在原地打转,硬停。 */ var MAX_CONTINUE = 6; var NUDGE = "接着做,别停。不要回复「继续搜」「下一步」这类过渡语 —— 把没做完的检索和复核补完,然后在这一次回复里给出完整的 ===答案=== 段。"; var FINAL_NUDGE = "这是最后一次回复,不要再检索了。根据你已经查到的内容直接定稿:现在就输出 ===答案=== 段,每题一行,一道都不许少。没把握的题用「存疑:」标出来,但必须给字母。"; /** 吐一小段字幕。节流和长度上限都在 ticker 里,这里不判断 */ function tickle(r, s) { if (!r.d.tick || !s) return; const out = pushTicker(r.ticker, s, Date.now()); if (out !== null) r.d.tick(out); } /** 一轮结束,把字幕擦掉。所有会清 busy 的路径都要叫一次,不然进度条会挂在那 */ function untick(r) { if (r.d.tick && clearTicker(r.ticker)) r.d.tick(""); } /** * 把这一轮的全貌打进控制台。由「把思考过程打进控制台」那个开关控制,默认关。 * * 分组折叠起来,不然一份作业能刷几百行。 * ⚠️ 只打对话内容,绝不打 headers —— API Key 在 Authorization 头里, * 打出来会跟着用户的截图和录屏一起泄出去。 */ function dump(model, round, messages, cot, text) { (console.groupCollapsed ? console.groupCollapsed.bind(console) : console.log.bind(console))(LOG + " 调试 · " + model + " · 第 " + round + " 轮"); console.log("对话(Key 在请求头里,这里没有):", messages); console.log("思考过程 CoT:\n" + (cot || "(这次没返回思考过程)")); console.log("正文:\n" + (text || "(空)")); if (console.groupEnd) console.groupEnd(); } function errText(e) { if (!e) return "未知错误"; const m = e.message; return typeof m === "string" && m ? m : String(e); } /** 跑一轮 streamText,把流里的东西分流到字幕和累加器上 */ async function once(r, model) { const turn = { text: "", cot: "", searches: 0, steps: 0, error: null }; const result = streamText({ model, instructions: r.instructions, messages: r.messages, tools: r.c.searchKey ? { web_search: createSearchTool({ key: r.c.searchKey, sites: r.c.searchSites, fetchImpl: createGmFetch({ timeout: 6e4 }), log: function(line) { r.searches++; turn.searches++; tickle(r, "\n" + line); } }) } : {}, stopWhen: isStepCount(MAX_STEPS), temperature: r.c.P.zeroTemp && !r.c.think ? 0 : void 0, providerOptions: r.c.P.effort ? { [r.c.id]: { reasoningEffort: r.c.think ? r.c.P.effort.on : r.c.P.effort.off } } : void 0, onError: function(e) { turn.error = e.error || e; } }); try { for await (const part of result.fullStream) if (part.type === "reasoning-delta") { if (r.debug) turn.cot += part.text; tickle(r, part.text); } else if (part.type === "text-delta") { turn.text += part.text; tickle(r, part.text); } else if (part.type === "finish-step") turn.steps++; else if (part.type === "error") turn.error = part.error; } catch (e) { turn.error = e; } if (!turn.error) try { const msgs = (await result.response).messages; for (let i = 0; i < msgs.length; i++) r.messages.push(msgs[i]); } catch (e) { turn.error = e; } return turn; } function askAll(d) { const ex = d.ex; if (!ex) { d.log("还没拿到题目,点 🔄 重新抓题"); return; } const c = aiConf(d.read); if (!c.key) { d.log("先点 ⚙️ 填 " + c.P.name + " 的 API Key"); return; } if (!hasXhr()) { d.log("脚本管理器没给 GM_xmlhttpRequest 权限"); return; } if (d.isBusy()) return; d.setBusy(true); const head = buildMessages(ex); const r = { d, c, ex, instructions: head.instructions, messages: head.messages, debug: !!d.read("ai_debug"), ticker: createTicker(), searches: 0 }; if (!c.searchKey) d.log("⚠️ 没配联网搜索的 Key,答案全靠模型记忆,教材细节题很容易错。点 ⚙️ 填一个 Kimi Key 就能联网。"); d.log("正在问 " + c.model + (c.searchKey ? "(联网搜索" + (c.think ? "+推理" : "") + ")" : c.think ? "(推理模式,可能要等一分钟)" : "") + "…"); drive(r); } /** 整条链路。每个出口都要清 busy 和字幕,漏一条面板就永久卡在「正在问…」 */ async function drive(r) { const d = r.d, c = r.c; const model = createOpenAICompatible({ name: c.id, baseURL: c.url, apiKey: c.key, fetch: createGmFetch({ timeout: 3e5 }), transformRequestBody: c.P.transform ? function(body) { return c.P.transform(body, c.think); } : void 0 }).chatModel(c.model); /** 所有轮次的正文接起来。parseAnswers 取的是**最后一个** ===答案===,接起来没有副作用 */ let all = ""; try { for (let round = 1;; round++) { const turn = await once(r, model); if (r.debug) dump(c.model, round, r.messages, turn.cot, turn.text); if (turn.error) { finish(r); d.log("请求出错:" + errText(turn.error)); console.warn(LOG, turn.error); return; } all += (all && turn.text ? "\n" : "") + turn.text; if (all.indexOf("===答案===") !== -1) break; if (!(!!turn.text || turn.steps > 1 || turn.searches > 0)) { finish(r); d.log("AI 返回了空内容,原始回复看 Console"); console.warn(LOG, r.messages); return; } if (round > MAX_CONTINUE) { finish(r); d.log("催了 6 次还是没给答案段,放弃。原始回复看 Console"); console.warn(LOG, all); return; } const last = round === MAX_CONTINUE; r.messages.push({ role: "user", content: last ? FINAL_NUDGE : NUDGE }); d.log(last ? "还是没给答案,最后催一次,让它拿现有结果直接定稿…" : "模型没给答案就收尾了,催它接着做(第 " + round + "/6 次)…"); } } catch (e) { finish(r); d.log("请求出错:" + errText(e)); console.warn(LOG, e); return; } finish(r); console.log(LOG, "AI 原始回复:\n" + all); const parsed = parseAnswers(all); const ans = parsed.answers, why = parsed.why; if (!Object.keys(ans).length) { d.log("没解析出答案,原始回复看 Console"); return; } d.onAnswers(ans, why); const net = !c.searchKey ? "" : r.searches > 0 ? "(联网检索 " + r.searches + " 次)" : "⚠️(一次都没联网,答案靠记忆)"; d.log("✅ " + r.ex.list.map(function(q) { return q.index + ":" + (ans[q.index] || "?"); }).join(" ") + net + (d.read("ai_go") ? "" : "\n(只勾选,不提交)")); const doubt = r.ex.list.filter(function(q) { return /^存疑/.test(why[q.index] || ""); }); if (doubt.length) d.log("⚠️ 第 " + doubt.map(function(q) { return q.index; }).join("、") + " 题 AI 自己也没把握,交卷前最好看一眼。"); d.onReady(); } /** 收尾:清 busy、擦字幕。每一条出口都得叫,漏一条面板就再也点不动解题 */ function finish(r) { r.d.setBusy(false); untick(r); } //#endregion //#region src/scripts/configs.ts /** * 各家服务商的凭据配置项。 * * 单独成文件、且不 import easy-us,是为了能单测 —— * 这里的键名必须和 ai/providers.ts 的 pk(id, base) 算出来的完全一致, * 一旦对不上,各家就会悄悄共用同一个 Key,而界面上看不出任何异常。 * test/config-keys.spec.ts 就是守这一条的。 */ var PROVIDER_KEY = "ykt.answer.ai_provider"; /** 灰色小字。必须 display:block 自己占一行 —— 跟输入框挤在同一个 table-cell 里会被裁掉 */ function hint(text) { return "" + text + ""; } /** 各家服务商各存各的 Key —— 键名由 ai/providers.ts 的 pk(id, base) 决定,别在这里改名 */ function credConfigs() { const out = {}; for (const id of PROV_ORDER) { const P = PROVIDERS[id]; const only = [PROVIDER_KEY, (c) => c === id]; out[pk(id, "ai_key")] = { label: "API Key", attrs: { type: "password", placeholder: "sk-…" }, defaultValue: "", showIf: only, suffixSlot: hint("申请:" + P.apply) }; out[pk(id, "ai_model")] = { label: "模型", attrs: { type: "text", placeholder: "留空用默认:" + P.model }, defaultValue: "", showIf: only }; out[pk(id, "ai_url")] = { label: "接口地址", attrs: { type: "text", placeholder: "留空用默认(OpenAI 兼容)" }, defaultValue: "", showIf: only }; } return out; } //#endregion //#region src/exercise/capture.ts /** * 抓题:把 get_exercise_list 的原始 JSON 解成纯文本题目。 * * 相对 legacy 的解耦:模块级的 EX / seenFont / filled / rewound / lastUrl 一个都不在这里持有。 * 「这份字体见过没有」由调用方通过 deps.seenFont() 回答, * 「解出来的题目」通过 deps.onExercise 交出去,其余状态清理放在 deps.onBatchStart 里。 */ var ENC_RE = /]*class="[^"]*xuetangx-com-encrypted-font[^"]*"[^>]*>([\s\S]*?)<\/span>/gi; function mapChars$1(s, m) { let out = ""; for (const ch of s) { const r = m.get(ch); out += r === void 0 ? ch : r; } return out; } function decHtml(html, m) { if (!html) return ""; return String(html).replace(ENC_RE, function(_, inner) { return mapChars$1(inner, m); }).replace(/]*>/gi, "").replace(/<\/?(html|head|body)[^>]*>/gi, "").replace(//gi, "\n").replace(/<\/p>/gi, "\n").replace(/<[^>]+>/g, "").replace(/ /g, " ").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/[ \t]+/g, " ").replace(/\n{2,}/g, "\n").trim(); } function isRecord(v) { return typeof v === "object" && v !== null; } function captureJson(raw, deps) { let j = raw; if (typeof raw === "string") try { j = JSON.parse(raw); } catch (e) { return; } const d = isRecord(j) ? j.data : void 0; if (!d || !d.font || !Array.isArray(d.problems) || !d.problems.length) return; if (deps.seenFont() === d.font) return; const font = d.font; const problems = d.problems; deps.onBatchStart(font); deps.log("拿到 " + problems.length + " 道题,正在解字体…"); deps.loadFont(font, function(err, m) { if (err || !m) { deps.log("字体解析失败:" + (err || "没拿到字表")); return; } const ex = { font, name: decHtml(d.name, m), answers: null, why: null, list: problems.map(function(p) { const c = p.content || {}; return { index: p.index, type: c.TypeText || c.Type || "", body: decHtml(c.Body, m), options: (c.Options || []).map(function(o) { return { key: o.key, text: decHtml(o.value, m) }; }) }; }) }; console.log(LOG, "题目已解出:\n" + ex.list.map(function(q) { return q.index + ". [" + q.type + "] " + q.body + "\n" + q.options.map(function(o) { return " " + o.key + ". " + o.text; }).join("\n"); }).join("\n")); deps.log(ex.list.length + " 道题已解出,点「🤖 解题」问 AI"); deps.onExercise(ex); }); } function ck(n) { try { const m = new RegExp("(?:^|;\\s*)" + n + "=([^;]*)").exec(doc().cookie || ""); return m ? m[1] : ""; } catch (e) { return ""; } } /** * 重新拉一次题目。 * legacy 里成功后直接 `seenFont = null; captureJson(j)`;这里把原始 JSON 交回调用方, * 由调用方清掉 seenFont 再喂给 captureJson —— 同一份字体要能被重新处理,这一步不能省。 */ function refetch(cb) { const path = doc().location.pathname; const m = /iframe-exercise\/(\d+)\/(\d+)/.exec(path) || /exercise\/(\d+)\/(\d+)/.exec(path); if (!m) { cb("当前页不是题目页"); return; } const opt = { headers: { accept: "application/json, text/plain, */*", "classroom-id": ck("classroom_id") || m[1], "university-id": ck("university_id"), "uv-id": ck("uv_id"), "xt-agent": "web", xtbz: "ykt" }, credentials: "include" }; fetch("/mooc-api/v1/lms/learn/leaf_info/" + m[1] + "/" + m[2] + "/", opt).then(function(r) { return r.json(); }).then(function(j) { const d = isRecord(j) ? j.data : void 0; const ci = d && isRecord(d.content_info) ? d.content_info : void 0; const lt = ci && ci.leaf_type_id; const sku = d && d.sku_id; if (!lt || !sku) throw new Error("leaf_info 缺 leaf_type_id / sku_id"); return fetch("/mooc-api/v1/lms/exercise/get_exercise_list/" + lt + "/" + sku + "/", opt); }).then(function(r) { return r.json(); }).then(function(j) { cb(null, j); }).catch(function(e) { cb(String(e && e.message || e)); }); } //#endregion //#region src/exercise/hook.ts /** * 拦截 ajax。抓到 get_exercise_list / get_kg_problem_list 的响应就回调出去, * 解析交给 captureJson —— 本模块只管「挂钩子」这一件事。 */ var EX_RE = /\/(get_exercise_list|get_kg_problem_list)\//; /** * @param onCapture 抓到匹配的响应体就回调。 * XHR 在 responseType === 'json' 时给的是对象而不是字符串, * 所以这里是 unknown —— captureJson 两种都认。 */ function hookAjax(onCapture) { const W = win(); const X = W.XMLHttpRequest; if (X && X.prototype && !X.prototype.__yktHooked) { const proto = X.prototype; const open = proto.open, send = proto.send; proto.open = function(...args) { this.__yktUrl = args[1]; return open.apply(this, args); }; proto.send = function(...args) { const self = this; try { this.addEventListener("load", function() { try { if (!EX_RE.test(String(self.__yktUrl || ""))) return; onCapture(self.responseType === "json" ? self.response : self.responseText); } catch (e) {} }); } catch (e) {} return send.apply(this, args); }; try { proto.__yktHooked = true; } catch (e) {} } const of = W.fetch; if (typeof of === "function" && !of.__yktHooked) { const nf = function(...args) { const input = args[0]; const u = typeof input === "string" ? input : input && input.url || ""; const p = of.apply(this, args); try { if (EX_RE.test(u) && p && typeof p.then === "function") p.then(function(r) { try { r.clone().text().then(onCapture, function() {}); } catch (e) {} return r; }, function() {}); } catch (e) {} return p; }; nf.__yktHooked = true; try { W.fetch = nf; } catch (e) {} } } //#endregion //#region src/font/const.ts /** * 字体解密用到的常量。原来散在 ykt_template.js 的 IIFE 顶部(源 57-60 行), * 现在收在这里,字体和剪贴板两边都从这儿取,避免两份定义漂移。 * * LOG 不在这里,它在 ../env(整个脚本共用一份前缀)。 */ /** 雨课堂给加密片段套的 class。只替换这里面的字符,见 legacy/README.md 的硬约束 */ var SELECTOR = ".xuetangx-com-encrypted-font"; /** 从 CSS 文本里抠混淆字体 URL */ var FONT_URL_RE = /(https?:\/\/[^"'\s)]*fe_font\/[^"'\s)]*exam_font[^"'\s)]*\.(?:ttf|otf|woff2?))/i; /** 克隆选区后要扔掉的元素:它们不贡献文本,只会把 innerText 搅乱 */ var STRIP = "img,video,audio,iframe,script,style,canvas,svg,noscript"; //#endregion //#region src/font/hash.ts function fnv(s) { let h = 2166136261; for (let i = 0; i < s.length; i++) { h ^= s.charCodeAt(i) & 255; h = h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24)) >>> 0; } return (h >>> 0).toString(16).padStart(8, "0"); } function coordKey(gl) { return fnv(gl.nc + "|" + gl.ends.join(",") + "|" + gl.pts.join(";")); } function geomKey(gl) { return fnv(gl.nc + "|" + gl.ends.join(",") + "|" + gl.bbox.join(",")); } var ykt_table_default = { CHARS: "一丁丂七丄丅丆万丈三上下丌不与丏丐丑丒专且丕世丗丘丙业丛东丝丞丟丠両丢丣两严並丧丨丩个丫丬中丮丯丰丱串丳临丵丶丷丸丹为主丼丽举丿乀乁乂乃乄久乆乇么义乊之乌乍乎乏乐乑乒乓乔乕乖乗乘乙乚乛乜九乞也习乡乢乣乤乥书乧乨乩乪乫乬乭乮乯买乱乲乳乴乵乶乷乸乹乺乻乼乽乾乿亀亁亂亃亄亅了亇予争亊事二亍于亏亐云互亓五井亖亗亘亙亚些亜亝亞亟亠亡亢亣交亥亦产亨亩亪享京亭亮亯亰亱亲亳亴亵亶亷亸亹人亻亼亽亾亿什仁仂仃仄仅仆仇仈仉今介仌仍从仏仐仑仒仓仔仕他仗付仙仚仛仜仝仞仟仠仡仢代令以仦仧仨仩仪仫们仭仮仯仰仱仲仳仴仵件价仸仹仺任仼份仾仿伀企伂伃伄伅伆伇伈伉伊伋伌伍伎伏伐休伒伓伔伕伖众优伙会伛伜伝伞伟传伡伢伣伤伥伦伧伨伩伪伫伬伭伮伯估伱伲伳伴伵伶伷伸伹伺伻似伽伾伿佀佁佂佃佄佅但佇佈佉佊佋佌位低住佐佑佒体佔何佖佗佘余佚佛作佝佞佟你佡佢佣佤佥佦佧佨佩佪佫佬佭佮佯佰佱佲佳佴併佶佷佸佹佺佻佼佽佾使侀侁侂侃侄侅來侇侈侉侊例侌侍侎侏侐侑侒侓侔侕侖侗侘侙侚供侜依侞侟侠価侢侣侤侥侦侧侨侩侪侫侬侭侮侯侰侱侲侳侴侵侶侷侸侹侺侻侼侽侾便俀俁係促俄俅俆俇俈俉俊俋俌俍俎俏俐俑俒俓俔俕俖俗俘俙俚俛俜保俞俟俠信俢俣俤俥俦俧俨俩俪俫俬俭修俯俰俱俲俳俴俵俶俷俸俹俺俻俼俽俾俿倀倁倂倃倄倅倆倇倈倉倊個倌倍倎倏倐們倒倓倔倕倖倗倘候倚倛倜倝倞借倠倡倢倣値倥倦倧倨倩倪倫倬倭倮倯倰倱倲倳倴倵倶倷倸倹债倻值倽倾倿偀偁偂偃偄偅偆假偈偉偊偋偌偍偎偏偐偑偒偓偔偕偖偗偘偙做偛停偝偞偟偠偡偢偣偤健偦偧偨偩偪偫偬偭偮偯偰偱偲偳側偵偶偷偸偹偺偻偼偽偾偿傀傁傂傃傄傅傆傇傈傉傊傋傌傍傎傏傐傑傒傓傔傕傖傗傘備傚傛傜傝傞傟傠傡傢傣傤傥傦傧储傩傪傫催傭傮傯傰傱傲傳傴債傶傷傸傹傺傻傼傽傾傿僀僁僂僃僄僅僆僇僈僉僊僋僌働僎像僐僑僒僓僔僕僖僗僘僙僚僛僜僝僞僟僠僡僢僣僤僥僦僧僨僩僪僫僬僭僮僯僰僱僲僳僴僵僶僷僸價僺僻僼僽僾僿儀儁儂儃億儅儆儇儈儉儊儋儌儍儎儏儐儑儒儓儔儕儖儗儘儙儚儛儜儝儞償儠儡儢儣儤儥儦儧儨儩優儫儬儭儮儯儰儱儲儳儴儵儶儷儸儹儺儻儼儽儾儿兀允兂元兄充兆兇先光兊克兌免兎兏児兑兒兓兔兕兖兗兘兙党兛兜兝兞兟兠兡兢兣兤入兦內全兩兪八公六兮兯兰共兲关兴兵其具典兹兺养兼兽兾兿冀冁冂冃冄内円冇冈冉冊冋册再冎冏冐冑冒冓冔冕冖冗冘写冚军农冝冞冟冠冡冢冣冤冥冦冧冨冩冪冫冬冭冮冯冰冱冲决冴况冶冷冸冹冺冻冼冽冾冿净凁凂凃凄凅准凇凈凉凊凋凌凍凎减凐凑凒凓凔凕凖凗凘凙凚凛凜凝凞凟几凡凢凣凤凥処凧凨凩凪凫凬凭凮凯凰凱凲凳凴凵凶凷凸凹出击凼函凾凿刀刁刂刃刄刅分切刈刉刊刋刌刍刎刏刐刑划刓刔刕刖列刘则刚创刜初刞刟删刡刢刣判別刦刧刨利刪别刬刭刮刯到刱刲刳刴刵制刷券刹刺刻刼刽刾刿剀剁剂剃剄剅剆則剈剉削剋剌前剎剏剐剑剒剓剔剕剖剗剘剙剚剛剜剝剞剟剠剡剢剣剤剥剦剧剨剩剪剫剬剭剮副剰剱割剳剴創剶剷剸剹剺剻剼剽剾剿劀劁劂劃劄劅劆劇劈劉劊劋劌劍劎劏劐劑劒劓劔劕劖劗劘劙劚力劜劝办功加务劢劣劤劥劦劧动助努劫劬劭劮劯劰励劲劳労劵劶劷劸効劺劻劼劽劾势勀勁勂勃勄勅勆勇勈勉勊勋勌勍勎勏勐勑勒勓勔動勖勗勘務勚勛勜勝勞募勠勡勢勣勤勥勦勧勨勩勪勫勬勭勮勯勰勱勲勳勴勵勶勷勸勹勺勻勼勽勾勿匀匁匂匃匄包匆匇匈匉匊匋匌匍匎匏匐匑匒匓匔匕化北匘匙匚匛匜匝匞匟匠匡匢匣匤匥匦匧匨匩匪匫匬匭匮匯匰匱匲匳匴匵匶匷匸匹区医匼匽匾匿區十卂千卄卅卆升午卉半卋卌卍华协卐卑卒卓協单卖南単卙博卛卜卝卞卟占卡卢卣卤卥卦卧卨卩卪卫卬卭卮卯印危卲即却卵卶卷卸卹卺卻卼卽卾卿厀厁厂厃厄厅历厇厈厉厊压厌厍厎厏厐厑厒厓厔厕厖厗厘厙厚厛厜厝厞原厠厡厢厣厤厥厦厧厨厩厪厫厬厭厮厯厰厱厲厳厴厵厶厷厸厹厺去厼厽厾县叀叁参參叄叅叆叇又叉及友双反収叏叐发叒叓叔叕取受变叙叚叛叜叝叞叟叠叡叢口古句另叧叨叩只叫召叭叮可台叱史右叴叵叶号司叹叺叻叼叽叾叿吀吁吂吃各吅吆吇合吉吊吋同名后吏吐向吒吓吔吕吖吗吘吙吚君吜吝吞吟吠吡吢吣吤吥否吧吨吩吪含听吭吮启吰吱吲吳吴吵吶吷吸吹吺吻吼吽吾吿呀呁呂呃呄呅呆呇呈呉告呋呌呍呎呏呐呑呒呓呔呕呖呗员呙呚呛呜呝呞呟呠呡呢呣呤呥呦呧周呩呪呫呬呭呮呯呰呱呲味呴呵呶呷呸呹呺呻呼命呾呿咀咁咂咃咄咅咆咇咈咉咊咋和咍咎咏咐咑咒咓咔咕咖咗咘咙咚咛咜咝咞咟咠咡咢咣咤咥咦咧咨咩咪咫咬咭咮咯咰咱咲咳咴咵咶咷咸咹咺咻咼咽咾咿哀品哂哃哄哅哆哇哈哉哊哋哌响哎哏哐哑哒哓哔哕哖哗哘哙哚哛哜哝哞哟哠員哢哣哤哥哦哧哨哩哪哫哬哭哮哯哰哱哲哳哴哵哶哷哸哹哺哻哼哽哾哿唀唁唂唃唄唅唆唇唈唉唊唋唌唍唎唏唐唑唒唓唔唕唖唗唘唙唚唛唜唝唞唟唠唡唢唣唤唥唦唧唨唩唪唫唬唭售唯唰唱唲唳唴唵唶唷唸唹唺唻唼唽唾唿啀啁啂啃啄啅商啇啈啉啊啋啌啍啎問啐啑啒啓啔啕啖啗啘啙啚啛啜啝啞啟啠啡啢啣啤啥啦啧啨啩啪啫啬啭啮啯啰啱啲啳啴啵啶啷啸啹啺啻啼啽啾啿喀喁喂喃善喅喆喇喈喉喊喋喌喍喎喏喐喑喒喓喔喕喖喗喘喙喚喛喜喝喞喟喠喡喢喣喤喥喦喧喨喩喪喫喬喭單喯喰喱喲喳喴喵営喷喸喹喺喻喼喽喾喿嗀嗁嗂嗃嗄嗅嗆嗇嗈嗉嗊嗋嗌嗍嗎嗏嗐嗑嗒嗓嗔嗕嗖嗗嗘嗙嗚嗛嗜嗝嗞嗟嗠嗡嗢嗣嗤嗥嗦嗧嗨嗩嗪嗫嗬嗭嗮嗯嗰嗱嗲嗳嗴嗵嗶嗷嗸嗹嗺嗻嗼嗽嗾嗿嘀嘁嘂嘃嘄嘅嘆嘇嘈嘉嘊嘋嘌嘍嘎嘏嘐嘑嘒嘓嘔嘕嘖嘗嘘嘙嘚嘛嘜嘝嘞嘟嘠嘡嘢嘣嘤嘥嘦嘧嘨嘩嘪嘫嘬嘭嘮嘯嘰嘱嘲嘳嘴嘵嘶嘷嘸嘹嘺嘻嘼嘽嘾嘿噀噁噂噃噄噅噆噇噈噉噊噋噌噍噎噏噐噑噒噓噔噕噖噗噘噙噚噛噜噝噞噟噠噡噢噣噤噥噦噧器噩噪噫噬噭噮噯噰噱噲噳噴噵噶噷噸噹噺噻噼噽噾噿嚀嚁嚂嚃嚄嚅嚆嚇嚈嚉嚊嚋嚌嚍嚎嚏嚐嚑嚒嚓嚔嚕嚖嚗嚘嚙嚚嚛嚜嚝嚞嚟嚠嚡嚢嚣嚤嚥嚦嚧嚨嚩嚪嚫嚬嚭嚮嚯嚰嚱嚲嚳嚴嚵嚶嚷嚸嚹嚺嚻嚼嚽嚾嚿囀囁囂囃囄囅囆囇囈囉囊囋囌囍囎囏囐囑囒囓囔囕囖囗囘囙囚四囜囝回囟因囡团団囤囥囦囧囨囩囪囫囬园囮囯困囱囲図围囵囶囷囸囹固囻囼国图囿圀圁圂圃圄圅圆圇圈圉圊國圌圍圎圏圐圑園圓圔圕圖圗團圙圚圛圜圝圞土圠圡圢圣圤圥圦圧在圩圪圫圬圭圮圯地圱圲圳圴圵圶圷圸圹场圻圼圽圾圿址坁坂坃坄坅坆均坈坉坊坋坌坍坎坏坐坑坒坓坔坕坖块坘坙坚坛坜坝坞坟坠坡坢坣坤坥坦坧坨坩坪坫坬坭坮坯坰坱坲坳坴坵坶坷坸坹坺坻坼坽坾坿垀垁垂垃垄垅垆垇垈垉垊型垌垍垎垏垐垑垒垓垔垕垖垗垘垙垚垛垜垝垞垟垠垡垢垣垤垥垦垧垨垩垪垫垬垭垮垯垰垱垲垳垴垵垶垷垸垹垺垻垼垽垾垿埀埁埂埃埄埅埆埇埈埉埊埋埌埍城埏埐埑埒埓埔埕埖埗埘埙埚埛埜埝埞域埠埡埢埣埤埥埦埧埨埩埪埫埬埭埮埯埰埱埲埳埴埵埶執埸培基埻埼埽埾埿堀堁堂堃堄堅堆堇堈堉堊堋堌堍堎堏堐堑堒堓堔堕堖堗堘堙堚堛堜堝堞堟堠堡堢堣堤堥堦堧堨堩堪堫堬堭堮堯堰報堲堳場堵堶堷堸堹堺堻堼堽堾堿塀塁塂塃塄塅塆塇塈塉塊塋塌塍塎塏塐塑塒塓塔塕塖塗塘塙塚塛塜塝塞塟塠塡塢塣塤塥塦塧塨塩塪填塬塭塮塯塰塱塲塳塴塵塶塷塸塹塺塻塼塽塾塿墀墁墂境墄墅墆墇墈墉墊墋墌墍墎墏墐墑墒墓墔墕墖増墘墙墚墛墜墝增墟墠墡墢墣墤墥墦墧墨墩墪墫墬墭墮墯墰墱墲墳墴墵墶墷墸墹墺墻墼墽墾墿壀壁壂壃壄壅壆壇壈壉壊壋壌壍壎壏壐壑壒壓壔壕壖壗壘壙壚壛壜壝壞壟壠壡壢壣壤壥壦壧壨壩壪士壬壭壮壯声壱売壳壴壵壶壷壸壹壺壻壼壽壾壿夀夁夂夃处夅夆备夈変夊夋夌复夎夏夐夑夒夓夔夕外夗夘夙多夛夜夝夞够夠夡夢夣夤夥夦大夨天太夫夬夭央夯夰失夲夳头夵夶夷夸夹夺夻夼夽夾夿奀奁奂奃奄奅奆奇奈奉奊奋奌奍奎奏奐契奒奓奔奕奖套奘奙奚奛奜奝奞奟奠奡奢奣奤奥奦奧奨奩奪奫奬奭奮奯奰奱奲女奴奵奶奷奸她奺奻奼好奾奿妀妁如妃妄妅妆妇妈妉妊妋妌妍妎妏妐妑妒妓妔妕妖妗妘妙妚妛妜妝妞妟妠妡妢妣妤妥妦妧妨妩妪妫妬妭妮妯妰妱妲妳妴妵妶妷妸妹妺妻妼妽妾妿姀姁姂姃姄姅姆姇姈姉姊始姌姍姎姏姐姑姒姓委姕姖姗姘姙姚姛姜姝姞姟姠姡姢姣姤姥姦姧姨姩姪姫姬姭姮姯姰姱姲姳姴姵姶姷姸姹姺姻姼姽姾姿娀威娂娃娄娅娆娇娈娉娊娋娌娍娎娏娐娑娒娓娔娕娖娗娘娙娚娛娜娝娞娟娠娡娢娣娤娥娦娧娨娩娪娫娬娭娮娯娰娱娲娳娴娵娶娷娸娹娺娻娼娽娾娿婀婁婂婃婄婅婆婇婈婉婊婋婌婍婎婏婐婑婒婓婔婕婖婗婘婙婚婛婜婝婞婟婠婡婢婣婤婥婦婧婨婩婪婫婬婭婮婯婰婱婲婳婴婵婶婷婸婹婺婻婼婽婾婿媀媁媂媃媄媅媆媇媈媉媊媋媌媍媎媏媐媑媒媓媔媕媖媗媘媙媚媛媜媝媞媟媠媡媢媣媤媥媦媧媨媩媪媫媬媭媮媯媰媱媲媳媴媵媶媷媸媹媺媻媼媽媾媿嫀嫁嫂嫃嫄嫅嫆嫇嫈嫉嫊嫋嫌嫍嫎嫏嫐嫑嫒嫓嫔嫕嫖嫗嫘嫙嫚嫛嫜嫝嫞嫟嫠嫡嫢嫣嫤嫥嫦嫧嫨嫩嫪嫫嫬嫭嫮嫯嫰嫱嫲嫳嫴嫵嫶嫷嫸嫹嫺嫻嫼嫽嫾嫿嬀嬁嬂嬃嬄嬅嬆嬇嬈嬉嬊嬋嬌嬍嬎嬏嬐嬑嬒嬓嬔嬕嬖嬗嬘嬙嬚嬛嬜嬝嬞嬟嬠嬡嬢嬣嬤嬥嬦嬧嬨嬩嬪嬫嬬嬭嬮嬯嬰嬱嬲嬳嬴嬵嬶嬷嬸嬹嬺嬻嬼嬽嬾嬿孀孁孂孃孄孅孆孇孈孉孊孋孌孍孎孏子孑孒孓孔孕孖字存孙孚孛孜孝孞孟孠孡孢季孤孥学孧孨孩孪孫孬孭孮孯孰孱孲孳孴孵孶孷學孹孺孻孼孽孾孿宀宁宂它宄宅宆宇守安宊宋完宍宎宏宐宑宒宓宔宕宖宗官宙定宛宜宝实実宠审客宣室宥宦宧宨宩宪宫宬宭宮宯宰宱宲害宴宵家宷宸容宺宻宼宽宾宿寀寁寂寃寄寅密寇寈寉寊寋富寍寎寏寐寑寒寓寔寕寖寗寘寙寚寛寜寝寞察寠寡寢寣寤寥實寧寨審寪寫寬寭寮寯寰寱寲寳寴寵寶寷寸对寺寻导寽対寿尀封専尃射尅将將專尉尊尋尌對導小尐少尒尓尔尕尖尗尘尙尚尛尜尝尞尟尠尡尢尣尤尥尦尧尨尩尪尫尬尭尮尯尰就尲尳尴尵尶尷尸尹尺尻尼尽尾尿局屁层屃屄居屆屇屈屉届屋屌屍屎屏屐屑屒屓屔展屖屗屘屙屚屛屜屝属屟屠屡屢屣層履屦屧屨屩屪屫屬屭屮屯屰山屲屳屴屵屶屷屸屹屺屻屼屽屾屿岀岁岂岃岄岅岆岇岈岉岊岋岌岍岎岏岐岑岒岓岔岕岖岗岘岙岚岛岜岝岞岟岠岡岢岣岤岥岦岧岨岩岪岫岬岭岮岯岰岱岲岳岴岵岶岷岸岹岺岻岼岽岾岿峀峁峂峃峄峅峆峇峈峉峊峋峌峍峎峏峐峑峒峓峔峕峖峗峘峙峚峛峜峝峞峟峠峡峢峣峤峥峦峧峨峩峪峫峬峭峮峯峰峱峲峳峴峵島峷峸峹峺峻峼峽峾峿崀崁崂崃崄崅崆崇崈崉崊崋崌崍崎崏崐崑崒崓崔崕崖崗崘崙崚崛崜崝崞崟崠崡崢崣崤崥崦崧崨崩崪崫崬崭崮崯崰崱崲崳崴崵崶崷崸崹崺崻崼崽崾崿嵀嵁嵂嵃嵄嵅嵆嵇嵈嵉嵊嵋嵌嵍嵎嵏嵐嵑嵒嵓嵔嵕嵖嵗嵘嵙嵚嵛嵜嵝嵞嵟嵠嵡嵢嵣嵤嵥嵦嵧嵨嵩嵪嵫嵬嵭嵮嵯嵰嵱嵲嵳嵴嵵嵶嵷嵸嵹嵺嵻嵼嵽嵾嵿嶀嶁嶂嶃嶄嶅嶆嶇嶈嶉嶊嶋嶌嶍嶎嶏嶐嶑嶒嶓嶔嶕嶖嶗嶘嶙嶚嶛嶜嶝嶞嶟嶠嶡嶢嶣嶤嶥嶦嶧嶨嶩嶪嶫嶬嶭嶮嶯嶰嶱嶲嶳嶴嶵嶶嶷嶸嶹嶺嶻嶼嶽嶾嶿巀巁巂巃巄巅巆巇巈巉巊巋巌巍巎巏巐巑巒巓巔巕巖巗巘巙巚巛巜川州巟巠巡巢巣巤工左巧巨巩巪巫巬巭差巯巰己已巳巴巵巶巷巸巹巺巻巼巽巾巿帀币市布帄帅帆帇师帉帊帋希帍帎帏帐帑帒帓帔帕帖帗帘帙帚帛帜帝帞帟帠帡帢帣帤帥带帧帨帩帪師帬席帮帯帰帱帲帳帴帵帶帷常帹帺帻帼帽帾帿幀幁幂幃幄幅幆幇幈幉幊幋幌幍幎幏幐幑幒幓幔幕幖幗幘幙幚幛幜幝幞幟幠幡幢幣幤幥幦幧幨幩幪幫幬幭幮幯幰幱干平年幵并幷幸幹幺幻幼幽幾广庀庁庂広庄庅庆庇庈庉床庋庌庍庎序庐庑庒库应底庖店庘庙庚庛府庝庞废庠庡庢庣庤庥度座庨庩庪庫庬庭庮庯庰庱庲庳庴庵庶康庸庹庺庻庼庽庾庿廀廁廂廃廄廅廆廇廈廉廊廋廌廍廎廏廐廑廒廓廔廕廖廗廘廙廚廛廜廝廞廟廠廡廢廣廤廥廦廧廨廩廪廫廬廭廮廯廰廱廲廳廴廵延廷廸廹建廻廼廽廾廿开弁异弃弄弅弆弇弈弉弊弋弌弍弎式弐弑弒弓弔引弖弗弘弙弚弛弜弝弞弟张弡弢弣弤弥弦弧弨弩弪弫弬弭弮弯弰弱弲弳弴張弶強弸弹强弻弼弽弾弿彀彁彂彃彄彅彆彇彈彉彊彋彌彍彎彏彐彑归当彔录彖彗彘彙彚彛彜彝彞彟彠彡形彣彤彥彦彧彨彩彪彫彬彭彮彯彰影彲彳彴彵彶彷彸役彺彻彼彽彾彿往征徂徃径待徆徇很徉徊律後徍徎徏徐徑徒従徔徕徖得徘徙徚徛徜徝從徟徠御徢徣徤徥徦徧徨復循徫徬徭微徯徰徱徲徳徴徵徶德徸徹徺徻徼徽徾徿忀忁忂心忄必忆忇忈忉忊忋忌忍忎忏忐忑忒忓忔忕忖志忘忙忚忛応忝忞忟忠忡忢忣忤忥忦忧忨忩忪快忬忭忮忯忰忱忲忳忴念忶忷忸忹忺忻忼忽忾忿怀态怂怃怄怅怆怇怈怉怊怋怌怍怎怏怐怑怒怓怔怕怖怗怘怙怚怛怜思怞怟怠怡怢怣怤急怦性怨怩怪怫怬怭怮怯怰怱怲怳怴怵怶怷怸怹怺总怼怽怾怿恀恁恂恃恄恅恆恇恈恉恊恋恌恍恎恏恐恑恒恓恔恕恖恗恘恙恚恛恜恝恞恟恠恡恢恣恤恥恦恧恨恩恪恫恬恭恮息恰恱恲恳恴恵恶恷恸恹恺恻恼恽恾恿悀悁悂悃悄悅悆悇悈悉悊悋悌悍悎悏悐悑悒悓悔悕悖悗悘悙悚悛悜悝悞悟悠悡悢患悤悥悦悧您悩悪悫悬悭悮悯悰悱悲悳悴悵悶悷悸悹悺悻悼悽悾悿惀惁惂惃惄情惆惇惈惉惊惋惌惍惎惏惐惑惒惓惔惕惖惗惘惙惚惛惜惝惞惟惠惡惢惣惤惥惦惧惨惩惪惫惬惭惮惯惰惱惲想惴惵惶惷惸惹惺惻惼惽惾惿愀愁愂愃愄愅愆愇愈愉愊愋愌愍愎意愐愑愒愓愔愕愖愗愘愙愚愛愜愝愞感愠愡愢愣愤愥愦愧愨愩愪愫愬愭愮愯愰愱愲愳愴愵愶愷愸愹愺愻愼愽愾愿慀慁慂慃慄慅慆慇慈慉慊態慌慍慎慏慐慑慒慓慔慕慖慗慘慙慚慛慜慝慞慟慠慡慢慣慤慥慦慧慨慩慪慫慬慭慮慯慰慱慲慳慴慵慶慷慸慹慺慻慼慽慾慿憀憁憂憃憄憅憆憇憈憉憊憋憌憍憎憏憐憑憒憓憔憕憖憗憘憙憚憛憜憝憞憟憠憡憢憣憤憥憦憧憨憩憪憫憬憭憮憯憰憱憲憳憴憵憶憷憸憹憺憻憼憽憾憿懀懁懂懃懄懅懆懇懈應懊懋懌懍懎懏懐懑懒懓懔懕懖懗懘懙懚懛懜懝懞懟懠懡懢懣懤懥懦懧懨懩懪懫懬懭懮懯懰懱懲懳懴懵懶懷懸懹懺懻懼懽懾懿戀戁戂戃戄戅戆戇戈戉戊戋戌戍戎戏成我戒戓戔戕或戗战戙戚戛戜戝戞戟戠戡戢戣戤戥戦戧戨戩截戫戬戭戮戯戰戱戲戳戴戵戶户戸戹戺戻戼戽戾房所扁扂扃扄扅扆扇扈扉扊手扌才扎扏扐扑扒打扔払扖扗托扙扚扛扜扝扞扟扠扡扢扣扤扥扦执扨扩扪扫扬扭扮扯扰扱扲扳扴扵扶扷扸批扺扻扼扽找承技抁抂抃抄抅抆抇抈抉把抋抌抍抎抏抐抑抒抓抔投抖抗折抙抚抛抜抝択抟抠抡抢抣护报抦抧抨抩抪披抬抭抮抯抰抱抲抳抴抵抶抷抸抹抺抻押抽抾抿拀拁拂拃拄担拆拇拈拉拊拋拌拍拎拏拐拑拒拓拔拕拖拗拘拙拚招拜拝拞拟拠拡拢拣拤拥拦拧拨择拪拫括拭拮拯拰拱拲拳拴拵拶拷拸拹拺拻拼拽拾拿挀持挂挃挄挅挆指挈按挊挋挌挍挎挏挐挑挒挓挔挕挖挗挘挙挚挛挜挝挞挟挠挡挢挣挤挥挦挧挨挩挪挫挬挭挮振挰挱挲挳挴挵挶挷挸挹挺挻挼挽挾挿捀捁捂捃捄捅捆捇捈捉捊捋捌捍捎捏捐捑捒捓捔捕捖捗捘捙捚捛捜捝捞损捠捡换捣捤捥捦捧捨捩捪捫捬捭据捯捰捱捲捳捴捵捶捷捸捹捺捻捼捽捾捿掀掁掂掃掄掅掆掇授掉掊掋掌掍掎掏掐掑排掓掔掕掖掗掘掙掚掛掜掝掞掟掠採探掣掤接掦控推掩措掫掬掭掮掯掰掱掲掳掴掵掶掷掸掹掺掻掼掽掾掿揀揁揂揃揄揅揆揇揈揉揊揋揌揍揎描提揑插揓揔揕揖揗揘揙揚換揜揝揞揟揠握揢揣揤揥揦揧揨揩揪揫揬揭揮揯揰揱揲揳援揵揶揷揸揹揺揻揼揽揾揿搀搁搂搃搄搅搆搇搈搉搊搋搌損搎搏搐搑搒搓搔搕搖搗搘搙搚搛搜搝搞搟搠搡搢搣搤搥搦搧搨搩搪搫搬搭搮搯搰搱搲搳搴搵搶搷搸搹携搻搼搽搾搿摀摁摂摃摄摅摆摇摈摉摊摋摌摍摎摏摐摑摒摓摔摕摖摗摘摙摚摛摜摝摞摟摠摡摢摣摤摥摦摧摨摩摪摫摬摭摮摯摰摱摲摳摴摵摶摷摸摹摺摻摼摽摾摿撀撁撂撃撄撅撆撇撈撉撊撋撌撍撎撏撐撑撒撓撔撕撖撗撘撙撚撛撜撝撞撟撠撡撢撣撤撥撦撧撨撩撪撫撬播撮撯撰撱撲撳撴撵撶撷撸撹撺撻撼撽撾撿擀擁擂擃擄擅擆擇擈擉擊擋擌操擎擏擐擑擒擓擔擕擖擗擘擙據擛擜擝擞擟擠擡擢擣擤擥擦擧擨擩擪擫擬擭擮擯擰擱擲擳擴擵擶擷擸擹擺擻擼擽擾擿攀攁攂攃攄攅攆攇攈攉攊攋攌攍攎攏攐攑攒攓攔攕攖攗攘攙攚攛攜攝攞攟攠攡攢攣攤攥攦攧攨攩攪攫攬攭攮支攰攱攲攳攴攵收攷攸改攺攻攼攽放政敀敁敂敃敄故敆敇效敉敊敋敌敍敎敏敐救敒敓敔敕敖敗敘教敚敛敜敝敞敟敠敡敢散敤敥敦敧敨敩敪敫敬敭敮敯数敱敲敳整敵敶敷數敹敺敻敼敽敾敿斀斁斂斃斄斅斆文斈斉斊斋斌斍斎斏斐斑斒斓斔斕斖斗斘料斚斛斜斝斞斟斠斡斢斣斤斥斦斧斨斩斪斫斬断斮斯新斱斲斳斴斵斶斷斸方斺斻於施斾斿旀旁旂旃旄旅旆旇旈旉旊旋旌旍旎族旐旑旒旓旔旕旖旗旘旙旚旛旜旝旞旟无旡既旣旤日旦旧旨早旪旫旬旭旮旯旰旱旲旳旴旵时旷旸旹旺旻旼旽旾旿昀昁昂昃昄昅昆昇昈昉昊昋昌昍明昏昐昑昒易昔昕昖昗昘昙昚昛昜昝昞星映昡昢昣昤春昦昧昨昩昪昫昬昭昮是昰昱昲昳昴昵昶昷昸昹昺昻昼昽显昿晀晁時晃晄晅晆晇晈晉晊晋晌晍晎晏晐晑晒晓晔晕晖晗晘晙晚晛晜晝晞晟晠晡晢晣晤晥晦晧晨晩晪晫晬晭普景晰晱晲晳晴晵晶晷晸晹智晻晼晽晾晿暀暁暂暃暄暅暆暇暈暉暊暋暌暍暎暏暐暑暒暓暔暕暖暗暘暙暚暛暜暝暞暟暠暡暢暣暤暥暦暧暨暩暪暫暬暭暮暯暰暱暲暳暴暵暶暷暸暹暺暻暼暽暾暿曀曁曂曃曄曅曆曇曈曉曊曋曌曍曎曏曐曑曒曓曔曕曖曗曘曙曚曛曜曝曞曟曠曡曢曣曤曥曦曧曨曩曪曫曬曭曮曯曰曱曲曳更曵曶曷書曹曺曻曼曽曾替最朁朂會朄朅朆朇月有朊朋朌服朎朏朐朑朒朓朔朕朖朗朘朙朚望朜朝朞期朠朡朢朣朤朥朦朧木朩未末本札朮术朰朱朲朳朴朵朶朷朸朹机朻朼朽朾朿杀杁杂权杄杅杆杇杈杉杊杋杌杍李杏材村杒杓杔杕杖杗杘杙杚杛杜杝杞束杠条杢杣杤来杦杧杨杩杪杫杬杭杮杯杰東杲杳杴杵杶杷杸杹杺杻杼杽松板枀极枂枃构枅枆枇枈枉枊枋枌枍枎枏析枑枒枓枔枕枖林枘枙枚枛果枝枞枟枠枡枢枣枤枥枦枧枨枩枪枫枬枭枮枯枰枱枲枳枴枵架枷枸枹枺枻枼枽枾枿柀柁柂柃柄柅柆柇柈柉柊柋柌柍柎柏某柑柒染柔柕柖柗柘柙柚柛柜柝柞柟柠柡柢柣柤查柦柧柨柩柪柫柬柭柮柯柰柱柲柳柴柵柶柷柸柹柺査柼柽柾柿栀栁栂栃栄栅栆标栈栉栊栋栌栍栎栏栐树栒栓栔栕栖栗栘栙栚栛栜栝栞栟栠校栢栣栤栥栦栧栨栩株栫栬栭栮栯栰栱栲栳栴栵栶样核根栺栻格栽栾栿桀桁桂桃桄桅框桇案桉桊桋桌桍桎桏桐桑桒桓桔桕桖桗桘桙桚桛桜桝桞桟桠桡桢档桤桥桦桧桨桩桪桫桬桭桮桯桰桱桲桳桴桵桶桷桸桹桺桻桼桽桾桿梀梁梂梃梄梅梆梇梈梉梊梋梌梍梎梏梐梑梒梓梔梕梖梗梘梙梚梛梜條梞梟梠梡梢梣梤梥梦梧梨梩梪梫梬梭梮梯械梱梲梳梴梵梶梷梸梹梺梻梼梽梾梿检棁棂棃棄棅棆棇棈棉棊棋棌棍棎棏棐棑棒棓棔棕棖棗棘棙棚棛棜棝棞棟棠棡棢棣棤棥棦棧棨棩棪棫棬棭森棯棰棱棲棳棴棵棶棷棸棹棺棻棼棽棾棿椀椁椂椃椄椅椆椇椈椉椊椋椌植椎椏椐椑椒椓椔椕椖椗椘椙椚椛検椝椞椟椠椡椢椣椤椥椦椧椨椩椪椫椬椭椮椯椰椱椲椳椴椵椶椷椸椹椺椻椼椽椾椿楀楁楂楃楄楅楆楇楈楉楊楋楌楍楎楏楐楑楒楓楔楕楖楗楘楙楚楛楜楝楞楟楠楡楢楣楤楥楦楧楨楩楪楫楬業楮楯楰楱楲楳楴極楶楷楸楹楺楻楼楽楾楿榀榁概榃榄榅榆榇榈榉榊榋榌榍榎榏榐榑榒榓榔榕榖榗榘榙榚榛榜榝榞榟榠榡榢榣榤榥榦榧榨榩榪榫榬榭榮榯榰榱榲榳榴榵榶榷榸榹榺榻榼榽榾榿槀槁槂槃槄槅槆槇槈槉槊構槌槍槎槏槐槑槒槓槔槕槖槗様槙槚槛槜槝槞槟槠槡槢槣槤槥槦槧槨槩槪槫槬槭槮槯槰槱槲槳槴槵槶槷槸槹槺槻槼槽槾槿樀樁樂樃樄樅樆樇樈樉樊樋樌樍樎樏樐樑樒樓樔樕樖樗樘標樚樛樜樝樞樟樠模樢樣樤樥樦樧樨権横樫樬樭樮樯樰樱樲樳樴樵樶樷樸樹樺樻樼樽樾樿橀橁橂橃橄橅橆橇橈橉橊橋橌橍橎橏橐橑橒橓橔橕橖橗橘橙橚橛橜橝橞機橠橡橢橣橤橥橦橧橨橩橪橫橬橭橮橯橰橱橲橳橴橵橶橷橸橹橺橻橼橽橾橿檀檁檂檃檄檅檆檇檈檉檊檋檌檍檎檏檐檑檒檓檔檕檖檗檘檙檚檛檜檝檞檟檠檡檢檣檤檥檦檧檨檩檪檫檬檭檮檯檰檱檲檳檴檵檶檷檸檹檺檻檼檽檾檿櫀櫁櫂櫃櫄櫅櫆櫇櫈櫉櫊櫋櫌櫍櫎櫏櫐櫑櫒櫓櫔櫕櫖櫗櫘櫙櫚櫛櫜櫝櫞櫟櫠櫡櫢櫣櫤櫥櫦櫧櫨櫩櫪櫫櫬櫭櫮櫯櫰櫱櫲櫳櫴櫵櫶櫷櫸櫹櫺櫻櫼櫽櫾櫿欀欁欂欃欄欅欆欇欈欉權欋欌欍欎欏欐欑欒欓欔欕欖欗欘欙欚欛欜欝欞欟欠次欢欣欤欥欦欧欨欩欪欫欬欭欮欯欰欱欲欳欴欵欶欷欸欹欺欻欼欽款欿歀歁歂歃歄歅歆歇歈歉歊歋歌歍歎歏歐歑歒歓歔歕歖歗歘歙歚歛歜歝歞歟歠歡止正此步武歧歨歩歪歫歬歭歮歯歰歱歲歳歴歵歶歷歸歹歺死歼歽歾歿殀殁殂殃殄殅殆殇殈殉殊残殌殍殎殏殐殑殒殓殔殕殖殗殘殙殚殛殜殝殞殟殠殡殢殣殤殥殦殧殨殩殪殫殬殭殮殯殰殱殲殳殴段殶殷殸殹殺殻殼殽殾殿毀毁毂毃毄毅毆毇毈毉毊毋毌母毎每毐毑毒毓比毕毖毗毘毙毚毛毜毝毞毟毠毡毢毣毤毥毦毧毨毩毪毫毬毭毮毯毰毱毲毳毴毵毶毷毸毹毺毻毼毽毾毿氀氁氂氃氄氅氆氇氈氉氊氋氌氍氎氏氐民氒氓气氕氖気氘氙氚氛氜氝氞氟氠氡氢氣氤氥氦氧氨氩氪氫氬氭氮氯氰氱氲氳水氵氶氷永氹氺氻氼氽氾氿汀汁求汃汄汅汆汇汈汉汊汋汌汍汎汏汐汑汒汓汔汕汖汗汘汙汚汛汜汝汞江池污汢汣汤汥汦汧汨汩汪汫汬汭汮汯汰汱汲汳汴汵汶汷汸汹決汻汼汽汾汿沀沁沂沃沄沅沆沇沈沉沊沋沌沍沎沏沐沑沒沓沔沕沖沗沘沙沚沛沜沝沞沟沠没沢沣沤沥沦沧沨沩沪沫沬沭沮沯沰沱沲河沴沵沶沷沸油沺治沼沽沾沿泀況泂泃泄泅泆泇泈泉泊泋泌泍泎泏泐泑泒泓泔法泖泗泘泙泚泛泜泝泞泟泠泡波泣泤泥泦泧注泩泪泫泬泭泮泯泰泱泲泳泴泵泶泷泸泹泺泻泼泽泾泿洀洁洂洃洄洅洆洇洈洉洊洋洌洍洎洏洐洑洒洓洔洕洖洗洘洙洚洛洜洝洞洟洠洡洢洣洤津洦洧洨洩洪洫洬洭洮洯洰洱洲洳洴洵洶洷洸洹洺活洼洽派洿浀流浂浃浄浅浆浇浈浉浊测浌浍济浏浐浑浒浓浔浕浖浗浘浙浚浛浜浝浞浟浠浡浢浣浤浥浦浧浨浩浪浫浬浭浮浯浰浱浲浳浴浵浶海浸浹浺浻浼浽浾浿涀涁涂涃涄涅涆涇消涉涊涋涌涍涎涏涐涑涒涓涔涕涖涗涘涙涚涛涜涝涞涟涠涡涢涣涤涥润涧涨涩涪涫涬涭涮涯涰涱液涳涴涵涶涷涸涹涺涻涼涽涾涿淀淁淂淃淄淅淆淇淈淉淊淋淌淍淎淏淐淑淒淓淔淕淖淗淘淙淚淛淜淝淞淟淠淡淢淣淤淥淦淧淨淩淪淫淬淭淮淯淰深淲淳淴淵淶混淸淹淺添淼淽淾淿渀渁渂渃渄清渆渇済渉渊渋渌渍渎渏渐渑渒渓渔渕渖渗渘渙渚減渜渝渞渟渠渡渢渣渤渥渦渧渨温渪渫測渭渮港渰渱渲渳渴渵渶渷游渹渺渻渼渽渾渿湀湁湂湃湄湅湆湇湈湉湊湋湌湍湎湏湐湑湒湓湔湕湖湗湘湙湚湛湜湝湞湟湠湡湢湣湤湥湦湧湨湩湪湫湬湭湮湯湰湱湲湳湴湵湶湷湸湹湺湻湼湽湾湿満溁溂溃溄溅溆溇溈溉溊溋溌溍溎溏源溑溒溓溔溕準溗溘溙溚溛溜溝溞溟溠溡溢溣溤溥溦溧溨溩溪溫溬溭溮溯溰溱溲溳溴溵溶溷溸溹溺溻溼溽溾溿滀滁滂滃滄滅滆滇滈滉滊滋滌滍滎滏滐滑滒滓滔滕滖滗滘滙滚滛滜滝滞滟滠满滢滣滤滥滦滧滨滩滪滫滬滭滮滯滰滱滲滳滴滵滶滷滸滹滺滻滼滽滾滿漀漁漂漃漄漅漆漇漈漉漊漋漌漍漎漏漐漑漒漓演漕漖漗漘漙漚漛漜漝漞漟漠漡漢漣漤漥漦漧漨漩漪漫漬漭漮漯漰漱漲漳漴漵漶漷漸漹漺漻漼漽漾漿潀潁潂潃潄潅潆潇潈潉潊潋潌潍潎潏潐潑潒潓潔潕潖潗潘潙潚潛潜潝潞潟潠潡潢潣潤潥潦潧潨潩潪潫潬潭潮潯潰潱潲潳潴潵潶潷潸潹潺潻潼潽潾潿澀澁澂澃澄澅澆澇澈澉澊澋澌澍澎澏澐澑澒澓澔澕澖澗澘澙澚澛澜澝澞澟澠澡澢澣澤澥澦澧澨澩澪澫澬澭澮澯澰澱澲澳澴澵澶澷澸澹澺澻澼澽澾澿激濁濂濃濄濅濆濇濈濉濊濋濌濍濎濏濐濑濒濓濔濕濖濗濘濙濚濛濜濝濞濟濠濡濢濣濤濥濦濧濨濩濪濫濬濭濮濯濰濱濲濳濴濵濶濷濸濹濺濻濼濽濾濿瀀瀁瀂瀃瀄瀅瀆瀇瀈瀉瀊瀋瀌瀍瀎瀏瀐瀑瀒瀓瀔瀕瀖瀗瀘瀙瀚瀛瀜瀝瀞瀟瀠瀡瀢瀣瀤瀥瀦瀧瀨瀩瀪瀫瀬瀭瀮瀯瀰瀱瀲瀳瀴瀵瀶瀷瀸瀹瀺瀻瀼瀽瀾瀿灀灁灂灃灄灅灆灇灈灉灊灋灌灍灎灏灐灑灒灓灔灕灖灗灘灙灚灛灜灝灞灟灠灡灢灣灤灥灦灧灨灩灪火灬灭灮灯灰灱灲灳灴灵灶灷灸灹灺灻灼災灾灿炀炁炂炃炄炅炆炇炈炉炊炋炌炍炎炏炐炑炒炓炔炕炖炗炘炙炚炛炜炝炞炟炠炡炢炣炤炥炦炧炨炩炪炫炬炭炮炯炰炱炲炳炴炵炶炷炸点為炻炼炽炾炿烀烁烂烃烄烅烆烇烈烉烊烋烌烍烎烏烐烑烒烓烔烕烖烗烘烙烚烛烜烝烞烟烠烡烢烣烤烥烦烧烨烩烪烫烬热烮烯烰烱烲烳烴烵烶烷烸烹烺烻烼烽烾烿焀焁焂焃焄焅焆焇焈焉焊焋焌焍焎焏焐焑焒焓焔焕焖焗焘焙焚焛焜焝焞焟焠無焢焣焤焥焦焧焨焩焪焫焬焭焮焯焰焱焲焳焴焵然焷焸焹焺焻焼焽焾焿煀煁煂煃煄煅煆煇煈煉煊煋煌煍煎煏煐煑煒煓煔煕煖煗煘煙煚煛煜煝煞煟煠煡煢煣煤煥煦照煨煩煪煫煬煭煮煯煰煱煲煳煴煵煶煷煸煹煺煻煼煽煾煿熀熁熂熃熄熅熆熇熈熉熊熋熌熍熎熏熐熑熒熓熔熕熖熗熘熙熚熛熜熝熞熟熠熡熢熣熤熥熦熧熨熩熪熫熬熭熮熯熰熱熲熳熴熵熶熷熸熹熺熻熼熽熾熿燀燁燂燃燄燅燆燇燈燉燊燋燌燍燎燏燐燑燒燓燔燕燖燗燘燙燚燛燜燝燞營燠燡燢燣燤燥燦燧燨燩燪燫燬燭燮燯燰燱燲燳燴燵燶燷燸燹燺燻燼燽燾燿爀爁爂爃爄爅爆爇爈爉爊爋爌爍爎爏爐爑爒爓爔爕爖爗爘爙爚爛爜爝爞爟爠爡爢爣爤爥爦爧爨爩爪爫爬爭爮爯爰爱爲爳爴爵父爷爸爹爺爻爼爽爾爿牀牁牂牃牄牅牆片版牉牊牋牌牍牎牏牐牑牒牓牔牕牖牗牘牙牚牛牜牝牞牟牠牡牢牣牤牥牦牧牨物牪牫牬牭牮牯牰牱牲牳牴牵牶牷牸特牺牻牼牽牾牿犀犁犂犃犄犅犆犇犈犉犊犋犌犍犎犏犐犑犒犓犔犕犖犗犘犙犚犛犜犝犞犟犠犡犢犣犤犥犦犧犨犩犪犫犬犭犮犯犰犱犲犳犴犵状犷犸犹犺犻犼犽犾犿狀狁狂狃狄狅狆狇狈狉狊狋狌狍狎狏狐狑狒狓狔狕狖狗狘狙狚狛狜狝狞狟狠狡狢狣狤狥狦狧狨狩狪狫独狭狮狯狰狱狲狳狴狵狶狷狸狹狺狻狼狽狾狿猀猁猂猃猄猅猆猇猈猉猊猋猌猍猎猏猐猑猒猓猔猕猖猗猘猙猚猛猜猝猞猟猠猡猢猣猤猥猦猧猨猩猪猫猬猭献猯猰猱猲猳猴猵猶猷猸猹猺猻猼猽猾猿獀獁獂獃獄獅獆獇獈獉獊獋獌獍獎獏獐獑獒獓獔獕獖獗獘獙獚獛獜獝獞獟獠獡獢獣獤獥獦獧獨獩獪獫獬獭獮獯獰獱獲獳獴獵獶獷獸獹獺獻獼獽獾獿玀玁玂玃玄玅玆率玈玉玊王玌玍玎玏玐玑玒玓玔玕玖玗玘玙玚玛玜玝玞玟玠玡玢玣玤玥玦玧玨玩玪玫玬玭玮环现玱玲玳玴玵玶玷玸玹玺玻玼玽玾玿珀珁珂珃珄珅珆珇珈珉珊珋珌珍珎珏珐珑珒珓珔珕珖珗珘珙珚珛珜珝珞珟珠珡珢珣珤珥珦珧珨珩珪珫珬班珮珯珰珱珲珳珴珵珶珷珸珹珺珻珼珽現珿琀琁琂球琄琅理琇琈琉琊琋琌琍琎琏琐琑琒琓琔琕琖琗琘琙琚琛琜琝琞琟琠琡琢琣琤琥琦琧琨琩琪琫琬琭琮琯琰琱琲琳琴琵琶琷琸琹琺琻琼琽琾琿瑀瑁瑂瑃瑄瑅瑆瑇瑈瑉瑊瑋瑌瑍瑎瑏瑐瑑瑒瑓瑔瑕瑖瑗瑘瑙瑚瑛瑜瑝瑞瑟瑠瑡瑢瑣瑤瑥瑦瑧瑨瑩瑪瑫瑬瑭瑮瑯瑰瑱瑲瑳瑴瑵瑶瑷瑸瑹瑺瑻瑼瑽瑾瑿璀璁璂璃璄璅璆璇璈璉璊璋璌璍璎璏璐璑璒璓璔璕璖璗璘璙璚璛璜璝璞璟璠璡璢璣璤璥璦璧璨璩璪璫璬璭璮璯環璱璲璳璴璵璶璷璸璹璺璻璼璽璾璿瓀瓁瓂瓃瓄瓅瓆瓇瓈瓉瓊瓋瓌瓍瓎瓏瓐瓑瓒瓓瓔瓕瓖瓗瓘瓙瓚瓛瓜瓝瓞瓟瓠瓡瓢瓣瓤瓥瓦瓧瓨瓩瓪瓫瓬瓭瓮瓯瓰瓱瓲瓳瓴瓵瓶瓷瓸瓹瓺瓻瓼瓽瓾瓿甀甁甂甃甄甅甆甇甈甉甊甋甌甍甎甏甐甑甒甓甔甕甖甗甘甙甚甛甜甝甞生甠甡產産甤甥甦甧用甩甪甫甬甭甮甯田由甲申甴电甶男甸甹町画甼甽甾甿畀畁畂畃畄畅畆畇畈畉畊畋界畍畎畏畐畑畒畓畔畕畖畗畘留畚畛畜畝畞畟畠畡畢畣畤略畦畧畨畩番畫畬畭畮畯異畱畲畳畴畵當畷畸畹畺畻畼畽畾畿疀疁疂疃疄疅疆疇疈疉疊疋疌疍疎疏疐疑疒疓疔疕疖疗疘疙疚疛疜疝疞疟疠疡疢疣疤疥疦疧疨疩疪疫疬疭疮疯疰疱疲疳疴疵疶疷疸疹疺疻疼疽疾疿痀痁痂痃痄病痆症痈痉痊痋痌痍痎痏痐痑痒痓痔痕痖痗痘痙痚痛痜痝痞痟痠痡痢痣痤痥痦痧痨痩痪痫痬痭痮痯痰痱痲痳痴痵痶痷痸痹痺痻痼痽痾痿瘀瘁瘂瘃瘄瘅瘆瘇瘈瘉瘊瘋瘌瘍瘎瘏瘐瘑瘒瘓瘔瘕瘖瘗瘘瘙瘚瘛瘜瘝瘞瘟瘠瘡瘢瘣瘤瘥瘦瘧瘨瘩瘪瘫瘬瘭瘮瘯瘰瘱瘲瘳瘴瘵瘶瘷瘸瘹瘺瘻瘼瘽瘾瘿癀癁療癃癄癅癆癇癈癉癊癋癌癍癎癏癐癑癒癓癔癕癖癗癘癙癚癛癜癝癞癟癠癡癢癣癤癥癦癧癨癩癪癫癬癭癮癯癰癱癲癳癴癵癶癷癸癹発登發白百癿皀皁皂皃的皅皆皇皈皉皊皋皌皍皎皏皐皑皒皓皔皕皖皗皘皙皚皛皜皝皞皟皠皡皢皣皤皥皦皧皨皩皪皫皬皭皮皯皰皱皲皳皴皵皶皷皸皹皺皻皼皽皾皿盀盁盂盃盄盅盆盇盈盉益盋盌盍盎盏盐监盒盓盔盕盖盗盘盙盚盛盜盝盞盟盠盡盢監盤盥盦盧盨盩盪盫盬盭目盯盰盱盲盳直盵盶盷相盹盺盻盼盽盾盿眀省眂眃眄眅眆眇眈眉眊看県眍眎眏眐眑眒眓眔眕眖眗眘眙眚眛眜眝眞真眠眡眢眣眤眥眦眧眨眩眪眫眬眭眮眯眰眱眲眳眴眵眶眷眸眹眺眻眼眽眾眿着睁睂睃睄睅睆睇睈睉睊睋睌睍睎睏睐睑睒睓睔睕睖睗睘睙睚睛睜睝睞睟睠睡睢督睤睥睦睧睨睩睪睫睬睭睮睯睰睱睲睳睴睵睶睷睸睹睺睻睼睽睾睿瞀瞁瞂瞃瞄瞅瞆瞇瞈瞉瞊瞋瞌瞍瞎瞏瞐瞑瞒瞓瞔瞕瞖瞗瞘瞙瞚瞛瞜瞝瞞瞟瞠瞡瞢瞣瞤瞥瞦瞧瞨瞩瞪瞫瞬瞭瞮瞯瞰瞱瞲瞳瞴瞵瞶瞷瞸瞹瞺瞻瞼瞽瞾瞿矀矁矂矃矄矅矆矇矈矉矊矋矌矍矎矏矐矑矒矓矔矕矖矗矘矙矚矛矜矝矞矟矠矡矢矣矤知矦矧矨矩矪矫矬短矮矯矰矱矲石矴矵矶矷矸矹矺矻矼矽矾矿砀码砂砃砄砅砆砇砈砉砊砋砌砍砎砏砐砑砒砓研砕砖砗砘砙砚砛砜砝砞砟砠砡砢砣砤砥砦砧砨砩砪砫砬砭砮砯砰砱砲砳破砵砶砷砸砹砺砻砼砽砾砿础硁硂硃硄硅硆硇硈硉硊硋硌硍硎硏硐硑硒硓硔硕硖硗硘硙硚硛硜硝硞硟硠硡硢硣硤硥硦硧硨硩硪硫硬硭确硯硰硱硲硳硴硵硶硷硸硹硺硻硼硽硾硿碀碁碂碃碄碅碆碇碈碉碊碋碌碍碎碏碐碑碒碓碔碕碖碗碘碙碚碛碜碝碞碟碠碡碢碣碤碥碦碧碨碩碪碫碬碭碮碯碰碱碲碳碴碵碶碷碸碹確碻碼碽碾碿磀磁磂磃磄磅磆磇磈磉磊磋磌磍磎磏磐磑磒磓磔磕磖磗磘磙磚磛磜磝磞磟磠磡磢磣磤磥磦磧磨磩磪磫磬磭磮磯磰磱磲磳磴磵磶磷磸磹磺磻磼磽磾磿礀礁礂礃礄礅礆礇礈礉礊礋礌礍礎礏礐礑礒礓礔礕礖礗礘礙礚礛礜礝礞礟礠礡礢礣礤礥礦礧礨礩礪礫礬礭礮礯礰礱礲礳礴礵礶礷礸礹示礻礼礽社礿祀祁祂祃祄祅祆祇祈祉祊祋祌祍祎祏祐祑祒祓祔祕祖祗祘祙祚祛祜祝神祟祠祡祢祣祤祥祦祧票祩祪祫祬祭祮祯祰祱祲祳祴祵祶祷祸祹祺祻祼祽祾祿禀禁禂禃禄禅禆禇禈禉禊禋禌禍禎福禐禑禒禓禔禕禖禗禘禙禚禛禜禝禞禟禠禡禢禣禤禥禦禧禨禩禪禫禬禭禮禯禰禱禲禳禴禵禶禷禸禹禺离禼禽禾禿秀私秂秃秄秅秆秇秈秉秊秋秌种秎秏秐科秒秓秔秕秖秗秘秙秚秛秜秝秞租秠秡秢秣秤秥秦秧秨秩秪秫秬秭秮积称秱秲秳秴秵秶秷秸秹秺移秼秽秾秿稀稁稂稃稄稅稆稇稈稉稊程稌稍税稏稐稑稒稓稔稕稖稗稘稙稚稛稜稝稞稟稠稡稢稣稤稥稦稧稨稩稪稫稬稭種稯稰稱稲稳稴稵稶稷稸稹稺稻稼稽稾稿穀穁穂穃穄穅穆穇穈穉穊穋穌積穎穏穐穑穒穓穔穕穖穗穘穙穚穛穜穝穞穟穠穡穢穣穤穥穦穧穨穩穪穫穬穭穮穯穰穱穲穳穴穵究穷穸穹空穻穼穽穾穿窀突窂窃窄窅窆窇窈窉窊窋窌窍窎窏窐窑窒窓窔窕窖窗窘窙窚窛窜窝窞窟窠窡窢窣窤窥窦窧窨窩窪窫窬窭窮窯窰窱窲窳窴窵窶窷窸窹窺窻窼窽窾窿竀竁竂竃竄竅竆竇竈竉竊立竌竍竎竏竐竑竒竓竔竕竖竗竘站竚竛竜竝竞竟章竡竢竣竤童竦竧竨竩竪竫竬竭竮端竰竱竲竳竴竵競竷竸竹竺竻竼竽竾竿笀笁笂笃笄笅笆笇笈笉笊笋笌笍笎笏笐笑笒笓笔笕笖笗笘笙笚笛笜笝笞笟笠笡笢笣笤笥符笧笨笩笪笫第笭笮笯笰笱笲笳笴笵笶笷笸笹笺笻笼笽笾笿筀筁筂筃筄筅筆筇筈等筊筋筌筍筎筏筐筑筒筓答筕策筗筘筙筚筛筜筝筞筟筠筡筢筣筤筥筦筧筨筩筪筫筬筭筮筯筰筱筲筳筴筵筶筷筸筹筺筻筼筽签筿简箁箂箃箄箅箆箇箈箉箊箋箌箍箎箏箐箑箒箓箔箕箖算箘箙箚箛箜箝箞箟箠管箢箣箤箥箦箧箨箩箪箫箬箭箮箯箰箱箲箳箴箵箶箷箸箹箺箻箼箽箾箿節篁篂篃範篅篆篇篈築篊篋篌篍篎篏篐篑篒篓篔篕篖篗篘篙篚篛篜篝篞篟篠篡篢篣篤篥篦篧篨篩篪篫篬篭篮篯篰篱篲篳篴篵篶篷篸篹篺篻篼篽篾篿簀簁簂簃簄簅簆簇簈簉簊簋簌簍簎簏簐簑簒簓簔簕簖簗簘簙簚簛簜簝簞簟簠簡簢簣簤簥簦簧簨簩簪簫簬簭簮簯簰簱簲簳簴簵簶簷簸簹簺簻簼簽簾簿籀籁籂籃籄籅籆籇籈籉籊籋籌籍籎籏籐籑籒籓籔籕籖籗籘籙籚籛籜籝籞籟籠籡籢籣籤籥籦籧籨籩籪籫籬籭籮籯籰籱籲米籴籵籶籷籸籹籺类籼籽籾籿粀粁粂粃粄粅粆粇粈粉粊粋粌粍粎粏粐粑粒粓粔粕粖粗粘粙粚粛粜粝粞粟粠粡粢粣粤粥粦粧粨粩粪粫粬粭粮粯粰粱粲粳粴粵粶粷粸粹粺粻粼粽精粿糀糁糂糃糄糅糆糇糈糉糊糋糌糍糎糏糐糑糒糓糔糕糖糗糘糙糚糛糜糝糞糟糠糡糢糣糤糥糦糧糨糩糪糫糬糭糮糯糰糱糲糳糴糵糶糷糸糹糺系糼糽糾糿紀紁紂紃約紅紆紇紈紉紊紋紌納紎紏紐紑紒紓純紕紖紗紘紙級紛紜紝紞紟素紡索紣紤紥紦紧紨紩紪紫紬紭紮累細紱紲紳紴紵紶紷紸紹紺紻紼紽紾紿絀絁終絃組絅絆絇絈絉絊絋経絍絎絏結絑絒絓絔絕絖絗絘絙絚絛絜絝絞絟絠絡絢絣絤絥給絧絨絩絪絫絬絭絮絯絰統絲絳絴絵絶絷絸絹絺絻絼絽絾絿綀綁綂綃綄綅綆綇綈綉綊綋綌綍綎綏綐綑綒經綔綕綖綗綘継続綛綜綝綞綟綠綡綢綣綤綥綦綧綨綩綪綫綬維綮綯綰綱網綳綴綵綶綷綸綹綺綻綼綽綾綿緀緁緂緃緄緅緆緇緈緉緊緋緌緍緎総緐緑緒緓緔緕緖緗緘緙線緛緜緝緞緟締緡緢緣緤緥緦緧編緩緪緫緬緭緮緯緰緱緲緳練緵緶緷緸緹緺緻緼緽緾緿縀縁縂縃縄縅縆縇縈縉縊縋縌縍縎縏縐縑縒縓縔縕縖縗縘縙縚縛縜縝縞縟縠縡縢縣縤縥縦縧縨縩縪縫縬縭縮縯縰縱縲縳縴縵縶縷縸縹縺縻縼總績縿繀繁繂繃繄繅繆繇繈繉繊繋繌繍繎繏繐繑繒繓織繕繖繗繘繙繚繛繜繝繞繟繠繡繢繣繤繥繦繧繨繩繪繫繬繭繮繯繰繱繲繳繴繵繶繷繸繹繺繻繼繽繾繿纀纁纂纃纄纅纆纇纈纉纊纋續纍纎纏纐纑纒纓纔纕纖纗纘纙纚纛纜纝纞纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵缶缷缸缹缺缻缼缽缾缿罀罁罂罃罄罅罆罇罈罉罊罋罌罍罎罏罐网罒罓罔罕罖罗罘罙罚罛罜罝罞罟罠罡罢罣罤罥罦罧罨罩罪罫罬罭置罯罰罱署罳罴罵罶罷罸罹罺罻罼罽罾罿羀羁羂羃羄羅羆羇羈羉羊羋羌羍美羏羐羑羒羓羔羕羖羗羘羙羚羛羜羝羞羟羠羡羢羣群羥羦羧羨義羪羫羬羭羮羯羰羱羲羳羴羵羶羷羸羹羺羻羼羽羾羿翀翁翂翃翄翅翆翇翈翉翊翋翌翍翎翏翐翑習翓翔翕翖翗翘翙翚翛翜翝翞翟翠翡翢翣翤翥翦翧翨翩翪翫翬翭翮翯翰翱翲翳翴翵翶翷翸翹翺翻翼翽翾翿耀老耂考耄者耆耇耈耉耊耋而耍耎耏耐耑耒耓耔耕耖耗耘耙耚耛耜耝耞耟耠耡耢耣耤耥耦耧耨耩耪耫耬耭耮耯耰耱耲耳耴耵耶耷耸耹耺耻耼耽耾耿聀聁聂聃聄聅聆聇聈聉聊聋职聍聎聏聐聑聒聓联聕聖聗聘聙聚聛聜聝聞聟聠聡聢聣聤聥聦聧聨聩聪聫聬聭聮聯聰聱聲聳聴聵聶職聸聹聺聻聼聽聾聿肀肁肂肃肄肅肆肇肈肉肊肋肌肍肎肏肐肑肒肓肔肕肖肗肘肙肚肛肜肝肞肟肠股肢肣肤肥肦肧肨肩肪肫肬肭肮肯肰肱育肳肴肵肶肷肸肹肺肻肼肽肾肿胀胁胂胃胄胅胆胇胈胉胊胋背胍胎胏胐胑胒胓胔胕胖胗胘胙胚胛胜胝胞胟胠胡胢胣胤胥胦胧胨胩胪胫胬胭胮胯胰胱胲胳胴胵胶胷胸胹胺胻胼能胾胿脀脁脂脃脄脅脆脇脈脉脊脋脌脍脎脏脐脑脒脓脔脕脖脗脘脙脚脛脜脝脞脟脠脡脢脣脤脥脦脧脨脩脪脫脬脭脮脯脰脱脲脳脴脵脶脷脸脹脺脻脼脽脾脿腀腁腂腃腄腅腆腇腈腉腊腋腌腍腎腏腐腑腒腓腔腕腖腗腘腙腚腛腜腝腞腟腠腡腢腣腤腥腦腧腨腩腪腫腬腭腮腯腰腱腲腳腴腵腶腷腸腹腺腻腼腽腾腿膀膁膂膃膄膅膆膇膈膉膊膋膌膍膎膏膐膑膒膓膔膕膖膗膘膙膚膛膜膝膞膟膠膡膢膣膤膥膦膧膨膩膪膫膬膭膮膯膰膱膲膳膴膵膶膷膸膹膺膻膼膽膾膿臀臁臂臃臄臅臆臇臈臉臊臋臌臍臎臏臐臑臒臓臔臕臖臗臘臙臚臛臜臝臞臟臠臡臢臣臤臥臦臧臨臩自臫臬臭臮臯臰臱臲至致臵臶臷臸臹臺臻臼臽臾臿舀舁舂舃舄舅舆與興舉舊舋舌舍舎舏舐舑舒舓舔舕舖舗舘舙舚舛舜舝舞舟舠舡舢舣舤舥舦舧舨舩航舫般舭舮舯舰舱舲舳舴舵舶舷舸船舺舻舼舽舾舿艀艁艂艃艄艅艆艇艈艉艊艋艌艍艎艏艐艑艒艓艔艕艖艗艘艙艚艛艜艝艞艟艠艡艢艣艤艥艦艧艨艩艪艫艬艭艮良艰艱色艳艴艵艶艷艸艹艺艻艼艽艾艿芀芁节芃芄芅芆芇芈芉芊芋芌芍芎芏芐芑芒芓芔芕芖芗芘芙芚芛芜芝芞芟芠芡芢芣芤芥芦芧芨芩芪芫芬芭芮芯芰花芲芳芴芵芶芷芸芹芺芻芼芽芾芿苀苁苂苃苄苅苆苇苈苉苊苋苌苍苎苏苐苑苒苓苔苕苖苗苘苙苚苛苜苝苞苟苠苡苢苣苤若苦苧苨苩苪苫苬苭苮苯苰英苲苳苴苵苶苷苸苹苺苻苼苽苾苿茀茁茂范茄茅茆茇茈茉茊茋茌茍茎茏茐茑茒茓茔茕茖茗茘茙茚茛茜茝茞茟茠茡茢茣茤茥茦茧茨茩茪茫茬茭茮茯茰茱茲茳茴茵茶茷茸茹茺茻茼茽茾茿荀荁荂荃荄荅荆荇荈草荊荋荌荍荎荏荐荑荒荓荔荕荖荗荘荙荚荛荜荝荞荟荠荡荢荣荤荥荦荧荨荩荪荫荬荭荮药荰荱荲荳荴荵荶荷荸荹荺荻荼荽荾荿莀莁莂莃莄莅莆莇莈莉莊莋莌莍莎莏莐莑莒莓莔莕莖莗莘莙莚莛莜莝莞莟莠莡莢莣莤莥莦莧莨莩莪莫莬莭莮莯莰莱莲莳莴莵莶获莸莹莺莻莼莽莾莿菀菁菂菃菄菅菆菇菈菉菊菋菌菍菎菏菐菑菒菓菔菕菖菗菘菙菚菛菜菝菞菟菠菡菢菣菤菥菦菧菨菩菪菫菬菭菮華菰菱菲菳菴菵菶菷菸菹菺菻菼菽菾菿萀萁萂萃萄萅萆萇萈萉萊萋萌萍萎萏萐萑萒萓萔萕萖萗萘萙萚萛萜萝萞萟萠萡萢萣萤营萦萧萨萩萪萫萬萭萮萯萰萱萲萳萴萵萶萷萸萹萺萻萼落萾萿葀葁葂葃葄葅葆葇葈葉葊葋葌葍葎葏葐葑葒葓葔葕葖著葘葙葚葛葜葝葞葟葠葡葢董葤葥葦葧葨葩葪葫葬葭葮葯葰葱葲葳葴葵葶葷葸葹葺葻葼葽葾葿蒀蒁蒂蒃蒄蒅蒆蒇蒈蒉蒊蒋蒌蒍蒎蒏蒐蒑蒒蒓蒔蒕蒖蒗蒘蒙蒚蒛蒜蒝蒞蒟蒠蒡蒢蒣蒤蒥蒦蒧蒨蒩蒪蒫蒬蒭蒮蒯蒰蒱蒲蒳蒴蒵蒶蒷蒸蒹蒺蒻蒼蒽蒾蒿蓀蓁蓂蓃蓄蓅蓆蓇蓈蓉蓊蓋蓌蓍蓎蓏蓐蓑蓒蓓蓔蓕蓖蓗蓘蓙蓚蓛蓜蓝蓞蓟蓠蓡蓢蓣蓤蓥蓦蓧蓨蓩蓪蓫蓬蓭蓮蓯蓰蓱蓲蓳蓴蓵蓶蓷蓸蓹蓺蓻蓼蓽蓾蓿蔀蔁蔂蔃蔄蔅蔆蔇蔈蔉蔊蔋蔌蔍蔎蔏蔐蔑蔒蔓蔔蔕蔖蔗蔘蔙蔚蔛蔜蔝蔞蔟蔠蔡蔢蔣蔤蔥蔦蔧蔨蔩蔪蔫蔬蔭蔮蔯蔰蔱蔲蔳蔴蔵蔶蔷蔸蔹蔺蔻蔼蔽蔾蔿蕀蕁蕂蕃蕄蕅蕆蕇蕈蕉蕊蕋蕌蕍蕎蕏蕐蕑蕒蕓蕔蕕蕖蕗蕘蕙蕚蕛蕜蕝蕞蕟蕠蕡蕢蕣蕤蕥蕦蕧蕨蕩蕪蕫蕬蕭蕮蕯蕰蕱蕲蕳蕴蕵蕶蕷蕸蕹蕺蕻蕼蕽蕾蕿薀薁薂薃薄薅薆薇薈薉薊薋薌薍薎薏薐薑薒薓薔薕薖薗薘薙薚薛薜薝薞薟薠薡薢薣薤薥薦薧薨薩薪薫薬薭薮薯薰薱薲薳薴薵薶薷薸薹薺薻薼薽薾薿藀藁藂藃藄藅藆藇藈藉藊藋藌藍藎藏藐藑藒藓藔藕藖藗藘藙藚藛藜藝藞藟藠藡藢藣藤藥藦藧藨藩藪藫藬藭藮藯藰藱藲藳藴藵藶藷藸藹藺藻藼藽藾藿蘀蘁蘂蘃蘄蘅蘆蘇蘈蘉蘊蘋蘌蘍蘎蘏蘐蘑蘒蘓蘔蘕蘖蘗蘘蘙蘚蘛蘜蘝蘞蘟蘠蘡蘢蘣蘤蘥蘦蘧蘨蘩蘪蘫蘬蘭蘮蘯蘰蘱蘲蘳蘴蘵蘶蘷蘸蘹蘺蘻蘼蘽蘾蘿虀虁虂虃虄虅虆虇虈虉虊虋虌虍虎虏虐虑虒虓虔處虖虗虘虙虚虛虜虝虞號虠虡虢虣虤虥虦虧虨虩虪虫虬虭虮虯虰虱虲虳虴虵虶虷虸虹虺虻虼虽虾虿蚀蚁蚂蚃蚄蚅蚆蚇蚈蚉蚊蚋蚌蚍蚎蚏蚐蚑蚒蚓蚔蚕蚖蚗蚘蚙蚚蚛蚜蚝蚞蚟蚠蚡蚢蚣蚤蚥蚦蚧蚨蚩蚪蚫蚬蚭蚮蚯蚰蚱蚲蚳蚴蚵蚶蚷蚸蚹蚺蚻蚼蚽蚾蚿蛀蛁蛂蛃蛄蛅蛆蛇蛈蛉蛊蛋蛌蛍蛎蛏蛐蛑蛒蛓蛔蛕蛖蛗蛘蛙蛚蛛蛜蛝蛞蛟蛠蛡蛢蛣蛤蛥蛦蛧蛨蛩蛪蛫蛬蛭蛮蛯蛰蛱蛲蛳蛴蛵蛶蛷蛸蛹蛺蛻蛼蛽蛾蛿蜀蜁蜂蜃蜄蜅蜆蜇蜈蜉蜊蜋蜌蜍蜎蜏蜐蜑蜒蜓蜔蜕蜖蜗蜘蜙蜚蜛蜜蜝蜞蜟蜠蜡蜢蜣蜤蜥蜦蜧蜨蜩蜪蜫蜬蜭蜮蜯蜰蜱蜲蜳蜴蜵蜶蜷蜸蜹蜺蜻蜼蜽蜾蜿蝀蝁蝂蝃蝄蝅蝆蝇蝈蝉蝊蝋蝌蝍蝎蝏蝐蝑蝒蝓蝔蝕蝖蝗蝘蝙蝚蝛蝜蝝蝞蝟蝠蝡蝢蝣蝤蝥蝦蝧蝨蝩蝪蝫蝬蝭蝮蝯蝰蝱蝲蝳蝴蝵蝶蝷蝸蝹蝺蝻蝼蝽蝾蝿螀螁螂螃螄螅螆螇螈螉螊螋螌融螎螏螐螑螒螓螔螕螖螗螘螙螚螛螜螝螞螟螠螡螢螣螤螥螦螧螨螩螪螫螬螭螮螯螰螱螲螳螴螵螶螷螸螹螺螻螼螽螾螿蟀蟁蟂蟃蟄蟅蟆蟇蟈蟉蟊蟋蟌蟍蟎蟏蟐蟑蟒蟓蟔蟕蟖蟗蟘蟙蟚蟛蟜蟝蟞蟟蟠蟡蟢蟣蟤蟥蟦蟧蟨蟩蟪蟫蟬蟭蟮蟯蟰蟱蟲蟳蟴蟵蟶蟷蟸蟹蟺蟻蟼蟽蟾蟿蠀蠁蠂蠃蠄蠅蠆蠇蠈蠉蠊蠋蠌蠍蠎蠏蠐蠑蠒蠓蠔蠕蠖蠗蠘蠙蠚蠛蠜蠝蠞蠟蠠蠡蠢蠣蠤蠥蠦蠧蠨蠩蠪蠫蠬蠭蠮蠯蠰蠱蠲蠳蠴蠵蠶蠷蠸蠹蠺蠻蠼蠽蠾蠿血衁衂衃衄衅衆衇衈衉衊衋行衍衎衏衐衑衒術衔衕衖街衘衙衚衛衜衝衞衟衠衡衢衣衤补衦衧表衩衪衫衬衭衮衯衰衱衲衳衴衵衶衷衸衹衺衻衼衽衾衿袀袁袂袃袄袅袆袇袈袉袊袋袌袍袎袏袐袑袒袓袔袕袖袗袘袙袚袛袜袝袞袟袠袡袢袣袤袥袦袧袨袩袪被袬袭袮袯袰袱袲袳袴袵袶袷袸袹袺袻袼袽袾袿裀裁裂裃裄装裆裇裈裉裊裋裌裍裎裏裐裑裒裓裔裕裖裗裘裙裚裛補裝裞裟裠裡裢裣裤裥裦裧裨裩裪裫裬裭裮裯裰裱裲裳裴裵裶裷裸裹裺裻裼製裾裿褀褁褂褃褄褅褆複褈褉褊褋褌褍褎褏褐褑褒褓褔褕褖褗褘褙褚褛褜褝褞褟褠褡褢褣褤褥褦褧褨褩褪褫褬褭褮褯褰褱褲褳褴褵褶褷褸褹褺褻褼褽褾褿襀襁襂襃襄襅襆襇襈襉襊襋襌襍襎襏襐襑襒襓襔襕襖襗襘襙襚襛襜襝襞襟襠襡襢襣襤襥襦襧襨襩襪襫襬襭襮襯襰襱襲襳襴襵襶襷襸襹襺襻襼襽襾西覀要覂覃覄覅覆覇覈覉覊見覌覍覎規覐覑覒覓覔覕視覗覘覙覚覛覜覝覞覟覠覡覢覣覤覥覦覧覨覩親覫覬覭覮覯覰覱覲観覴覵覶覷覸覹覺覻覼覽覾覿觀见观觃规觅视觇览觉觊觋觌觍觎觏觐觑角觓觔觕觖觗觘觙觚觛觜觝觞觟觠觡觢解觤觥触觧觨觩觪觫觬觭觮觯觰觱觲觳觴觵觶觷觸觹觺觻觼觽觾觿言訁訂訃訄訅訆訇計訉訊訋訌訍討訏訐訑訒訓訔訕訖託記訙訚訛訜訝訞訟訠訡訢訣訤訥訦訧訨訩訪訫訬設訮訯訰許訲訳訴訵訶訷訸訹診註証訽訾訿詀詁詂詃詄詅詆詇詈詉詊詋詌詍詎詏詐詑詒詓詔評詖詗詘詙詚詛詜詝詞詟詠詡詢詣詤詥試詧詨詩詪詫詬詭詮詯詰話該詳詴詵詶詷詸詹詺詻詼詽詾詿誀誁誂誃誄誅誆誇誈誉誊誋誌認誎誏誐誑誒誓誔誕誖誗誘誙誚誛誜誝語誟誠誡誢誣誤誥誦誧誨誩說誫説読誮誯誰誱課誳誴誵誶誷誸誹誺誻誼誽誾調諀諁諂諃諄諅諆談諈諉諊請諌諍諎諏諐諑諒諓諔諕論諗諘諙諚諛諜諝諞諟諠諡諢諣諤諥諦諧諨諩諪諫諬諭諮諯諰諱諲諳諴諵諶諷諸諹諺諻諼諽諾諿謀謁謂謃謄謅謆謇謈謉謊謋謌謍謎謏謐謑謒謓謔謕謖謗謘謙謚講謜謝謞謟謠謡謢謣謤謥謦謧謨謩謪謫謬謭謮謯謰謱謲謳謴謵謶謷謸謹謺謻謼謽謾謿譀譁譂譃譄譅譆譇譈證譊譋譌譍譎譏譐譑譒譓譔譕譖譗識譙譚譛譜譝譞譟譠譡譢譣譤譥警譧譨譩譪譫譬譭譮譯議譱譲譳譴譵譶護譸譹譺譻譼譽譾譿讀讁讂讃讄讅讆讇讈讉變讋讌讍讎讏讐讑讒讓讔讕讖讗讘讙讚讛讜讝讞讟讠计订讣认讥讦讧讨让讪讫讬训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谉谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷谸谹谺谻谼谽谾谿豀豁豂豃豄豅豆豇豈豉豊豋豌豍豎豏豐豑豒豓豔豕豖豗豘豙豚豛豜豝豞豟豠象豢豣豤豥豦豧豨豩豪豫豬豭豮豯豰豱豲豳豴豵豶豷豸豹豺豻豼豽豾豿貀貁貂貃貄貅貆貇貈貉貊貋貌貍貎貏貐貑貒貓貔貕貖貗貘貙貚貛貜貝貞貟負財貢貣貤貥貦貧貨販貪貫責貭貮貯貰貱貲貳貴貵貶買貸貹貺費貼貽貾貿賀賁賂賃賄賅賆資賈賉賊賋賌賍賎賏賐賑賒賓賔賕賖賗賘賙賚賛賜賝賞賟賠賡賢賣賤賥賦賧賨賩質賫賬賭賮賯賰賱賲賳賴賵賶賷賸賹賺賻購賽賾賿贀贁贂贃贄贅贆贇贈贉贊贋贌贍贎贏贐贑贒贓贔贕贖贗贘贙贚贛贜贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赤赥赦赧赨赩赪赫赬赭赮赯走赱赲赳赴赵赶起赸赹赺赻赼赽赾赿趀趁趂趃趄超趆趇趈趉越趋趌趍趎趏趐趑趒趓趔趕趖趗趘趙趚趛趜趝趞趟趠趡趢趣趤趥趦趧趨趩趪趫趬趭趮趯趰趱趲足趴趵趶趷趸趹趺趻趼趽趾趿跀跁跂跃跄跅跆跇跈跉跊跋跌跍跎跏跐跑跒跓跔跕跖跗跘跙跚跛跜距跞跟跠跡跢跣跤跥跦跧跨跩跪跫跬跭跮路跰跱跲跳跴践跶跷跸跹跺跻跼跽跾跿踀踁踂踃踄踅踆踇踈踉踊踋踌踍踎踏踐踑踒踓踔踕踖踗踘踙踚踛踜踝踞踟踠踡踢踣踤踥踦踧踨踩踪踫踬踭踮踯踰踱踲踳踴踵踶踷踸踹踺踻踼踽踾踿蹀蹁蹂蹃蹄蹅蹆蹇蹈蹉蹊蹋蹌蹍蹎蹏蹐蹑蹒蹓蹔蹕蹖蹗蹘蹙蹚蹛蹜蹝蹞蹟蹠蹡蹢蹣蹤蹥蹦蹧蹨蹩蹪蹫蹬蹭蹮蹯蹰蹱蹲蹳蹴蹵蹶蹷蹸蹹蹺蹻蹼蹽蹾蹿躀躁躂躃躄躅躆躇躈躉躊躋躌躍躎躏躐躑躒躓躔躕躖躗躘躙躚躛躜躝躞躟躠躡躢躣躤躥躦躧躨躩躪身躬躭躮躯躰躱躲躳躴躵躶躷躸躹躺躻躼躽躾躿軀軁軂軃軄軅軆軇軈軉車軋軌軍軎軏軐軑軒軓軔軕軖軗軘軙軚軛軜軝軞軟軠軡転軣軤軥軦軧軨軩軪軫軬軭軮軯軰軱軲軳軴軵軶軷軸軹軺軻軼軽軾軿輀輁輂較輄輅輆輇輈載輊輋輌輍輎輏輐輑輒輓輔輕輖輗輘輙輚輛輜輝輞輟輠輡輢輣輤輥輦輧輨輩輪輫輬輭輮輯輰輱輲輳輴輵輶輷輸輹輺輻輼輽輾輿轀轁轂轃轄轅轆轇轈轉轊轋轌轍轎轏轐轑轒轓轔轕轖轗轘轙轚轛轜轝轞轟轠轡轢轣轤轥车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辛辜辝辞辟辠辡辢辣辤辥辦辧辨辩辪辫辬辭辮辯辰辱農辳辴辵辶辷辸边辺辻込辽达辿迀迁迂迃迄迅迆过迈迉迊迋迌迍迎迏运近迒迓返迕迖迗还这迚进远违连迟迠迡迢迣迤迥迦迧迨迩迪迫迬迭迮迯述迱迲迳迴迵迶迷迸迹迺迻迼追迾迿退送适逃逄逅逆逇逈选逊逋逌逍逎透逐逑递逓途逕逖逗逘這通逛逜逝逞速造逡逢連逤逥逦逧逨逩逪逫逬逭逮逯逰週進逳逴逵逶逷逸逹逺逻逼逽逾逿遀遁遂遃遄遅遆遇遈遉遊運遌遍過遏遐遑遒道達違遖遗遘遙遚遛遜遝遞遟遠遡遢遣遤遥遦遧遨適遪遫遬遭遮遯遰遱遲遳遴遵遶遷選遹遺遻遼遽遾避邀邁邂邃還邅邆邇邈邉邊邋邌邍邎邏邐邑邒邓邔邕邖邗邘邙邚邛邜邝邞邟邠邡邢那邤邥邦邧邨邩邪邫邬邭邮邯邰邱邲邳邴邵邶邷邸邹邺邻邼邽邾邿郀郁郂郃郄郅郆郇郈郉郊郋郌郍郎郏郐郑郒郓郔郕郖郗郘郙郚郛郜郝郞郟郠郡郢郣郤郥郦郧部郩郪郫郬郭郮郯郰郱郲郳郴郵郶郷郸郹郺郻郼都郾郿鄀鄁鄂鄃鄄鄅鄆鄇鄈鄉鄊鄋鄌鄍鄎鄏鄐鄑鄒鄓鄔鄕鄖鄗鄘鄙鄚鄛鄜鄝鄞鄟鄠鄡鄢鄣鄤鄥鄦鄧鄨鄩鄪鄫鄬鄭鄮鄯鄰鄱鄲鄳鄴鄵鄶鄷鄸鄹鄺鄻鄼鄽鄾鄿酀酁酂酃酄酅酆酇酈酉酊酋酌配酎酏酐酑酒酓酔酕酖酗酘酙酚酛酜酝酞酟酠酡酢酣酤酥酦酧酨酩酪酫酬酭酮酯酰酱酲酳酴酵酶酷酸酹酺酻酼酽酾酿醀醁醂醃醄醅醆醇醈醉醊醋醌醍醎醏醐醑醒醓醔醕醖醗醘醙醚醛醜醝醞醟醠醡醢醣醤醥醦醧醨醩醪醫醬醭醮醯醰醱醲醳醴醵醶醷醸醹醺醻醼醽醾醿釀釁釂釃釄釅釆采釈釉释釋里重野量釐金釒釓釔釕釖釗釘釙釚釛釜針釞釟釠釡釢釣釤釥釦釧釨釩釪釫釬釭釮釯釰釱釲釳釴釵釶釷釸釹釺釻釼釽釾釿鈀鈁鈂鈃鈄鈅鈆鈇鈈鈉鈊鈋鈌鈍鈎鈏鈐鈑鈒鈓鈔鈕鈖鈗鈘鈙鈚鈛鈜鈝鈞鈟鈠鈡鈢鈣鈤鈥鈦鈧鈨鈩鈪鈫鈬鈭鈮鈯鈰鈱鈲鈳鈴鈵鈶鈷鈸鈹鈺鈻鈼鈽鈾鈿鉀鉁鉂鉃鉄鉅鉆鉇鉈鉉鉊鉋鉌鉍鉎鉏鉐鉑鉒鉓鉔鉕鉖鉗鉘鉙鉚鉛鉜鉝鉞鉟鉠鉡鉢鉣鉤鉥鉦鉧鉨鉩鉪鉫鉬鉭鉮鉯鉰鉱鉲鉳鉴鉵鉶鉷鉸鉹鉺鉻鉼鉽鉾鉿銀銁銂銃銄銅銆銇銈銉銊銋銌銍銎銏銐銑銒銓銔銕銖銗銘銙銚銛銜銝銞銟銠銡銢銣銤銥銦銧銨銩銪銫銬銭銮銯銰銱銲銳銴銵銶銷銸銹銺銻銼銽銾銿鋀鋁鋂鋃鋄鋅鋆鋇鋈鋉鋊鋋鋌鋍鋎鋏鋐鋑鋒鋓鋔鋕鋖鋗鋘鋙鋚鋛鋜鋝鋞鋟鋠鋡鋢鋣鋤鋥鋦鋧鋨鋩鋪鋫鋬鋭鋮鋯鋰鋱鋲鋳鋴鋵鋶鋷鋸鋹鋺鋻鋼鋽鋾鋿錀錁錂錃錄錅錆錇錈錉錊錋錌錍錎錏錐錑錒錓錔錕錖錗錘錙錚錛錜錝錞錟錠錡錢錣錤錥錦錧錨錩錪錫錬錭錮錯錰錱録錳錴錵錶錷錸錹錺錻錼錽錾錿鍀鍁鍂鍃鍄鍅鍆鍇鍈鍉鍊鍋鍌鍍鍎鍏鍐鍑鍒鍓鍔鍕鍖鍗鍘鍙鍚鍛鍜鍝鍞鍟鍠鍡鍢鍣鍤鍥鍦鍧鍨鍩鍪鍫鍬鍭鍮鍯鍰鍱鍲鍳鍴鍵鍶鍷鍸鍹鍺鍻鍼鍽鍾鍿鎀鎁鎂鎃鎄鎅鎆鎇鎈鎉鎊鎋鎌鎍鎎鎏鎐鎑鎒鎓鎔鎕鎖鎗鎘鎙鎚鎛鎜鎝鎞鎟鎠鎡鎢鎣鎤鎥鎦鎧鎨鎩鎪鎫鎬鎭鎮鎯鎰鎱鎲鎳鎴鎵鎶鎷鎸鎹鎺鎻鎼鎽鎾鎿鏀鏁鏂鏃鏄鏅鏆鏇鏈鏉鏊鏋鏌鏍鏎鏏鏐鏑鏒鏓鏔鏕鏖鏗鏘鏙鏚鏛鏜鏝鏞鏟鏠鏡鏢鏣鏤鏥鏦鏧鏨鏩鏪鏫鏬鏭鏮鏯鏰鏱鏲鏳鏴鏵鏶鏷鏸鏹鏺鏻鏼鏽鏾鏿鐀鐁鐂鐃鐄鐅鐆鐇鐈鐉鐊鐋鐌鐍鐎鐏鐐鐑鐒鐓鐔鐕鐖鐗鐘鐙鐚鐛鐜鐝鐞鐟鐠鐡鐢鐣鐤鐥鐦鐧鐨鐩鐪鐫鐬鐭鐮鐯鐰鐱鐲鐳鐴鐵鐶鐷鐸鐹鐺鐻鐼鐽鐾鐿鑀鑁鑂鑃鑄鑅鑆鑇鑈鑉鑊鑋鑌鑍鑎鑏鑐鑑鑒鑓鑔鑕鑖鑗鑘鑙鑚鑛鑜鑝鑞鑟鑠鑡鑢鑣鑤鑥鑦鑧鑨鑩鑪鑫鑬鑭鑮鑯鑰鑱鑲鑳鑴鑵鑶鑷鑸鑹鑺鑻鑼鑽鑾鑿钀钁钂钃钄钅钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钜钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铇铈铉铊铋铌铍铎铏铐铑铒铓铔铕铖铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛锜锝锞锟锠锡锢锣锤锥锦锧锨锩锪锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镄镅镆镇镈镉镊镋镌镍镎镏镐镑镒镓镔镕镖镗镘镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镵镶長镸镹镺镻镼镽镾长門閁閂閃閄閅閆閇閈閉閊開閌閍閎閏閐閑閒間閔閕閖閗閘閙閚閛閜閝閞閟閠閡関閣閤閥閦閧閨閩閪閫閬閭閮閯閰閱閲閳閴閵閶閷閸閹閺閻閼閽閾閿闀闁闂闃闄闅闆闇闈闉闊闋闌闍闎闏闐闑闒闓闔闕闖闗闘闙闚闛關闝闞闟闠闡闢闣闤闥闦闧门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛阜阝阞队阠阡阢阣阤阥阦阧阨阩阪阫阬阭阮阯阰阱防阳阴阵阶阷阸阹阺阻阼阽阾阿陀陁陂陃附际陆陇陈陉陊陋陌降陎陏限陑陒陓陔陕陖陗陘陙陚陛陜陝陞陟陠陡院陣除陥陦陧陨险陪陫陬陭陮陯陰陱陲陳陴陵陶陷陸陹険陻陼陽陾陿隀隁隂隃隄隅隆隇隈隉隊隋隌隍階随隐隑隒隓隔隕隖隗隘隙隚際障隝隞隟隠隡隢隣隤隥隦隧隨隩險隫隬隭隮隯隰隱隲隳隴隵隶隷隸隹隺隻隼隽难隿雀雁雂雃雄雅集雇雈雉雊雋雌雍雎雏雐雑雒雓雔雕雖雗雘雙雚雛雜雝雞雟雠雡離難雤雥雦雧雨雩雪雫雬雭雮雯雰雱雲雳雴雵零雷雸雹雺電雼雽雾雿需霁霂霃霄霅霆震霈霉霊霋霌霍霎霏霐霑霒霓霔霕霖霗霘霙霚霛霜霝霞霟霠霡霢霣霤霥霦霧霨霩霪霫霬霭霮霯霰霱露霳霴霵霶霷霸霹霺霻霼霽霾霿靀靁靂靃靄靅靆靇靈靉靊靋靌靍靎靏靐靑青靓靔靕靖靗靘静靚靛靜靝非靟靠靡面靣靤靥靦靧靨革靪靫靬靭靮靯靰靱靲靳靴靵靶靷靸靹靺靻靼靽靾靿鞀鞁鞂鞃鞄鞅鞆鞇鞈鞉鞊鞋鞌鞍鞎鞏鞐鞑鞒鞓鞔鞕鞖鞗鞘鞙鞚鞛鞜鞝鞞鞟鞠鞡鞢鞣鞤鞥鞦鞧鞨鞩鞪鞫鞬鞭鞮鞯鞰鞱鞲鞳鞴鞵鞶鞷鞸鞹鞺鞻鞼鞽鞾鞿韀韁韂韃韄韅韆韇韈韉韊韋韌韍韎韏韐韑韒韓韔韕韖韗韘韙韚韛韜韝韞韟韠韡韢韣韤韥韦韧韨韩韪韫韬韭韮韯韰韱韲音韴韵韶韷韸韹韺韻韼韽韾響頀頁頂頃頄項順頇須頉頊頋頌頍頎頏預頑頒頓頔頕頖頗領頙頚頛頜頝頞頟頠頡頢頣頤頥頦頧頨頩頪頫頬頭頮頯頰頱頲頳頴頵頶頷頸頹頺頻頼頽頾頿顀顁顂顃顄顅顆顇顈顉顊顋題額顎顏顐顑顒顓顔顕顖顗願顙顚顛顜顝類顟顠顡顢顣顤顥顦顧顨顩顪顫顬顭顮顯顰顱顲顳顴页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟颠颡颢颣颤颥颦颧風颩颪颫颬颭颮颯颰颱颲颳颴颵颶颷颸颹颺颻颼颽颾颿飀飁飂飃飄飅飆飇飈飉飊飋飌飍风飏飐飑飒飓飔飕飖飗飘飙飚飛飜飝飞食飠飡飢飣飤飥飦飧飨飩飪飫飬飭飮飯飰飱飲飳飴飵飶飷飸飹飺飻飼飽飾飿餀餁餂餃餄餅餆餇餈餉養餋餌餍餎餏餐餑餒餓餔餕餖餗餘餙餚餛餜餝餞餟餠餡餢餣餤餥餦餧館餩餪餫餬餭餮餯餰餱餲餳餴餵餶餷餸餹餺餻餼餽餾餿饀饁饂饃饄饅饆饇饈饉饊饋饌饍饎饏饐饑饒饓饔饕饖饗饘饙饚饛饜饝饞饟饠饡饢饣饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕首馗馘香馚馛馜馝馞馟馠馡馢馣馤馥馦馧馨馩馪馫馬馭馮馯馰馱馲馳馴馵馶馷馸馹馺馻馼馽馾馿駀駁駂駃駄駅駆駇駈駉駊駋駌駍駎駏駐駑駒駓駔駕駖駗駘駙駚駛駜駝駞駟駠駡駢駣駤駥駦駧駨駩駪駫駬駭駮駯駰駱駲駳駴駵駶駷駸駹駺駻駼駽駾駿騀騁騂騃騄騅騆騇騈騉騊騋騌騍騎騏騐騑騒験騔騕騖騗騘騙騚騛騜騝騞騟騠騡騢騣騤騥騦騧騨騩騪騫騬騭騮騯騰騱騲騳騴騵騶騷騸騹騺騻騼騽騾騿驀驁驂驃驄驅驆驇驈驉驊驋驌驍驎驏驐驑驒驓驔驕驖驗驘驙驚驛驜驝驞驟驠驡驢驣驤驥驦驧驨驩驪驫马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧骨骩骪骫骬骭骮骯骰骱骲骳骴骵骶骷骸骹骺骻骼骽骾骿髀髁髂髃髄髅髆髇髈髉髊髋髌髍髎髏髐髑髒髓體髕髖髗高髙髚髛髜髝髞髟髠髡髢髣髤髥髦髧髨髩髪髫髬髭髮髯髰髱髲髳髴髵髶髷髸髹髺髻髼髽髾髿鬀鬁鬂鬃鬄鬅鬆鬇鬈鬉鬊鬋鬌鬍鬎鬏鬐鬑鬒鬓鬔鬕鬖鬗鬘鬙鬚鬛鬜鬝鬞鬟鬠鬡鬢鬣鬤鬥鬦鬧鬨鬩鬪鬫鬬鬭鬮鬯鬰鬱鬲鬳鬴鬵鬶鬷鬸鬹鬺鬻鬼鬽鬾鬿魀魁魂魃魄魅魆魇魈魉魊魋魌魍魎魏魐魑魒魓魔魕魖魗魘魙魚魛魜魝魞魟魠魡魢魣魤魥魦魧魨魩魪魫魬魭魮魯魰魱魲魳魴魵魶魷魸魹魺魻魼魽魾魿鮀鮁鮂鮃鮄鮅鮆鮇鮈鮉鮊鮋鮌鮍鮎鮏鮐鮑鮒鮓鮔鮕鮖鮗鮘鮙鮚鮛鮜鮝鮞鮟鮠鮡鮢鮣鮤鮥鮦鮧鮨鮩鮪鮫鮬鮭鮮鮯鮰鮱鮲鮳鮴鮵鮶鮷鮸鮹鮺鮻鮼鮽鮾鮿鯀鯁鯂鯃鯄鯅鯆鯇鯈鯉鯊鯋鯌鯍鯎鯏鯐鯑鯒鯓鯔鯕鯖鯗鯘鯙鯚鯛鯜鯝鯞鯟鯠鯡鯢鯣鯤鯥鯦鯧鯨鯩鯪鯫鯬鯭鯮鯯鯰鯱鯲鯳鯴鯵鯶鯷鯸鯹鯺鯻鯼鯽鯾鯿鰀鰁鰂鰃鰄鰅鰆鰇鰈鰉鰊鰋鰌鰍鰎鰏鰐鰑鰒鰓鰔鰕鰖鰗鰘鰙鰚鰛鰜鰝鰞鰟鰠鰡鰢鰣鰤鰥鰦鰧鰨鰩鰪鰫鰬鰭鰮鰯鰰鰱鰲鰳鰴鰵鰶鰷鰸鰹鰺鰻鰼鰽鰾鰿鱀鱁鱂鱃鱄鱅鱆鱇鱈鱉鱊鱋鱌鱍鱎鱏鱐鱑鱒鱓鱔鱕鱖鱗鱘鱙鱚鱛鱜鱝鱞鱟鱠鱡鱢鱣鱤鱥鱦鱧鱨鱩鱪鱫鱬鱭鱮鱯鱰鱱鱲鱳鱴鱵鱶鱷鱸鱹鱺鱻鱼鱽鱾鱿鲀鲁鲂鲃鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳚鳛鳜鳝鳞鳟鳠鳡鳢鳣鳤鳥鳦鳧鳨鳩鳪鳫鳬鳭鳮鳯鳰鳱鳲鳳鳴鳵鳶鳷鳸鳹鳺鳻鳼鳽鳾鳿鴀鴁鴂鴃鴄鴅鴆鴇鴈鴉鴊鴋鴌鴍鴎鴏鴐鴑鴒鴓鴔鴕鴖鴗鴘鴙鴚鴛鴜鴝鴞鴟鴠鴡鴢鴣鴤鴥鴦鴧鴨鴩鴪鴫鴬鴭鴮鴯鴰鴱鴲鴳鴴鴵鴶鴷鴸鴹鴺鴻鴼鴽鴾鴿鵀鵁鵂鵃鵄鵅鵆鵇鵈鵉鵊鵋鵌鵍鵎鵏鵐鵑鵒鵓鵔鵕鵖鵗鵘鵙鵚鵛鵜鵝鵞鵟鵠鵡鵢鵣鵤鵥鵦鵧鵨鵩鵪鵫鵬鵭鵮鵯鵰鵱鵲鵳鵴鵵鵶鵷鵸鵹鵺鵻鵼鵽鵾鵿鶀鶁鶂鶃鶄鶅鶆鶇鶈鶉鶊鶋鶌鶍鶎鶏鶐鶑鶒鶓鶔鶕鶖鶗鶘鶙鶚鶛鶜鶝鶞鶟鶠鶡鶢鶣鶤鶥鶦鶧鶨鶩鶪鶫鶬鶭鶮鶯鶰鶱鶲鶳鶴鶵鶶鶷鶸鶹鶺鶻鶼鶽鶾鶿鷀鷁鷂鷃鷄鷅鷆鷇鷈鷉鷊鷋鷌鷍鷎鷏鷐鷑鷒鷓鷔鷕鷖鷗鷘鷙鷚鷛鷜鷝鷞鷟鷠鷡鷢鷣鷤鷥鷦鷧鷨鷩鷪鷫鷬鷭鷮鷯鷰鷱鷲鷳鷴鷵鷶鷷鷸鷹鷺鷻鷼鷽鷾鷿鸀鸁鸂鸃鸄鸅鸆鸇鸈鸉鸊鸋鸌鸍鸎鸏鸐鸑鸒鸓鸔鸕鸖鸗鸘鸙鸚鸛鸜鸝鸞鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹙鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹮鹯鹰鹱鹲鹳鹴鹵鹶鹷鹸鹹鹺鹻鹼鹽鹾鹿麀麁麂麃麄麅麆麇麈麉麊麋麌麍麎麏麐麑麒麓麔麕麖麗麘麙麚麛麜麝麞麟麠麡麢麣麤麥麦麧麨麩麪麫麬麭麮麯麰麱麲麳麴麵麶麷麸麹麺麻麼麽麾麿黀黁黂黃黄黅黆黇黈黉黊黋黌黍黎黏黐黑黒黓黔黕黖黗默黙黚黛黜黝點黟黠黡黢黣黤黥黦黧黨黩黪黫黬黭黮黯黰黱黲黳黴黵黶黷黸黹黺黻黼黽黾黿鼀鼁鼂鼃鼄鼅鼆鼇鼈鼉鼊鼋鼌鼍鼎鼏鼐鼑鼒鼓鼔鼕鼖鼗鼘鼙鼚鼛鼜鼝鼞鼟鼠鼡鼢鼣鼤鼥鼦鼧鼨鼩鼪鼫鼬鼭鼮鼯鼰鼱鼲鼳鼴鼵鼶鼷鼸鼹鼺鼻鼼鼽鼾鼿齀齁齂齃齄齅齆齇齈齉齊齋齌齍齎齏齐齑齒齓齔齕齖齗齘齙齚齛齜齝齞齟齠齡齢齣齤齥齦齧齨齩齪齫齬齭齮齯齰齱齲齳齴齵齶齷齸齹齺齻齼齽齾齿龀龁龂龃龄龅龆龇龈龉龊龋龌龍龎龏龐龑龒龓龔龕龖龗龘龙龚龛龜龝龞龟龠龡龢龣龤龥龦龧龨龩龪龫龬龭龮龯龰龱龲龳龴龵龶龷龸龹龺龻龼龽龾龿鿀鿁鿂鿃鿄鿅鿆鿇鿈鿉鿊鿋鿌鿍鿎鿏鿐鿑鿒鿓鿔鿕鿖鿗鿘鿙鿚鿛鿜鿝鿞鿟鿠鿡鿢鿣鿤鿥鿦鿧鿨鿩鿪鿫鿬鿭鿮鿯", HC: "a51a3260829694d329130d166e9d7f851bfc33740f91a624f07a557328a89649346032345c84cc797b5f2d2f0ecfad54c5b1ec9c292c27c4f908bf4426a44e839a4ead8d30db9b09b3a4a7e294b14b95addfcafae6ed652e95a0d991c3c4ddfdc9112091e71d33fb15f1c5a50b2ffd54ba545b60ee104254b059d7c7fa4902908ba2382bc475eb1d3a0faf616df7e3871eac2cf014573de4c2a3c52c31f6a9902479989e66242d6f82af0f98ea319e0255bdbd8ea946620c97af769455d36d732e5fa1bae3957fe256f740ff473e198cd7a52e4e484f32e5b9b119059bbf669597749ba03a640b147ca738550c39b907b05d9a8d69688864583e7da9f67c227798747b28fecff04d237a3e0f72749c996b6b58d42b3227ce5ee53fadbdba51faaf539b0e631412b978bdafdea8fe548eab91cf19a472c64bec04004db62cd8dd2bf6a6482e2d0f83c414b18a2e43f40874717e48bef25b076e5c1d3d13554883efb7d99b852170e1f6651e971de5f6b2d242482ed2e3e5f91f085cde28c0add7589d53446dac41432af50f1a38698a14dd8c3ef735dbba8d85b5d1cbe0771e47fa68f11263c387aea5f67a961f2b11f663e36a5a000cc21d5fbc9f578b782c36fbbb77714b71f37238242e3897005971e3c9680e44403acf9e541653dd86418dd34407f392a10198abe057d160f33f1c696381fac33f5d5a1ae4532f3081a1fafc2882617bc18ebaf644337062e476302b494da7507bc7ae9b0d4ef10daa7e080c1f8605611bf267d84364cadb95eb3826bd48f2f13fd12dc321254cd21722d3727579755bfec6f883c0b0faa7539e146c83ed78cca5c9405e2f416a12cc1c2770405f81ee1be36a2c536d72608fd18598a4eb2bc651c9022fb42eb6be9778547cfbc8e9dd120f86367e70562cf4041fc0a7af672c4f0a607a16b9d719684acb2463111498a7dc836e0db41b503e545b38ec2f0f9c04c1d1c38c4ffc56a96fba71e0a6576711120850c306a48d685d4efe6c4633fd80d33f7a842a16fdef3cdfec0935a3fac0cb96323fcbac8561a92b2c370f57fa7523c24f67b597f7a56b9456dd9bd744fb9c5e6dffbe3ba203e5bdec96973fde645bf851145eec7487a50e802f1e7f808eaaae45f44a2aa2afc83f695532075bb89d0d961aa275b12f6e423a1083b005a766310cd3362c2b19901884b02d8568c0ced6398256d2c392ea392ab3004819031332744dd962d869d67c2c72555783cede882d7e0386f8740521f107bd9fe9e0501eaf6171ef3cb305d46b0edc338b5c51c6ff4bcb41693c189e6d3f2505b79acaece11a6b4e48517617d1c0607cd00210fcb904760ba2579df53c2269c7bdf06918092d80368a7bf036e7ff4d7d8fe8363e36b5a87440501cee07390bceed062ed182cdcfa2af6bc4c209541bfc1614d531e8a904face85abee5a038fa9ff2731a3d52e899383d4f2eef8dd1265a16fd2e264f132a3abad42f789fe4e46857ed57c865771611b059e3309e9ac73c8032377fa69f44849c701cdefbff5967a04e1f2faa123fd7163600925c276b2ff7a7995078cf119b20ac6946395b33410f0175b73305d376c29ca0bfb00996b4437790fa759c144c1e0030c668a8a87cd92002351b9ccf8f6f9e0ab3650d842e53065998bdc3abb617d5d4634dd456af6331f4c51e611338164a9965a3e91e282b8d1d8288ed5f488cc8144423238849d5672c667988587ee317acb81c88072a65713d85a18bfddfeb847e7b5c5abb32a4a9a86e0d7311b370043c398ba442ea0593095e6056750816d05a12b3e799178f3a170f41730e9d135d21ae31a05207670c31cc8ecc27d4785998af52ab0c66e34bcb54a4b164db5a07486b1574e57c690e0eb4659d3b54ac3baca6b93320f3cffb83d942f6c9de473db9571b6daba26bb43b8717ded525c7dea5819db2194f118c8040e8c7da5f8a1d10b15f4ddfc4389a26f06d632409f035231f59136808c24cbec47bedce9c090bb646e913848a8c77815b0c8ef2543eaf582ea4d7d2b72b19893a5be6585c79479b8b26fc08d8393eb2eadeb53bcbe1ac56c52809ed2e3bc1f0308198a267a8d22c5b10e659612477610522f2ccd7c295ad642382d2d8628286acb9e7a91d644d299c41cceb3ec1398f4b2d2c2202f308d70f758cc204c4345dfaf7e15190e71b08218d0e98d5880d52c80ddd3df4e93cd37d6f40c4410679aec310a5667cfb7d0dcbdd4660246e14522f928bca20fcf2086ebe0225852fe70cebeae9e0f8f7c9c4fb8bf53c6f5e8d5366ee896b2be4415e3687f7b9f92b8255c6d977e908b41b72f8a364162e912dc37770e6a1db0c25ec7fd919825566b5b0246b38426a8161255e695ee363a1ad7c5749b6b12dcf6d34b4f17b8b4728aab091de6ac3f95a017515bbf899708cd5987ab3e8bf2a1e06ece28bbc119648133ccc32073643cdf6df8267c31200855a3467a8c9984b9a1fac0a46cf652124cfc648ea3dfd9b81ca142a3c8821cb75e3af1a7d2ce12355842930a3ea9f860f0941181fc74328e6a3e808435cd623aa043e5e5bdcacfdaa46755807251cbc8881567bc81df261632f15ce120f833c57797bf85b8423515f35767b9a935d5d5f0c5bb15a90dcaa79101ff093e20714befa0e00faec4e076e3c748f26df1e12eb241c469d4915b28f660671e77fb403a174439126757a85b1f3d368ed36e5d7d95a3c6d478181077d6ead49ebd008b34d68e56be15c53dc17c725927561bbf37b097d51de7f73a5681bab9f24f6777a30a88bc1bd482264fff2ec102d90bb7aec14674a26cf49555db18ad775186b11769ceede2a0b7b2c10a60ab6de03582d238899d86c8d146ecbe6c00d4e9e23f1cdda9dea8868024ad6d97b8adce8c4784a3202042fcce5a9ad86689bab33701fd154965e5a9b4b012a83b30d49f99b08064888e0f733bb5125440c7ef755b45a53280cc5af38e00cef87bcd776b0cf72b09d64a8619bf35881f6d077fc5a0517767107a2187a249fcc954a32f864d2ee15ca04350b5360ac754130acc4ce19fa52ee487f1fe43a8739010293e8fb95fdd0f1c0d560d0ff171453744c0b3f5026f61bab146daaccc794f22fdf373b74ef691ee6a05169e731cd325d8b0ae5eef78e8639e22dfad9c9a29889af0ba1f624e20280365de0468afcb53cfc4faaaa98766cecbe2ccd53364db07e3b148a256964e05a00526ae4cb28d1c220d22d2d149e587691fcdb5ac42933d1b3ddc4611a041b14696788427bbd2c17beafff12ba4d6a9cf62bd2212d33b9693cfd761a3b88dc1ab74ea3b27ea470fd5a02cb4307e5fda1057f38ad4e6b39bb9f65d2d6ef0fdece95e1378b23c0ec7ee690478a23c5f557807133791b72bd561b4d36038e12097955349bae7d34d8ff17fe5c9dc2a1961fe330922d45352ec2f73c0b04b7a050defd6778916a4bd3172494dda43a69539eb8028a78788cfc83b5900de4a011625f74924081fdc4635316c67d7fb07a7ac43e6b1d3be94fad5780fb886d322069176b365cd059c5f002e28f6bd85dd3a85acabdb9b2c627ba58ecaa2b0be65e129130f4235c95482d3bb81b41a9edf71ac281c6e15325656c2a3cb90ffc76db8a16895bdf3e905363c87c8f99dfd8706b7e9b60906741ce15054ccca97a730a7e63206482369fd87a125c585fba42652648be68c23bf36aa6b8982b282674740b5398f6220af54804062563afcc5cb1e9e1adfd88ee81ca9429c658dcd956c30fdd6b7de2f6d66c0d6803714c1e2c5a9afe4a9ada901e9a53c9a716358af544c68469b79329d03105d11971a72871d6e2b724360e3a97e62cb71816a2aeec30aa4442b083ac7d22faaf605c4a3479b9fb93c0577e65e3a1a942072248e8d657a54da79eb044108d29eef2c0ad65ae800c48a3a561c7777f0e592c551a7cf149ea8c5d4345f890b35e33384ba2ab6d986a2e3a25ea054cc889182ddbaca36faa55c83e099cdebc843b4c1343ea488471289502c648dd3e01bf0f517b9f130d2adda00633fec4f89111226d0902753fd77f91a6785f93ad2f6381716c66514d70c6ab3f4f297a6f653759b53f8f29d232ebd299214f51046fad8234aece0242b64437f9f5d9edc44b955f89498c010f6bd1d18a2ac9402da07edd37d0beca2f7656a0ee1cf3a9fd3c66bd07d8088295dc9dde9d345b0e9ed281777bd45bee66adbc075149a8a77240fa0952ee1a7d525c4bc457ac3b05a7351a1b0e17e10e4f0277f7ab16b0e4f64b261120128ec7ee0346319d3964c5c7b9545d2b5e2fd47d3ff653c4af5b43d5bc2bbc6643c55caa319af83c41b8024a936efb8bc0142cabcd818c4b5786473b6629ba64a93bfff89efbd59a5aa926c47b8549124ce2b67671261f1d037e1d09318b2ffecf8871130c0146b7524f04cd45df2f5b9dd5fd7572187ec0b2028b76ed7363d8d20f4de4828b143a03720d6de439f9e78e2d911ec623a9b7eb2f3fdf83f8c1444b87f117334326998149555ac7a2d9d4c6352a2b9261522a5da5103def890c4a296efef98a20ef6cc1ef7ab0256153feba66974e1c80f67247e30ee6fef30147942fb278660314e17b39a35f9e1233bdeba62b8badb7f789f404aff4815a9c39ef722defb8c4269dc50e73faea37f9e0ea8de038c5ce674481bfec35d3888b9d26cef86ca036ff42c8a78a51b04c1be127888641cb2789a6ae2a973cb0dae5c10469820498451ec6681822f2a87dfd08a9192e4bd978f308c9564fba9eaff18741dd76765504e927029fd156a6c38b75e776718cba51f772bf8fdf4757dda5c5670fdd384a8a0a467c20e8176c188b13efe16129b2a76864d2883a71fd2493737df4af20df293b5f7984e9309ad1e5f54b917abf65ef499ed57c71fc6bbb4edf004623ee39fb86e975ef771270895fb8472c90740e1722bc4c80a745172835dc894b068e2e2a3d0720791f6d15828ad16e0bcba5bc0a97ca246207b92c86feeb03b367d2512df7e90d10ddf92ded420607ba2ce108d318c6daa87f03724502fdaeaac2a371a7c87f5d04c8ec326ce19ed686552a6488613cd015b05b9851d099db2a14d08b2ee0b75a412acd8fe741d2d7a5baf4343cb34571eb55ede2de5443b984de3a76576c5a38b0d9c317ecad4f8cc34ae1bb227ce68de8b02d5f6daf2f16b502d77807920096253dea2d84a4ce4a68a751245335b191223a709ed1a420aacce41fc7fff9b07285c04951f3fbc87a7062f767f02ca7abbb9ecfb0b6decfa0bf1a490cf0c8eb23b301480dc791ab87994aa89c96d5f8add177360fc8946b7510ca274a16a0a34206f62b8f9cd1dfed7425baa81f3dab6372a943057660321691eab76fb5325875d7eb7aabbf46027185609acab37f87e1b666993223ad9f3a9821637c870f1cc04b150ab300f31b06d91c5a8b641b48fa5e256adac441b36355950972af071e8f2d775c8b271a1c8ea93a539c8b8323d61c8ab8e1a8a6e2fe510e95b2487ea8e74566aa192d020826871a1eef09c3478c9ddbc1130bfc96545fba2d0769b4b2d3d0a6238cc01ba4a89bee6e82e0208990c4ad01929c77a553f0680680f596faee63229c78da21870874ee5a0e3673f37084bb937c838ee9c0f6e3cf350f1ef804eab8a3ea3016a3515ed119f8d2ce6d5e0b141669e98f0644582a56e4d4d77767040d4f38b7d52812f27e9a56ae7cba199f4bfbaf9f04bad85f789a7100e762fc0c42c5deb12829189249c750c3d46a425163da5ea6c68afb41aeb11b05741bc5d321cead9cd93d1fa4d5c3928868c9f5b855eed4c0bb4523571c062d99e02c3d096ec0e17e28fff04467b3af0b03c9138c6b1bc328fd0e7f20b794c38e92132f3069360e5c247391a0e1b232c918bb176dfc3e7c5e8bbc4c371b773f43dd797bc6f6edeb0a8555be1f17227cd28c313e93fc209649e7fc5207881a1c92f9b86e9f9c31d38c5e61af4a01d663dd03923b0b8281be5c5aa1270d1cf6beb9a1097007af1235ef6f36ed318599c0834f34658e5f3c1a7d671aee8dd16b94ebe1e10a661c921d524aac0c6b4e5e5d23fae91cae9bdc2cbae43a6359228b1c3b8ff8d8db8bb8b7ba28ffd378e90bbbbaf8406a20e20c4fb4716badb7d8829193c4aa15987d49ab02f00d8353edefb5d8276a76128f0733231dc9be173190d432934f9c4a347e38cd2b51d8b4212d7f99adf3a3c5b4b566dd3591784a65164445fc98e876a6c80de3bd1e9869ba848772890792b1eb2a14ae06111f9708309c1ce7574c43af179b0f33c60b39265428acc607d4b077a468aafa89fc23bb97bf6063c4a56159df40b56ecbd375f86dff68d2f39d0c98cde7aedb6fd8ed5e7b57100a7d1247ccc0bde47edbfe08fa36373455de295c86341f0fd2054239114beac5f35cceba9e3d5d8358964e55847693ab41756f3f24abe7a1bbe59f63ddd91d9ea483fb4f4828e0c0ade2c53069604862bd2c009eb92c6f8c889606abfc48e53ff5fc5c785321320ae46f3140f2969966351c7d08ce2ba9ebd00bfd791b71d405852b0de101379014e99b2068fd12c20e4be598e88f30053d5bc1d970f05d8ffc2aef9fe1eea1643405b5c0734eae1ef1b3eb6c7cc8d8789a99f14444d123bca6c9f85873f7a3505606db8c71e5ecb4467d3104da56ed366e63f433102d7b4ebbb5d8f591cd2a8287304c83aa383eefebe9834732165b6422334c97885368d895f1cd8f3319294d8dd8bc3b7eeaea0315097ac58e71d82698afb9d9050dfa268698d9ecc94861deed3bcb4a715491fc2644e0ad8ace27e8970e3841f7d337645a982f5ccc9b9f3efee2b3568326da82ed33b3b888f8bf4a6adb685949383b83a93d4ec8899424446bb87a1849e1dbc443abded5983d81cc33ccc98605fce2d92f14e826539f7ad4ef5689d777e150aa2d4a406515f2b7c5d9cec8103148ac6278f0593325b1852609c837e77ae5ed1f59e2342d3fe5c048dd8e178488a87023c35e50aef8faab5415fca42139cb93ef59414910b5a95b53a3dc2e0ef5cae2248d8ba1a9b1a0245356cb34ab87e5556a01a70b159ddd3140993729e59a86cc05519411987bcb0d62854bb4fce3cf35fb068c32dc415be163e0db7121fe5bf103a098ac9e8819a3f9b2a873475c9634c6fe64ebd13e185c78598ba1db67b9e3119607e7bac3067157662ab782bc481bae418ef3fbefa777241c923cbbf24f8daa89e6cec5c58c6425d1e00e46b593ba15d3c7ab8aac25f283153dbc9a23995fdb2d2b176e4789422ce2d8bd191d068e279ee53710065f1c556800376f5ba82dfc232af9a2a0daa2430da4352a387219641b956db6545b665eccb8ab5662f7aafbc004b80aa3ce129a104b35456c073f23c78bc2189d02aae7fb1a3f8e183677cbfcdeee9e1b07ea8c7a80fd0c012dcf785414c2aff0a4566fd5cf2067272debe96bb993ee83dd0427b173eb050d6fd28933e2d677cf8b2b476bf0f60139ec709ddb81d99a1d035536e0f1132a2f06580fc6f8686c7807879c150df437d6a2a5a2e1013a4b13d3c8e070b963e75e5fd42c6129b99c749e65b45e905379cd0a5df1a76b8c6c6073eb724b619d94c49e28e9d095407b8c5c75c5651f58d2a237ff0654e4c8147e0903f9a65bd4e8e280b733ad191c00346a3e78b8d6fbb10185b1eaeb730bee010f71e9f5002b10f784c510b32f5bde2ae3251bb084f2f76ed0dcaca8885fe4643efc4e6b45fe32242f4c7ef1b0c3cee44e1a58a80a6241e11f5aa4984baf37d5109464cc66a62bd692012ecb2a3a7c6d127abec8402fc158a01ce6a26cbda09f25acc174a88db26361a6bdb963e2543438057145c4aaa30eac115eacc0d797c08b1f9d44eaac9b9e296abb8060a60c6486d981bbd1a577976d01f164c9427789fd778dc59f92a69e4d8d86ebb506180e4b027fbb13935d7d41d454ad32602a2a3e15f28a36e85112c6d13f9a5af66a4b5ecd18d17ca2f87ff22366acaf5e32551a2158107a310344d3577cea6ef75570fe30d3ba89c011313b9104dd116938f26b76c05c95ac44b4c95edff30661856a765918da10cdd210d27453e79d4d75579f64ce6e360e3ea237ed06409d60934a1daf032451a87b23916285f812f5536f9fba3b6422d159611b4aee049b6c9bcb6f8b6592170cfe9f14909fd49dd6abbc3d0fcfea7fb2460d2f895d6e787f06efa3a6a676d2feb7603ed2272051b9ff7e635664f77d9ba865cc004ea4f6211e39d10c75f5e7867d24566d17a32c60c6bc8da3c2a95c2ef24ea8a5412535d1c13ed373700d53b54de12025113c8c0d5bedba17583ee9cb45ae62b28ec3fa6013d34c09f834aaaf25df8920156221a2e998176120f54d2b1bd36c11c2bdf29549e4c888e69f70845eecbdca48e406ac9d666bae6c41b550aed86571d70656dc600009e474080102516d00d2b736d809c0a2c94c5da6c27a20b2f464a1b911d727d6d8f8d0559e7cdd749f4b96e04b14a61c5d5cf9f2e0c1a27e58b4d8af727a782fe705db7feed8c3be55c9360ae9d6f9d45a379feae87d08572a8d5482fc743f062f891f838b11a49fce88f060d0f9114a999a6777598a59ba73ef90af179c7907a1f1a07630ab3394165f7242b3f98f388eccc10ee0997d1b5970c2125217b214ab73534a7a5ee668e484016584f283b2e4f161ef8178bb0a9b233496ca2f88e36e4e907044364ec770a696bd0b0aeea7d68c104550251e6dcdf82d53516d7163e3d75f9a32fce9883398116304ea27a621d09a002ada1e298d03756be10280c4f4c972df5f4d7dd3a3b0bb16957e41ecd5d4690489d638380bd319a045d9a210ea29f0156006d742ffafabbb26eb2a3338aa1202c7c5d03c9ce9a2f2d9e817f80e82933533ae63e694a610938d07727833a42a074d6ac84fd7be2ffba83cda3f6828af4b3737410130e82f06704427d2cd54c74620e2f032f1ea31a60e7fec7f859e355c5ba3a527205172a21a4a283edb2d09521ca51903312e4db5b5b1475929471baefd468678eb89029bc26980caaa3d09026486d2beab9ed6ead4ec5ec8b5b4b4d95787bdb6b47eeb68a6b0fbb87ffab3fb946d5ee24dd2455a2ac10437ca4e58651769da1b2f60fe215d4d27925d7827910d571cd2c1cef6d158e94e0a4e37a9b853b3ecc0f99302949c699585a0a29ce0e7216ffaa0e7ac23bd4e0dae478bd576838ee1e0027c5906b2068b1e9623d393927212bcb10479ca784708cec0917a4cb6bb9210774641bbe59796be588be1ba5e7ae27d5cfdf1e45c6b57a4c13d30bd8177a71e99afe2ddc0ffce8934d363339b8be743fddae290a86a8a414a6f84b263bb0cabd0fe1d36c09a57a4ea48d7f6a6cb9c1fe452e8e909fba14562c8ddd939900b88a1dad255fdd4fa90ed13307f7573c671801153a6394114e0fdd3e86a3e58fe69c0f81676c97ca0f8ac7ba8d2cd071e88f9e9581c09ca01f52e960e36cd498ac49b9113cf731680cfcf1f4f715712004fe0a4900e2e6ffc5e4a2894b28b5021fbc479f567e32204b4a7a72b6f482821fcc3743573de204fa868cf7b743652471dcd7ea8d2158e0ced98e89a88e2328ed7911707656961d843967d42f4535082edaea00e2874bf6646eaf9e07462e46085ec9bcd961fc6c24079bd232c65c0cb6bf48fdebfb2e8ca3ba480c7dbce0535da07b71b1c66b6b8175e4a09ae69a66f6e7b9ed4e9a5c22f58a0c6db8734ca2b2322bb296996b0cecda24b5827e9bceed0a58297a654ad3f96453770c9ae500b307ae33a698ec382b7175e01cca396ab3a8f9b7fe461a5810ca0da98a9ec58ceaa7c227f36520e62994c5518c842176b7f2b342e390e36728758cb48f49d649035c926d23ea1fcb470de0bdace5fc165bfe956092498c179fc15de823b290c0c6e46b62ecb8fcd47a660ecc2139dd6fbf0d26715ac09518e3bc8f66dedb1080bb38dd38aaedfe40fa43117486058fd81cc74624169850e2e8980d8b4a2e53ce1a7ce07640dcfd0b4195303e664ee092dce7306d7933987962ab985eb9ae6ea63336a241c19c02df7b56672d831f674428b90462a20534c93fa3100f7f6e3f97aa358c8f1d2704a15f5539b7b9c06f7e50ddbcdfeb10136d40b197a65f77da742fd0b4da5d0fdf1ab6928514aca89bba3eacba5027cbabe223a470d49674ff749692160bf4d0bbdc401dbcdf9a5b700d10ecfdc4d844fb02979583ba4e601e22601146f13062e95080037b90a7e870cdb773f9264059732787a6eacffa16a6640608a52fdb33e8d45a3e8120107b202348919ccbff1a0689f1dc4801500f4139a709280c3d8eaab3e3b9345d0ed98f3bdc25dd8bb5c8c74cb88db92fc403bd4b7fe5c476afc353d537371171a4a42949a6b288223f04bc9ad902994f10933f07419b1ac3c5c806c6bcb10864c7e2dc35bcec544fb907f45320245bf9be9c5326c74bc3ab84774976b5e3e114936b0332394d00300389407bf1a13ebf4cbea2711ec5f78e5a70a201c0abac35cd244c6a0dde5bdab6532b61d3523c5d9faaee9514fdfffc5c9a085bc0f58b388ab4f3e7124be158b70b6cc9b7fbc72a8edd661f39aaf2d0765e1b77c3340bb790f013a84c727974d2d04fc6d03c47c3811727c4289955e048fbd33a1e394545bf33408f40a8ca8d3e122c2928701402ade85df649a87d8b338eb20686eebfe2da4d28ae7c53fecfe641f1583e044dd027a38c9f974d50a19d20f34a90abee38f49b62a731e241fe17e020ff48f228579777efca859dcac9f00de4fb70b22517626f9df6a8bc628bd6895141434af1f4064ef26709487ee5cb6920d58dc1884b5cac3a4469d7462b20da57176185046f50cde446340aa2528d55e116e6dd80c2a05398890cc43885cc3e0938137b0e4cf1f577b3e0551f9320fddbdba137b72e2e8b5c6dcc67cf5f8453ada17cb222d8c7c95dd88210de5a95061a84a1bdedbdf2d69b9900398b944328a58eb1d313869ea7d901f68023544e160e1c782f2a6e12fb4c8f9125b46ce3c216cbf485870b4b7641e557cb37f2d8c71be832be52455f2b2f123620bf8771fffc39fce5edb7cba270eb7799e2e431b78606fc326b979f837833dcb074ea000df99efc2db721b3c7c9f9bdd257944b7c64d43b362b81a20214e7b4a88aef9ed513845f001a789d3bef0097c49ff40f5ddd4f2944af7f4ad22d1fb45966df115fc6c66fdbd5a6b9ab0526f2385d4ec91cb49488d96c9d2ffc50519b240cfbab19a22ff5ff00497c3986ae132733b72427ebcb2af6c01af590155dc1f2aa094b4872add1c98a6d30592bc6abba45af0eac8cc3a34813d6e318aebed528f42cdd8d532a14a6d3f1aefd613434e21f0e6417a2a8756cc7fcba3b30b87b625f3d0d4a0952483081b5cc90b946f63c8aad3fb957decaabe3c19e0c8470661ca7188eac32af7803ee1c7ced912bd3d670a950e7eddfe8f3d31f5dc45958da96228bca1805f33a603803e44d1d325fef5bbc4fe4d3ccf18ac541aa8ab567b0663f229fb5b9ee61e23b6ccec7b35811a3c9b15a7fff56842031ef8b4eaf79edced336052d8a27a30db20a40e5f2ed443a086c8d9a7a2bb945365cc198ca51708cd7b3f2d7323f82e2633bfc1e69927dfeeeffa806f596d116b5113f1414bed1735cb01fd4c8e7472b5443629f5185eefed8a1526dd9ac8cb01ec01008ceb297503f92f6313860ed058f06ded384bce74fc6c82edbcb057de51a7ff8f4b0f0e0c09cb00a3cfa31c11ab85569a6a5b1ac3b9462b9a7ad4be0d88c2acc7970a55e5cd506087022c98b15cdd9fd41a0e2cbb093e2a7b344228521aaac44da809402ea496d9bf710c2ad1f6463cd6300fb5666ba91dd2d5767cfb3e233150c7bbd8c3575229591eda8eeb6c6c7618be960cee972f27ae12c516ced7328f653d116e86c0731ddf56fc14ba58ebb9bb9171b4754b7aed56898284a01c3d356c26ec7a675804e7b1d1041a5bb8bf35ad4b2cd6f3d321d0f6dd5b174864dc332349e9119741a78a73303a1b0ed9f27ec2c14676cdb0ba83841ff85ef1fa4abafb132b6ae2f179b18411ff9faa162b5397e71d3bed651d85bd5dc1a6404a5dc5797fac69c83660a11d9f1faa433becaa55cd0f752bbc8eda8ac4de355f8cbf4ba76bde35c740ce4c58a4f4acde6a529c8eefda16116def843618d9b574aec4866bfed46ac01f6e25c38515aa311f4be23d16292418b7a822204b6470b998af81ad6489e9bf239e0c2a5f6602c50058ced0096ee38149f1d402b0a6d7e662f1553d8eb87e6baeea4f378528cdf8c942f3507a89b0935632a2bf86002a0dae2fe288b311ff50af8dae110fa42311def76a46c854e4da0c8d4ecadf61e17e82576f5f8f40d9fafcc2c0b8b6baef91346629606c6053bf75d86c1cb27c45676965a7070e120686543393aaa1a7e3aadcc33209de6018723cb2b44fe58646d39d6268ac97bdd17417c6e75858c72c81ebb27854066bf9003c50045aba77be8e1df8703e2ddc6a55da13929fa17f40f3cca37250cbbe9ac1008e9b88cbba273929190ef252a3185e57b4159cbbd2de1c9f5420949abd7c5e95226dff8700d6af556675e20211022e38566bc8d2335b9b9e0be20d8dfc9fc7db3e02574d827e54032a88d2990ed83af796ff5fe2bc8b9d080c4361e6587e2d67aed4431e3fca43d21acc1e9ef7a8657df425a327c2ee38434685dfea7e8a6d8d811fefe816ea33828a4b968d555a7b34db5e9cd485ec528dbd5745d6ee6690fa76a9362b7f5d504f813a383e64ce77ca7cd4a7e0abf54e4c098d607255c8219c7218b9bfc9cc9fa1e311dd23c5cfc5163edb27e10268299ec282c80cee1287bcfa66466025848468a32b900de6c97582bd7940706f7b2faa3e31146612fc1fd2af0f4d113ea6d0753153cc0e4a7456c39c73cc08fd1b3ccd3157788b45564733e05f1610d94c98636a608db9289ed4bf664866e3b28170f2631e2a5efdc15e5d25758ccc6559fdadcc16f08810ce1a5d57f8dff2319483c09a380079f61b1537ac1dd472ee7e4a9aec132e6e795498b3863d50be03172d8e607b880bce3b28510bb232c8182b64fff5c91661b1bb844f9617474c6067f4f74b10805dd81fec2e9d3df13b63aed3d629d620f6ab51c266d3e7691271d1143f2b420765c152bd2bf0fcf48feca0f729fec1840d9b30b9e0f993ebba78c03c5bf802d2defa88ca17b2e5f5ce8ed486192679becd5103b22d5d07ac8a6faeaa288b7e7e22a9dde02f69ab7df468fdab5122054a47e4710947d1f1c0e0f84d3b591861c0ec47563b5e3c55ed5297e519999e39830e254c3c7ecce2a79ac4e029e5503e85d1b188c3ebd5aa2367188ebb534a7e0dc0e402a0409a40c47108d27de21c62242937e7ee6340e949557a46a83b0b6981417e1a2e9a6816df8d9912f321df99b1eb6e95cebdf6bfecac4f55ecc59f41cb024f1fe62f8eb59e10e2af68e48ee65e3da3e1b405b91bd1e9d6bab2b7a150fb74a73bd813f406888558cf41ee7a6f8b003c470d8d8eba97888bccb23ac603c7f0017beb2162cd72c2c3ee969440f2ff4ef98e1aed7470dae53b603042c5fbbd4ce31097a9ec4d4ba213e3ade1a56dadf77d60540eca93ef8d1ff42f8814c4c8e5f11c3099f0ac9c3e52b5afe509f817cd832a62dd8169173356ea29ed27b412e3aa9b3dfde49775c90264a85d6eb5af8b9b39df2ad3d9f72ba049f7af3ad55001bdfdf05156aeb9bb3bc4a983cf003ce102dcb411e635d5a4fdc85a00784c0abab221c720552c3335e6c251139a3233b24c369a5c4a7a2d25954665718afd52c40fee5bc05714d55a4a1d982c2c8a5a883dd707f22d73cf40288b123e93ace585417b8bd5c24a07990009340498e63ace45c42821b24cf4bc0d81056788e120c50af53cf1754a9480cb9e4315ca2cf4ec84dacb0ee497a633b6fda945a478311cafaff3404780d67f84c8b921a3b979ae639e6dd572e250c600ba25b465b3328e877b930c3108f9b66c99a961a996884503286fae01cca6154cbc1caeb211343d2ca26a453a8d1569d72b05bc4b558c9ad0a9895c5598c3a163fbaf432fce03d6b74669ecb2a71f82e7f78b98bd35a2b5b5f13a2942742174d219c2eacee7e0df7771b27e2c1bedb32ce601d45be6855cc8c24087ba75e1735f611f72733aced90eae915c76802b487ebe60f8102d0a3c15739b09bc9281851f63cfb594dd079684019f32ac32283be1d43c8602176ea54306228d6db7b6e4fcbf63af808005a32adbab700a8ad8454f303b87f7ec56d4bb02097a580f6a2783d154ef8e4f2d2e62f8c79f97fdd3d486ce14ec18b367e0b439e1a9fa5767fbd5ad40ca1f27fd724f376b224b08761bb2d2737ccd00c25c13c2d12889f30db96a23562af4180947feacd0b7b1c000be1d62778c605af096c39c052d83cf985f3e0d6dd2b123701684a38aa25e37f1f61ffe724a9108921929e73afb01f0f4f6d978750011e3e6235d74908330f5e9b214d3aa65f9c6cc8858f04ecf938cf14d15a2b1453e8f3253c8ff762eb336dad7bbc7a2c0fbc29501712146b678b42067c7acd57f23d0e137788ff514d3401d9c9cf32c2722f759c3164d6bd7a6f68cb14e49fc92e0dfe26af8b1c07ff1563697f9170780956e65bdec8dcbd1c7486e585eece654a23453a197a550e54e188820f2c1e8764f0ca6facd7d9c6feae7252958c212daa3b28fae07fb846456a6c06dc4e597790ca7b8936045bcaebef272c5d1eb322cb1ea3fd1e78d08c146319e45fe0069e960f4de0e0912be5f09b109588d7777df6db6a1c6474c9db3983062a8cc85921142060ed55d7890329e5752b17f79cf8ae021a03569626ba70cb171afdf48cc595773c602df3159ee2c552ceda43387132be255864bc4fb745d120ed75bfd5eebf3a421452c325742c812a15856f80d991b43f7537442df109cb81a62d56b20b03711a934f928db33cb7828866cf68fc98f757197fe637634523daab3adbe166b67355aa7162f15082400584275216b09c0f293bd54f0043d1c04d86149a0822e0287bccb4276109093bcd4df34e3c65c39e88a04d380e6159543a2e84951ae9cd5bc0601e2b261c0756f4d5e49025bbbfe64774206d9b29515f6b69d32f3e24e54d9432aebca9418367c18d00592da1cc7295d4a27060e78201e0719fedbbcb0b57a06d5fc205834ce681b74a3414efea4fbca592a9e87ed11b082de26619e4e33143481e39a4ff818b619be0632e4b1129c920e0e99a79771dda78f488650daf064e7017f3d5dc7ccf8185b62c49a13c02f4153eb9a4e38d9cbe476e991d80e51bc6a680d40dcdb6ed803f83bdb84225d4fae27b25792e16a160a4c0787532aa70bce5e961ae0a58bbb6b2ae80be2105acdd292a2168358088b84285fa282a9fbddbbd4b3427ea05bf5c856b0df5119fc694643d639b48c5f47c2e69cca99e4e2783065726b79ac14a2a2f86853e46872aaca9f77758456c1e8f4d5b7509b0a790d74765add3ae9aeecd42a5cf3c7945f7151f69e381f9748361e79ada7ff28a5d80d22c79d4ded48431d0c58474cd35b0067497e54960e797bfc72b3ebc22ecdb2539876c8cc70ed43f446a5b4a834941d19794fe75a73f2a51c5ae7528000d0fde2e3bbf205f5ca9258f032d6b7655e3d178dbdba92b4ed7a4480185bf8b9c5051af9f27b62f2e69ba4e3f32a5ad8c01a69193f83654da1552850ad31792cd6ffe8f785c7fda3612536e6c413c36d95f44e7ee272cb796293a9ecca654840d17f6afef7e807d969ac54767693d3debe1fb0c41dc7938c5918e84754ded9ea63f6e77eb5a1116bcb49dda731319d28733e1181b6b53e32107f65bf108d1b4e5ce218fd52807c3bee8f8786284660c79d071489629d8183370eeac05c0bf6fa5c694643d11d0b7f320c17114b37217aa638aea8eff6b0435c51bc10ef9f5f22bc0c7cbf4455ba4ec76370d20acc9d31ff8b64e472ea0d049b03e2750649e7106fcd6dc96274c1743ccb2f11b9e39dd95b03ce8bb3aacb8bc276d706e1d9b516a0b1a96875ca5425881d087dcb05e6a1bcabdfcb3ae35893ec567316dcd78b3d7710e9bb48e6871eb3f1dfa10300b11d1c5c33c44abcbacd5472d85aee5ec698a68abaa66052103d54c711d44de01a030433b761aa7d25a7e31dd95d8ccb5c1efade6b99e2b3e15f2ba08b2eded22a56d6e4dd98c81053d6831d7dc40c17ec7f99ba4a5a19a8f25f7296e163f99fb44f72e3c11b96591177f3c158d600d02e36d318ce4bf6d1f246dc7579c5c15891e9d7b92b0c4faa80846b1c785d4785a369e5dc8841924e17495ca90c5e79db644dcf3eecf0a56eec2479474fa28326d6927abf030e4b7ee2c4c226799adb44489334449a9eb77471b608b3937f92609e1cb781df33f7ac55255e6a31c83f53d457cc34df26090d82505ff181377beb13976152edfa3f0f8acc579121036c7aa2f04c06003660581edc27f3356c893fda4a0935ff585198b0115a3e6ab7a3761307eec3ed59ee8179983bbf1730934d1a131256c98fb5cc5f904184308e71bdcff4d39fdb88d11c1e90b8588f1648a8532e2630f1d2817653f5ff48cbfeb8d5d2ee1e55d273556fa3b4d993dd8b20e9fcf4650369834a36c749a6bbe607fda30a4a216b052c657997a35214709e643a09552d5d03586094e9dbe770ffa910a246b765b20c36abe28b03a98db9f66bf593747319aa822d83c99dd269c40b3dccc0d5a3afa54f9eb79766ef5576c81f555f54209ab02600a1d4f85cfaa319e37d91573cc66eef5e298701f75f6d728a64202fdc392035aa2e1c2e6cd72044bb37e3dfc27cdea55f7c3112a4efcc7d96a631f133a5b47276cff3b51d2388e439e5d5ba18af1804a7fd0a17821b6fe854b5d256d7408ec395d96d31e73a2fed470ec0ad79578253e7a6b322ae42ad5f28b0332f3c069bc0a482f630dcb245a9349b4b89c46983ffa7c988f1781b155f46ced04012d5d22bf85a5bc649da2c4a72f1bff9db632c7975e16a5c4582b1b507f22af74d3f572b171385ead9c870af49f1cb2742d42da42bb410771eacf0f21afab92bc9b77c16d599cbfee7ae28aa35839757027a1063c0cb4f765752ab97a130ff0ccb4501c12e6ae5279005e06dfdd141e2d30fdf1377e3380d2658a5f9fd97f560325b38b26ba38a585a8764f7865643416326854385065614d354ffd8b6b277a7dbd3e0a3eb463f741512e3d070caf4436776e715e38bf32ce692500b2155039671a5862847d5fdf312e6491664310ca3a811c8d523426270e87b883b5a09f92cbec0b6368a48ba6999f791132acb1a0f20cd353a6a8eea10e097af8b2363f639ffdd373a4125401408b52a7d9b8a5b9bbb3cabd4e7fe219cc95300f2e636e65e3548b9b2df3af65ffc9d4dbe3ea86ba5bc4172761b5ad2c393b177c1df8c31a1522a5e881435c496177c2a63d5dc96e390cb7205bfd523be0431a99aa2bed8798cf52fb0188611b59b2bfeddaac49d46a461c016fe8fd847e767e9dc7a183e172ff1098e3dd51fad3edfed3809137399420d739cd41d66a1f6effad389606f146201c6c997bbfeadefd1b2461a28d5a2940dd1dbcdb3562f8aa036af3c572c75acd0317cba0638ceb53d82bcd4b6804ae2bd51957cab27e9c5aef166ae36828492579094712fc8bd98844ee2769a028add9f9e7fea857a2e20d7f8b39863cfdba4bd83c50765de6610d518ab2a46344c18079ddb5ba3d9e70960f397b1342505090620ddd88b82c8a78afb0f8abe3da7ce108c6d7465c434435d5db46e69179557d0810fa8864cdbf9c85082447725cc1a8d8e1b6fb7df526d668bd18046e1b89b47a2076d0303fc50035b5f32831bcd1d96d6e543fb09ee4db8e2a889565d158ea5a6316930e9bf8c95753418284b087afc9dd39d620b888ed2ecbd6dc5e8709083fa598960c1466f77987f15f79342f0de6e7eb3c4820d7384a1ca4c5d130f37e86ff2f693c243f0c78b87c2b1ff8043bacc91bbdd417912e656f4bad9720a2be7811c969b6bb9517a98640eae73ddea1a73e1538b5ff3674a82796ed1eb350ce3e1b61354c70addf063acf741c8089cf6f1c04d455cf66b6451a890be7c05b0dfad3e95c48f189fcbccfa37a55aa2cb3adfc2e6ce5fc485b9ca81781222102a82dc91186f29e0464a07e3d09e8e9d3075ce8b433cbe6912de501f0940f79731829fedaf88f57c81cb5cdc0f6805fff63eceeca642341a9b59e5ac5a4cd77140b87fc1475c88027586a2c564f76b8908d6d61c1df2f3375d952d76063c7cdf8fc94f8ae4f4286bc90d762e2128ed067191e2ea82f72766d12a7f7e0c8899c60638c28d5fd3275273a032e1e741b62f110e52a0901600cfa727e0c502dad9c7fea182cfcc825b8d5b0c04568cbfd6baa8c55bab8852ba54027a85786a5f077302ab16e864b861eeae94a4741f947b734e7748f087dad88edffdebee1783535491021f246c5eef7389af42a30939d572816afb1a97f4b1e89cb14f4500cbf39dccb76c517392e3b8783e0732325ae158cd6367d6b01d239d1230b53a3580c968faef91492caf2fb83bfd50625918d5602929a32653312d5d5706f6f31acf69137d50db5ca5f124a00e3c89c34d132de02ce34b1b20955a6731b0b14639d819f319953ba42bbadd2eb4528ee59e51351e59a63a92a44f17f1937f4e804206561643eb9ed6cd2420e0206c5b0ef8e07e6fbd43cf562a44acc198616bca5e392b1ef804decd792edd8b215bd7a53e7b0d07960594956e4a86ca7cde7a1983a32f23741926bfd823db5423b8892c2a66814b0913e2937c730aef9342df68fe847d8d74e53461929f1b94a5ed51757c0063ca3d442349f49f70822331a9a6fbccebbc77f1316349ef407e49cc2ee65becb2d701ab58eeddf4425defedc8ef0e56691a301eefa2ec23b273fcf3d89cc7d3e9ca30aa75cce723f82d0398c61f19827ddf4691e24f476dcccd2f3a82b12064549dcde754fe55036bfb4446722071d0086e7ddf9abb6bbb2e5dd7f751e9838968d71283efdfca38bfd450274ed8952b7beb2507ea9aa5e6ac22426fdba3c1e1985d7def5e0db7c94ae42be4675fea2fde4ed984b59797ed772c60855231f2179dfea3223d7702e8cf2c0f75c2356517cd56db2c61183d5df5460372da16b4f29ad601f5673faa7bf83119adcf304121aa396c5664c38e94499d0fc7b737accef463fa685a825d36a5cce044a78b812ae28068f6636ba9c3bb604bb5c44b5872147fd2bfd0e190e57787b0f9fd9d8d54cac890f79094b6db13bd267f07c2f147a43cbe14d548e5809008ff2be772419b7ddc03d2de2c3fc0e490452e142f8817958d5a460f0deffb8c3fc007ac2385d17252d1ffae2a4dcbf665f732741580cbe88b8e22c0a9b6ecb5d632a37f1f1f21e4fe0d24432860bcf680c2f7e7eae793c39f2ee33c51b665fc865d61137112b93866607032d03d180f299fe2a4392247605c88ed4f5d3fd93bc7f2efc44e41b9ef75a26815605426bf99bfa3c419573ded49d1395a9058805f64088ec1c9af8c99be59fe067396f04e7ded13794345fda3b237a094ade1ae256244176d9821145afefa3a975d1773abda009b22f48cc752101553d0a3160a3c3dc11fda3bd8c705ce5ef02aff85eaf86d4d6a93db8edd6c0d65495761d02958f03719021c1ff384ca9c504145abe2b0cdf04bd4879db57a35ce0d393ff04a9a22efee17ec2762c618ea45f52716fab1e52c0ec46e3e508ba02ed10127dcd797f43f0be104a1765708829d968afd4659add5ca5d317f1c16d6392758ed5face5d563aabd89292ec6ae2f8303ad87d9185891e6cf556c5c57b1d36a074866a34bc91c9bbbc15e8628702c52ac87a1f1a084d98257d3b70008f18cce5059f65ad3f6f034e14f461a056837fe558149bec75f43c81a0706725baf70df8f2fedcea30ffafe9ffdfc5a7dd549a7e39de2887a3fdf281f637a00e2106d68e7dd2182ea2255ed9c5d79515bed7fbf8da5227ac81580a54072a37525681a4cbeee532f3c5993e665d2c5de902ee46512394fe419fb3cb7eeb729bdc232bbc2634c523aed94cfa3bef122279db21bbe77bab7775b38ccb2c26732fb2ca2e70a1579c645f29a3f64d49bd353f661f2af48f9fe26b84c974eb8c01706b93b0930c0b26d87a8019e7a4d99211cdd7381244b3b125bf13c31df54ad49823533fb273ef52d4b383e582d5e15a0b70dd939d6ea2402cd4062031d4c66218cd625fb3bc9100e5f05cdbe31f363917a04d9caa00b4ebc5ca1d8a7b1c1aefea0b41278038b4e0c0158b43f229d396a05e74f7de9b5215e5658fd3a4257dd599dda96444e4fa30ae5cc8291c4072c9ce6f5ffe2f4e2700b7463744d1ffd5fdded0ac157e7946c8d1d17aab38f364708950a0891b718f6ece85d9f5c8f6d79f03ddc68a21df9d4277fdf529810f429fe4a27e62453f836fca8cb812cda4675482f6efe93a9a15f080ab00257e04bb5def7afd6f9c4b59d8dda8b21d7f8ce5095036a27f467520d013aa9e13dee45e7f5bcfd909df434dc98a21bd99046ed5704cba557ad0c57ac98ba2ecca64f5863aa6bd3e9bf05c1ab4d290417de6995750c0059ada49c7944f0fec73ed671dd876c50b850564bca07811bc8351a45ee370298c898014e83d47e3e2ee547c57de7ff4879c055abc52c4efe64be978cdeac54c151a4dcf1cbb9667db509decfe0f527d53584003311b77bac192473e0ae81c6b216db0d67fceb461b714e7c72d148a0c8213beb498e5883432ab1296e2159259be80baf9fb0e9ad39b53db63ab508744728ed5a4cf7a9b71ef94171ada7d3e2f07aa09d5a46ef04dbdfba1bc9bd35c62ab002110d5c6058508e93cf1da555d637f337f2b902e7fc70d33f16c605b5508a59abc6dd6246e48b66a88ea3b0ad419aca51bd0b377cae76872a1f2e0edcaa67f870e1116f766e82035b9d964d172108de8e5dade17d6c1a5c9dbea4b90394378672a352a3be9966039cfc26d4135fa61d6b15b5398212c411d7175f3c7c4f4bb047fba34aeb8040f90b056e321456544d8b922fa45b018b859b04505f62e99afa60326264694d9bd4b5c387963a444a7952b978006670082532fe28f287903b34a55de650f39ddd81d91247f9479712465fa1abe8b88d02c0206665800fc837bf786bc16886a7d2ca8a819acd274fb82921609b9e638e9f538793f9233cb626a0c5d732ce9d6240643e7fe7b09da0462d7945b552c603eb4caf2414220f179ed6cf15c0ff08c6ea596e44f7e442a6461492440b2f4725f84f600ae8657a3f3361d0b47e3dfd4c3136a6c621806db817bd604a77955f3e214b5a414e4f55ccedc818ce230ad20f6034c45a1884b0825e5da1a9a5dcd112baa4fda81da444ed74c903411cb7f3f8c03288c1c51ffb8cf74939cdec6dc5491a672cca627c609d74c398be6b67f0536e67dc6277b7a85e0b956854b683966a8400bbf03924310950e113d1ae57951cb4c99307aaaa06f033de627c3cd8a32be3c102ca4374e20507b6dd2e543e0de1abf14ea32ab4dd98f3976838abb6890e9c8a98ef9ae509742cd0011e57f24db5586edecbf1dbdea258d456e1ed43721c27f934de7c1ea7b109df8abc591d85267fafe752779d11d0cd5cf7e7ac1c2034c46ac27f73954c4eb8eeb25312aa80f7f3c4493f32544bc617870cf206a1a23f4dbdca3287cb8b7c64267af6f71ee445b5c6acd33e7ebdeb99426caf6bcb7596f481ee2f483f90632449a71fd9d3aebe3db3644f4bda0bd6179d71ff258d41f745370d6fbf1090b449856f87d361f4389b42ad5507d4d822b88ce315cd298186b390bc63a233632c6417412d75839fe82b3e4af5a4a05e4439f59cbbe7b04d6cca5330721fecb9cc674b155d276de2b74f828322eaeb87c04f68fe2bf94c0db7787ec108c1226b9c659fce7f9057f04b0502838c5568b2f722c17f97b873a0e5ae66f0fc0ec0c1cfc06d90b10cdcd5ab026da93a76246b19c55c5002e2c1a5e74b4f253f4ebbee73223a142ed7bcb9284e30a7042ca6b2d4b4e5d68b0d0ce5d6df4052a6fb492cad97c83b1a4e33940d2e27ba737a9abadddbcfe6134d60046700f0ba0ba5ec5943bf0939ce96753f13b154660468fcdd78d4198c7a955c6dde8e943bebf010780abe31bfca0a3f60e42974af0cb94ef25a5714cc75a984e6eb795a378ed82109c08fa19e05be1b6651c5b38171415e876b62be2ae30ae6c56e95bfe7ca7abd8e8a3994ae46d73f33b81480e182270227023d245efcc883de7d21bffccd5ebdb00302f3262b8255b527f43ac79c2bde1495c4e5c3bc74b1b95e08b8c9b0590c4a4c881335f071b3387e2c331cdb8731a870d1c57ddf36c6aa13c92fd0639e63f87f517640fc48ebe872b888b497f4b15014caa8e256530240259044c859734f9cda97e0586f5707050aa29bb8d0fdd5999dc1540cf471cf07d550f9f1d9b0fc0ba09dfc1466efa70d773360718cb5173f90af1281700d0fe8a039525b192692349fdebff48f848661a5dbb841431f7adb434a15444837c27d637ab7ee2c7da9f0f210fbae0a00ab21aa1c5c23cb674d131c03d819e3f8514d2c596277bd6acf7dde24f2c7a54b71206cc41c1b6cf9a410da9b9094a7aa9303a11814830db465b2a936e17c7ee7b93488eb2d6e5c34572eb213e721d7376bb9390cfce9866bbecce083fecf5c250f9544a3d3ae1c4998771312ece5880c37323f697f5edf1c7df2dd1453e7c8a021806664be1b12c71c111832a60fba00bd259ac339aa9094586c87322d83fe7e42285e7f863850d91e3e451e008c5d3fb9922f2e0341710209d11f55c43d81bd857efd5dafba37fcdc6576c0bbb415921112aacbb695fe94acc390391c30c4dca337976745aa348aec0295000523951d85c1949e243cf907ffa76430b481e8d6b42064c9c451f6798314bb649509b0a0dd9dab1be57efc094299976089336f6982a836ffd5f0aeb6c11f18754efedfece802279ddce54dae1e154d9e5d6ccb466f798be3dc6d05ef88316a2b0c251d547846fb21d92a6350d5bfc9c6f61e7a6d474a7edd9bb53a95989961ff5740cfc82b4efd8be1e5fe3105e16ef123c8ce3284f87006804a20cce45b69f80eb8695b27fb14eb91c78b6491f54fadd7cb69e3356d21e67619a383ab327ead8e76bee4fcb6c0a3fa74b01ca4b0b6ba1f6f29fc7e7513be012d0cfe8b86b4f5e615bc063af820c6a295c168c2450943c43b7efc41928c31ef6d3a92c75999d4e504fa852b0c5626b4df3bed66c0b76089e0d48f09e128e1b40cd323572c4e0ce627c264c44cc3084db9de966501038b81476b96620f463529cd48cc13b200ee2514c40dd305a4cd7e3341d0f576990d72e9cc563410407005d8f962cb816ca4a5428d79b1c8342f4b4b52a6f76cc29fecbc988462d2b58682b47de4aa950902b7785d8cd5e3e02c8141743fdb66b7150cef9e4e069d9c9de9cda23ce31e4b27865c4f46e63ac819740a7354f80eed525bd7444af94fcd27fe81f796d21b8e1511d5422e8f4f4249582274c6c5c5ba94bcf650b7280b7de02ed3bded5dee72c399224dae8cf80f696e5ff711c74e0d7f32a2541ae26d759427d82a65e7b6fd8fc6059d0f8d9c6a70728eb533f9ededd5cbeb592cbc2e03bdc6c51aff82fe220f8eb681fc00de0274ab618928ddda1cb20ec9e888f8f50d6ae091de1b5d38b1985195da82cb40ccdefb2e1e71c9a095972a41272bcee68044c0dabbe5d229972bb21693f9c05c236df11e51343420b0be8b7672168daa6ded8c59978fff672669503e6fb0f480d443deac75238d08ecf1224a0a7eaf02d37d03ebfa1382202d2b47463440737bb29971574d39217ddf4e34eb304d883b13a4b635fd87b65fb9d6d578785865692f11e3a48abb3c83641737c915b996887c565f074b22a7c6fc8a78c5c9902ca6e002696d92543d2cadeec376a08968713e7ced7505fcb75d015ab879da2e06e0a53c515dd1ef213df1162c74105a8db8c6a5d2eb1b478ba23090834912fd6e50701818ddb0284abd705a1cb6ad60a578ab50c054ee07585339b7e364de18fb7263a1a25a745d9beff8eac52a92ec685eb0b05cb5c82e609b253d1e3ae5dc83ef70c4b870ce45c465ac7da22e6be51163a7707725e0ed1a230e38db5d9568b91831309d922d9445d494f8f7f086d42e08a070e33e457ba8947010ba49ee9d31ad15ab5e2d832c4c14c426b6d7cf6127c5efbdd6552a045fe31afce0f3dacab7d353912a06faebc1ebfae932a3e20b284844b33a26993b18757a7b194d13becabde2a4c7fdcc9ecbe5995fdb31c856c1ca85ade32a8a3a48a5ada6a733bce94a68548f2bf12049779819ef735d1f53fa6d5493cf6bfde550cf4dccdabdd0fbcac61b9126df109b08c4e444ad066d3a63c92bc4639abbdfee830d1d0aeb89f0d1b40b489d96cf47dda70916e81a517f5ccebb3d94ae512e9f9b1220c788f59ef078df4c2dcdbfffd99c8070b20b10560c1d58eb42e15e9e18ab5c376e65322ddf010b5451514f22399b4b019bf87b96e46442969bd9695e6dd896e9ad9023bd7b9c0096abd105fd0a3a382422684dd2854e456c086d90b1d5e5a22b89a9772c60f0b89dad10ed981567966a9007f0787442f7f873b43ba037883e26e8d55fb2fb57ae337d7145f6a029d680804738298abbc7ba8a5a2733c940402ff8377baa697f77d9a61a7e04c20928ce14f7e6e7efea66479c7febaae20a2d794ae233bbb515fd90b636289623fbd9e630d05677686e86ea0d224df094de44ee6903384756f297837d9fea75df2057c3c775c8306718df4bf388e917f57c4a6e802c40424571f9061ab65cddd9bf055923b908b15aab89680c2c65013267476ebe706108286ef15bd6dcb87bd8a7f0bb0649b59ac4ff43369624e0e452cf9709c0132e4daa9a76c9da30cc0e7f5f58666c4aa8e2342ae3ab17c5c81af467f2978476b78b719c0eb2ce04582c77f4e4418d64c6f806a8ef1943591760d70391b35d4c58bd4ca18b17d751b8b3ceaf0647b4ba23a9f876c517e0a7911641752031cf75770891e13df870faa813e4ee85978b50cdd3c09b08f52544e937d9258fc4a81576e3ffb81f0066ccab754acf3eb19c11b45cd580f6f4ffbf3c0f796d426ff8aaede2b86b0a6e16978f0d083ac68524f8772cf884117a08cb9947a40154bf1746dd7d1ac882d0643a893a98e2ad58809a804743b0c6350381f98d6bacea84a4abc21f49c1ba25186de30612d677b432e315d660976392f312a5871a420541b39f1e2aed3d9fab1da71c2944d3fc3e3547727ac512ad2a2dfa5773bf55eef882fcd53733551b44d6234ed8f5361d3693db1fb30db43c0743acfa39b612bc43476248d43aa158a2f30610f2686155d3f0e015b4767e63af32251aec97a2b91bef759f81c396694c0a8a5415bd7d1732c97d1f62d7117244b4020947348e1b608607784a286479fd1902f055a441ffbb0025de78f07b08e93fd3940b5431b4c5d2e385a347763f404f35e55631ed0de2ba2ee845815fd50ea5c0b388dce4f31fffc62e41fa802a7689188ab8d6a2f3e8b3b04a0172cf87ab4ef6be35919164c863f53b7f6f136a7e46959246b45186531fe9c39843c4df948c63a40e010a62f201e294dbbc63330549488bdaaf32093d2f2b80bbf85b0542e1634821d375493385b5df2b245675fdc5843f6894e8c8ec6277ad72faeb2c5ea4a0e1cd30c1f919d918a5d43bcb273849a2417c30c5a871b6af5b291ccf8e346d5327a89fb30149848f4d88827c2dea66a14c9f8d221d1643134d7e2f45fc43acf6cf6867539e5d44d38d626ac20b54412780ab4d8e31e5eb8f880d4bfca2ef3a2e635035bab3fdf25e82ce6b65e072b42433ccf1b4f6524b7f256c279351dfb4bb568dd94f230a983afdbf2a1aa17de89f6ae5673b97439773cb777cf4df62cba44a37423803c45024d05dfa91bc298b1b40260180ffdf81e0a76a31c54266369c925db10339a1c550d8786135fa65b732e21cfd678fd6ec3676b36cc2ec53a7f401b23e991dac5b167e243506845e925e49a0e28c6a8bafc8fb8d9f604008f951683b456efcbe2a8c995ddd932b5ff6b1d86797a2e1a4202b755465f33c0446b148d7c3b81ecc5677ead2b6ff148097455395d7ec951373047e2e9f7b7cbaae3fa09cbb348e65bb4d09ea3619339c401b4dd4709632a6f359ce9f1099908f8715e9405906a5baeab2ca85005f192b004843aecb3f4921a8ced10fa13dc3d220b40c1223099fd1436106a8cebf974d6e6e80d1fb6c13c5e6efc49e9d5aad1547b9115ef45451160329aa534550428015894d467e5a66c6d2be512efd3144dbfcf7bb60919faf7a27f96965b24952ef157c2801f0f26a557a6e6d505709ed029f64ee8adbaa18a72c9d3e67168e2ea4f51586785f7cdd97d413998ba41713526a4fcdc5eadeebae01f7319d59ae45d8c83393cf3227ed8c70f9df6b508ca6df89820758dbc907ae4d871e98265e1ca9188f19505725b127854a8377e5ff2129a22d4ed0cb3e545e95a3b952c8753f231407943d45230cb3d5072aa3ce757ce07b5bb1b140a9c7ac787e75b06a8f55e9f4f1f065a209dbaf54b94d7c6a264690213b5571679fbc88a6b397b1733e3f94f4816630040d81d804ec36fb4b821f7a289fbf1f0f7da530ad7b252c9a67e4dab0fbe490efc330321ad4673e7505e6b956f931b839bff153c3e6d09147b79100bab3c240914de0a436001f8abe8191438983f5feef1dcdb135a7183e51c5f558793b8a5540c7e0e750f79b1a0744bd6fec015b64ebef3caf2a8488c1b515c5990afdaefd2ff68a7e0fa72066c245a572f119ea42e54a0442ea228d754559bb5269aec54ed57f4dab9f090c696185e8844cbdf1a43a1aff92da20ca3d3074f6c6035fd3d94038c0ab6cbcfaa1b79dbe727395e2e936773b4a3c71120ebaf0f4a36f8555f0d2c9de3c1a53ba91aa6d2f295761b183a6f1b28c79f48ca27bb15ef51909b30c0f5a66b8423d992e09687ad1c94e18e41970084f436960d1f6692090d7fd0cda5fcd877c766eefc6723576b346f2e938a44aa0bfe5620b2062f7aa702b2bbfefaf558ba71f0cf7227638b9516cd0208d0a2ff34dc3d3a78ce2a76e3d784ce6cc9af2c29608a18401053781efd4b1075b9628af99f311cd70f8cf4a54421be9a33d25edeedec861aa708d2164bcb1cf0288779f48b3eaec5bba142c4aba972b90fa2369810ac21a3f72e6fb96bea1927f0928a92c49d2346d481166594b413803b728994c12af74c0daad9118f919216cdc4ef3a5d58d1aecf4a0bb9e7eb450de3179dab825bd073b17247560378e01701d43913ab62a868092f800627ae9300644070f78a2e188adeacdf0dbcaa6f4bb8a5ea2cb2abf3d9cdc9dfe948441ad74cbf07baf8a02d90b5c3fffdf6a4f6ae5f3240003e6cb1021f33047888ecb46055b7ed422da8d7c2834a8d054758c77537025dfec7fd9643f4675e541a04bf7494e386deefced336832e0011a671cbe6b2982ac98d2dc8831efd5c45122472c2bc0461b402e0defdd751b2092cc52449661582ee37e29387ca623eb6da44ef42df98ed1b5dcfb474fcbb9a727e0a7d6b3067187552bbf5e644071df0bc30f99a9116e2dfa9259026220e17afe53778848a8a3ebbdadadce30293b06f29c952ec80b08697eac3891c2df77832c2b029c18ba36c4490924da70dc11bb97d965579105c9fa141056ade7673851d8ce339fca2ba120a606436b9215e1670c587f86ae042c7b2a93f7f1e96cb05cabab4221b488eca4151a3ca60b85f605a6bdd1d2ed4696e50f5f73e03345af8c5a90e1c0a97def206d5f1cf365dc74ac5f7bbbc821fe1dcff3bbd1a03e0eca4c5750c6a00be255fec476b1fc53e3f1343541cc88ddbe274a94615d55daf9617461bf69fcb61fc1b202002a2d81aabf43f60ed577da59e0db072dda277c56c556b8780b34c5a2dadcb8cf2405af0334ba27603ba00330fc69abfc604c68da4cb9dc758cc1b056fc0e8bb58fb0488e22e4743a3e400912d0ff14b5af6012fa09ac6a9cc6558a8bde62a9c4b4d00b6214f669bcb147bcd7d17e80ee90451e1551cf264e443abccde0a615d309ab1b9f967241faaf7a5a1ee48822ee5ed05c08c32bc1b58e70cbc62e2535f93696f498eb37e7c9f9b6ca205af1e143de8e65f682668e8229835c7274cc4b3c86b52155e0f54e4c621fa0d80a8ebef3206b3ef4fcf57b85ced6d14b5e3c5cc1b3f4049d9353817a98c5d71f66193ca36ea7e130f1cf2ffa2d1ccb15bbc53b53fc6791c523df0c0451df621cae314c5ba50304846cf5b9e09eb3858e0145498cf268ab5f3e7137c3007b5d907451a9c8ce07b50a3b5a5b4e36238702cd4198eb20033ef6d934f8ff308df0c55300d938746b3383520db84edec8f6d2e5837ded0bd4792277489af48a01dc0bdf00f6c5064931bafca374033f18fc051bbcda1472fdc1228ea7413bef094ba8b0da19f962397a8d193eff72fecce2d7d22b69aaa8da3dba3a138376adab5b795c68fe2112b064f47045beb83bc3cde45b2193731804545252f68aea1e0314ee20b3855e095a961cbad6776f3fff59612e66372367180c05b41af5d620df9e631e9410b0dfb910b2f26f409b87ffa8abdd9deee6882359abb755305d1b79ff96e7a7c58b752dbf8e18e996238e6c263e041cbed2cef9f1414795cf186a2523d0db37ee15aec3f64ebef36f31e20f658b89a3bef9e75078236eaa9b501d2bb86a1b4e0a04a24d5abcf496d47d9dab6f3c09a33bd8b485d16e8f5098cf19a58631675811a7eccb7278731f25979e51896c744d1cb584da623f34e9c3dfab556d666d9eed42912aaa41febf9540683dfcbe57756ee022ffeb44e3ec139adb625dc3c7f10ec407c34f106752b2aa08b372f220e508ba76f48e6d3b60499663814265c45017332c566797d1fa3ade2ce46635d329a508ab4289ce05b8598a582bc59494149caad186377b12d2df5cf270da2e76eb073ca173e7bc1c0c9c0c1c8ab6d3c04d56bcf83db5069322164796d9c4c56276a2fa38496ed71bbcb0596bbcaf4cc5430623305b7efcb94220d6723114411d17dea14b1c4651ff87a6cd6191dc9426817769ec3878430c903747747e946be0d202830beef02f5ef9f5993202b5cf53c27eb33831adc510d06173a2ebd91d728cece43157260541ee96311db8ca4c1ac108d0fd22809cc8085aa52354c02a0cb69b15278cb2ae26315f1b0abcd6f96077861ec2221b1ad8d0f3ae3296a82d0ff2e6a4aa0e3b8041c8e580412bb60ba06f0ea943193b55ccc5b89230ee6b8d5f39decfe651c9356313ef50bfe7d01d257b78197b8beac4ec25186b73f83c3abd9ab53414827a5c918cfc5e14cfde3e86834e92532d8f8cd4ba6849095568c6ea97c4fd30706df337047d0d771db866af0efca5d1459f7070174ff9ee3416c86d9cf144257b754883f542d4f6240328233544e0dd2db160ba8d53f70babb4e9389c392996621cb87bac3d6401c984ae5d5fd44c2a03ffe0e7432702bb7a4245461245212ae08ba78da531c79d3e086610e87ced607b2e0f13c485421b1fb4346afc401286f0ab1ceeb5a1cb5a1c22e64fcb6e28e875f5d809fe6e7516c722bfd4c02fcb4aecee5891c9470807519f0a60e3ae82bbd0adb50758f2efb855aec974ea259208ae739207277bb62fafbae79f7644b51890aa3a0f55fcbc9396ef2315ab4b9b2db764810f357915ec2ac65b644fdb549bdfee5cf42f8728dfd63971098190888650d2a605e87c63a59cef934375d1b0bc2e171c31b51bcf6f3da604a24d4f3fc8e6d7663ecd50519c4b4a58f1f951f9454b179645738f0d34999c06a3623a2da734af6c9efec7a218a976774cc13cdb6c5870e79d25c5fde8e14b9fc0feec4c74c7ed7a4c83b9dc637eb36275a1989b71e721bc3e1869492a5793b8a4afb51510af19ccb7e354292672f98ddac5c20c98945042525bae4f0ab74aea73ba16d6bfbce16f15ffd9e1e6a5263c4584ad74666deca84d770da6e1bb28c0717de64d24f114f14bec053716a759d63cf0201bad6e8593f6d0458e8890f667561feae211121533fb83140d8bdcbe7a9e6303eb253c9b86b6661672b6254cdf861d0efa33e2bc7ea711a64e06cd372362b09b6ad130810e024557618043aa2851d72d7dc0ce782c79f1ed65876795561b1c56650f06d9fe56e20009b392233ca5aa007cfdf7da92eea8c9c57d350d6eec6b8fe680b394d25af218f219baabfc47b702ad1ca4f100e91948bad733920aded28202c76b1442af01da9ef62418016854fe38456471da99fe091fab4ad3de14814f078df122ff742055dfc8a12e81ea3b41b3dc4e3d67aa011b3db20fef276c862f0b19ea688aeb82029149a99657d89fe88f5a5a2f907c6545594454ea9ba5704c72ca53f6cd54db8b2c148e7fa9ed9a2c826993aac23c1a22120ff1d4685574694a81fd6145c5f8c5418681c2cd3bc66efec4601b33e7d12c045fed4b97f47a9f11a9b3fb2a476ecd5b3e77357001ff1caba8dc9c064b06e04758141c80147cfcea25652ca5d3b74b676f234547f332cf12ce2fa537e5222e4cec72074dd691c91097c0c3697e1d2977b55c0b25668c544b5dbe163865472895a3c23f00038395e07f7efea0b14ac57a67717831750a8c4870d89721efc744dcfc2bdff50bf80de1b6fc22ba2aa44f60cc3195b9b0a68c8d1f7571f142eb26d241c866aca528818fa9740b153e7312d5203ecad68047ae3a5c92d7e6dfa0acc0decc7b92a59a50309df48d5e08638cbf3755b2e9e40da6f8260b2b7883a20b3306770f8ebb35a71310b56254f1261b338c90deb5abb383b5ba2bd42dc76a21c4c3d6ebbf4624eed5e9f973629617e2bbe0aeac990b1f552cc68611bdf69311a021c1d79a5ecfa3c2517d9d8878a7ba3c09e20efa4e61e56b208224baaad1491c4fd7a8e9b6281d5edbebff0cc5ed51c4bbb217e055c0de3c9b525499870cdea8bcadcd0712221faa1446ac83315305346d350ce9debf095239cc9055fd7ea71aaf7b8a04908a380e2c1bc288336ced4e02484bc31fcccf110fb22162711c9fcadb481e936d9a1e567b322073a918e8333f5734e074caf4c8748397e6bfdf6e90ed2c60adedd0dd29a1730ff596296e03cb23f5d94a051ae4e36d1315131b6acb20e5254b936d4925249f47e714228637f6eab8dbf577b35436a0719623e372bfd502495d4c7182bce3aa90dbbdc6384bbe6218e2ead17d192f9e4ea90531d0be608106c1e4b087b2118c24d37de982ac0e3a8ff69517bf48dd7d975cee8a1fc44c98884a7ce88f306672f9160473349758fec85da1cd8991cd4d3dd479363d71a83edee33156d57ac1a751d275ac3de03b05e69d902f2b50d003ef740bc320019a3edfd4ea19f9b1c53af9dd09f66a54226d61daf9994fa0bed28f94ef57fe121da8e663f01be9b1d79de1dedbd4214b724bbfaa237befafc9718a19209f23fe1dbc43f5e3cd269602ef485712dfc58c00aa7473734274f1236daa12328b62b57dc215295fcefc94f465af331a18c77b86f6962d51a5225698551281ec00c919aaf9aacbe67644bd26d99ffb30599ed0976b75572ec5562d08d514e36ffa12e00048ec8d53f6f97ae0d5cb81cd8e29939a82b6a8d9b07978e536e6f3ab4f3771ca1b08cce656e477ca17e2c0e324906ac4e6472e79db52a500d925c3ff9afb4b3deb7d6b1dbcd030694337a32e0939d3829a98991a28e486402034ee3bb52908a094d9efb69759c0516135723f0c201f2d084f95d3c1a7c9d6a42f2f2edc1f5ea4baf087f34e6e3ae5d4ed91c80903e6b74937856e68f31a9d356e790223e2e48150a8b202a8acd4a146d7c73227acd4b5f5d01dd4f6e8a5144789f99bf280bd8b615f9942c7763f9d5ec40026cad7b31de0e060fc4d9da70262a63a589bb74d693f69a854d46bf3ac72e1c58d28d9c9bb4d602dc9ece78b6bd8b87a777f1a44b5fa8b08426d3de5780d6ce1d8d11d289fb8db65d4c104d905794ce9e2eb8b9cdf9551445e2c134b838457286fc9050dc0e82b07c4d68308b7ebc4cc21268d6e4504988f755e86e3561a2919a59d6479f4a5375cc18df1c05235722262d6102966d0219c38a21198341bef71c38a835129da5a05e55d5e2c0e3ddc6f411f683e81e7265e6b9b9f0ad5b14ae9b7e1a6978a0c3cefceeae07768a187edc55f460aa7246b0ddd5981b775997d80b0d2187ed74de2a13d7c8f536245c9233094d19cd172ddf1fc5e582db5b12acd6f80ddfd8e4ba7bc6ebde50e133e00f4fcd50827557d49d0d796dc54344c3f9b73e06b24bc077f0791163878a4356d7bc55c42c398b49f5675e2ce5e156ff11f49834ea80611d95bec41984b950cdcc76f30a34168533585eab7f0571dbd82fbcc8d1663aab7899c546883facd87bcdb7c8f566fe21c79d78aa89203a37b79df1c3556e8d0867ba5e7d6a474e15ae3838418e33012f0a9a8172a81a198cf744bfc19db1a324c4d99fcd92bed8fc2ae423221dc2c3778de720a5a8352bdb667efec7632cc0c011a879661d691dd37f9c781f1d1517fc6083dcecac2de3ce4ece4e5d2e122da5011da5d4a8c89a70668266528885396f4abd05d6f02e3910f0ba6d5f87cc35ab0267775a8dc397f0a4b8e8b33879024ab9424e32f228f890afc38af588c94b5b8138eb5d9def229a09ec919e329d63d73357d04fddfe2fc511ae7089ecacf0eb0a5e2fd10a38997a1bab5f364bc0cc8acc2e1d1a05ba94b46aad39c77ad6fbf7b1213aa0bbc33b144a143bfe8cb63f5ba38c89b717f1ab3159997dd5d55f3bc21d5d1d6c1507b3c1b6d4ff8b90aec265bc690900cdb083662281fe65d7500675f19cf6ddec45aa565ec12349633b3fb52e10841b6fc6a1cb822271964f87a22f4732a922992d98de871e25d55fced03613d34441b72d62fe2eb605b8d8cf7df9e981b8965a2a8983e513f0e74211cc14eb8cf99327c6540fd31668c9bb07fc6ee57a280dc194c9321fcb3029c47858ed8651599824d1d4785ca611be933a951ede21b06580cc4a6b016e5267f9e834abf1af92370f8bd0426f3d10e1bc33e759ed769377da6b39f07098be2bbd54bd8a06f53155a9c04565d818bcefa2672d18b626655d04d00baa94568f5903ebb9ae82e07e510a18e6714d422d6f59a757fd9730b0776e467cfe908040864bd08926ae62f848081e26a0871c70b955f5497b012ec6342f6a5e9d4500fb61e6875b0694638c0a84a869b10fdbc8edaca6e76c7f3906e72d123ebb97f1e644138a61afa7db7ed33f2d79d59caa4c92814667fdc75aeed3ad338b3da51961b36ee928789d90e8e53b0fae4b12b98856ca99c2497c67f462fc8c49fd00892f10c5525208709f033538bfade476fca7692891ae222cd34cd399922e6c897f44f99a0c3cc2e7f0c3ed40a475e5efed8b7467887cb15a7873a93621a0dde7c521f6540265b734dc1c37b4089e8c6e3caf1eacc751cec0a64e8790dec8f5ab7684f454de25be356663d687c1168e9d95fdf0428b39377013481af4be1d2c5d0088547d2cd16ef3466fc0b21c9b28ee585f08b74c7a0a97ee23a6fedd0c13a6f500f040c6ec88499f237ce18bdd89b66321e9ba394ad9e9f9354d83fd5c28ce8fa27157304bdcd204fe2826224a600ef2b6bea6f357e919c0555acbecfe26428a8f07778747bb596e14964c2ae7105ea16b293dc7a1b2229359c75f93aab253f418f79d0b83499be0facfff9e053e4291578875bd5767cd7637f629c09c3a0d4f4493d1c04476f43433221b155b688f649e8a3b96ac59f1a3ab26fafc810c9b31446f0315e7a1aef179d095a78462b2e88780acff7177d00d6e1d9dcc62ab10ad7c9e91a0b10ef5bb8af768f52a87524e529131f0142d383ec8ba92c013bab47a84865a33c581ab7da238c3210512cb8f30337d2a4760d7c88f4520e3e3fa2acc0d514476ad70730ec18cf4f7345d4d8cbcc71f0ce781e5f8a8cdbe6640f62136d14f93086f44235fb406517fe4ac5696a8877ad752431aefd42940cbd7a81159ed63e8478e899b38541d6db7651ae8fa96a74df18bfcc839ad73fc1634016438f3121442bcd15816248cb374d016922e09c0660ae972f7c0de9057d44ba1d62c296cff825bf3e4ea1e0db49b5d7599b277caf782a7fd7c7e948fc183d8a52dc6680b4285871bd40a62708b68d11804702acccc4126f3db4f331fe7ea4eccca0059933d09b53c29b09318fe9037f173e4f14e7df01db2ff2a1ef1b2ff32a00ddc1d25bff93a92a2f19e5fcd500de6b4c5b5cfcb734a37c14772bcd6810104573fb1762dfb59e53a3a559bf30541d9f31e6164607cde97b2eaaa09c101b8c63825d9d8a1c77775521f55e0568466795375f98201c598f8ec8dde842a345564b69a301e91521b11a60355789b2294b740ae8fb1f8153150c5dcc418efbed764d0706afbe440cd3fcf67ad5a3e4c7afa7b62e4e178f2769a1661900dd3f2387b5dc36643fe9563c22c804865bfe6a06fb2a077c72740da2ba920e121b226ab7447dba549bf56e92726f9e6b53c0f436475d99cf0d8c524752cce0e6e3fd57eadc98b87da7122c24dd99cf7ef81306782f3101772ba15d5ad2630080127f905bdab56514acc3d9531a6d6f6a948d2dcd312d5c68bcede0216395b4574a34680e16cfe12456467d0663499f6ff3925776d0590a90833ee50c85889ef064b4b139199a461ba9393881e5308e09325ebd42eaccab3ece582fb00c6f238f3beb5c1012131118e4ee325a867971a143be1846e7706bf8a5f8469201f55dfc6246613f60a440a2a2dbff70ed6004c89b17970ef95b93795a6e13e94374b3a41c07ecb84081bf4a42c153aea4317c9b5564cdd9b6b996f1a10d405b2f7303840782196b5c7ad997f8d1453cf028a1a6454c2c7926590d2d0b160768a8e986991852598eed01ebfb45d61e396fef82d3ed3147a1ba9adba868a70d83e63544b57607a789305cfa1ba80233615f56f4cb1141681fa26d1beb36240a1bc52fccf140d5ed5919269e790a459b8270da2982b73d9d99c0a44c7e8b280ebf48c4d078427ac87911b36479fd2aaa45ec4dd30473de280f275550f9e4f5f3c36c06768659b83fc94f162f85c51b86d751f02a97fee2af3ca40cdf1664a15926cb622c05cd95eb585446ec8ba4f6de151f678b04b1aee39b56bfdd8ee3bbfb354064613971cf263a21c66050a8c25d05a8f91542e113eecebbf402dbc0f09fd9870074e09a2eb92d4ee3e1e844d36a5299f35a001ffec0ea1583063c818a9cf9c6d2f19370387e9bff5551a2c03672a15e1e9332eb5d8553bba68038d1ef796578cdc75a83e2206d4a5ea30bd19a09193d6f65b117b73d5b51ae5743658ddd0e8ee0cd55a136dcb0b058ab37738e0f6caddc580cba5cc5b4139a6be148d1db5bcb54b92cd86aa7f491701669579d5572b4ff166eaf73bbca8b3cdd991866687da07af2964468d4767f3be25d52c1babcce9be62654dae35d7abcfbc1b6e0653bf23333a1a59470d0c0d8c96b61e1042d580bb5dc862c85865bd391f795188cda1f80c6c1006fa19f0cc90775da8c9deb7d9004645128e6d7b287f500a8c78c60bdfdaec8855c76d2d9dcad0dc084c1e0ed0ae85223f66eb393d11f4579c84b987d50fcfb1e2bb2bd905c3a10c29701c2546bff47298bbf0ba8960e311cd588eb196a8d2d64b8c12f0e1a0cd0d6c7f880ddeac85da8da1ef82c87a87e5aa09a28d8cf5e7e83ddb4b82741de51300f2f517f023eee9b7ad4e35145e4588c80418386e37716253f089a18911ceb41ecaeb49e611ba35b0e319c6facd421ce57245ddae4a02f9194557fda29febee271bae301f38496b49563f826b4e9d094c7c57d36bbdbf8bccfbca11aa0429235107ec63e3a7eb8769f6f6275169dfc070ed27db8628ae10a7d25d87bcd2cf2496fb7ea915881f5ee0c23a7477b5babb47a7314614e2dd03e5dc247e0f399af9712cffc294bfb4a23d82a0a27bdd4aa888e576805a331304047e315d564c285342423334dc1465e49f04332d6e927c185877020062882df8aeb213caf3ce4122e87b4a70d5b7bf80ab86e17fa1c23bf2256ed7096ec411e6a042b1aae0c3f72be83bab9b824e1e069f64b9257ba4e866c7231901ee9488eafdd35d0ed41f95e3aaa7f24616671cb724be8592084f1bbd3385f58eb91d4f57aa945b2effaf566599ed0ffaa173073e590ef72deea87ad1875ef50c39d5e9dee723f57d333d43c92fa1360862cf651ffa60594a0925ff727fac1cfab76bc138c40fccbdcfed5bc11ad19566891bc346d8f6a0cf85d9156fcbb6efa0e0ecd5404cace6cf7208ae2f8e9cc39e8fdf0ed742ccc19af6adf2de74f7a58074408603f99c9795a946011175d37a48fe79396eabe411fac4c39806488f7877adbbb88d5508686c94fddb70ac42f54b9859e1d321adde41d3d2daab833e7d949186a049bb18dedfbc59037c91deb7fd9f673ad8748eed1b5b560f6155811c224acb7c02e2362398adf448c5f5fd0354c89b8c395330104eda49bb9307a3b6c618fc6c2c80654022217a741084cfb396c26e0806aa023771570ae10082bfe9d2f2ed198b2de0f5e8cc82b18ab1add831425fdb6f055d0b265050fef4204eb5234fffd83da1afabeb43452846ae246bb3654fe0d47ae596338b7074ea4bb84cf7ba0c56ec4422a8f7b7b7e525974768aa641e4cfe9452d8640a89881e1f31ac7dd918bc062b756ed3f5bceca88b515620ae0708616c5dc57489249bd3f1749cdb7cbb4053563847ca8a8abc7618d95d36d327bc7f21febe012f810971be5eadec56ebe9242de85e454ba2114f116371ad63d151c92ab4bde38d82c41e2dc32eeeb53193950f2325784e2d0b2731f351c365cdbb2ce23f5bea1122e1bdd86df1954877d89b3e2452550e54aa8ca81864d6673613408a113608288f4c32bf438b85bdd9ce559646eaf0233a787d35a0a120ea9116d1e3647bf96b0b5782e2e7cfcb77896d954654c636b3631d0005364a54c11db6b758b2ff0421316bde8bb42b6b08b8e67bea9239348d930b6dffa823433e7ad758217314663f43a9fd620188f2f922b853fd4862c165256eed39c91a90ccd64f2349f649c54091e38cfed7845a93500e2f0d9e2326a84cd4365430e125f6d5c29d7e5d1f21bd66b75c0f73c92bb4bbb81c77aaafbb8a7c982e0bc08f2613095ecb30cfdf4dfd4d7889df434634a2d16f678e280550929a70345ecf2dca5d249b278ae10acb90ed76da16439e8632ccba38ae9c9fdd1623fd56ea6306138a781fff540c13456d1022a91447fb1daaa9ae16285776fca8fe5e242a4763ee0aa18ee1ff12ee80af07b9a4e9e753617a3646141768e4f97b26b787dd5204b8a01651fe05b1408efd701bf99bab9e42474f3b5be709d39a93619f6e97794d7272c3bea836b8f32c614cd49c7d86abd71a1e59f1718d65cb8db531de705fadb2e1b7c0ca663066f14dcc0bdc5e00361414c4ac47815bf57c8cc93839eae5a2b53cc918929edeab726eb3a4144224e14f542791abc005db3e505e9837bb6cb2e62a492a9da5b2f13211a740e0d27a2c10b707f58b73b2ab520e3d1e99f9086bbca35d2108a5e963941ff80717406a146c493adef8c9b12e73dc80c20917aece43428baeb347455ff091583bc6d813fa2f8796b15acdb7e1b39a44cf2a7bc478bddb6789f67880e5a7e34517109856f901ca7a79135da1da30583e385f9b4594b5fb7bd08c5c658967a2b3d061adf175a2277f1c0b8216dab8c0c9bfe22bebf4a1015068cd2dddb2076b0188d250105351afe40c0757136c54914dfbd48a5d59cd88204c50e7c2dca5952f96e3d4b86298efeff21190c36f5d27f2a6043a8f2b0aca839e9b35cb4f7a9a2e2b3f2816bd0dffc4a257f6f32829e17330aa28c1ccf8ba4ce6b1e3dbad377fdd5da18bec53dc63a12a4f3f60d4f56fe3b9d58b57409b6f5dcae8ae8b349c10958beca40b732350e709f3e450a98466bea9ab2ef8060c1fb7775c2400a34c5197c0a25149357a6acec958f26ec61df5a6dc31fca6c0e4f7f3f4f06038d327cb20b12c7672b6a64d84c7e25f26ce0ee0977816a5f9aee77722ff47850221c12f31f3d45ebb9fd5799e5fe667e67f2fb5d505c3914a318ce8554dcd3d6621ade4608066296199f705a7f9b4a9fbcc2c495dfd3651b5791cd4d28a0491cd308c045ce632999e395e9ef6176c1d69769d7f8f5bb2282a679c6cfe9ecbb165d727af1ed624f39c4282e035bd771f8eed5d5f3b2ecba5450c7afa2527cddb442ec40f7355c96d9773baaa707a99d3d42ed3cd72cf9625fb434abd03281bf2fb94feed6250f767debf98ce3473a67463c60fca1205d1549fd62b3e277e40739b7b3cba2d6bb292d243bd3002cc933019b1c80c9e085590842c2bc33c71f5507c0f8e2e28389b1ba95a832d013558045a4bd3fb3b061e49a3ab00baf400284a8ee120e44aed7a80de03cd87bdc191b167d660931afa187a99c30f03d683dffa4066201c195f6c2285d6298fa6eeb076a1c4a3319175f03630acf09267a104a9c96e04c3a2f903bd2f83f9dc083176e15294a16733d7df2aefd0a4c245e488c299ba19b9566d977ea7e4b770177a72ed956c4c65c87dbe22e788c0b4a6842329257dde127976401fc221a92e4530c30ee37228eff93bf07d9e5f0da99700dd51f906f5b3322cd849d6989d8c870f0a25b0ed942b41568f905dd166c1a5d25fe4a85db916ff496c64dea59f23be64d8f73228655faaa524e4e89c062675aabb9d5145407c57bbd555e2035f1a2bc0516eb934c73c229d622ca098eda3ae83b99979ca981273fbb4e838dac47717d863f28cd6d02370789a5c4c8739123fb98d494372dbd60fce664b7e3116aff9bab26430360be31729649aa93ad0e03b3279fa1626f77203f2a45d6305e857603bec21508a86fb65f600fa487761f12a3222dfb346e2ca8eb5ba377544c5884db13b593a7a2261c420f91067299895694f1aede198c669be128b8305194d980fcf37504a4a0f0054d32513849a0a83f342480f12b9f0ca3e768da3649953c22b25527e0abd371dd1ba3b92a4ca4d0cd514c8fbdb991514bce9f5e34d33f6c56e097429eb4a20f807c5ea4367d20c03f243ef90eb1eff7bdb6af3483122cb662642e2f1cc6e44fa12e2df77ef090939c33f74b4d1b4173559cf4b79356e7518b805710cfe3741960f09a230fc48ed2253eee7e3cf5c159ce248ec7f0dd480c913be8449b1433f4e1516f3555506e3ab2e4c91bfa26568b2c7e22df541e422397585e3f316260e977c525dab96644dcd6f8be53d9d7418aaaa7213cfc2357c140634b485d7cb4eb9f3df62b878fa97e9144ad545a35a59de8191d19444e5e50f0bf3a480243347374ae0656f9d484c935583dcb5311ab8fb23023272177ad30b55d84cc8c498343060862a49275ef2a377250826c9b6484d26e902b984328d16404426e206889c099a70b49f188da2a9910b8129b951fd972540b3b20d52aee6578570ce0e90b35dbdd8e862f872fd18acb8fc2b735af37ed51ccb99ed3ed868ff268d5aa05bfc0a2551e762625cf61e1cc1afcd8e637ad4ab63c37978306dcc1fa8676e078f468a833cbaae107f587fa24f183e58fd3f97aaf5cf3901788f28d369760a250ac50acc666153d6b24179590e13d146fd9935013ee5fe85388077de49275cbd82b22428a1c342f43a0264eda94097c07623751db6c9324fc837e91d93ed5b36397e24576863988b21cd2924128da33666b2e44b08075a68514b1bcee452ded103d7bf3023cf5a2e3dc7466e6cace7502810b613d777201738a62714269edf1c4f35f4bc30c745b9284dadea0523bc6d70bf066617cd6bc3a519d91aeb8ac7cf566fc04a3eeefee5a956cb0361dee51118b7397ef06c1c75896631247dc50d6ad9b53a24c5bf3bfabc4a0b5dc9294e4c0c00f38a9f817e286bf4a8e51c87acb31a5f347b0c1879f15d04a5f591d6d16e4056619ce1303134eef3b1c4f0ee2c47be5cc8e6dda355865cb91c8b41cf2e1e832c8cb498ff9d6a3f766e50c7c26d41091661a521372009edcdec05b9ae10f6efdb0d2832fd74ffa7fbf3d864b3ae9b5a9c85243ce223bc1ecb749e4b2ed348c5fc79c547c89e167289cc933c0baa428f1294959d8aff894489b5abfe89cf1838fcf514b770b0f0509772180de9bf2aa5af58b7c1181a6483f333872377c4233bce16a7e0f0f21f16986f0749ebebc43f88236fd92165e2dc23d0eba5e57e6e94085bee3343d0cc3dfbc696f78be8e9fad7395c9eccba919e0f8d18120a7eeeb9870d884079b56de8849d48e2066ea61ced331a799c78c8ff49549402eb8e067ace3b288f6e3c07e4614b8588ef7605c435af7350e0239e47a04efe67564286f9d36ce4e2ba0eb47678c3de1ae5db8f8b50a3364511063ee2bf149e72613322b7404056688597be2129a8e6e88e5088abd8c264a2c40b5e66b10cbd7a58d60338da5298225a6bf98d98a8333f39a9ea63892bc8ca10115edb66577fa9839c832229699e6252f8fcbdff81cbd989658c6ac123a97056d262b6d73934a83e1661b15225dedd4afee7f358a5c6e8f47e3d0bd731293944fadf8d25265827f7326587694b0bc9b932da239f89feade61218ded31f170a80469f5dae1d51bd38f6b16f729b395023ec6dcbd206ba5532cd8d934c6d7b70aa60011153c05a5f0d53456bc75cd99afa9661912fd61a241149a0860415a188a9499ea8f857a83493ff86c8b9feac6dfa2af2eb26c24d1808bcf9b1c458a018741508cf17cedbf84da2cf000cc84a56b54e258853ba31316616b805194f32979179187e63a8c4eee398901affd1ad2b30dc72a1814808a19003ec2921996daaf1ee16e0eadeeac9cb9cc251bfbb4a9fcc326c25742f8d628804f6cab112cf7289d10370727591232ae17f5764931baccb8d92dc829c9a8f556f8ed48ebd2b484ea4eefd4fb274f71878a7e688d47370d6bcbb985232f60813a81d03fa4162747714f7e72954d89e5ad77cd0ccb0137b9910c92811e7e86243f466a46243efb0a3035c02ebf3cf99f57f3d4676d7bc42d0179b3862bdf216e6ca261e97356181e016aa7cab408477ba6e2381fbee076a973bc5029aa654c2506cb8c9e6f032b41ab2764174636a43877fd1e25ff229b96b79fb7eeb03ea7090a8bbbd4d8c42c2bd610d20ba944608e09afd06f616c281a759f2a1114af76e604005e181e7b18693fa1e3d9cfd32fc746f2774229377c8d82c14730d0097e867fa50077ad5310d7457e1f0f79c9e168fad0f693a0e4813caf15ab42d5913d86443a35fd2ff43dca30695ce3f0d0a2e578ba741e335a1fae3ac4406e098432e2d9dfee75c27a32066fc33670b5fd9add1cb4c51856355a7bd44e507a01fbd6efe1342f794869798c3548d21c8f63de3895bc9c7a1985e97bb01e8ccbef9d14f806c024405649cf9b5e40ae7bd0b53acd1899c76efc3aeb755edb9db515e9dadcfe2debf02f08f8151e62cb5fc98d2d2379f0587bb6583f5eb4f01424f47cff98a4b038a33b5f9afdce0808625f5c6a037e2194342d82e778044c487cd3be283a15c626eaf8123a59a7dad6b763a02ae633a4dc07b6c584a4bae8b4f595c9de1a4f2c161f71b7e1fa779b0227a73d711f7aa61a73b449d1135d9a226b4628c5f2e30ffa54a5a6bfbd8e176150029b10667d623bd9cc88af613d9217d4e77ea132d9b69b59b8a745f0ffaf2fe1546c6e2dfe463253a125d55048f348ac18cadcee22740e36591ad8dbcfd7b52f6439bdadf9e5616a1e055ea73ea691202dc8e474dda02f115eb729e4a24b110d7e8e54f45f5469af96f0f185cb602b0f7c36b315059db60c9dc278419d7d70fe41e724a26ecdceedb613acab3353e7bb6ab3a48baa8685bbff3123958b45cb0b1b40b189c2ede2d3dacd04cd622f06f26c3b4234191528a45b5b9523120b62ae28adc0fe6a90318e718436e2d11d578fa848f57c68c2bae464dc2fc28a626f02ecf17e800cb82da59a2f66ce64fa0726b04265ffca2c0ed0803c45c4ee0719ac9baa899019a008ce1cddcf1fcfdadd18cdc79aa937745f12a19fc5b867d5847b27d7a2d14e88f6aa7fc74c2d1212a3fa31ced12dd281ac8f03123bda79b98fa9d54015bec10e02e0b5ca67af8b8226d59c245ff546dc5d5e4beff6058e2c036233ed67862121af111cf77ddb8cec588b931397e5ff7cfe5d4886b3cb42069c58a7b95f95d4070b088d06f2509902d87065601bcb7fb9c379f4bfc17abc6f66a5e126de548247868e87920bb2f11135860de1ce35f1ce24073145e7cd59fb09bc71bf0694c2933e20b1287a5c6573fecab2f0ec0091d6b6722ba763a4356983eae8c0b028c6e6d8e307ba16889cbe34e95b1ff8c986c77c3482a2d2e40aef65dbe6441bee8ce6798467a1791630532c1014bb6345bdcc240e2c24c6b0a84bb690d017d6581d3720137c01ac3cfcddf7afbf52a594b4ae3286efc5a1d6a2487dae9a8fccbe4043fa26da970aa3d05af88cc3e917209a8270db676c3bb17885444d99e8af7031c39dac4821d7866e28317a76913953684b46ad6db6fe1aa917943d229e379ad118c587c165ec3f1f06d38734a91ef3763f38d2de25f6caf7ee87f7698187bec57434653120ae0d0ff8376a3d1491232a35948c92b012b33d6587328782f029f9dc7cf2f29919abb3c21a20b7691afb33bf76c95841f269907054b6adaef486e7819ef5bcb975f5ce4cda48e6af8fd58a09106cdafdbee96788ca681d6e087fe3b419c4ebd5dd715129fd98213bc8e2689db56881d660e19174835206fd5a3eb5af331ccda43867795cae7c55a143e1620155b36dba060fcd52b590a5c3ac881d0536c81e57def5af68956112edc47ac66643293b3db51bfc7150a15c16d8f57af8c905a698061815bf88286c8f3aebf52c4e6747086589d41362a73979b5c793d8e2b5cf5f96e1612e1d886748bf9af543a213c2cf7583f3b79b79a52de580876a1926d522c1f384abd6955e7c0f8e3beda188255b4772c46bebe27a4b9bd56d85a33f33e4c22adfcf7f687d49ded31343b80511a41b40baef1044bcaf514eb92e3aa64b38c2c32f166a85b4fe282bf9a8067c15db025af2a4ca4af5e5f8b8cbc6df6c1d619ee307d5129d3ed8f9d4f19b8d024f22636174dd530d3112060918b5b679de17db77119ece24ed9189244aa58dd68bef9a0e39b7d469f2bb0badb99fd1b8458db509247f8298eb5844feadeed26efd09154fe4a645b8f7e91fa97aeb374faf3bcf844599811f4df96eba1e3447b803d6f4e90cbfac77a42f475151cec5d7aa2d00b6780d5fb9adbe94e0265f0294fa35f6434d021565b4b7b2dbe346bd0b49cd98b401cce1f986b7bfd1eeee5e21360f940226c5f8379e23332109495e0442a68b61eb8e43405a34c3d85966c23f9cda184a8a7ca43d5ff10ac606725f31ca632505cc90a811adedd2b09ebab9ce453a3fce8d460383f379281be33c0dec8fc2b395608f8418ee88a8ddf2e7d3ab2f5fb9ecd48d29c13b43292264a68fbdc99408df8073fc782fb666255fe0c53431aca921177012d084ea76d03ec128a4cd2fc90d1d368dd60289fa8b8e04a510d3d2bc3f678cc1f18bc16818196ae93929310489724abc5794549a24366e2a51f05f8d775a7455e37e2b71a05b445cebe3d61f47365b128b2946a7475601863748f984c0d655a0dfbbe296675e0016df5ae7d5d136eaed72f57b4aa97fc123e6514e3b1a71320a73339ea448d0654acf652e084486a302fa010424d0870d34ef701a67458bb51e4bc37f7b32cde1816d938da76c8bfbea2a3fa0953de8af7682beffbeecf0a937cde8093b057895cf0dd3fca560d743644091bcd7e173cc3908589fa260931b3ce6c914d69bbdd0b5633e452cdc23a3061fc0d28876aa54006384f7e82922ddb08384e1fe4851601dd4075249833c3be6b17708a49f00752ad59f2f512365456a2c2270e8c488250f9784b0a3ba89f8aa0cf6bdc367c881b7ade3faa11c142974b67d51145ad01c4bbdc291e6a1bd68c40ce79831069e8346dc59264113da45e50d692e043ce9b39f5426643c3b9948ea540de9b9a72f714a3dc3244b8cb818721c76b49c0391e8692329ccb492e820d05bcb21690aa7d32be16a43f5bb209e1a153dee944136abfc732c8f25794daf17f1e96355695e076ad12f157e538ba862b8425491ddaea4b9c308049b5e27853c0cabe47c53c836de73486855107760e73a00bb787db16350534ddc1a87b8e652156a0658884991f4bc293cddabae03d5d178af2b2bf8f9fc3652a60a818075e7ae4b36167dda4f8d8cf59df50f24995aca31bcd8f92a0eb9c001aaa71fab9ff73d01e12fcfbf1b0315ee2b73dd7b835ab8e5ad563487f6e35852eb755035e6e1d4af1041ace5688b946800642906e56c5fb8ab5dfc4ef4aff8db6b3dcc7a073fabbbeb9f7c04384f2a35dcf611f45fa5301e1ca57b43b6a109d0883bd580b5420abbd1acbfbd612d314a6bcf13a948335ac36453aa8caa2cdebb11b10b9b8039003dcdc742e3c775af6bddd29c4b1d5b061984e5d2ab1d9b9c0dfff9040f84c2848ccbd5fb3bfd6c2a83daf85d9e6bf54f54f1911e972717cdabebc64e08802bdddb8d36894061749955be644e7830db0696041920f7af6835636a6e77284287c7803391ab57d41c901a17c05c7cf7eeee260e6384e823471d7e6f80b2eee694b43b77670d067cd42c3c8ecef9462d701ce3e22b8ad268a583248cb459fc257c5eafaf2e0b003b5b57b705cf2167dce8d54e7ee0847f9624fbb161d18a4b600350f14074afa9ea9a81388f249fee159bb8d68f3b80857b2f703086519e54d6a0d588169b295bd0517e3930fbef65301025e491f6efc85b98ac8b855686945303f8dd92b0905c13e999fbd29a3df98c021a475ce09efea85cc0adcb9727a1b8710651af2079022d84fe073add8ac9b975e73a8dd1b7f1fe1dd5aa8ded786e0cc5159b6ec82ee65f729c7307cc832245ce7f004a1c36f5865c7db79b44d641033646973ed7094044b0a2da8c321f8d9c07d2bc984e00e0689af26155ee7a143569bfd1020d421c7e4e0f8334128832ffe377e6f4aae1b9fe729cd45d88bd551e7bb1d8fb68cb553b5f50447d8ef7ead2907ea9c37a5bcd301869204bac63838ee0d92540c7b1191fec835b11e088d9b438f042abb0e23e3dfbe3478be4b1a2d755e5b40067747435ed4fc0c5b1cbabcb3eaa1090fbe8d4331f69a3fc212390f5981797464c25a6ba7656f78eece5d9098c0a627ec7439b93c370cbc4dfdff5c47775b9e1d3a6569d084314f9d60ebf478b133f7b8b7e1bad225b7b66ccd0783a9f1fff33055e429eed4fb11a16824aac593320f8ba3a14a0d2f5f244c596041cd17d4a973b5c8b5fa0fe3a5f3c1dc6f13dbf6bf730baac81e7755cdef03a8f18c9daabb83e8ad87576eeb72ce97bd6bf188ef75b9312cdac23bcab52d974a4390ac5bd209c2698fa9c1ec55317c51a7d8322704fe322c934391a4fc062b5a977eca493b9b094b59b7d962fe70a8fe1559042d42325785605b9a32183133fa9385e8df675a7e8343a2112beba7d08f9a34e003cbbc3b64854681b292c98c0c68815336062a534fe5070d85b2a9ea7928e120bd52033a7bd31ff442fc05acf476ac5fd2f188aecd5a694690818cb4852f845dd529cceef87d3c77440aeb0ea6d270887e7462c5b4bbf7e32e494e4bad0103d93af387981142849aa3ff9e981e6334d25838eb3359a87a2cccf2752d3988da5a6673977b708e23510752ac67faf958a714f51d40b03eb2243540bbd792fbd028b9e64766177a1b3d23fa6df734dd2ea6ab808c58f5770cf53873ea6ee69bcb1de43a299f7e0dfc85ffbf2e228669c1aafecaa5f5d03a40baab0d08cfbf4b4deac8d93504ab6c8a80e4fd2f203bd29397af0ab64d09e354ba724b8fabdf7ab294f47e0c01c5ab2a3aab44ce2d115b955d0e8edc364eab81f76274accd6c27d01deb642c37fd836ced879708ff1e7fad5be9b1632ff28af5269c9f4232cbd5d27649624cd807c3ea3e1d42ded5d33e79baaf44014727109cf688e3cc4efcf83bbf6d228beec93e0b5c2af961090925998bdd8c2f7acc9a1ef03343b98025676a52236301395b7f0a786642d85183c0435423a909ffec10f714c4798801f8fbe9cf80a0715c3afe3fead640b0279878093a715e86b5306ef62d9b9e54ca2c3772215378862092392e64ea102ce9ce1466c065c2bcfebb4da2dd22c4ce023af35d00b799467f944d9bfe446c9431d836104d4622da7d7a2157218e0daf18938b7d28d7d2f9aff6d4156d8b4c86b541409fa1b3cc28663bce97aad276a459785e3d6cfb3e93af4bed870c2300d4d289a9f21d0925dd2c9f9dbec19e62fc31c9bb76adc8e747597ea6430152cf59f7bfa366d4095ed6eb32de63d26feaca568e092b437b696de2814ff0c77474488aff24fd1ec68421080cb8e9cbcb0ecb38033951706ae1c215900fcf96bfea5a7ec33436af8208dac14823ff3df0ba5d3b1a0d1ccdcf7ee43c4a3aed4c721d1a967157143f4999a8e3959707f2bb7c3fd6c6588baec866f121f4ec95b3e7a47de45e0884a421a794120a548e4765b1a341e651b604a243e92eecee414aaf92e886567856c06f3f119a153258c78bbe25accf84dacfd684f7b35a5d94ae5fb6146b7b8f529eaccfcb7b36905ad1a947d221e5147db3cd6e5b8b0122b642f5becd7ae4bee718b2cbd790bbcf241010d6b0e3ad673c3c150df971e0f09c0b4db061989792cbb86eec6730a55d353ce5a736dc45357de01352bf95d247cbb50cf3c516441727602f29a335ea7c3f002384080b34573bb276030f5b6a8f4214e4dae2c3b58c6df861fac6351c50cf5e8bc218575bc235b60e26cd6adc8b337964783147adf11a72c5d7a80596dc5215be1d93998ea086669a531a571ebe8ece72e0667c52760130fb079140313d5431cd1cf14540f429dd421ff2901d605bacbda5017c83bb67447fec27d10b111709460b2bdb4bb37cdcd16f3465a2d91d3f866edd6585faffbd8f586e08562120982266cb3f1cb89a5f7316e15a7596fbb1d897d70231d89681d0ea244fc87f2e260b0dde837ad029940a89dd27570c8956c469ca5d5559080c96f567ac5c27c6f46f9e9ce9820b8e1cc942ad831eef9732bcb9a9a17b90f6422842ef26d725a98a2168235ab4f566ba90bd0d3fd7a8aba0426685d38f3248aadd3d3f05a872eedd526dc81b2263b38e82b1b270df4aeb21f38414f7312d03cb9687d49342653d64711f056caadfc0090eb10ddd4fe2479fe88f4b429eb1af433f9a82b9b709d8cbee3c3ac14455d2c65613093d8938c7e85255469025b4e8bb13f66c3d30271ff599bd58af1eacb651b9b9f436c261bc2af5a2267ed2675704f368f48fe3d47b224d26f76f9a0110c3961b09e00edc52bff960137fb8d73e313bceb2b3a4d70c9755b0094cd5642d2159cafb3561aae7f3d62005fde03833a043a1ed98929513b62b834689d6c389d0603e07f48ecf6e7cb4c39ecf740d1240c5fe887d5bd28b76777d113f2799778ff2a86e17b9f9032e71b595fd0aabd15806ea1901c835f2ff5a68af95c0a655f26eed1eb08c3649821f9ae65a0cb3e4fe530ef377a78ed9d6f54ec4ac72e2dd64f2e5debf89dee57d3e1d5eff33f6f82f15524ec3be22a3163ed34373d721252657c7775aee8c9b33ea9cacfe9ec6583823d02289b17723f21d76b86454f5d8f65df96ca216088485431c6d806e672e5058d9090a0b95895dbac6359dcf728934a4515d094a23cde7cdf3df9af9534e057180a07c2ff1edd772df1f3715321f4c98964051d55f945881c099dc29c337d61fd254f0eaacd7b1b7030a2df2a4f1a9d9552f3d3b5f13ee23a6034d73bbcb9d41669aaf6bd885fca78ad426ead6d724e59a284b6cd0c37e454db9c22143ac313d676d3507ca09962b8bb07589c79fce5e6fadc073ceca69a0dcedae40f0b90931f5a23e2b4a5614d8ae0139596760210b57b1f8567c9765405ecc2f1a4735967d24bebe65fbb8ea058447fc8065cda7dba5bf49f03b4dde709d1f76ff60f49a3e92cee99b538b454c60ac7bc7396af6790a19b841b86c6753badd00261b9b10f27d43fb10af904860e213f7722fbcab4167880909fed6231ef6f934ea66b4e35f51570609fd1f22cf61cc2ddc26d1f58d815ae264db43311728148556a20b7676d2d82b8217c79e0de3fe8a3f4eb4a86824365fcff5fa0c1aea511fba8f7a5a076fb3172ee77afa13e004bbbf5b5ad0648441d05336c104d427cf432ea42b6c3c99350afce1338be5aec69dea073b52c0c005059bfe0c8705e5fa07c9c6696bb5a5a5716fe36beac631784b836549db50e225eef50cf4f47a7aa4e817aba51833ab31cc4046193cd394648f0aec2234cf6920201af59aa6bcc7fe04790d3aaffac788d50010899d9155a2f9f807fd831fd270f02d63bdfd2e0d7b96aec2d04cfd8217d284f976eab29eaa66673b34e829e84e35a67da8370a14d70bb33ef7a85df6a8a5f120aadfe6d75a4cf8afe9de9b9d0f1595cfe8dfd571e7c03a8eb34deac22c7ea864c4cbbc6aa65a1eb8dcec5d8adc9df082838eccdcab50ff87629b267b6913e77aa8a385014c5f9e8c52afaa63d2be7f6a9cab93ceb1629680802d162f3717af3ef73abaa8ca96d2fe9aea2aeb4b17854ef57aedc121f99eae3b08035d785793f3ea5a2f24298cda79ff1ec61b0002a407d31bea921c70162d7c5dccb9b91c900ce284f836dcf62ef9221078b81d59e5ab010ebc439d122e7a1676487b5539b7241de3d89ff20754d28656e327595aad650c97e78186b06eb6ba926bc91dd7c51d23c51ce762ba6c7fff6bb1ab5bac16ff2844fe16e6ddc0fc4ff51d1c1d723bb07731aabb96d36145357fc721559b036c01e04e1de911118a94e00935615dd61a092222a7df2fbfae3cedaf13345b4bbbe092eb4304c8310dd9a81313827401d9a12ffedf330e217ca0b064ea91015e9127f429a50aad5fded5907ea915169899ca4ac01fdddaef6280486a4cdf94b3517128535b92596aec0788395a9278fd97aeb0abbb0f0af1acb9d72f884dc0124de10f920dd0cbf71ccf7ad706b7add298c998600103bc267133a7849af812dce821ca7a7f546418a092d0be41d21d9e4f42386617202f55f448157e0dbd1b7efddbd68d30a6674362490450e320fe592881aa57400dcfb9f3e893772bcf260882bf6385019207503e51727a5798d2d5d0b4a20abe1005d0e5e22ea0f7a7d838f990e368474fbd90c8a6093300ad06eb044364571fb4da54a70e60c3dd6cf54c0ac462fe87b29b7bec2885e2279f2627b3dca6f461cbc0dec8e927c98886dd3987c3a0d200563dad60bba7422eca6d238ff9036666df26ca7b0b344aa859966adea7f9e119e9336ca54ba404e50122e7179026234310b5fa07b3ca4f56b62839deb7c9daa94b9d7fe288cd6dc06c97b9774481d2e3a6b7b0a9040ded05a22c7eca27439e35d8bc358313b34d61d3057eecf875b05c8d5ca254fba27cb151f767d1d5a6abc0bc92581d1f1592b92636cc07dc81bada4f38df3122ce6a513cebabcc1915282ce5f256b97474885f33d3ac61b0b140caa22847e4ac935f056361bb3b50fa55ba5b3e6e8f21b4aa6aad0d570e0f58d83ceb3a3aa1c661d4aefd34eab23333ffbd1d4a4f36de5dc8374410402a7bba84d0f323790dad40ddf6fdca339a507eecc25206e023e3714c41cfb8ba9a966fb593c211322d2c3d55a72caa05516f4182c020225e9ab90ecd52aa26b3cfee311320999b8d7432b15d8c967cb55ec873856e7dc63999434c06238f2b3dbe2e551891e791faac8073f8a10442cb490cf6dea010142bd72f573dae756fea69218b8058667a8436f8b16d1b8cf12f1c63629d77609dc4455d8275faab4a1c325ef1e1f1db20db3fd42787fb6441bc871b28b0116d9dabe1a68962b53f6200f208f3356d30109e39b1860a58411585504ddb96f2bf8c6b756c917b5b4909836ab25292e26cc3f60f838ac4dd218e3b2ef6666a460b03defa5784c48fd0fbf180500ccf1da4cc726075070e18402d3a985a386b932d0b0dd2217b63ca8ef91254824a0eec7532119f6d5eaaf8de88237c9a7e9c01f6e8554035fda532c82ea18606696db42e294e889067e60942407cd7e2f56490f121bcf12a4d4af6a40ca89303c4d9ab67400b68238f387afaf4c2ac32494220b323d430e60cfa59918fc47a17fca323d259452122adcf6987e4853f7a7ad668a8065480ff4707f352dd7baf3576a5bf48b82723da0bab44fdcbf670f40efea546b6027d4a33601aa814d88f67849c54d2d7bd0e144ee6b0d068ec1e92c588b26318a5d57f59012fc0e0aea37c83c5b5425ee460d91420fd54953ed0077efd1d51a274903c5a936d5c1ddd45d7800635de864bb6740c6cd31fc2d2e710778b5624d986c2d2acc00c63163400fd941a39318b31fa7f371063c2783e94397f0306c5ad3a8841e4d7a2ebca43bdff4a20c321f9068110519d893a3d209c3ba84e3e97579786e8af2659aa3530a596440f80b98201822c89f37cbdaec5693d21ce7900c5c78359598216cc11fd4135a021455c3f45a43a08d38592fe2e3971c1b9977fe126ed2ef7f4dd3eb8d95085d77387c4156bf05f0cffc476998251e2c47a163c11da454abb7a00e993ef64f4f6907e4b283f29730f39b7b256014422d5e288a6a95eb6220b6dd0ece73b562ca4a507ecf73469069c292cf101a2b9982a0bf4d6d56080b0d9e058f7aa76ee3e93e8c581e1d4070a2409a49b672e52991ba12778b790afc67da8fa4837c282ce911a742d0d56782dfd6f60f6f61ec946e7b4c8d07ffcf9a384319716f4f6793a96bc4e2499514c108aad173efd705d8d32817e44603ebb894123d57ac47e2bdde95fbde384c21210ab908be9b9e16750741860afc8c8e8bb647f10a9d3dbbd2d20b8ef3313458c98dbf5ec809f4c9dfa564b10b12443bca315df0df306767338b7cad7af11bee1e0581d28325ba5bbe33f5ae9336824b0e09469681b4d89b190e3715a13f4100f8303c88d38167e56bc5b85561fd62e5565c8c8de4ff0c099f5a8e6981c1d567b628e9eed8b42d3d0a1da4dc8462896f0ea8357e0dfd23496c60020f293d2cdeb58564993620c8d6eb86dba35bf1b49442eb30dfb6d6f18d97c34db73fdb5e17f53655efbf5d92e884046c33e756c238a7a7d32d359f10ac186aaeb7819c69816e0f8e90fa873315f29a5a787a2f9a9d6a1f4445d2021fe699ed1bcd0c8c0eade1d642e502a69cc0172170e166a2b26e27bc79e71e4fe090f41d04dab4d85b682f63b133cee1fc66897b2de6770ea34a2afb950d3263194c9a0afee543a8532e00ead7a4038a7afb065cf278b545e5b05ff9de95a4d168683ff2151e78b897728c8f5e7913d4ef217eaf49c47cc2095708c17b8ab776a673b30afaf44bcd3b7b807ed17093125646e6ca01bbbf1a4a5468d9105f9277d9b4c652a0030fe93b0174fbbbee143a8a45a47771c0d4926d6966bd3341b773d4326e9ea4fd2a88d6f7f08e02154c859ad78c416847aa2cecbb6d61f7bd6e97ff445382c8cba8ef1a63a523f567eab85fd9f7610622f1bec313d517891b9b1bc5ecfc6411290686ea6718f35b2eb44ec5bef2571f080d9fc8efb56568ea10229e551364b69ae44dbdb67a413ad85fedc47ea049e0cb389df4c54bafd46c7c434d79846aaaa1813831b6c88634c861d50212056eda8e0fbe33ecd7f5188200a630003fc5c40f14315deed00f3a09f307ef8152a9724f9a5e245571bce2afb685b87898f3e668ef0d8da15a8240d49c84176da8cc7a41020221157d3d615c5a7c5c7224ec7da9a3816f9684a62d0db3df6e2ddc46c8f0a9628052f346fcaf1660d2797ae5ed50c6a76559e1f082be7e023a11b2ec48e85ca4d86ef6d3843179d8acfac7931eff40b2ab21e5e3bf669a582de7e8d32a83f5d872b871cc2b7cf6ec14887f301208a9657b7c780babab69f7092f9eb229ce79041283a916479b56c4b27cbcd3bd7aeb90b464ce624674d272114bbb6a4e3a835520b4806f7d1d68de5489ce015cc082de34e2f6c6307415f243b8ee993fc08cb1383ad09539655d2c9ff21c1bc9a7df47c8b69f6710fbf3332ee232a53c7323989228b5f445dd6f20ce2c2ffa2f7795862adeb73a9a43042fbe00bb07605845628510583a2e451f4d703ee4ac7f12429a01eab1b0db9dc69511615bd6464647fccdc0c8dc1ddfaec3efd8b43635fe82b9b5875cb04631e5c154c7b4d0d173173a3924e99b257bce9d3c3e220bec241011d9f740f967a91466c3283d70bd7a55456d39aee68dfc8cd5fb4b0ee90c494ec2bed8e4f19cec6dbe753b3787128f092de623a2b715a89ce26e8b43e7c278c950240b574d9bf53c0f76c4719031274915b7338b030341785247f1979beba656b6db79eea74db46f2e7c65d44b293ab32293b31adcdd7a2ce112a14d6889584d1f8d0f78be4bf1175fd4ede4988e1bb46b36befe49af8eeabcc98cda8fbf450bade838beaa51d91e4d928c905818ecc679af99692bb74185062bda34ba1628a0d908cc196e279973a18efe1046519b07d6321505fc668699d8770b5e213514ff6bfba4d6ba8d21e628d5ee95c86935006520008a10aacdf717a40b174f749b175d79755a471af03f5ffe89d0862703af9541d8ea5714d9f0f082a5c13a425c8e949a0806eb9118a4905be57a6296403338ed7f9de9893a2b11f49161cff295e8f989906274fe8be9fa36c089cd622846da70db2f83f5eaf920a3ce843e8050d78b0179c29d96f06266bc22989dbbfcfd0f3779193f4a48aee4df7dcf4a2492e77d33654ec89761c395298426bdf11aca30e154f09a139417da62ff52a77292d37e8a2276799fe59478afce24dc5b18d568a05e44a9685de432d0ed7cf1969fc4b51321fc24cfe35356211c83f9c4cec0d321d971506d24116b52203b9193e6479d5b0d459205c3524cf786cf02c734f8b3309cf5263ea83b8f35433dcaa9a6d071b34dbbf5b77c674b5176f7c99a29b92797994c40ba538c1627ef3917752743ecacd439df532cb90a0674e3e37ff97d55c8dc9e6dae9bf0ec13493baf25b5fb9cd8a4db1ad40f0ec1e75bf9ce130577e663d312aad459323e1f513e71c1ffd26f2d0e2ac26d17fbf16c5121c6b6222de0ca407c98eb80da938eb7eb15b37cd9f383fec98b079103ae9019228e33d0973673afc158b6509b7863543518074fa9ea1129837081e1d7772c70db1d638a7e21a4cc9507982583428498e24e3c4c41c5ff029d4b3531ae9ea922502f93af21b3ddec062bc78cd366563da1880ae84c35f1190a4f816c15e2fb9b72cee65a68b3930f7b6f7631e513d98f0bbfd67e60096db7f933668fa5526cdf7c42491db0451f78cfc6cffd534c518f1f5e8d2459254edca38da474e10c0f1bc055bbc0231fbcef526139907a71d5e08a50d9129203dd27424e86ea818aacf13ebe00f6c9f086d613978957ed7f15f8903a9e29c25778cb4f9695322f999c093c79e298f4467a4ea7e3090752a8bec52c2cd1b3db81c8c8d130b4dd0acf31faa555a4a7b1e8b3dfa669ec5f832238d9aef292378ffc7f3e936437e8c971dfbd9eeb3a13cf4adb9e4246a4caeb50fb6422862864d5d0b53da95c65f48fa777f86946e841ef1ba87cae61e1e409c3021febf6dabf9ce6f43932dcf5c69923b9d94c147512687135b3b29298ef79fdc1eb5af46cec6d4c68b3d734813a61facfe402c7411f504769e5b8d5f99f0439b3003c6187d33c068a659afac1fb89b78b7698ccd7f8bfb209edaa52a45f235a3e63b9fb15e11512ad1a8173d47a58183c30e632accc1758e04a1355d2eb29b1ed31ee599169b5ecf09db07ac504c511d6382bb95fc86c746181fcee9149be26ad85f22c1384b927ed3cbbe6f3218a46149d93ef83b2de85d59142c5419741ab4ebfbda78345df5fb692457da36fbf06a7177c30604ac0a6c746db1e4f1ce6b8f89c1510070712c8fc7b9c7c7f052dc9796c36ac9062fbb49745e5eb0b229cd39b5e79de59e0b33510614fd9082d7a5e278a3d6239d94f222161e4ffe93e449e8cd9b7c7e1d2a868ab752bddedaf53ddc8691baa5905f12beace437809ce6d80fce4143732660c092266ee73a018755f66ab3af05f5f2539a274fbf653ad949344a3c8c754e4df5e763aae740ccc272db96c4890e5a8174932635cc7fafb4d61fad8dd2da5634ace39a4a5aa674656816514bcba7815ec4291dfcc05291d980c28ecdc56b1ed8714dbe9cad0c4f835678f6347fbf783d6a3abf42564b8d19ad3f51f06eb1ef4c34e07d6a949bdc673ce7db3d4448bd51964b3573f37476fc4ace0c12b76bf853cbc7532cd225d0a226335f9ed8f9663bcd4992808735040d0fb17114c4cf24438f7efe8890fa1997db6a31ce8f7e4d96ad22157c804145f47a8399cae37b8f53a3d6df9489b2634c47c4e9992a35860b366c5216979542443e5ce0c09d15fc09ff0c5e1ad553058090fc3953f858adc0f8a3ee0bf4d4010af67afda8381ae1d6547d95075756ebe2c2385ed0ae719b2a8d68b4437be248bf5fdf36d08d47c5057d4ecaaf97005a527f6d9f0fa64d505c366c0e7b44f36010f86eb8335c8a8c1a1a3cf8e3f4f578e758cc81b8a56395a80f0a06e56046c7075cfb9d7f1d69a58a38e7ba681afb5bcb48b4a734c14a805e3ff4be572027158b8ee596d21fe7e5be72deeb8933228810e26cec0386071861f5e991aeffe6cb618c3ef1d4181b467ce373f59f5b6d865728661506cf7005172b53bc7c44d54122e4c00a23fc247fe513db298027780f9e629aef5e7ee4e13cb2dc88b74ad704b940c7ee5a6215c84688320b2f9a6f7ab6c97dde1eabaa9d07efbd44e3e78606626ccc1e04449a723b0db6546751934ddca48676b01f7194caec0650e0aacc856f47ded33f8b536f11a1f5e72e71771e3d59270fa235909246862fb91dafd803b59e804ab7d32595088ceea7f040211003f618b843763d50977f2ce6c50aa40780d0c1e7c7695f26efc2f18e06362e025b224f9637a881352f1fa935da20909b47a6086862663c221538ba2fc72381f7e8ae88ffc9b4a05d829bdf1cf6acbc199e04bc3a507f7a45f5674ca98d095d9a2f3680d4192da65e08daa40e116a54153e1d6cd19c442de1bbd14dc3020864f45ea5960b8fb085295c5df004f678a675b2b3d9a6513d1e9ab3a1421e082b3c195c703cc4401031d953b4afc9bf6137d7f6f7a9125307c09c51528256a3a4d7fef38232bd92b6327b1542ffe1d8610b45c9195962b334a1b7ecac81bdb2ff1a4e5c2d522ed213f66293d4e251126f3f399082035e5164da4eaf42aac23b60386eb491f1250784393f377ac9fbdc829be291e6817dfb4f33514b9cff163189aa46a16051b45c5f0bcbfaaa464909750c2c8a1b042ca3dc11c405c3211cfdd5424b64e1eb2e09d2d3fadda02cabeda407d9dd4f4e14b81fb3239c0d135048ded85051544e2dcab09bfd4276395ffde9fb79ce585f4149a820df2ec2dec53b70aa12b9d60c5e11e9e43b4485419818aa1c51247d344522a828cd72476c41634ad237fd5189e8c8cf68db3eff09a1846322c88c60c4ebe19f82c0e7fbfb54240b1eac75b707f96d9a57af3ff4f4f8895d3097afdb6b2d5cd09833c36bc9a08f1e5e016717284ffc42cf4dc24820097035c4c8375050c7e8c5220e063d38faa0af1b805a6acdc28da3735f7f8c26571da00fa126e0440943b1289ce5448583710277b43ab756e1845a7ab866a83821516b0a2f25c74894ab86a47088a73c41dc04b48f27e3a40f5836ca5d486d0cb3244f9d1f3bc10c97b90e093d3cbb5b54747ee6d6fa7ef71a02365b4ef79fe7df1379ecc67c1c7e0aa004fe9490368216543b16da6eb7aade03484ba666e83934afbf0bd51405237795bc120ef8ae0cebcc66e0456dc74a08f83c57e864091ff7a4b4514de6416df928cdcbd96e038c1a4f52fa85d528a58a9c7171a8f8194601476fb6e61e62044aa1e4ddca017db40fb4cfcab3141aed3d4462ef558d5bdedd469977f64d206dbc57f0270cd953c0d0278cd5966777a117ab316c47ec8677c412a2afc735505a2931ac29f24abd79c94d4052cce029ab097377376c86d62f1c516c273731f402ddee1b77c14518d4ab3784e11a901ae51e64d91ea55d6c90996f399ad7229c6a9f8dd9940359b16ece230188139658c5d29d9d2ffe73ea67a7d37913a8b57ab11ce094f2a560fc93adc08d56da733a593bd0dfa01ecff35e8b889c587b2443b71e7fef8a352b8b95fbb9421583edb881eb939bce5fad520b9d7db1afbb16dfe42e44b8820e6e22a32a0a306dde863ed34c073bbb4bbf2d3663ab64a5fb1f9f8af81331d5008336761cb7119fe581d66851315cb90cfae1f6182fd1b1a0aa78efa00b09f0c778dd535bb938849e7c080f2d8b76dc46eea944791afdb8cec95952cb1475f09ee029ee5fa0296a84c94a0bf4b49ef6be5a5ca6aef81de4b08092118fa676cda14fc9eb0921789439f1ec77288931e74d4664bb3f0043ca505752d8a58ac61f3bce0564742e2a50e6873db94b33a18f1504adfb3e3caa351621441b94cacf2e95b2469fa8b10e66c495acabe24e55020be1e3e0b4fa50afc714458652a3e519d8b17251f2e54e3d9edc507a60186dbdef675f8ea0f4dd1de0c6bc14cb9317df51fb29d94706a976deb9e396a8783d58631d7c3488a414f7d90ded82f67d493e54744db8cb187018c9023624f2c46736c05822589992b7e22d2055d967eb8cfdaa25db44cc2785bc02931b4e91c54eebe500fbec3ee96adb496259578f15ca10d13e093a69e5fba546708d25e7a5428aa521b3c10b3f56aedf75f7dfafd9208f8a5fb243713c8cf8304a6c9b80e977f60f1a6d092162ab8c3372610527788c9b53a5e36790bee5b77fca5d55228ba5fd532127b00a0a27cbfed93d7a600579630a24b01a4b0c98adfc8c79f9b56b4c749305d3117b94e39b0b9b3601d5e9d8bbfbee37f08138a592973734840a4333e72e85b1d4da31d6324b445987786098150cceb401a050e35c87c3c9917448ed16b7df74de59187c514647fb1cade7f99d7255a6160fde35dc53192c871b06d8268fef96197db9498fe3b5cac1a443b7efc02f5ba3161e9b5317956bb7bc4766cbedd0dbd47d810105268b946fabc79a305c378b3566618a19a5bc3c0c574c30be4057906b2b85d2a56e8efeb8836279852ccaef7a02fff78d6b5a3d68e7e46a4a99c16527d77db141e7f8bffd9d75eb7a5fdeb46d19f64690d80e597ee49a6c05400194a6dcb8c8fd3b3f95c27b8a94f4f2a7e022258594225e40749bafb8655ba4a0a845b4ae98b4a50f5a0d38a9cdc73322d3e2d344d2e46e3cf40535ddef412d0753fa9ca03611eaa71946ebe9dd73b8d1611ffb936aac5ed8d47cb870d09e6b1ed90de75a8881e3ee5d5d9ba4d3fde0742db47615cdd8652f9cf9689ef01b01861c2ced8d51135cd97defda76bcbb0090497c86d172abedec37d099da051e07e72d7e837e66a4376a8182ff2a13d15e5eea00a1ee38c175d9f23fd50dc2baf2a024fa1f1ef9da02885c38455fc46564a95c10fc38be9207e8307297e789d18e703a081cf0b5d41968535940d802bdaf5669d380f975b5339d980bb83ab9336ec26c1b3398cc6f0759efe856ccdaa90644255e7a597e9c22bcf9386e8c29c6037bed0015ef472407770fb545d80aa45fefbff19b1f2947e0de00ff3b98eebc6ff5599eddd4b405267e4f990947573ed8a7fd4f689fd8865e95c8bc809a51a24d68d5c6d26b0b61be075c5ede2aae11e4c417c1fbd2ffe3b1480ae7ab7496620b550f5f3e5cdff9fe7d46dbd00810e86d69d905401cf86dfa6ef9aae2f45992f0c50e1acec89c474c20ba0ac6d586ea5ba5b38794bf363c8611719d5c2bc626b4e5d55cdfc171218acc9b177bb7804ded99c4726912268baa402c9637e60f593cad687b5c8a50b331c2c858068808c6ea01f90038f9b1ffd0248ae36bd68d938a1db790045223f60a1713e297556eda624b2379a311ca8bec0be5c752a9b9e4e904593de7cd8239f361599a5893bd18471a32bd2099dd13d1e4bd992ac0ae249fbd84be8c007d686f64d69af5ceedc2a94da34c3c314f6d7e348de212a986395c603cd26cb69b572bf3b2f14a6553f423c9210b362825ca3285fc78d42aa39e191b01e54de4c53ad59900e8636044e9a61e890c66def1c5c829b3975d6677f505e953ac87580cebe2f3c90809a2042e4388ea14694a6c79c1f08b413dabef4e8c508dd00a8536dd0bf1b6e3df438f34d1455db70cacdb50cc9ffa45326be023eca5e1641af9863e1cccbdba8866f1031fae8e603edc612e24fda3133443be68d1082bddc8df8201ebf680825f1f4cfb9579f263e9a7e7c0aa4bccb11c57f3a85154358f22f1473e5b3ad1875758416d00033da3441127631635d4095acd37dc4278cecec061b2f033f324797ee13101e17d25bc80930e0b90ec71c9c8156ccb35faf0d7043d91c12ff52500265970d4a1d8287a0ad37310fce83d5bf1d508adf716c28024066bca2d6516b57dc5664065a82bfd19d4b612e34d5d9706ae72e7262c59284bdbb0615217b5568a2bf941c4772e0d0144aa7a6b418a3a570f8f7c451b99138da3aaf9e9a8529262eb76996d15308438736543b7eb0ae41fb78883ed7e5cc638c4d6dcfdb855fc8c8d0c5e9264883273b219011a512f4fa7f475421cb6446660c1ec98d0f0d11ce9e054339d7c3b3ffa725f252ade91e641965807762009fb7a0a045a9a59d15a833e122103a4817cbad0662efc3d4a58ae42a9cca682f59a770452cb4f0f957997f427ec165b7b0e5280b395e82c6c6a40902e13c05200a0c3c5a34506de203ccd2b3d5ff324b9a54a5f67ebbaa39edf7fcfab6ff0a861235bafaa812c132992a540abdad833be389ab00e58d73deff3bb8797bcc2889f5fc07780306f0700eeac5711945a827ce23e75ff7d48d589684b24c73a2fec28e3c4356faa5c06e76815286487da36df4b67386afc8ddb2200adb8d06d45f7642c01e99ab45a7b0b0199e5940f350216211c8cc642d0f20f3ae59e8394f670b6fba3d35b4e300d7abbe199ddbe2243e01df0e312128e097837b05d56b59a855d9be2c968a5d48915a01952ed3f29880b2e49dffb7598db9383ec7cbdb943f15510716e8065ebfd0dd092ffe8dddf5a2430f9217faba38c3ebc3bf111b0439367fd0440bece421188adadb2e46deb61471f8cd3c5d398622f388196424187221400467b5fe0c9ceddec758edd420a45a3709b000737d82766ed42a466d55f4ce447b48272267e141d954007c5b45961ba55e5df5f65999168b90f885c962c6bee871bf644cd7a06bc4ed75e68d42d301d49ccdef8d2ff8a10aa3def12a8999e6ecc13d6a9e89154aee5a718af8448be05130cf91729a77148bc4c7c197834f700de995b0cd3f04bce8f0d3781211e4649ee48aba764c906178881796fe5d2636f33b8679d6ad3db9019bb9a2874e9f531e5e3684cf4e555219c59581c37fcc3c61ea41c464e14f8cd99632c4b71798ef4d8b72a3c40c4fcb29b9fd5694a7304a43351f83f0965b0a998b460eb2fb767849947d55819193775d7aeadf21d4ada63acea427fdb6523ddd25f387f1d7bcc845d5d1a1ebdf5db0a85174af56ead90e437c39346c749dd3158be563411dd9e61e5a0914d18e126c57c7ac014b5d24ad2f4c57cb8e461551fe4dcd088a1ca6b64ced067fa8f17508b3fa8bfa66974b55c5d3b98ee62ae3d5499766d97995d63af8d97300da496f274401e6af1e00f689d853927e246f1a2bf5bd922bf2a364f288fe1d24eb4e18458a4c5f545541ee11b701f8038fc2888a98964cdbca2672f625bb88b4a5e55c27b1e140c2b224dcafd987accb023beb371b33031bc1662be71482059914d75294647a37bc668c433ab2a4fd62565f50bdf8015c726c0b2fd97bd3279054244fc4d4f5eccfe9020320757f6c49bb447f7c4687e425b91d77eead5d8aaac5efde5d5244ef643c86dd5136080129bb05748b195c63fa3d94a19e0badf44c39bc86640fd2aec1e260d90ea302de9434c9602879b62f5b69de10aa696ac314283f4dbe5a6afab6429c2d6be56a66f93ff08f4facf446de424e8a667f1b891ce977ed77153f7cecc749e0a73b8023839c25872605bacd1a3af6559593e0787896860a49c92836129f4025c1bf5b66f517fc3447ecdf65c5ba2e943e6dee0678f5ba586808ee700a2f380e20cad5cceb2c85e312b983bd7dd6644acc7f29f23ded7f88ecb9b7ba43c22b1fd263eb10a49932487aa5e5952c7e00b9c59726af02575aae8e18bda1e976f0e9c20f20497603c8a04edb96bcbbbe1bcacb4ba642ece091028066cb48159c1c45e2da55d77d6a1db27e00d99d181757f66662383d7ae28f8313ef4f03fe23f61b7559391e4266ef3d066b2732f79b71b398ebf436cdb0ff67fa55265f5115efa058bd23bd55ef31a6d5424817e1b4b2da9e57ce3785c9b752cbca61ad5bb997dc6340c1a845320c44caffc6a210d455f784186cbfc3d19132a649835071072ff1e1cd48f25fef6dca9a77f3b92ad7049b5e30de007a91c346203ab09e7c041ebcaffe1646a13ffa969078de9371eabddc501d784341f822e56f965da045d58dd4dc2d4a81a8efc1d1aad37ec94ce564509adafc069722037eaf03795283133b460120a7b649c4f27260178f81a8768223a1a46dcaa7c574f4a6f1743508e43e641b2112132262a5df09edd05e9734108ef8f791253aa0570ad8616c9b582338da4466c97a6a89b1fa2aa16b705f0d9926f92c027fcab0256e710dced90f8cecbcbb42c4167bb13460861b1eb06b40626d94b92ec9be594818c4f5216c1d4ab5b983a619b72eaf8172a36e2245a59114ba71017a8525e08f4b3a7601b443b86642d93d64f7f051843c9372c692423e2fff656096d68bf8aee1a1d64f961b2df9c762f89f74bb6f3da446692d4300bf4d1461fbae8aa6cc0c9ec8d9c76374450df598270c9947fb6decf748d52b7ecb8bc26e2a9fb161558cc875c258367bcd744e7e2c5f522b2ebc8e38bc9c467081e8854a54227c9e71cbbd7ffb69e9ef5efe4b1e51b798f8a474e8373ce3d83d2b431306fbcd34b94aff8c3b921282ccbe39023caf8035bba8bc7e3a28086f44694d03622077a9d9a0e3ff3bb7c94b93593d7aa40368c5a27857daf4ee02274a8425b447773aa1de6f83a0bf94b356158e9d0bfd2ba0f2e993edec38c031b5224fee2f47449334c3c0bb6e01b186e35c45e96158f09337c208f1adc637b8dbced7423e42126104496327b36ac88603b8bc073acf42901064ca7466ce2ed6b2bfa09b7510a1c5528b8a98fa6a6dbfc2a173a06dc4d871d61b59c78b520bc4c02360807048c28b48f275ca8c8a9aa447389e746078ef4f81ce7bf4b5cdcfc48f92c658fb71b4d9246fbd52d44b5410ab8d80dcb50b9abf1b67cb93b0b6bf36290796e2b077b6dd2325e9b38dc0bdd2d38021f72d7296142a63e05c72c9f2ad4558360e735dd9b47c56a235f3a0fa83754d8413b41aa36356fb9803b4da411b6bc1d335750e9ba86a00dd93490c9205e5173d6839cb7e43ceb0d56e2817a4f7c0be857422349d857972401b6ebe284598537f72b1e5a7c58b5fe43d61bf1cdaa1aacd27bcbc20f8f8e342386fbb2ccdae6fea71cdf2c20a4f0894bbe2dbdbeaee08643f7e843bb4793569d04100420edbd962d9b7074d5a273889268ecacfc2b930ecb014113cb9fa9b9e4263caac70dd8faf2d07428d9ff76a9690c84e8cd0a01de758271d76ed4cd9dd035699737c5caf4c9fb07b447d0b4c28cccf555d35bb9e9a625c7afd65f3a04caf94012ca61953588801ec31e8d7bdfd5d5617fd1ed8b85dfaa3980692e39d39c1dfcc1a2cc71fbbc9d12f5891a615a47360026ac717a0dba499a93235f7f2a912f0a436eb1fa62e13dbf9d64cfd763e7ada2a78f52ab4b34436c5c11060a63cc2d28c6747e114015d9b52c31a14db93ca0ea80be8118a0fb22c8b803fd16787f205c78159ad1aa7951a9c2c82b25fcebc1bd26d956aa8937d3cd9e069fa0cd782fc908f0637fb8e37f748868f453150301001ba3130473eeb8ca174485c4b09161811e056925d742b6ef144593e53a460861e460330199df7c6883a6af3726d881b9cd1eeb814296d1534f8e252d960801a0ca762f0e298ba7feb668bce22d5cd06afa29428e73778a60bd0d32f9cdc2cf19b4def8b34bd5851ef4d7f428e3df13eb35d21e220a96b7317bc63bc187b82a526140255c514ea676d30a96d9347e0376bff554d218c0aad52cb994af9025efcbc01f675e7c5953f6c92954bda8dc19adba44b0dcc538e6e985199238ad07eb016b0338bf8d006ee12ed8dae50aad531d78d21fc1d1a5d4ef69c9c8e646aa3ab98e09156ca132ee11e985bd07742f4266ed789e09541ebb0ee62f2a098593494ba4b3c5ce8ab3cae02de6356b4f8f8e9a57dfc5c65604e712aa0643739ad9d9bd47f46a4d5d11dd7107c540f17b63f8c971d4b84a33d58054760b7879afa4e8d24501577373fa1ad7353654d812b0a9c0cf10c8105af7f88373f73efd0f84c4297da437ddf7cdf9ed1847a37309a9dd62ce04a395af2d10352570a5f7371f5fa1830fee32b6cd8957162c50f54762647e6a57aa0477992d2a6c358f7ad34eea81b46c6863408a54b212ce8beba8f1c24802b8d817b0e8f7d93d77fb3ae999dd9779201cfaeb9f309094eddb76c8954657f9f4eb6acebb38e88a4474bdffe25339cca73ba67b108f6b493c03b282716f947745f16fb81e611d042460a853d3895d03924a32c7b4e3c6dad65bc90ad9d861972ce9a649bc8d853d5e428e3d26b5ed4a1ba4df2f17cd23cafb40940afc46588bed10ce955b8a180ef3f66a559e003b7e6d55aefc051b8ab638a8e11cb60891fa1683dde48c17bd079eebbd18797122098dc4d1746ff2841f346450d3a516493c692e19fe589c1a59f2853849ccd5200bd007acb8a413377f7c23a295f38e762e003b306cf667a5cc492d37110ea6eb7638a4dd4f5c2adf0a62991b4e3b724675ec5b245c225be6774ef05ce9f44a7672672f9c1c6ee47ddc85f2dd7cf549a748f720cce84326465ac6aa70e9645ba4a64eeb318e950b95f82bf090e9a6af60786b944a03a4e633d2571dc8682a3a8ff859d439ca05de489b784bb52e92c43e4b8d636c54c5ef594ade24848f5a93f618a18a0769645b596803516012b7549a90ea137badceb2ee6945006646e4683798e7fa6aeb7e2d5bfcb74cd95c68086db9dcdcdf724677ed597cde60f7360aa11c15bd8b91aba73e6452d2fccc12012830ff12d4937a2ec65d62e70f0ee3ed4c87db7f033ac26f7ee9a2012ec66d3893cef3fb8912a1391dea78ee35cc04b564762c5f8a3dae3021b4148699adfdb85be224d83f229eb58f17cf8a939f5c7352ddc719375ae9892dd08ddc64f4dfcd2cd42b07c3f6a6048950311db56c6617517e8e12a6b0fe99bda3f6402623e41eb0d3516084d495fdbd155e5fa66c3105d71e7cb266e891daae4f4acc06d542d7b6e7d9fe6215ad2c974e66c23640f7d5ab5f424a49fb814fe9aa38d2421f86a76400400f3862b82aafedc297f4b0cff714391c4dbf7077ea1dc6b6f0c4cf3ec95734ef38805574b948404746632c69e6d623b74359ff00c2c768400ab2e665d3cbe75f26c4a6acfd0553c5d88d05343c8e1acff57131371ea86d8944f49308754ba88785f1e2c806dee46d3c94b160f45c129f07f13e03bda36a8ecc21a56ba68658ec67dd91aa99d6e10f59cc11e159c6cfe26987e1730843e660d0999e8e921f739f1496251269ab9664e83570650d26f23d94539558fed2099b3575c518190cf5f5f0e8e9e86c898d30a6dd4021befe9706630d83c2a8c3b4066bb2c8202a964515e349156bbd51c981ced2824a37a19a6d78cbddc94699a9d061de31546a1b1b4492f967cc0d41bb5b70532f4737186689f1021bab088c5652b38cbfce7a630e414c4f54d23b1ad45f11acbc8818536513cff9499a7d2e6817c964e5c8b717ca76baebabd3ac4a2f9d013343c4f21f3ba599f13fc1c626ef7d56ac846d402f3a3ad27ab89474f3e4897d3ecb312b93840d4953f00e9de660ed75b5aa58610f0857230cc8a04b482833e4dc286f5959782fba1f8bd5a71127bec496d6d51c5f21996b94608ecdd3da371cb14eaab6f2b3da27500c879977f0ddc8913cfde70291c5b2246cc7362bba15588a379359ab920a5d706c167f02cc8dfe249daebfded095662e4627533c77c25cf30462e0fa0ad754f2828e04345798c3dab07ff282f7a2eb2eff38b9b04c28b6b1479a6ba496e06a22201a34a6c7e8f3f9284a95cb0ae65bb4b791aa1660c4fbf87871df9c6c22c3edc35ac50e504ef52cde78a0c40edfc61084bc29e0b6a80428e5999d0767f3a9a44297da2ce9efe31da009d2b229457b55f39dd86c22330947759208eae2be6d563e6b69aa76c844b2baa269e7394e838fd5d3370665dd5ff9f5744a0493407fe9114eb053c08f6dc0cc524a3f53d0f183459a13beb20d4f589d751967f1ff081fcc32a73a3457189c1051c1b899aab71e6673a315fcc9793ac516832235f182090226dd7c8be8afd4bfd397b833ece9c34356911d52259c338a3ab1cc39d22bc43d9450a9da2eb2b69b1f4f5504d00ebb71f0c6592fd745a6097d547cce01bceb0fd9556c2048ed70aaf5e4a45e4acd01b154413922dd4c72987fc797dcd05e25c0dee7411cc19da55e26a36834ae5b391485441a49120e5e00610367bf11278901fd44d765e54c4f50514d9208805bc605f91208720081bc8f8a37246143c12c27e1e294531d37977096f03a80ed21d5fdc6d4ef089ef0f749b939d18180fff0d8cdb5679c7351a345f6dc4ed480ba7edbb78a1cc6b349feb33fb55be06c62421415977f299718642c003c0da8c7b9dce7bce16e5cd340c17897fd973f147fbcca3f8c520cf145e01c23949fc478969482ab77126268d25bd80c992f103112d84b30f2b76024c12a6bd25faac9c5e98699145186a2f4ccdf0a262c2d08f9a4dcca613d770e076318e73e5be9e78465ecc49c8bf13dfc3c461fad4382f2fb70b4426d5b6176f93b694c1c6d68e944dd5c7d571935412db4995ee051203392e5e98a9818391e17fe27cd6e1f837067a615010efdef3dd2b704db582e0520218354acbb4426663d6641de5ae545817e4b84df669d5d8310e94b105f34c3b8fcd4f572804adb38ea4341e9ebb54918fd23b30e7ece152a4ceb0f0a8323e26b2071fb37c997e394fe59aaf6660a1fc107508995c3ab767d38ffbda464cfc257e943b04e6d2e64eb26cc3019575031022c2c1d6ca5d10fdccd3632da7c529677efaffaeec980c897ea7dd229ec432b508d6f1986040e9a1fbbfd830aa09f9088b8f0de2734c627f967eb1228bf5f768dae4c0bedc7cc9b0c3d48d490cd4de603e3e6f914caada39b9c7a7300c4b39149a95410c4b8f82c97208eff73a69c2ecb94a3d6302349e8b757f60d199dfb0dc9a5ed9182f02769800dab442302c9176387c6ccac7e8eb41fad0ec3bdd1de1806571f5a79e166f010f1813f58ba8ac7ee01ada49256c2fde731dbcc5e3376e00dd84b806322d353ec758090d265f79451106f0122838bf84868e5b750c87920fadec9bf74d04d732d6a9b64e50b285dbbaba7b7ca81058f32b99f34ba3172ae45610bad1811a785ebdc3b02a6717cf7a6f177e839bb5b891d44c3940b07539ae9f87f20e186ac10fb471dca988eca8e4306db5ac3e7aeb1b36aa2a0248aba0ec837c3db660e5f1e556f84b455ff628a33c1adbf6d5f06151d899b1091ad03dc4b9d6f2d2b726ebd1f9b3ce656230b498e0b9a6c4ee9365ebb0bf645a7d8434a1b64002f7b76d57d5aee4e958ca30eee98857753fa78122c1addefda4818ee679fdc128deb7b4a0b55c275f95d5c104a67a1a506a68e1af602dbd4df968627c1c20f06649ba78131d6d0a9fdc977a6a124553dedc2e3a76ce03f4b695e1400afb245dd699363b90cda54c932fa53833952c1865ed7913cd3cafc2f85e8c336ce0950a20a5251dfd4452b5298222fa40ecbcac6ece0147afbcb0486e46e93e09d69ce74ba6f4c168378c7bd70fd9625e31489dd4d6f4f378c7a9fa091b7bbca023cd9a820e935aaa8805e25d952b2e90096006e8d13efbdc047f43d0964c26061dbdf73af7dc7992503da5c7a3af8fce7cd69a2b78dfe99af4d4618db110fd7e0fd94327310ed140a0464e2cc4930b5d53439a49bfc0c9afec98e9042be37e1a01b2d6d2391bedacd754f65800b44b6f681d8bd6e34d6d80442810146ec19a4fa8788d75f145983835ce8dbac7a5eb4559b588db6855229cbf883d5ac098ccabc8099167b81df030c5ebfa6fa27f0eeeb111f799e3556d65140d03578f765efba48ab2cb5342f9f67b9adb5aff943549c107acd6efbd10d4e4b6869068f10cfff9c8b5a64324ad358cb2bfd4fccdc527faaeaeae88e8b843ec723ed8e3f318328b1d038488be15a6e93e6aebb2ab4d2e8eb27290244ab4c593b0cecfce4ed80ed89161de1fa295020738c19c8ca537b55f3c8d3696d1f80cc71787ab45141b590446f28ac74c94ef3126ac8cc01594ca687262bc0aea0ee6f7cebcaa359b69cba64fbdfb15e9d541c6197135b7f7874ac72fb5537abc2fb746e1d50565f5f1a549531845b955fdf0ad273db4d3d60d9475a44c9147571bda35ba4b7e6aa3454384db1290e47435ce7807017f20018d418b4f33236b4a406d33989939afb50736ff81d3993a228bb3ce62f29816d777b5f4c0b4dd53a285c4246161c606baa17b61786e60760a63a302995c44731c1d1601255f4fd82701db6a94a35a5cb61c0d8545b31be035d32fe6d295eb361b2bc551609be412318d4ae4f0b2668ff1cfa5e1f4cab13aa0c5762642d8fc1cbd5b5177f8300aa1cd010ce3e03c2a06d47b81185a8bc591289bcf1007814b19a51fcb269798e306d0bf2b1b4496fc79b708464d437f324b8377ea61293fc32113444101688c46c8c17fb1a16ced63d69b0d9185c5b66c6d6573ad9b5af8f842e9db85e5621a1972b92970e39cecface798d49a9d504b238e94b5a7470db661061482def705e5c9e8dbdee98e1590bd1993555796c3cc0ecd520616779b1934dd0a75bacacb2121d1c47609f920fcd62211227f3c24ee83439b220e0078a5790c10be49580a50814eb6d7796362e2d6d14e57624f0b4018ab38a12ad9c8918f43dd610ee114df56fee4a9867416b65f0f0fa670dbebcaa8f9c4aa88c0ea0bbc17858b9bc03c1fe0eab922eb9179b4cfa0ec2930cca6592d7753d2515a6b5df94d1d5bf2b399e70ef631f394475a80a198c640302ae8605a156c38e5e2df8e42ef918d15abd1da71314ac34303d3760092b224b68f2ab6c2318a7d9c3d14dbc64da7aaaeeed9d32e33627790ebc23faff61c6065a33278f83362bdf7a35fe106e999255fa4f9c45d2e67acb02dc342b37da404fb4bb4df25f76459bb1cf144317efb635c441ac58d2910316d169ce40d4a92c75a7765d16aff37759479e333ca0660ed123c78d69550fc5120306176d81c76c99706314d95168e6318a5313d2acf0f62d156a3f902ecd3c3fbebe8515476e33d67a39efa755909e774ad9a9d32e13a07776a2ec1568eb1933eb620ce39a79ab76ebaea9728cd367fbfeedb34a76bb211b435af28c4c29032ed7a781c15dc06bd7626078ecd9128553de5705ad35e8cdfdc328ef95b8b1042d911946f678a248056852fd80c3a200674c8abf2fc015b9f384bae68a6ed8466d83640ad243f1a8fa2a7a7de8a4c469eaf029b0189e9bd68349b88d47694b8542f0a4d8ecbd5800f6304076f3ca2bbecf0cac9fcf182b7c87693982923f3f4f138992d882183eaed8b02c6caf1df161c551d15c348e0a9634f17eccb99c32a556afaafd094d637642d50ddb1a6a65172a08c0411299907d1f6f68752dcd3bf68c6c98aa3f4ca099c2fad19ab8e1b3212331fc739ee867783eb33bf22f1014c972631ba98fcfd8eeae9a4ed52b147f280675c7ea9f824dafaec604ee4a64fff3d044b8ad55be1411f83f5571deb973926084e9c6d3829480f09374d875a489fabc6d7c4ad9254861357f8cc2155d50877a368f5baff36c093ae25c8cf3b43e8cba0301f9b20fe4558ff5cd33346e142a7768edc62dfd28e07a7777de09f70e793b93e06ad9fb5050a4b35ccf1902f97e103a2917add79f9d941812338b50afb50e843dcdbcfdc2c429e6fc831d97eb190640e544ab1d343584f1b8b197e54d1ef44f04eea9b2fce2ab48d619b58d1d75386043a50c5d7dbdf211dcd161aef6188a2201959ef51091528945aa22f3f9da691266d7ff504337678a9382abe39aa665f7536e46a9a8cb19e2783ac6943d34a61a46a164262ae59b6e30328570a4e70a3c839de6a9ebb01375261bc417e9fe8ba8f66d2aa409671677fa4f4ee82ee3a0fd56a83894bc08c3274a2b281e4c7b5a8a7d6aa4418229809c5105ae6980ce7ce75008dcc2e3949d26bced53990717827048d42f64b70cef11027d000612197d23ab5ddc5d3f6fbd9d4e42c4c6f14c14155cd20589a6d04180f99f001620db776ddf94dcfdf37dc5cd80b9d52f0112f09f7320f26df64f0006279c3a19c7ba5b69d7d32b62b53c1269c0c89ef042cc3b42acfdee49f5759a787702ac5f26ad326986cd28eb49205a8115a408b95b555340478ea6f3b655e6830a33d78fee7c140dffca6fb3f63b4797526cfad2f77b1289684f1d7ef9aa6ecfe62dc6bb2555495c41d356963ec5778f1462cc116acc95bd870665be9f3bdbd6397fc6cd1f08ca4bf3b2b24b524251f5c2bebcb3bc0546a3714481bf0de94e4df5b58c54c51bb54360e6b441ea5126a1d439dd0bf0a95ac3596836bcb652355675e39568a22c739c36f2d84d74772ea7a70c4239dd76ed5ad7d1925d83e541e523fa90531b565848b094ca4b04c274a01ecba03fd6912b5b3203ca496493499064acda026baeb10610a05693a0b8990d281591931179328fb58d139b3e6b08a2ca95f77b21d2757c9276eed0f2705d9dc85eaa88a77bbe58cefcd6752350aad1e26c6a27d14973c19c0069d5c9ed32e7aa18f71142cee330d35aa30d19ff9cb630c32d5b6f0d0acd8453d63035511d728f31e871ee0e6510651ae99557179f2ec01dd6730af3bceef3ca50e1695a1a12a014a8b915710a1da35d44249eacbe1e9a9a68b3b0c4e8fa7df4799dfd5695a2aeac6f87d3e1ce84a3c21eb34390ce2d638971114617f0589a0cf85de0ecc94887ad9bc72e74581ef4b254a9afd28bdf5253140d2490acda3c310436f80447378261f36a977c13dc1ae903e5a8d9a717873802a93c1a82cce9f003aec11f3790fccf5d68295aea2ffecf4b423d6c30d729a1d3f6f6bdd0b305bb09014f59bc41717d2439427406972ac4b13a3b0619b31859e7e445037eb22593dc6a6aa4594052c257512ce144f476a6151c84444e7061454ed0d12afd807ac7c0588dda665f8e84b291c8d76924fc0ea94e66d3e07861aebbaa253610f34b0fc18302032fc316b6ba8d7428b4b8e2b2df73731079941feeccf6f8ae7d29ec5b3b10bb69bbbc214cef064d974ed5cca3ec1744044904e301c93a99b3637d3495d5d369f2d34c1d1eef85c35681d5d5ae2535a74f198cecdbf950f89d1e542738a63bcd9283d875ab84b0bf8b7588312113bce4a0ac920471349829f677808b421d1ab8f08bd856a241ead4dc5d0fec2e3bd3d1d3c66f90e174337e3f141551dd769d26b9f94f2d22a3db5c19a451433fcab019b0962589d244f2868c54a136608550d0d71776091d3f17e33dad4c2856c99b4e34b024770883236e0b18cf856c59df34a36d3dc68256e16deac0b10a14d1dca35282a4239ae10ea945a87b4ab5133191bd8e40e99025b1c0e250c2703bc573140e8b0b5674ec05e8d0c87a955aca0349f9e458c81dfbd70bd082313f289d3a9d05f340a0b53804f15ba426e1973e596118c362a79b4cd404d493ec917e40447f82f665e0b137945168f33ed607645494521c7e70b59c7220984dcf055402b99e2bcc5ca5af5224e5e60aa5ede853d626fc6c7ea33f2f7cbe143a3d5ed71927d984572daff940d0b144e5f5c7c2155df926bef93d661ebaf3c597d7c2c9f5ccf2775897791530ced56dfb7124da7534a1850be32acc708528565807878ac4f08e6eff5ba99c37cd44d29d875136a4bdf67308013f5cd6eba21bc2df0a427f8453208309f559889778f1f80cee1e35410cd9595f089fd1bc33bfcef51698c63ffaa5875e2e5467cfdbc3183fd9456d9de2fe888e93fec175e7b44e5842e4d50bb30bf00c1ce5abd1df6a8f9a256bdfd8a81151c55715d81714f37adb1c77a169fd65d2b42c9e3c78330d6555340edc3c8490c920bf2c8c55822f127467bedca46689f246d0f579452993fd3c9e01a0f7f6409e78704eba7835b905777d1d6daf09739edf2df10d051b02b324a2f87d9544e14fa90450d1a42593507e4bd4fccd36c6a0604345804302e186998a498228b44d9286e8f3c509eab007dc670c336d887a1b50e79b9c61bf43ab3ea3eacdf79de2d69351d502e397bf78078b85995ffe7a68b06369f1e39496d2f860ef4798c6e77ed616e05eafcc2975f50c773a0a105a567e9700aa20d5ec53fa4b2be7dab8385ea7916a6caa59109ba34b928d926255ece19fa5d81aabf5f89a0135d31d072f8c0f75cf4955bd275f1c9d1b628166a49fdde17681f5e654d2415af8226b4b25f415a9302a6564af9acd8096a8402ddb963919de107ad02466919ee3ebed6d819701d77206ee65b3212391ba9f811c4d59d82e6d8a0d3c9b2ee91c9e446d64f2b31a3006ac1754a1f586ef7e50624930b0af871c4752ebc4899f3053b1f58e1ef7fda752241b79a5afa396ec9564372ab38763e2e751b2a88a08e0ed3566cbc8c90681f8832970009349d4c3b9f113375ff6ecb613fb03fdfe5f4e3a49eacdb10ed89eb3efbd94da84f627ee2b423ef1b61ffb6d3f7ad5e4fe9b736a14fa62d0ec01846a11bc1f7471d50bb638ae31b7412d347b315ade79b2777cdce52714b36816539bce7e84162c749ebd9cf21c1b49c186388a0db48c0e1c397cd419f4bfc39942b77411cc25f6d235a4154871510dc315b3bcad7509591682a7988f14afe51806904b1b3257c02ad31f37e66b7c495905a91cc6906598e295da37b8364ffacdedd1a44b81025bcfe30c40bfd214280ca59e180550fbaf3452692895f9b52305bd823ba0dc1a41c8d3b16123de45acf824a050d7ca6df0e881a9aabcdca8e920d29a76a779b30f8e765fa6a8c15fa115156ee1293d4f33ec45bc8380bdf4182d661d11439b886056715532c6a45a8c9399db9b43322c9423f78d03c6b89cea199ffabe708be76960abf17a2fc376aa1abc089c70df1c4448b320ea40b12e1ef1cbdc89679b6c782d28d05e0e4c7a95f9bb3d3895c54f0b0b977e1e716097c54c3034f39264d227ff7f228735b9a0dc3b4debbe143f7f5139b6f431669fcda3e909f642d9beeec3d6309a717f2adff4e05ea47424ca8adde751184151b39d53aeb23fb12f3480bd6a705d99b9c0e7b1948525b3330e633b8d193496a7a8847e705c328917e2431632fe239e6fa07499c68f03588b85b693b06c3fc10095952bc19df3d58399a23daeef64c42909f565ad254ae107e157f2714a51fa7a22eff920e0d8dc91a7ebc269826eee11d54ad8daaac7ac62341444b8d817f827eeee78d39d62037e3078965c6758e91c82ff760f011c0bbc15683a6608a7d32dab3d5436129e180bb56a60a88b0cd47d4222f88459c85f4d71cdcb0aebcac12b13e433dd0fcec2aa46b1de6ea98f67d255ff70f32560b58bc70c3fbc82397045999ffc826cc4ba25785d9958ecec4f7a5eff15dda657cb71326ea4960cd5e6ae1d8652dfa1b91fb549fe77394544a62f12e25f8cf1662317b627ecda05c49a8d93cc98de819c8aa14256cef1b0eadc78b58d1c0f64606ebf7e58c01b7980764394096c8e716e4834796bd773d662a7bd2067ceb5abd01f7c8d772043cde7f561115d480b5a7998e8ce0cd37793f565ddd25c93c525fecb396d9f678853265ed24f6b3fcb8dadcd79a6be630b6ba3c8240d48cd69492dd1f133417616337e71570c99e471df07dd9bebfc0142e53cc84db41c9f1fd57cf242f3070bde4a8cd5ccd298a1d0b332d09de603eddfbee958e74f7140979c8289acef446ad490e5bfb434b6c67a2355e2ce2091ce83068659b17202412ce56f0eb2f09bfdf64f8f3636e57267e34a7b3f66761d0fd42fbd701b5dadfd028fd9cae36d9264fb753093e37c023ee2ece222f1a2c2bd26424cb78232b8e846c6c5fa2dccafb0d752a92a1185781fe7e9a0b6b4e0f4a3ed76aa4c44dc71947f9ff7b7df724c55f85b3683a9f39bc790fdf0eae84a0fbdcafc19e81b4a80928470178f9d1d3c25e37f10dc61f43a5487c211f5cab7eb4cae1205aa0df5dd7596238dd28387ae480d961f91e3209d9745969f9b5357eb6de8547fd8e66f418c881b831cbab730c94b2edac0f05335884ff2906e810fd24418f7c14f1678185eb3c7507bdf7288f64fe050b2a2d3f10240ad82ba5285c879e5844d2695de5680c5f30951625f0f7305ac5065de99847bcbb7ad79ad84e6b59c0f4b5c2cd71a59f0302b9d355f8d1ac3a0f3e8005fc2b511a913a4ab6b0cc3a0afcf539182bb17846d578b4dfc9bfe5446c1303d2265a7839b7c3e287465a15bc0c7ed3d91f2f6180072ca2f7cd6eb9cccf37fffd0410b42c870897f3d358fe494121e7a574e12b0ecb12d9d3c01cecb3daeef594646f1c9f459c9bffb12c47d0b719f346583a1c41cb059131d496eb4e2c069fa9069e8b019140b1c67e2077f811651c394b2f1fd2ff6bc570f3df77a71f36dbbedb649b954b361ecb9a9d1a2922afabe3a9bbed1cb6a16419be381b88e6834fafab149892805778e2a50e91ff003bfeae1bfdec715196163779f5397269480340ebc31477f96e759ffea3e53113ade7333b49de2bf8d3c2a2189331ffcb95f2cff89c958b7f8ac33707063a7386f080f712acbc66a22d0c28a093294b37a2dd0f1251e5118de1a2a621df05ac690be09c88a891181adcb157132aec3d60f737207380f0e1dce353d125feb398f79b21b8b28fba86082274f2d40e22fd527ba85c4254a495560db7c8ad727e0bf63f6ad552ca1edff1c2640c1eb04b0c2e599661a73cd56285c26d4ed4805ee5f93d2aba519388ee00aabb73b307cedbb7a91114ff5aad2cc8b33b0c97f09c80db4940caad62d241eb98bd1b01489cb17d23850583ec9220d4625666b5860af29cf7ac13a21eca808f6e2c526407088f7eb9b54a8a760f1584230e3476e9734ab8a3f11b83580bbebb067899e5897da7e9903d473dacd29ec53d54a01b0b62329e23f25b12de7901a42e971680128b93496eea27a7b626bb4bccc34003c8167ad0d91e85a4c0b264b29b5a91ef5700d4aa75adb3ec29011ca85df0ed929d353676ec2bd140e8c5cfdb5e028fc85324176ef03edb17fc09ec91cb1ab07975833ed7dab527338e77e11d57d87212a28bc849113735ff9d72e62a8e3513fcc7102b0cb1c7503e6bfe991797d9769f97f68398c51c9952542ccedc2f87dca6f60959cfa94adb288aff94784d0c761d14067f3a8902e81ab78af138d5a02aae9854759a7d7fc97ce29a46dd075855958bd3f9c50b0fd1b998da996e745caf20cf555fa5a435f7ead1acf910daf7244ba2dfcf728001963ed933ec4ff808ff135dd5d3f7a0b2ad0a9d2f06bd057841a0f4ab6af8fefdf7b95fc4c1ab4e5acec13624438ac64630202f3492066e7dc015fb6777f74a0df564263963ab0099b25983838e40bd0596a555864102fbf38170746c298951ac6a60696e33da277cbff3734dd4092a1c4c8bcc352ce87c7f1a19f765ab4001b8507eea89ad41085c735c8da31dcef352d3ef7ab0a1c169feabc4c5257631e60af679d93b5fb903214ab972b2cec5e5e63294d0e05485fa9445b1f9eb179ee901e894428a06469c701140250f6b0a6c6521c694b80f7e9d59b3532be638e79d08880e2de529e47ae80faa0b813399639f4c75659c067916e4315a89b960546fe84868f57aed17f92f620c83619f190cc8b592d8375f53b4e29d23e712931ff03c16f504751be80c8df8972813dbe9c9b31b3574d7504e584833cb6c5c6fee724960bc4d7e09257282eebcd677990c7b65051353e922c8dc67064cd6a5188aef9b582cf9234f6e1bd2537c7435b3b8212019300b93cab918d5f5f4a2091441f6343354da8ab43d9f51828ce59a8b5977a2d84948e5deb1bfa9c08869fa45420308d1d16f7200e0e9d1bfa84c3c9839f6e47cbbaa6c65364b00d65378e9d3081196ef871d890b69de35e869e483e37b1e088231921aa567c15d177430de5675eefe7985447badb710b8c9eab6cd0242d3f82ecb207381290c594e988887e57c88f1fa292e73846e1c60ec057e04e0b2cd18121e2629ee69d5056b5851e9eafb44515ecc6155444843cf57c9417022fdd369263eba86d226b42d822f08567870fdaefc5bfd014d3238b3a829d2f0b1588727185f6f949544c62fb0f518cac2722f8df8fa29a60f9040018883257fe9d530f47ce21c81c2d873c56e2017ddb48ffa99535e610915e5abcbba2c9b9d9b49b3416b9d2760c5c04c797c3dfcc77cffc1fd544c0eaf5373e6628ef51b9fcec3e6a68f1c1f44a84a084534fba3c4e01826158ca82085f7b4f821fc9c52e6899e479dc3df2ab9113ca18ea961b85c4a2f61db75c531fb9b766f463268ed5b718df2e32ab9bcfc3596a3580fd4e7780de587eaa02f890e0d7cd371a4dfa32847b8d4a28cdf02c37a64bbf32c749e5c28d612beaa0f233fcd95a8caca97a3821de56446611bbc1cba1c4da716603b9fec3094da67b03bad9f8db12a19a9a8a5d39c43fa612c95c45df1d31f7bb9ce49b4fb05b5c5e5d9c2caa41f13f87336eeaa2ea05ba4385df57906c78a5f45c834a5590d5ceaf3640381cba0d6438ef607dfbd4bef92a9611ee1dd96ea795161b3ea1bac7e04e5be5cc5f0490b0557f8347a7308b330aa3236aefbf574347392d0b2e7c83e17debf8d0990808a8e808deab0b96c7c2f1889def32dd672357cc1a47c11dc5ad39847c826973ae1d5c420763c739baa53185abc75fc3830bb00c359e2b99f86c040bfcb8a3ad694ed111dd27c7771eefa92472b71d63bf929f255c7eceb0e27ece135a51bdf86a654462d85779a9fc3c3f706cef0ab275422aab69e03b4a902763f454e73daec05923efe4c82c3da4077fcf4d760b958e063e04b29fbf714fcd4ea1095781a1935ef07df378b02d09c2a732d5341f4cbee0aec4d79d1ccda054edf5c41d4239571075b1cad127adc48b16bacfcd3d89ab6c1388dee36d2495ccc76fcbb386205d4233dc3fb66c4bbbe4c595f62e18f73c6b1fedcaaf7e5183b0e5b877058c2e9f23282c6a49b46991cf0c2fa3695ef89acfd4dd5f43ccabb798113f0d0bd1f486a4703467d424667c9621cf72fe55d297550f5f67d77f4bbf376925906a229332e71f71663006547c16d3f429b1b97d7bf7559cf1c3085e58d48140f5cf8818e34e554007e855255f19a7a05b6266a65da3fdd1fe146f668ff8a6f97b9eea41245a49726ed3930844fe1b5fdbc3941240e198f652a3716b67fdb1111220e23f8fc639ae010b0a0653ce707e33a907761e3621ee4b6d2b60889b2d5e7e6f024ff238f21996f35f5d920e4ed582c554b8b7253d1b17120765bb8ac98beca892feb11696a4f379793b190201d7658975eb4cce38d9e13f6800ae9267bdda96b888cb5648ee1c55a6bf065b2640bc38af5e60529ed3496210fcaa836cac6737137a924ae8a915acf2b85ad943829c34d148140c773c7ff3bad0e42c1b9d53f8776ed7b69e60dee9e9fc7cef981c5379a63fbb272a10c189f7b59386eb777172153b162d3028a96aea5fd61d99958552eb60d7626339a6293f6bda32aac394b1c0ee48a8291d7563bf6d0a30371435e6432a317349065c690c9d77c5f79989be11e6e7e410d279cdf164197900f102ec65d45c35d102dc2dafb57fce9da5f9e1517c630e0c778a113b13bbac076daea18dcd2e2326fa1c4741ddf0ee002efbd3266843e3cfb9c2bd20a88529f31e5acc4e02b8a9c9e79582ebdc7e91c4c9f64350f1b796a6d86601aa904c44001bf935e2165d2f8641ba26a9953ed163e995b97d76825f86d6e9dcea5ab90837f4484d9d952a589028d0df970c26ed8fb92a77a0b60e6c5a733912919f71dc06d8dfb6b2a9e1b1f44a95f3d3ddcc235976866bb07d48e5bcf8cd51833eca2f65de43f1aa88d55bf475b896ab1103b9347ea57e10cf75c1ecad7265e862f7a1ebdc8068c67ebe0e8e31da4cf96bbd98e928a4dd275cddb01a0316510adb27e02d5fcd79d6f8ad4cb72ba2c83f7bfa372c69a7d3e9dbf9be5d56d30770281f8b16802873fe4f567b5061f6751ad5e7cedebd02027afb9fab87499a2435343e7e4244265d461ad758311b3e458fc67109ff0c790bad83ed68a67db7e7b23e62bb02f81c0512b5536ca8badb2d2c4d7373b8f78a4c0c825e9f375fb7c9dd3fe38dc974a13e7efc669a2cea4823f587a49faae17a4808b6e025357451307c4284ebd26d2b07bed20f87c776786b7a8036849b45e69c7ece67cea8a8ec06f3d3dd6eed68abcceceb0e92f1583096f55dff1dabdc15324bdd535b65c7a06518e5a252256967f387459f45b4157166ea015232a64b0b44490165aa255878dafe764a9f751071bb91c0c8bbb4bd2dc988559cab5be01b61fa676883eae483d868a8e5b037a1b693d777204d4543950477d17bd70e69ca565ba4874394a16e4de4ad355741f35534705f1dfde23730e73356c9eb9588fb510b5a268bcad740c4c5c6640035d2aca8b39821f68f7891e09d37cd715550ca6b9bee7d2883bb6e15cff3af9efa443429b1a859a9dbd90018814ca0d4059e2ee06c9910ffc65c0eacd0a0219d71d6cfc2235251ca26fcd8386ba606b29ac35c8c34a558b9d06471bf2a56b8f53254a2e601aa648a140e0b689e44d6e058a21d06d35dbb9a57e2693f38af749e9e564fbf71648cff787c1c339248337efa6e39d0fa7b5bbec20c509415b079dafdcccceb30377b80719497995c7cb4c1f7210ec2fc2834ae6450ccfb65fbb00809d403a6c01ad858b084c4fff0e105338bb60e1300becbd510941ac49345dac79a0e398a4ac45fff9b00977c73fc2ae219ff334e2e9a34a9bf97c1dbd102774bc0b2ec8ce5aba96855bd2f68fc7f1477fdc165b83da49ca0a289f17de96b2555701d30fc0ee78bc139f1fee05cb07ea4017068f7bb192bbfe4f1d51765e0143d58627336a6cd093fa1cd87d2b9840e8f33bb8c6917bd6d021c77e15680559ad3fe459c335251d8824bd9093932cfc249d4f38262588ab49d27d48c1c07eb827e9d8c910afd545db150a9d256a5f181a34d3de2fc52af7ed139d143916306d44907bd76f475ea1d64e3123afacd02569a3a2db2ad5629edaef06826f307267a714ab0e2e5fb56fe3edd5bf5fd359b4b8309472c2e36ed4eaa728e4d2ab7ffe91740cd3774d835693bf05d6713860bf51a568a7b8eb182894fc6c0e306fc2739c1e7c946c2338fe7a46157181b96b6b2a38aaf5595d8a5ea62781fa7263730d68bb1ce89f3e1276dc15d74599ba5576f1d0f4b258d4a3630b889f16a33002c3d156a054711fa6372c45c2f9528d3f03e2c0d9455d9bee5f3adc5b9911f5c6002deaf1329427190a35d8876ec138140081e0c8026d770364e88a7d0f9d9ec9eb5669dee57c83dce8c7d876a8d807633d284bcf0e4fbf88813225798b7bfc83f37e4c9a4a5713ad93565fbd4da06de11cfc8ca7f44de9f30d7e9ad8acd41c7d358e92c7a05f2490e5e14b2299671b1e5e24e4892184adaab376eaf4adb00fec151e893674644589b03e6da10c2e7cf671e53f76abedf8c8bf4aea4d4ac966a038d4e5ea20f5fb9eea6905c69e7e4fd0b84e9e711623a2dc4d38f9971c66d02085d7bb8472b88662da12a698df69190c68d88c521a8d51fea4d75293299a041e1e142fc5ec674931207e8904cacd0adcd92b1ec253812d3d79935a138158aae724741e3a631daa2f163d105632d096718928474bb39cacd0efa59c811aa40ab7970df1e6d6803d80673a02bc1b767f8d0301e29162c1de990cdb85b5e2f0cee507395f21aeaeabda5e1dfabf45e87fa565ed3d247f59902d4fd64f3d4e911af7a97e6c778cfb41946622db16803f277069d0a503444b297697a385428e16765dde9b6cef2d7fac85db02c5c47c7e1e283c65ffaf6621469dc61ac046c9c35d0c778d43f4cdf62595c0ce1ad818119f06ed65ede8cd34e552e03758aa1cbc31d5a3777651aa050258d716b55c4827b54626eb7d14d570cb185c5e879c78937d9524fe62b51dc4e7b918bb3371e2ab4cc89e3169dac776f6f965484cfc9d92239337d64bc9b245dd21eb580ca2d89981e5bc92ab19d796cb042be83bda77917e62d204e7d88b1dca314d833a304c7eb568f42ea06f165802c2cd93f68a0140d39abd7752924b9f33443106a369672652b613ea0ff46e534276f57c54eee3168b7c894664fad0a4ad2808670b9c07484aa0987bf0d069210037a0fff039b2dbc691ee4d25ea73b38dceb88ad2f660fb60b23ffa189bc375236f22d7b8062c676c591dfe9841f136a1ba5b764160bfffd2a0ae1ab00b9760f1084ef2c2cacf3b149ffc2cd945915e62c451e4f8b9f8fab6da278534c74e29c835326a581db61143f6b0b6ac556eefbedc06acbcfa23201660f9a1136452ed2426764da8896e0ddeb35dc8836c571f72612ac38c52e596ab1bd73cf6cb3170de9ecbc763c21bcf5c2e642050ce0ca06d793aa4e4c65d44d791d54bbb624e576411d0df6a2f1ff766c44a48d10dc52648a5368ffee9152190883e7b4fead2e2b8aaf959e1615888d143d5c56315d418e35abcd819283ad27df1496c890fc9df7c147c564804be6efe4c37ad63c13cd0c594e329aa7b5278ca2ba55d0593ef94a8fc37d1477f18ebdddbda3eca28e4317e56b05bd839e3d16cd5960e69d1e4c93c62021f04797f558700a9e5e5db04e4551b3ef0a01b609362d1eb73ae13d55dc6c50fcd51a8c55f3762f6defc8cf38d390c2df4fcdc57d72f3c2c60b28ce08ac0bfa37af492c8a19d213828b4202f839a1a7d067e4c34f22c02f632f73eacf1967b9b2e4cf5a81efd6f98145747a19e666d42231764d5951379ecd422a3622257772d48826fa7302643f3c10e148cc23a583ffd1ccd6dca94767f3fa2912436b4d56faa27503b6babb943f5ace9ff878d9bb5dfd8e4f37dedfb4afabfdd38dd7ca8374a9be1b09799cf505cbe0893966da9ce5e98479cb43ab85234893f6595aa8f0cea1b96af4505a9f65e66cfb828c1b43cd16547fad1a39981f52b4f1093ed8afefee7b2f472a8c3a545b46bce27e9de4853471b81943efd30b64253a4a196ae52dde1514695104679e1a4467a58c0d9784f6918093c407a3ae33f828297fb6b300bdf6feb7c5e2d72814a395a5c694366af5a883282cd9bbc54668565e5316552425ff0f0f0d6d3e1f0e2ef3aa7c56b6e3dff5b9541a4ec1a33502a2feeb1bf60c424983e44d8b5a48c00ee85e7fabf8cf016738c20a36a0bc0d5af776ba7157c81088bd706c22d3aba601bdcc4316e949d6761c7dca65a23acb85c36a864fafd3c4a171849ec46f8eef7b7ab69d41a239c79dae780e614e498ee79e849c3326a9cda16c6de60c0c3fe4b15782d43ec7ce870f57188685bd1b02f45d4343fd1b2f395d70f9e4ba8c30ed0794e2f217b56b3ca03e816e79d468e4620ec4acae65241f5ef3449b9e62bae351c017111a04f991fca211f1b7946fde3482220e8193a99d7f58710bea741978f7c26fde8717ea6dcb01358b6624cad164cf7134c95d95ef9cb33354f533d6d493f6897e9a2df2c14ab824ab2a8b99c590d25a2c37a982e6ad6172c02fa995de1971b1d49ba741892d593dc904fc7a20447ae3e00ad8f25f9995f9817a2869857b099ee6381106d67fd6aa7cbe3ec4aa6a858f587211fe71c1c5fb3a0f14e33b610c3801fd3a0a9c95e1c322a4d78104ed1664ae814c9de673449aaf53c19a93dc1751b14d92372f09be4f5e276e85b8d559c5f8d0df98a9a11e2937548a12f49a3d5c231247fa6c1958a07e79430269fd1ffc7b391d7af53d86df66536482141dbdddb6235da75d46751d8010de3c34429c8e1e735c1c12006fc9405be641eaf528373fe2843b2ff8fde673040ef550cd61b708362b8b9c668db39b601205ca386304e29212baa13fb86fd2196bbcb4281697fc5e3959e5cdc8a4cbfe10dc8242f6e59822136b4c040d04ccb2a6f15c09c5833b0d82d739076d3f4b791e12223a12757f10604f1193f1ac818e608f92bfcdbaf88000e187f8c858cb91e36c0d7407cd8e2c79c29632b1d7d64c6003c9ef53b1707328dfdc291a6fca97e22e73d5070b0fbcace9f98498e1c92298e523571723701be3747ac0ae5f74e3fd8a6fd7269b70717cf23cba55d3819269f9c9362cc302c509312abbd0e0c9935b746c7c65aff0bbb555d73e712af44abb3e96479e7a79a3ff73d53fa7c6f1603838b834157e5b80f0c28a5197be74e2b87fbc118c64384718b7e03fcb49816044deeb9861dd9431129dd7c80a27aee042da7f465f46c80d704ab2b0023be8bbec2fb7019da7bcd31a0ef96a34394b300be339d50ecc30e6b0086d846ec7e7db28fd1bbbd7f4a318495994eb0d188db1da9340b25d1810da75c758bdcf5b79451d2eda60532712d3f52a44bb378f67e5687bb3cbb82715f8c59f02f74d9a56d8c13630af89f250c730eb1851bf629ed059139d5a96e49cbce74032140ee8389808e4e532eb876c93cf5618d7b9c3f7125962bd239fc689b184379b1a7574612328c29edaa690e3741e8d0ae5fe0f35ef7f2275af7d7010aa2b044489a139dff4be8019984ee47fac5b6482518f435dca665c477b0534c552a0a778533a828902ebc92f09cd1d51ccca93b8b7eef82a7fd0015b6fb7c5ff33d350abd384959246108ad8e78da82b9b566bfe780aafc8873ea9a522989289feb16122cd9cfc1bc9733b7fcc84044eac8b1c2707522fe1571f44bb21c3f04bf8e33c822b195adc5db262a7c25547cc030be098536a06509aa99b83979e5542e8ff654ffd6bf339feb227ce1cf6994f3e3a23f9fca3850883ea6cd380466a263c6d34ba968a9026c61ed1d3268a17a0ae4c4d60be885b8a0f6580606ea9e7526683ffd579700405963f9b3da7d785ead92d899b66a1421fd021c859dba48747842bdac2df8a677af07690055ee56d188aca30d4733c27e9869e7312a14055120a2a432945e2b022481a6399259dee60a55815e4620b28a9637f8007e2e880fbe707398e7d54854da3bc8bc1ec51f2459656a43948c60aba344db3deca093a5f1cb9ef27c8c7384a8c1b24574e725b27a94a36d3be20f107679fb261e224ba4afbe46b7e883c90b8cfdc750456a4c46e2a929576e49804dc639c7431832d716ba3ef9b1433a7b2b49616729c425a72b8a13112114036c84f9f1063aee4b1c30bdfd7048135919d0a1b6721b1b326bf28a829a6f9c422f0d6eca05e0a1dc625f39af3a45a15058664f59baf14b2cc007b7c166de768136d8fe01f50d3fb5816d261a77b744103c2c234dab0ad9d78490f916b2f3c9b59484eb94968c4abf4c48d4ceec5064fbaf08b0c5eb73311f911eb1e880976f52961af01ad26c98cb18e4d28c443ae778e01167519640b7dab8fddaa646ba923b4253ae12d5fb3188f6b896764dadadd1ec39f45d10bf97f563d2e6d4a4d08243d27014303ec02ae3d16a9ea12a3859e2e1e4803927788831ce0a7835ce8238ffe5fb3c4fdb59b910a12121eceeea4b2fdfdd81da051a0d5722290b3c1b2680191e10a688302aeb74617fa03a8768638397f39d7e13744ea6a629f0af55e00f2455cad0ffd6975249ca094c4ea5e59dad1f73d85d45aec41fbc032f7c9fe77bb027e50362a226583a57e1dda54797ef1440d5641b181f350ac7cb94e025744fb4b6191226d4445d4f15f440482af4fcafc28c406d4ce1bc54301a0411e87933688b8b8c2cd5f21428a8c0308321330a26210fed638f22438a042013780ac98a142a3aa0f383c80b936b7de3559ee5178166d03bf30bf42a6868d7d28d61959422f7ee87f1018153687c8c436f65b1154cdb50f3d9b3b2ad6504d0680cb8dec8acb7edc1c51e4d3faba547258956abbdd485b2fd6d7496859ba9e9d4a7273c8a050c7284fe653eb48d0d8445655f86d259f3a5c792bf5858ce8e7c520f972a471a11ea8582803e2abf5ed9beff28191434b1a14c7934374bc3537ad00ceb0ae18f1f717ee5abf192c9886042145726f9730d9e8d1368cd6787751131a25d2f148ac044bc1e15a21f5a012fabd518ff49249d088fd5156f83370995ce15985a7504e512b59b64c808bb84e238241d3bd337239b93fdc84a0b467400a4567b0aeb3c208d8471b4c02b95c2c8bf1dd3f04645647c19b4bf3cb8261e94b3b45ce12df859730f0441c6488caa4a869cad108683690323ed739d65c359eac2338b02f88c153b187a7582bb8dce2fb77193e1a43abb0d06db5370a87990969af7fcba540070a73c028537e5e1644704de87a9280e69b399d19847e2cac81a3b0f5328f96a808ec3702b61dd15e90808aa9b06c045ab2473349fc1cddd8bc8ac62a4483a7747ef5be61a26edf50d0170f1ee095c05d7d91870416ae49239581a2066a0ef7c1f2393f70e67e1ab9862de81b10625c58bc711fa66c082bbfbea1037b2755e89662263a8f19126b8e5de988ca49ca4c1b068412b24c16a716e6e345f4586839c0f43d9b268cfe2172835b659b00545c92482953f1e3118f8bd093988ef7c302608edbc9a9e6bce4596823fbc36ea777b402a68b8d3fa67468d43c62cb3fa5660fe22b8bd8e013065835791da377674ab30c3d269fca850d8180ffef84bed00ac337f1616495a9654d469a637bac32cb198eeac23f151db687ee7dc8f6ea8161441f444cc765fc7668d11b06344c059c712610de167a3a378cdf20421ff6327cf07dd8c74630778e65766e0e63cdfac1adb0e4ef8d7b8631288986923e57d52b2fbfd4369c4c20f1dd2e25ab176283f6925c6b063ce64cdbc6c61455490cc6d01560705c9bc56667e74702f5616d7683ce785151d33367e455d4a005c9a63a47a9f93cb090ee03070dc4da711971d7cd3ae601167631ceebd4206a0795b87df5778b44d21e75ee03cb53a3d1dc12f27881b45f0490533910a959b9c798fbd6a04e92c90b6e285ebb8bdc1859666970330166d7806f91e6c1d26abf8523d22606bf623235138324ee0d50c6f425b5a463cfbd63447ff128a0015231cd8266dcb437bc8e1e296c4797cf7ea03bb4aaad8ca398e77de593886acd5311958ebca3c026bfeb9141ea2a6f93a5f2ed964c001c34ebeeae5b100d0df53d556526e6d5223ecef818e1bc2a7429c4cb5369f1bca831942930dc96c06f6e95f53d2665a6cb6c72ff3b6bab06d527fe385ecc29ad10d47f0c8c1fc81ec23d6f768c2408214b3f60ff2c28096878d3201874855a112fca173b8cf85b46f0a635a72aa05cf3258d1368b61709f073b98b45d9dc172637837b9ddca204e1f05003945dd9016d37c0bc615cc2087ce8383d2b803aea574fb52367dd220318e25b6884c04c4335e9c015e874b2d1cb128c704e88603652dae56011f66c3d9bbafc7d60af53a0401828b0eedab366e3e7bd82b6f540f1550520d63e3131eaac6adefc280544f2e6d2a9e46c323ba8d3866b0f016c4fe2ada274479623782716cfe42e5c7c78959aa0f6adb3e5a59523fd5608c6daecf4df3a6c148b05a045e7513cf42f1ac46a16d3eb8b3f517b7db26da0a9b963a3bf1c20be152afc0d40b9bd8a071b0d34406861b3d1edd7b183fde0aa2d7ac274954e12dd6b6bbff324c619e5b636309c1b01cc6fc969aa41993ca8015e2dde51dd3279e096080b0e7e7fd56bd8be4abdccf9e2d94eb96469506964202aed67b9cc0128ecb1d0723c88e2919a76aec911d653308703226fa27a3e3e1e50e2f5f887b8474d31e1d394d9b5ba4f6598f3bc12a58b4f27f365919800ac32f562f0e2164ac1b9fc185dea593ecc66ff9cedd1dd8a4a856959e0f8d21c4bb411f03c4fd4cfb89a1c825a78df4dca4d0bb125bf9ea0abc484fc01c2ef258a314ca87f74c34b1c5a290f3b914295fcf39410f1d4e383181b4c274c4807361b98f1f560ca9a4f45a840416f49ebfefe4f17fdab1dc1d7bd4f53034a1984618ea3ebc5485bdb02b877dcc08a731eaa2dc356cc9ddc31a6e2f56d6b517defdaf5947d043b29a3b5310f109eea47e18c1d83c6f607ce18a602de408583d87657353419b2a82d50bf1bc54d391e5ac576878f5bbb700f6e1372c4db44c114853c3c1edd9449b983f0b8bfda8b3acfa1df852a43141f328678d8e897cc0264c4dff553aa0a9443a0719ff06f313740bc3d972d67347e5a96c8e10a896a446f154ca4f4ac5a9f7f6d5734928b62ef995a44bdd416d6d1ffeb26eda001cbf5821bb528c2384777c4499b2da766819074a5f134c4fb4dbf0bb204e29b47c1627f3bd362944f416eacda987d0e7dbd236bcd5eff8cf6ebbb85256c780083dbb6a81b04ac1d6d3dd40acbf1be6bb7c801a13612f003fa4c63b19da7a174a60587a384c2f835fa7eb1ceca56b85f0bfa109b1ce844b940f3573f16108a6df114b1d6e1ed6964d75ae79340753e7a5d365aa34b6e060bec4de1a6a14aa1c4a13fd61538cd8563fce3f40e7e00fdafcf3f79de558cecab02396d2f37f250828f55a20f1fd91151d50ca0cabc8175a79ca7a509da1eef67eeda8397ae23d6dc6c6739db04bfe04f50e9ac20bbb5428cc7432e51f649930cd5c160c6baa84eac6b04a3bb3ab14595c4f57153a841d98c9f3305e3a56cb3524e977897313ad385084e9379a1fc24e6ca4e93afc6929ff743600f3a31223a545686e7c8325b0c802d24a86bd22dc5d3e4ded70f843ad6bf8bf5d3a9dd0979c23311d3806db1445c46bc35956842141dfb603da9928d419c1d5a185ffbcbcadbf95cf585cfeae7d1f33d86df87c53411b25abf995f935593e63f50950c66bac8f91dddb347fe0892641df10b5239a658a43c9a84b016f7ef16c8989b676a7190fdeab57c323c643a9c8193199f9fb41c3e637e4e0c7a998cbf4554628f814ce6f09cce8e4e5298758e234fa8cf7d299a4371e504f782f3d8567ff3fbbed979c28ccf2330799091237342ea3dc443117b572306933a11949625e06ebb6c3f4eb5baacfa4a01c6dd59b34bda7150e739221b1710c29d1920c760ea4ba6bfd337fc5c8dcfab2f36e23c7ef045ae1100abd267dac7c17d9f9ab8d36fd26137dd3a3bf75cf76bb4eae24ec5d94aadfed43d954618ca6aa084bf84bde021af4068a8d5968cf752caed8605180020f3c2eec43b802ac07a2ca499348dad0ae12a188e775aab3246326443c88429d8ad74cdf77f49aee7ea998619802f35c132219e18a749a82100def762f01666d1510577b28c46c928a84e09ff6000ebdea48a288ef6bcbb99db08b49f98121624d2e02ad26b80c55664d6104add06145de627c3db5d300f2adc5cc2ff19e01c13a134c8f5c9d7860d9d9f41d7974bdb0a2f531d9ef0a7548794cc1cd70a351c021ebe337f8d1710100003cdfbd47332f00f66e7ffa81dca26a418560001517dc2a37e00a0ef294efb46f668d982e99ed150fe52175c623967553c92e75e3a966eef84f67d61e23373918561ac5ba63a85b23407f57d1066977d2da96a475df7b68d7f5b260d76163c3c498165aabf093117367ec4fb93aa0db6f0c9b96118532efe9e384212525ca7907c69f93611ee815be81b7cdd54c5ca11522878ca4af03271d40ad94e5a17da9c072f8444eba5e86656530177167d375051507e752be8c0d7e466a5251995cd59b19eb4754028393303b0e040f3d0616af28d6e764ec1fa0d9333e79e8ea63ac17924c1d90ad967828b66c3cb7a1566bb15dd531b7af6da6e94a9538991405d4d7193d12f30a67138766152615a514cd26d280d5f18be5e212a9ec7d5c7de5204b9adf38fd305fea48bc1510da409d208ecad13b937775d18fe9b761719699c31404aadd92d5609c27a5447ff27d9e1527ed2ebaf9801344846e7c4fa6c2336c5ddebd1ae0ca9218412abbdcfd2ffc77651d22e455249aa70dfcbba625b7952707768d8dfce04ec395edce1ad3aafbef5c292d61621ac70603c7594a2a5f88135e65803dfbd85fc25b7e245872e572f5c2fd2050026119014e6c253bd69434b4877bfbfed98a8a72011a38583b40cbd707d064a3999bf016bbc46cd4640fa35f69cf84d7f99598e8cdbaeff107488469faa5d8f0d91c4f1d1c833ad8735e8f0ec71cc660b16548932001793a2d27f627c86727b71bcd936ef93b16fe58ca95d4c934c554ecd4ba3a9cca10c4fce7133ec9a461e7f21b56bb8b1f5be00c5f99a762ec061ba1b9f325da3e3c2023229f94e4dcb1e614d34e2e732ffa58f3456551059d150f574483f1b99cfd3de155ba15b9a9bd4227e36e8f645fd8401d5f0ee1e3715cb818d6cdf46b57425f99e88a6c1236b9eabad18e9a3e203813ea27cc8411ee8a0081da011f1dae15ffa4781973e80a67a5dcaec4c76ff752e21cdebe4494ea4a5388440fcc27d5c4a0cfe79bb70d241a650375e7e811dcf933bd531f92e703e5e34d927ecc31acdb5399fc3724afe3baa1c44bfb917e1fbb239ff9ecc6cad820eac8eb0acf226ede960652f22df11a9a7b25ea4ce30b4a070214d2e173530991a01450aac02133a368c7db68d011368667b5af6d3d588ad8423a8f142211d267263d5afc533a8a364ea85fda6195ef8299c56fe27058961a6684c4ea7a3d27957d0b36f5f36827caa3db24b14938934ed5daf01cde23b7dc14014b2bf157ff569f8896fe7ac275fe2291df7f4707fd90544f5379dd0f6ad1612f210d307732f278eebe8a19860127d441e67d3889eafc50748624de8b32a0c5e0afddd5615d3e167dc7a0b22a9b81339defb68bf830af74046ecd096e9c10c9b301162182641f84a2b36137a8dc291c9e9a8c70e9d66ba9f1b2f72c69397baefdf571c805e2e9643186215f88183c4a7e785127c2233017328b87da5dc8460979b29dd25e05959a61ee40d170c3498cb52e6d3a4c400e707a83fab1e2c27b3d7310263abc166d7df4b31de8aea892f58bf4b82830eb157e300cd8f25cd9347cfc9bc5880f82f063e9a3d9d9cee7a4261a72e5c6c7298e2372b4580db51f5fac788fe52a8d1d2870f7d86275305094b76d9b4c355fb23bd2dc7171d6ddd981c2112a0574ffd517689f6c43a7f791d543b8e0de2b63f8fdba880436da2ae3b0fae415c83be8104fba4c51e86b2d05748a6615d287c70c71686d35e1505da7a2b62056794a34a763a5f130bbd506a57036e06f85f7fbf5b2e77eeb45a713bdb86ef725f725d9bcb1375c0b68345f540badf34ed33255706c3b407ddc239e51f2f16ae91acad548400a00825057e139975f1c4fae89ca4c6d6d71985ecc45feb09c081cc4122c0ac0100e770c19b98862945f6af9b6672618038f1a5d89a99caf06ad621b9f534344ff0269ac8e96b177d8a6e6f57d4329410fff387c30e67c64ccb9b3ae02bb650aa01d9be7c3f5aff99d929d682bd5808dd0432b96cd9c1c130c2e410364be2628fe7fdf49632d7cb9dd309eaf5f491a3621f81f14dd5b444b9f9d92054e2c60b84470c2f6538391e6673ca8d8e0d6b6dd8bf567d6158c900cc8096941bad4ed0fbc746be43b5968a1094c1dfe3994f1eb45a565cd4f3d9d56f56dd8e571e4ae6f0e1e773605a5b7e0138f18d32e170877c7176a1e7139243f36621886b6b26ab3264e95eef6b9e28673f8b9b2bfdaa0ddc0365c0edd0a204078cc9623933720d69d5777c356290db0934ca31d9a3be327fad246bab2c29464212bd62d6023a1020752e6d72860769186a81a1ac66aafbf258b0f3aa9b3c36e6955d8f6fb595ab7c9d211d355e675bf8af14dd2dbcbf4aa840df475644e96f753d92bc281bdc6556e3e9e972922a369b02f8469ac0458cdc0d54656410d6b440f3c43ac2a1085231a18d1771206e641984cad4c40249db0f735ac95ef409973813faf298384de6bff1b8704109831dc0897958f1a2d2c72490f8df47e4a2f74848d96aab456ba31829b82ac0158559e3708bf9b3e8831776ede1d7129f38855fd562237fec674cca96fb42eda0bdac3c22fa408b2d656b8d2f51ec21a0a8f972d167cb4e5330e19f1ae05e6a35d77a4742602ad830d50008cf86aaebe611d0976132ea590ff8b355ce28deb1dd94a4d74381bc7fe85dcdb9767a97605750e006f92cb012b93c5ab8c96a1439cfef4ad44054c66511d4b28290bbcd4b0aca32cb723161f689f08ad26aa070f39aa91d52dc818aee89a3f2ab1228532a57555abaf2f69d898c2ea4618ff4e2f939976855d48fabf9bd5b6d356839f19571a2fb9545bce8fe15d07eddaa18c6ec7dd2c6ecf6d5922cebbd5e91805c805eddf393ad5eea63c8d4ccb57e47716775b191a0256df4440d23e389482c9c059c75d447133a6ec45d9bd743f4ed112d3e01d18f568b715878f9ca103833076b1bc05b3a318969fcbf401b2b90022aa32b656bf57e2402d83892dcd3a6dea90a5c8299bde0244bb24c9eb9358ff0bca0a89caf98a8654ff99765ca4b2150c901a0157027f989be45a66dd395c594b01d80851a5ac1887a89c35ce4fa4a6e7d2e1a97508289443973be5551708d7c709dfd48663447346472dd794122d59999f57150fb3093cb9ade2ec6edfdf8ee20f00fba06c5e497499f83da52c7c44542f0de9bfd53a7c1c9fcd2db4d066c87b56c10b12d7f093d6b1f318f07cdf51d738f60432a6bfebaec4a627fc8bcf2d4c529a6b0943eb43e1be10a6f2d5c1c98c113db989197555038cbe15198d8d50e18e2ea3ff073551d3d49a2a043dda49a04c7b30a277424e4a0e3804469e1d415e04572a4e12b2bd05f7367ce15c6e4e2597cffceb1d9aa49f5fc6bfa9d02b25fa5bb99035da1f8065406f8dd5f2a3125f91fa2848f637e078e992296f63a8ecc0be782214abd6ba4299c6d38f539a9eadfb6b466bf6bf51c41019467fa7ec2204a0abb27a12d2935a4b7be8e9656792e847e9c99d3719979a63b0121a85ea96cd61bdc58a87fbaf7de225fc619ddbd8addcb2f6cfb384615dba6db845d117b64406eff33215b15d3e0fbe0ae788ba2fe20e8c6097420af88da067980d6c3e32d91b31f0685819c70380ed799013561efda6316bfeebe14a56fa11145b8acd03acb00a53a3d1ba92737e379eea7ba98ab7484a35a0f430dda2f7849235fdc2f62b2f9384ea357c54b01cb1fcd952119480d18faef3aa68016f15fe7f81e5972349e10a78a5393f3950f165be9604d846ba77174a48fcacae479ce104143c2ca27b087fc141feaef3cb24b38e4b8ffc84528627acb83e8281d2cdfba6b9eb616f399a8621c3799a48296c5c0195fb2ad5a52d7063eba03fb77a75c07981f289498cb1524237891fb4a253efd7607756090b89f6cfd36500ccc2baa6bee7fc07367df75b838586aa8c2c35a21d69fedd38366097b720c084290703eac341f1b0af173db7066c26e9e46d93759cb29809cf12065f24ea55a2485fffedd4b38906b578ad3d0431f2aa2557dbb900e90a95ad1d1c8b82a23e25666dfb416776957ed3992a8bb06b67cae0faaa63a5ee24d5ed5935624b20ae74d1e721a0b1a926ab875caa1d79ea9c875658945dca8503add5f98bbfbd24f84491083b5d6569ffffad51e9edcf81e862590c61846149d8970c201e2999bc0c5c67d74c677c61e79662c2765e1ed1ade9148b67ae4ef800c3decca843737e811156c00d339f4c047591e5a5d5b4a1dea3d55432247b7df104a83302e74191e104e50bf6beb262391f761293ca090ebaf50bb8f3bc615e985e2337506a4e578652b407c0a31d114c114668c74d476ec40645599a4f3e401cc791d55110bd61aa951ab7b8f66f4aa346cfe252d94a7e77257ab125bf6a3c18f696adee490c14e591b6973e127604de96e7d9d6fce254adb1af34e36e63f524174a77b75863742d1c7068c6e14244817e881252a235ffd97624aa01a1a19025b330c7f37258246878fb5188c54ab74a7d4583d375249ca631b5355fd43fb72fc96f30286120750f1db283315c4ccdad39582dc5c90c1557e0e5610ca740cac41c7626cf08966dca89c200a3248948dc22005c67873634344732c5466322a95759c1f6834cab10d16577f187b053107e5a60d6aa09454968d85864f79e0d5a7648332bb7bd0fc01306b8e60baf616e08af4d93e9ad7a7611a5569f6180c0c34f64638fd51e63b53f2838bfe8547f7dbc8f19a84fd8a8dada75fb46469322cad3bde5790ba5b4935e4f3019624072fa9be276282feaea582975eceb8ef93a8e2a311e6cd78090dc1dd93c04ed3f38638430ff4c86e8cc6029abc99c14f980b1441dfedc3970644bfad33f5e64e8a02a40982b102c014ab9f4f29a94ceab5ca56666740448a23400b84eec866b8c2d3ddbe2cbbdcedd0ddb6e081099b005ad8dae96ea8b491147085221202398409263c84efbec3cfe1ff3d106fcd72f78d8bd2a580a781b3801aa3d31ffd568867fa6433c5a750122543483cd85d5ca092d6f4fa3234f112cf5c3258dc74d94d1a876a37bef4a3a4b46e4db8fa09c9196822b8a104ef6ccbf0804b2ff4fcf2280e3358b0e0e7f43759b9623b04ef018cc5c35ee82c3cbfd5b35e74260f5e8e6d86724e6269bc71f1151cf1068923488a1fd9cededce12625231b99439cee49204d00f603c5bc47dc6492f6f0d423b65b0e5a0a467273aa95a249cb3f03137862e82d6bf7924a5db7de6cade0a274a1f694a5c9027aabaaf6146ebe73a8fdd244a025081103bb3534a24ff24f5f235d42f743663e556d574c65da325782512269e661c3b7f16b0be05f88f782c9dc5879ce59687b6b233f75a8ceb45cdce84e35b9a65736e0446e44a4996a285a659899cfc92a548d49d7ae17a9cb1681655cf508b75abd9843c8c775c4a2b95e6ce310c73935a2f6fbe3f65d7dc2b115ef49fe743b1815bc3cd675f7146fd431f38c4a79c71411e4ed4cf7287ea942b9da02d1dc27628558e3612f8a62ca935004c2d9ab3e1f7dc01e22c5a390b73989698501edd444be828ac2a4b7f666e492779f83a74c9f510e0d0f67105b2a38af400c0f306a14b8b64dd61d8cadebb772cdcf34db697c77ba4b7cfdb95873cc99cfeb2f77947a1b7ed20dc30da7352d95f8f9518909bee0c3ecfd51840e34ff959c32919f3e4dc6fb3551479c368020a1d2ea681012ba52ea9cba4f52fe30a44d9091de0f3535a390884aac4ef7ee27d00bfd34567bc27d693911d1eec0a81f85a0039b83bc621af7eb084d8b11fa66f3a4d08c11c1f7619be3d96c6a96a4a1a4e77b9afc626e8593fb77767aec642ca2ed042aa43f980fa851e536496f91f828a42180788fc50572921f8d849474510f9eeea200c4e1339c1c216c05d6dab1fde36be8c1f5627dcbc1e506693cc3378fcd908205295334e58fa2aa75852ca2691d942f57f2f559617598cbfaf24dfc477a2522258b05cf1829aba19d7fda1aad2725080f020194228901d8b770ec473d4e10d0a99c32cb09d226cc3d035314ca8cefb8c498de39b332cc1f614aa29485aafd77d3bf5264aeb8dbcdc8949ec699cb1531bf1f067ee5c975d76a6bc18cc5b198d2631cfde9d4041e3681eddf6a36b13fe48986ad7b6e15116cac37d7880ed2d3a4a522dfea677c4b84bad716dc5badd19b56ef835ca7fdcd3fbee3eecfc026c3eebc644d64f54423e94e72b877ffc4dc5d9544edceb259984ed4ffa8e92e3551fb35a69d0b026ba89aea8361a86d02fb794e5f00e61d20cf4569b06703b0858ace9542a740eb860cc78271ad432ef27c07f1455d39d44789b09e002166cde4ec4d6163d0f2e0d3dd8083b336dddffd7d32d028146c903b12ca69b02541d5d111afd516dc7653aee93905d8e46ae313e41388d8f8c817244d28671def8fdf40932689c7d687e18b61c5cb958aba8d5363d65a5b0daa42768dfe709d81f4008c070dc3667abf947bde6d56d81a0714d7bc8e58b8ee819b858580812229dd155b63d684b379023d463052a4e3210d76e693dce4ed3efcc0ba5e8716e0ca0a45ee24b1de284e09c9b7485af1079a06b9c333dfeb87c60d1d59882bd95ca71f3900b486aa53cac642eee4c7cc38a6c1ab9aed5a366689e3dddbca5d7370d8c6d3df91c85acfc9d358b7f8456d61a4fbb8fdf8c920a02ae9af28ff2f37159ad26e86dd7569f1eeede442262d286bdcdd307c2248c7b1cfb97d3ebf3f55adb9004d2ec4783444138947cde42ef6e0533a0b62055d0cca94e26d3be2cd8e234e3b344082eb33eec3fc6f8de5491cc2ebec2cb1e0836b006333869902e5b4ead73ab565cf2fa7d1ecd0a13b8209ac9edf096e83b3a01f6393d7e955f777889333f873507c8ebcef89d45c7aed698d098fa5b4a03db57c91dad97913d659588a240a6bf1cf6e5e1fa73dc8d44f2fb9ac936ec3b66ee553659d8919faf7479f9f240eade452739e0985f03a7400c387498a471f960d6eb3e2256ace1d1918b2cab0f66da1a66185bbf1a75e096fd971c36636103b936edbfbca60ee9e49dd51e1a1bf4ffe73d0cc8b532873dfdbdc5e5578e600d34b293210e1349d1f3ffbb6cc0549fdcfa52f659e038b749adc008524a08b359adf8d027bc062fed9ff52b2e327c5ccf2340906b153e6b2fa56f6a4b721cd3b727ab0d1eb1cbe8dbb9a9db84ee3c012962caee80528c9ad33576d287f21734272d238b39e937484dfcf590c3b2054c0acde526042e7010e17c43cd64cb842e39f2c83fba0a50a1727438f558185ad9f74ab42182661a4f6fbb3ff655edd3a9b323df1f0b39832fa64c316e99ba4dd91563c4d9490bbb4f558da9aa81f5e3f37157981cc960a80f90dbb04ea7d0a15a14a20bef0940a0bb78f17ecf8fc10413cf32f7622c426b7da6089604d070066e1b5bf7d69cdf59329e3b8f8cd2d5524429f3ab323578852b77a01064391573fb29574fc266e8626010b970e063778cdfe584660c6a649fad24c08789e5f6f9828c1164772e3406d5332ae3a73a92d3c1408aac64c13de7a3e1ff615b4a0198defdc8126f8de6af47aa44fe7e6b5eb7d95163861062fc1cd4b337d7651c2d80cb0a9b9e47ff53b6a694af87c1720a2e4281e84afe756b68435ccbb1aeef7159aa39a5648ede6c9585847a3f2484c2b9c745b1c1d972959ac855dd05cd70f89b60ca07cb252d82151f0a7514bb75f8ff5d7bc9c9257c12a171df828b02d989ab2f875528b01d29f2693105787c8982a02ede9b31db5e20e804e27b3526c1f9dbaa3b1c6cac7f508151b51abd0adc05bff7a725bab001107539726f75ba19630e80780bd1cc62411ccfed677e19ab6844391ef7db6e7b113da101f8f1530b7ea06e67dda763e221ab49a2f7b0b751d93cfefdc6bb569d1e5af142f8f09469ed49a2bfb4b224adabd0ecfedc5c1fca21d5a0684c6a8aafe5229ed19b48078d4598a5bcda3209739d19469952f53fa5fffd3c0266b4ccb114b0bde781a16ae03d9bbff48f573de1e59df2a2a344d4d1d851acc73d9ce461a465863a425df1d9455cfbed80ddaf2460f4fab2ae55045132f35929632de63f1694f632b9a6747081dd2564916faf9a6c1dfbed6d320175dd854c362b978d5e640872daa65649e1ce913756d2b17a24c675a39341bbcf43038442f878216fbc0323ed356ff9f9587829ce4a8013ac1a651d2d5606bc62e55e167995e0d5cb3b1e4145a18898cfaa40be8e0a4b4eabbf06c8f72c55426abee9a3cb38d7d4a3f02d172791c935a7a4a3da6a03ae418c942578cded52300c8e26927732721c7b49662471651c46c796094b1f11a3b1db2a49fa302deabd691e97fb3f3ba40b6d542e40af16debcae289db5e03c8aa76bc7bec7a726d1580da97eef48b6de3724bfe28efd8efb51302d05058af30d7308c3a14e68d860a52692b98cd8fb64b834d67b6e8113ad931a0ba882e4a16048992594f21f8b48608da4b6f327f3b7d6b9b17742ba812ab5a406951661e70383a7dac16248997f92ec450164aa957378da3bfbb2728f9b0b82a0b64c59bdfe40f761df2ed2727574ef2c799a2ec4e8a6f990ddcd854e0143dd84c465fce9e9fd2bf37e0c4b4e63c5c1a4701791272e66ccb08ab3be8db4ea7cc7249bba0a0e0377b681bc0bf01badbba6816997c3ef5be86878ef92fd1c20c0e4b9ca26cf38fa5e7ec4ab2bebb4fb65b28287d9ae03d95056aed3b7a23a22dafe14910f4ac286b9115d174b85f0d85f148185c666df2782fc4a2b9aae1ed7adeb35cceae3336e310f2fba9ee9c94c69161ee6cb822f726ee1a118bac6d0899c41f6be80b69fa3bc63017e9841295c00b42b6707bc2a2fd304d6fadb077b06539c95f8cae4a66a97ed6aab26548217f62592da16befc7077d734fd9db552ca2410100b9f5f120198e2eec30658a2a1c1b1909f0edc242c2c42fe1379f7dbb1d0b8d5bb90a56ece15ebc8f0aeddd511edb0c7fce14fb6fde5aca5eceb7ab2a3f683b60050f46fe8012819d0522ce285ee3a23ecfdf19e6f2a77c2aa35193689faed41d98cfcaf4e129851d48494020ae395b164d303ee5e7f976fe1f2120f100692bcb9ac97440a410c9c177a6c5d1b64fed62ee428398569d89d16fe29e167e2a3c1abcda8f0a101288476efed5e7052063c99d9d13baa8937a604408bad9e0899b93c5adcbd076273c825fbef660ac8b7aaabb79115d6ffb20310392c08478f01c4df7db2ee10ca88619d6244b51005350c3c2f74029567bc78cd4762f7317cc1a54090769d03f85f3911b97791f626e9b7e0dd2fbeaacc93a06d991959faf08ccfc735ccb94cec31a5a2bb5d7dcf98907daae49c2631efdc972b667a91ecb27dda02232bb3ae26b87b7d5dbcc652c3625e3c3a48ec6ffa4e3cb194ad734216be58a23fecd271fd669f618cf95a2732fde669ab95d6496afb41d468e6ba40c2963844a5fd1d8d00f79e1968828e27601f912495a67b71a8746475e78deaf90c60bfaf3be14932be25bf9d666b566406b8250c5ac467d8fb63bfa95f92f86e424ba8f45cc14b37273602fb5933f8aacd3164fe5f52ea87211429da8c00b01630fb7fbf33775adda0db56a5e3063f1a2ff8aeb7bc3cd2bbb47b75610a24ad68898605a9ecd22142c013db1dc3c8f802264e1f91c96efab42ff96f84b8417753b39e2dcb7f589e2c9f5c0f4632c9982a5ecf00f7d38d292feba65f29d04c4b82e0377ef3b7f42de8427bcbabd0c35f6a04526bba991cb76674737d4fa15ccb593ee48f7f2a193400ca8c95923297d53078e2e449b1c107c42b09fb963825d01619a5b748e79ddffdeda848f1129d695ae29fbf83c0587c106a9dc999196b8f5ab24238efef3c03282afe0abd29a991238b0eee7c112daac891fa7db16485d564652781b87fb36efaf483d20c047cd28d9a2a14dcddccd2ece7353a1d3338f69a48ab75cb9ef6b1526b8fbb4443e36121af487bb555374f71fd1e6736e80a932dd902b5b7d8a2d8ecdfcab1bc1b3f8ca20d6bae07399c594496d612d2dadeb9959c05b9318e5122995bad4e823a3c115ce467430d3e42e1f907342bdbbce8120b33973ca2693ad9aea8ba610c8fef69cf7a4637aaea384cab4ee319cd196764fcded8cb2c36fda901d67e0b8de26f8d237e654a60ed4e8bc6b1391cff8e211922aa6c9c4891315d089911b2efd554439fbb5e72c0e4b17f8518d828d0aa4a03d1f84aebf8e2f41bfd8539b6b303981233404b49786f38e42e4a6d5cecd35fe597b55b645f30ddea01b8ff96f5163a2c9013cd9bef8d29ca31ddba6b63ddb3433e0a5102e7c34457f94a84867a2ee5a25f8f60339d88ac9f9f9f2b59e6fce0000dfb0b442c54bc6a293e05098e98b3ba43664e18514e66228177d5043c7e156db983b27b5e0369bafc87033289ed10d7d02b17cd33ca88e3dd3719147ba9f9ea51f64b2b392a383d0c045d10716db4a6f4cdbae052b0f82ef8306d3a3a7076c0b9700bda147142e111e77e527fec21210a35b42162aaae7a2f85f6ed6f7c3df70c985ba2e388c628edb0ee891783dd64371ac3c889192383748371d4c617702b7fcf78575374fde0e9f964e431b8f210b33c2faccc7389457add5dcaf103cdf4a867d1f0656c8a2ddedde3e1e439c703e4c09abc32e3f4e08f8225c467083981eb5e8628a6fa59a936c78b08b8adc055d2b2cda0479055c8db8b651e6a7ec61b9be1fe90e91fb83b96a6814c6474c7fa3bd9ddfc7b13d725dff7e6ba010b01d246b5853118b1231a50935ab33c5095ed04ab3dd021d92dd6dd97c75f64a810902a3daa17486bf53fb4a1f1db17aef6ec84b7342d6d6b70a1225f2f7038e9d517547aec3e11825c3653943a14443e26e1dd95c6062bcda3219d8790a56ea16de10ecbe53ac8aeab20bb38efe3efc0b7425b5231d3c6615452672e789768064de8d17002ed1e21aa4ee2732ecfa70fa79e08d32a0299e2073eda15ee209eb4a949e9d7a6a142e877242fef62d7d5237ca03ddb943d857da566f755d9b6d395a517713f55cb26173cdb1a80afa5a7d177d540aedc7d7e1d08ee0ee920ab249f00dc28f3c5e356ca878d4c3860cae6788105e83b2c3ab6773f275aec2b8d76065055e31478302dff0d01cdf0ca58bd42a4cbaab13eb1e5333ba4c3c3ef69ee841467d6eee926ce36742c4e588d79ee12b479e0f9fbf0f15846252865e796975de4be737374e245c96e61e6d5c23d12dcd7f6cf360c8fa5897ce2c490f487cc2a77eba57fdb1364677248574e856c26709988a401cde1da07aef1d7b33e1ca983785b13c3c6e67ae33087175a2e0189f5992af1e357b156c2782d42351a1a28bc27a6521ef86b7faec8d0e1aa818b8b7b2a6f0a052604173675d8042d06572d7c3854ebd2f1c08106ea06e4e502033a9fb7780597f9556d8eb817b6b687d65b68dde268a4c579f8610d47ac9cb08b906319532710f43d07447fb0e37974fb6ef04550f39790300423208c4c5889f58d22fe26e20195082840c91cf2f31856e0aff18aea9a407129bc44c9a040d9002dd015d5305257b8d046b8ce0f7e58ec9f47e059c03b432ed2939a7171166055e9712da4e76d9eeaf28305eb907bcd8767ae36a53d0d1c95e0dbd167ad23e637be3f2d33403c5bd354e08aab8acd1cb583359c981c852dfcbfb0c81dbc54971d76362414de108c2bc87582b230caa4352c95e242d78093207f431d3d662aaa838dcb228f9321dd44c1bafeb4a671edd363dd9034dcc1d62792a0cb100afd71312a0688989c6efe5a6375b83984cebc651ead5decbc1cd747fe4c209faff19fa51e1137dc23f30647198124e60a1753a22fb2e1eef3d734e715a6f5fce133f766e368f3ccedf06a37019939818445d005a68872e68f2838231caf66c80d228ee585e9f893ca8f086b2bd07052096fee2da5548e2fce6a3ead5d99cdd975aabc9b170af8fcf818c8bed879ce8eecb77e3a65f2b1abce0d200c6302839b455812da2dcfed9e2a1ce1df61c4d8f6ef14995bbe87818c0c511349350b763707230cba1bf57d196f6150cc3641a9155bceaffb8463f67a75d7ce18b71451749129af75d95fcdbb99e1cedea338cac7ceb72541b191e52f73b5176c4b78d9a922b25d9d98bd78b7ffacbd275c620493f7012630d83888c10b5309b93bff87a7cdc93eebeee3fa34813fee6ab0fd7363c2dca7aadabd48f5de23bd612016a510e9dbf971855204048014d7e439e040f990688803b60fff20ecf53ef2c05f2632ab59f71749d20524564f47438601d669f685209172324011f0d01316ec663a3964474519da5e20c1a099c701bc1f916b1490c5631182d68757547ad9c336219ff9af8db07307adb867d561951ff547772a653c3b48513a29edeb13ba9ccbdcf1411cd61c3b3a4239aae1c37234979f7bd219df61b4090b884df5ae88eeb92b0f95ad45abe1a216434b86e90d84a2eb0ea2e7d602f19ce32bac5a6f4aff8af5119eb3b3426bf9d2a3b96df67182b7d4b36511f03114f9097781c3cfa134e0e31b4168e25e9ddc4afc6c146a34112693d21befe74132da83b01ab6dbba0fa8f9d51452291abca329cac6458595223eee5af8e3a1bd10776196f9ef916596f7044c3bc23cc88f6e4c0325b08a06f6bacde2bb3440725d18efe3fa11b479eeca089219a6a6e2ee1e1d82a0f6b10cc632c9a6cca563411accb6a36bf4e62bb8e585985d264d702e5a4e6c6795bd0582e40fde8467273c567076b28b5e3ad925d5aa6799fd86ba624d05a08ee13f930c14a4ddf46479e595c77adaeed506c85816e44e6dfd0b83e81ac4863a4ae36364a0582a7c87e9b152076689ab46d71a345245e24b91c44e06fd70ba50e8f2a128c54069ba14a76a5abe4f37d5fccae1c208dd633677a72152448e6dc5ee7a61efcee2c44fd1a611177493c8f4a8191da78e60f41480b8b5004e47303397f41e3e45dc33cfc43ebeac7b56b82be55471fd0f7dc895b539c8d9fcb2377043fad5a58b590d2e9677c842676d3eb3a3a6ae0a42d253aca623c4f99809c928e8d1cb5aa3e0d91de0b71756e7d57d500b07f60657b04b260ea73e32f70dd0b5d97b015bf6a1a1ffbcba7e76fc439a98eeafa04b69b1bc3db27723a0e3ba760d8d75e870709cc899a697e67557e04b77ad2255c830691116be78b32c53979db08ccc450bb256bb521de06763c4f4bd8795a0602042973434acfbce05a2195ad1a80846c6aefa01caa1919a01835b59519536146a3f7b1e2e44ec6542e5eed59a2f68e081f30ffb6d7f6c140c50f71010794bd9ccb7610b5005f23c52da582b1e47af5e5369c4095b810dc610eb0c3f0123da887e733ac29c5864e86dc75f65bbef67713cf009492438f47e2058d02e325dafb09ec953927f4346862678b144c2ef2200ce03045c13cb4f11b4808b9ff3308cc66e0761d6c614ca6894c98689478397a7b1b0db477b9771d2cb69bdce8e81c7eaebf8dfcb3c2d83da0e8f4256e6e077833a1beaf9f4477d39685024505ba057d013da07da6ca8043ce6991736a9914346ba7782207b48e642b06f48c9adb17f1c4f5f9ab525de0bebb26ac5f6598bd3e4273d7f20a02abad2b6b84ac3b23c00b674fe21ac4f23023ae4e57cd77d1e082e710ad8783f64e18ecd00a7518918a974cacfc5204d744fdd083e99fdd2344b72f0ae29250e53637d21a797662305ce59b4d7d9c7532dfdb6ff5eda209d3a39b08e4ef108dc5a93a0d7868f8156d968b58aa53edd5a278b07444f6660847f4deec702ba0883af594c3c863076e1dc16841a4c5782720b9aa083acf021b91937190c0095f40d43d9ab2a25ae128b712d24d447f129fdace820feecd95c846c354ed4754a3780fbce7d67474a79686eb0269bfefc37620b1a972772980e71d66cb08cebfb2407fc2785f21bfd5c50c5888a1d5b73ddcb20129a83437b5c1a3adc4fd3c0fc3072170037d80b7f6773cc656b6710a2fe75b501bb83f8b25eed63a5345ae9ba6028ee07dcf77ca19c72540c6a23b60135a36d800780a9fd4235ec9182a6f20525f29cf79f4d7c8a50e09ac40dae18b757de34e3cdeef037093f1ef08cb79d0dd769a6c90f3f495ba24c57c6e04cdcf0ea612c35dd606958819139ea32d91a0a98241d58582249512088d27af379a614207a62e1cfefd63eb415b03089be78639cd31be241c14a49bccd33bc685adb5ace928448373a4cf0b7483821a2cbd8b7cc62ff1540a5df2f47187176bfc3f44cf544666546b2afb3ea490ac5124b0221d14ab05deceec102e2afa230b96cbf325f964a4785c54e8dc1f106fb4539d5c7930a22314898aaf5b80fa698db29e772dd144560102d21842dea8d8bef6490e985c3819aad56caed37fcc2df117529a114a410611ecfdef7bce493840ccb1312e222c725f55239d50550d7173e8ccf5091c4ab59f1a65fa9182f6bfeaa629b7fb23257b84d89cfb56347689192a56ce86bba4536c84b44ceb792d09162b8487fd0567fe2167298d4694c58f386ad2ac3222cbaae93ed7463a773713d250cf750fb78e714afe1661c6f162837b4247b7ce79df48c86d58ac8b7a60729a0ed11d08f8d6ec5543fa1b7db2fab61f508948111072e1c3649c9ecbf9345fb68da00e5331b0c466a7af9af8014595b0d43a8a61b99bb368364646f220bf0ce5703315c2040f432be276c4e513ea9f5bcb245bfc4b4b3b0dfd91a474868c7087350669382f4df4f484b60a72a16144ab8712c17c49d848d0c537c28e05061403aae719bb90f2499cc0ed6d0353bb7c81e31682b6343d1b05df1578f08313e20d0b81efcd77e2e5abe30db8c4ea51ffecdc1e854045d3805e7c27ba19c9163cab2c790d95b252ce1dca4b3770b271915af4954cd72d57f6f78143027da030013b0f6eb107730d3554ebb99b645b39c2d405ff646fd939f68b380e13a673e78e0d7fd9d738ee9d2e1d9082e518cb308f7fbc71515da0675a8adef4550835d99de7b19cf17c1974f558dc36aaf9034dd8d67363ef43196ca5f95f1ec8accc7e87fa1e11abea1fbd5e492c328b0cd82038a952d955db1741ba201df211cb07bde486bf0d1ef6ebc24d810d1651ce73e3392c944b29b249eb2cdd71c990daab375235e70ea79eaacba9719c63039a3489adb958ac6d0a78430be04ddd2637d75d797c289dc549efecfe5fb0089dd39fa756d55ddf21b846b844e252873afb00b73b84a625dae26d2415bd1ba800c50798766de694802c9138d3b60b8e41b90f3a9f4d0d155e69cf37c8a00d0390da78a41d70b0bd7424314d33acd28d290ed1fa2fe032d16bcff588af56a97609c83d7e8b947db241c444e8b441c4a8ce27f522aab28091e91172319518edde15f24a8a060383415dd59e830a073da70bc9541009013222eb5cc1e7e492694a290d529789d8f20848d4422d2adeff598d16f3c5788db1feb8c53d1288ab5a33679ae8dc37dbd9cae73cf5f679ff87b4321fd5c83c8fe109ec6f9155583d86d8f95e7bff3a76c1660e1dc5e230fb395f23a8f2e0f7ab15ec92cd8e000746b740085fbc27a0e5b65caa28620cce59311408379e832f3d26e3b7730c681128072fe48bdfa2289dc90304929f9f76c748c6154cf8fec565ae99feddedff04064c9d3c68b42b0487067d524f7a9bb1ba2b7607e705cc6280c257f0eb42406a1f0604178729d61173c652c35119f61c058defc030302c424902ae74dc05fc2c0bc4d873ed4d52d90f1db07645480ccd406e0e689f9146f0a0fd9b6c26f178de2f08796048303859c0f3fab0bc3b5600945da4f056e75f3e0cc1f9684142e1a03de01eada0b0b5be336a2bde02cf0bbb0d3133142df07d28bee034a245895dc5f0a79dee9de736c598abb4a6f428a19cb98bab7afa64390142b55d233f85c4e8da21f4ce83ee5a8186aca4c27cdccdf872769f920223f73290eb3796a15d1e5aadece9aae34ad2763a196f1670cbdfd4525c8695f73047d228a41c598ae5641f0aa1d30289b3d23d021cf6b0cf2307cf01f11be61c0b4b5811aec4d09e61cc3e8efd8c4336195117ecbdb87303ad8db3be08ef36787b92414c85bf37a45ee47e1e3f85216aaab7d9b062dfc15e1f0dd627a9e61d1a24cf288e5e6b01ced71776c16e76f08cb6e300537d86adf4c7af9b28b0564ce21326f6a1a3eb05fec36513d305f618b8a56dcd4996a4ba318b5fbc28f9030660d5240a5a6ce272a3b5fed8e1a09fafb3b5ea629d95b7e15c1a319ed1742025379e3e67a0ad561472229e8b8bf948f6b9128969ac5f65205695f401f13872f92f6638f9c8fc20dd19eb71d6625e22be9ce65a0efba0f50da14d3b70cf2c08d098e61be52891da1787de005bc061c7039d6e5c1ef1aefda508bbc281e9c2dcb46eb9094811688ce8629e8e5570a3a95835dc4494d734fb972d830d65f70aed146b3ae94427d9abfacf0c5a16dd2cc13faccc8cede035147d08a1bb37f4f213f7987e4f6d7f278df2ecbde082177cb0d01312d72e8e498baef5c7c9b9e19882799f9a9d5007d4e107ac657b43e613ea58a7b1194642758b7b7097f9f968846e1351c1aba9c606b1c0baf2a77035ced80a44f54b38d92b7cf090dae3c671b17fc36aa98832d5ec1bf72de549e63cc18d3ea2ae9c6a23e00e3ef966edb5f1fb90d2064fdad05771d84ac77c1a70797f369abdb969f414b4f433d1eec826f3fa246543abd5166d834e4bb5d4012af4d8956b6b5abfd8e604f49300a9d5b9fcdcb946be6937521e06bc1158df567e56f81cc43b2633ed271deaad7146969166babd8a208382e8eb9ae08925fe0085ac4bdfd6277a189d39283c63c370f6236fd90fde168982fc6846e5788128819bbcfb899c2c77828e18bbee2c83a97a8f4e9eb4c7d1dae8cc05adc0722a7af1858fc5e02b64e94286e40e84bfe33aae1b894207ea6ed7c7af54c4274b8a5ebb27a0548b2ff902d5d008ffe7131941deda2eb34d615e5f150f9a5e537187703a99dce23a0e65ece781e188b0819bc343e7572f87c23b532e56de603b536046dfd97bfaa86b26b4f92f4fa060e58aedc8c8ac5629bc8cfb61c9768ad3de4edbece96c1b0e69adc089ca86e16dbfd73e3e160de797f69686e262667410ebe2381a8206c521edf2b8bd1e2b5cb5ac0918ddc935644026f12d8799655d1112188eb2a631549719c36af0b8135dfc487316545c64731ffe31bc524b4c2672ae6ce8f987bfa9000cd884f9a845d2da719902ba4dc15d09243131c1cb96a13b498b591ce1cf7c87ba473d4907d5616d1bd6a168b2965a759b0974ed9e7c88ff4d2fcdd54d45a9307de5bfcb18ef66f41db407d1beaf3acb7481450b17ee44028aab09119d4806cb8b604732341698fd0974b6ee815cd190f3367928bdb1041270ea8f55e5f6dcaeb681e6aff1a60fff313c4ceb570ce7feb0fcaf8078bcc4570fd3a06051499cda015c8736b128ea03df93a037f7fafafe8b568995b83b29a15981828e6b63b78d690ac62c63bce4fbdb0a420b3226f06332d364650973a204b56e7ef72414e8138ab932477193e80079079b500db35f757e7bdb6887cd0df239233a6d1e6835113d362731319694b7061d01dba4644b897b7e01f3dc19689fd5f6dd0c47821d87c3204857e66e71a8d3b77d29fa9cc9d4d9a6c870ca69822d7a6ed3caf4a509595b8bdd6d15c12cbdeab9a6f5002edd2039a331acb7db82247fc396bb053bb2fae47a18a80565132997f1418ef8edc43c3f21028d6fa3f1899591421aa8d67ad4e870299139372ccb1c197f2c5e4189bbd2aef68f6c087457a216f00b3f05794c74d7de2ef4be7275faf2439d36587d2c8f10bb036e3d46c0d151df14ec3c84fbe991ef4b190e1ea3baee8bd4fd676e8395a0bec967e99c02ac3f7d88093dbb048fe5edb2095e6ec8e7772536f1af38bdb388bd47fdd1f3217cb71ade23d23957c782b9a6ba4f0384733f6c816752220912bbf0394a0acac0a480c01845dc3f6fd44af5698485238342ab0f1252963f2c53c3f8a62c384ef99f9bd98b6d89cbbab47d02c2942bd0ae9b0d7fc0cc51c3e3b0c3c4103e24620fb7b89ef8ceadf861702348cb6f59111d330855074e4582621f587f7d2e82fca95b3ee61f99e8c03c3021f1c9382c46ec81b443e5c5b53d49dccba9eb4f6132d481b022c449bef16511f60b49e0275b583c018e4e45fae714f5ab52fe9e29bd6fe063a252af100387f1b1b846f4138773b6d44443f8aba9db6cc8e94771cedcc52fd833b3c4277293ba0d2fc910843cbbf5bdc17c353439bd72115f02a013df4bb50bb58f1c22417fc24d39a0fbf98dff3ce61e4300ec914550307ce5727b64da73e2731cbb60d429ebe575f5b22b961509bd6b1e0928f8c2068b2f471514f135bd5c63c66e8938052795972b3d05193f732f7430e19d48567b86c9753bbfa956b414cdc8973fb4b5c949b397620b9195e2f2fd374a8fcbf68ffefc7674e6f52ffe1b49c3628fcbd9444c0e5467c1f341c6f45c92c2295055b2c2de1af766fc8d344d4162c30f5332cd3d94db6805a599a3e3242c4754dbdfeeba20c599f86db9dee1f02240412f500769747a580c63354afe96476a61619adfab33356ec1f836004a269389e370f2df75310699af5bc2ba4ee35616b303fae0a103c9ad9b39674cf882761d5d6dbc604fceefb314fc9f060a108c5d05731a78116a9133df09dd7a435fa47012e42ec70dce3ad471b3c5870fceaffa701683035ea684ee018b7bfe75285a443a96498b9392974a60ef991086c04c191e66ef093ef95aa2383b2ad471d3702d60786d6dbde58efca77e6759a51584e59bd8c2345d3a95d384de1c679ffe19e35d93bc7e04020405024db8733e3a556856ef4f8b11d2d029c3e289634417625c455e04c0055ebf6b83b200cb538986b32d23ed83e6ec99cd19bfaa5d31bbc2e32389589015622584059b67cd89857a9dccd97ba0860fb40cfde94f263a89979abdf70f2f899c8b1a20dad1701b9b8c665f14a8754b7904ff2bb3d057d62b3056192d369dbc03bca0fc5544b457663c0cc483d7992e8b19100733d9536b38a60cdf06c3ba8940feb8976923b19b788b43b93b1a2ab4bba1e0b590de87be134320e525e2fbf31929b62bed0c50c74b28e08d3a1b1c3052c0d3efbe0b6885f152d55d93171cbdfca5fae1fd05c8b1d785aaf1a38bc668e305e2ceacfc48470e5dc43fa51d514b968e0c55ea1229a198ce859a78b8a76de69c3f703b99535530d3eb2d75116e011aff6452fafe273116651ce3f2f4351278895eec6f99f3ddc503ccb409386b2fa3319f44ec3858633bb80f6146d9aef670e738b7762dcc57efa4bbebf07371c17aead1569c163be561b195e4f8928fdd8278b80a4e43af630d8b8da183798d5c671656021a0efd0e879506ba74454a0b26a382575130cb98c0913122180b738ed5c71702e27ca5ee6f2fd40d759b9ccce568de024b58adbdde7cd9b2815709636f1b5bfe2d95dfc331302b043cd4dde40517068550397a0feb41cb10a92b527f79f7f70fa6161303ffd2bad62824150e5ecb3f31c3768748c2abf80cebbf5a9d2c59e3e82dc310702d16ef2437645544092fece9665f1414dbc0e8734e66e2b3566775fc0de714494f96ef814e1412a2672de80819b5bec2d2190176edae3fd98d1c05d9223e392df91f90ccc191f9a9d08a7df2fb7d742ea48617647ec0ad082e993e5d0ce15884aa1c260db220702b322efcc1b7469b1d2261172d18bb5d768c65e89b1fcea1f870b103f89f6f8d2a03435c0ae34e0b935d0efe386e623341f257aaf7852a98ef9d683b247dda23934a83811fb0bfaf1510741535ce06662b4766919e3f225a05b633d053b406cc436c73a9968938a614cfbacdd2292d6199080b9502ed83d4549fc8f39f438d652d54ec69feed91ea99a81538e48a1b91625944565225d6e84ec16f88a552fa4156b0dec679a245c55383ecb967afb8ebb029457bf9daa55c150631ed245b80e90d0173fbcc7f7c0cb6cbb9fe8c772503b6477aba225f0699c13a6a1d663f36a11c7fa82bfcfc088f077c6e72dfda50f96abe6d56fd6991f8aebfe74779aee6a40550d02cb016371a21da478b148d283079127c7b130504aac47fe2d3acd3ee29f700aad7c1179c3831120663623b17c7b83b238c279f9b6cd1d340ffa43a3a5c466622bdf6986ffb8d5d3896d9b31eb2cbb62a168a6d25cd1bc490b524b495e0da9868620999b0d501f4a8f69a2cc4a3d6b0bcf15c40f51d3a46297bdac593c9fc60a9ba2a4e8350afdd7586ab7e23ee807b15bb26138b58a0f60af793c760619a447cc235e9c105ee29169f294cab626cf1dba48d8cfada4f3aa3f46a81165fe25ea17137fbc30a94fe9bc606dfc22c500bc64faf3556c6fc2c066eeda44ee1c00ae4a97caefda3e7186de11db7d2c29e05fb2b9d798547d7d7eba889c9106b36290f99f09d282c986ba373ccbe8be3273152378d01495fca3ac9884369bd29d3e5b938f9bf9c623cf3677b7867097a6fedf96577f3fe002bf6be79d3a79a4a70b9cc5b245593d30d6c10afdd5c5458804bce71cc5f26d05dfeefd52e19fb590ce26cb0e019d939dd7a98a3de9d5f90d27c28bc01d3dad9912493b80ef50bd9c968cdc9f889dbee9202e34e5adf93ce2975d0003b1af58c7aa9ef0a88cf42b31098ef6cef6cd0d60c4c3f9d54b18cdb9a6879f23c8bcc8ec1cf94ed5833edd02a2c65c0d43d51e241153c554988681a318c11f33d31a493070a277bd5944f9867b45f0f1561218c691d50c720808f1d9d3efd10764f659a5885e40dabba1ea0cac46c96e68c2ffaf68a288f73e8bc6ee48268f6b2b7f6825f398f9c426f73e095fd07813bc2fd3e520c7a183b94562d6d9b943523cdd695f47aab5361eb8e388c3d5b42d694729dd92f0b941e136b8b0aaf5c4d7eb82f304349b0d4364571d41a3657720ca9c77a93c564373913bfb5634c40b2cfd7ed8e8afa236b44655caedbe31cd1a2ba856ad37457d7143c6adc67838a43c72f6e26f8ec1be54816fcb49269f6e1a6e2da362443a27d79bdcf900349150206b8559776cbd121f7b23076a126ef672fd8acd0b7aa1d6f395e85355c1dae7f3dd22274e59b9d92f1f0c6ddc740d163b1f2af739e59f35b8b273247eefac6e86dc417f27acc7f6554eb9b579c8ff98c5dacb98dee520049a996d3f145b05012e73193798e6563f76b0492ddb86222400a645247f1bb72013170d6fe87f858f987b9dae1daf379ab0a648b73338b20960b8b72fbf0c86508dc05cdcfe6e8482c4419398545166a3b0adcce1c7e2522f6b907074111e88fe5c5e3cf3e19211fe0125fcb4c3ae75ea58175e34653984116aad2f02180c2a60a68bb2c200a9fccf15f9270c63ff8e1ff42f93d22481a26decf22a0e9ffe488c395b82d4bb1b5ab77e729c5571ae89be2b5a34bb96db4ed3a56c7f9941eaed3f04243edbbff80b6ae77eed5d401a43d6c0242599755e514d58184793c233d9d0dbcc6fb3b724594059d0f56871ba8a1198c215d65b1c9230bbb04285504ee06a15029fce4c1b7ad8281fc584f65324be821dccdc5db87d6488db027ee7c12b96098b8195b5ff80a931b524cd0154f55ea18f1fb1fcd80b8e2b40c05ab44f9f66768758d6f9fca10b136c642f57f72f9dda92e6f452b2dc4c28b08076a4e043ad6f418e0a7874bc6093d4775d192a73a940b0da4397ca2c1a2bc6795311569c30eb3336e7eb0460007f767237ff694bb93febf5f008fb2fbd7d9d8b101518d4fbcd4bb9009fdc1cf2a9d71b75ba4977a22b71ee0063bfb9316dceb0a534f3b28cc564e77d60be50d8439932cb2aec21ec26f14d684003cc38f15be2e25a9c068803a0f12377c1ec6569c79081540fafc56d069131b6c967c68b18e434a4e96e2aa441339fd8b081510b8b1d39b14bd5fa85dad1e6a5315e28c53bd70de658e81ec6c10d4531e66579e91fb6f9a601fd2382b6ae30d0d55e13cca53e0a96cfc47b5c90a2890b3d791b0a191c2dec8628e1420535e5c3a1fdabc48eaa865d868d09a1105ccf811db89742de5255bb3bf7ad23cbe163feaa8cfcb399054fe42400e248e91d2700e6ce0c90523e3991fcffa152ba4e917da7a514e30861482dfee399c3b88764f3517ec1157544d2286a12749dce97d535cfad49dbff341e52898e07cbc50c95a15805d925cb8b30bb549f8306e3d41298ea7aea18f75beb746eb3debb6cbe91e51ce1897ad48942d10403531eb34b6f29590880f1c78a1b87d4e67f712da30ae383c8d57be8e78776159666ed9c52209d1e11d25351b81303733e7d318466aa3d3065aea8aa9af3fc204b14ffb06f9745c35a337d9fca948a2a49676e7812f3ecb59ca5e1673fbb51e5452864566a4e902368d82ff345921feb75c02becb5e413bbcd7b2fc574cb94d3b3c35299c578defdfb7e8aa56b3395a7c5c3c49e9d15ba1cb4c3c51d2c1b0aeb29a192ac99ceef7a76befd4ef11e80051e00772f31db6980f5e29549b42c407cc766e0ba9e446010f25485422d907757a75df827da8569cbf0689d45d41ec8cbcde066c2cc7338db69e58775838fbe125ff07ccbe838c37a84a0a972a836337d9f851d90ee62c754485b340dda39f5132fdb123ff48a3dfd5bf8b04d38f8d9c3ec44dadee6009805adac080e35d52003820f45755f364bf0913a2246eeb877dd86fc328ce1a8cf11513c40134818df7dabb434a4405fced105edf7254a7ebb3afa2291687035361cad0b331ebeec795d175733ef3d66a7ebac560016cf17a6e74e7d445866e26cf7247b483920142698287133d77700e97239dcdcea60fcec7f03b9fbd9807b321d3ff22b9b9eaafe8a3aebdf6918123c69d6e09bb076d8b28a6a1727ffcca1e90e809db21105c81b9440c955e2090cc933fc3846da4aec269e80e1f83bce343c2d900b11637f04f58ea50c1ebc389469cfc29e0fc01ffa20ec3536feedc116af5faac2d051af3d70825339c854515616c2c62deb87823cac31a151f3abb7b815a0edb48ddc3d647fef4feb3a97c8b2ea9a3e49c640538c4e5678fe4c7196662c3f6e0fd3b8626ec7295d9ba2533b5f979e2a98893adf385768abd35b23a5af9ebb31fc74d6089a0bc9252c4fbb7b48702351b18c1dbfbebd664eb5d111d3ba30e6bfbbc7cc72c7ed2f72a9a0cde43e4888e6ea939006e02d725cc4f06615021b355cbe6e77368440ce92addbeaa4608c81b2e6d9720d7dd7679a5a723ff432f40abfba1965a4b9fd22c6318fefc412577313a73efa4f7d2754f1e93b28d511315621408a02453262e6317f7c8258b5ad50a37e475ae50f66d4f01d783203b5c63354879815716ad32ddf6ce01e7cd824a3e95da4eee9895f1d2e5d5b646d63d5fb93499242537a42d494c0a01d39ee1d9a7458ff512efd3eda109b248941e3ef44c2600b954abb1956d46a252676b0d0c6877a538aa26728067ff99899402d68e257b5fce273108b275614d8a7f874cfedb954f0a77059b1da9f078b29b121798bb6d92db9d5ae7a0dcb4b3e20aec12e7ed2fd9f31f24e96f59ca7a5971b7398606c13d7bf7b65a06ba4529f8427960fa61b1abc3820e1e5a71beba4ae46c203121a95588104b2ee91c82ce578e40f2604c8cd1b153ecbbda3de40d26197053c7fd8f13192b9250d9e5ffdc018bb0e877e86098b8d4dede7e4c22cfb66c84a64f3a0f58e224d4e9e502af9a751304c5e0a6da538c186b10757c25f894916f5f9ed20c37c4e3eae2486ce913ece899faf0d0d2675639446eb24f5b413f46e3a2c880540bd77149d7d67b3c2a5a5a8df1b27cbf67e256cc673851aff3033e0fc8adbdadf67867d63adbf50bc9e8d11a4fc770d67b31233af37dae0e6ce7a60368b9bbe90c319c93a3b88abe785234419c3a1927569a0fe4ac8dcc5e144694d9d11852e354087e2212f872f9282e9682a533c3718afbd0a91eed851bfd7b73a7730353c88d228b6ce0a9239cb8ccc960a13fb501543fc43f639f59478143c08dac8eb5f6129f04bb617ab260c58a38b094635bfc6b854ba6ad7ff3276bcc96caac396c3860a3c568593e690d58c491d1d054bb170336c3c0e4e6389dd7b0d1c17e61b390df80ad4374647a935ac606b4ce7437896edb75875b1356b73683620f758ea100844a0e040f66e7476acf4b800455b597d9b70371f767d779bd5a21edaeb5248ff0a7e700227071491c44ba1477b512ddff3646ec14b5d1fefd394137174930adfc89129ab382cb36ae9931c506019c206c79cfd0ff760b0f599b1c9f81a7bf8df612242aa116e80fbeed88077ece41687753bd45da7728c375cf940b88c06456b0ca15ad69b146ac8a999ce158733485b533637c0e0150589056046f897ebd3545cd4a5dbba775481e6d209784a3dceeaa42e55876e0d396d9f7fbda01aa83ee510bebf75879578ddb4dc851dafb1adf4f75a73e7018ff970565ac87baa8fa682b5ed5be72ff2996586cc09fbfe5bda7e096e71c88cf11fce5c5d533f3d4f0b1d093e644054803b2a757ba7e383385e75ef3983fb6444e0081c841a426bb7810204c76162208213b18b6a21338544913aa2a4003e6e03c85fb530f6341461745e644d98b6e1c823b57f4d143dc4b385e4a220c67012f7fe30ad2314f0dd12f8b2b03939888b605f8a1fc91158d8482966a5f422915b8a6e193b0154666b14f69061e3d30a9a3b6e7c607d138a0ab86a8ac6d49aa9062f70c3101e8a9cad0c6562bcf76aa2842bc09541a91a9ac15487fb5e40063ceb27291937e2b977becc8daf7737689eb8273dcdc1ae1e3ed71cf6cbd1e3d60573db7e733486916cc81b8c701da0ca2ab28904532d94a1eba669b334038a29fd0993bab1f183c1c5f1a64a7229a4bdc6047f717bdb035109e3bb37ba525aa1fa46ba31bdf729746f17a696ba72010d8a6039e584b05b52d81140cbf2354bb00ae1fd2206e4fcb4ec39a87c14d3a947728a0487fc97836397aea9ccd295ea1db1c9f0c428438f7d7e12b4cf08872733f7cf2a0285ea560977897167c86b9980f0afa28fe515b3876f6ff0a56d57fdbc94cbd22650351f29414d9fe7238eb24397f646fbaf400319be5a2b5e10cfcb3c54b6f3de8ee1ca061ebbaa794c7a51464449f5363405009cf73e1f986f29aa31747d2da0ad6ffd13ae2c1d17c0b2443b388a1bae56961bcc0db7fcdc4344031c87fa37afec5cc49a444e5acb02c006b34f4db6c97698b8a3e1018b7cebe0a638a2bca6b792c43a80e36b3b0922f21136bd92e6831535048779f7eb303ae71b1e66ac657e7cf900265b14021802999c77fc62026b208bd166e543b879354d012c88c88a99eef74d2009a6c013423dda97d1f040aa40b3245f8e476f33e58e1c10b5133dd9caf67980f7b00f51547d124dd5398a74eccc06dbeaa431949e342575317bc529c978467ed1d4d0d860cfe79fff01fa885f2b3658bd43234326609a066ed9bc5ed1753cb51cd7164e7dd08af18d016573f476dff19d0d394b7783356ff9e587cbdf54a93b6e892acdbad7e4c1b2fd9c621368232df3b235fb835e491f7a67618854c7794abeaa6effdedd7abc44d0be87482df30aef60f478822c6394af515e122d151dae2aaa0b5f856242516ec339f1c0159554c38493fd39211ed66c8009fcfc97bdcfd780c83554b1aabe1cdfc4f86b3cc925a68804b5eb1997bbb1518f5eca59e2e0360d0ebc14e18ca656fba54eb022c583dcf80a79903abd3fe1dfa089a31de3919d4b4235647852adba8977860fdcedeb747e50318687779829c1f5ee6ab8f99cd3d0d4452a6354690c58cb4a4c63b64f9b8d3c51075fa94eb7fe8511175bdb7281c3d04f6a0a94c8d7bab1da6bf288cf51b7b73ea03aec0bae9016b2771234de62e718103ca050303c2139326d6b9ff6a59eae115401a3ddfcde00e284fb512d2ba3e43527ba0354406c1a3939c482e2923b0816d6f96e53528d2d837dad9cd2480cc64f34d81f7a35ecc1122f277451b56f5e1d7fcf1aa0982d3da0ce23a8af6c1a14115a2efd4ba54c2d7bceddd891963041582d159104d919460c0fdb5a5d532d64b6e8bb73e9c9f3d95d8366c177e5b8851e854003c8b1decedbdce1be85f07f4c07ac84c84cb4563d08bfbb2db3be48016e2b0bbfb82733ee1e3dccfd5ac3e58ab36b474f0484d50cc6b7edac764539cc0e35a2f0f0df388be4849d912e1b89e2e4035075e6c588c340b1ccc2749cbe375c198c37756d523b72b4fcd20cffdda7f0fa878c51d5420a5fe5b42e8fbc9796c27b09a455e49e50a7cc7734a184a2fdd263cc723bbd4e5b6c14aa3341183d7d66cea925eb5b213e43723f4a15cbe1e8ffbae729854fd86dec858bcef2c8254a641afa5034d2e8f7c79fa7a3aa9ef96dbf2b79762d7348f8c13ff927483c51e3023fc76dd4aebba1af6c13b0065a7f4790b59753c5c19b7a27e0cbd507c9f42c25330e98822dc8af645336870ef26c7aeaf84611f4926c57f94d49cd7172a011f1e5ea08694a160af31e686e09146217e5ff7e56df38fdc4a58bc4905ef1071eb6b6fe304536a91a4b6b3f2eb3f1e3433d2866de648abf6fb350afb45ff3bd3b5f9fc3ef33a0a500d19c00c849ef43480489e8e37b0e5940f7d52285e5a748273e9adcb5b6b06e528bcdf44352333fe7f99bfe9634601db4b4c11f43074af92c61a4117eeb1c5ab9ff6a6e6514b560b3e36ccb411d20b48988c71c113b7acde112a9b586b9bc0d1ab5379c16302c73f4ab164a440124fc2386b05601c548142df66c9e32b6a32462cb1e5836fc8ab61d7e66d2332c23501280ca4f6bbaf30735d61607d7b7bb3bfdb73cac85e11de96528eac1c89ed82d43a05dcd1e7e03b8287735c9a8f2404735c0d3972205d958b3205788aad470c845022fc4a8969b2536615e2e0d8833883f567f54721593a4061c2a23303a93ef01c164134f55d222d9a90fb43ef6587eb3a923e1b7e3ff2625d5f9c25c0a81c5d3cded7b73c4598eb264b3212ac086376b9d50f44a492cfc2e1428717a9a85668527a405f9ef429fa3e24575dc244075a3a4e89d05e17792de7d16d67b5ae613753091e7bc95f2df22e6e96bd02f0f95f3286f6ffa8738ef60ddb53a95fe9680471a674a50f58af4d59761bebc4f721a2327e48a4969a2364c4b90f9edd918434ce71ff2792969583e8e0b399f2877a6f8440134d0dffb2ced00c1bdb3c600183d3fa869655bd8e6f824656e500b509b3b9ff9f0f816f47b6c8d95b6a9f88ca0ae2393c41f7c46c5adaec017ba8ad85f57751cc3fad8ca277f45cbaf49f0a46dbddf6234444d6c1db50fa54128c12880aa4cb7451df17f3f973254aba527bd891472536727f867b8265e1d281ac136d4b5e8f00e66a6b49f2d50d458800e2f7a36cb8f3b598a550d9a0b294c51bcbefb79d49e2e3b20b9ed74138177129969d9058addc7205a73a0a9e54ad106b4bfa14cbb04921dd85e7aeada0d2a3ecdb0a16b4571ed7a3f69d8bb938444ea1f8aae1b92b7daba6081bbf75bcad784234844a51d7d785180aafc96432297a86e38c4cde82713f08a7e9a99f9d95559d806fed7c989b986ea8712c96e9ffd73184a3831b8f687c3e06b949f92ec519933f4291f15a810875f7849db1ade78189996580b765fb2d2f27a8f96cc61a02790686df184efee7719f9173c4710583689cccea0218459a8f70ec62e327e2d95775ce5f1db60e7f79b98c127773780990c6ed803b63aa3757d4bcf41d032e9073ca7c725555a85d9f9e4f73c5463d9873aa0e6db7e35fc2c998c5211ed133a23dd01dc6efb1467ba75241af9eb313632cc551ee27c545c942156cf14ecc83424967b49d6e6011bd278cc39845cbbf8b83a39cff697f9b96f778fd7030319331f04f6ffc34fad9aa398c07f59365c6616a219b321ade70fbd674a2cc307ab5f6bf15b233a2a952ab3228495797e694f7ff2d9d31f33d3bb0c1796c8d5de790be1ece56f96a22d09c0041483ffd543401f4a144da17a83b1756d939deb912fa185e96848dac3068970714f905a770c59cefb1b07eefff103d0cb2d9ce725442ccb52d29d07ff69e004887ca664fbf6b4a87ad87f413e4b91df14e2e02a0f2624e2e840b24d070282a5eda102032775b71c5bad7d6aad368e338347955b562ef35ef89971ede83bb494cf4365c638a440ed983b7874f68d3692a58c096e68a1f3e446292887db0c0dda5a56ed0ae0331b11271b3a2c790808dc8c6a1e7826738032752ef0e0becbf0f1e288cb9fdcb18fffe129ee6ff2ebdc32e8cfee01f60c7d929d3fb6412e43a5afb62c39b728cd4566d6c9dba6146bdc2ae0680731d7eb52b6f00b90a5120a048e2814a2863153b57bfe31eef66cb7187f32ecfe01e0da7ebb76e2cfaba5eb921770e330d533672fc3738ba0f891be39d01587d75d9c313d7ff46f0d2a8ee143a15a32104d8b63e16c45f0bacdece991845efe1551560ac55d6a0fc05c8f58d94741a7aedc78451ed2a828b4f60b0e655760168a3815a673bb01db59b9f2cd62d312126e7c1f43ce3c682e7026f4a9f5529c29a709615ffba5ea1eabd259aebd77307629e064da7febdc5425d718edb7f608c0d9eeda87fc31da93c449e3120ed4fd296c18def15ea465e10a7d1711a81cf53f70c07527321253d3c4fdbecaa31f4a094940896fc56b3d164c28fc2ee325bc2c3a293d871b89fa68c388c06703b636fafffc0dc334886e8259c482a60bde6f7250d41d6a611a18902f6239f8541e4a7db77159214b932fa2b5efc627b691464c94b1ecf75fb0542be689b5ac63a69e118377a7678a0575ac9adfdc3e9cc4cb9528d97b0fa86f59c1a0ee7aa3fb86483be7370230b171ecb47fc6fa8f6413c7f99f06ad120acbc8a3cb6eeca58ea98a08d5fc3746bc260a7485e998ef037c213b93ff92f35c7bc41afbcf5d86f82384ceb4f386ec27913c5051c6d0ee55226b3d3fd10ee226bacd0e938502deacd2800c1943d64623c8afd004cdd08c5e8882994b5bc1bf2fc32922278566431b92d301274966c9dd4334b94d0bdd1072a0b62fad67c508f766ba11dfa16e5d034717f32bd86f1d87756b72b0099263c2378b8a5bce047ab49368df7ba1329b3c301c877eebbf21c81b76229ed8173ed1858ac4035fbba04f1b249b0dfe35817ae70b19a125482652de65d38c9db8035822abfa5604e490889afc14e5703005164b172cec264f386e559a582d1169e92c0b02d9736aa6ececbcd0398a95ff405412448b18a20aa7569283e12e3bdbb9d0bd12eeb3050ad693e503371039e161b07e69186894e0074d8a03fb73934818f53d06907ad4c073084c7892940a338a8cc0e6c8ed4bf6f232977adc925a5522b4c0a85b9c98ef30c294f396e653a55ee15b37a849351acfe2d7100976ddc8f1ad694ecde430a7d5c1e1f60a397b7a8f1b174394305fb13bd14437db3e57c0388113230fa342b29f3ef46851f7237fe2c239e2ce8713105026faa030b8c2ec733a4a7969233d49d5f26b9c18099236b0d194d976e0fd9e3469ed9f38d399a67dbe313fb0555c0e75d46a23ded9f83c5d9fe725e2fa0c28ec55f9bf22ea9cc114f8802a1fa59fa22f90a24f03cf952c16068bb9322511460389d39c7c0c9334245f0b00358747df6897010dbb68eac93720a01cbbc62128a2e38f3a9e6405ee356892a8dfae92a34371d4d97dca9a1f27b44fdaa50c9ea28f7ad3da972577d6cca2caf70c315787d55b85cac614b1976149bf2fd6c1a360ead3d24492e24f0963c4d4af7feb667463403e5673ca01a463e92bec8169fab2e5140b75afa225603ba46245ee7ba3da44a52e3517ec4258044e0f8646c8aadce11e7137872888d08aa94915888fefa57b3d71f08db373ab1265a32e676a3fef15d0c73d1889c4c20795592ecf3b17120847c014245ca722e62794541edced18ec9d94d146c13f48fc33f9a5151e79a11d5cdc8075c0664911e7822cbe50518b3e16ce2f64e03b5ff1e2afd13bce411ae7538b3a8c9eec864f9962da391b58fcb7a92f250a4b9891c01a988b5967a5d5a1517961394cdfcd7a1e03a4eb0b9cec7f291172d2f19b745a476f348b419cedd52155acb2303d06a79b77241bb9f0fd0ab09f428138cecbf088b47732dbdbb7bd6a441022caa12974ad9500757ca15a1f6322b8549b865fb10749eddb84372dee7c8ae302a6956bee47b7d5154b1a4831cef0bf0d3ca0a683ce30d17da1e1948a0e690892860f256673b09b1c955db7ba6f1687373b93f46e1dd28fd5df426e89ac5322724480a45475f5820fdb9cc6e18d44cfb37c3a5068ab6bb0b4674751d672ec41f091439b4afab8a69b0ddb5d10c14133db978897ffdf9873dad11112b95f0dd29d8ceb668a5f03ab01d841c1156816d292c0dd6161489816d85462d2eb7dcd9dd78d3ee0e86026bb5c86266a292f97cd7985f4c03bfc108386bb1f4d8f45ce44c8efb878ad64e33c6bfffaf7772d4be957a868271069905d585e0e45799484eaff00696040d67e9c7433aac58f0a40896cbe017e681c90d68dff0a60f2c9f9955d2bdcb7a98f0ece3699b1446bc4576402349cee3c096b68e8d4ccaba56fe90290d08c489c687bd135952631d17116d3dbeb92fefd5693d4df714f7ac2fb0497b1e5c84748d074974a6608172c61cb33a4c520d38d9d0697887fb5523853f39488ba33a9aa17a42a9300238fb792753529f49ec392c92a68a8d0f38c846e528a3eb7a1bc08d7787cac2ad1eb5ca13cc8011a2d52fb5144cb0e53eb55fc80c63bca21cae3e831773766392ac4dd4346b756f68f1f71ab342e77fdb0817799712f57fe2ef3165700e4c221f40c9e28da39b8b1d645408fad753a564777923b9dbddef0abb5a95cdc6274f3b6ec6aa8f58f5743a8936dddb90248c9139c0aaeb99422adf3772a82396d35779f1ba3d27c12d3a183cef26788b80bd91d72230c213658ba9262675dfda1d2495e9012de4024d093af10689aa614b15b12bf4459a533a51bc48e542c56ee0ae622e57723d5c2df5aa37f5c481e757935609d29650cb995d60ec17445e39f3d38c23e4320ffd1b82ef03ff3892ebaac1227236d248b34befffebf4179d3e9f4bbe2cd0e70787c5ff81c973e5e41331c4a4b6f7452d51e0ed704e9897e0f65743a3e095b6fd90f9dbe230081ba26ceb07542dcc5123859bfa20b45c727a627e92346dce00842f03969945b27100d30c42dbcfd664cc850673846c95a94f76a7dec3b3783a3c9a441b7156463115f7d82b9a2f206b1165f574127b495f1e5e0ecb0b0b12af9f67abf181ceb57d69e68ff5bfd7814664a2d9988272b84febdab06b141f68dff940636be6658069ac24eff8681ac7f239be870334aef3426dc7d4ac8ea2d86325cf7dfe02497c181b3e33ce356ac8a0ed4cdb6497866a20e2eb4001b1a30db6665e2f29c17925951250c4cc99c918022a742af295ba4f3888a89550729e147ac2c74bb96c3a1fe86898a0fd03257f70e7956e6a3d299bbe73cdf0afcd20bb71d335e2d886691fe9e272ec2e2694c4e961e8cad94b75a56ffcfbfa44b24ed950c55459c8a9ee726ad0b4aecb3e3a31615ecb50ee1f0b1ea50ed3d4dd584daab04e06d3b6ccfa6e60611687e8788e17ef04cc2614f0582bd3810bab2013ca856c20600e9974529eb2f64f083d6344d332bbc7ad595b26a5f159353823377aeac02cd53382d5911eb84090f3ce46110865927047941d2b8cdab7089af3a4e89b314e451ee099eb6e2d14813956c68f3946d453da5ec45dfd4bff25a91da34740ae75c776da73aac13bbe0dd207d3221c7e4c82b41c2405c1cb2219c9aaf1e391f87e7cc50ce3a4f67ffbfa8a30f39795ec7ce55f9764f6461e51e6d1110560facd81c8c7c04b5e97b6b65598bcf30fb73425ef669e60a9c3bc3e9fa9639a984aca8593b47c08485538c586d730842b4f0e945a73724e434344b769e02919aa5dd5299a4f692a19ef342b12240a419d527be9d46aa71ee2705498d66b07f64cd240fa6568d9397e5b95c69f200387967bffbf69e69299adaec6c9a702037c72e2cb8c9a54ada5a02c96943f64f0c08bbc2ff8584f7f9b3bbd8b4feb7163b873af66dc35feb6bcbb25e148e7ad2d4e9b13cbd682b7464cc94be6642a49080aa0b53db7b7a2964a412f2136af660e94903b49f0e5d0e297e9ff550488252bc91abe74fad55f644f8605fbb8eb1789f12a06c8827", GA: "一万三上下不与专且世业东两严个中临为主么义之乐乙也习书买乳了予争事二于互五亚些交产人什介从他付代令以仪们件价任份仿企众优会传伤估但位低住体何余作你使例供依侧便促保信修借债值假偏做停健储像儿元充先光克免党入全公共关兴其具养内再写军农冲决况冷准减凝几出击函分切划列则创初判利别到制剂前力办功加务动助劳势包化北区医十升半华协单南卡卫印危即历压原去参又及双反发取受变叙口古句只可台史右叶号司各合同名后向否含吸告员周呼命和品响哪售商善器四回因团围固国图圆土在地场址均坏块坚型城域培基塞填境增士声处备复外多够大天太央失头女好如始委子孔字存学它安宋完定宜实审客室宫害家容密富察对导封射将小少尔就尺尿局层展属山岁工左差己已巴币市布师带常干平年并幼广床序库应底府度康延建开异引张弹强当录形影往征径很律得循微德心必志快念态思急性总息患情想意感慢成我或战户房所手才打托执扩批承技把投抗折护报抽担拉择括持指按损换据排接控推措描提播操支收改放政故效敏救教散数整文斗料断斯新方施旅旋族无日早时明易映是显普景曲更最月有服期未本术机杂权杆李材束条来板极构析果某染查标校样核根格案档检楷概模次款止正此步死段母每毒比毛民气氧氨水求汽没油治法波注泽活流测济浓海消润液深混清温游湿源溶滑满激火灭灯炎点热然照燃爱片牙物特状独率王环现班球理生用由甲申电男画界留略疗疫疾病症痛瘤癌白的皮益监盘目直相盾看真眼着矛知短石码研破础硬确碱磁示社神票离种科积称移程税稳究空突立站章端符第等筑答策签简算管米类粒精糖系素索紧红纤约级纪纳线组细织终经结给络绝统继续维综编缩缺网置美群老考者而职联肌肝肠股肢育肺肾肿胃胆胎胞胸能脂脉脏脑脱腔腹腺膜自至致航般船良色艺节花若英范药获菌营落虑虫蛋融血行衡补表被裂装西要见观规视觉角解触言警计认让训议记许论设证评识诊词试话该语误说请读课调象负财责账货质购费资走起超越足距路践身车转轮软轴轻载较辑输边达过运近还这进远违连述退送适选透通速造道避那部都配酒酶酸采释里重量金针钟铁银链销错键镜长门闭问间队防阳阴阶阻附际降限院除险随隔障难雅集零需青静非面革音页项顺须预领频题额风食饮首马验骨高黄黑", GF: "ea991da476a112051bda22f5fc7cc63e04356a710e25bc613aa8f0e91b3e7a81be10069459328bf20331549a041729dfdbec26cb72b5b1656e07bbd716b3ae2f98d57ccb830fd69b124446ecac5dc65538b3f54f7162202fe91e21106ae7911b282d00b9670d8c257409465696f7c44971b9d379b41c0cf70c60ab078b44d372c315933bebc7ddb87ff85bbc84104183b9651a9bc142d09f00d96f35908c4d2a9928ca8bcd2e511b0cfedc62fc4a36d8a19c53d90d6b391d2eedeb79fcf345f3625f386244c89321ae9e8c9e7ba72ab006a8684d20d95aa43e3b2f21f64e91a5af990b24405ae3890dd091a1e36e6ebad36ec161d7e51ad8a20e19134497a8b3ee88199ef8eea47ba9ea821fec190ec754e8a312d795ff3eac14e5e142c22a24bcfe46e0c0d43492f4de19a25616ac6bba2db8c929a0bf378361a364a12c73a5fa286e467c74c5683f9f38a8c875075a7e6a84237e5d87d40c416302b96d6beeed25f5aac98868eaf88b187aca6a4a7cb48dfba372ba37e2e3440e111371fdbfb781f3a053f5b4322e50482bc3584f9792c77582b6f6ce3033c984b653fe0354a313842bdd223f9138e359bec410cf3877a040f6a2434e3472430987adf7a0a767c26e98936f8b68b5c4a99d5efd202f813b39ddfb68b5d46a1b5f15986d9de9928282c7d000695162db6ffd0b6d29315b711564165010d6b13be9b0c38c96881057f092816a9c00287239dee885039256759678fbab53955051a88c77f8fb549ed6a0ed4f904bdf612fdf895572611e36b4b205407a90f5496d57a927128a2fe5b5f3e98222eefb3c90c50357c9cc6bf38104019c9b7a8e09dbbc06ebc98f52566c0e3157099e20b36008221c32d1f3a2bc8607eab460a6aaea835c76738252821ce76ee7c11ec96b1e3636c84a2923d01d7d759465431956f7e7cb1e67047725b3f83b878666712857d86f31d38352385a38f9bf222dbf0c432b5553b2740a88b7c60df755e6a1b1e74726b2f6a92ea4ded51edd1ce7e39778bf4fa6af394ab9a0cdea7d2f7d323359ca881229df5a539dc67c2b738ddbb6fd69a9e78be9b5c208dc6dd4e4e9f0e7481ece6537d8da789a3c094070f452ed00ff9d0ff9673c167a89f3b739bc193733ba733899f132848d84d79500da6ee6d1384ef423f838c773ab49f23532d4fc570c2b7fd8620eab01b90b4aea2c5d09c3995b89cbe3286784f6c653fcdbfe6e8d1551445782e46201b64499936f7ed37eb257a76894049e3115455d303e748c453c5adef0dd9b4d710064f92a355f52cdc909d561252c7db4148e2a98880f7d1623e39070a20492e0a4a077fe6e6a1b5e35bbafad1b2f3549c1b911a7f82e96262b92dd6e6021e8f755d8688f71e7aa9340ef8fa5d4fd9f302f6eedde87cd36a1f77023d7cab278af60a111e15e330844cd068e695ce76b7b8fe637f0709d91deb49c84e5cbf55708105ed96bcbf973216f7f7d8769c6c9ff58ea950a78302c30bd5bce0d870fccd2fe86a4ff4df6610cd43686dc218bae0e23a92f7935d189e78808b2f1370f011101c04ef99c89ef836cc09e47a0c6c49875af1a278280a73965c8a062c4aed33091c78bc178ef921c3fb3734ff6c0d60cdb36abe1c400bc47a0f3e4860ac8eb1cf359857fa8acbae27ea90c7a625d087ad6f029ccc48f0a41ddb4f81575cd0da5ddd01285bd0510edf48e3ce670dd217154270e44f879ba11289fd74018bc2b1a945cfd4086f469ce2c923f6e1310d95b105b2d259a726316c30f579a2282dc43152f817c8b005673ca3766a1ebc74b9642e22bdc8f76626325b0038c22bbda83160b74303db2918e700b15a09adb5ba46a22e4c3abffe03a92e3245c005f750c35b10f316c7f912352851d0e5db45d9d15cf593b70407d44fea49fed10701b9a68a34fcc013ba90c1bbdb1b2da997d098107692b3b809a075828e22f5a831af0425b7f9d83817559c554b81ef9b48891648623ade983b9bca1c5b1ab2d40f355ec4ef12ca8163f8f948f155397d34d4de08a1221a81f1bba830f8f4a508446fb6554f1587f2893eac3aaf72e0e4981d6ccf522398642ded956e1b87ce6c6a93f67135b7057cda2ede66012f781a5c6c2f959c54b5e146a69f04e1e60302499b25ef22f79bd9ffa91fd30bd2a0c669f84a485c16995de318c1595a34d233e0f86312bfaec3e37b41d24e277916c27ea641fb33b2b35d15364592fcfd15f810ca10001efb18803ac28e44d8e6918f3b03a9b6c93ae36e4f878a75786cb63e57847ac27bf057ea5b191cebde8934929c8580cb6c713f93a04edd875a4ce126b309da4ef1b3f58150d77c9fb9edc24ef0c0dcb32133d9e20c157c0a21e6804b0d98140f7e64b38103357c85a82f30a51d29903ead8b25b779aa5a7acddd3bd910d00a336c6c4313b435d04363f67791cdd94b1c3bfb86466bfd9c02dec16ebdc95599ad75db5a49218937dedb0e9e40d8548c6b4bd3c6a4cee4de23bb3da8f6a894edd85b0473ee0a317033f8f3882f313ef79874a1685233b83fd829252ada8cc2bf9a9d9457a54e38517cdb2a3effd11a32f8c5c91a5abe5447402a397c30fa389bc8d844620e8aa39217d660762b0a752140b85da7c406a948cb23f393b2229762b2f4fad500e1d1c944fd2b320362e3974b379f680291d422c133b4d41cb4c99680cd7e4c636381f81cd423ab1974f14873d9a739be2cb8f029d14b3a9b41b9eb6e9272a6033f6fdd2e8181675bdca38105cb0123143abde7e06e6f69eb0df66f4879cc51cf6f8ed50f08c695755ef807426d17da79be865d18315ff059dc78483a0720cf967dcda166356bf131070f59adc2b046d8da404f43ece209b280cbd259f2f07cabb39fc06eb13b4092b85aaea70569c98167608574aeb1f98818d090273eb004258c41ac9820fda804456d0989b12484d3dba1820099c50c8ee6b12a940201be46f5398cfb246b779161fc51dee265f4e8cda8b5fd72a637f7e56ec9464ca4c61641a19fb30dfd15c9d4e8ae82cb4468227e941e54de9292e0fb95850ba67d21c806fe43daa66656852f2f8072677faa6da43f3627fe9e5425badcc435a708869741114e14533d0a5dfa3c6605dc8f26ba4e08776388456b2ea94eb6ab08378d90a87f2b0f35eab8f6145d4f163dada5e0920b650f0fa0ca8091843c750e091c07c902b5e0a275df0003979edd2453fe8aaa5f359bcf21c23c6449127208eed8c46e5e052eb6eb7461707f0fa4d8eba823c30496ec5863efd481860c9f3450bf4597e470712f973976048d7fc62d43bf7504ce139ed0fe68f513f49cb3fccc0a2ec31034f6a6dba99be1f3892290083e4235ccca89c1af717dd3be25c3545a2468eea88977e666b8a65a88c9cb7cb801be928ed9c154d2ef19b8406d1aaa6331e43a804a2e6af7d575383076485bcc2cd62a8899936158b66bee619ad57716e76ec44c2c20e506c31d8cf1a5f9e3b7b635882408634816fc725ccf3b6d74e3342c596c4dcd8306211d02b8134c17ce509c0056c283414623d5a0d9e5146ecc6021b910a9e46b8474fb8ccaa4f10d4042dcded4c3f86e981bedc98cb6dd0bcb8f29bcf0dbbcba953bec38bb653683d72c5e28bb825f61212b8ffef4f6b2287277da9b55f51db2b60d148312168e4265c7a9d7d0a06550ad0b43edb8d1eb6c12a81ecf91160a60fc753dc760d317c3be27065d494b15f38e3e336f7ba40892ad71291c1c819cb46a9b38f19d53adc9763b33be9b3629d2e540fd75fc7e4cebed71b850b6ab8ffc93a41969d29f3902f24224f9075b23ecb580883c052f6217bff83b22a93becf6eab9ae843c344c35ba01f5bbbfbea5773e17d20ddadd5e37329058ef7bda538d5181a9ea98e9d7cc5304ab2f3853d401a1537dfd7afc0b2e38ccc655d303ccdc440dd677b5095287b6623aad0d21f9b558e8289b1b416c12bbbc9ac60ed490447c864844cb284e6cc46bf3c72fdfc66a337f12492e726978ee336e116700d5980f4521da8b63a6212d3cab74110a25193233e2e5920b84f67068e163eec8086d4369649794b224c650b5565e70d7983eadf2c38443d83789bef1397259d1711839237afa7eca01db4e77201cf32e6085835058a94284113527c3af599e75239aeb31b2ee9c88709b2324bbd96bb6984528cda21250c3bb9af5c2e10a7f8387e18a629f8acc6b0d37cd27a7d62d4564f3f091e8913302f42829c16ad25334b3b36fff16bbe982ac3a480bea0c4daa945e46fce7a70b85f3e648bd2113022a85312d99d1e6f75fe6c292f72ede8dd690efbf2cded419266324344bab97094de3b447969ecb9963a509b47ddc7f2c079d3aa87f58824ad03bb36809190651886a59b7d2db49bd9bf5a577c520031ce2f55d6e3342a0efef38fe046194dadaa5664864d4bd61d221799a5e069a5906d454cd6566b0c348420f59520f34bcb21795c89110e597449b62109b4b744d14dfbf611c513e6a784d38264dd0a4a43f871e1486d77f3df60cde5ffdac05da40f252fd165da1ae92e7ce30a8d3096eeffdf5adeca46d86e098d51fae3948a173183c73e7b560d3ceec45b7d77ccfb21203056b5a42736e002ab447ff43d29f7f5912ea2003b1dad6c5d27ec4100801423bbf6501eb26b07197e24612faf659633ca0bbce16e1caf22a799c3b1c5338910ff192cf9283699ef0c3cd5f4429c709295cdafdbe54098af14d41ed4f21f7f4c2f07db4ae2e51c84343e9d604bcf231ed8b62bbac20c61bbae3aea1885d605ff90e37843043e16013af897a9cca3ac266d58dafbf1fae2a60b5621be5f6e735905e2d71f7a5f427e3479694c00704e9c3aabd3340c4339f1ba1154d78eb342e0a614adc08997b109447798a25e0715256de5119f26af9cd9bd7452e75e0e908446abb43719b1e9c8bf7bbbd2565a273acd18e0401ca51359557f72d0586ffe37b5767fb8ad45b8bf7b54" }; //#endregion //#region src/font/lut.ts /** * 内置查表(由 Source Han Sans SC VF 2.004 生成)。 * * 旧版是 gen_userscript.js 把 ykt_table.json 的四个数组用 /*__CHARS__*\/ 之类的占位符 * 内联进源码,再在 IIFE 顶层建两张 Map(源 64-77 行)。现在改成静态 import JSON: * * - **必须静态 import**。动态 import() 没内联成功时,构建插件会把它悄悄换成 * Promise.resolve({}),不报错 —— 表变成空的,脚本却一声不吭地什么都还原不出来。 * - **建 Map 懒执行**。两张表加起来 2 万多条,模块顶层跑掉的是脚本启动时间; * 页面上没有加密字体时这活儿根本不该干。第一次 buildMap 才建。 */ var CHARS = ykt_table_default.CHARS; var HC = ykt_table_default.HC; var GA = ykt_table_default.GA; var GF = ykt_table_default.GF; var luts = null; function build() { const LUT = /* @__PURE__ */ new Map(); const GLUT = /* @__PURE__ */ new Map(); for (let i = 0; i < CHARS.length; i++) { const k = HC.substr(i * 8, 8); if (!LUT.has(k)) LUT.set(k, CHARS[i]); } for (let j = 0; j < GA.length; j++) GLUT.set(GF.substr(j * 8, 8), GA[j]); return { lut: LUT, glut: GLUT }; } function ensure() { if (luts === null) luts = build(); return luts; } /** 坐标哈希 -> 汉字。第一次调用时才建表 */ function getLUT() { return ensure().lut; } /** 几何指纹 -> 汉字。第一次调用时才建表 */ function getGLUT() { return ensure().glut; } //#endregion //#region src/font/ttf.ts function readTables(dv) { const n = dv.getUint16(4), t = {}; for (let i = 0; i < n; i++) { const o = 12 + i * 16; const tag = String.fromCharCode(dv.getUint8(o), dv.getUint8(o + 1), dv.getUint8(o + 2), dv.getUint8(o + 3)); t[tag] = { off: dv.getUint32(o + 8), len: dv.getUint32(o + 12) }; } return t; } function readCmap(dv, t) { const c = t.cmap.off, n = dv.getUint16(c + 2); let best = null, bestScore = -1; for (let i = 0; i < n; i++) { const r = c + 4 + i * 8; const pid = dv.getUint16(r), eid = dv.getUint16(r + 2), off = dv.getUint32(r + 4); const fmt = dv.getUint16(c + off); let score = -1; if (pid === 3 && eid === 10 && fmt === 12) score = 3; else if (pid === 3 && eid === 1 && fmt === 4) score = 2; else if (fmt === 12) score = 1; else if (fmt === 4) score = 0; if (score > bestScore) { bestScore = score; best = { sub: c + off, fmt }; } } const map = /* @__PURE__ */ new Map(); if (!best) return map; if (best.fmt === 4) { const s = best.sub, segX2 = dv.getUint16(s + 6); const endO = s + 14, startO = endO + segX2 + 2, deltaO = startO + segX2, rangeO = deltaO + segX2; for (let k = 0; k < segX2 / 2; k++) { const end = dv.getUint16(endO + k * 2), start = dv.getUint16(startO + k * 2); const delta = dv.getInt16(deltaO + k * 2), ro = dv.getUint16(rangeO + k * 2); if (start === 65535) continue; for (let cp = start; cp <= end; cp++) { let g; if (ro === 0) g = cp + delta & 65535; else { const gi = rangeO + k * 2 + ro + (cp - start) * 2; if (gi + 1 >= dv.byteLength) continue; g = dv.getUint16(gi); if (g) g = g + delta & 65535; } if (g) map.set(cp, g); } } } else { const s2 = best.sub, ng = dv.getUint32(s2 + 12); for (let m = 0; m < ng; m++) { const go = s2 + 16 + m * 12; const a = dv.getUint32(go), z = dv.getUint32(go + 4), sg = dv.getUint32(go + 8); for (let p = a; p <= z; p++) map.set(p, sg + (p - a)); } } return map; } function readLoca(dv, t) { const fmtLong = dv.getInt16(t.head.off + 50); const numGlyphs = dv.getUint16(t.maxp.off + 4); const loca = new Array(numGlyphs + 1); for (let i = 0; i <= numGlyphs; i++) loca[i] = fmtLong ? dv.getUint32(t.loca.off + i * 4) : dv.getUint16(t.loca.off + i * 2) * 2; return { numGlyphs, loca }; } function parseGlyph(dv, off, end) { if (off + 10 > end) return null; const nc = dv.getInt16(off); if (nc <= 0) return null; const bbox = [ dv.getInt16(off + 2), dv.getInt16(off + 4), dv.getInt16(off + 6), dv.getInt16(off + 8) ]; let p = off + 10; const ends = []; for (let i = 0; i < nc; i++) { if (p + 2 > end) return null; ends.push(dv.getUint16(p)); p += 2; } const nPts = ends[nc - 1] + 1; if (p + 2 > end) return null; p += 2 + dv.getUint16(p); const flags = []; while (flags.length < nPts) { if (p >= end) return null; const f = dv.getUint8(p++); flags.push(f); if (f & 8) { if (p >= end) return null; let rep = dv.getUint8(p++); while (rep-- > 0 && flags.length < nPts) flags.push(f); } } const xs = [], ys = []; let x = 0, y = 0, fl; for (let a = 0; a < nPts; a++) { fl = flags[a]; if (fl & 2) { if (p >= end) return null; const dx = dv.getUint8(p++); x += fl & 16 ? dx : -dx; } else if (!(fl & 16)) { if (p + 2 > end) return null; x += dv.getInt16(p); p += 2; } xs.push(x); } for (let b = 0; b < nPts; b++) { fl = flags[b]; if (fl & 4) { if (p >= end) return null; const dy = dv.getUint8(p++); y += fl & 32 ? dy : -dy; } else if (!(fl & 32)) { if (p + 2 > end) return null; y += dv.getInt16(p); p += 2; } ys.push(y); } const pts = new Array(nPts); for (let c = 0; c < nPts; c++) pts[c] = xs[c] + "," + ys[c] + "," + (flags[c] & 1); return { nc, ends, bbox, pts }; } //#endregion //#region src/font/resolve.ts /** * 由字体文件重建本次映射 + 字体发现与缓存。 * 搬自 ykt_template.js 源 205-308 行,控制流一行未改。 * * 这几个函数碰 DOM 和网络,一律走 ../env 现取,不在模块顶层求值 document —— * 脚本是 document-start 注入的,模块求值那一刻 body 还不存在。 * * 例外:ensureUrl 里的 fetch 照搬旧版的**裸 fetch**(沙箱那份),没换成 win().fetch。 * 这里只是下载一个公开 CDN 上的字体文件,用哪个 window 的 fetch 语义不同(沙箱 fetch * 不受页面改写影响),旧版实测是好使的,不自作主张改。 */ function buildMap(buf) { const LUT = getLUT(), GLUT = getGLUT(); const dv = new DataView(buf), t = readTables(dv); if (!t.cmap || !t.glyf || !t.loca || !t.head || !t.maxp) throw new Error("字体缺少必需的表"); const cmap = readCmap(dv, t), L = readLoca(dv, t); const map = /* @__PURE__ */ new Map(); let exact = 0, geom = 0, fail = 0; cmap.forEach(function(gid, cp) { if (gid >= L.numGlyphs || L.loca[gid] === L.loca[gid + 1]) { fail++; return; } const gl = parseGlyph(dv, t.glyf.off + L.loca[gid], t.glyf.off + L.loca[gid + 1]); if (!gl) { fail++; return; } let real = LUT.get(coordKey(gl)); if (real) exact++; else { real = GLUT.get(geomKey(gl)); if (real) geom++; } if (real) map.set(String.fromCodePoint(cp), real); else fail++; }); map.stats = { exact, geom, fail, total: cmap.size }; return map; } /** url -> { state, map }。diagnose 也要读它,所以导出 */ var cache = /* @__PURE__ */ new Map(); var lastUrl = null; function findFontUrl() { const styles = doc().querySelectorAll("style"); for (let i = styles.length - 1; i >= 0; i--) { const txt = styles[i].textContent; if (!txt || txt.indexOf("exam-data-decrypt-font") === -1) continue; const m = FONT_URL_RE.exec(txt); if (m) return m[1]; } const sheets = doc().styleSheets; for (let s = sheets.length - 1; s >= 0; s--) { let rules; try { rules = sheets[s].cssRules; } catch (e) { continue; } if (!rules) continue; for (let r = rules.length - 1; r >= 0; r--) { const mm = FONT_URL_RE.exec(rules[r].cssText || ""); if (mm) return mm[1]; } } try { const res = performance.getEntriesByType("resource"); for (let j = res.length - 1; j >= 0; j--) if (FONT_URL_RE.test(res[j].name)) return res[j].name; } catch (e) {} return null; } function ensureFont() { let url; try { url = findFontUrl(); } catch (e) { return; } if (!url) return; lastUrl = url; ensureUrl(url); } /** * 指定「当前这一份字体」。 * * 复制解密那条线优先用 findFontUrl() 从页面 CSS 里扒 URL,扒不到就退回这里存的这一份。 * AI 那条线从接口 data.font 拿到的 URL 更可靠(就是本次请求专属的那一套), * 所以抓到题目时要调一下这个,让两条线用同一份字体。 * 对应 legacy/ai_section.js:134 的 `lastUrl = d.font; // 复制解密也跟着用这一份`。 */ function setActiveFont(url) { if (url) lastUrl = url; } function ensureUrl(url) { if (!url || cache.has(url)) return; const ent = { state: "loading", map: null }; cache.set(url, ent); fetch(url, { credentials: "omit" }).then(function(r) { if (!r.ok) throw new Error("HTTP " + r.status); return r.arrayBuffer(); }).then(function(buf) { ent.map = buildMap(buf); ent.state = "ready"; const s = ent.map.stats; console.log(LOG, "字体解析完成 " + url.split("/").pop() + ":还原 " + ent.map.size + "/" + s.total + " 字" + (s.geom ? "(其中 " + s.geom + " 字靠几何指纹兜底,建议反馈作者更新字表)" : "") + (s.fail ? "," + s.fail + " 字无法识别" : "")); }).catch(function(e) { ent.state = "error"; ent.error = e; console.warn(LOG, "字体加载或解析失败:", url, e); }); } function loadFont(url, cb) { ensureUrl(url); const t0 = Date.now(); (function poll() { const ent = cache.get(url); if (ent && ent.state === "ready") { cb(null, ent.map); return; } if (ent && ent.state === "error") { cb(String(ent.error && ent.error.message || ent.error || "解析失败")); return; } if (Date.now() - t0 > 2e4) { cb("字体加载超时"); return; } setTimeout(poll, 200); })(); } function readyMap() { let url = null; try { url = findFontUrl(); } catch (e) {} const ent = cache.get(url || lastUrl || ""); return ent && ent.state === "ready" ? ent.map : null; } //#endregion //#region src/lms/bridge.ts /** * 跨帧桥。 * * 为什么非要有它:easy-us 的浮窗是 **只在顶层帧** 创建的 * (node_modules/easy-us/lib/utils/start.js 里那句 `if (self === top)`), * 而题目和答题 DOM 全在 /v2/web/iframe-exercise/… 这个 iframe 里。 * 也就是说「点按钮的地方」和「干活的地方」天生不在同一个 JS 上下文, * 面板上的 🤖 解题不隔着帧喊一声,点了就是没反应。 * * 四条通道,全部用 easy-us 的 cors(底层是 GM_setValue + 值变化监听, * 两端对等,谁都能 on、谁都能 emit): * * EV_CMD 顶层 → 题目帧 面板按钮(解题 / 重新抓题) * EV_STATUS 题目帧 → 顶层 状态文字,喂给面板那行灰字 * EV_DONE 题目帧 → 顶层 整份作业交完了,给「📚 作业跳转」当跳转信号 * EV_THINK 题目帧 → 顶层 流式思考过程的滚动字幕(会被覆盖,不留档) * * ⚠️ 事件名必须是两端共用的字面量常量,所以集中写在这里。 * 以前用的是 cors.defineTopFunction —— 它拿 **函数源码的哈希** 当事件名 * (getFuncId 里 fn.toString() 逐字符算 hash),两端各写各的回调就会算出 * 两个不同的名字,信号永远接不上,而且不报错。别再退回那个写法。 * * ⚠️ cors.on 的处理器只在 remote 为真(改动来自别的上下文)时触发, * 所以同一帧里既 on 又 emit 不会自己触发自己 —— 顶层帧碰巧就是题目帧时 * (用户直接打开 iframe-exercise 的地址),要走本地直调,不能走这里。 */ var EV_CMD = "ykt.exercise.cmd"; var EV_STATUS = "ykt.exercise.status"; var EV_DONE = "ykt.exercise.done"; var EV_THINK = "ykt.exercise.think"; /** 接顶层面板的按钮 */ function serveExerciseFrame(h) { import_lib.cors.on(EV_CMD, (args) => { const cmd = String(args && args[0]); if (cmd === "solve") h.solve(); else if (cmd === "refetch") h.refetch(); return ""; }); } /** * 把状态文字送到顶层面板。 * * 去重:say() 在一轮里会被叫很多次,同一句重复发只是白白往 GM 存储里写三四个键 * (emit 每次都要 set arguments / state / 队列,还要挂一个一次性监听器)。 */ var lastStatus = ""; function reportStatus(msg) { if (msg === lastStatus) return; lastStatus = msg; import_lib.cors.emit(EV_STATUS, [msg]); } /** * 把滚动字幕送上去。 * * ⚠️ 调用频率必须先在 ai/ticker.ts 里节流过(当前 2 次/秒)。 * 这条通道底层是 GM_setValue,一次 emit 要写好几个键 —— * 照着 token 的速度发,页面会肉眼可见地卡。 * * 和 reportStatus 一样去重:字幕经常连着两次是同一行。 */ var lastThink = ""; function reportThink(line) { if (line === lastThink) return; lastThink = line; import_lib.cors.emit(EV_THINK, [line]); } /** 整份作业交完了 */ function reportAllDone(total) { import_lib.cors.emit(EV_DONE, [total]); } /** 顶层面板把按钮转发给题目帧 */ function sendCmd(cmd) { import_lib.cors.emit(EV_CMD, [cmd]); } function onExerciseStatus(fn) { import_lib.cors.on(EV_STATUS, (args) => { fn(String((args && args[0]) ?? "")); return ""; }); } function onExerciseThink(fn) { import_lib.cors.on(EV_THINK, (args) => { fn(String((args && args[0]) ?? "")); return ""; }); } function onExerciseDone(fn) { import_lib.cors.on(EV_DONE, (args) => { fn(Number(args && args[0]) || 0); return ""; }); } var EV_ASK = "ykt.exercise.ask"; /** 题目帧:回答顶层的「这份作业做完了没」 */ function serveProgress(get) { import_lib.cors.on(EV_ASK, () => JSON.stringify(get())); } /** * 顶层:隔着帧问题目帧要进度。 * * 为什么需要它:雨课堂侧栏的那个「已完成」圆圈勾是服务端下发的,刷新有延迟 —— * 题目明明四道全交了,侧栏还显示没做完,于是「⏭ 下一道」会一直说「就是当前这道」。 * 题号格子在 iframe 里是实时的,问它最准。 * * ⚠️ 必须自己兜超时。页面上根本没有作业 iframe 时(课程页还没点进任何一道), * 没人监听这个事件,cors.emit 的回调永远不会来,不兜就是个永久挂起的 Promise。 */ function askProgress(cb) { let settled = false; const finish = (p) => { if (settled) return; settled = true; cb(p); }; setTimeout(() => finish(null), 2500); import_lib.cors.emit(EV_ASK, [], (val) => { try { finish(JSON.parse(String(val))); } catch { finish(null); } }); } //#endregion //#region src/exercise/dom.ts /** * 题目页面的 DOM 探针。 * * 全是只读判断,不做任何点击 —— 点击在 runner/nav.ts 里。 * 这么切是因为「判断页面处于什么状态」这件事被状态机的每一道闸反复调用, * 必须保证它绝对没有副作用。 * * DOM 结构见 legacy/API.md 末尾那张图。 */ var SUBMIT_RE = /^(提交|保存|确认|确定)$/; var DONE_RE = /本题得分|正确答案|回答正确|回答错误|已完成作答|已作答|作答记录/; var REJECT_RE = /do not have chance|no chance to answer|没有.{0,6}作答机会|没有.{0,4}机会|已经.{0,2}作答|重复提交/i; function currentIndex() { const t = doc().querySelector(".item-type"); const m = t && /(\d+)\s*[..、]/.exec((t.textContent || "").trim()); return m ? parseInt(m[1], 10) : 0; } function letterOf(label, i) { const el = label.querySelector(".radioInput, .checkboxInput"); const m = el && /[A-Z]/.exec((el.textContent || "").trim()); if (m) return m[0]; const inp = label.querySelector("input[value]"); if (inp && /^[A-Z]$/.test(inp.value)) return inp.value; return String.fromCharCode(65 + i); } function indexOf(item) { const te = item.querySelector && item.querySelector(".item-type"); const m = te && /(\d+)\s*[..、]/.exec((te.textContent || "").trim()); return m ? parseInt(m[1], 10) : 0; } function questionItems() { const all = doc().querySelectorAll(".subject-item"); const out = []; for (let i = 0; i < all.length; i++) if (all[i].querySelector && all[i].querySelector(".item-type")) out.push(all[i]); if (!out.length) { const c = doc().querySelector(".container-problem"); if (c) out.push(c); } return out; } function optionCount() { const it = questionItems()[0]; if (!it) return 0; const ls = it.querySelectorAll("label.el-radio, label.el-checkbox"); return ls ? ls.length : 0; } function barButton(re) { const bs = (doc().querySelector(".problem-fixedbar") || doc()).querySelectorAll("button, .el-button"); for (let i = 0; i < bs.length; i++) { const b = bs[i]; const txt = (b.textContent || "").replace(/\s+/g, ""); if (!re.test(txt)) continue; if (b.disabled || b.className.indexOf("is-disabled") !== -1) return null; return b; } return null; } function tabFor(n) { const all = doc().querySelectorAll(".subject-item"); for (let i = 0; i < all.length; i++) { const el = all[i]; if (el.querySelector && el.querySelector(".item-type")) continue; const o = el.getAttribute && el.getAttribute("data-order"); if (o && parseInt(o, 10) === n) return el; if (!o) { const t = (el.textContent || "").replace(/\s+/g, ""); const m = /^(\d+)\D{0,2}$/.exec(t); if (m && parseInt(m[1], 10) === n) return el; } } return null; } function tabAnswered(n) { const t = tabFor(n); return !!(t && t.querySelector && t.querySelector(".status-container .icon-status")); } function answeredNow() { const box = questionItems()[0] || doc().querySelector(".container-problem"); const t = box && box.textContent || ""; if (DONE_RE.test(t)) return true; if (tabAnswered(currentIndex())) return true; const ls = box && box.querySelectorAll && box.querySelectorAll("label.el-radio, label.el-checkbox"); if (ls && ls.length) { let dis = 0; for (let i = 0; i < ls.length; i++) { const L = ls[i]; const inp = L.querySelector && L.querySelector("input"); if (L.className.indexOf("is-disabled") !== -1 || inp && inp.disabled) dis++; } if (dis === ls.length) return true; } return false; } function rejectToast() { const ms = doc().querySelectorAll(".el-message, .el-message__content, .el-notification, .toast, .van-toast, [class*=\"toast\"]"); for (let i = 0; i < (ms ? ms.length : 0); i++) if (REJECT_RE.test(ms[i].textContent || "")) return true; return false; } function submitted() { return answeredNow() || !barButton(SUBMIT_RE); } /** * 数一遍题号格子:这份作业一共几题、其中几题已经答过。 * * 用途是隔着帧回答课程页的「这道作业到底做完没有」。 * 不看 state.EX —— 那是接口解出来的题目,用户半路接手时可能压根没抓到; * 题号格子是页面自己渲染的,半途进来也数得准。 * * 上限 200 纯粹是防呆,正常作业远到不了;tabFor 返回 null 就停。 */ function tabProgress() { let total = 0; let done = 0; for (let n = 1; n <= 200; n++) { if (!tabFor(n)) break; total++; if (tabAnswered(n)) done++; } return { done, total }; } //#endregion //#region src/runner/clock.ts /** * 「等页面站稳」的统一口径。 * * 翻页之后必须等页面站稳再动手。只看 DOM 会在这里翻车: * 题号和选项都已经换成第 1 题了,Vue 内部还指着第 2 题,这时候点提交, * 答案会被记到第 2 题上,第 1 题反而收到「you do not have chance to answer」 * —— 实测就是这么丢的。 * * 题号什么时候变的,由一个 200ms 的哨兵盯着(tick 是 1.2 秒一拍,太粗, * 而且它在 stepping 期间直接 return,正好漏掉翻页那一刻)。 * navAge() = 距离上次题号变化过了多久,所有「等站稳」都以它为准。 */ /** * 三档缓冲时间。做成可变对象而不是 const,是为了让测试能把 POST_SUBMIT_HOLD 改成 0 * 去验证那条回归哨兵(改成 0 必须能复现「第1题的提交落到了第2题」)。 * 生产代码一律不要改它。 */ var TIMING = { /** 翻页后至少静置这么久才认为页面站稳了 */ NAV_GRACE: 2500, /** 点「提交」这一下最危险,等得比翻页还久一点 */ SUBMIT_GRACE: 3500, /** 提交落地到真正翻页之间,再压一段(见 step.ts 的 submitThenNext) */ POST_SUBMIT_HOLD: 2500 }; var navIdx = 0; var navAt = 0; var navTimer = null; function watchNav() { const i = currentIndex(); if (i !== navIdx) { navIdx = i; navAt = Date.now(); } } function navAge() { return navAt ? Date.now() - navAt : 1e9; } /** * 启动 200ms 的题号哨兵。 * 只能由脚本入口调用一次 —— 放在模块顶层会让测试永远关不掉它。 */ function startNavWatch() { if (navTimer) return; watchNav(); navTimer = setInterval(watchNav, 200); } /** * 轮询等一个条件成立。 * 翻题流程全程等状态,绝不用固定 setTimeout 硬等 —— * 提交和翻页都是异步的,用固定延迟一定会在慢一拍的时候漏题(实测漏过第 2、3 题)。 */ function waitFor(test, timeout, cb) { const t0 = Date.now(); (function poll() { let r; try { r = test(); } catch (e) { r = false; } if (r) { cb(r); return; } if (Date.now() - t0 > timeout) { cb(null); return; } setTimeout(poll, 200); })(); } /** 题号是目标题、选项已渲染、且静置够久 —— 三条同时成立才算站稳 */ function waitSettled(n, cb) { waitFor(function() { return currentIndex() === n && optionCount() > 0 && navAge() >= TIMING.NAV_GRACE; }, 25e3, function(r) { cb(!!r && currentIndex() === n); }); } //#endregion //#region src/runner/context.ts var state = { EX: null, seenFont: null, filled: {}, tries: {}, rewound: false, announced: false }; /** 默认实现是空转,接 easy-us 时由 scripts/answer.ts 覆盖掉 */ var hooks = { log: () => void 0, getCfg: (_key, dflt) => dflt, setCfg: () => void 0, onAllDone: () => void 0 }; function setHooks(h) { Object.assign(hooks, h); } /** 重新抓题 / 测试复位时用 */ function resetState() { state.EX = null; state.seenFont = null; state.filled = {}; state.tries = {}; state.rewound = false; state.announced = false; } function say$1(msg) { hooks.log(msg); } //#endregion //#region src/runner/lock.ts /** * 流程互斥锁 + 代际令牌。 * * 每条流程带一个代号。超时的老流程(waitFor 最长要等 25 秒)醒过来时, * 新流程可能已经在跑了 —— 老流程这时候解锁,新流程就会在页面还没站稳的时候动手, * 答案正好记到上一题上。所以解锁只认自己的代号,过期的一律当没发生。 */ var stepping = false; var steppingAt = 0; var stepSeq = 0; function isStepping() { return stepping; } function steppingSince() { return steppingAt; } function lock() { stepping = true; steppingAt = Date.now(); return ++stepSeq; } function stale(tok) { return tok !== void 0 && tok !== stepSeq; } function unlock(tok) { if (stale(tok)) return; stepping = false; } /** 连带把在跑的老流程作废 */ function forceUnlock() { stepSeq++; stepping = false; } /** * 出了对不上号的事就立刻停手:这类操作不可逆,宁可停下来让人看一眼。 * 提交被拒、或者要交的题和页面上的题对不上,都走这里。 */ function halt(msg) { hooks.setCfg("ai_go", false); forceUnlock(); say$1("⚠️ " + msg + "\n已自动关掉「自动提交并翻页」,请手动确认这一题。"); } //#endregion //#region src/runner/nav.ts /** * 翻页与点击。 * * 和 exercise/dom.ts 的分工:那边只读判断、绝无副作用,这边负责真的点下去。 * * 硬约束: * - 灰掉的按钮不硬点(barButton 已经过滤过 disabled / is-disabled) * - clickNext 额外过一遍提交/保存/确认黑名单做双保险 —— * 有的版本最后一题的「下一题」位置上是「交卷」,点下去不可逆 * - 翻页认准 idx+1,不是「题号变了就算数」。页面偶尔会一下跳两题,那就漏了一道 */ function gotoIndex(n, cb, left, noTab) { const cur = currentIndex(); if (cur === n) { cb(true); return; } if (left === void 0) left = 12; if (left <= 0) { cb(false); return; } const tab = noTab ? null : tabFor(n); if (tab) { tab.click(); waitSettled(n, function(r) { if (r) { cb(true); return; } gotoIndex(n, cb, left - 1, true); }); return; } const b = barButton(n < cur ? /^(上一题|上一道|上一步)/ : /^(下一题|下一道|下一步)/); if (!b) { cb(false); return; } b.click(); waitFor(function() { const c = currentIndex(); return c && c !== cur && optionCount() > 0; }, 15e3, function(r) { if (!r) { cb(false); return; } if (currentIndex() === n) { waitSettled(n, cb); return; } gotoIndex(n, cb, left - 1, noTab); }); } //#endregion //#region src/runner/step.ts /** * 一道题的完整流程:填 →(可选)交 →(可选)翻页。 * * 全程等状态,绝不用固定 setTimeout 硬等 —— 只有 POST_SUBMIT_HOLD 那一处是例外, * 而那一处要的就是一段固定缓冲,理由见 submitThenNext 里的注释。 * * 这个文件里每一条等待、每一次复查,背后都是一个实测复现过的 bug。 * 改之前先读 legacy/README.md 的「设计上的硬约束」。 */ /** 面板位置微调(避让底栏)之类的每拍杂活,由 UI 层注入 */ var onTick = null; function setTickHook(fn) { onTick = fn; } function fillCurrent() { const EX = state.EX; if (!EX || !EX.answers) return false; const items = questionItems(); if (!items.length) { say$1("没找到题目容器"); return false; } const done = []; const skipped = []; let only = 0; for (let k = 0; k < items.length; k++) { const item = items[k]; const idx = indexOf(item) || (items.length === 1 ? currentIndex() : 0); const ans = EX.answers[idx]; if (!ans) { skipped.push("第" + (idx || "?") + "题没答案"); continue; } const labels = item.querySelectorAll("label.el-radio, label.el-checkbox"); if (!labels.length) { skipped.push("第" + idx + "题无选项"); continue; } const multi = labels[0].className.indexOf("el-checkbox") !== -1; const want = {}; for (const ch of ans) want[ch] = 1; for (let i = 0; i < labels.length; i++) { const L = labels[i]; const letter = letterOf(L, i); const checked = L.className.indexOf("is-checked") !== -1; if (want[letter] && !checked) L.click(); else if (!want[letter] && checked && multi) L.click(); } done.push(idx + ":" + ans); only = idx; } if (!done.length) { say$1(skipped.join("、") || "没有可填的题"); return false; } say$1("已勾 " + done.join(" ") + (hooks.getCfg("ai_go", false) ? "" : "(未提交)") + (done.length === 1 && EX.why && EX.why[only] ? "\n" + EX.why[only] : "") + (skipped.length ? "\n跳过:" + skipped.join("、") : "")); return true; } function step() { if (isStepping()) return; const idx = currentIndex(); if (!idx) return; if (!optionCount()) return; const tok = lock(); state.filled[idx] = true; state.tries[idx] = (state.tries[idx] || 0) + 1; try { if (answeredNow()) { say$1("第 " + idx + " 题之前已作答,跳过"); if (!hooks.getCfg("ai_go", false)) { unlock(tok); return; } goNext(idx, tok); return; } if (!fillCurrent()) { if (state.tries[idx] < 3) { state.filled[idx] = false; unlock(tok); say$1("第 " + idx + " 题这次没填上,稍后重试(" + state.tries[idx] + "/3)"); return; } say$1("第 " + idx + " 题填不上,跳过这一题"); if (!hooks.getCfg("ai_go", false)) { unlock(tok); return; } goNext(idx, tok); return; } if (!hooks.getCfg("ai_go", false)) { unlock(tok); return; } submitThenNext(idx, tok); } catch (e) { unlock(tok); say$1("第 " + idx + " 题出错:" + (e instanceof Error && e.message || String(e))); } } function rewind() { if (isStepping()) return; const idx = currentIndex(); if (!idx || !optionCount()) return; if (idx === 1) { state.rewound = true; return; } const tok = lock(); say$1("页面停在第 " + idx + " 题,先退回第 1 题…"); gotoIndex(1, function(ok) { if (stale(tok)) return; state.rewound = true; unlock(tok); say$1(ok ? "已回到第 1 题" : "退不回第 1 题,从第 " + currentIndex() + " 题开始"); }); } function submitThenNext(idx, tok) { waitFor(function() { return currentIndex() === idx && navAge() >= TIMING.SUBMIT_GRACE && barButton(SUBMIT_RE); }, 25e3, function(btn) { if (stale(tok)) return; if (currentIndex() !== idx) { halt("要交第 " + idx + " 题,页面却跳到了第 " + currentIndex() + " 题"); return; } if (!btn) { say$1("第 " + idx + " 题:「提交」一直是灰的,跳过提交"); goNext(idx, tok); return; } if (currentIndex() !== idx || navAge() < TIMING.SUBMIT_GRACE) { say$1("第 " + idx + " 题:临提交前页面又动了,这一题放弃提交"); goNext(idx, tok); return; } btn.click(); waitFor(function() { return rejectToast() || tabAnswered(idx) || currentIndex() === idx && submitted(); }, 2e4, function(r) { if (stale(tok)) return; if (rejectToast()) { halt("第 " + idx + " 题被服务端拒绝作答,这一题的提交可能记到别的题上了"); return; } if (!r) say$1("第 " + idx + " 题:没等到提交结果,继续往下"); setTimeout(function() { if (stale(tok)) return; goNext(idx, tok); }, TIMING.POST_SUBMIT_HOLD); }); }); } function goNext(idx, tok) { if (stale(tok)) return; const EX = state.EX; if (!EX || idx >= EX.list.length) { unlock(tok); say$1("全部 " + (EX ? EX.list.length : 0) + " 题处理完毕。"); if (EX && !state.announced) { state.announced = true; hooks.onAllDone(EX.list.length); } return; } const want = idx + 1; if (currentIndex() === want) { waitSettled(want, function() { unlock(tok); }); return; } gotoIndex(want, function(ok) { if (stale(tok)) return; unlock(tok); if (!ok) say$1("第 " + idx + " 题:没能翻到第 " + want + " 题"); }); } var lastIdx = 0; var sameFor = 0; function tick() { if (onTick) onTick(); if (!state.EX || !state.EX.answers || !hooks.getCfg("ai_auto", false)) return; if (isStepping()) { if (Date.now() - steppingSince() > 9e4) { const stuck = currentIndex(); forceUnlock(); if (stuck) state.filled[stuck] = false; say$1("上一步卡了 90 秒没动静,已解锁,从第 " + (stuck || "?") + " 题重试"); } return; } if (!state.rewound) { rewind(); return; } const idx = currentIndex(); if (idx === lastIdx) sameFor++; else { lastIdx = idx; sameFor = 0; } if (idx && !state.filled[idx] && sameFor >= 1 && navAge() >= TIMING.NAV_GRACE) { idleAt = Date.now(); step(); return; } watchIdle(idx); } var idleAt = Date.now(); var idleSaid = 0; function watchIdle(idx) { if (!idx) return; if (!hooks.getCfg("ai_go", false)) { idleAt = Date.now(); return; } const EX = state.EX; if (EX && idx >= EX.list.length && answeredNow()) { idleAt = Date.now(); return; } if (Date.now() - idleAt < 4e4) return; idleAt = Date.now(); if (idleSaid >= 3) { say$1("第 " + idx + " 题反复推不动,请手动处理这一题"); return; } idleSaid++; state.filled[idx] = false; state.tries[idx] = 0; say$1("第 " + idx + " 题停了 40 秒没进展(" + (!optionCount() ? "选项没渲染" : EX && EX.answers && !EX.answers[idx] ? "这题没有 AI 答案" : "原因不明") + "),重试一次"); } //#endregion //#region src/ui/place.ts /** * 看着浮窗:挂没挂上、在不在视口里。 * * easy-us 把窗口挂进页面的方式很随意(interfaces/custom-window.js 的 mount): * * parent.children[$.random(0, parent.children.length - 1)].after(this.wrapper) * * —— 随机插在 document.body 某个子节点后面,而且只挂这一次。 * 雨课堂的课程页是 Vue SPA,挂载时机(readystatechange → interactive)正好在 * 应用自己重建 body 之前,宿主 div 被冲掉就再也回不来了。 * 实测现象:customElements 里 container-element 已经注册(说明窗口造出来了), * 但 document.body 的直接子节点里找不到那个零属性的宿主 div。 * * 所以这里不信任「挂一次就完事」,改成一直盯着:掉了就重新挂回去。 * 检查本身只是一次 Node.contains,1 秒一轮的开销可以忽略。 * * 位置也一起管:easy-us 自带的越界防护只看左上角坐标有没有超出 * clientWidth / clientHeight,不看窗口自身的宽高,坐标合法但大半露在视口外它不管。 * * 只改内联样式,不回写 cfg.x / cfg.y —— 拖动时框架自己会存, * 我们再插一脚会和用户的拖动抢方向盘。 */ /** * 拿到真正带坐标的那个元素。 * * 注意不是 $elements.wrapper:wrapper 只是挂 closed Shadow DOM 的宿主 div, * 它自己在文档流里是个零尺寸的空壳,量它的 getBoundingClientRect 永远是 0, * 改它的 style.top 也不会让面板动一下。真正 position:fixed 定位的是 * shadow root 里的 (样式见 assets/panel.css)。 */ function box() { const root = import_lib.$elements.root; if (!root) return null; return root.querySelector("container-element"); } function clamp() { const el = box(); if (!el) return; const r = el.getBoundingClientRect(); if (!r.width || !r.height) return; const maxX = Math.max(0, document.documentElement.clientWidth - r.width); const maxY = Math.max(0, document.documentElement.clientHeight - r.height); const x = Math.min(Math.max(0, el.offsetLeft), maxX); const y = Math.min(Math.max(0, el.offsetTop), maxY); if (x !== el.offsetLeft) el.style.left = x + "px"; if (y !== el.offsetTop) el.style.top = y + "px"; } /** * 自检。 * * 面板挂在 **closed** Shadow DOM 里,页面控制台和 DevTools 的 Elements 搜索都进不去 * (wrapper.shadowRoot 恒为 null),只有脚本自己能看。所以把探针挂到页面 window 上, * 出问题时在控制台敲 __ykt() 就能拿到面板的真实状态。 */ function report() { const w = import_lib.$elements.wrapper; const el = box(); const cs = el ? getComputedStyle(el) : null; const styleTags = el ? Array.from(el.querySelectorAll("style")) : []; const body = el ? el.querySelector(".body") : null; const hs = w ? getComputedStyle(w) : null; return { 宿主存在: !!w, 宿主在DOM里: !!w && document.body.contains(w), 宿主display: hs ? hs.display : null, 宿主visibility: hs ? hs.visibility : null, 宿主宽高: w ? w.offsetWidth + "x" + w.offsetHeight : null, 宿主父节点: w && w.parentElement ? w.parentElement.tagName + (w.parentElement.id ? "#" + w.parentElement.id : "") : null, 容器存在: !!el, 容器类名: el ? el.className : null, 容器子节点数: el ? el.children.length : 0, 样式标签数: styleTags.length, 样式字符数: styleTags.map((t) => (t.textContent || "").length), display: cs ? cs.display : null, position: cs ? cs.position : null, left: cs ? cs.left : null, top: cs ? cs.top : null, zIndex: cs ? cs.zIndex : null, 宽: el ? el.offsetWidth : 0, 高: el ? el.offsetHeight : 0, 矩形: el ? JSON.stringify(el.getBoundingClientRect()) : null, 面板正文长度: body ? body.innerHTML.length : -1 }; } /** 应急:强制恢复显示并挪到左上角。控制台敲 __ykt_reset() */ function reset() { const w = import_lib.$elements.wrapper; if (w) { if (!document.body.contains(w)) document.body.appendChild(w); forceHost(w); } const el = box(); if (!el) return "浮窗还没建出来"; el.className = "normal"; el.style.position = "fixed"; el.style.left = "20px"; el.style.top = "20px"; el.style.zIndex = "2147483647"; el.style.display = ""; return "已强制恢复显示"; } /** * 把宿主 div 摁成可见。 * * 宿主在 light DOM 里没有 class、没有 id、没有任何子节点,页面上一条 * `div:empty { display: none }` 之类的重置规则就能把它整个关掉。 * 宿主不渲染,里面的 container-element 就算 position:fixed 也量不出尺寸 —— * 实测自检报的就是 display:block / position:fixed / z-index:99999 全对, * 但 getBoundingClientRect 全是 0。 * * assets/panel.css 里的 :host 规则已经兜了一层,这里再用行内 !important 兜一层: * 行内 !important 的权重压得过页面里任何选择器,是最后一道保险。 */ var HOST_STYLE = [ ["display", "block"], ["visibility", "visible"], ["opacity", "1"], ["position", "static"], ["width", "auto"], ["height", "auto"], ["max-width", "none"], ["max-height", "none"], ["transform", "none"], ["filter", "none"], ["clip-path", "none"], ["contain", "none"], ["content-visibility", "visible"], ["pointer-events", "auto"] ]; function forceHost(w) { for (const [k, v] of HOST_STYLE) w.style.setProperty(k, v, "important"); } /** 只说一次,别把控制台刷爆 */ var warnedNoWrapper = false; var warnedRemount = false; /** 被 Ctrl+O / 三连击切成隐藏的话,本次加载纠正一次就好,别一直跟用户抢 */ var unhidOnce = false; var reported = false; function check() { const w = import_lib.$elements.wrapper; if (!w) { if (!warnedNoWrapper) { warnedNoWrapper = true; console.warn(LOG, "顶层帧没有创建浮窗。看看控制台有没有 easy-us 抛的错。"); } return; } if (!document.body.contains(w)) { document.body.appendChild(w); if (!warnedRemount) { warnedRemount = true; console.warn(LOG, "浮窗被页面从 DOM 里移走了,已重新挂回 document.body。"); } } forceHost(w); const el = box(); if (el && el.classList.contains("hidden") && !unhidOnce) { unhidOnce = true; el.className = "normal"; console.warn(LOG, "面板之前被切成了隐藏状态(Ctrl+O / 三连击),已恢复显示。"); } clamp(); if (!reported && el && document.body.contains(import_lib.$elements.wrapper)) { reported = true; console.log(LOG, "面板自检:", report(), "(随时可在控制台敲 __ykt() 重查,__ykt_reset() 强制恢复)"); } } /** * 浮窗只在顶层帧存在(easy-us 的 start.js 里 `if (self === top)`), * 所以这个守望也只在顶层帧跑。 */ function watchPanel() { if (self !== top) return; try { const g = win(); g.__ykt = report; g.__ykt_reset = reset; } catch {} check(); setInterval(check, 1e3); window.addEventListener("resize", clamp); } /** * 面板避让底栏。 * * legacy 里这是 placePanel():面板和 .problem-fixedbar(提交 / 下一题那一条) * 都钉在同一个视口底部,会互相压住,所以要动态避让。 * * 现在只在「顶层帧自己就是题目页」的情况下才有意义 —— 正常走 lms-graph 时 * 底栏在 iframe 里,顶层帧查不到这个选择器,这里自然就是个空转。 * * 推完就不再重叠,下一拍自然不会再动 —— 会收敛,不会打架。 */ function dodgeFixedBar() { const el = box(); if (!el) return; const bar = document.querySelector(".problem-fixedbar"); const h = bar && bar.offsetHeight || 0; if (!h) return; const rect = el.getBoundingClientRect(); if (!rect.height) return; const overlap = rect.bottom - (window.innerHeight - h); if (overlap > 0) el.style.top = Math.max(0, rect.top - overlap) + "px"; } //#endregion //#region src/ui/panel.ts /** * 「🤖 AI 自动答题」的面板主体。 * * 和 legacy 的 mountPanel 相比少了一大半东西,因为这些活 easy-us 接管了: * - 浮窗本身、拖动、最小化 —— 框架的 CustomWindow * - 三个开关、Key / 模型 / 接口地址输入框、服务商下拉 —— 声明成 Script.configs 就自动渲染 * - 配置的持久化和跨帧同步 —— this.cfg 双向绑定,不用自己写 GM_getValue * * 还有一段 hack 可以整段删掉:legacy 为了对抗 Element-UI 的全局 reset, * 强行给 checkbox 写 appearance:auto / -webkit-appearance:checkbox 一堆内联样式。 * easy-us 的面板挂在 closed Shadow DOM 里,页面 CSS 进不来,不需要这些。 * * 这里只剩两个按钮和一行状态文字 —— 它们不是配置项,配置表单放不下。 * * ⚠️ 这个面板只会在 **顶层帧** 渲染(easy-us 的窗口是 self === top 才建的), * 而干活的代码在题目 iframe 里。所以状态文字要靠 setSayForward 往上送, * 按钮要靠 lms/bridge.ts 往下发。 */ var statusEl$1 = null; /** 滚动字幕那一行。空的时候整行收起来,不占版面 */ var thinkEl = null; /** 字幕也要攒着:面板可能比第一段思考过程晚渲染出来 */ var pendingThink = ""; /** 面板还没渲染出来时先攒着,渲染出来立刻补上(legacy 的 pending) */ var pending = "在 ⚙️ 里填好 API Key,然后点「🤖 解题」。当前:只勾选,不提交。"; /** 在题目帧里装上,把每一句状态转发给顶层面板;顶层帧不装 */ var forward = null; /** 同上,字幕专用。两条通道分开,免得高频字幕把状态文字的去重搅乱 */ var forwardThink = null; /** 题目帧专用:把状态文字接到跨帧通道上 */ function setSayForward(fn) { forward = fn; } /** 题目帧专用:把滚动字幕接到跨帧通道上 */ function setThinkForward(fn) { forwardThink = fn; } function say(msg) { pending = msg; if (statusEl$1) statusEl$1.textContent = msg; if (forward) forward(msg); } /** 顶层帧收到题目帧送上来的状态时用这个写面板,不能再转发回去,否则会来回弹 */ function showStatus(msg) { pending = msg; if (statusEl$1) statusEl$1.textContent = msg; } /** * 滚动字幕:模型正在想什么。 * * 这是进度条,不是日志 —— 只显示当前这一行,看过就扔, * 所以这里永远是覆盖(textContent =),绝不追加。空串表示收工,整行收起来。 */ function sayThink(line) { pendingThink = line; paintThink(); if (forwardThink) forwardThink(line); } /** 顶层帧收到题目帧送上来的字幕时用这个,不再转发回去 */ function showThink(line) { pendingThink = line; paintThink(); } function paintThink() { if (!thinkEl) return; thinkEl.textContent = pendingThink ? "💭 " + pendingThink : ""; thinkEl.style.display = pendingThink ? "block" : "none"; } function button(label, title, primary) { const b = document.createElement("button"); b.textContent = label; b.title = title; b.style.cssText = "cursor:pointer;border:1px solid #dcdfe6;border-radius:5px;padding:6px 9px;font:inherit;" + (primary ? "flex:1;border-color:#1677ff;background:#1677ff;color:#fff" : "background:#fafafa"); return b; } /** 面板里那行灰色小字的统一样式 */ var STATUS_CSS = "margin-top:7px;color:#909399;white-space:pre-wrap;word-break:break-all;max-height:160px;overflow:auto;font:12px/1.5 inherit"; /** * 往 easy-us 的面板主体里塞自定义内容。 * 面板每次展开 / 切换都会重新渲染,所以这里必须是幂等的 —— 先清空再画。 */ function renderPanelBody(body, actions) { body.replaceChildren(); const row = document.createElement("div"); row.style.cssText = "display:flex;gap:6px;margin-top:8px"; const go = button("🤖 解题", "有答案就填上;没答案就问 AI", true); const re = button("🔄", "重新抓题", false); go.addEventListener("click", actions.solve); re.addEventListener("click", actions.refetch); row.append(go, re); const st = document.createElement("div"); st.style.cssText = STATUS_CSS; st.textContent = pending; const th = document.createElement("div"); th.style.cssText = "margin-top:4px;color:#b0b3b8;font:11px/1.6 inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"; body.append(row, st, th); statusEl$1 = st; thinkEl = th; paintThink(); } //#endregion //#region src/scripts/answer.ts /** * 🤖 AI 自动答题。 * * ⚠️ 这个脚本在两种帧里跑,干的事完全不同: * * 题目帧(/v2/web/iframe-exercise/…) 真正干活的地方。 * hook ajax 拿题、解字体、问 AI、勾选项、提交翻页。 * 这一帧里 **没有面板** —— easy-us 的浮窗只在顶层帧创建 * (lib/utils/start.js 的 `if (self === top)`)。 * * 顶层帧(/ai-workspace/lms-graph/…/exercise/…) 只有面板。 * 它自己既抓不到题也点不了选项(DOM 全在 iframe 里), * 所以按钮要隔着帧发下去、状态要隔着帧送上来,走 lms/bridge.ts。 * * 用户直接打开 iframe-exercise 的地址时这两种帧重合,那就本地直调,不绕 cors。 * * 配置全部声明成 configs 交给 easy-us:它负责渲染表单、持久化、跨帧同步, * 所以 legacy 里那套 cfg() / setCfg() / GM_getValue 和手写的输入框全删了。 * * ⚠️「② 自动提交并翻页」默认关,关着时这个脚本绝不会点任何提交按钮。 * 唯一的闸门在 runner/step.ts 的 step() 里读 ai_go。 */ var started = false; var busy = false; /** * 这一帧是不是真正装着题目的那一帧。 * * 必须按 URL 判断而不是按 self === top:顶层的 lms-graph 地址里也带 /exercise/, * 光看 matches 两种帧都命中,但只有 iframe-exercise 那一帧里有题目 DOM。 * 每次现算不缓存 —— SPA 会改 URL。 */ function isExerciseFrame() { return /\/iframe-exercise\//i.test(location.href); } /** * 读配置。指向当前 Script 实例的 this.cfg,在 onstart 里装上。 * 做成模块级而不是 Script.methods:methods 的类型在 Script 内部推不出来, * 而 aiConf / provId 要的就是一个 (key) => unknown 的纯函数。 */ var read$1 = () => void 0; /** * 把一份接口 JSON 喂进解析链。两个入口共用: * - hookAjax 拦到页面自己发的 get_exercise_list * - doRefetch 自己补发的那一次 */ function ingest(raw) { captureJson(raw, { seenFont: () => state.seenFont, loadFont, log: say, onBatchStart: (font) => { state.seenFont = font; state.filled = {}; state.rewound = false; setActiveFont(font); }, onExercise: (ex) => { state.EX = ex; say("已解出 " + ex.list.length + " 题:" + ex.name); if (read$1("ai_auto") && aiConf(read$1).key) solve(); } }); } /** * 补发一次题目请求。 * * 两件事一件都不能省: * 1. 先把 seenFont 清掉 —— captureJson 开头有去重(同一份 font 直接 return), * 不清的话重抓同一份作业会被静默吞掉,界面上就是点了 🔄 什么也没发生。 * 2. 必须拿回调里的 raw 显式喂给 ingest。refetch 用的是本脚本作用域里的裸 fetch, * 而 hookAjax 替换的是 unsafeWindow 上的 fetch 属性 —— 这两个是不是同一个对象, * 由脚本管理器的沙箱实现决定,不能赌。legacy 也从不赌:它清掉 seenFont 之后显式调 captureJson。 * * 显式调不会造成重复处理:万一沙箱确实转发到了被 hook 的那个 fetch, * 钩子会先跑一遍 ingest 并把 seenFont 设成 d.font,等回调里再调一次就被去重挡掉; * 反过来也一样。两条路径至多生效一条 —— 不会问两遍 AI,也不会重复解字体。 */ function doRefetch() { state.seenFont = null; refetch((err, raw) => { if (err) { say("抓题失败:" + err); return; } ingest(raw); }); } /** 面板上「🤖 解题」按下去的完整分支,和 legacy 一致 */ function solve() { if (state.EX && state.EX.answers) { fillCurrent(); return; } if (state.EX) { askAll({ ex: state.EX, read: read$1, log: say, isBusy: () => busy, setBusy: (v) => { busy = v; }, onAnswers: (answers, why) => { if (!state.EX) return; state.EX.answers = answers; state.EX.why = why; }, onReady: () => fillCurrent(), tick: sayThink }); return; } say("没抓到题目,正在补请求…"); doRefetch(); } /** 🔄 重新抓题 */ function refetchAll() { resetState(); say("重新抓题…"); doRefetch(); } /** * 面板按钮的统一出口。 * 面板在顶层帧,引擎在题目帧 —— 同一帧就直接调,不同帧就隔着 cors 发下去。 */ function dispatch(cmd) { if (isExerciseFrame()) { if (cmd === "solve") solve(); else refetchAll(); return; } showStatus("已把「" + (cmd === "solve" ? "解题" : "重新抓题") + "」发给题目页,等它回话…"); sendCmd(cmd); } var answerScript = new import_lib.Script({ name: "🤖 AI 自动答题", namespace: "ykt.answer", matches: [["雨课堂题目页", /exercise/i]], configs: { notes: { defaultValue: "选服务商、填 API Key(点下面的「申请」去领,都有免费额度),然后点「🤖 解题」。
⚠️ 提交不可逆。自动化默认全关,关着时只勾选项、绝不点提交。" }, ai_provider: { label: "服务商", tag: "select", options: PROV_ORDER.map((id) => ({ label: PROVIDERS[id].name + "(" + PROVIDERS[id].note + ")", value: id })), defaultValue: "deepseek", separator: "接入 AI" }, ...credConfigs(), ai_think: { label: "推理模式(更准,更慢)", attrs: { type: "checkbox", title: "让模型先想再答。这家不支持推理时这个勾不起作用" }, defaultValue: true }, ai_search_key: { label: "联网搜索 Key", attrs: { type: "password", placeholder: "留空就用上面 Kimi 那一栏的 Key" }, defaultValue: "", separator: "联网搜索(所有模型通用)" }, ai_search_sites: { label: "只搜这几个站", attrs: { type: "text", placeholder: "逗号分隔,最多 5 个;留空就全网搜", title: "填上你常用的题库站域名,检索就会钉在这几个站里,比全网搜准得多" }, defaultValue: "" }, ai_auto: { label: "① 自动解题并填入", attrs: { type: "checkbox", title: "抓到题目后自动问 AI 并勾上选项。只勾不交,勾错了你随时能自己改" }, defaultValue: false, separator: "自动化(从上往下逐级打开,③ 在「📚 作业跳转」里)" }, ai_go: { label: "② 自动提交并翻到下一题", attrs: { type: "checkbox", title: "⚠️ 提交不可逆。先用 ① 跑几道确认答得对,再开这个" }, defaultValue: false }, ai_debug: { label: "把思考过程打进控制台", separator: "排查", attrs: { type: "checkbox", title: "F12 打开控制台,能看到完整的请求体、思考过程 CoT 和原始返回。答错了想知道它怎么想的就开这个" }, defaultValue: false } }, onstart() { if (started) return; started = true; read$1 = (key) => this.cfg[key]; if (!isExerciseFrame()) return; if (self !== top) { setSayForward(reportStatus); setThinkForward(reportThink); } setHooks({ log: say, getCfg: (key, dflt) => { const v = this.cfg[key]; return v === void 0 ? dflt : v; }, setCfg: (key, value) => { this.cfg[key] = value; }, onAllDone: (total) => { say("通知课程页:这份作业 " + total + " 题已全部提交"); reportAllDone(total); } }); hookAjax(ingest); }, oncomplete() { if (isExerciseFrame()) { serveExerciseFrame({ solve, refetch: refetchAll }); serveProgress(tabProgress); startNavWatch(); setTickHook(dodgeFixedBar); setInterval(tick, 1200); } else { onExerciseStatus(showStatus); onExerciseThink(showThink); } }, onrender({ panel }) { renderPanelBody(panel.body, { solve: () => dispatch("solve"), refetch: () => dispatch("refetch") }); } }); //#endregion //#region src/clipboard/oncopy.ts /** * 复制拦截。搬自 ykt_template.js 源 317-438 行(mapChars / buildDecrypted / onCopy / diagnose)。 * * 唯一的改动:**配置读取由调用方注入**。 * 旧版这里有个 cfg(key, dflt) 直接读 GM_getValue(源 312-315 行),onCopy 开头 * `if (!cfg('enabled', true)) return;`。现在配置归 easy-us 的 Script.cfg 管, * 那是个带响应式的面板配置,不是 GM_getValue,而且这个模块不该知道配置存在哪、叫什么名字。 * 所以 cfg 整个删掉,改成 installCopyHook({ enabled }) 由调用方传一个「现读」的回调进来 —— * 必须是回调而不是布尔值:用户在面板上改开关是随时的,复制那一刻才读到的才算数。 * * 没有做成「强制解密」之类的额外开关,是因为 legacy/README.md 的硬约束在这儿卡死了: * 字体没解析好就不干预复制(宁可复制出乱码,也不要复制出看起来通顺的错字), * 而且只替换 .xuetangx-com-encrypted-font 内部的字符(混淆字表的 key 集合和 value 集合 * 相同,盲替换会毁掉正常中文)。任何「强行解密」的语义都只能靠破坏这两条来实现, * 所以这里不留这个口子;真要加,得先想清楚加的到底是什么。 */ function mapChars(s, m) { let out = ""; for (const ch of s) { const r = m.get(ch); out += r === void 0 ? ch : r; } return out; } function buildDecrypted(range, m) { const host = doc().createElement("div"); host.appendChild(range.cloneContents()); host.querySelectorAll(STRIP).forEach(function(n) { n.remove(); }); let changed = 0; function mapTextNodes(root) { const w = doc().createTreeWalker(root, NodeFilter.SHOW_TEXT); for (let n = w.nextNode(); n; n = w.nextNode()) { const out = mapChars(n.data, m); if (out !== n.data) { n.data = out; changed++; } } } const anchor = range.commonAncestorContainer; const anchorEl = anchor.nodeType === 1 ? anchor : anchor.parentElement; let hits; if (anchorEl && typeof anchorEl.closest === "function" && anchorEl.closest(".xuetangx-com-encrypted-font")) { hits = [anchorEl.closest(SELECTOR)]; mapTextNodes(host); } else { hits = Array.prototype.slice.call(host.querySelectorAll(SELECTOR)); hits.forEach(mapTextNodes); } if (changed === 0) return { text: null, changed: 0, hits }; host.style.cssText = "position:fixed;left:-99999px;top:0;white-space:pre-wrap;"; doc().body.appendChild(host); const text = host.innerText; host.remove(); return { text, changed, hits }; } var warned = false; /** 造一个 copy 监听器。配置从 opts 现读,模块自己不碰 GM_getValue */ function createCopyHandler(opts) { return function onCopy(e) { if (!opts.enabled()) return; if (!e.clipboardData) return; const sel = win().getSelection(); if (!sel || sel.isCollapsed || sel.rangeCount === 0) return; const m = readyMap(); if (!m) { if (!warned && doc().querySelector(".xuetangx-com-encrypted-font")) { warned = true; ensureFont(); console.warn(LOG, "字体尚未就绪,本次未干预。等一两秒再复制。"); } return; } let res; try { res = buildDecrypted(sel.getRangeAt(0), m); } catch (err) { console.warn(LOG, "处理选区失败,已放行原生复制:", err); return; } if (res.text === null) return; e.clipboardData.setData("text/plain", res.text); e.preventDefault(); }; } /** * 挂上 copy 拦截(旧版是 IIFE 里那句 document.addEventListener('copy', onCopy, true))。 * 返回卸载函数:easy-us 的脚本可能被停用,得能摘干净。 */ function installCopyHook(opts) { const onCopy = createCopyHandler(opts); doc().addEventListener("copy", onCopy, true); return function uninstall() { doc().removeEventListener("copy", onCopy, true); }; } function diagnose() { const lines = []; (function walk(w, path) { let d = null, href = "(跨域)"; try { href = w.location.href; d = w.document; } catch (e) {} if (!d) { lines.push({ frame: path, url: href, crossOrigin: true }); return; } const enc = d.querySelectorAll(SELECTOR); let url = null; try { const ss = d.querySelectorAll("style"); for (let i = ss.length - 1; i >= 0 && !url; i--) { const txt = ss[i].textContent; if (txt && txt.indexOf("exam-data-decrypt-font") !== -1) { const mm = FONT_URL_RE.exec(txt); if (mm) url = mm[1]; } } } catch (e) {} const ent = url ? cache.get(url) : null; lines.push({ frame: path, url: href, encCount: enc.length, font: url ? url.split("/").pop() : "(未找到)", state: ent ? ent.state : "(本 frame 未处理该字体)", mapped: ent && ent.map ? ent.map.size : 0, sample: Array.prototype.slice.call(enc, 0, 3).map(function(el) { const m = ent && ent.map; return el.textContent + (m ? " → " + mapChars(el.textContent, m) : ""); }) }); for (let k = 0; k < w.frames.length; k++) try { walk(w.frames[k], path + ">" + k); } catch (e) {} })(win().top, "top"); console.log(LOG, "诊断:"); console.table(lines.map(function(l) { return { frame: l.frame, 加密元素: l.encCount, 字体: l.font, 状态: l.state, 已还原: l.mapped }; })); lines.forEach(function(l) { if (l.sample && l.sample.length) console.log(LOG, l.frame, l.sample); }); console.log(LOG, "完整信息:", lines); } //#endregion //#region src/scripts/copy.ts /** * 📋 复制解密。 * * 匹配全站、document-start、每一帧都跑 —— 加密内容在 iframe 里, * **绝不能加 @noframes**,也不能只在顶层帧装监听。 * * 只改剪贴板,不动 DOM。页面显示的仍然是那套乱码字, * 这样 ocsjs 的「🔤 字体解密」就算开着也不会互相覆盖(虽然还是建议关掉它)。 */ var copyScript = new import_lib.Script({ name: "📋 复制解密", namespace: "ykt.copy", matches: [["雨课堂全站", /.*/]], configs: { notes: { defaultValue: "选中题目按 Ctrl-C,粘出来就是正确汉字 —— 只改剪贴板,页面显示原样不动。
普通中文照常复制,脚本不介入。
⚠️ 请关掉 ocsjs 的「🔤 字体解密」,它用的静态字表已经失效,开着会把页面改成另一套乱码。" }, enabled: { label: "复制解密", attrs: { type: "checkbox", title: "关掉之后 Ctrl-C 走浏览器原生复制,脚本完全不介入" }, defaultValue: true }, diagnose: { label: "出问题时用", attrs: { type: "button", value: "🔍 把当前帧状态打进控制台" }, defaultValue: "", onload() { this.addEventListener("click", diagnose); } } }, onstart() { installCopyHook({ enabled: () => this.cfg.enabled }); } }); //#endregion //#region src/lms/dom.ts /** * AI 学伴课程页侧栏的 DOM 层。选择器全部来自实测 DOM,改之前先看这里的注释。 * * ⚠️ ocsjs 在这块踩了两个坑,都不是语法错、不报错、只是静默失效,抄的时候别一起抄过来: * * 1. 展开态的标记类是 **is-expand**,而且挂在 **.expand-icon 的父节点 .nav-item-title** 上。 * ocsjs 查的是 `.expand-icon:not(.is-expanded )` —— .expand-icon 上永远没有 is-expanded, * 于是全部命中,它那个 5 轮循环就变成对每个章节点 5 次 toggle(奇数次), * 结果是把页面默认展开的章节全给合上了。 * * 2. 完成标记的真实类名是 **icon-yuanquangou-mianzhuang**。 * ocsjs 写 `.icon-yuanquangou` —— CSS 类选择器是精确 token 匹配不是前缀匹配, * 匹配不到,所以它的「过滤已完成」从来没生效过。 * 这里用 [class*="yuanquangou"] 做子串匹配,雨课堂换实心/空心图标也不会挂。 */ /** 一个任务项。作业平铺在顶层 .nav-item-list 下,视频在 .nav-item-child 里,都是这个类 */ var LEAF = ".leaf-item"; /** 未展开的章节头上的那个箭头。父节点没有 is-expand 才是真的没展开 */ var COLLAPSED_ARROW = ".nav-item-title:not(.is-expand) .expand-icon"; /** * 完成标记。真实类名是 icon-yuanquangou-mianzhuang,未完成时这个位置是 Vue 的空注释节点。 * 用子串匹配而不是写死类名:CSS 类选择器是精确 token 匹配, * 写 .icon-yuanquangou 匹配不到 icon-yuanquangou-mianzhuang(ocsjs 就是栽在这儿)。 */ var DONE_ICON = ".leaf-item-status [class*=\"yuanquangou\"]"; var sleep = (ms) => new Promise((r) => setTimeout(r, ms)); /** 标签文本实测是 "\n 作业\n ",空白必须全清掉 */ function tidy(el) { return (el?.textContent || "").replace(/\s+/g, ""); } function toView(el) { return { tag: tidy(el.querySelector(".leaf-item-tag")), title: (el.querySelector(".leaf-item-title")?.textContent || "").trim(), done: !!el.querySelector(DONE_ICON), active: el.classList.contains("is-active") }; } function leafElements() { return Array.from(doc().querySelectorAll(LEAF)); } function leafViews() { return leafElements().map(toView); } /** * 把所有折叠着的章节展开。 * * 只点没展开的,所以对「默认就是展开的」这种页面是彻底的空操作 —— 这正是 ocsjs 缺的那一下。 * 循环是因为展开一层会把下一层的章节头渲染出来,得再扫一遍; * 一轮下来没有可点的就立刻停,不会空转满 max 轮。 */ async function expandAll(max = 8) { let clicked = 0; for (let i = 0; i < max; i++) { const todo = Array.from(doc().querySelectorAll(COLLAPSED_ARROW)); if (todo.length === 0) break; for (const el of todo) { el.click(); clicked++; } await sleep(150); } return clicked; } /** 等侧栏渲染出来。SPA,进页面时 .leaf-item 还不存在 */ async function waitLeaves(timeout = 15e3) { const until = Date.now() + timeout; while (Date.now() < until) { if (leafElements().length > 0) return true; await sleep(300); } return false; } /** 点进某一项,并滚到可视区中间 */ async function openLeaf(index) { const el = leafElements()[index]; if (!el) return; el.click(); await sleep(200); el.scrollIntoView({ behavior: "smooth", block: "center" }); } //#endregion //#region src/lms/nav.ts var TAG_HOMEWORK = "作业"; /** * 挑出下一个该做的项,返回它在 views 里的下标,没有就返回 -1。 * * 顺序规则:先从当前项往后找,找不到再从头回绕一遍。 * 回绕是必须的 —— 作业在侧栏里是平铺的一长条,用户完全可能从中间点进去, * 前面还漏着没做的。ocsjs 的 getNextJob 用 splice(active_index) 直接把前半截扔了, * 那样前面漏的永远够不着。 */ function pickNext(views, opts) { const ok = (v) => v.tag === opts.tag && (opts.restudy || !v.done); const ai = views.findIndex((v) => v.active); const from = ai < 0 ? 0 : opts.includeActive ? ai : ai + 1; for (let i = from; i < views.length; i++) if (ok(views[i])) return i; for (let i = 0; i < Math.min(from, views.length); i++) if (ok(views[i])) return i; return -1; } /** 统计:面板上要显示「作业 3/10」 */ function countBy(views, tag) { const hit = views.filter((v) => v.tag === tag); return { done: hit.filter((v) => v.done).length, total: hit.length }; } /** 「跳转前等待」下拉框的选项。value 是字符串 —— easy-us 的 select 存的就是字符串 */ var DELAY_CHOICES = [ { value: "3", label: "3 秒(最短)", title: "几乎不给你反悔的时间" }, { value: "8", label: "8 秒(推荐)", title: "够扫一眼 AI 填的答案,不对就按「取消」" }, { value: "15", label: "15 秒", title: "慢慢看" }, { value: "30", label: "30 秒(近乎手动)", title: "基本等于每道都自己确认一次" } ]; /** * 读「跳转前等待」的秒数。 * * 下限锁 3 秒不是随便定的:交卷是异步的,题目帧喊「交完了」的时候回执可能还在路上, * 这会儿把 iframe 换掉,那条回执落地时里面已经是下一份作业了。 * 同 runner/clock.ts 里 POST_SUBMIT_HOLD 的道理,只是这里跨的是帧。 * 所以哪怕存进去的是 0,也要抬回 3。 */ function delaySeconds(raw) { const n = Math.floor(Number(raw)); if (!isFinite(n) || n <= 0) return 8; return Math.min(60, Math.max(3, n)); } //#endregion //#region src/ui/jump-panel.ts /** * 「📚 作业跳转」的面板主体。 * * 单独一个模块、不和 ui/panel.ts 共用模块级变量:两个脚本的面板会在同一帧里 * 先后渲染(lms-graph 的题目页两个脚本都匹配得上),共用一个 statusEl * 会让后渲染的那个把前一个的引用覆盖掉。 * * 比 ui/panel.ts 多一样东西:倒计时行。自动跳转不能说跳就跳 —— * 页面在眼皮底下自己换掉是很糟的体验,而且那会儿人可能正想看一眼 AI 答得对不对。 * 所以倒计时是看得见的,而且随时能按「取消」留下来。 */ var statusEl = null; var countRow = null; var countText = null; /** 面板还没渲染出来时先攒着,渲染出来立刻补上 */ var pendingStatus = "正在等侧栏加载…"; var pendingCount = ""; function jumpSay(msg) { pendingStatus = msg; if (statusEl) statusEl.textContent = msg; } /** 显示 / 刷新倒计时行 */ function showCountdown(text) { pendingCount = text; if (countText) countText.textContent = text; if (countRow) countRow.style.display = "flex"; } function hideCountdown() { pendingCount = ""; if (countRow) countRow.style.display = "none"; } function renderJumpBody(body, actions) { body.replaceChildren(); const row = document.createElement("div"); row.style.cssText = "display:flex;gap:6px;margin-top:8px"; const go = button("⏭ 下一道没做完的作业", "当前这道没做完就先做这道,做完了才往后翻", true); go.addEventListener("click", actions.next); row.append(go); const st = document.createElement("div"); st.style.cssText = STATUS_CSS; st.textContent = pendingStatus; const cd = document.createElement("div"); cd.style.cssText = "display:none;align-items:center;gap:6px;margin-top:7px;padding:6px 8px;border:1px solid #ffe58f;background:#fffbe6;border-radius:5px;font:12px/1.5 inherit"; const txt = document.createElement("span"); txt.style.cssText = "flex:1;color:#874d00"; txt.textContent = pendingCount; const stop = button("取消", "留在这一页,不自动跳转", false); stop.style.padding = "2px 8px"; stop.addEventListener("click", actions.cancel); cd.append(txt, stop); body.append(row, st, cd); statusEl = st; countRow = cd; countText = txt; if (pendingCount) showCountdown(pendingCount); } //#endregion //#region src/scripts/jump.ts /** * 📚 作业跳转 —— AI 学伴课程页(/ai-workspace/lms-graph)。 * * 这一页只有侧栏导航,题目本身在右边的 iframe 里,由「🤖 AI 自动答题」接管。 * 本脚本干四件事:展开章节、找出下一道没做完的作业、点进去、等内层答完再往下走。 * * 排除手机版:/ai-workspace/lms-graph-mobile 的 DOM 不长这样, * 而字符串匹配是子串匹配,'lms-graph' 会把 mobile 一起吃掉,所以这里用正则断言。 */ /** 指向当前 Script 的 this.cfg。config 里 button 的 onload 拿不到 Script 实例,只能这么绕 */ var read = () => void 0; /** * 已经因为「做完了」而跳走过的作业标题。 * * 跨帧信号和侧栏轮询是两条独立的触发路径,同一道作业两条都可能响; * 内层帧还会因为看门狗解锁再喊一次。共用这一个集合,保证一道作业只跳一次 —— * 少了它就会一次连跳两道,中间那道直接被略过。 */ var jumped = /* @__PURE__ */ new Set(); /** * 本次会话里已经确认交完的作业标题。 * * 侧栏那个「已完成」圆圈勾是服务端下发的,刷新慢一拍 —— 四道题全交完了, * 侧栏还显示没做完,于是「⏭ 下一道」一直说「就是当前这道,先把它做完」。 * 这个集合是盖在侧栏状态上的一层修正:只要题目帧说交完了,就按交完算。 */ var finished = /* @__PURE__ */ new Set(); /** 侧栏状态 + finished 修正。除了读原始 DOM,其它地方一律用这个 */ function views() { return leafViews().map((v) => v.done || !finished.has(v.title) ? v : { ...v, done: true }); } function progress() { const c = countBy(views(), TAG_HOMEWORK); return "作业 " + c.done + "/" + c.total; } function activeTitle() { return views().find((v) => v.active)?.title || ""; } /** * 跳到下一道没做完的作业。 * includeActive=true 用于手动点按钮(当前这道没做完就先做这道,别莫名其妙往后跳)。 */ async function jumpNext(includeActive) { const list = views(); if (list.length === 0) { jumpSay("侧栏还没加载出来,等一下再点"); return false; } const i = pickNext(list, { tag: TAG_HOMEWORK, includeActive, restudy: !!read("lms_restudy") }); if (i < 0) { jumpSay("作业全做完了(" + progress() + ")。想重做就打开复习模式。"); import_lib.$message.success("作业全做完了"); return false; } if (list[i].active) { jumpSay("就是当前这道,先把它做完:" + list[i].title); return false; } jumpSay("跳转:" + list[i].title + " " + progress()); await openLeaf(i); return true; } /** * 「⏭ 下一道」按下去。 * * 不能直接信侧栏:它的完成勾是服务端下发的,交完卷要等下一次刷新才亮。 * 所以当侧栏说「当前这道没做完」时,先隔着帧问一句题目 iframe —— * 题号格子在那一帧里是实时的,四个格子全打勾就是真交完了。 * * 问不到(课程页上还没点开任何一道作业,没人应答)就退回原来的行为。 */ function manualNext() { const cur = views().find((v) => v.active); if (!cur || cur.tag !== "作业" || cur.done) { jumpNext(true); return; } jumpSay("侧栏说这道没做完,问一下题目页…"); askProgress((p) => { if (!p || p.total === 0) { jumpNext(true); return; } if (p.done >= p.total) { finished.add(cur.title); jumpSay("这道 " + p.total + " 题都交过了(侧栏还没刷新),继续往下找。"); jumpNext(false); return; } jumpSay("这道还有 " + (p.total - p.done) + " 题没交(" + p.done + "/" + p.total + "),先做完它:" + cur.title); }); } /** 正在走的倒计时;0 表示没有 */ var ticker = 0; function stopCountdown() { if (ticker) clearInterval(ticker); ticker = 0; hideCountdown(); } /** * 用户点了「取消」:留在这一页。 * 这道作业已经记进 jumped 了,所以不会再自己跳第二次;想走随时点「⏭」。 */ function cancelCountdown() { if (!ticker) { jumpSay("现在没有在倒计时"); return; } stopCountdown(); jumpSay("已取消,留在这一页。想走随时点「⏭」。"); } function startCountdown(why) { stopCountdown(); let left = delaySeconds(read("lms_delay")); const paint = () => showCountdown(why + "," + left + " 秒后切下一道"); paint(); ticker = window.setInterval(() => { left--; if (left > 0) { paint(); return; } stopCountdown(); jumpNext(false); }, 1e3); } /** 两条触发路径共用的收尾:记下这道已经跳过,然后往后走 */ function advanceFrom(title, why) { if (!title || jumped.has(title)) return; jumped.add(title); if (!read("lms_auto")) { jumpSay(why + "。自动跳转没开 —— 点「⏭」手动走下一道。"); return; } startCountdown(why); } var jumpScript = new import_lib.Script({ name: "📚 作业跳转", namespace: "ykt.jump", matches: [["AI学伴课程页", /\/ai-workspace\/lms-graph(?!-mobile)/]], configs: { notes: { defaultValue: "课程页侧栏助手:挑出没做完的作业、点进去,题目交给「🤖 AI 自动答题」。
上面的「⏭ 下一道」随时能手动跳,一个自动开关都不开也照样好用。
⚠️ ③ 要生效,得先在题目页把「② 自动提交并翻到下一题」打开,否则里面永远交不了卷。" }, lms_expand: { label: "进页面自动展开折叠的章节", attrs: { type: "checkbox", title: "只点折叠着的箭头,本来就展开的不会被合上" }, defaultValue: true, separator: "侧栏" }, lms_restudy: { label: "复习模式(已完成的也跳进去)", attrs: { type: "checkbox", title: "默认只挑没做完的;打开后已完成的也算候选,可以重做" }, defaultValue: false }, lms_auto: { label: "③ 一道交完自动跳下一道", attrs: { type: "checkbox", title: "⚠️ 会连着把整门课的作业做完。先用「⏭」手动跳一道,确认 AI 答得对再开" }, defaultValue: false, separator: "连跳(需要题目页先开到 ②)" }, lms_delay: { label: "跳转前等待", tag: "select", options: DELAY_CHOICES, defaultValue: "8", showIf: "ykt.jump.lms_auto" } }, async oncomplete() { read = (key) => this.cfg[key]; onExerciseDone((total) => { const title = activeTitle(); if (title) finished.add(title); advanceFrom(title, "这份作业 " + total + " 题已全部提交"); }); if (!await waitLeaves()) { jumpSay("侧栏一直没出来,刷新页面重试"); return; } if (this.cfg.lms_expand) { const n = await expandAll(); jumpSay(n > 0 ? "展开了 " + n + " 个折叠的章节。" + progress() : progress()); } else jumpSay(progress()); setInterval(() => { const cur = views().find((v) => v.active); if (!cur || cur.tag !== "作业" || !cur.done) return; advanceFrom(cur.title, "侧栏显示这道已完成"); }, 3e3); }, onrender({ panel }) { renderJumpBody(panel.body, { next: manualNext, cancel: cancelCountdown }); } }); //#endregion //#region src/project.ts var yktProject = import_lib.Project.create({ name: "雨课堂助手", domains: ["yuketang.cn"], scripts: { copy: copyScript, answer: answerScript, jump: jumpScript } }); //#endregion //#region assets/panel.css?raw var panel_default = "/*\n * 面板样式。\n *\n * 来源:ocsjs/packages/scripts/assets/css/style.css,原样复制。\n *\n * 为什么必须有这个文件:easy-us **自己不带任何 CSS**。\n * 它的 container-element / header-element / script-panel-element 都是裸自定义元素,\n * 没有样式的话 position 是默认的 inline,面板就是一堆纯文本直接掉在\n * document.body 里某个随机位置(mount() 真的是随机插的),\n * 在 SPA 里通常被 overflow:hidden 裁掉 —— 表现就是「脚本在跑但没有 UI」。\n *\n * 关键的一行是 `container-element { position: fixed }`(在下面 container-element 那一段)。\n *\n * 这是 ykt-pass 里唯一一处从 ocsjs 抄来的资源,改 easy-us 版本时留意元素名有没有变。\n */\n\n/*\n * 宿主 div 的兜底。\n *\n * :host 指的是 attachShadow 的那个
(easy-us 的 $elements.wrapper)。\n * 它在 light DOM 里没有任何子节点、没有 class、没有 id —— 也就是说页面上\n * 随便一条 `div:empty { display: none }` 之类的重置规则就能把它整个关掉。\n * 一旦宿主不渲染,里面的 container-element 哪怕是 position:fixed 也量不出尺寸:\n * getBoundingClientRect 全是 0,computed style 却还报 display:block —— 排查时极其迷惑。\n *\n * 页面样式的选择器权重通常压得过 :host,所以这几条必须带 !important。\n */\n:host {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n pointer-events: auto !important;\n /* 宿主本身不参与布局,面板靠 container-element 的 position:fixed 定位 */\n position: static !important;\n margin: 0 !important;\n padding: 0 !important;\n border: 0 !important;\n width: auto !important;\n height: auto !important;\n max-width: none !important;\n max-height: none !important;\n transform: none !important;\n filter: none !important;\n clip-path: none !important;\n contain: none !important;\n content-visibility: visible !important;\n}\n/** 默认字体 */\n/** 输入框默认边距 */\nul,\nol {\n line-height: 26px;\n padding-left: 22px;\n margin: 0px;\n}\na {\n color: #1890ff;\n}\nhr {\n border-style: solid;\n border-color: #63636346;\n border-width: 0px;\n border-bottom: 1px solid #63636346;\n margin-block-start: 1em;\n margin-block-end: 1em;\n}\n.base-style-active-form-control {\n border: 1px solid #ffffff00;\n}\n.base-style-active-form-control:focus {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n}\n.base-style-active-form-control:focus:not([type='checkbox'], [type='radio']) {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n background-color: white !important;\n}\n.base-style-active-form-control:hover {\n background-color: #ebeef4;\n}\n.base-style-input {\n outline: none;\n border: 1px solid #ffffff00;\n padding: 2px 8px;\n margin: 0px;\n background-color: #eef2f7;\n border-radius: 2px;\n color: black;\n}\n.base-style-input::placeholder {\n color: #bababa;\n}\n.base-style-switch {\n appearance: none;\n -moz-appearance: none;\n -webkit-appearance: none;\n width: fit-content;\n min-width: 48px;\n height: 20px;\n border-radius: 100px;\n display: flex;\n align-items: center;\n padding: 2px 4px;\n transition: all 0.2s ease-in-out;\n width: auto;\n background: gainsboro;\n}\n.base-style-switch:checked {\n background: #1890ff;\n}\n.base-style-switch:disabled {\n background-color: #f7f7f78b;\n}\n.base-style-switch:checked::before {\n transform: translate(24px, 0px);\n}\n.base-style-switch::before {\n background-color: #fff;\n border-radius: 9px;\n box-shadow: 0 2px 4px #00230b33;\n width: 14px;\n height: 14px;\n content: '';\n}\n.base-style-button {\n appearance: none;\n -moz-appearance: none;\n -webkit-appearance: none;\n border-radius: 4px;\n background-color: white;\n border: 1px solid #2c92ff;\n color: #409eff;\n cursor: pointer !important;\n margin-bottom: 4px;\n}\n.base-style-button:active {\n box-shadow: 0px 0px 8px #0e8de2a5;\n}\n.base-style-button + .base-style-button {\n margin-left: 12px;\n}\n.base-style-button:hover {\n background-color: #7abbff24;\n}\n.base-style-button.danger:hover {\n background-color: #ffdede86;\n}\n.base-style-button:disabled {\n background-color: white;\n border: 1px solid #c0c0c0;\n color: #aeaeae;\n cursor: not-allowed;\n}\n.base-style-button.danger {\n color: #f36669;\n border-color: #dd5a5d;\n}\n.base-style-button:disabled:active {\n box-shadow: none;\n}\n.base-style-button-secondary {\n appearance: none;\n -moz-appearance: none;\n -webkit-appearance: none;\n border-radius: 4px;\n border: 1px solid #2c92ff;\n color: #409eff;\n cursor: pointer !important;\n margin-bottom: 4px;\n color: gray;\n background-color: white;\n border: 1px solid #dcdcdc;\n}\n.base-style-button-secondary:active {\n box-shadow: 0px 0px 8px #0e8de2a5;\n}\n.base-style-button-secondary + .base-style-button-secondary {\n margin-left: 12px;\n}\n.base-style-button-secondary:hover {\n background-color: #7abbff24;\n}\n.base-style-button-secondary.danger:hover {\n background-color: #ffdede86;\n}\n.base-style-button-secondary:disabled {\n background-color: white;\n border: 1px solid #c0c0c0;\n color: #aeaeae;\n cursor: not-allowed;\n}\n.base-style-button-secondary.danger {\n color: #f36669;\n border-color: #dd5a5d;\n}\n.base-style-button-secondary:disabled:active {\n box-shadow: none;\n}\ncontainer-element.hidden {\n display: none;\n}\ncontainer-element.minimize {\n min-width: unset;\n}\ncontainer-element {\n position: fixed;\n top: 10%;\n left: 10%;\n z-index: 99999;\n text-align: left;\n min-width: 300px;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n color: #636363;\n box-shadow: 0 0 24px -12px #3f3f3f;\n border-radius: 8px;\n letter-spacing: 0.5px;\n border: 1px solid #c1c1c1;\n}\nheader-element {\n display: flex;\n align-items: center;\n background-color: white;\n border-radius: 8px 8px 0px 0px;\n user-select: none;\n padding: 4px;\n padding-bottom: 0px;\n}\nheader-element .extra-menu-bar {\n width: 100%;\n padding: 4px;\n padding-bottom: 0px;\n margin-top: 4px;\n border-top: 1px solid #e8e8e8;\n /** 默认隐藏,一直到需要激活的时候再更改 */\n display: none;\n}\nheader-element .extra-menu-bar .script-panel-link {\n appearance: none;\n -moz-appearance: none;\n -webkit-appearance: none;\n border-radius: 4px;\n border: 1px solid #2c92ff;\n color: #409eff;\n cursor: pointer !important;\n margin-bottom: 4px;\n color: gray;\n background-color: white;\n border: 1px solid #dcdcdc;\n padding-bottom: 2px;\n margin-bottom: 0px;\n}\nheader-element .extra-menu-bar .script-panel-link:active {\n box-shadow: 0px 0px 8px #0e8de2a5;\n}\nheader-element .extra-menu-bar .script-panel-link + header-element .extra-menu-bar .script-panel-link {\n margin-left: 12px;\n}\nheader-element .extra-menu-bar .script-panel-link:hover {\n background-color: #7abbff24;\n}\nheader-element .extra-menu-bar .script-panel-link.danger:hover {\n background-color: #ffdede86;\n}\nheader-element .extra-menu-bar .script-panel-link:disabled {\n background-color: white;\n border: 1px solid #c0c0c0;\n color: #aeaeae;\n cursor: not-allowed;\n}\nheader-element .extra-menu-bar .script-panel-link.danger {\n color: #f36669;\n border-color: #dd5a5d;\n}\nheader-element .extra-menu-bar .script-panel-link:disabled:active {\n box-shadow: none;\n}\nheader-element .extra-menu-bar .script-panel-link.active {\n background-color: #1890ff1a;\n border-color: #1890ff;\n color: #1890ff;\n}\nheader-element .extra-menu-bar .script-panel-link + .script-panel-link {\n margin-left: 4px;\n}\nheader-element .profile {\n flex: 1;\n cursor: move;\n}\nheader-element .switch:hover,\nheader-element .dropdown:hover {\n background-color: #f3f3f3;\n}\nheader-element .close:hover {\n background-color: #ff000038;\n}\nheader-element .switch,\nheader-element .close {\n cursor: pointer;\n}\nheader-element .dropdown {\n line-height: 24px;\n text-decoration: underline;\n}\nheader-element .switch,\nheader-element .close,\nheader-element .profile {\n display: inline-flex;\n align-items: center;\n padding: 0px 8px;\n}\n.logo {\n width: 18px;\n height: 18px;\n cursor: pointer;\n}\n.project-selector {\n display: flex;\n align-items: center;\n}\n.project-selector select {\n background: #ffffff00;\n border-radius: 4px;\n border: 1px solid #63636346;\n padding: 4px;\n}\n.project-selector.expand-all {\n display: none;\n}\n.body {\n overflow: auto;\n width: auto;\n height: 100%;\n}\nscript-panel-element {\n display: block;\n background-color: white;\n border-radius: 0px 0px 8px 8px;\n padding: 0px 8px 12px 8px;\n overflow: auto;\n}\nscript-panel-element .script-panel-body {\n padding: 0px 8px;\n}\nscript-panel-element + script-panel-element {\n margin-top: 12px;\n}\n.card + .card {\n margin-top: 12px;\n}\n.card {\n background-color: white;\n border-radius: 2px;\n padding: 0px 8px;\n}\n.notes {\n background: #0099ff0e;\n border-left: 4px solid #0099ff65;\n width: -webkit-fill-available;\n margin: 0px 8px;\n line-height: 26px;\n letter-spacing: 1px;\n}\n.secondary {\n font-size: 12px;\n color: #8b8b8b;\n}\n.tooltip-container {\n z-index: 99999999999999;\n margin: 12px 0px 0px 12px;\n padding: 4px;\n color: black;\n background: #f0f0f0;\n box-shadow: 0px 0px 4px #949494;\n position: fixed;\n white-space: normal;\n max-width: 200px;\n height: auto;\n border-radius: 2px;\n line-height: 18px;\n}\n.configs-container.lock {\n filter: blur(1px);\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n.configs-container .lock-wrapper {\n cursor: not-allowed !important;\n border-radius: 4px;\n position: absolute;\n left: 0px;\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n.configs-container .lock-message {\n background-color: #ffffff7d;\n border-radius: 4px;\n box-shadow: 0px 0px 12px #6a6a6a98;\n padding: 2px;\n}\n.configs {\n display: table;\n background: #e1e1e107;\n width: -webkit-fill-available;\n}\n.configs .configs-body {\n display: table-row-group;\n}\n.configs .configs-body config-element + config-element label {\n padding-top: 4px;\n}\n.configs .configs-body config-element + config-element .config-wrapper {\n padding-top: 4px;\n}\n.configs .configs-body config-element {\n width: 100%;\n display: table-row;\n line-height: 26px;\n}\n.configs .configs-body config-element label {\n white-space: nowrap;\n color: #4e5969;\n display: table-cell;\n padding-right: 12px;\n text-align: left;\n vertical-align: top;\n margin-right: 12px;\n}\n.configs .configs-body config-element .config-wrapper {\n display: table-cell;\n vertical-align: middle;\n /** check box 的样式 */\n}\n.configs .configs-body config-element .config-wrapper select {\n outline: none;\n border: none;\n border: 1px solid #e4e4e4;\n border-radius: 4px;\n padding: 2px 8px;\n border: 1px solid #ffffff00;\n}\n.configs .configs-body config-element .config-wrapper select:focus {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n}\n.configs .configs-body config-element .config-wrapper select:focus:not([type='checkbox'], [type='radio']) {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n background-color: white !important;\n}\n.configs .configs-body config-element .config-wrapper select:hover {\n background-color: #ebeef4;\n}\n.configs .configs-body config-element .config-wrapper textarea {\n padding: 2px 8px;\n outline: none;\n border: none;\n border: 1px solid #ffffff00;\n}\n.configs .configs-body config-element .config-wrapper textarea:focus {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n}\n.configs .configs-body config-element .config-wrapper textarea:focus:not([type='checkbox'], [type='radio']) {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n background-color: white !important;\n}\n.configs .configs-body config-element .config-wrapper textarea:hover {\n background-color: #ebeef4;\n}\n.configs .configs-body config-element .config-wrapper input:not([type='button']) {\n outline: none;\n padding: 2px 8px;\n margin: 0px;\n background-color: #eef2f7;\n border-radius: 2px;\n color: black;\n border: 1px solid #ffffff00;\n}\n.configs .configs-body config-element .config-wrapper input:not([type='button'])::placeholder {\n color: #bababa;\n}\n.configs .configs-body config-element .config-wrapper input:not([type='button']):focus {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n}\n.configs .configs-body config-element .config-wrapper input:not([type='button']):focus:not([type='checkbox'], [type='radio']) {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n background-color: white !important;\n}\n.configs .configs-body config-element .config-wrapper input:not([type='button']):hover {\n background-color: #ebeef4;\n}\n.configs .configs-body config-element .config-wrapper input[type='range'] {\n padding: 0px;\n}\n.configs .configs-body config-element .config-wrapper input[type='button'] {\n appearance: none;\n -moz-appearance: none;\n -webkit-appearance: none;\n border-radius: 4px;\n background-color: white;\n border: 1px solid #2c92ff;\n color: #409eff;\n cursor: pointer !important;\n margin-bottom: 4px;\n}\n.configs .configs-body config-element .config-wrapper input[type='button']:active {\n box-shadow: 0px 0px 8px #0e8de2a5;\n}\n.configs .configs-body config-element .config-wrapper input[type='button'] + .configs .configs-body config-element .config-wrapper input[type='button'] {\n margin-left: 12px;\n}\n.configs .configs-body config-element .config-wrapper input[type='button']:hover {\n background-color: #7abbff24;\n}\n.configs .configs-body config-element .config-wrapper input[type='button'].danger:hover {\n background-color: #ffdede86;\n}\n.configs .configs-body config-element .config-wrapper input[type='button']:disabled {\n background-color: white;\n border: 1px solid #c0c0c0;\n color: #aeaeae;\n cursor: not-allowed;\n}\n.configs .configs-body config-element .config-wrapper input[type='button'].danger {\n color: #f36669;\n border-color: #dd5a5d;\n}\n.configs .configs-body config-element .config-wrapper input[type='button']:disabled:active {\n box-shadow: none;\n}\n.configs .configs-body config-element .config-wrapper input[type='checkbox'] {\n appearance: none;\n -moz-appearance: none;\n -webkit-appearance: none;\n width: fit-content;\n min-width: 48px;\n height: 20px;\n border-radius: 100px;\n display: flex;\n align-items: center;\n padding: 2px 4px;\n transition: all 0.2s ease-in-out;\n width: auto;\n background: gainsboro;\n}\n.configs .configs-body config-element .config-wrapper input[type='checkbox']:checked {\n background: #1890ff;\n}\n.configs .configs-body config-element .config-wrapper input[type='checkbox']:disabled {\n background-color: #f7f7f78b;\n}\n.configs .configs-body config-element .config-wrapper input[type='checkbox']:checked::before {\n transform: translate(24px, 0px);\n}\n.configs .configs-body config-element .config-wrapper input[type='checkbox']::before {\n background-color: #fff;\n border-radius: 9px;\n box-shadow: 0 2px 4px #00230b33;\n width: 14px;\n height: 14px;\n content: '';\n}\n.configs .configs-body config-element .config-wrapper input:not([type='checkbox'], [type='radio']),\n.configs .configs-body config-element .config-wrapper textarea,\n.configs .configs-body config-element .config-wrapper select {\n width: -webkit-fill-available;\n font-size: inherit;\n}\n.configs .configs-body config-element .config-wrapper input[type='checkbox'],\n.configs .configs-body config-element .config-wrapper input[type='radio'],\n.configs .configs-body config-element .config-wrapper input[type='range'] {\n accent-color: #0e8ee2;\n}\n.configs .configs-body config-element .config-wrapper > *:not(.tooltip) {\n background-color: #eef2f7;\n border-radius: 2px;\n color: black;\n float: right;\n}\n.configs .configs-body config-element .config-wrapper > *:disabled {\n cursor: not-allowed;\n background-color: #f7f7f78b;\n}\n.message-container {\n margin-bottom: 4px;\n position: absolute;\n bottom: 100%;\n left: 50%;\n width: 100%;\n transform: translate(-50%, 0px);\n min-width: 300px;\n}\n.message-container message-element {\n display: flex;\n border-radius: 4px;\n padding: 4px 12px;\n margin-bottom: 4px;\n}\n.message-container message-element .message-content-container {\n margin-right: 8px;\n flex: auto;\n}\n.message-container message-element .message-text {\n letter-spacing: 1px;\n font-weight: bold;\n}\n.message-container message-element .message-closer {\n width: 18px;\n min-width: 18px;\n cursor: pointer;\n background-color: #ffffffb3;\n color: #a1a1a1;\n border-radius: 100%;\n text-align: center;\n height: 18px;\n vertical-align: middle;\n font-size: 12px;\n}\n.message-container message-element.error {\n background-color: #ffe6e6;\n color: #c70208;\n border: 1px solid #ff6b6ded;\n}\n.message-container message-element.info {\n background-color: #c9e7ff;\n color: #004d95;\n border: 1px solid #1890ff69;\n}\n.message-container message-element.success {\n background-color: #e8ffe0;\n color: #3e8d0d;\n border: 1px solid #6fd91d;\n}\n.message-container message-element.warn {\n background-color: #ffefc8;\n color: #9b7400;\n border: 1px solid #ffc107;\n}\nmodal-element {\n position: absolute;\n top: 50%;\n left: 50%;\n background-color: white;\n border-radius: 4px;\n box-shadow: 0px 0px 24px -12px black;\n border: 1px solid #929292;\n height: fit-content;\n transform: translate(-50%, -50%);\n padding: 12px 18px 18px 18px;\n font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;\n z-index: 99999999999;\n line-height: 24px;\n}\nmodal-element .modal-profile {\n zoom: 0.9;\n color: #969696;\n user-select: none;\n margin-bottom: 4px;\n}\nmodal-element .modal-title {\n font-size: 18px;\n font-weight: bold;\n user-select: none;\n}\nmodal-element .modal-body {\n margin: 12px 0px;\n overflow: auto;\n}\nmodal-element .modal-footer {\n display: flex;\n white-space: nowrap;\n justify-content: end;\n align-items: end;\n}\nmodal-element .modal-footer > * + * {\n margin-left: 12px;\n}\nmodal-element .modal-input {\n outline: none;\n padding: 2px 8px;\n margin: 0px;\n background-color: #eef2f7;\n border-radius: 2px;\n color: black;\n border: 1px solid #ffffff00;\n width: -webkit-fill-available;\n}\nmodal-element .modal-input::placeholder {\n color: #bababa;\n}\nmodal-element .modal-input:focus {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n}\nmodal-element .modal-input:focus:not([type='checkbox'], [type='radio']) {\n border: 1px solid #0e8de290;\n box-shadow: 0px 0px 4px #0e8de252;\n background-color: white !important;\n}\nmodal-element .modal-input:hover {\n background-color: #ebeef4;\n}\nmodal-element .modal-cancel-button {\n appearance: none;\n -moz-appearance: none;\n -webkit-appearance: none;\n border-radius: 4px;\n border: 1px solid #2c92ff;\n color: #409eff;\n cursor: pointer !important;\n margin-bottom: 4px;\n color: gray;\n background-color: white;\n border: 1px solid #dcdcdc;\n}\nmodal-element .modal-cancel-button:active {\n box-shadow: 0px 0px 8px #0e8de2a5;\n}\nmodal-element .modal-cancel-button + modal-element .modal-cancel-button {\n margin-left: 12px;\n}\nmodal-element .modal-cancel-button:hover {\n background-color: #7abbff24;\n}\nmodal-element .modal-cancel-button.danger:hover {\n background-color: #ffdede86;\n}\nmodal-element .modal-cancel-button:disabled {\n background-color: white;\n border: 1px solid #c0c0c0;\n color: #aeaeae;\n cursor: not-allowed;\n}\nmodal-element .modal-cancel-button.danger {\n color: #f36669;\n border-color: #dd5a5d;\n}\nmodal-element .modal-cancel-button:disabled:active {\n box-shadow: none;\n}\nmodal-element .modal-confirm-button {\n appearance: none;\n -moz-appearance: none;\n -webkit-appearance: none;\n border-radius: 4px;\n background-color: white;\n border: 1px solid #2c92ff;\n color: #409eff;\n cursor: pointer !important;\n margin-bottom: 4px;\n}\nmodal-element .modal-confirm-button:active {\n box-shadow: 0px 0px 8px #0e8de2a5;\n}\nmodal-element .modal-confirm-button + modal-element .modal-confirm-button {\n margin-left: 12px;\n}\nmodal-element .modal-confirm-button:hover {\n background-color: #7abbff24;\n}\nmodal-element .modal-confirm-button.danger:hover {\n background-color: #ffdede86;\n}\nmodal-element .modal-confirm-button:disabled {\n background-color: white;\n border: 1px solid #c0c0c0;\n color: #aeaeae;\n cursor: not-allowed;\n}\nmodal-element .modal-confirm-button.danger {\n color: #f36669;\n border-color: #dd5a5d;\n}\nmodal-element .modal-confirm-button:disabled:active {\n box-shadow: none;\n}\nmodal-element.alert .modal-input,\nmodal-element.alert .modal-cancel-button {\n display: none;\n}\nmodal-element.alert .modal-confirm-button {\n margin: 0;\n}\nmodal-element.prompt .modal-input,\nmodal-element.prompt .modal-cancel-button,\nmodal-element.prompt .modal-confirm-button {\n display: block;\n}\nmodal-element.confirm .modal-input {\n display: none;\n}\n.modal-wrapper {\n width: 100%;\n height: 100%;\n z-index: 9999;\n position: fixed;\n top: 0px;\n left: 0px;\n z-index: 9999999;\n background-color: rgba(0, 0, 0, 0.265);\n color: #636363;\n font: 14px Menlo, Monaco, Consolas, 'Courier New', monospace;\n}\n.pointer {\n cursor: pointer;\n}\n.separator {\n display: flex;\n align-items: center;\n text-align: center;\n padding: 4px 0px 8px 0px;\n}\n.separator::before,\n.separator::after {\n content: '';\n flex: 1;\n border-bottom: 1px solid #63636346;\n}\n.separator:not(:empty)::before {\n margin-right: 0.25em;\n}\n.separator:not(:empty)::after {\n margin-left: 0.25em;\n}\ncontainer-element.minimize .body,\ncontainer-element.minimize header-element .dropdown,\ncontainer-element.minimize .footer {\n display: none;\n}\ncontainer-element.minimize header-element {\n padding: 8px;\n border-radius: 8px;\n box-shadow: 0px 0px 24px -12px black;\n}\n.user-guide > li {\n padding: 4px 0px;\n}\n.search-infos-num {\n width: 26px;\n margin: 2px;\n height: 20px;\n border-radius: 4px;\n display: inline-block;\n background-color: white;\n text-align: center;\n cursor: pointer;\n border: 1px solid #b6b6b6;\n}\n.search-infos-num.requested {\n border: 1px solid #63b4ff;\n color: #63b4ff;\n}\n.search-infos-num.active {\n background-color: #127de1 !important;\n color: white;\n}\n.search-infos-num.error {\n border: 1px solid #ff8789ed;\n background-color: #ff6b6ded;\n color: white;\n}\n.search-infos-num.finish {\n background-color: #63b4ff;\n border: 1px solid #63b4ff;\n color: white;\n}\nsearch-infos-element {\n display: block;\n overflow: auto;\n}\nsearch-infos-element .search-result {\n margin-bottom: 12px;\n padding-left: 12px;\n}\nsearch-infos-element .search-result .question {\n font-weight: bold;\n max-height: 200px;\n overflow: auto;\n}\nsearch-infos-element .search-result .answer {\n color: #7c7c7c;\n}\nsearch-infos-element .search-result .answer code {\n border-bottom: 1px solid #dcdcdc;\n padding: 2px 0px;\n border-radius: 2px;\n margin: 4px;\n line-height: 22px;\n}\nsearch-infos-element .search-result .answer code + code {\n margin-left: 4px;\n}\nsearch-infos-element .search-result .search-result-answer-tag {\n padding: 2px 6px;\n border-radius: 2px;\n font-size: 12px;\n cursor: pointer;\n margin-right: 6px;\n}\nsearch-infos-element .search-result .search-result-answer-tag + .search-result-answer-tag {\n margin-left: 4px;\n}\nsearch-infos-element .search-result .search-result-answer-tag.blue {\n background-color: #e6f7ff;\n border: 1px solid #91d5ff;\n color: #1890ff;\n}\nsearch-infos-element .search-result .search-result-answer-tag.green {\n background-color: #f6ffed;\n border: 1px solid #b7eb8f;\n color: #52c41a;\n}\nsearch-infos-element .search-result .search-result-answer-tag.gray {\n background-color: #fafafa;\n border: 1px solid #d9d9d9;\n color: #595959;\n}\nsearch-infos-element .search-result .search-result-answer-tag.red {\n background-color: #fff1f0;\n border: 1px solid #ffa39e;\n color: #ff4d4f;\n}\nsearch-infos-element .search-result .search-result-answer-tag.yellow {\n background-color: #fffbe6;\n border: 1px solid #ffe58f;\n color: #faad14;\n}\nsearch-infos-element .search-result-question-type {\n background-color: #e6f7ff;\n border: 1px solid #91d5ff;\n color: #1890ff;\n margin-right: 8px;\n padding: 0px 4px;\n border-radius: 4px;\n}\nsearch-infos-element .error {\n color: #ff6b6ded;\n display: inline-block;\n padding-left: 12px;\n}\n.copy,\n.question-title-extra-btn {\n margin-left: 4px;\n padding: 2px 4px;\n border-radius: 2px;\n box-shadow: 0 0 4px #b1b1b1;\n cursor: pointer !important;\n font-weight: normal;\n font-size: 12px;\n}\n.work-result-question-container {\n position: absolute;\n width: 400px;\n left: -100%;\n top: 0px;\n background: white;\n border: 1px solid #cbcbcb;\n border-radius: 4px;\n box-shadow: 0px 0px 12px #d1cfcf;\n padding: 12px;\n}\n.work-result-question-container .close-search-result {\n font-size: 12px;\n margin-left: 8px;\n text-decoration: underline;\n color: gray;\n cursor: pointer;\n}\n.work-result-list {\n max-height: 400px;\n overflow: auto;\n margin: 12px 0px;\n padding: 6px;\n border: 1px solid #e1e1e1;\n border-radius: 4px;\n}\n.search-info-title {\n border: 1px solid #e1e1e1;\n border-radius: 4px;\n padding: 8px 12px;\n margin-bottom: 12px;\n line-height: 20px;\n overflow: auto;\n}\n.search-info-title .title-content {\n max-height: 200px;\n overflow: auto;\n}\n.search-info-details {\n margin-left: 4px;\n}\n.console {\n max-height: 300px;\n max-width: 400px;\n overflow: auto;\n background-color: #292929;\n padding: 12px 6px;\n color: #ececec;\n font-size: 12px;\n}\n.console .item {\n padding: 3px 0px;\n border-radius: 2px;\n}\n.console .item .time {\n color: #757575;\n}\n.console .item .info {\n background-color: #2196f3a3;\n}\n.console .item .warn {\n background-color: #ffc107db;\n}\n.console .item .error {\n background-color: #f36c71cc;\n}\n.console .item .debug,\n.console .item .log {\n background-color: #9e9e9ec4;\n}\n.console *::selection {\n background-color: #ffffff6b;\n}\n.markdown {\n max-width: 400px;\n max-height: 50vh;\n overflow: auto;\n}\n.markdown code {\n padding: 2px 4px;\n background-color: #f0f0f0;\n border-radius: 6px;\n font-size: 12px;\n}\n.markdown blockquote {\n padding: 4px 4px 4px 12px;\n margin: 0px;\n color: #b5b5b5;\n border-left: #ababab 2px solid;\n}\n.markdown blockquote p {\n margin: 0px;\n}\n.markdown h1,\n.markdown h2,\n.markdown h3,\n.markdown h4,\n.markdown h5,\n.markdown h6,\n.markdown p {\n margin: 8px 0px;\n}\n.dropdown {\n position: relative;\n display: inline-block;\n}\n.dropdown.active .dropdown-trigger-element {\n color: #1890ff;\n}\n.dropdown-trigger-element {\n cursor: pointer;\n}\n.dropdown-content {\n display: none;\n position: absolute;\n background-color: #ffffff;\n overflow: auto;\n box-shadow: 0px 8px 16px 0px #00000033;\n z-index: 1;\n border-radius: 4px;\n padding: 8px 12px;\n min-width: 120px;\n}\n.dropdown-content.show {\n display: block;\n}\n.dropdown-content {\n cursor: pointer;\n z-index: 999;\n}\n.dropdown-content .dropdown-option {\n padding-left: 4px;\n white-space: nowrap;\n}\n.dropdown-content .dropdown-option:hover {\n background-color: #f3f3f3;\n}\n.dropdown-content .dropdown-option.active {\n background-color: #1890ff1a;\n color: #1890ff;\n}\n.space {\n display: inline-flex;\n}\n.config-details {\n animation: fade-in 0.5s;\n}\n.config-details label {\n padding-left: 12px;\n}\n.alert-info-wrapper {\n margin-bottom: 8px;\n}\n.alert-info-wrapper .result-info {\n padding: 12px;\n text-align: center;\n border-radius: 6px;\n}\n.alert-info-wrapper .unresolved {\n color: #a1a1a1;\n background-color: #f7f7f7;\n}\n.alert-info-wrapper .no-answer {\n color: #a1a1a1;\n background-color: #f7f7f7;\n}\n.alert-info-wrapper .error {\n color: #ff4d4f;\n background-color: #fff1f0;\n}\nmessage-element {\n animation: show 0.5s;\n}\nscript-panel-element > div,\nscript-panel-link,\ncontainer-element,\nmodal-element {\n animation: fade-in 0.3s;\n}\n@keyframes show {\n 0% {\n transform: translateY(20px);\n opacity: 0;\n }\n 100% {\n transform: translateY(0);\n opacity: 1;\n }\n}\n@keyframes fade-in {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n@keyframes fade-out {\n 0% {\n opacity: 1;\n }\n 100% {\n opacity: 0;\n }\n}\n.checkbox-label {\n display: inline-block !important;\n position: relative;\n cursor: pointer;\n font-size: 16px;\n color: #2c3e50;\n}\n/* 隐藏原始复选框 */\n.checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n/* 自定义按钮样式 */\n.checkbox-label::after {\n content: '';\n display: inline-block;\n border-radius: 50%;\n transition: all 0.1s ease;\n position: relative;\n margin-left: 4px;\n vertical-align: middle;\n}\n/* 向下箭头(未选中状态) */\n.checkbox-label::before {\n content: '🔽';\n position: absolute;\n width: 0;\n height: 0;\n right: 8px;\n transition: all 0.1s ease;\n z-index: 2;\n}\n/* 向上箭头(选中状态) */\n.checked .checkbox-label::before {\n content: '🔼';\n}\n"; //#endregion //#region src/main.ts /** * 入口。 * * metadata 块不在这里 —— 由 vite-userscript-plugin 的 header 配置生成(见 vite.config.ts)。 * easy-us 只管运行时,两者不冲突。 */ /** * 面板初次打开时默认展开哪个脚本。 * * ⚠️ 这里只能填 `script.namespace`,或者 `工程名-脚本名` 这个完整写法。 * easy-us 的 isCurrentPanel 就认这两种(interfaces/custom-window.js): * * projectName + '-' + script.name === currentPanelName || script.namespace === currentPanelName * * 以前填的是光秃秃的 '雨课堂助手'(工程名),两边都匹配不上, * 结果是窗口只剩一条标题栏、底下什么都不画 —— 看着就像「面板不见了」。 * * 顺手按当前页挑一个最相关的:作业页开 AI 答题,课程页开作业跳转,其余开复制解密。 * 用户自己在下拉里选过之后,框架会把选择存进 tab,这里的默认值就不再起作用了。 */ function defaultPanel() { const u = location.href; if (/exercise/i.test(u)) return "ykt.answer"; if (/\/ai-workspace\/lms-graph/.test(u)) return "ykt.jump"; return "ykt.copy"; } /** * 窗口设置脚本(字体大小 / 连点次数 / 面板坐标 / 显隐状态都存在它的 cfg 里)。 * * ⚠️ 必须自己补一次 createConfigProxy。 * easy-us 的 start() 只给 `projects` 里的脚本挂配置代理(utils/start.js 开头那段 map), * 而 renderScript 不在 projects 里,于是它的 cfg 一直是个空对象 {} —— * 读出来的 x / y / visual / fontsize 全是 undefined, * 结果 handlePosition 会写出 `style.left = "undefinedpx"`(非法,被浏览器丢掉), * 拖动位置也存不住,「字体大小」那一栏更是调了没反应。 */ var renderScript = (0, import_lib.createRenderScript)({ name: "🖼️ 窗口设置" }); renderScript.cfg = import_lib.$.createConfigProxy(renderScript); /** * 关掉「连点三下把面板挪到鼠标位置」。 * * easy-us 在 window 上挂了个 click 监听(interfaces/custom-window.js 的 handleVisible): * * if (e.detail === Math.max(config.render.switchPoint, 3)) { 移动面板 + setVisual('normal') } * * e.detail 是连击计数,双击选词之后再点一下就满三次 —— 在答题页上误触率很高, * 面板会毫无预兆地跳到鼠标底下。监听器是匿名函数,摘不掉, * 只能把阈值抬到一个够不着的数(Math.max 的下限是 3,所以只能往上顶)。 * * 阈值是在 CustomWindow 构造时从 cfg 里读走的,所以必须赶在 start() 之前写。 * 键盘的 Ctrl+O 显示 / 隐藏不受影响,还留着。 */ var NO_TRIPLE_CLICK = 999; renderScript.cfg.switchPoint = NO_TRIPLE_CLICK; var rsConfigs = renderScript.configs; if (rsConfigs.switchPoint) { rsConfigs.switchPoint.label = "连点唤出面板(已关闭)"; rsConfigs.switchPoint.attrs = { type: "number", min: 3, max: NO_TRIPLE_CLICK, step: 1, title: "默认连点三下会把面板挪到鼠标位置,答题时太容易误触,这里已经关掉。想用就改回 3。" }; } (0, import_lib.start)({ projects: [yktProject], renderConfig: { renderScript, title: "☂️", styles: [panel_default], defaultPanelName: defaultPanel() } }); watchPanel(); //#endregion })();