dsh-messager 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +86 -0
  3. package/README.md +241 -0
  4. package/assets/icon.png +0 -0
  5. package/cordis.patch.yml +11 -0
  6. package/lib/channels/feishu.d.ts +58 -0
  7. package/lib/channels/feishu.d.ts.map +1 -0
  8. package/lib/channels/feishu.js +77 -0
  9. package/lib/channels/feishu.js.map +1 -0
  10. package/lib/channels/system.d.ts +26 -0
  11. package/lib/channels/system.d.ts.map +1 -0
  12. package/lib/channels/system.js +73 -0
  13. package/lib/channels/system.js.map +1 -0
  14. package/lib/client.js +2001 -0
  15. package/lib/client.js.map +1 -0
  16. package/lib/config-route.d.ts +55 -0
  17. package/lib/config-route.d.ts.map +1 -0
  18. package/lib/config-route.js +170 -0
  19. package/lib/config-route.js.map +1 -0
  20. package/lib/config-shared.d.ts +28 -0
  21. package/lib/config-shared.d.ts.map +1 -0
  22. package/lib/config-shared.js +7 -0
  23. package/lib/config-shared.js.map +1 -0
  24. package/lib/config.d.ts +82 -0
  25. package/lib/config.d.ts.map +1 -0
  26. package/lib/config.js +59 -0
  27. package/lib/config.js.map +1 -0
  28. package/lib/index.d.ts +15 -0
  29. package/lib/index.d.ts.map +1 -0
  30. package/lib/index.js +152 -0
  31. package/lib/index.js.map +1 -0
  32. package/lib/notify.d.ts +75 -0
  33. package/lib/notify.d.ts.map +1 -0
  34. package/lib/notify.js +157 -0
  35. package/lib/notify.js.map +1 -0
  36. package/lib/settings.d.ts +23 -0
  37. package/lib/settings.d.ts.map +1 -0
  38. package/lib/settings.js +23 -0
  39. package/lib/settings.js.map +1 -0
  40. package/lib/signals.d.ts +57 -0
  41. package/lib/signals.d.ts.map +1 -0
  42. package/lib/signals.js +52 -0
  43. package/lib/signals.js.map +1 -0
  44. package/lib/templates.d.ts +40 -0
  45. package/lib/templates.d.ts.map +1 -0
  46. package/lib/templates.js +107 -0
  47. package/lib/templates.js.map +1 -0
  48. package/lib/types/client/card-controller.d.ts +171 -0
  49. package/lib/types/client/card-controller.d.ts.map +1 -0
  50. package/lib/types/client/config.d.ts +20 -0
  51. package/lib/types/client/config.d.ts.map +1 -0
  52. package/lib/types/client/diff.d.ts +26 -0
  53. package/lib/types/client/diff.d.ts.map +1 -0
  54. package/lib/types/client/fetch-scope.d.ts +29 -0
  55. package/lib/types/client/fetch-scope.d.ts.map +1 -0
  56. package/lib/types/client/index.d.ts +24 -0
  57. package/lib/types/client/index.d.ts.map +1 -0
  58. package/lib/types/client/locales.d.ts +92 -0
  59. package/lib/types/client/locales.d.ts.map +1 -0
  60. package/lib/types/client/section.d.ts +16 -0
  61. package/lib/types/client/section.d.ts.map +1 -0
  62. package/lib/types/client/settings-form.d.ts +22 -0
  63. package/lib/types/client/settings-form.d.ts.map +1 -0
  64. package/lib/types/config-shared.d.ts +28 -0
  65. package/lib/types/config-shared.d.ts.map +1 -0
  66. package/lib/types/config.d.ts +82 -0
  67. package/lib/types/config.d.ts.map +1 -0
  68. package/package.json +96 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","names":["valueMap","record"],"sources":["../node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.2/node_modules/@deepseek-ai/cosmokit/lib/index.js","../node_modules/.pnpm/@deepseek-ai+schemastery@3.18.1/node_modules/@deepseek-ai/schemastery/lib/index.mjs","../src/config.ts","../src/config-shared.ts","../src/client/config.ts","../src/client/diff.ts","../src/client/card-controller.ts","../src/client/fetch-scope.ts","../src/client/settings-form.tsx","../src/client/section.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["//#region lib/types/misc.js\n/** No-op callback returning `undefined` at runtime and `any` at type level. */\nfunction noop() {}\n/** Return true when a value is `null` or `undefined`. */\nfunction isNullable(value) {\n\treturn value === null || value === void 0;\n}\n/** Return true when a value is neither `null` nor `undefined`. */\nfunction isNonNullable(value) {\n\treturn !isNullable(value);\n}\n/** Return true for non-array object values. */\nfunction isPlainObject(data) {\n\treturn data && typeof data === \"object\" && !Array.isArray(data);\n}\n/** Filter object entries and return a new object. */\nfunction filterKeys(object, filter) {\n\treturn Object.fromEntries(Object.entries(object).filter(([key, value]) => filter(key, value)));\n}\n/** Map object values while preserving the original key set. */\nfunction mapValues(object, transform) {\n\treturn Object.fromEntries(Object.entries(object).map(([key, value]) => [key, transform(value, key)]));\n}\n/** Pick selected keys from an object, optionally including `undefined` values. */\nfunction pick(source, keys, forced) {\n\tif (!keys) return { ...source };\n\tconst result = {};\n\tfor (const key of keys) if (forced || source[key] !== void 0) result[key] = source[key];\n\treturn result;\n}\n/** Omit selected keys from a shallow object copy. */\nfunction omit(source, keys) {\n\tif (!keys) return { ...source };\n\tconst result = { ...source };\n\tfor (const key of keys) Reflect.deleteProperty(result, key);\n\treturn result;\n}\n/** Define a non-enumerable writable property and return the object. */\nfunction defineProperty(object, key, value) {\n\treturn Object.defineProperty(object, key, {\n\t\twritable: true,\n\t\tvalue,\n\t\tenumerable: false\n\t});\n}\n//#endregion\n//#region lib/types/array.js\n/** Return true when every item in `array2` is present in `array1`. */\nfunction contain(array1, array2) {\n\treturn array2.every((item) => array1.includes(item));\n}\n/** Return items that appear in both arrays. */\nfunction intersection(array1, array2) {\n\treturn array1.filter((item) => array2.includes(item));\n}\n/** Return items from `array1` that do not appear in `array2`. */\nfunction difference(array1, array2) {\n\treturn array1.filter((item) => !array2.includes(item));\n}\n/** Return the set-union of two arrays while preserving first occurrence order. */\nfunction union(array1, array2) {\n\treturn Array.from(new Set([...array1, ...array2]));\n}\n/** Remove duplicate values while preserving first occurrence order. */\nfunction deduplicate(array) {\n\treturn [...new Set(array)];\n}\n/** Remove one item from an array and report whether it was found. */\nfunction remove(list, item) {\n\tconst index = list?.indexOf(item);\n\tif (index >= 0) {\n\t\tlist.splice(index, 1);\n\t\treturn true;\n\t} else return false;\n}\n/** Normalize nullish, scalar, or array input to an array. */\nfunction makeArray(source) {\n\treturn Array.isArray(source) ? source : isNullable(source) ? [] : [source];\n}\n//#endregion\n//#region lib/types/types.js\n/** Test values using `instanceof` with a `toStringTag` fallback. */\nfunction is(type, value) {\n\tif (arguments.length === 1) return (value) => is(type, value);\n\treturn type in globalThis && value instanceof globalThis[type] || Object.prototype.toString.call(value).slice(8, -1) === type;\n}\nfunction isArrayBufferLike(value) {\n\treturn is(\"ArrayBuffer\", value) || is(\"SharedArrayBuffer\", value);\n}\nfunction isArrayBufferSource(value) {\n\treturn isArrayBufferLike(value) || ArrayBuffer.isView(value);\n}\n/** Binary source detection and base64/hex conversion helpers. */\nvar Binary;\n(function(Binary) {\n\tBinary.is = isArrayBufferLike;\n\tBinary.isSource = isArrayBufferSource;\n\tfunction fromSource(source) {\n\t\tif (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);\n\t\telse return source;\n\t}\n\tBinary.fromSource = fromSource;\n\tfunction toBase64(source) {\n\t\tsource = fromSource(source);\n\t\tif (typeof Buffer !== \"undefined\") return Buffer.from(source).toString(\"base64\");\n\t\tlet binary = \"\";\n\t\tconst bytes = new Uint8Array(source);\n\t\tfor (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]);\n\t\treturn btoa(binary);\n\t}\n\tBinary.toBase64 = toBase64;\n\tfunction fromBase64(source) {\n\t\tif (typeof Buffer !== \"undefined\") return fromSource(Buffer.from(source, \"base64\"));\n\t\treturn Uint8Array.from(atob(source), (c) => c.charCodeAt(0));\n\t}\n\tBinary.fromBase64 = fromBase64;\n\tfunction toHex(source) {\n\t\tsource = fromSource(source);\n\t\tif (typeof Buffer !== \"undefined\") return Buffer.from(source).toString(\"hex\");\n\t\treturn Array.from(new Uint8Array(source), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n\t}\n\tBinary.toHex = toHex;\n\tfunction fromHex(source) {\n\t\tif (typeof Buffer !== \"undefined\") return fromSource(Buffer.from(source, \"hex\"));\n\t\tconst hex = source.length % 2 === 0 ? source : source.slice(0, source.length - 1);\n\t\tconst buffer = [];\n\t\tfor (let i = 0; i < hex.length; i += 2) buffer.push(parseInt(`${hex[i]}${hex[i + 1]}`, 16));\n\t\treturn Uint8Array.from(buffer).buffer;\n\t}\n\tBinary.fromHex = fromHex;\n})(Binary || (Binary = {}));\n/** Decode a base64 string into binary data. */\nconst base64ToArrayBuffer = Binary.fromBase64;\n/** Encode binary data as base64. */\nconst arrayBufferToBase64 = Binary.toBase64;\n/** Decode a hex string into binary data. */\nconst hexToArrayBuffer = Binary.fromHex;\n/** Encode binary data as hex. */\nconst arrayBufferToHex = Binary.toHex;\n/** Deep-clone common JavaScript values while preserving prototypes and cycles. */\nfunction clone(source, refs = /* @__PURE__ */ new Map()) {\n\tif (!source || typeof source !== \"object\") return source;\n\tif (is(\"Date\", source)) return new Date(source.valueOf());\n\tif (is(\"RegExp\", source)) return new RegExp(source.source, source.flags);\n\tif (isArrayBufferLike(source)) return source.slice(0);\n\tif (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);\n\tconst cached = refs.get(source);\n\tif (cached) return cached;\n\tif (Array.isArray(source)) {\n\t\tconst result = [];\n\t\trefs.set(source, result);\n\t\tsource.forEach((value, index) => {\n\t\t\tresult[index] = Reflect.apply(clone, null, [value, refs]);\n\t\t});\n\t\treturn result;\n\t}\n\tconst result = Object.create(Object.getPrototypeOf(source));\n\trefs.set(source, result);\n\tfor (const key of Reflect.ownKeys(source)) {\n\t\tconst descriptor = { ...Reflect.getOwnPropertyDescriptor(source, key) };\n\t\tif (\"value\" in descriptor) descriptor.value = Reflect.apply(clone, null, [descriptor.value, refs]);\n\t\tReflect.defineProperty(result, key, descriptor);\n\t}\n\treturn result;\n}\n/** Deeply compare arrays, dates, regexps, buffers, and plain object fields. */\nfunction deepEqual(a, b, strict) {\n\tif (a === b) return true;\n\tif (!strict && isNullable(a) && isNullable(b)) return true;\n\tif (typeof a !== typeof b) return false;\n\tif (typeof a !== \"object\") return false;\n\tif (!a || !b) return false;\n\tfunction check(test, then) {\n\t\treturn test(a) ? test(b) ? then(a, b) : false : test(b) ? false : void 0;\n\t}\n\treturn check(Array.isArray, (a, b) => a.length === b.length && a.every((item, index) => deepEqual(item, b[index]))) ?? check(is(\"Date\"), (a, b) => a.valueOf() === b.valueOf()) ?? check(is(\"RegExp\"), (a, b) => a.source === b.source && a.flags === b.flags) ?? check(isArrayBufferLike, (a, b) => {\n\t\tif (a.byteLength !== b.byteLength) return false;\n\t\tconst viewA = new Uint8Array(a);\n\t\tconst viewB = new Uint8Array(b);\n\t\tfor (let i = 0; i < viewA.length; i++) if (viewA[i] !== viewB[i]) return false;\n\t\treturn true;\n\t}) ?? Object.keys({\n\t\t...a,\n\t\t...b\n\t}).every((key) => deepEqual(a[key], b[key], strict));\n}\n//#endregion\n//#region lib/types/string.js\n/** Uppercase the first character of a string. */\nfunction capitalize(source) {\n\treturn source.charAt(0).toUpperCase() + source.slice(1);\n}\n/** Lowercase the first character of a string. */\nfunction uncapitalize(source) {\n\treturn source.charAt(0).toLowerCase() + source.slice(1);\n}\n/** Convert dash or underscore delimited text to camelCase. */\nfunction camelCase(source) {\n\treturn source.replace(/[_-][a-z]/g, (str) => str.slice(1).toUpperCase());\n}\nfunction tokenize(source, delimiters, delimiter) {\n\tconst output = [];\n\tlet state = 0;\n\tfor (let i = 0; i < source.length; i++) {\n\t\tconst code = source.charCodeAt(i);\n\t\tif (code >= 65 && code <= 90) {\n\t\t\tif (state === 1) {\n\t\t\t\tconst next = source.charCodeAt(i + 1);\n\t\t\t\tif (next >= 97 && next <= 122) output.push(delimiter);\n\t\t\t\toutput.push(code + 32);\n\t\t\t} else {\n\t\t\t\tif (state !== 0) output.push(delimiter);\n\t\t\t\toutput.push(code + 32);\n\t\t\t}\n\t\t\tstate = 1;\n\t\t} else if (code >= 97 && code <= 122) {\n\t\t\toutput.push(code);\n\t\t\tstate = 2;\n\t\t} else if (delimiters.includes(code)) {\n\t\t\tif (state !== 0) output.push(delimiter);\n\t\t\tstate = 0;\n\t\t} else output.push(code);\n\t}\n\treturn String.fromCharCode(...output);\n}\n/** Convert text to dash-delimited parameter case. */\nfunction paramCase(source) {\n\treturn tokenize(source, [45, 95], 45);\n}\n/** Convert text to underscore-delimited snake case. */\nfunction snakeCase(source) {\n\treturn tokenize(source, [45, 95], 95);\n}\n/** Runtime alias for `camelCase`. */\nconst camelize = camelCase;\n/** Runtime alias for `paramCase`. */\nconst hyphenate = paramCase;\n/** Format a property key as a JavaScript member access suffix. */\nfunction formatProperty(key) {\n\tif (typeof key !== \"string\") return `[${key.toString()}]`;\n\treturn /^[a-z_$][\\w$]*$/i.test(key) ? `.${key}` : `[${JSON.stringify(key)}]`;\n}\n/** Remove one trailing slash from a path string. */\nfunction trimSlash(source) {\n\treturn source.replace(/\\/$/, \"\");\n}\n/** Ensure a path starts with `/` and has no trailing slash. */\nfunction sanitize(source) {\n\tif (!source.startsWith(\"/\")) source = \"/\" + source;\n\treturn trimSlash(source);\n}\n//#endregion\n//#region lib/types/time.js\n/** Time constants plus parsing and formatting helpers. */\nvar Time;\n(function(Time) {\n\tTime.millisecond = 1;\n\tTime.second = 1e3;\n\tTime.minute = Time.second * 60;\n\tTime.hour = Time.minute * 60;\n\tTime.day = Time.hour * 24;\n\tTime.week = Time.day * 7;\n\tlet timezoneOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset();\n\tfunction setTimezoneOffset(offset) {\n\t\ttimezoneOffset = offset;\n\t}\n\tTime.setTimezoneOffset = setTimezoneOffset;\n\tfunction getTimezoneOffset() {\n\t\treturn timezoneOffset;\n\t}\n\tTime.getTimezoneOffset = getTimezoneOffset;\n\tfunction getDateNumber(date = /* @__PURE__ */ new Date(), offset) {\n\t\tif (typeof date === \"number\") date = new Date(date);\n\t\tif (offset === void 0) offset = timezoneOffset;\n\t\treturn Math.floor((date.valueOf() / Time.minute - offset) / 1440);\n\t}\n\tTime.getDateNumber = getDateNumber;\n\tfunction fromDateNumber(value, offset) {\n\t\tconst date = new Date(value * Time.day);\n\t\tif (offset === void 0) offset = timezoneOffset;\n\t\treturn new Date(+date + offset * Time.minute);\n\t}\n\tTime.fromDateNumber = fromDateNumber;\n\tconst numeric = /\\d+(?:\\.\\d+)?/.source;\n\tconst timeRegExp = new RegExp(`^${[\n\t\t\"w(?:eek(?:s)?)?\",\n\t\t\"d(?:ay(?:s)?)?\",\n\t\t\"h(?:our(?:s)?)?\",\n\t\t\"m(?:in(?:ute)?(?:s)?)?\",\n\t\t\"s(?:ec(?:ond)?(?:s)?)?\"\n\t].map((unit) => `(${numeric}${unit})?`).join(\"\")}$`);\n\tfunction parseTime(source) {\n\t\tconst capture = timeRegExp.exec(source);\n\t\tif (!capture) return 0;\n\t\treturn (parseFloat(capture[1]) * Time.week || 0) + (parseFloat(capture[2]) * Time.day || 0) + (parseFloat(capture[3]) * Time.hour || 0) + (parseFloat(capture[4]) * Time.minute || 0) + (parseFloat(capture[5]) * Time.second || 0);\n\t}\n\tTime.parseTime = parseTime;\n\tfunction parseDate(date) {\n\t\tconst parsed = parseTime(date);\n\t\tif (parsed) date = Date.now() + parsed;\n\t\telse if (/^\\d{1,2}(:\\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).toLocaleDateString()}-${date}`;\n\t\telse if (/^\\d{1,2}-\\d{1,2}-\\d{1,2}(:\\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).getFullYear()}-${date}`;\n\t\treturn date ? new Date(date) : /* @__PURE__ */ new Date();\n\t}\n\tTime.parseDate = parseDate;\n\tfunction format(ms) {\n\t\tconst abs = Math.abs(ms);\n\t\tif (abs >= Time.day - Time.hour / 2) return Math.round(ms / Time.day) + \"d\";\n\t\telse if (abs >= Time.hour - Time.minute / 2) return Math.round(ms / Time.hour) + \"h\";\n\t\telse if (abs >= Time.minute - Time.second / 2) return Math.round(ms / Time.minute) + \"m\";\n\t\telse if (abs >= Time.second) return Math.round(ms / Time.second) + \"s\";\n\t\treturn ms + \"ms\";\n\t}\n\tTime.format = format;\n\tfunction toDigits(source, length = 2) {\n\t\treturn source.toString().padStart(length, \"0\");\n\t}\n\tTime.toDigits = toDigits;\n\tfunction template(template, time = /* @__PURE__ */ new Date()) {\n\t\treturn template.replace(\"yyyy\", time.getFullYear().toString()).replace(\"yy\", time.getFullYear().toString().slice(2)).replace(\"MM\", toDigits(time.getMonth() + 1)).replace(\"dd\", toDigits(time.getDate())).replace(\"hh\", toDigits(time.getHours())).replace(\"mm\", toDigits(time.getMinutes())).replace(\"ss\", toDigits(time.getSeconds())).replace(\"SSS\", toDigits(time.getMilliseconds(), 3));\n\t}\n\tTime.template = template;\n})(Time || (Time = {}));\n//#endregion\nexport { Binary, Time, arrayBufferToBase64, arrayBufferToHex, base64ToArrayBuffer, camelCase, camelize, capitalize, clone, contain, deduplicate, deepEqual, defineProperty, difference, filterKeys, formatProperty, hexToArrayBuffer, hyphenate, intersection, is, isNonNullable, isNullable, isPlainObject, makeArray, mapValues, mapValues as valueMap, noop, omit, paramCase, pick, remove, sanitize, snakeCase, trimSlash, uncapitalize, union };\n","import { Binary, clone, deepEqual, filterKeys, isNullable, isPlainObject, pick, valueMap } from \"@deepseek-ai/cosmokit\";\n//#region lib/types/index.js\nconst kSchema = Symbol.for(\"schemastery\");\nconst kValidationError = Symbol.for(\"ValidationError\");\nglobalThis.__schemastery_index__ ??= 0;\nglobalThis.__schemastery_refs__ = void 0;\nvar ValidationError = class extends TypeError {\n\toptions;\n\tname = \"ValidationError\";\n\tconstructor(message, options) {\n\t\tlet prefix = \"$\";\n\t\tfor (const segment of options.path || []) if (typeof segment === \"string\") prefix += \".\" + segment;\n\t\telse if (typeof segment === \"number\") prefix += \"[\" + segment + \"]\";\n\t\telse if (typeof segment === \"symbol\") prefix += `[Symbol(${segment.toString()})]`;\n\t\tif (prefix.startsWith(\".\")) prefix = prefix.slice(1);\n\t\tsuper((prefix === \"$\" ? \"\" : `${prefix} `) + message);\n\t\tthis.options = options;\n\t}\n\tstatic is(error) {\n\t\treturn !!error?.[kValidationError];\n\t}\n};\nObject.defineProperty(ValidationError.prototype, kValidationError, { value: true });\nconst Schema = function(options) {\n\tconst schema = function(data, options = {}) {\n\t\treturn Schema.resolve(data, schema, options)[0];\n\t};\n\tif (options.refs) {\n\t\tconst refs = valueMap(options.refs, (options) => new Schema(options));\n\t\tconst getRef = (uid) => refs[uid];\n\t\tfor (const key in refs) {\n\t\t\tconst options = refs[key];\n\t\t\toptions.sKey = getRef(options.sKey);\n\t\t\toptions.inner = getRef(options.inner);\n\t\t\toptions.list = options.list && options.list.map(getRef);\n\t\t\toptions.dict = options.dict && valueMap(options.dict, getRef);\n\t\t}\n\t\treturn refs[options.uid];\n\t}\n\tObject.assign(schema, options);\n\tif (typeof schema.callback === \"string\") try {\n\t\tschema.callback = new Function(\"return \" + schema.callback)();\n\t} catch {}\n\tObject.defineProperty(schema, \"uid\", { value: globalThis.__schemastery_index__++ });\n\tObject.setPrototypeOf(schema, Schema.prototype);\n\tschema.meta ||= {};\n\tschema.toString = schema.toString.bind(schema);\n\treturn schema;\n};\nSchema.prototype = Object.create(Function.prototype);\nSchema.prototype[kSchema] = true;\nObject.defineProperty(Schema.prototype, \"~standard\", { get() {\n\treturn {\n\t\tversion: 1,\n\t\tvendor: \"schemastery\",\n\t\tvalidate: (value) => {\n\t\t\ttry {\n\t\t\t\treturn { value: Schema.resolve(value, this, {})[0] };\n\t\t\t} catch (error) {\n\t\t\t\tif (ValidationError.is(error)) return { issues: [{\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tpath: error.options.path\n\t\t\t\t}] };\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t};\n} });\nSchema.ValidationError = ValidationError;\nSchema.prototype.toJSON = function toJSON() {\n\tif (globalThis.__schemastery_refs__) {\n\t\tglobalThis.__schemastery_refs__[this.uid] ??= JSON.parse(JSON.stringify({ ...this }));\n\t\treturn this.uid;\n\t}\n\tglobalThis.__schemastery_refs__ = { [this.uid]: { ...this } };\n\tglobalThis.__schemastery_refs__[this.uid] = JSON.parse(JSON.stringify({ ...this }));\n\tconst result = {\n\t\tuid: this.uid,\n\t\trefs: globalThis.__schemastery_refs__\n\t};\n\tglobalThis.__schemastery_refs__ = void 0;\n\treturn result;\n};\nSchema.prototype.set = function set(key, value) {\n\tthis.dict[key] = value;\n\treturn this;\n};\nSchema.prototype.push = function push(value) {\n\tthis.list.push(value);\n\treturn this;\n};\nfunction mergeDesc(original, messages) {\n\tconst result = typeof original === \"string\" ? { \"\": original } : { ...original };\n\tfor (const locale in messages) {\n\t\tconst value = messages[locale];\n\t\tif (value?.$description || value?.$desc) result[locale] = value.$description || value.$desc;\n\t\telse if (typeof value === \"string\") result[locale] = value;\n\t}\n\treturn result;\n}\nfunction getInner(value) {\n\treturn value?.$value ?? value?.$inner;\n}\nfunction extractKeys(data) {\n\treturn filterKeys(data ?? {}, (key) => !key.startsWith(\"$\"));\n}\nSchema.prototype.i18n = function i18n(messages) {\n\tconst schema = Schema(this);\n\tconst desc = mergeDesc(schema.meta.description, messages);\n\tif (Object.keys(desc).length) schema.meta.description = desc;\n\tif (schema.dict) schema.dict = valueMap(schema.dict, (inner, key) => {\n\t\treturn inner.i18n(valueMap(messages, (data) => getInner(data)?.[key] ?? data?.[key]));\n\t});\n\tif (schema.list) schema.list = schema.list.map((inner, index) => {\n\t\treturn inner.i18n(valueMap(messages, (data = {}) => {\n\t\t\tif (Array.isArray(getInner(data))) return getInner(data)[index];\n\t\t\tif (Array.isArray(data)) return data[index];\n\t\t\treturn extractKeys(data);\n\t\t}));\n\t});\n\tif (schema.inner) schema.inner = schema.inner.i18n(valueMap(messages, (data) => {\n\t\tif (getInner(data)) return getInner(data);\n\t\treturn extractKeys(data);\n\t}));\n\tif (schema.sKey) schema.sKey = schema.sKey.i18n(valueMap(messages, (data) => data?.$key));\n\treturn schema;\n};\nSchema.prototype.extra = function extra(key, value) {\n\tconst schema = Schema(this);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\t[key]: value\n\t};\n\treturn schema;\n};\nfor (const key of [\n\t\"required\",\n\t\"disabled\",\n\t\"collapse\",\n\t\"hidden\",\n\t\"loose\"\n]) Object.assign(Schema.prototype, { [key](value = true) {\n\tconst schema = Schema(this);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\t[key]: value\n\t};\n\treturn schema;\n} });\nSchema.prototype.deprecated = function deprecated() {\n\tconst schema = Schema(this);\n\tschema.meta.badges ||= [];\n\tschema.meta.badges.push({\n\t\ttext: \"deprecated\",\n\t\ttype: \"danger\"\n\t});\n\treturn schema;\n};\nSchema.prototype.experimental = function experimental() {\n\tconst schema = Schema(this);\n\tschema.meta.badges ||= [];\n\tschema.meta.badges.push({\n\t\ttext: \"experimental\",\n\t\ttype: \"warning\"\n\t});\n\treturn schema;\n};\nSchema.prototype.pattern = function pattern(regexp) {\n\tconst schema = Schema(this);\n\tconst pattern = pick(regexp, [\"source\", \"flags\"]);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\tpattern\n\t};\n\treturn schema;\n};\nSchema.prototype.simplify = function simplify(value) {\n\tif (deepEqual(value, this.meta.default, this.type === \"dict\")) return null;\n\tif (isNullable(value)) return value;\n\tif (this.type === \"object\" || this.type === \"dict\") {\n\t\tconst result = {};\n\t\tfor (const key in value) {\n\t\t\tconst item = (this.type === \"object\" ? this.dict[key] : this.inner)?.simplify(value[key]);\n\t\t\tif (this.type === \"dict\" || !isNullable(item)) result[key] = item;\n\t\t}\n\t\tif (deepEqual(result, this.meta.default, this.type === \"dict\")) return null;\n\t\treturn result;\n\t} else if (this.type === \"array\" || this.type === \"tuple\") {\n\t\tconst result = [];\n\t\tvalue.forEach((value, index) => {\n\t\t\tconst schema = this.type === \"array\" ? this.inner : this.list[index];\n\t\t\tconst item = schema ? schema.simplify(value) : value;\n\t\t\tresult.push(item);\n\t\t});\n\t\treturn result;\n\t} else if (this.type === \"intersect\") {\n\t\tconst result = {};\n\t\tfor (const item of this.list) Object.assign(result, item.simplify(value));\n\t\treturn result;\n\t} else if (this.type === \"union\") for (const schema of this.list) try {\n\t\tSchema.resolve(value, schema, {});\n\t\treturn schema.simplify(value);\n\t} catch {}\n\treturn value;\n};\nSchema.prototype.toString = function toString(inline) {\n\treturn formatters[this.type]?.(this, inline) ?? `Schema<${this.type}>`;\n};\nSchema.prototype.role = function role(role, extra) {\n\tconst schema = Schema(this);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\trole,\n\t\textra\n\t};\n\treturn schema;\n};\nfor (const key of [\n\t\"default\",\n\t\"link\",\n\t\"comment\",\n\t\"description\",\n\t\"max\",\n\t\"min\",\n\t\"step\"\n]) Object.assign(Schema.prototype, { [key](value) {\n\tconst schema = Schema(this);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\t[key]: value\n\t};\n\treturn schema;\n} });\nconst resolvers = {};\nSchema.extend = function extend(type, resolve) {\n\tresolvers[type] = resolve;\n};\nSchema.resolve = function resolve(data, schema, options = {}, strict = false) {\n\tif (!schema) return [data];\n\tif (options.ignore?.(data, schema)) return [data];\n\tif (isNullable(data) && schema.type !== \"lazy\") {\n\t\tif (schema.meta.required) throw new ValidationError(`missing required value`, options);\n\t\tlet current = schema;\n\t\tlet fallback = schema.meta.default;\n\t\twhile (current?.type === \"intersect\" && isNullable(fallback)) {\n\t\t\tcurrent = current.list[0];\n\t\t\tfallback = current?.meta.default;\n\t\t}\n\t\tif (isNullable(fallback)) return [data];\n\t\tdata = clone(fallback);\n\t}\n\tconst callback = resolvers[schema.type];\n\tif (!callback) throw new ValidationError(`unsupported type \"${schema.type}\"`, options);\n\ttry {\n\t\treturn callback(data, schema, options, strict);\n\t} catch (error) {\n\t\tif (!schema.meta.loose) throw error;\n\t\treturn [schema.meta.default];\n\t}\n};\nSchema.from = function from(source) {\n\tif (isNullable(source)) return Schema.any();\n\telse if ([\n\t\t\"string\",\n\t\t\"number\",\n\t\t\"boolean\"\n\t].includes(typeof source)) return Schema.const(source).required();\n\telse if (source[kSchema]) return source;\n\telse if (typeof source === \"function\") switch (source) {\n\t\tcase String: return Schema.string().required();\n\t\tcase Number: return Schema.number().required();\n\t\tcase Boolean: return Schema.boolean().required();\n\t\tcase Function: return Schema.function().required();\n\t\tdefault: return Schema.is(source).required();\n\t}\n\telse throw new TypeError(`cannot infer schema from ${source}`);\n};\nSchema.lazy = function lazy(builder) {\n\tconst toJSON = () => {\n\t\tif (!schema.inner[kSchema]) {\n\t\t\tschema.inner = schema.builder();\n\t\t\tschema.inner.meta = {\n\t\t\t\t...schema.meta,\n\t\t\t\t...schema.inner.meta\n\t\t\t};\n\t\t}\n\t\treturn schema.inner.toJSON();\n\t};\n\tconst schema = new Schema({\n\t\ttype: \"lazy\",\n\t\tbuilder,\n\t\tinner: { toJSON }\n\t});\n\treturn schema;\n};\nSchema.natural = function natural() {\n\treturn Schema.number().step(1).min(0);\n};\nSchema.percent = function percent() {\n\treturn Schema.number().step(.01).min(0).max(1).role(\"slider\");\n};\nSchema.date = function date() {\n\treturn Schema.union([Schema.is(Date), Schema.transform(Schema.string().role(\"datetime\"), (value, options) => {\n\t\tconst date = new Date(value);\n\t\tif (isNaN(+date)) throw new ValidationError(`invalid date \"${value}\"`, options);\n\t\treturn date;\n\t}, true)]);\n};\nSchema.regExp = function regExp(flag = \"\") {\n\treturn Schema.union([Schema.is(RegExp), Schema.transform(Schema.string().role(\"regexp\", { flag }), (value, options) => {\n\t\ttry {\n\t\t\treturn new RegExp(value, flag);\n\t\t} catch (e) {\n\t\t\tthrow new ValidationError(e.message, options);\n\t\t}\n\t}, true)]);\n};\nSchema.arrayBuffer = function arrayBuffer(encoding) {\n\treturn Schema.union([\n\t\tSchema.is(ArrayBuffer),\n\t\tSchema.is(SharedArrayBuffer),\n\t\tSchema.transform(Schema.any(), (value, options) => {\n\t\t\tif (Binary.isSource(value)) return Binary.fromSource(value);\n\t\t\tthrow new ValidationError(`expected ArrayBufferSource but got ${value}`, options);\n\t\t}, true),\n\t\t...encoding ? [Schema.transform(Schema.string(), (value, options) => {\n\t\t\ttry {\n\t\t\t\treturn encoding === \"base64\" ? Binary.fromBase64(value) : Binary.fromHex(value);\n\t\t\t} catch (e) {\n\t\t\t\tthrow new ValidationError(e.message, options);\n\t\t\t}\n\t\t}, true)] : []\n\t]);\n};\nSchema.extend(\"lazy\", (data, schema, options, strict) => {\n\tif (!schema.inner[kSchema]) {\n\t\tschema.inner = schema.builder();\n\t\tschema.inner.meta = {\n\t\t\t...schema.meta,\n\t\t\t...schema.inner.meta\n\t\t};\n\t}\n\treturn Schema.resolve(data, schema.inner, options, strict);\n});\nSchema.extend(\"any\", (data) => {\n\treturn [data];\n});\nSchema.extend(\"never\", (data, _, options) => {\n\tthrow new ValidationError(`expected nullable but got ${data}`, options);\n});\nSchema.extend(\"const\", (data, { value }, options) => {\n\tif (deepEqual(data, value)) return [value];\n\tthrow new ValidationError(`expected ${value} but got ${data}`, options);\n});\nfunction checkWithinRange(data, meta, description, options, skipMin = false) {\n\tconst { max = Infinity, min = -Infinity } = meta;\n\tif (data > max) throw new ValidationError(`expected ${description} <= ${max} but got ${data}`, options);\n\tif (data < min && !skipMin) throw new ValidationError(`expected ${description} >= ${min} but got ${data}`, options);\n}\nSchema.extend(\"string\", (data, { meta }, options) => {\n\tif (typeof data !== \"string\") throw new ValidationError(`expected string but got ${data}`, options);\n\tif (meta.pattern) {\n\t\tconst regexp = new RegExp(meta.pattern.source, meta.pattern.flags);\n\t\tif (!regexp.test(data)) throw new ValidationError(`expect string to match regexp ${regexp}`, options);\n\t}\n\tcheckWithinRange(data.length, meta, \"string length\", options);\n\treturn [data];\n});\nfunction decimalShift(data, digits) {\n\tconst str = data.toString();\n\tif (str.includes(\"e\")) return data * Math.pow(10, digits);\n\tconst index = str.indexOf(\".\");\n\tif (index === -1) return data * Math.pow(10, digits);\n\tconst frac = str.slice(index + 1);\n\tconst integer = str.slice(0, index);\n\tif (frac.length <= digits) return +(integer + frac.padEnd(digits, \"0\"));\n\treturn +(integer + frac.slice(0, digits) + \".\" + frac.slice(digits));\n}\nfunction isMultipleOf(data, min, step) {\n\tstep = Math.abs(step);\n\tif (!/^\\d+\\.\\d+$/.test(step.toString())) return (data - min) % step === 0;\n\tconst index = step.toString().indexOf(\".\");\n\tconst digits = step.toString().slice(index + 1).length;\n\treturn Math.abs(decimalShift(data, digits) - decimalShift(min, digits)) % decimalShift(step, digits) === 0;\n}\nSchema.extend(\"number\", (data, { meta }, options) => {\n\tif (typeof data !== \"number\") throw new ValidationError(`expected number but got ${data}`, options);\n\tcheckWithinRange(data, meta, \"number\", options);\n\tconst { step } = meta;\n\tif (step && !isMultipleOf(data, meta.min ?? 0, step)) throw new ValidationError(`expected number multiple of ${step} but got ${data}`, options);\n\treturn [data];\n});\nSchema.extend(\"boolean\", (data, _, options) => {\n\tif (typeof data === \"boolean\") return [data];\n\tthrow new ValidationError(`expected boolean but got ${data}`, options);\n});\nSchema.extend(\"bitset\", (data, { bits, meta }, options) => {\n\tlet value = 0, keys = [];\n\tif (typeof data === \"number\") {\n\t\tvalue = data;\n\t\tfor (const key in bits) if (data & bits[key]) keys.push(key);\n\t} else if (Array.isArray(data)) {\n\t\tkeys = data;\n\t\tfor (const key of keys) {\n\t\t\tif (typeof key !== \"string\") throw new ValidationError(`expected string but got ${key}`, options);\n\t\t\tif (key in bits) value |= bits[key];\n\t\t}\n\t} else throw new ValidationError(`expected number or array but got ${data}`, options);\n\tif (value === meta.default) return [value];\n\treturn [value, keys];\n});\nSchema.extend(\"function\", (data, _, options) => {\n\tif (typeof data === \"function\") return [data];\n\tthrow new ValidationError(`expected function but got ${data}`, options);\n});\nSchema.extend(\"is\", (data, { constructor }, options) => {\n\tif (typeof constructor === \"function\") {\n\t\tif (data instanceof constructor) return [data];\n\t\tthrow new ValidationError(`expected ${constructor.name} but got ${data}`, options);\n\t} else {\n\t\tif (isNullable(data)) throw new ValidationError(`expected ${constructor} but got ${data}`, options);\n\t\tlet prototype = Object.getPrototypeOf(data);\n\t\twhile (prototype) {\n\t\t\tif (prototype.constructor?.name === constructor) return [data];\n\t\t\tprototype = Object.getPrototypeOf(prototype);\n\t\t}\n\t\tthrow new ValidationError(`expected ${constructor} but got ${data}`, options);\n\t}\n});\nfunction property(data, key, schema, options) {\n\ttry {\n\t\tconst [value, adapted] = Schema.resolve(data[key], schema, {\n\t\t\t...options,\n\t\t\tpath: [...options.path || [], key]\n\t\t});\n\t\tif (adapted !== void 0) data[key] = adapted;\n\t\treturn value;\n\t} catch (e) {\n\t\tif (!options?.autofix) throw e;\n\t\tdelete data[key];\n\t\treturn schema.meta.default;\n\t}\n}\nSchema.extend(\"array\", (data, { inner, meta }, options) => {\n\tif (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);\n\tcheckWithinRange(data.length, meta, \"array length\", options, !isNullable(inner.meta.default));\n\treturn [data.map((_, index) => property(data, index, inner, options))];\n});\nSchema.extend(\"dict\", (data, { inner, sKey }, options, strict) => {\n\tif (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);\n\tconst result = {};\n\tfor (const key in data) {\n\t\tlet rKey;\n\t\ttry {\n\t\t\trKey = Schema.resolve(key, sKey, options)[0];\n\t\t} catch (error) {\n\t\t\tif (strict) continue;\n\t\t\tthrow error;\n\t\t}\n\t\tresult[rKey] = property(data, key, inner, options);\n\t\tdata[rKey] = data[key];\n\t\tif (key !== rKey) delete data[key];\n\t}\n\treturn [result];\n});\nSchema.extend(\"tuple\", (data, { list }, options, strict) => {\n\tif (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);\n\tconst result = list.map((inner, index) => property(data, index, inner, options));\n\tif (strict) return [result];\n\tresult.push(...data.slice(list.length));\n\treturn [result];\n});\nfunction merge(result, data) {\n\tfor (const key in data) {\n\t\tif (key in result) continue;\n\t\tresult[key] = data[key];\n\t}\n}\nSchema.extend(\"object\", (data, { dict }, options, strict) => {\n\tif (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);\n\tconst result = {};\n\tfor (const key in dict) {\n\t\tconst value = property(data, key, dict[key], options);\n\t\tif (!isNullable(value) || key in data) result[key] = value;\n\t}\n\tif (!strict) merge(result, data);\n\treturn [result];\n});\nSchema.extend(\"union\", (data, { list, toString }, options, strict) => {\n\tconst messages = [];\n\tfor (const inner of list) try {\n\t\treturn Schema.resolve(data, inner, options, strict);\n\t} catch (error) {\n\t\tmessages.push(error);\n\t}\n\tthrow new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);\n});\nSchema.extend(\"intersect\", (data, { list, toString }, options, strict) => {\n\tif (!list.length) return [data];\n\tlet result;\n\tfor (const inner of list) {\n\t\tconst value = Schema.resolve(data, inner, options, true)[0];\n\t\tif (isNullable(value)) continue;\n\t\tif (isNullable(result)) result = value;\n\t\telse if (typeof result !== typeof value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);\n\t\telse if (typeof value === \"object\") merge(result ??= {}, value);\n\t\telse if (result !== value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);\n\t}\n\tif (!strict && isPlainObject(data)) merge(result, data);\n\treturn [result];\n});\nSchema.extend(\"transform\", (data, { inner, callback, preserve }, options) => {\n\tconst [result, adapted = data] = Schema.resolve(data, inner, options, true);\n\tif (preserve) return [callback(result)];\n\telse return [callback(result), callback(adapted)];\n});\nconst formatters = {};\nfunction defineMethod(name, keys, format) {\n\tformatters[name] = format;\n\tObject.assign(Schema, { [name](...args) {\n\t\tconst schema = new Schema({ type: name });\n\t\tkeys.forEach((key, index) => {\n\t\t\tswitch (key) {\n\t\t\t\tcase \"sKey\":\n\t\t\t\t\tschema.sKey = args[index] ?? Schema.string();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"inner\":\n\t\t\t\t\tschema.inner = Schema.from(args[index]);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"list\":\n\t\t\t\t\tschema.list = args[index].map(Schema.from);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"dict\":\n\t\t\t\t\tschema.dict = valueMap(args[index], Schema.from);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"bits\":\n\t\t\t\t\tschema.bits = {};\n\t\t\t\t\tfor (const key in args[index]) {\n\t\t\t\t\t\tif (typeof args[index][key] !== \"number\") continue;\n\t\t\t\t\t\tschema.bits[key] = args[index][key];\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"callback\": {\n\t\t\t\t\tconst callback = schema.callback = args[index];\n\t\t\t\t\tcallback[\"toJSON\"] ||= () => callback.toString();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"constructor\": {\n\t\t\t\t\tconst constructor = schema.constructor = args[index];\n\t\t\t\t\tif (typeof constructor === \"function\") constructor[\"toJSON\"] ||= () => constructor[\"name\"];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: schema[key] = args[index];\n\t\t\t}\n\t\t});\n\t\tif (name === \"object\" || name === \"dict\") schema.meta.default = {};\n\t\telse if (name === \"array\" || name === \"tuple\") schema.meta.default = [];\n\t\telse if (name === \"bitset\") schema.meta.default = 0;\n\t\treturn schema;\n\t} });\n}\ndefineMethod(\"is\", [\"constructor\"], ({ constructor }) => {\n\tif (typeof constructor === \"function\") return constructor.name;\n\telse return constructor;\n});\ndefineMethod(\"any\", [], () => \"any\");\ndefineMethod(\"never\", [], () => \"never\");\ndefineMethod(\"const\", [\"value\"], ({ value }) => typeof value === \"string\" ? JSON.stringify(value) : value);\ndefineMethod(\"string\", [], () => \"string\");\ndefineMethod(\"number\", [], () => \"number\");\ndefineMethod(\"boolean\", [], () => \"boolean\");\ndefineMethod(\"bitset\", [\"bits\"], () => \"bitset\");\ndefineMethod(\"function\", [], () => \"function\");\ndefineMethod(\"array\", [\"inner\"], ({ inner }) => `${inner.toString(true)}[]`);\ndefineMethod(\"dict\", [\"inner\", \"sKey\"], ({ inner, sKey }) => `{ [key: ${sKey.toString()}]: ${inner.toString()} }`);\ndefineMethod(\"tuple\", [\"list\"], ({ list }) => `[${list.map((inner) => inner.toString()).join(\", \")}]`);\ndefineMethod(\"object\", [\"dict\"], ({ dict }) => {\n\tif (Object.keys(dict).length === 0) return \"{}\";\n\treturn `{ ${Object.entries(dict).map(([key, inner]) => {\n\t\treturn `${key}${inner.meta.required ? \"\" : \"?\"}: ${inner.toString()}`;\n\t}).join(\", \")} }`;\n});\ndefineMethod(\"union\", [\"list\"], ({ list }, inline) => {\n\tconst result = list.map(({ toString: format }) => format()).join(\" | \");\n\treturn inline ? `(${result})` : result;\n});\ndefineMethod(\"intersect\", [\"list\"], ({ list }) => {\n\treturn `${list.map((inner) => inner.toString(true)).join(\" & \")}`;\n});\ndefineMethod(\"transform\", [\n\t\"inner\",\n\t\"callback\",\n\t\"preserve\"\n], ({ inner }, isInner) => inner.toString(isInner));\n//#endregion\nexport { Schema as default };\n","/**\n * dsh-messager 配置模型。\n *\n * 本 schema 同时承担两个角色:\n * - host 端的 Loader config(cordis.yml 中该插件行的 `config:`,成为 settings 命名空间的 base 层);\n * - `ctx.settings.register('messager', Config, { base })` 的命名空间 schema,\n * 因此 Web 设置页会自动渲染配置表单,用户层可覆盖 base。\n *\n * 有效值优先级:schema 默认值 → base(cordis.yml)→ 用户层(设置页)。\n */\n\nimport Schema from '@deepseek-ai/schemastery'\n\n/** 通知内容繁复度。 */\nexport type Verbosity = 'minimal' | 'normal' | 'detailed'\n\n/** 触发时机开关(需求 1:什么时候通知)。 */\nexport interface TriggerConfig {\n /** 会话需要交互(审批 / 提问 / 计划待审)时通知。 */\n interaction: boolean\n /** 任务执行完毕时通知。 */\n completed: boolean\n /** 任务出错时通知。 */\n error: boolean\n}\n\n/** 系统通知通道(OS 级 toast,host 端由 node-notifier 投递)。 */\nexport interface SystemChannelConfig {\n enabled: boolean\n /** 图标:绝对路径(或包内 assets/icon.png 的绝对路径)。 */\n icon?: string\n verbosity: Verbosity\n}\n\n/** 浏览器通知通道(Web Notification API,client 端投递)。 */\nexport interface BrowserChannelConfig {\n enabled: boolean\n /** 图标:URL 或 data URL。 */\n icon?: string\n /** 仅当页面隐藏/未聚焦时才弹通知,避免看着界面还被打扰。 */\n onlyWhenHidden: boolean\n verbosity: Verbosity\n}\n\n/** 飞书机器人通道(webhook 版,即自定义机器人 webhook,host 端投递)。 */\nexport interface FeishuChannelConfig {\n enabled: boolean\n /** 飞书自定义机器人 webhook 地址。 */\n webhookUrl?: string\n /** 签名密钥(飞书机器人 webhook“安全设置-签名校验”),配置后按 HMAC-SHA256 签名。 */\n secret?: string\n /** 单次请求超时(ms)。 */\n timeoutMs: number\n verbosity: Verbosity\n}\n\n/** 去重 / 节流配置。 */\nexport interface DedupConfig {\n /** 同一会话同一类触发的冷却时间(ms)。 */\n interactionCooldownMs: number\n /** 完成通知防抖窗口(ms):等待 turn/end 事件以丰富内容并合并边界抖动。 */\n completedDebounceMs: number\n /** 每通道每分钟通知上限(防止第三方通道限流/刷屏)。 */\n perChannelPerMinute: number\n}\n\n/** 消息内容配置。 */\nexport interface MessageConfig {\n /** 标题前缀,例如 \"[DSH]\"。 */\n titlePrefix?: string\n /** 正文是否附带会话标题。 */\n includeSessionTitle: boolean\n /** GUI 地址,用于通知中的“打开”链接/按钮。 */\n guiUrl: string\n}\n\nexport interface Config {\n triggers: TriggerConfig\n system: SystemChannelConfig\n browser: BrowserChannelConfig\n feishu: FeishuChannelConfig\n dedup: DedupConfig\n message: MessageConfig\n}\n\nconst verbosity = Schema.union(['minimal', 'normal', 'detailed'] as const)\n\nexport const Config: Schema<Config> = Schema.object({\n triggers: Schema.object({\n interaction: Schema.boolean().default(true),\n completed: Schema.boolean().default(true),\n error: Schema.boolean().default(true),\n }),\n system: Schema.object({\n enabled: Schema.boolean().default(true),\n // 无 default 的字段即可选(undefined 允许)\n // 注意:node-notifier 需要文件路径且该文件必须存在;Linux(notify-send)与\n // macOS(terminal-notifier)对缺失路径可能直接失败而非像 Windows 那样降级,\n // 通道层虽已做存在性校验,仍建议配置有效的绝对路径。\n icon: Schema.string(),\n verbosity: verbosity.default('normal'),\n }),\n browser: Schema.object({\n enabled: Schema.boolean().default(true),\n icon: Schema.string(),\n onlyWhenHidden: Schema.boolean().default(true),\n verbosity: verbosity.default('normal'),\n }),\n feishu: Schema.object({\n enabled: Schema.boolean().default(false),\n webhookUrl: Schema.string(),\n secret: Schema.string().role('secret'),\n timeoutMs: Schema.number().default(5000),\n verbosity: verbosity.default('normal'),\n }),\n dedup: Schema.object({\n interactionCooldownMs: Schema.number().default(10000),\n completedDebounceMs: Schema.number().default(1000),\n perChannelPerMinute: Schema.number().default(20),\n }),\n message: Schema.object({\n titlePrefix: Schema.string(),\n includeSessionTitle: Schema.boolean().default(true),\n guiUrl: Schema.string().default('http://127.0.0.1:3080'),\n }),\n})\n\n/**\n * 用 schema 默认值解析一份配置(输入可省略任意字段)。\n * 与 cordis Loader 的校验同源,保证“默认值 → base → 用户层”的解析一致。\n */\nexport function resolveConfig(input: Partial<Config> = {}): Config {\n return Config(input as Config)\n}\n","/**\n * 配置路由的跨端共享类型(host 与浏览器 client 共用,不得 import 任何\n * Node/浏览器专属模块)。\n */\n\n/** 配置路由路径(挂在 DSH webServer 上,同源访问)。 */\nexport const CONFIG_PATH = '/dsh-messager/config'\n\n/** client ScopeLike 快照同构的配置视图。 */\nexport interface ConfigView {\n status: 'ready' | 'unavailable'\n value: unknown\n user: unknown\n base: unknown\n writable: boolean\n mode: 'host'\n revision?: number\n}\n\n/** client ScopeWriteOp 同构的写操作。 */\nexport interface ConfigWriteOp {\n op: 'set' | 'unset'\n path: string[]\n value?: unknown\n}\n\n/** POST /dsh-messager/config 的请求体。 */\nexport interface ConfigWriteBody {\n ops: ConfigWriteOp[]\n expectedRevision?: number\n}\n","/**\n * 客户端配置读取:经 host 配置路由(GET /dsh-messager/config)拉取 messager\n * 命名空间有效值,并通过 `settings/document-updated` 失效后重拉。\n * 路由不受 Web 设置白名单门控,发行版同样可用;拉取失败回退 schema 默认值。\n */\n\nimport { resolveConfig, type Config } from '../config.js'\nimport { CONFIG_PATH, type ConfigView } from '../config-shared.js'\n\nexport interface ClientConfigHandle {\n get(): Config\n subscribe(listener: () => void): () => void\n refresh(): Promise<void>\n}\n\nexport class ClientConfig implements ClientConfigHandle {\n private current: Config = resolveConfig({})\n private readonly listeners = new Set<() => void>()\n\n get(): Config {\n return this.current\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n /** 拉取 host 配置视图(首次与收到 document-updated 后调用)。 */\n async refresh(): Promise<void> {\n try {\n const response = await fetch(CONFIG_PATH, { headers: { accept: 'application/json' } })\n if (!response.ok) return\n const view = (await response.json()) as ConfigView\n if (view.status !== 'ready' || view.value === undefined) return\n this.current = resolveConfig(view.value as Partial<Config>)\n for (const listener of [...this.listeners]) listener()\n } catch {\n // 拉取失败(路由未挂载/网络问题)保持当前值,不打断插件\n }\n }\n}\n","/**\n * 客户端会话摘要 diff(纯函数,可单测):\n * 对比两次会话列表快照,产出需要浏览器通知的变化。\n * 语义与 Web UI 状态圆点完全一致:\n * - pendingInteraction 从无到有 → 需要交互(橙点)\n * - running true→false 且会话非当前选中 → 任务完成(绿点)\n */\n\nimport type { SessionId, SessionSummary } from '@deepseek-ai/dsh-client-runtime/client'\n\nexport type ClientNoticeKind = 'interaction' | 'completed'\n\nexport interface ClientNotice {\n kind: ClientNoticeKind\n sessionId: SessionId\n /** interaction 细分(与 PendingInteractionStatus 一致)。 */\n interaction?: 'approval' | 'plan-review' | 'question'\n /** 会话显示标题(displayTitle)。 */\n title?: string\n}\n\n/**\n * 对比两次列表快照。\n * 首次出现的会话只建立基线、不通知;被移除的会话不通知。\n * @param previous - 上一次快照的 byId。\n * @param next - 本次快照的 byId。\n * @param current - 本次快照的当前选中会话(选中会话的完成不打扰)。\n */\nexport function diffSessionSummaries(\n previous: Readonly<Record<SessionId, SessionSummary>>,\n next: Readonly<Record<SessionId, SessionSummary>>,\n current: SessionId | undefined,\n): ClientNotice[] {\n const notices: ClientNotice[] = []\n for (const id of Object.keys(next) as SessionId[]) {\n const summary = next[id]\n if (summary === undefined) continue\n const before = previous[id]\n if (before === undefined) continue // 首次出现:只建立基线\n if (summary.pendingInteraction !== undefined && before.pendingInteraction === undefined) {\n notices.push({\n kind: 'interaction',\n sessionId: id,\n interaction: summary.pendingInteraction,\n title: summary.displayTitle,\n })\n }\n if (before.running && !summary.running && id !== current) {\n notices.push({ kind: 'completed', sessionId: id, title: summary.displayTitle })\n }\n }\n return notices\n}\n","/**\n * 设置页卡片:字段清单与表单控制器(纯逻辑,可单测)。\n *\n * 配置为嵌套结构,而客户端 SettingsScope 的 set/unset 只支持单层路径写,\n * 因此保存走 scope.writeOps:把每个草稿翻译为一条「嵌套路径」写操作\n * (set/unset path: ['group', 'field']),由适配层直连 settings RPC。\n *\n * 为什么不用「整组合并 set」:mutate 的 set 是**整组替换**语义——\n * 1) 服务端回显脱敏(write-only 密钥永不回显),写后校验必然误报失败;\n * 2) 合并对象不含密钥时,已存的密钥会被静默抹掉。\n * 逐字段路径写则只在显式填写/重置密钥时才触碰它,其余字段互不牵连。\n *\n * feishu.secret 为 write-only(服务端会脱敏,响应永不携带其值):\n * - 输入框留空 = 不修改;填入并保存 = 写入;\n * - 点「重置」= 发出 unset 清除已存密钥。\n */\n\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-runtime/client'\n\n/** 字段控件类型。 */\nexport type CardFieldKind = 'toggle' | 'text' | 'number' | 'select'\n\n/** 门控:仅当指定组内开关字段生效值为 true 时,该字段才可编辑/可见。 */\nexport interface FieldHiddenUnless {\n group: string\n field: string\n}\n\n/** 一个可编辑字段(位于某个顶层配置组内)。 */\nexport interface CardFieldSpec {\n /** 顶层组:config 的一级键,同时是 scope 的标量字段名。 */\n group: string\n /** 组内字段名。 */\n field: string\n kind: CardFieldKind\n label: string\n hint?: string\n /** select 的选项。 */\n options?: readonly string[]\n /** write-only 字段(secret):响应永不携带其值。 */\n secret?: boolean\n /** 门控开关:开关关闭时该字段不可见且保存计划跳过(如第三方通道的子配置)。 */\n hiddenUnless?: FieldHiddenUnless\n}\n\n/** 字段渲染状态。 */\nexport interface CardFieldState {\n /** 草稿文本 / 选中值。 */\n text: string\n /** 保存后是否会产生用户层覆盖。 */\n overridden: boolean\n /** 草稿非法(数字格式错误等),阻止保存。 */\n invalid: boolean\n}\n\n/** 卡片状态快照(槽位 hook 的载荷)。 */\nexport interface MessagerCardState {\n /** 命名空间是否可用(ready)。 */\n available: boolean\n /** 原始 scope 状态(loading/unavailable/ready),供提示区分原因。 */\n status: string\n /** 连接模式(host/memory);memory = 非 loopback 访问,设置页不可用。 */\n mode: string\n /** 设置文档是否可写。 */\n writable: boolean\n /** 是否存在待保存的编辑。 */\n dirty: boolean\n /** 是否有非法草稿。 */\n invalid: boolean\n saving: boolean\n failed: boolean\n fields: Readonly<Record<string, CardFieldState>>\n}\n\n/** 卡片动作(组件直接调用)。 */\nexport interface MessagerCardActions {\n edit(group: string, field: string, text: string): void\n reset(group: string, field: string): void\n save(): void\n discard(): void\n}\n\n/** 槽位注入面:hooks 中的 messagerCard 会变成 useMessagerCard 选择器;动作平铺为组件 props。 */\nexport interface MessagerCardFace {\n hooks: {\n messagerCard: {\n getSnapshot(): MessagerCardState\n subscribe(listener: () => void): () => void\n }\n }\n edit(group: string, field: string, text: string): void\n reset(group: string, field: string): void\n save(): void\n discard(): void\n /** 翻译函数(键 → 当前语言文案);未接入 locale 时原样返回键。 */\n t(key: string): string\n}\n\n/** 一条嵌套路径写操作(与 settings.mutate 的 SettingsPathOpView 同构)。 */\nexport type ScopeWriteOp =\n | { op: 'set'; path: string[]; value: unknown }\n | { op: 'unset'; path: string[] }\n\n/** 控制器依赖的 scope 窄接口(便于测试替身)。 */\nexport interface ScopeLike {\n getSnapshot(): {\n status: string\n value: unknown\n user: unknown\n base: unknown\n writable: boolean\n mode?: string\n /** 命名空间修订号(直连 api 写时作为 expectedRevision 回传)。 */\n revision?: number\n }\n subscribe(listener: () => void): () => void\n set(field: string, value: unknown): Promise<void>\n unset(field: string): Promise<void>\n /** 一次批量嵌套路径写;返回是否落库成功。memory 模式下应静默成功(与 scope 一致)。 */\n writeOps(ops: readonly ScopeWriteOp[]): Promise<boolean>\n}\n\n/** 字段键:`group.field`。 */\nexport function fieldKey(group: string, field: string): string {\n return `${group}.${field}`\n}\n\n/**\n * 渲染层门控判断(与控制器 gatedOff 语义一致):\n * hiddenUnless 指定的开关字段当前(含草稿)不为 true 时,该字段不渲染。\n */\nexport function isFieldGated(\n spec: CardFieldSpec,\n fields: Readonly<Record<string, CardFieldState>>,\n): boolean {\n const gate = spec.hiddenUnless\n if (gate === undefined) return false\n return fields[fieldKey(gate.group, gate.field)]?.text !== 'true'\n}\n\ninterface StagedEdit {\n text: string\n clear: boolean\n}\n\ninterface PlannedWrite {\n run?: () => Promise<boolean>\n}\n\n/** 把草稿解析为组内值;undefined 表示非法(阻止保存)。 */\nfunction parseDraft(spec: CardFieldSpec, text: string): unknown | undefined {\n const trimmed = text.trim()\n switch (spec.kind) {\n case 'toggle':\n return trimmed === 'true' ? true : trimmed === 'false' ? false : undefined\n case 'select':\n return spec.options?.includes(trimmed) ? trimmed : undefined\n case 'number': {\n if (trimmed === '') return undefined\n const parsed = Number(trimmed)\n return Number.isFinite(parsed) ? parsed : undefined\n }\n case 'text':\n return trimmed\n }\n}\n\n/** 把存储值格式化为草稿文本。 */\nfunction formatValue(spec: CardFieldSpec, value: unknown): string {\n if (spec.secret === true) return '' // write-only:永不回显\n if (value === undefined || value === null) return ''\n return String(value)\n}\n\nexport class MessagerCardController {\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n private saving = false\n private failed = false\n private cache: MessagerCardState | null = null\n\n constructor(\n private readonly scope: ScopeLike,\n private readonly fields: readonly CardFieldSpec[],\n ) {\n scope.subscribe(() => this.invalidate())\n }\n\n /** 槽位注入面。 */\n inject(): MessagerCardFace {\n return {\n hooks: {\n messagerCard: {\n getSnapshot: () => this.getSnapshot(),\n subscribe: (listener) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n },\n },\n },\n edit: (group, field, text) => this.stage(group, field, { text, clear: false }),\n reset: (group, field) => {\n const spec = this.spec(group, field)\n this.stage(group, field, { text: formatValue(spec, this.baseValue(group, field)), clear: true })\n },\n save: () => {\n void this.save()\n },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.invalidate()\n },\n // 默认透传键(组件未接入 locale 时 fail loud);client/index.ts 组装真实 t\n t: (key: string) => key,\n }\n }\n\n /**\n * 读取缓存的快照。\n * 注意:useSyncExternalStore 要求 getSnapshot 在状态未变化时返回**同一引用**,\n * 否则 React 会以 #185(最大更新深度)崩溃 —— 因此快照按变更点惰性计算并缓存,\n * 只有 invalidate() 之后才重建。\n */\n getSnapshot(): MessagerCardState {\n return this.cache ??= this.compute()\n }\n\n private compute(): MessagerCardState {\n const snapshot = this.scope.getSnapshot()\n const available = snapshot.status === 'ready'\n const fields: Record<string, CardFieldState> = {}\n for (const spec of this.fields) {\n const key = fieldKey(spec.group, spec.field)\n const staged = this.staged.get(key)\n const effective = this.effectiveValue(spec)\n if (staged === undefined) {\n fields[key] = {\n text: formatValue(spec, effective),\n overridden: this.userHas(spec),\n invalid: false,\n }\n continue\n }\n fields[key] = {\n text: staged.text,\n overridden: staged.clear ? false : this.userHas(spec),\n invalid: staged.clear ? false : parseDraft(spec, staged.text) === undefined,\n }\n }\n const plan = this.plan()\n return {\n available,\n status: snapshot.status,\n mode: snapshot.mode ?? '',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some(item => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n fields,\n }\n }\n\n private effectiveValue(spec: CardFieldSpec): unknown {\n const group = this.groupValue(spec.group)\n if (group === undefined) return undefined\n return group[spec.field]\n }\n\n private groupValue(group: string): Record<string, unknown> | undefined {\n const value = this.scope.getSnapshot().value\n if (typeof value !== 'object' || value === null) return undefined\n const record = value as Record<string, unknown>\n const section = record[group]\n return typeof section === 'object' && section !== null\n ? section as Record<string, unknown>\n : undefined\n }\n\n private baseValue(group: string, field: string): unknown {\n const base = this.scope.getSnapshot().base\n if (typeof base !== 'object' || base === null) return undefined\n const section = (base as Record<string, unknown>)[group]\n if (typeof section !== 'object' || section === null) return undefined\n return (section as Record<string, unknown>)[field]\n }\n\n private userHas(spec: CardFieldSpec): boolean {\n const user = this.scope.getSnapshot().user\n if (typeof user !== 'object' || user === null) return false\n const section = (user as Record<string, unknown>)[spec.group]\n return typeof section === 'object' && section !== null\n && Object.hasOwn(section as Record<string, unknown>, spec.field)\n }\n\n private stage(group: string, field: string, edit: StagedEdit): void {\n this.staged.set(fieldKey(group, field), edit)\n this.failed = false\n this.invalidate()\n }\n\n private spec(group: string, field: string): CardFieldSpec {\n const spec = this.fields.find(candidate => candidate.group === group && candidate.field === field)\n if (spec === undefined) throw new Error(`messager card has no field ${group}.${field}`)\n return spec\n }\n\n /**\n * 计算保存计划:把每个有效草稿翻译为一条嵌套路径写操作。\n * 逐字段而非整组合并:密钥字段只有被显式填写/重置时才生成 op,\n * 其余字段互不牵连(mutate 的 set 是整组替换,合并写会抹掉未回显的密钥)。\n */\n private plan(): PlannedWrite[] {\n const ops: ScopeWriteOp[] = []\n for (const [key, staged] of this.staged) {\n const [group, field] = key.split('.') as [string, string]\n const spec = this.spec(group, field)\n if (this.gatedOff(spec)) continue // 门控关闭:隐藏字段的草稿不参与保存\n if (spec.secret === true && staged.text.trim() === '' && !staged.clear) continue // 留空不修改\n if (staged.clear) {\n // unset 幂等;非密钥字段在用户层没有覆盖时无需操作\n // (密钥无法从脱敏层得知是否已存,总是发出,对未存场景无害)\n if (!spec.secret && !this.userHas(spec)) continue\n ops.push({ op: 'unset', path: [group, field] })\n continue\n }\n const desired = parseDraft(spec, staged.text)\n if (desired === undefined) return [{ run: undefined }] // 任一非法草稿阻塞整个保存\n // 密钥无法与已存值比较(write-only),总是写(幂等);其余字段无实际变化时跳过\n if (spec.secret !== true && deepEqualJson(desired, this.effectiveValue(spec))) continue\n ops.push({ op: 'set', path: [group, field], value: desired })\n }\n if (ops.length === 0) return []\n const scope = this.scope\n return [{\n run: async () => {\n const ok = await scope.writeOps(ops)\n return ok\n },\n }]\n }\n\n /**\n * 门控判断:hiddenUnless 指定的开关字段当前(含草稿覆盖)不为 true 时,\n * 该字段不可见、草稿不参与保存。\n */\n gatedOff(spec: CardFieldSpec): boolean {\n const gate = spec.hiddenUnless\n if (gate === undefined) return false\n const gateKey = fieldKey(gate.group, gate.field)\n const gateSpec = this.spec(gate.group, gate.field)\n const staged = this.staged.get(gateKey)\n let gateValue: unknown\n if (staged !== undefined && !staged.clear) {\n gateValue = parseDraft(gateSpec, staged.text)\n } else {\n gateValue = this.effectiveValue(gateSpec)\n }\n return gateValue !== true\n }\n\n private async save(): Promise<void> {\n const plan = this.plan()\n if (plan.length === 0 || this.saving || plan.some(item => item.run === undefined)) return\n this.saving = true\n this.failed = false\n this.invalidate()\n let landed = true\n for (const item of plan) {\n if (item.run === undefined) continue\n landed = (await item.run()) && landed\n }\n if (landed) this.staged.clear()\n this.saving = false\n this.failed = !landed\n this.invalidate()\n }\n\n /** 失效缓存并通知订阅者(getSnapshot 下一次调用时重建)。 */\n private invalidate(): void {\n this.cache = null\n for (const listener of [...this.listeners]) listener()\n }\n}\n\n/** 深比较 JSON 形状数据(组对象比较)。 */\nexport function deepEqualJson(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false\n return a.every((entry, index) => deepEqualJson(entry, b[index]))\n }\n const left = a as Record<string, unknown>\n const right = b as Record<string, unknown>\n const keys = Object.keys(left)\n if (keys.length !== Object.keys(right).length) return false\n return keys.every(key => key in right && deepEqualJson(left[key], right[key]))\n}\n\n/**\n * 设置分区展示的字段清单。\n * label/hint 为**翻译键**(见 src/client/locales.ts),渲染层经 t() 取当前语言;\n * 键名与字典一致,缺键时 t() 原样返回键名(fail loud)。\n */\nexport const CARD_FIELDS: readonly CardFieldSpec[] = [\n // 触发时机\n { group: 'triggers', field: 'interaction', kind: 'toggle', label: 'field.triggers.interaction' },\n { group: 'triggers', field: 'completed', kind: 'toggle', label: 'field.triggers.completed' },\n { group: 'triggers', field: 'error', kind: 'toggle', label: 'field.triggers.error' },\n // 系统通知\n { group: 'system', field: 'enabled', kind: 'toggle', label: 'field.system.enabled' },\n { group: 'system', field: 'verbosity', kind: 'select', label: 'field.system.verbosity', options: ['minimal', 'normal', 'detailed'] },\n { group: 'system', field: 'icon', kind: 'text', label: 'field.system.icon', hint: 'hint.system.icon' },\n // 浏览器通知\n { group: 'browser', field: 'enabled', kind: 'toggle', label: 'field.browser.enabled' },\n { group: 'browser', field: 'onlyWhenHidden', kind: 'toggle', label: 'field.browser.onlyWhenHidden' },\n { group: 'browser', field: 'verbosity', kind: 'select', label: 'field.browser.verbosity', options: ['minimal', 'normal', 'detailed'] },\n { group: 'browser', field: 'icon', kind: 'text', label: 'field.browser.icon' },\n // 第三方推送(飞书机器人 webhook):enabled 为门控开关,关闭时不显示/不保存子配置\n { group: 'feishu', field: 'enabled', kind: 'toggle', label: 'field.feishu.enabled' },\n {\n group: 'feishu', field: 'webhookUrl', kind: 'text', label: 'field.feishu.webhookUrl',\n hiddenUnless: { group: 'feishu', field: 'enabled' },\n },\n {\n group: 'feishu', field: 'secret', kind: 'text', label: 'field.feishu.secret',\n hint: 'hint.feishu.secret', secret: true,\n hiddenUnless: { group: 'feishu', field: 'enabled' },\n },\n {\n group: 'feishu', field: 'timeoutMs', kind: 'number', label: 'field.feishu.timeoutMs',\n hiddenUnless: { group: 'feishu', field: 'enabled' },\n },\n {\n group: 'feishu', field: 'verbosity', kind: 'select', label: 'field.feishu.verbosity',\n options: ['minimal', 'normal', 'detailed'],\n hiddenUnless: { group: 'feishu', field: 'enabled' },\n },\n // 消息内容\n { group: 'message', field: 'titlePrefix', kind: 'text', label: 'field.message.titlePrefix', hint: 'hint.message.titlePrefix' },\n { group: 'message', field: 'includeSessionTitle', kind: 'toggle', label: 'field.message.includeSessionTitle' },\n { group: 'message', field: 'guiUrl', kind: 'text', label: 'field.message.guiUrl' },\n]\n","/**\n * fetch 版 ScopeLike:浏览器经 /dsh-messager/config 路由读写配置。\n * 替代 settingsScope(受 Web 设置白名单门控)—— 本通道不受门控,发行版可用。\n *\n * - getSnapshot:缓存视图(初始 loading;无变化时返回同一引用,满足\n * useSyncExternalStore 契约);\n * - subscribe:document-updated 事件或显式 refresh 时重新 GET 并通知;\n * - writeOps:POST 逐字段 ops,成功后重新 GET。\n *\n * fetcher 可注入,便于单测。\n */\n\nimport type { ConfigView, ConfigWriteBody } from '../config-shared.js'\nimport type { ScopeLike, ScopeWriteOp } from './card-controller.js'\n\n/** 路由访问器(浏览器 fetch 实现见 client/index.ts;测试注入替身)。 */\nexport interface ConfigFetcher {\n get(): Promise<ConfigView>\n write(body: ConfigWriteBody): Promise<{ ok: boolean; error?: string }>\n}\n\n/** 快照形状(与 ScopeLike.getSnapshot 声明一致)。 */\ninterface ViewSnapshot {\n status: string\n value: unknown\n user: unknown\n base: unknown\n writable: boolean\n mode?: string\n revision?: number\n}\n\nexport interface FetchScope {\n scope: ScopeLike\n /** 重新拉取配置视图(document-updated 或手动触发)。 */\n refresh(): Promise<void>\n}\n\n/** 创建 fetch 版 scope。 */\nexport function createFetchScope(fetcher: ConfigFetcher): FetchScope {\n let view: ViewSnapshot = {\n status: 'loading',\n value: undefined,\n user: undefined,\n base: undefined,\n writable: false,\n mode: 'host',\n }\n const listeners = new Set<() => void>()\n const notify = (): void => {\n for (const listener of [...listeners]) listener()\n }\n\n const refresh = async (): Promise<void> => {\n let next: ConfigView\n try {\n next = await fetcher.get()\n } catch {\n // 拉取失败(路由未挂载等):标记不可用,不打断订阅者\n view = { ...view, status: 'unavailable' }\n notify()\n return\n }\n view = {\n status: next.status,\n value: next.value,\n user: next.user,\n base: next.base,\n writable: next.writable,\n mode: next.mode,\n revision: next.revision,\n }\n notify()\n }\n\n const scope: ScopeLike = {\n getSnapshot: () => view,\n subscribe: (listener) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n async set(field: string, value: unknown) {\n await scope.writeOps([{ op: 'set', path: [field], value }])\n },\n async unset(field: string) {\n await scope.writeOps([{ op: 'unset', path: [field] }])\n },\n async writeOps(ops: readonly ScopeWriteOp[]) {\n const result = await fetcher.write({ ops: ops as ConfigWriteBody['ops'] })\n if (result.ok) await refresh()\n return result.ok\n },\n }\n\n return { scope, refresh }\n}\n","/**\n * dsh-messager 设置表单体(设置页分区共用)。\n *\n * 渲染全部字段分组(FieldRow)+ 底部操作栏(放弃修改 / 保存),\n * 样式沿用 DSH 主题变量(--dsw-alias-*),与 ValueField 布局同源。\n * 文案经 t() 取当前语言(字典见 locales.ts);字段 label/hint 为翻译键。\n */\n\nimport type { ReactNode } from 'react'\nimport { CARD_FIELDS, isFieldGated } from './card-controller.js'\nimport type { CardFieldSpec, MessagerCardActions, MessagerCardState } from './card-controller.js'\n\n/** 分组标题的翻译键(键见 locales.ts;导出供字典一致性测试)。 */\nexport const GROUP_TITLE_KEYS: Record<string, string> = {\n triggers: 'group.triggers',\n system: 'group.system',\n browser: 'group.browser',\n feishu: 'group.feishu',\n message: 'group.message',\n}\n\n// ---- DSH 主题变量(fields.module.css 同源) ----\n\nconst FIELD_STYLE: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n padding: '12px 0',\n}\n\nconst FIELD_HEAD_STYLE: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n}\n\nconst FIELD_LABEL_STYLE: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n fontSize: 13,\n fontWeight: 500,\n lineHeight: 1.5,\n color: 'var(--dsw-alias-label-primary)',\n}\n\nconst BADGE_STYLE: React.CSSProperties = {\n borderRadius: 999,\n padding: '1px 8px',\n fontSize: 11,\n lineHeight: '17px',\n whiteSpace: 'nowrap',\n fontWeight: 500,\n background: 'var(--dsw-alias-bg-module-platform)',\n color: 'var(--dsw-alias-label-secondary)',\n}\n\nconst RESET_STYLE: React.CSSProperties = {\n border: 'none',\n background: 'none',\n padding: 0,\n font: 'inherit',\n fontSize: 12,\n lineHeight: 1.5,\n color: 'var(--dsw-alias-label-secondary)',\n cursor: 'pointer',\n}\n\nconst INPUT_STYLE: React.CSSProperties = {\n height: 34,\n padding: '0 12px',\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n background: 'var(--dsw-alias-bg-layer-3)',\n font: 'inherit',\n fontSize: 13,\n lineHeight: 1.5,\n color: 'var(--dsw-alias-label-primary)',\n}\n\nconst HINT_STYLE: React.CSSProperties = {\n margin: 0,\n fontSize: 12,\n lineHeight: 1.5,\n color: 'var(--dsw-alias-label-tertiary)',\n}\n\nconst INVALID_STYLE: React.CSSProperties = {\n ...HINT_STYLE,\n color: 'var(--dsw-alias-label-error)',\n}\n\nconst GROUP_HEADING_STYLE: React.CSSProperties = {\n margin: '12px 0 0',\n fontSize: 12,\n fontWeight: 600,\n lineHeight: 1.5,\n color: 'var(--dsw-alias-label-tertiary)',\n}\n\nconst READ_ONLY_STYLE: React.CSSProperties = {\n margin: '12px 0 0',\n fontSize: 12,\n lineHeight: 1.5,\n color: 'var(--dsw-alias-label-tertiary)',\n}\n\nconst FOOTER_STYLE: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: 8,\n padding: '12px 0 4px',\n borderTop: '1px solid var(--dsw-alias-border-l2)',\n marginTop: 12,\n}\n\nconst FAILED_STYLE: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n margin: 0,\n fontSize: 12,\n lineHeight: 1.5,\n color: 'var(--dsw-alias-label-error)',\n}\n\nconst BUTTON_BASE: React.CSSProperties = {\n appearance: 'none',\n border: '1px solid transparent',\n borderRadius: 8,\n padding: '5px 14px',\n font: 'inherit',\n fontSize: 13,\n lineHeight: 1.5,\n cursor: 'pointer',\n}\n\nconst DISCARD_STYLE: React.CSSProperties = {\n ...BUTTON_BASE,\n borderColor: 'var(--dsw-alias-border-l2)',\n background: 'none',\n color: 'var(--dsw-alias-label-secondary)',\n}\n\nconst SAVE_STYLE: React.CSSProperties = {\n ...BUTTON_BASE,\n background: 'var(--dsw-alias-label-primary)',\n color: 'var(--dsw-alias-bg-layer-3)',\n}\n\n// ---- 字段行(ValueField 同款布局) ----\n\n/** 渲染一个字段行(DSH ValueField 同款;toggle 标签与勾选框同一行)。 */\nfunction FieldRow({ spec, state, actions, t, disabled }: {\n spec: CardFieldSpec\n state: MessagerCardState['fields'][string]\n actions: MessagerCardActions\n t: (key: string) => string\n disabled: boolean\n}) {\n const id = `dsh-messager-${spec.group}-${spec.field}`\n const label = t(spec.label)\n const overriddenBadge = state.overridden && (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>\n <span style={BADGE_STYLE}>{t('badge.overridden')}</span>\n <button type=\"button\" style={RESET_STYLE} disabled={disabled} onClick={() => actions.reset(spec.group, spec.field)}>\n {t('action.reset')}\n </button>\n </span>\n )\n\n if (spec.kind === 'toggle') {\n // 勾选框与描述同一行:标签占满左侧,徽标/重置与勾选框靠右\n return (\n <div style={{ ...FIELD_STYLE, flexDirection: 'row', alignItems: 'center', flexWrap: 'wrap', gap: 8, minHeight: 34 }}>\n <label style={{ ...FIELD_LABEL_STYLE, flex: '1 1 auto', cursor: disabled ? 'default' : 'pointer' }} htmlFor={id}>\n {label}\n </label>\n {overriddenBadge}\n <input\n id={id}\n type=\"checkbox\"\n checked={state.text === 'true'}\n disabled={disabled}\n onChange={(event) => actions.edit(spec.group, spec.field, String(event.target.checked))}\n style={{ flex: 'none', accentColor: 'var(--dsw-alias-brand-primary)' }}\n />\n {spec.hint !== undefined && <p style={{ ...HINT_STYLE, flexBasis: '100%' }}>{t(spec.hint)}</p>}\n </div>\n )\n }\n\n let control: ReactNode\n if (spec.kind === 'select') {\n control = (\n <select\n id={id}\n value={state.text}\n disabled={disabled}\n onChange={(event) => actions.edit(spec.group, spec.field, event.target.value)}\n style={{ ...INPUT_STYLE, cursor: 'pointer' }}\n >\n {spec.options?.map(option => <option key={option} value={option}>{option}</option>)}\n </select>\n )\n } else {\n control = (\n <input\n id={id}\n type=\"text\"\n inputMode={spec.kind === 'number' ? 'numeric' : undefined}\n value={state.text}\n placeholder={spec.secret === true ? t('hint.feishu.secret') : undefined}\n disabled={disabled}\n aria-invalid={state.invalid}\n onChange={(event) => actions.edit(spec.group, spec.field, event.target.value)}\n style={state.invalid ? { ...INPUT_STYLE, borderColor: 'var(--dsw-alias-label-error)' } : INPUT_STYLE}\n />\n )\n }\n return (\n <div style={FIELD_STYLE}>\n <div style={FIELD_HEAD_STYLE}>\n <label style={FIELD_LABEL_STYLE} htmlFor={id}>{label}</label>\n {overriddenBadge}\n </div>\n {control}\n <p style={state.invalid ? INVALID_STYLE : HINT_STYLE}>\n {state.invalid ? t('status.invalidField') : spec.hint === undefined ? '' : t(spec.hint)}\n </p>\n </div>\n )\n}\n\n/** key → spec 查找表(渲染时用)。 */\nconst FIELD_LOOKUP: Record<string, CardFieldSpec> = Object.fromEntries(\n CARD_FIELDS.map(spec => [`${spec.group}.${spec.field}`, spec]),\n)\n\n/**\n * 设置表单体:全部字段分组 + 底部操作栏。\n * @param state - 控制器快照(useMessagerCard 的返回)。\n * @param actions - 控制器动作(edit/reset/save/discard)。\n * @param t - 翻译函数(键 → 当前语言文案)。\n */\nexport function MessagerSettingsForm({ state, actions, t }: {\n state: MessagerCardState\n actions: MessagerCardActions\n t: (key: string) => string\n}) {\n const groups = [...new Set(Object.keys(state.fields).map(key => key.split('.')[0]!))]\n const actionsDisabled = !state.writable || state.saving\n const blocked = !state.dirty || state.invalid || state.saving\n\n return (\n <>\n {!state.writable && <p style={READ_ONLY_STYLE} role=\"status\">{t('status.readOnly')}</p>}\n {groups.map(group => (\n <div key={group}>\n <p style={GROUP_HEADING_STYLE}>{t(GROUP_TITLE_KEYS[group] ?? group)}</p>\n {Object.entries(state.fields)\n .filter(([key]) => key.startsWith(`${group}.`))\n .map(([key, field]) => {\n const fieldName = key.slice(key.indexOf('.') + 1)\n const spec = FIELD_LOOKUP[key]\n if (spec === undefined) return null\n if (isFieldGated(spec, state.fields)) return null // 门控关闭:不渲染子配置\n return (\n <FieldRow\n key={key}\n spec={spec}\n state={field}\n actions={actions}\n t={t}\n disabled={actionsDisabled}\n />\n )\n })}\n </div>\n ))}\n <div style={FOOTER_STYLE}>\n {state.failed && <p style={FAILED_STYLE} role=\"status\">{t('status.saveFailed')}</p>}\n {state.invalid && !state.failed && <p style={FAILED_STYLE} role=\"status\">{t('status.invalidInput')}</p>}\n <button\n type=\"button\"\n style={{ ...DISCARD_STYLE, ...((!state.dirty && !state.failed) || state.saving ? { opacity: 0.4, cursor: 'default' } : {}) }}\n disabled={!state.dirty || state.saving}\n onClick={actions.discard}\n >\n {t('action.discard')}\n </button>\n <button\n type=\"button\"\n style={{ ...SAVE_STYLE, ...(blocked ? { opacity: 0.4, cursor: 'default' } : {}) }}\n disabled={blocked}\n onClick={actions.save}\n >\n {state.saving ? t('action.saving') : t('action.save')}\n </button>\n </div>\n </>\n )\n}\n","/**\n * 设置页分区组件:渲染在 设置 → 「通知&信使」分区(Agent预设下方,动态 order)。\n *\n * 数据走 webServer 配置路由(见 src/config-route.ts / fetch-scope.ts),\n * 不受 Web 设置白名单门控 —— 发行版(未打补丁)同样可读写。\n * 表单体复用 MessagerSettingsForm;文案经 face 平铺的 t() 取当前语言。\n */\n\nimport type { PropsRuntime, InjectFace } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { MessagerCardFace } from './card-controller.js'\nimport { MessagerSettingsForm } from './settings-form.jsx'\n\nexport type MessagerSectionProps = PropsRuntime<'settings.section'> & InjectFace<MessagerCardFace>\n\nconst SECTION_STYLE: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n maxWidth: 640,\n}\n\nconst TITLE_STYLE: React.CSSProperties = {\n margin: 0,\n fontSize: 18,\n fontWeight: 600,\n lineHeight: 1.4,\n color: 'var(--dsw-alias-label-primary)',\n}\n\nconst DESCRIPTION_STYLE: React.CSSProperties = {\n margin: 0,\n fontSize: 13,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-label-tertiary)',\n}\n\nconst UNAVAILABLE_STYLE: React.CSSProperties = {\n margin: 0,\n fontSize: 13,\n lineHeight: 1.6,\n color: 'var(--dsw-alias-label-tertiary)',\n}\n\n/**\n * dsh-messager 设置分区(设置页「通知&信使」)。\n * @param props - 槽位 owner props + 注入面(useMessagerCard + 动作 + t)。\n */\nexport function MessagerSection(props: MessagerSectionProps) {\n const state = props.useMessagerCard(snapshot => snapshot)\n const { edit, reset, save, discard, t } = props\n\n return (\n <div style={SECTION_STYLE}>\n <div>\n <h2 style={TITLE_STYLE}>{t('nav')}</h2>\n <p style={DESCRIPTION_STYLE}>{t('section.description')}</p>\n </div>\n {state.available\n ? <MessagerSettingsForm state={state} actions={{ edit, reset, save, discard }} t={t} />\n : <p style={UNAVAILABLE_STYLE} role=\"status\">{t('status.unavailable')}</p>}\n </div>\n )\n}\n","/**\n * dsh-messager 客户端字典(zh / en),注册进 DSH locale 服务\n * (ctx.locale.register('dsh-messager', { zh, en }))。\n * 键集合必须 zh/en 一致(tests/locales.spec.ts 校验)。\n */\n\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** 本插件字典键(typed bind / slot locale 声明)。 */\n 'dsh-messager': keyof typeof zh\n }\n}\n\nexport const zh = {\n nav: '通知&信使',\n 'section.description': '会话交互 / 任务完成 / 出错时的通知推送:系统通知、浏览器通知、飞书机器人。',\n\n 'group.triggers': '触发时机',\n 'group.system': '系统通知',\n 'group.browser': '浏览器通知',\n 'group.feishu': '第三方推送',\n 'group.message': '消息内容',\n\n 'field.triggers.interaction': '需要交互时通知',\n 'field.triggers.completed': '任务完成时通知',\n 'field.triggers.error': '任务出错时通知',\n 'field.system.enabled': '启用系统通知',\n 'field.system.icon': '图标路径',\n 'field.system.verbosity': '内容繁复度',\n 'field.browser.enabled': '启用浏览器通知',\n 'field.browser.icon': '图标 URL',\n 'field.browser.onlyWhenHidden': '仅页面隐藏时通知',\n 'field.browser.verbosity': '内容繁复度',\n 'field.feishu.enabled': '飞书机器人',\n 'field.feishu.webhookUrl': 'Webhook 地址',\n 'field.feishu.secret': '签名密钥',\n 'field.feishu.timeoutMs': '请求超时(毫秒)',\n 'field.feishu.verbosity': '内容繁复度',\n 'field.message.titlePrefix': '标题前缀',\n 'field.message.includeSessionTitle': '正文包含会话标题',\n 'field.message.guiUrl': '打开链接地址',\n\n 'hint.system.icon': 'node-notifier 需要文件绝对路径',\n 'hint.feishu.secret': '留空不修改;重置可清除已存密钥',\n 'hint.message.titlePrefix': '如 [DSH]',\n\n 'action.save': '保存',\n 'action.saving': '保存中…',\n 'action.discard': '放弃修改',\n 'action.reset': '重置',\n 'badge.overridden': '已覆盖',\n 'status.readOnly': '设置文档当前为只读。',\n 'status.saveFailed': '保存失败,请重试。',\n 'status.invalidInput': '存在无效输入,请修正后再保存。',\n 'status.invalidField': '无效输入(数字/选项),请修正后再保存。',\n 'status.unavailable': '配置通道不可用:配置路由未就绪(host 插件未加载或 webServer 服务缺失)。',\n}\n\nexport const en = {\n nav: 'Messenger',\n 'section.description': 'Notifications for interaction, task completion and errors: system toast, browser notification, Feishu bot.',\n\n 'group.triggers': 'Triggers',\n 'group.system': 'System',\n 'group.browser': 'Browser',\n 'group.feishu': 'Third-party',\n 'group.message': 'Message',\n\n 'field.triggers.interaction': 'Notify when interaction is needed',\n 'field.triggers.completed': 'Notify when a task completes',\n 'field.triggers.error': 'Notify when a task errors',\n 'field.system.enabled': 'Enable system notifications',\n 'field.system.icon': 'Icon path',\n 'field.system.verbosity': 'Verbosity',\n 'field.browser.enabled': 'Enable browser notifications',\n 'field.browser.icon': 'Icon URL',\n 'field.browser.onlyWhenHidden': 'Notify only when the page is hidden',\n 'field.browser.verbosity': 'Verbosity',\n 'field.feishu.enabled': 'Feishu bot',\n 'field.feishu.webhookUrl': 'Webhook URL',\n 'field.feishu.secret': 'Signing secret',\n 'field.feishu.timeoutMs': 'Request timeout (ms)',\n 'field.feishu.verbosity': 'Verbosity',\n 'field.message.titlePrefix': 'Title prefix',\n 'field.message.includeSessionTitle': 'Include session title in the body',\n 'field.message.guiUrl': 'Open link URL',\n\n 'hint.system.icon': 'node-notifier requires an absolute file path',\n 'hint.feishu.secret': 'Leave blank to keep the stored secret; Reset clears it',\n 'hint.message.titlePrefix': 'e.g. [DSH]',\n\n 'action.save': 'Save',\n 'action.saving': 'Saving…',\n 'action.discard': 'Discard',\n 'action.reset': 'Reset',\n 'badge.overridden': 'Overridden',\n 'status.readOnly': 'The settings document is read-only.',\n 'status.saveFailed': 'Save failed, please retry.',\n 'status.invalidInput': 'There are invalid inputs, fix them before saving.',\n 'status.invalidField': 'Invalid input (number/option), fix it before saving.',\n 'status.unavailable': 'Config channel unavailable: the config route is not ready (host plugin not loaded or webServer service missing).',\n}\n","/**\n * dsh-messager —— DeepSeek Harness 通知插件(浏览器 client 端)。\n *\n * 功能:\n * 1. 浏览器通知:基于客户端会话摘要(ctx.sessions.list)投递,语义与 Web UI\n * 状态圆点一致(橙点=需要交互、绿点=任务完成)。\n * 2. 设置页分区「通知&信使」:注册到 settings.section(Agent预设下方,动态\n * order),经 host 配置路由(/dsh-messager/config,webServer 通道)读写\n * `messager` 命名空间 —— 不受 Web 设置白名单门控,发行版同样可用。\n *\n * 行为要点:\n * - 配置与 host 端同源(settings 命名空间 `messager`,document-updated 失效重拉);\n * - `onlyWhenHidden`(默认 true):页面可见时不弹,避免看着界面还被打扰;\n * - tag 去重 + localStorage 跨标签页冷却,多开标签不重复弹;\n * - 点击通知聚焦窗口;权限未授予时在插件加载时请求一次。\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-client-runtime/client'\nimport type { SessionListState } from '@deepseek-ai/dsh-client-runtime/client'\n// 类型合并:ctx.locale(dsh-client-locale)与 settings.section 槽位声明(ui-settings)\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { Verbosity } from '../config.js'\nimport type { Config } from '../config.js'\nimport { ClientConfig, type ClientConfigHandle } from './config.js'\nimport { diffSessionSummaries, type ClientNotice } from './diff.js'\nimport { CARD_FIELDS, MessagerCardController } from './card-controller.js'\nimport { createFetchScope, type ConfigFetcher } from './fetch-scope.js'\nimport { MessagerSection } from './section.jsx'\nimport { zh, en } from './locales.js'\nimport { CONFIG_PATH, type ConfigView, type ConfigWriteBody } from '../config-shared.js'\n\nexport const name = 'dsh-messager'\n\n/** locale 字典命名空间(与 section 的 locale 声明一致)。 */\nexport const LOCALE_NS = 'dsh-messager'\n\n/** 依赖的客户端服务:会话列表、远程事件(document-updated)、槽位、locale。 */\nexport const inject = ['sessions', 'remote', 'slots', 'locale']\n\n/** localStorage 跨标签页去重键前缀。 */\nconst STORAGE_PREFIX = 'dsh-messager:notified:'\n\n/** 浏览器通知投递器。 */\nclass BrowserNotifier {\n /** `${kind}:${sessionId}` → 上次投递时间戳(内存冷却)。 */\n private readonly cooldowns = new Map<string, number>()\n\n constructor(private readonly config: ClientConfigHandle) {}\n\n dispose(): void {\n this.cooldowns.clear()\n }\n\n /** 列表快照变化 → 通知。 */\n onListChange(previous: SessionListState, next: SessionListState): void {\n const config = this.config.get()\n if (!config.browser.enabled) return\n if (typeof Notification === 'undefined') return\n if (Notification.permission !== 'granted') return\n if (config.browser.onlyWhenHidden && document.visibilityState !== 'hidden') return\n\n const notices = diffSessionSummaries(previous.byId, next.byId, next.current)\n for (const notice of notices) {\n if (!this.allow(notice, config)) continue\n this.show(notice, config)\n }\n }\n\n /** 冷却 + 跨标签页去重。 */\n private allow(notice: ClientNotice, config: Config): boolean {\n const now = Date.now()\n const key = `${notice.kind}:${notice.sessionId}`\n const cooldownMs = config.dedup.interactionCooldownMs\n const last = this.cooldowns.get(key)\n if (last !== undefined && now - last < cooldownMs) return false\n try {\n const storageKey = STORAGE_PREFIX + key\n const raw = window.localStorage.getItem(storageKey)\n if (raw !== null && now - Number(raw) < cooldownMs) return false\n window.localStorage.setItem(storageKey, String(now))\n } catch {\n // localStorage 不可用(隐私模式等)时仅靠内存冷却\n }\n this.cooldowns.set(key, now)\n return true\n }\n\n private show(notice: ClientNotice, config: Config): void {\n const verbosity = config.browser.verbosity\n const notification = new Notification(this.titleOf(notice, config), {\n ...(verbosity === 'minimal' ? {} : { body: this.bodyOf(notice, config, verbosity) }),\n ...(config.browser.icon === undefined ? {} : { icon: config.browser.icon }),\n // tag 同键通知自动替换,避免同一会话反复堆叠\n tag: `dsh-messager:${notice.kind}:${notice.sessionId}`,\n })\n notification.onclick = () => {\n window.focus()\n notification.close()\n }\n }\n\n private titleOf(notice: ClientNotice, config: Config): string {\n let base: string\n if (notice.kind === 'interaction') {\n base = notice.interaction === 'approval'\n ? '需要交互:等待审批'\n : notice.interaction === 'plan-review'\n ? '需要交互:计划待审'\n : '需要交互:等待回答'\n } else {\n base = '任务完成'\n }\n const prefix = config.message.titlePrefix\n return prefix === undefined || prefix === '' ? base : `${prefix} ${base}`\n }\n\n private bodyOf(notice: ClientNotice, config: Config, verbosity: Verbosity): string {\n const lines: string[] = []\n if (verbosity === 'minimal') return ''\n if (config.message.includeSessionTitle && notice.title !== undefined) {\n lines.push(`会话:${notice.title}`)\n }\n if (verbosity === 'detailed') {\n lines.push(`打开:${config.message.guiUrl}`)\n }\n return lines.join('\\n')\n }\n}\n\nexport function apply(ctx: Context): void {\n const config = new ClientConfig()\n void config.refresh()\n\n // 配置路由访问器(同源 fetch;路由由 host 半挂载,见 src/config-route.ts)\n const fetcher: ConfigFetcher = {\n get: async (): Promise<ConfigView> => {\n const response = await fetch(CONFIG_PATH, { headers: { accept: 'application/json' } })\n if (!response.ok) throw new Error(`config route responded ${response.status}`)\n return (await response.json()) as ConfigView\n },\n write: async (body: ConfigWriteBody) => {\n try {\n const response = await fetch(CONFIG_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n const result = (await response.json()) as { ok: boolean; error?: string }\n return { ok: response.ok && result.ok === true, error: result.error }\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : String(error) }\n }\n },\n }\n const fetchScope = createFetchScope(fetcher)\n void fetchScope.refresh()\n\n // 设置变更(host/设置页/本分区保存)→ 重拉有效配置与表单视图\n const offRemote = ctx.remote.$on('settings/document-updated', () => {\n void config.refresh()\n void fetchScope.refresh()\n })\n ctx.effect(() => () => offRemote?.(), 'dsh-messager: settings invalidation')\n\n const notifier = new BrowserNotifier(config)\n ctx.effect(() => () => notifier.dispose(), 'dsh-messager: browser notifier')\n\n // 会话列表快照 diff\n let previous = ctx.sessions.list.getSnapshot()\n const offList = ctx.sessions.list.subscribe(() => {\n const next = ctx.sessions.list.getSnapshot()\n notifier.onListChange(previous, next)\n previous = next\n })\n ctx.effect(() => () => offList(), 'dsh-messager: sessions subscription')\n\n // 设置页分区「通知&信使」:注册到 settings.section。\n // 数据经 webServer 配置路由读写(不受白名单门控),控制器与表单复用\n // MessagerCardController / MessagerSettingsForm;文案走 locale 字典。\n const controller = new MessagerCardController(fetchScope.scope, CARD_FIELDS)\n ctx.effect(() => ctx.locale.register(LOCALE_NS, { zh, en }), 'dsh-messager: locale dictionaries')\n const t = ctx.locale.bind(LOCALE_NS)\n ctx.slots.inject('settings.section', function* () {\n // 动态 order:紧随 agent-presets(Agent预设);不存在则排在当时已注册\n // 分区之后;全空时用大数兜底 —— 语义即「自然向后排序」,不写死数值。\n const existing = ctx.slots.entries('settings.section')\n const agentPresets = existing.find(entry => entry.options.id === 'agent-presets')\n const maxOrder = existing.reduce((max, entry) => Math.max(max, entry.options.order ?? 0), 0)\n const order = agentPresets !== undefined\n ? (agentPresets.options.order ?? 0) + 1\n : existing.length > 0\n ? maxOrder + 1\n : 1000\n const face = controller.inject()\n yield ctx.slots.register({\n name: 'settings.section',\n id: 'dsh-messager',\n order,\n label: () => t('nav'),\n locale: LOCALE_NS,\n inject: () => ({ ...face, t }),\n }, MessagerSection)\n })\n\n // 权限:default 状态时请求一次(部分浏览器需用户手势,README 有说明)\n if (typeof Notification !== 'undefined' && Notification.permission === 'default') {\n void Notification.requestPermission()\n }\n\n ctx.logger.info('[dsh-messager] client loaded')\n}\n"],"x_google_ignoreList":[0,1],"mappings":";;;;;;;;;EAIA,SAAS,WAAW,OAAO;GAC1B,OAAO,UAAU,QAAQ,UAAU,KAAK;EACzC;;EAMA,SAAS,cAAc,MAAM;GAC5B,OAAO,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI;EAC/D;;EAEA,SAAS,WAAW,QAAQ,QAAQ;GACnC,OAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,WAAW,OAAO,KAAK,KAAK,CAAC,CAAC;EAC9F;;EAEA,SAAS,UAAU,QAAQ,WAAW;GACrC,OAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,UAAU,OAAO,GAAG,CAAC,CAAC,CAAC;EACrG;;EAEA,SAAS,KAAK,QAAQ,MAAM,QAAQ;GACnC,IAAI,CAAC,MAAM,OAAO,EAAE,GAAG,OAAO;GAC9B,MAAM,SAAS,CAAC;GAChB,KAAK,MAAM,OAAO,MAAM,IAAI,UAAU,OAAO,SAAS,KAAK,GAAG,OAAO,OAAO,OAAO;GACnF,OAAO;EACR;;EAqDA,SAAS,GAAG,MAAM,OAAO;GACxB,IAAI,UAAU,WAAW,GAAG,QAAQ,UAAU,GAAG,MAAM,KAAK;GAC5D,OAAO,QAAQ,cAAc,iBAAiB,WAAW,SAAS,OAAO,UAAU,SAAS,KAAK,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE,MAAM;EAC1H;EACA,SAAS,kBAAkB,OAAO;GACjC,OAAO,GAAG,eAAe,KAAK,KAAK,GAAG,qBAAqB,KAAK;EACjE;EACA,SAAS,oBAAoB,OAAO;GACnC,OAAO,kBAAkB,KAAK,KAAK,YAAY,OAAO,KAAK;EAC5D;;EAEA,IAAI;EACH,CAAA,SAAS,QAAQ;GACjB,OAAO,KAAK;GACZ,OAAO,WAAW;GAClB,SAAS,WAAW,QAAQ;IAC3B,IAAI,YAAY,OAAO,MAAM,GAAG,OAAO,OAAO,OAAO,MAAM,OAAO,YAAY,OAAO,aAAa,OAAO,UAAU;SAC9G,OAAO;GACb;GACA,OAAO,aAAa;GACpB,SAAS,SAAS,QAAQ;IACzB,SAAS,WAAW,MAAM;IAC1B,IAAI,OAAO,WAAW,aAAa,OAAO,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,QAAQ;IAC/E,IAAI,SAAS;IACb,MAAM,QAAQ,IAAI,WAAW,MAAM;IACnC,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,YAAY,KAAK,UAAU,OAAO,aAAa,MAAM,EAAE;IACjF,OAAO,KAAK,MAAM;GACnB;GACA,OAAO,WAAW;GAClB,SAAS,WAAW,QAAQ;IAC3B,IAAI,OAAO,WAAW,aAAa,OAAO,WAAW,OAAO,KAAK,QAAQ,QAAQ,CAAC;IAClF,OAAO,WAAW,KAAK,KAAK,MAAM,IAAI,MAAM,EAAE,WAAW,CAAC,CAAC;GAC5D;GACA,OAAO,aAAa;GACpB,SAAS,MAAM,QAAQ;IACtB,SAAS,WAAW,MAAM;IAC1B,IAAI,OAAO,WAAW,aAAa,OAAO,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,KAAK;IAC5E,OAAO,MAAM,KAAK,IAAI,WAAW,MAAM,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;GAChG;GACA,OAAO,QAAQ;GACf,SAAS,QAAQ,QAAQ;IACxB,IAAI,OAAO,WAAW,aAAa,OAAO,WAAW,OAAO,KAAK,QAAQ,KAAK,CAAC;IAC/E,MAAM,MAAM,OAAO,SAAS,MAAM,IAAI,SAAS,OAAO,MAAM,GAAG,OAAO,SAAS,CAAC;IAChF,MAAM,SAAS,CAAC;IAChB,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,GAAG,OAAO,KAAK,SAAS,GAAG,IAAI,KAAK,IAAI,IAAI,MAAM,EAAE,CAAC;IAC1F,OAAO,WAAW,KAAK,MAAM,CAAC,CAAC;GAChC;GACA,OAAO,UAAU;EAClB,EAAA,CAAG,WAAW,SAAS,CAAC,EAAE;EAEE,OAAO;EAEP,OAAO;EAEV,OAAO;EAEP,OAAO;;EAEhC,SAAS,MAAM,QAAQ,uBAAuB,IAAI,IAAI,GAAG;GACxD,IAAI,CAAC,UAAU,OAAO,WAAW,UAAU,OAAO;GAClD,IAAI,GAAG,QAAQ,MAAM,GAAG,OAAO,IAAI,KAAK,OAAO,QAAQ,CAAC;GACxD,IAAI,GAAG,UAAU,MAAM,GAAG,OAAO,IAAI,OAAO,OAAO,QAAQ,OAAO,KAAK;GACvE,IAAI,kBAAkB,MAAM,GAAG,OAAO,OAAO,MAAM,CAAC;GACpD,IAAI,YAAY,OAAO,MAAM,GAAG,OAAO,OAAO,OAAO,MAAM,OAAO,YAAY,OAAO,aAAa,OAAO,UAAU;GACnH,MAAM,SAAS,KAAK,IAAI,MAAM;GAC9B,IAAI,QAAQ,OAAO;GACnB,IAAI,MAAM,QAAQ,MAAM,GAAG;IAC1B,MAAM,SAAS,CAAC;IAChB,KAAK,IAAI,QAAQ,MAAM;IACvB,OAAO,SAAS,OAAO,UAAU;KAChC,OAAO,SAAS,QAAQ,MAAM,OAAO,MAAM,CAAC,OAAO,IAAI,CAAC;IACzD,CAAC;IACD,OAAO;GACR;GACA,MAAM,SAAS,OAAO,OAAO,OAAO,eAAe,MAAM,CAAC;GAC1D,KAAK,IAAI,QAAQ,MAAM;GACvB,KAAK,MAAM,OAAO,QAAQ,QAAQ,MAAM,GAAG;IAC1C,MAAM,aAAa,EAAE,GAAG,QAAQ,yBAAyB,QAAQ,GAAG,EAAE;IACtE,IAAI,WAAW,YAAY,WAAW,QAAQ,QAAQ,MAAM,OAAO,MAAM,CAAC,WAAW,OAAO,IAAI,CAAC;IACjG,QAAQ,eAAe,QAAQ,KAAK,UAAU;GAC/C;GACA,OAAO;EACR;;EAEA,SAAS,UAAU,GAAG,GAAG,QAAQ;GAChC,IAAI,MAAM,GAAG,OAAO;GACpB,IAAI,CAAC,UAAU,WAAW,CAAC,KAAK,WAAW,CAAC,GAAG,OAAO;GACtD,IAAI,OAAO,MAAM,OAAO,GAAG,OAAO;GAClC,IAAI,OAAO,MAAM,UAAU,OAAO;GAClC,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO;GACrB,SAAS,MAAM,MAAM,MAAM;IAC1B,OAAO,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,QAAQ,KAAK,CAAC,IAAI,QAAQ,KAAK;GACxE;GACA,OAAO,MAAM,MAAM,UAAU,GAAG,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,MAAM,UAAU,UAAU,MAAM,EAAE,MAAM,CAAC,CAAC,KAAK,MAAM,GAAG,MAAM,IAAI,GAAG,MAAM,EAAE,QAAQ,MAAM,EAAE,QAAQ,CAAC,KAAK,MAAM,GAAG,QAAQ,IAAI,GAAG,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,KAAK,MAAM,oBAAoB,GAAG,MAAM;IACpS,IAAI,EAAE,eAAe,EAAE,YAAY,OAAO;IAC1C,MAAM,QAAQ,IAAI,WAAW,CAAC;IAC9B,MAAM,QAAQ,IAAI,WAAW,CAAC;IAC9B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,OAAO,MAAM,IAAI,OAAO;IACzE,OAAO;GACR,CAAC,KAAK,OAAO,KAAK;IACjB,GAAG;IACH,GAAG;GACJ,CAAC,CAAC,CAAC,OAAO,QAAQ,UAAU,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;EACpD;;EAqEA,IAAI;EACH,CAAA,SAAS,MAAM;GACf,KAAK,cAAc;GACnB,KAAK,SAAS;GACd,KAAK,SAAS,KAAK,SAAS;GAC5B,KAAK,OAAO,KAAK,SAAS;GAC1B,KAAK,MAAM,KAAK,OAAO;GACvB,KAAK,OAAO,KAAK,MAAM;GACvB,IAAI,kCAAkC,IAAI,KAAK,EAAA,CAAG,kBAAkB;GACpE,SAAS,kBAAkB,QAAQ;IAClC,iBAAiB;GAClB;GACA,KAAK,oBAAoB;GACzB,SAAS,oBAAoB;IAC5B,OAAO;GACR;GACA,KAAK,oBAAoB;GACzB,SAAS,cAAc,uBAAuB,IAAI,KAAK,GAAG,QAAQ;IACjE,IAAI,OAAO,SAAS,UAAU,OAAO,IAAI,KAAK,IAAI;IAClD,IAAI,WAAW,KAAK,GAAG,SAAS;IAChC,OAAO,KAAK,OAAO,KAAK,QAAQ,IAAI,KAAK,SAAS,UAAU,IAAI;GACjE;GACA,KAAK,gBAAgB;GACrB,SAAS,eAAe,OAAO,QAAQ;IACtC,MAAM,OAAO,IAAI,KAAK,QAAQ,KAAK,GAAG;IACtC,IAAI,WAAW,KAAK,GAAG,SAAS;IAChC,OAAO,IAAI,KAAK,CAAC,OAAO,SAAS,KAAK,MAAM;GAC7C;GACA,KAAK,iBAAiB;GACtB,MAAM,UAAU,gBAAgB;GAChC,MAAM,aAAa,IAAI,OAAO,IAAI;IACjC;IACA;IACA;IACA;IACA;GACD,CAAC,CAAC,KAAK,SAAS,IAAI,UAAU,KAAK,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE;GACnD,SAAS,UAAU,QAAQ;IAC1B,MAAM,UAAU,WAAW,KAAK,MAAM;IACtC,IAAI,CAAC,SAAS,OAAO;IACrB,QAAQ,WAAW,QAAQ,EAAE,IAAI,KAAK,QAAQ,MAAM,WAAW,QAAQ,EAAE,IAAI,KAAK,OAAO,MAAM,WAAW,QAAQ,EAAE,IAAI,KAAK,QAAQ,MAAM,WAAW,QAAQ,EAAE,IAAI,KAAK,UAAU,MAAM,WAAW,QAAQ,EAAE,IAAI,KAAK,UAAU;GAClO;GACA,KAAK,YAAY;GACjB,SAAS,UAAU,MAAM;IACxB,MAAM,SAAS,UAAU,IAAI;IAC7B,IAAI,QAAQ,OAAO,KAAK,IAAI,IAAI;SAC3B,IAAI,2BAA2B,KAAK,IAAI,GAAG,OAAO,oBAAoB,IAAI,KAAK,EAAA,CAAG,mBAAmB,EAAE,GAAG;SAC1G,IAAI,2CAA2C,KAAK,IAAI,GAAG,OAAO,oBAAoB,IAAI,KAAK,EAAA,CAAG,YAAY,EAAE,GAAG;IACxH,OAAO,OAAO,IAAI,KAAK,IAAI,oBAAoB,IAAI,KAAK;GACzD;GACA,KAAK,YAAY;GACjB,SAAS,OAAO,IAAI;IACnB,MAAM,MAAM,KAAK,IAAI,EAAE;IACvB,IAAI,OAAO,KAAK,MAAM,KAAK,OAAO,GAAG,OAAO,KAAK,MAAM,KAAK,KAAK,GAAG,IAAI;SACnE,IAAI,OAAO,KAAK,OAAO,KAAK,SAAS,GAAG,OAAO,KAAK,MAAM,KAAK,KAAK,IAAI,IAAI;SAC5E,IAAI,OAAO,KAAK,SAAS,KAAK,SAAS,GAAG,OAAO,KAAK,MAAM,KAAK,KAAK,MAAM,IAAI;SAChF,IAAI,OAAO,KAAK,QAAQ,OAAO,KAAK,MAAM,KAAK,KAAK,MAAM,IAAI;IACnE,OAAO,KAAK;GACb;GACA,KAAK,SAAS;GACd,SAAS,SAAS,QAAQ,SAAS,GAAG;IACrC,OAAO,OAAO,SAAS,CAAC,CAAC,SAAS,QAAQ,GAAG;GAC9C;GACA,KAAK,WAAW;GAChB,SAAS,SAAS,UAAU,uBAAuB,IAAI,KAAK,GAAG;IAC9D,OAAO,SAAS,QAAQ,QAAQ,KAAK,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,MAAM,KAAK,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,OAAO,SAAS,KAAK,gBAAgB,GAAG,CAAC,CAAC;GAC5X;GACA,KAAK,WAAW;EACjB,EAAA,CAAG,SAAS,OAAO,CAAC,EAAE;;;EChUtB,MAAM,UAAU,OAAO,IAAI,aAAa;EACxC,MAAM,mBAAmB,OAAO,IAAI,iBAAiB;EACrD,WAAW,0BAA0B;EACrC,WAAW,uBAAuB,KAAK;EACvC,IAAI,kBAAkB,cAAc,UAAU;GAC7C;GACA,OAAO;GACP,YAAY,SAAS,SAAS;IAC7B,IAAI,SAAS;IACb,KAAK,MAAM,WAAW,QAAQ,QAAQ,CAAC,GAAG,IAAI,OAAO,YAAY,UAAU,UAAU,MAAM;SACtF,IAAI,OAAO,YAAY,UAAU,UAAU,MAAM,UAAU;SAC3D,IAAI,OAAO,YAAY,UAAU,UAAU,WAAW,QAAQ,SAAS,EAAE;IAC9E,IAAI,OAAO,WAAW,GAAG,GAAG,SAAS,OAAO,MAAM,CAAC;IACnD,OAAO,WAAW,MAAM,KAAK,GAAG,OAAO,MAAM,OAAO;IACpD,KAAK,UAAU;GAChB;GACA,OAAO,GAAG,OAAO;IAChB,OAAO,CAAC,CAAC,QAAQ;GAClB;EACD;EACA,OAAO,eAAe,gBAAgB,WAAW,kBAAkB,EAAE,OAAO,KAAK,CAAC;EAClF,MAAM,SAAS,SAAS,SAAS;GAChC,MAAM,SAAS,SAAS,MAAM,UAAU,CAAC,GAAG;IAC3C,OAAO,OAAO,QAAQ,MAAM,QAAQ,OAAO,CAAC,CAAC;GAC9C;GACA,IAAI,QAAQ,MAAM;IACjB,MAAM,OAAOA,UAAS,QAAQ,OAAO,YAAY,IAAI,OAAO,OAAO,CAAC;IACpE,MAAM,UAAU,QAAQ,KAAK;IAC7B,KAAK,MAAM,OAAO,MAAM;KACvB,MAAM,UAAU,KAAK;KACrB,QAAQ,OAAO,OAAO,QAAQ,IAAI;KAClC,QAAQ,QAAQ,OAAO,QAAQ,KAAK;KACpC,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,KAAK,IAAI,MAAM;KACtD,QAAQ,OAAO,QAAQ,QAAQA,UAAS,QAAQ,MAAM,MAAM;IAC7D;IACA,OAAO,KAAK,QAAQ;GACrB;GACA,OAAO,OAAO,QAAQ,OAAO;GAC7B,IAAI,OAAO,OAAO,aAAa,UAAU,IAAI;IAC5C,OAAO,WAAW,IAAI,SAAS,YAAY,OAAO,QAAQ,CAAC,CAAC;GAC7D,QAAQ,CAAC;GACT,OAAO,eAAe,QAAQ,OAAO,EAAE,OAAO,WAAW,wBAAwB,CAAC;GAClF,OAAO,eAAe,QAAQ,OAAO,SAAS;GAC9C,OAAO,SAAS,CAAC;GACjB,OAAO,WAAW,OAAO,SAAS,KAAK,MAAM;GAC7C,OAAO;EACR;EACA,OAAO,YAAY,OAAO,OAAO,SAAS,SAAS;EACnD,OAAO,UAAU,WAAW;EAC5B,OAAO,eAAe,OAAO,WAAW,aAAa,EAAE,MAAM;GAC5D,OAAO;IACN,SAAS;IACT,QAAQ;IACR,WAAW,UAAU;KACpB,IAAI;MACH,OAAO,EAAE,OAAO,OAAO,QAAQ,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG;KACpD,SAAS,OAAO;MACf,IAAI,gBAAgB,GAAG,KAAK,GAAG,OAAO,EAAE,QAAQ,CAAC;OAChD,SAAS,MAAM;OACf,MAAM,MAAM,QAAQ;MACrB,CAAC,EAAE;MACH,MAAM;KACP;IACD;GACD;EACD,EAAE,CAAC;EACH,OAAO,kBAAkB;EACzB,OAAO,UAAU,SAAS,SAAS,SAAS;GAC3C,IAAI,WAAW,sBAAsB;IACpC,WAAW,qBAAqB,KAAK,SAAS,KAAK,MAAM,KAAK,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC;IACpF,OAAO,KAAK;GACb;GACA,WAAW,uBAAuB,GAAG,KAAK,MAAM,EAAE,GAAG,KAAK,EAAE;GAC5D,WAAW,qBAAqB,KAAK,OAAO,KAAK,MAAM,KAAK,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC;GAClF,MAAM,SAAS;IACd,KAAK,KAAK;IACV,MAAM,WAAW;GAClB;GACA,WAAW,uBAAuB,KAAK;GACvC,OAAO;EACR;EACA,OAAO,UAAU,MAAM,SAAS,IAAI,KAAK,OAAO;GAC/C,KAAK,KAAK,OAAO;GACjB,OAAO;EACR;EACA,OAAO,UAAU,OAAO,SAAS,KAAK,OAAO;GAC5C,KAAK,KAAK,KAAK,KAAK;GACpB,OAAO;EACR;EACA,SAAS,UAAU,UAAU,UAAU;GACtC,MAAM,SAAS,OAAO,aAAa,WAAW,EAAE,IAAI,SAAS,IAAI,EAAE,GAAG,SAAS;GAC/E,KAAK,MAAM,UAAU,UAAU;IAC9B,MAAM,QAAQ,SAAS;IACvB,IAAI,OAAO,gBAAgB,OAAO,OAAO,OAAO,UAAU,MAAM,gBAAgB,MAAM;SACjF,IAAI,OAAO,UAAU,UAAU,OAAO,UAAU;GACtD;GACA,OAAO;EACR;EACA,SAAS,SAAS,OAAO;GACxB,OAAO,OAAO,UAAU,OAAO;EAChC;EACA,SAAS,YAAY,MAAM;GAC1B,OAAO,WAAW,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,WAAW,GAAG,CAAC;EAC5D;EACA,OAAO,UAAU,OAAO,SAAS,KAAK,UAAU;GAC/C,MAAM,SAAS,OAAO,IAAI;GAC1B,MAAM,OAAO,UAAU,OAAO,KAAK,aAAa,QAAQ;GACxD,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,QAAQ,OAAO,KAAK,cAAc;GACxD,IAAI,OAAO,MAAM,OAAO,OAAOA,UAAS,OAAO,OAAO,OAAO,QAAQ;IACpE,OAAO,MAAM,KAAKA,UAAS,WAAW,SAAS,SAAS,IAAI,CAAC,GAAG,QAAQ,OAAO,IAAI,CAAC;GACrF,CAAC;GACD,IAAI,OAAO,MAAM,OAAO,OAAO,OAAO,KAAK,KAAK,OAAO,UAAU;IAChE,OAAO,MAAM,KAAKA,UAAS,WAAW,OAAO,CAAC,MAAM;KACnD,IAAI,MAAM,QAAQ,SAAS,IAAI,CAAC,GAAG,OAAO,SAAS,IAAI,CAAC,CAAC;KACzD,IAAI,MAAM,QAAQ,IAAI,GAAG,OAAO,KAAK;KACrC,OAAO,YAAY,IAAI;IACxB,CAAC,CAAC;GACH,CAAC;GACD,IAAI,OAAO,OAAO,OAAO,QAAQ,OAAO,MAAM,KAAKA,UAAS,WAAW,SAAS;IAC/E,IAAI,SAAS,IAAI,GAAG,OAAO,SAAS,IAAI;IACxC,OAAO,YAAY,IAAI;GACxB,CAAC,CAAC;GACF,IAAI,OAAO,MAAM,OAAO,OAAO,OAAO,KAAK,KAAKA,UAAS,WAAW,SAAS,MAAM,IAAI,CAAC;GACxF,OAAO;EACR;EACA,OAAO,UAAU,QAAQ,SAAS,MAAM,KAAK,OAAO;GACnD,MAAM,SAAS,OAAO,IAAI;GAC1B,OAAO,OAAO;IACb,GAAG,OAAO;KACT,MAAM;GACR;GACA,OAAO;EACR;EACA,KAAK,MAAM,OAAO;GACjB;GACA;GACA;GACA;GACA;EACD,GAAG,OAAO,OAAO,OAAO,WAAW,EAAE,CAAC,KAAK,QAAQ,MAAM;GACxD,MAAM,SAAS,OAAO,IAAI;GAC1B,OAAO,OAAO;IACb,GAAG,OAAO;KACT,MAAM;GACR;GACA,OAAO;EACR,EAAE,CAAC;EACH,OAAO,UAAU,aAAa,SAAS,aAAa;GACnD,MAAM,SAAS,OAAO,IAAI;GAC1B,OAAO,KAAK,WAAW,CAAC;GACxB,OAAO,KAAK,OAAO,KAAK;IACvB,MAAM;IACN,MAAM;GACP,CAAC;GACD,OAAO;EACR;EACA,OAAO,UAAU,eAAe,SAAS,eAAe;GACvD,MAAM,SAAS,OAAO,IAAI;GAC1B,OAAO,KAAK,WAAW,CAAC;GACxB,OAAO,KAAK,OAAO,KAAK;IACvB,MAAM;IACN,MAAM;GACP,CAAC;GACD,OAAO;EACR;EACA,OAAO,UAAU,UAAU,SAAS,QAAQ,QAAQ;GACnD,MAAM,SAAS,OAAO,IAAI;GAC1B,MAAM,UAAU,KAAK,QAAQ,CAAC,UAAU,OAAO,CAAC;GAChD,OAAO,OAAO;IACb,GAAG,OAAO;IACV;GACD;GACA,OAAO;EACR;EACA,OAAO,UAAU,WAAW,SAAS,SAAS,OAAO;GACpD,IAAI,UAAU,OAAO,KAAK,KAAK,SAAS,KAAK,SAAS,MAAM,GAAG,OAAO;GACtE,IAAI,WAAW,KAAK,GAAG,OAAO;GAC9B,IAAI,KAAK,SAAS,YAAY,KAAK,SAAS,QAAQ;IACnD,MAAM,SAAS,CAAC;IAChB,KAAK,MAAM,OAAO,OAAO;KACxB,MAAM,QAAQ,KAAK,SAAS,WAAW,KAAK,KAAK,OAAO,KAAK,MAAA,EAAQ,SAAS,MAAM,IAAI;KACxF,IAAI,KAAK,SAAS,UAAU,CAAC,WAAW,IAAI,GAAG,OAAO,OAAO;IAC9D;IACA,IAAI,UAAU,QAAQ,KAAK,KAAK,SAAS,KAAK,SAAS,MAAM,GAAG,OAAO;IACvE,OAAO;GACR,OAAO,IAAI,KAAK,SAAS,WAAW,KAAK,SAAS,SAAS;IAC1D,MAAM,SAAS,CAAC;IAChB,MAAM,SAAS,OAAO,UAAU;KAC/B,MAAM,SAAS,KAAK,SAAS,UAAU,KAAK,QAAQ,KAAK,KAAK;KAC9D,MAAM,OAAO,SAAS,OAAO,SAAS,KAAK,IAAI;KAC/C,OAAO,KAAK,IAAI;IACjB,CAAC;IACD,OAAO;GACR,OAAO,IAAI,KAAK,SAAS,aAAa;IACrC,MAAM,SAAS,CAAC;IAChB,KAAK,MAAM,QAAQ,KAAK,MAAM,OAAO,OAAO,QAAQ,KAAK,SAAS,KAAK,CAAC;IACxE,OAAO;GACR,OAAO,IAAI,KAAK,SAAS,SAAS,KAAK,MAAM,UAAU,KAAK,MAAM,IAAI;IACrE,OAAO,QAAQ,OAAO,QAAQ,CAAC,CAAC;IAChC,OAAO,OAAO,SAAS,KAAK;GAC7B,QAAQ,CAAC;GACT,OAAO;EACR;EACA,OAAO,UAAU,WAAW,SAAS,SAAS,QAAQ;GACrD,OAAO,WAAW,KAAK,KAAK,GAAG,MAAM,MAAM,KAAK,UAAU,KAAK,KAAK;EACrE;EACA,OAAO,UAAU,OAAO,SAAS,KAAK,MAAM,OAAO;GAClD,MAAM,SAAS,OAAO,IAAI;GAC1B,OAAO,OAAO;IACb,GAAG,OAAO;IACV;IACA;GACD;GACA,OAAO;EACR;EACA,KAAK,MAAM,OAAO;GACjB;GACA;GACA;GACA;GACA;GACA;GACA;EACD,GAAG,OAAO,OAAO,OAAO,WAAW,EAAE,CAAC,KAAK,OAAO;GACjD,MAAM,SAAS,OAAO,IAAI;GAC1B,OAAO,OAAO;IACb,GAAG,OAAO;KACT,MAAM;GACR;GACA,OAAO;EACR,EAAE,CAAC;EACH,MAAM,YAAY,CAAC;EACnB,OAAO,SAAS,SAAS,OAAO,MAAM,SAAS;GAC9C,UAAU,QAAQ;EACnB;EACA,OAAO,UAAU,SAAS,QAAQ,MAAM,QAAQ,UAAU,CAAC,GAAG,SAAS,OAAO;GAC7E,IAAI,CAAC,QAAQ,OAAO,CAAC,IAAI;GACzB,IAAI,QAAQ,SAAS,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI;GAChD,IAAI,WAAW,IAAI,KAAK,OAAO,SAAS,QAAQ;IAC/C,IAAI,OAAO,KAAK,UAAU,MAAM,IAAI,gBAAgB,0BAA0B,OAAO;IACrF,IAAI,UAAU;IACd,IAAI,WAAW,OAAO,KAAK;IAC3B,OAAO,SAAS,SAAS,eAAe,WAAW,QAAQ,GAAG;KAC7D,UAAU,QAAQ,KAAK;KACvB,WAAW,SAAS,KAAK;IAC1B;IACA,IAAI,WAAW,QAAQ,GAAG,OAAO,CAAC,IAAI;IACtC,OAAO,MAAM,QAAQ;GACtB;GACA,MAAM,WAAW,UAAU,OAAO;GAClC,IAAI,CAAC,UAAU,MAAM,IAAI,gBAAgB,qBAAqB,OAAO,KAAK,IAAI,OAAO;GACrF,IAAI;IACH,OAAO,SAAS,MAAM,QAAQ,SAAS,MAAM;GAC9C,SAAS,OAAO;IACf,IAAI,CAAC,OAAO,KAAK,OAAO,MAAM;IAC9B,OAAO,CAAC,OAAO,KAAK,OAAO;GAC5B;EACD;EACA,OAAO,OAAO,SAAS,KAAK,QAAQ;GACnC,IAAI,WAAW,MAAM,GAAG,OAAO,OAAO,IAAI;QACrC,IAAI;IACR;IACA;IACA;GACD,CAAC,CAAC,SAAS,OAAO,MAAM,GAAG,OAAO,OAAO,MAAM,MAAM,CAAC,CAAC,SAAS;QAC3D,IAAI,OAAO,UAAU,OAAO;QAC5B,IAAI,OAAO,WAAW,YAAY,QAAQ,QAAR;IACtC,KAAK,QAAQ,OAAO,OAAO,OAAO,CAAC,CAAC,SAAS;IAC7C,KAAK,QAAQ,OAAO,OAAO,OAAO,CAAC,CAAC,SAAS;IAC7C,KAAK,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC,SAAS;IAC/C,KAAK,UAAU,OAAO,OAAO,SAAS,CAAC,CAAC,SAAS;IACjD,SAAS,OAAO,OAAO,GAAG,MAAM,CAAC,CAAC,SAAS;GAC5C;QACK,MAAM,IAAI,UAAU,4BAA4B,QAAQ;EAC9D;EACA,OAAO,OAAO,SAAS,KAAK,SAAS;GACpC,MAAM,eAAe;IACpB,IAAI,CAAC,OAAO,MAAM,UAAU;KAC3B,OAAO,QAAQ,OAAO,QAAQ;KAC9B,OAAO,MAAM,OAAO;MACnB,GAAG,OAAO;MACV,GAAG,OAAO,MAAM;KACjB;IACD;IACA,OAAO,OAAO,MAAM,OAAO;GAC5B;GACA,MAAM,SAAS,IAAI,OAAO;IACzB,MAAM;IACN;IACA,OAAO,EAAE,OAAO;GACjB,CAAC;GACD,OAAO;EACR;EACA,OAAO,UAAU,SAAS,UAAU;GACnC,OAAO,OAAO,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;EACrC;EACA,OAAO,UAAU,SAAS,UAAU;GACnC,OAAO,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;EAC7D;EACA,OAAO,OAAO,SAAS,OAAO;GAC7B,OAAO,OAAO,MAAM,CAAC,OAAO,GAAG,IAAI,GAAG,OAAO,UAAU,OAAO,OAAO,CAAC,CAAC,KAAK,UAAU,IAAI,OAAO,YAAY;IAC5G,MAAM,OAAO,IAAI,KAAK,KAAK;IAC3B,IAAI,MAAM,CAAC,IAAI,GAAG,MAAM,IAAI,gBAAgB,iBAAiB,MAAM,IAAI,OAAO;IAC9E,OAAO;GACR,GAAG,IAAI,CAAC,CAAC;EACV;EACA,OAAO,SAAS,SAAS,OAAO,OAAO,IAAI;GAC1C,OAAO,OAAO,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,OAAO,UAAU,OAAO,OAAO,CAAC,CAAC,KAAK,UAAU,EAAE,KAAK,CAAC,IAAI,OAAO,YAAY;IACtH,IAAI;KACH,OAAO,IAAI,OAAO,OAAO,IAAI;IAC9B,SAAS,GAAG;KACX,MAAM,IAAI,gBAAgB,EAAE,SAAS,OAAO;IAC7C;GACD,GAAG,IAAI,CAAC,CAAC;EACV;EACA,OAAO,cAAc,SAAS,YAAY,UAAU;GACnD,OAAO,OAAO,MAAM;IACnB,OAAO,GAAG,WAAW;IACrB,OAAO,GAAG,iBAAiB;IAC3B,OAAO,UAAU,OAAO,IAAI,IAAI,OAAO,YAAY;KAClD,IAAI,OAAO,SAAS,KAAK,GAAG,OAAO,OAAO,WAAW,KAAK;KAC1D,MAAM,IAAI,gBAAgB,sCAAsC,SAAS,OAAO;IACjF,GAAG,IAAI;IACP,GAAG,WAAW,CAAC,OAAO,UAAU,OAAO,OAAO,IAAI,OAAO,YAAY;KACpE,IAAI;MACH,OAAO,aAAa,WAAW,OAAO,WAAW,KAAK,IAAI,OAAO,QAAQ,KAAK;KAC/E,SAAS,GAAG;MACX,MAAM,IAAI,gBAAgB,EAAE,SAAS,OAAO;KAC7C;IACD,GAAG,IAAI,CAAC,IAAI,CAAC;GACd,CAAC;EACF;EACA,OAAO,OAAO,SAAS,MAAM,QAAQ,SAAS,WAAW;GACxD,IAAI,CAAC,OAAO,MAAM,UAAU;IAC3B,OAAO,QAAQ,OAAO,QAAQ;IAC9B,OAAO,MAAM,OAAO;KACnB,GAAG,OAAO;KACV,GAAG,OAAO,MAAM;IACjB;GACD;GACA,OAAO,OAAO,QAAQ,MAAM,OAAO,OAAO,SAAS,MAAM;EAC1D,CAAC;EACD,OAAO,OAAO,QAAQ,SAAS;GAC9B,OAAO,CAAC,IAAI;EACb,CAAC;EACD,OAAO,OAAO,UAAU,MAAM,GAAG,YAAY;GAC5C,MAAM,IAAI,gBAAgB,6BAA6B,QAAQ,OAAO;EACvE,CAAC;EACD,OAAO,OAAO,UAAU,MAAM,EAAE,SAAS,YAAY;GACpD,IAAI,UAAU,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK;GACzC,MAAM,IAAI,gBAAgB,YAAY,MAAM,WAAW,QAAQ,OAAO;EACvE,CAAC;EACD,SAAS,iBAAiB,MAAM,MAAM,aAAa,SAAS,UAAU,OAAO;GAC5E,MAAM,EAAE,MAAM,UAAU,MAAM,cAAc;GAC5C,IAAI,OAAO,KAAK,MAAM,IAAI,gBAAgB,YAAY,YAAY,MAAM,IAAI,WAAW,QAAQ,OAAO;GACtG,IAAI,OAAO,OAAO,CAAC,SAAS,MAAM,IAAI,gBAAgB,YAAY,YAAY,MAAM,IAAI,WAAW,QAAQ,OAAO;EACnH;EACA,OAAO,OAAO,WAAW,MAAM,EAAE,QAAQ,YAAY;GACpD,IAAI,OAAO,SAAS,UAAU,MAAM,IAAI,gBAAgB,2BAA2B,QAAQ,OAAO;GAClG,IAAI,KAAK,SAAS;IACjB,MAAM,SAAS,IAAI,OAAO,KAAK,QAAQ,QAAQ,KAAK,QAAQ,KAAK;IACjE,IAAI,CAAC,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,gBAAgB,iCAAiC,UAAU,OAAO;GACrG;GACA,iBAAiB,KAAK,QAAQ,MAAM,iBAAiB,OAAO;GAC5D,OAAO,CAAC,IAAI;EACb,CAAC;EACD,SAAS,aAAa,MAAM,QAAQ;GACnC,MAAM,MAAM,KAAK,SAAS;GAC1B,IAAI,IAAI,SAAS,GAAG,GAAG,OAAO,OAAO,KAAK,IAAI,IAAI,MAAM;GACxD,MAAM,QAAQ,IAAI,QAAQ,GAAG;GAC7B,IAAI,UAAU,IAAI,OAAO,OAAO,KAAK,IAAI,IAAI,MAAM;GACnD,MAAM,OAAO,IAAI,MAAM,QAAQ,CAAC;GAChC,MAAM,UAAU,IAAI,MAAM,GAAG,KAAK;GAClC,IAAI,KAAK,UAAU,QAAQ,OAAO,EAAE,UAAU,KAAK,OAAO,QAAQ,GAAG;GACrE,OAAO,EAAE,UAAU,KAAK,MAAM,GAAG,MAAM,IAAI,MAAM,KAAK,MAAM,MAAM;EACnE;EACA,SAAS,aAAa,MAAM,KAAK,MAAM;GACtC,OAAO,KAAK,IAAI,IAAI;GACpB,IAAI,CAAC,aAAa,KAAK,KAAK,SAAS,CAAC,GAAG,QAAQ,OAAO,OAAO,SAAS;GACxE,MAAM,QAAQ,KAAK,SAAS,CAAC,CAAC,QAAQ,GAAG;GACzC,MAAM,SAAS,KAAK,SAAS,CAAC,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC;GAChD,OAAO,KAAK,IAAI,aAAa,MAAM,MAAM,IAAI,aAAa,KAAK,MAAM,CAAC,IAAI,aAAa,MAAM,MAAM,MAAM;EAC1G;EACA,OAAO,OAAO,WAAW,MAAM,EAAE,QAAQ,YAAY;GACpD,IAAI,OAAO,SAAS,UAAU,MAAM,IAAI,gBAAgB,2BAA2B,QAAQ,OAAO;GAClG,iBAAiB,MAAM,MAAM,UAAU,OAAO;GAC9C,MAAM,EAAE,SAAS;GACjB,IAAI,QAAQ,CAAC,aAAa,MAAM,KAAK,OAAO,GAAG,IAAI,GAAG,MAAM,IAAI,gBAAgB,+BAA+B,KAAK,WAAW,QAAQ,OAAO;GAC9I,OAAO,CAAC,IAAI;EACb,CAAC;EACD,OAAO,OAAO,YAAY,MAAM,GAAG,YAAY;GAC9C,IAAI,OAAO,SAAS,WAAW,OAAO,CAAC,IAAI;GAC3C,MAAM,IAAI,gBAAgB,4BAA4B,QAAQ,OAAO;EACtE,CAAC;EACD,OAAO,OAAO,WAAW,MAAM,EAAE,MAAM,QAAQ,YAAY;GAC1D,IAAI,QAAQ,GAAG,OAAO,CAAC;GACvB,IAAI,OAAO,SAAS,UAAU;IAC7B,QAAQ;IACR,KAAK,MAAM,OAAO,MAAM,IAAI,OAAO,KAAK,MAAM,KAAK,KAAK,GAAG;GAC5D,OAAO,IAAI,MAAM,QAAQ,IAAI,GAAG;IAC/B,OAAO;IACP,KAAK,MAAM,OAAO,MAAM;KACvB,IAAI,OAAO,QAAQ,UAAU,MAAM,IAAI,gBAAgB,2BAA2B,OAAO,OAAO;KAChG,IAAI,OAAO,MAAM,SAAS,KAAK;IAChC;GACD,OAAO,MAAM,IAAI,gBAAgB,oCAAoC,QAAQ,OAAO;GACpF,IAAI,UAAU,KAAK,SAAS,OAAO,CAAC,KAAK;GACzC,OAAO,CAAC,OAAO,IAAI;EACpB,CAAC;EACD,OAAO,OAAO,aAAa,MAAM,GAAG,YAAY;GAC/C,IAAI,OAAO,SAAS,YAAY,OAAO,CAAC,IAAI;GAC5C,MAAM,IAAI,gBAAgB,6BAA6B,QAAQ,OAAO;EACvE,CAAC;EACD,OAAO,OAAO,OAAO,MAAM,EAAE,eAAe,YAAY;GACvD,IAAI,OAAO,gBAAgB,YAAY;IACtC,IAAI,gBAAgB,aAAa,OAAO,CAAC,IAAI;IAC7C,MAAM,IAAI,gBAAgB,YAAY,YAAY,KAAK,WAAW,QAAQ,OAAO;GAClF,OAAO;IACN,IAAI,WAAW,IAAI,GAAG,MAAM,IAAI,gBAAgB,YAAY,YAAY,WAAW,QAAQ,OAAO;IAClG,IAAI,YAAY,OAAO,eAAe,IAAI;IAC1C,OAAO,WAAW;KACjB,IAAI,UAAU,aAAa,SAAS,aAAa,OAAO,CAAC,IAAI;KAC7D,YAAY,OAAO,eAAe,SAAS;IAC5C;IACA,MAAM,IAAI,gBAAgB,YAAY,YAAY,WAAW,QAAQ,OAAO;GAC7E;EACD,CAAC;EACD,SAAS,SAAS,MAAM,KAAK,QAAQ,SAAS;GAC7C,IAAI;IACH,MAAM,CAAC,OAAO,WAAW,OAAO,QAAQ,KAAK,MAAM,QAAQ;KAC1D,GAAG;KACH,MAAM,CAAC,GAAG,QAAQ,QAAQ,CAAC,GAAG,GAAG;IAClC,CAAC;IACD,IAAI,YAAY,KAAK,GAAG,KAAK,OAAO;IACpC,OAAO;GACR,SAAS,GAAG;IACX,IAAI,CAAC,SAAS,SAAS,MAAM;IAC7B,OAAO,KAAK;IACZ,OAAO,OAAO,KAAK;GACpB;EACD;EACA,OAAO,OAAO,UAAU,MAAM,EAAE,OAAO,QAAQ,YAAY;GAC1D,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG,MAAM,IAAI,gBAAgB,0BAA0B,QAAQ,OAAO;GAC7F,iBAAiB,KAAK,QAAQ,MAAM,gBAAgB,SAAS,CAAC,WAAW,MAAM,KAAK,OAAO,CAAC;GAC5F,OAAO,CAAC,KAAK,KAAK,GAAG,UAAU,SAAS,MAAM,OAAO,OAAO,OAAO,CAAC,CAAC;EACtE,CAAC;EACD,OAAO,OAAO,SAAS,MAAM,EAAE,OAAO,QAAQ,SAAS,WAAW;GACjE,IAAI,CAAC,cAAc,IAAI,GAAG,MAAM,IAAI,gBAAgB,2BAA2B,QAAQ,OAAO;GAC9F,MAAM,SAAS,CAAC;GAChB,KAAK,MAAM,OAAO,MAAM;IACvB,IAAI;IACJ,IAAI;KACH,OAAO,OAAO,QAAQ,KAAK,MAAM,OAAO,CAAC,CAAC;IAC3C,SAAS,OAAO;KACf,IAAI,QAAQ;KACZ,MAAM;IACP;IACA,OAAO,QAAQ,SAAS,MAAM,KAAK,OAAO,OAAO;IACjD,KAAK,QAAQ,KAAK;IAClB,IAAI,QAAQ,MAAM,OAAO,KAAK;GAC/B;GACA,OAAO,CAAC,MAAM;EACf,CAAC;EACD,OAAO,OAAO,UAAU,MAAM,EAAE,QAAQ,SAAS,WAAW;GAC3D,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG,MAAM,IAAI,gBAAgB,0BAA0B,QAAQ,OAAO;GAC7F,MAAM,SAAS,KAAK,KAAK,OAAO,UAAU,SAAS,MAAM,OAAO,OAAO,OAAO,CAAC;GAC/E,IAAI,QAAQ,OAAO,CAAC,MAAM;GAC1B,OAAO,KAAK,GAAG,KAAK,MAAM,KAAK,MAAM,CAAC;GACtC,OAAO,CAAC,MAAM;EACf,CAAC;EACD,SAAS,MAAM,QAAQ,MAAM;GAC5B,KAAK,MAAM,OAAO,MAAM;IACvB,IAAI,OAAO,QAAQ;IACnB,OAAO,OAAO,KAAK;GACpB;EACD;EACA,OAAO,OAAO,WAAW,MAAM,EAAE,QAAQ,SAAS,WAAW;GAC5D,IAAI,CAAC,cAAc,IAAI,GAAG,MAAM,IAAI,gBAAgB,2BAA2B,QAAQ,OAAO;GAC9F,MAAM,SAAS,CAAC;GAChB,KAAK,MAAM,OAAO,MAAM;IACvB,MAAM,QAAQ,SAAS,MAAM,KAAK,KAAK,MAAM,OAAO;IACpD,IAAI,CAAC,WAAW,KAAK,KAAK,OAAO,MAAM,OAAO,OAAO;GACtD;GACA,IAAI,CAAC,QAAQ,MAAM,QAAQ,IAAI;GAC/B,OAAO,CAAC,MAAM;EACf,CAAC;EACD,OAAO,OAAO,UAAU,MAAM,EAAE,MAAM,YAAY,SAAS,WAAW;GACrE,MAAM,WAAW,CAAC;GAClB,KAAK,MAAM,SAAS,MAAM,IAAI;IAC7B,OAAO,OAAO,QAAQ,MAAM,OAAO,SAAS,MAAM;GACnD,SAAS,OAAO;IACf,SAAS,KAAK,KAAK;GACpB;GACA,MAAM,IAAI,gBAAgB,YAAY,SAAS,EAAE,WAAW,KAAK,UAAU,IAAI,KAAK,OAAO;EAC5F,CAAC;EACD,OAAO,OAAO,cAAc,MAAM,EAAE,MAAM,YAAY,SAAS,WAAW;GACzE,IAAI,CAAC,KAAK,QAAQ,OAAO,CAAC,IAAI;GAC9B,IAAI;GACJ,KAAK,MAAM,SAAS,MAAM;IACzB,MAAM,QAAQ,OAAO,QAAQ,MAAM,OAAO,SAAS,IAAI,CAAC,CAAC;IACzD,IAAI,WAAW,KAAK,GAAG;IACvB,IAAI,WAAW,MAAM,GAAG,SAAS;SAC5B,IAAI,OAAO,WAAW,OAAO,OAAO,MAAM,IAAI,gBAAgB,YAAY,SAAS,EAAE,WAAW,KAAK,UAAU,IAAI,KAAK,OAAO;SAC/H,IAAI,OAAO,UAAU,UAAU,MAAM,WAAW,CAAC,GAAG,KAAK;SACzD,IAAI,WAAW,OAAO,MAAM,IAAI,gBAAgB,YAAY,SAAS,EAAE,WAAW,KAAK,UAAU,IAAI,KAAK,OAAO;GACvH;GACA,IAAI,CAAC,UAAU,cAAc,IAAI,GAAG,MAAM,QAAQ,IAAI;GACtD,OAAO,CAAC,MAAM;EACf,CAAC;EACD,OAAO,OAAO,cAAc,MAAM,EAAE,OAAO,UAAU,YAAY,YAAY;GAC5E,MAAM,CAAC,QAAQ,UAAU,QAAQ,OAAO,QAAQ,MAAM,OAAO,SAAS,IAAI;GAC1E,IAAI,UAAU,OAAO,CAAC,SAAS,MAAM,CAAC;QACjC,OAAO,CAAC,SAAS,MAAM,GAAG,SAAS,OAAO,CAAC;EACjD,CAAC;EACD,MAAM,aAAa,CAAC;EACpB,SAAS,aAAa,MAAM,MAAM,QAAQ;GACzC,WAAW,QAAQ;GACnB,OAAO,OAAO,QAAQ,EAAE,CAAC,MAAM,GAAG,MAAM;IACvC,MAAM,SAAS,IAAI,OAAO,EAAE,MAAM,KAAK,CAAC;IACxC,KAAK,SAAS,KAAK,UAAU;KAC5B,QAAQ,KAAR;MACC,KAAK;OACJ,OAAO,OAAO,KAAK,UAAU,OAAO,OAAO;OAC3C;MACD,KAAK;OACJ,OAAO,QAAQ,OAAO,KAAK,KAAK,MAAM;OACtC;MACD,KAAK;OACJ,OAAO,OAAO,KAAK,MAAM,CAAC,IAAI,OAAO,IAAI;OACzC;MACD,KAAK;OACJ,OAAO,OAAOA,UAAS,KAAK,QAAQ,OAAO,IAAI;OAC/C;MACD,KAAK;OACJ,OAAO,OAAO,CAAC;OACf,KAAK,MAAM,OAAO,KAAK,QAAQ;QAC9B,IAAI,OAAO,KAAK,MAAM,CAAC,SAAS,UAAU;QAC1C,OAAO,KAAK,OAAO,KAAK,MAAM,CAAC;OAChC;OACA;MACD,KAAK,YAAY;OAChB,MAAM,WAAW,OAAO,WAAW,KAAK;OACxC,SAAS,oBAAoB,SAAS,SAAS;OAC/C;MACD;MACA,KAAK,eAAe;OACnB,MAAM,cAAc,OAAO,cAAc,KAAK;OAC9C,IAAI,OAAO,gBAAgB,YAAY,YAAY,oBAAoB,YAAY;OACnF;MACD;MACA,SAAS,OAAO,OAAO,KAAK;KAC7B;IACD,CAAC;IACD,IAAI,SAAS,YAAY,SAAS,QAAQ,OAAO,KAAK,UAAU,CAAC;SAC5D,IAAI,SAAS,WAAW,SAAS,SAAS,OAAO,KAAK,UAAU,CAAC;SACjE,IAAI,SAAS,UAAU,OAAO,KAAK,UAAU;IAClD,OAAO;GACR,EAAE,CAAC;EACJ;EACA,aAAa,MAAM,CAAC,aAAa,IAAI,EAAE,kBAAkB;GACxD,IAAI,OAAO,gBAAgB,YAAY,OAAO,YAAY;QACrD,OAAO;EACb,CAAC;EACD,aAAa,OAAO,CAAC,SAAS,KAAK;EACnC,aAAa,SAAS,CAAC,SAAS,OAAO;EACvC,aAAa,SAAS,CAAC,OAAO,IAAI,EAAE,YAAY,OAAO,UAAU,WAAW,KAAK,UAAU,KAAK,IAAI,KAAK;EACzG,aAAa,UAAU,CAAC,SAAS,QAAQ;EACzC,aAAa,UAAU,CAAC,SAAS,QAAQ;EACzC,aAAa,WAAW,CAAC,SAAS,SAAS;EAC3C,aAAa,UAAU,CAAC,MAAM,SAAS,QAAQ;EAC/C,aAAa,YAAY,CAAC,SAAS,UAAU;EAC7C,aAAa,SAAS,CAAC,OAAO,IAAI,EAAE,YAAY,GAAG,MAAM,SAAS,IAAI,EAAE,GAAG;EAC3E,aAAa,QAAQ,CAAC,SAAS,MAAM,IAAI,EAAE,OAAO,WAAW,WAAW,KAAK,SAAS,EAAE,KAAK,MAAM,SAAS,EAAE,GAAG;EACjH,aAAa,SAAS,CAAC,MAAM,IAAI,EAAE,WAAW,IAAI,KAAK,KAAK,UAAU,MAAM,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE;EACrG,aAAa,UAAU,CAAC,MAAM,IAAI,EAAE,WAAW;GAC9C,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,GAAG,OAAO;GAC3C,OAAO,KAAK,OAAO,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW;IACtD,OAAO,GAAG,MAAM,MAAM,KAAK,WAAW,KAAK,IAAI,IAAI,MAAM,SAAS;GACnE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;EACf,CAAC;EACD,aAAa,SAAS,CAAC,MAAM,IAAI,EAAE,QAAQ,WAAW;GACrD,MAAM,SAAS,KAAK,KAAK,EAAE,UAAU,aAAa,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK;GACtE,OAAO,SAAS,IAAI,OAAO,KAAK;EACjC,CAAC;EACD,aAAa,aAAa,CAAC,MAAM,IAAI,EAAE,WAAW;GACjD,OAAO,GAAG,KAAK,KAAK,UAAU,MAAM,SAAS,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK;EAC/D,CAAC;EACD,aAAa,aAAa;GACzB;GACA;GACA;EACD,IAAI,EAAE,SAAS,YAAY,MAAM,SAAS,OAAO,CAAC;;;;;;;;;;;;;EC5flD,MAAM,YAAY,OAAO,MAAM;GAAC;GAAW;GAAU;EAAU,CAAU;EAEzE,MAAa,SAAyB,OAAO,OAAO;GAClD,UAAU,OAAO,OAAO;IACtB,aAAa,OAAO,QAAQ,CAAC,CAAC,QAAQ,IAAI;IAC1C,WAAW,OAAO,QAAQ,CAAC,CAAC,QAAQ,IAAI;IACxC,OAAO,OAAO,QAAQ,CAAC,CAAC,QAAQ,IAAI;GACtC,CAAC;GACD,QAAQ,OAAO,OAAO;IACpB,SAAS,OAAO,QAAQ,CAAC,CAAC,QAAQ,IAAI;IAKtC,MAAM,OAAO,OAAO;IACpB,WAAW,UAAU,QAAQ,QAAQ;GACvC,CAAC;GACD,SAAS,OAAO,OAAO;IACrB,SAAS,OAAO,QAAQ,CAAC,CAAC,QAAQ,IAAI;IACtC,MAAM,OAAO,OAAO;IACpB,gBAAgB,OAAO,QAAQ,CAAC,CAAC,QAAQ,IAAI;IAC7C,WAAW,UAAU,QAAQ,QAAQ;GACvC,CAAC;GACD,QAAQ,OAAO,OAAO;IACpB,SAAS,OAAO,QAAQ,CAAC,CAAC,QAAQ,KAAK;IACvC,YAAY,OAAO,OAAO;IAC1B,QAAQ,OAAO,OAAO,CAAC,CAAC,KAAK,QAAQ;IACrC,WAAW,OAAO,OAAO,CAAC,CAAC,QAAQ,GAAI;IACvC,WAAW,UAAU,QAAQ,QAAQ;GACvC,CAAC;GACD,OAAO,OAAO,OAAO;IACnB,uBAAuB,OAAO,OAAO,CAAC,CAAC,QAAQ,GAAK;IACpD,qBAAqB,OAAO,OAAO,CAAC,CAAC,QAAQ,GAAI;IACjD,qBAAqB,OAAO,OAAO,CAAC,CAAC,QAAQ,EAAE;GACjD,CAAC;GACD,SAAS,OAAO,OAAO;IACrB,aAAa,OAAO,OAAO;IAC3B,qBAAqB,OAAO,QAAQ,CAAC,CAAC,QAAQ,IAAI;IAClD,QAAQ,OAAO,OAAO,CAAC,CAAC,QAAQ,uBAAuB;GACzD,CAAC;EACH,CAAC;;;;;EAMD,SAAgB,cAAc,QAAyB,CAAC,GAAW;GACjE,OAAO,OAAO,KAAe;EAC/B;;;;;;;;EC/HA,MAAa,cAAc;;;;;;;;ECS3B,IAAa,eAAb,MAAwD;GACtD,UAA0B,cAAc,CAAC,CAAC;GAC1C,4BAA6B,IAAI,IAAgB;GAEjD,MAAc;IACZ,OAAO,KAAK;GACd;GAEA,UAAU,UAAkC;IAC1C,KAAK,UAAU,IAAI,QAAQ;IAC3B,aAAa;KACX,KAAK,UAAU,OAAO,QAAQ;IAChC;GACF;;GAGA,MAAM,UAAyB;IAC7B,IAAI;KACF,MAAM,WAAW,MAAM,MAAM,aAAa,EAAE,SAAS,EAAE,QAAQ,mBAAmB,EAAE,CAAC;KACrF,IAAI,CAAC,SAAS,IAAI;KAClB,MAAM,OAAQ,MAAM,SAAS,KAAK;KAClC,IAAI,KAAK,WAAW,WAAW,KAAK,UAAU,KAAA,GAAW;KACzD,KAAK,UAAU,cAAc,KAAK,KAAwB;KAC1D,KAAK,MAAM,YAAY,CAAC,GAAG,KAAK,SAAS,GAAG,SAAS;IACvD,QAAQ,CAER;GACF;EACF;;;;;;;;;;ECfA,SAAgB,qBACd,UACA,MACA,SACgB;GAChB,MAAM,UAA0B,CAAC;GACjC,KAAK,MAAM,MAAM,OAAO,KAAK,IAAI,GAAkB;IACjD,MAAM,UAAU,KAAK;IACrB,IAAI,YAAY,KAAA,GAAW;IAC3B,MAAM,SAAS,SAAS;IACxB,IAAI,WAAW,KAAA,GAAW;IAC1B,IAAI,QAAQ,uBAAuB,KAAA,KAAa,OAAO,uBAAuB,KAAA,GAC5E,QAAQ,KAAK;KACX,MAAM;KACN,WAAW;KACX,aAAa,QAAQ;KACrB,OAAO,QAAQ;IACjB,CAAC;IAEH,IAAI,OAAO,WAAW,CAAC,QAAQ,WAAW,OAAO,SAC/C,QAAQ,KAAK;KAAE,MAAM;KAAa,WAAW;KAAI,OAAO,QAAQ;IAAa,CAAC;GAElF;GACA,OAAO;EACT;;;;ECuEA,SAAgB,SAAS,OAAe,OAAuB;GAC7D,OAAO,GAAG,MAAM,GAAG;EACrB;;;;;EAMA,SAAgB,aACd,MACA,QACS;GACT,MAAM,OAAO,KAAK;GAClB,IAAI,SAAS,KAAA,GAAW,OAAO;GAC/B,OAAO,OAAO,SAAS,KAAK,OAAO,KAAK,KAAK,EAAE,EAAE,SAAS;EAC5D;;EAYA,SAAS,WAAW,MAAqB,MAAmC;GAC1E,MAAM,UAAU,KAAK,KAAK;GAC1B,QAAQ,KAAK,MAAb;IACE,KAAK,UACH,OAAO,YAAY,SAAS,OAAO,YAAY,UAAU,QAAQ,KAAA;IACnE,KAAK,UACH,OAAO,KAAK,SAAS,SAAS,OAAO,IAAI,UAAU,KAAA;IACrD,KAAK,UAAU;KACb,IAAI,YAAY,IAAI,OAAO,KAAA;KAC3B,MAAM,SAAS,OAAO,OAAO;KAC7B,OAAO,OAAO,SAAS,MAAM,IAAI,SAAS,KAAA;IAC5C;IACA,KAAK,QACH,OAAO;GACX;EACF;;EAGA,SAAS,YAAY,MAAqB,OAAwB;GAChE,IAAI,KAAK,WAAW,MAAM,OAAO;GACjC,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM,OAAO;GAClD,OAAO,OAAO,KAAK;EACrB;EAEA,IAAa,yBAAb,MAAoC;GAQf;GACA;GARnB,yBAA0B,IAAI,IAAwB;GACtD,4BAA6B,IAAI,IAAgB;GACjD,SAAiB;GACjB,SAAiB;GACjB,QAA0C;GAE1C,YACE,OACA,QACA;IAFiB,KAAA,QAAA;IACA,KAAA,SAAA;IAEjB,MAAM,gBAAgB,KAAK,WAAW,CAAC;GACzC;;GAGA,SAA2B;IACzB,OAAO;KACL,OAAO,EACL,cAAc;MACZ,mBAAmB,KAAK,YAAY;MACpC,YAAY,aAAa;OACvB,KAAK,UAAU,IAAI,QAAQ;OAC3B,aAAa;QACX,KAAK,UAAU,OAAO,QAAQ;OAChC;MACF;KACF,EACF;KACA,OAAO,OAAO,OAAO,SAAS,KAAK,MAAM,OAAO,OAAO;MAAE;MAAM,OAAO;KAAM,CAAC;KAC7E,QAAQ,OAAO,UAAU;MACvB,MAAM,OAAO,KAAK,KAAK,OAAO,KAAK;MACnC,KAAK,MAAM,OAAO,OAAO;OAAE,MAAM,YAAY,MAAM,KAAK,UAAU,OAAO,KAAK,CAAC;OAAG,OAAO;MAAK,CAAC;KACjG;KACA,YAAY;MACV,KAAU,KAAK;KACjB;KACA,eAAe;MACb,IAAI,KAAK,OAAO,SAAS,KAAK,CAAC,KAAK,QAAQ;MAC5C,KAAK,OAAO,MAAM;MAClB,KAAK,SAAS;MACd,KAAK,WAAW;KAClB;KAEA,IAAI,QAAgB;IACtB;GACF;;;;;;;GAQA,cAAiC;IAC/B,OAAO,KAAK,UAAU,KAAK,QAAQ;GACrC;GAEA,UAAqC;IACnC,MAAM,WAAW,KAAK,MAAM,YAAY;IACxC,MAAM,YAAY,SAAS,WAAW;IACtC,MAAM,SAAyC,CAAC;IAChD,KAAK,MAAM,QAAQ,KAAK,QAAQ;KAC9B,MAAM,MAAM,SAAS,KAAK,OAAO,KAAK,KAAK;KAC3C,MAAM,SAAS,KAAK,OAAO,IAAI,GAAG;KAClC,MAAM,YAAY,KAAK,eAAe,IAAI;KAC1C,IAAI,WAAW,KAAA,GAAW;MACxB,OAAO,OAAO;OACZ,MAAM,YAAY,MAAM,SAAS;OACjC,YAAY,KAAK,QAAQ,IAAI;OAC7B,SAAS;MACX;MACA;KACF;KACA,OAAO,OAAO;MACZ,MAAM,OAAO;MACb,YAAY,OAAO,QAAQ,QAAQ,KAAK,QAAQ,IAAI;MACpD,SAAS,OAAO,QAAQ,QAAQ,WAAW,MAAM,OAAO,IAAI,MAAM,KAAA;KACpE;IACF;IACA,MAAM,OAAO,KAAK,KAAK;IACvB,OAAO;KACL;KACA,QAAQ,SAAS;KACjB,MAAM,SAAS,QAAQ;KACvB,UAAU,SAAS;KACnB,OAAO,KAAK,SAAS;KACrB,SAAS,KAAK,MAAK,SAAQ,KAAK,QAAQ,KAAA,CAAS;KACjD,QAAQ,KAAK;KACb,QAAQ,KAAK;KACb;IACF;GACF;GAEA,eAAuB,MAA8B;IACnD,MAAM,QAAQ,KAAK,WAAW,KAAK,KAAK;IACxC,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;IAChC,OAAO,MAAM,KAAK;GACpB;GAEA,WAAmB,OAAoD;IACrE,MAAM,QAAQ,KAAK,MAAM,YAAY,CAAC,CAAC;IACvC,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO,KAAA;IAExD,MAAM,UAAUC,MAAO;IACvB,OAAO,OAAO,YAAY,YAAY,YAAY,OAC9C,UACA,KAAA;GACN;GAEA,UAAkB,OAAe,OAAwB;IACvD,MAAM,OAAO,KAAK,MAAM,YAAY,CAAC,CAAC;IACtC,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM,OAAO,KAAA;IACtD,MAAM,UAAW,KAAiC;IAClD,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM,OAAO,KAAA;IAC5D,OAAQ,QAAoC;GAC9C;GAEA,QAAgB,MAA8B;IAC5C,MAAM,OAAO,KAAK,MAAM,YAAY,CAAC,CAAC;IACtC,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM,OAAO;IACtD,MAAM,UAAW,KAAiC,KAAK;IACvD,OAAO,OAAO,YAAY,YAAY,YAAY,QAC7C,OAAO,OAAO,SAAoC,KAAK,KAAK;GACnE;GAEA,MAAc,OAAe,OAAe,MAAwB;IAClE,KAAK,OAAO,IAAI,SAAS,OAAO,KAAK,GAAG,IAAI;IAC5C,KAAK,SAAS;IACd,KAAK,WAAW;GAClB;GAEA,KAAa,OAAe,OAA8B;IACxD,MAAM,OAAO,KAAK,OAAO,MAAK,cAAa,UAAU,UAAU,SAAS,UAAU,UAAU,KAAK;IACjG,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,MAAM,8BAA8B,MAAM,GAAG,OAAO;IACtF,OAAO;GACT;;;;;;GAOA,OAA+B;IAC7B,MAAM,MAAsB,CAAC;IAC7B,KAAK,MAAM,CAAC,KAAK,WAAW,KAAK,QAAQ;KACvC,MAAM,CAAC,OAAO,SAAS,IAAI,MAAM,GAAG;KACpC,MAAM,OAAO,KAAK,KAAK,OAAO,KAAK;KACnC,IAAI,KAAK,SAAS,IAAI,GAAG;KACzB,IAAI,KAAK,WAAW,QAAQ,OAAO,KAAK,KAAK,MAAM,MAAM,CAAC,OAAO,OAAO;KACxE,IAAI,OAAO,OAAO;MAGhB,IAAI,CAAC,KAAK,UAAU,CAAC,KAAK,QAAQ,IAAI,GAAG;MACzC,IAAI,KAAK;OAAE,IAAI;OAAS,MAAM,CAAC,OAAO,KAAK;MAAE,CAAC;MAC9C;KACF;KACA,MAAM,UAAU,WAAW,MAAM,OAAO,IAAI;KAC5C,IAAI,YAAY,KAAA,GAAW,OAAO,CAAC,EAAE,KAAK,KAAA,EAAU,CAAC;KAErD,IAAI,KAAK,WAAW,QAAQ,cAAc,SAAS,KAAK,eAAe,IAAI,CAAC,GAAG;KAC/E,IAAI,KAAK;MAAE,IAAI;MAAO,MAAM,CAAC,OAAO,KAAK;MAAG,OAAO;KAAQ,CAAC;IAC9D;IACA,IAAI,IAAI,WAAW,GAAG,OAAO,CAAC;IAC9B,MAAM,QAAQ,KAAK;IACnB,OAAO,CAAC,EACN,KAAK,YAAY;KAEf,OAAO,MADU,MAAM,SAAS,GAAG;IAErC,EACF,CAAC;GACH;;;;;GAMA,SAAS,MAA8B;IACrC,MAAM,OAAO,KAAK;IAClB,IAAI,SAAS,KAAA,GAAW,OAAO;IAC/B,MAAM,UAAU,SAAS,KAAK,OAAO,KAAK,KAAK;IAC/C,MAAM,WAAW,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK;IACjD,MAAM,SAAS,KAAK,OAAO,IAAI,OAAO;IACtC,IAAI;IACJ,IAAI,WAAW,KAAA,KAAa,CAAC,OAAO,OAClC,YAAY,WAAW,UAAU,OAAO,IAAI;SAE5C,YAAY,KAAK,eAAe,QAAQ;IAE1C,OAAO,cAAc;GACvB;GAEA,MAAc,OAAsB;IAClC,MAAM,OAAO,KAAK,KAAK;IACvB,IAAI,KAAK,WAAW,KAAK,KAAK,UAAU,KAAK,MAAK,SAAQ,KAAK,QAAQ,KAAA,CAAS,GAAG;IACnF,KAAK,SAAS;IACd,KAAK,SAAS;IACd,KAAK,WAAW;IAChB,IAAI,SAAS;IACb,KAAK,MAAM,QAAQ,MAAM;KACvB,IAAI,KAAK,QAAQ,KAAA,GAAW;KAC5B,SAAU,MAAM,KAAK,IAAI,KAAM;IACjC;IACA,IAAI,QAAQ,KAAK,OAAO,MAAM;IAC9B,KAAK,SAAS;IACd,KAAK,SAAS,CAAC;IACf,KAAK,WAAW;GAClB;;GAGA,aAA2B;IACzB,KAAK,QAAQ;IACb,KAAK,MAAM,YAAY,CAAC,GAAG,KAAK,SAAS,GAAG,SAAS;GACvD;EACF;;EAGA,SAAgB,cAAc,GAAY,GAAqB;GAC7D,IAAI,MAAM,GAAG,OAAO;GACpB,IAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,MAAM,QAAQ,MAAM,MAAM,OAAO;GACvF,IAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;IACxC,IAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,OAAO;IAC5E,OAAO,EAAE,OAAO,OAAO,UAAU,cAAc,OAAO,EAAE,MAAM,CAAC;GACjE;GACA,MAAM,OAAO;GACb,MAAM,QAAQ;GACd,MAAM,OAAO,OAAO,KAAK,IAAI;GAC7B,IAAI,KAAK,WAAW,OAAO,KAAK,KAAK,CAAC,CAAC,QAAQ,OAAO;GACtD,OAAO,KAAK,OAAM,QAAO,OAAO,SAAS,cAAc,KAAK,MAAM,MAAM,IAAI,CAAC;EAC/E;;;;;;EAOA,MAAa,cAAwC;GAEnD;IAAE,OAAO;IAAY,OAAO;IAAe,MAAM;IAAU,OAAO;GAA6B;GAC/F;IAAE,OAAO;IAAY,OAAO;IAAa,MAAM;IAAU,OAAO;GAA2B;GAC3F;IAAE,OAAO;IAAY,OAAO;IAAS,MAAM;IAAU,OAAO;GAAuB;GAEnF;IAAE,OAAO;IAAU,OAAO;IAAW,MAAM;IAAU,OAAO;GAAuB;GACnF;IAAE,OAAO;IAAU,OAAO;IAAa,MAAM;IAAU,OAAO;IAA0B,SAAS;KAAC;KAAW;KAAU;IAAU;GAAE;GACnI;IAAE,OAAO;IAAU,OAAO;IAAQ,MAAM;IAAQ,OAAO;IAAqB,MAAM;GAAmB;GAErG;IAAE,OAAO;IAAW,OAAO;IAAW,MAAM;IAAU,OAAO;GAAwB;GACrF;IAAE,OAAO;IAAW,OAAO;IAAkB,MAAM;IAAU,OAAO;GAA+B;GACnG;IAAE,OAAO;IAAW,OAAO;IAAa,MAAM;IAAU,OAAO;IAA2B,SAAS;KAAC;KAAW;KAAU;IAAU;GAAE;GACrI;IAAE,OAAO;IAAW,OAAO;IAAQ,MAAM;IAAQ,OAAO;GAAqB;GAE7E;IAAE,OAAO;IAAU,OAAO;IAAW,MAAM;IAAU,OAAO;GAAuB;GACnF;IACE,OAAO;IAAU,OAAO;IAAc,MAAM;IAAQ,OAAO;IAC3D,cAAc;KAAE,OAAO;KAAU,OAAO;IAAU;GACpD;GACA;IACE,OAAO;IAAU,OAAO;IAAU,MAAM;IAAQ,OAAO;IACvD,MAAM;IAAsB,QAAQ;IACpC,cAAc;KAAE,OAAO;KAAU,OAAO;IAAU;GACpD;GACA;IACE,OAAO;IAAU,OAAO;IAAa,MAAM;IAAU,OAAO;IAC5D,cAAc;KAAE,OAAO;KAAU,OAAO;IAAU;GACpD;GACA;IACE,OAAO;IAAU,OAAO;IAAa,MAAM;IAAU,OAAO;IAC5D,SAAS;KAAC;KAAW;KAAU;IAAU;IACzC,cAAc;KAAE,OAAO;KAAU,OAAO;IAAU;GACpD;GAEA;IAAE,OAAO;IAAW,OAAO;IAAe,MAAM;IAAQ,OAAO;IAA6B,MAAM;GAA2B;GAC7H;IAAE,OAAO;IAAW,OAAO;IAAuB,MAAM;IAAU,OAAO;GAAoC;GAC7G;IAAE,OAAO;IAAW,OAAO;IAAU,MAAM;IAAQ,OAAO;GAAuB;EACnF;;;;ECxZA,SAAgB,iBAAiB,SAAoC;GACnE,IAAI,OAAqB;IACvB,QAAQ;IACR,OAAO,KAAA;IACP,MAAM,KAAA;IACN,MAAM,KAAA;IACN,UAAU;IACV,MAAM;GACR;GACA,MAAM,4BAAY,IAAI,IAAgB;GACtC,MAAM,eAAqB;IACzB,KAAK,MAAM,YAAY,CAAC,GAAG,SAAS,GAAG,SAAS;GAClD;GAEA,MAAM,UAAU,YAA2B;IACzC,IAAI;IACJ,IAAI;KACF,OAAO,MAAM,QAAQ,IAAI;IAC3B,QAAQ;KAEN,OAAO;MAAE,GAAG;MAAM,QAAQ;KAAc;KACxC,OAAO;KACP;IACF;IACA,OAAO;KACL,QAAQ,KAAK;KACb,OAAO,KAAK;KACZ,MAAM,KAAK;KACX,MAAM,KAAK;KACX,UAAU,KAAK;KACf,MAAM,KAAK;KACX,UAAU,KAAK;IACjB;IACA,OAAO;GACT;GAEA,MAAM,QAAmB;IACvB,mBAAmB;IACnB,YAAY,aAAa;KACvB,UAAU,IAAI,QAAQ;KACtB,aAAa;MACX,UAAU,OAAO,QAAQ;KAC3B;IACF;IACA,MAAM,IAAI,OAAe,OAAgB;KACvC,MAAM,MAAM,SAAS,CAAC;MAAE,IAAI;MAAO,MAAM,CAAC,KAAK;MAAG;KAAM,CAAC,CAAC;IAC5D;IACA,MAAM,MAAM,OAAe;KACzB,MAAM,MAAM,SAAS,CAAC;MAAE,IAAI;MAAS,MAAM,CAAC,KAAK;KAAE,CAAC,CAAC;IACvD;IACA,MAAM,SAAS,KAA8B;KAC3C,MAAM,SAAS,MAAM,QAAQ,MAAM,EAAO,IAA8B,CAAC;KACzE,IAAI,OAAO,IAAI,MAAM,QAAQ;KAC7B,OAAO,OAAO;IAChB;GACF;GAEA,OAAO;IAAE;IAAO;GAAQ;EAC1B;;;;ECpFA,MAAa,mBAA2C;GACtD,UAAU;GACV,QAAQ;GACR,SAAS;GACT,QAAQ;GACR,SAAS;EACX;EAIA,MAAM,cAAmC;GACvC,SAAS;GACT,eAAe;GACf,KAAK;GACL,SAAS;EACX;EAEA,MAAM,mBAAwC;GAC5C,SAAS;GACT,YAAY;GACZ,KAAK;EACP;EAEA,MAAM,oBAAyC;GAC7C,MAAM;GACN,UAAU;GACV,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,cAAmC;GACvC,cAAc;GACd,SAAS;GACT,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,cAAmC;GACvC,QAAQ;GACR,YAAY;GACZ,SAAS;GACT,MAAM;GACN,UAAU;GACV,YAAY;GACZ,OAAO;GACP,QAAQ;EACV;EAEA,MAAM,cAAmC;GACvC,QAAQ;GACR,SAAS;GACT,QAAQ;GACR,cAAc;GACd,YAAY;GACZ,MAAM;GACN,UAAU;GACV,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,aAAkC;GACtC,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,gBAAqC;GACzC,GAAG;GACH,OAAO;EACT;EAEA,MAAM,sBAA2C;GAC/C,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,kBAAuC;GAC3C,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,eAAoC;GACxC,SAAS;GACT,YAAY;GACZ,gBAAgB;GAChB,KAAK;GACL,SAAS;GACT,WAAW;GACX,WAAW;EACb;EAEA,MAAM,eAAoC;GACxC,MAAM;GACN,UAAU;GACV,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,cAAmC;GACvC,YAAY;GACZ,QAAQ;GACR,cAAc;GACd,SAAS;GACT,MAAM;GACN,UAAU;GACV,YAAY;GACZ,QAAQ;EACV;EAEA,MAAM,gBAAqC;GACzC,GAAG;GACH,aAAa;GACb,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,aAAkC;GACtC,GAAG;GACH,YAAY;GACZ,OAAO;EACT;;EAKA,SAAS,SAAS,EAAE,MAAM,OAAO,SAAS,GAAG,YAM1C;GACD,MAAM,KAAK,gBAAgB,KAAK,MAAM,GAAG,KAAK;GAC9C,MAAM,QAAQ,EAAE,KAAK,KAAK;GAC1B,MAAM,kBAAkB,MAAM,cAC5B,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;IAAM,OAAO;KAAE,SAAS;KAAe,YAAY;KAAU,KAAK;IAAE;IAApE,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,OAAO;KAAc,UAAA,EAAE,kBAAkB;IAAQ,CAAA,GACvD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KAAQ,MAAK;KAAS,OAAO;KAAuB;KAAU,eAAe,QAAQ,MAAM,KAAK,OAAO,KAAK,KAAK;KAC9G,UAAA,EAAE,cAAc;IACX,CAAA,CACJ;;GAGR,IAAI,KAAK,SAAS,UAEhB,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;KAAE,GAAG;KAAa,eAAe;KAAO,YAAY;KAAU,UAAU;KAAQ,KAAK;KAAG,WAAW;IAAG;IAAlH,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;MAAO,OAAO;OAAE,GAAG;OAAmB,MAAM;OAAY,QAAQ,WAAW,YAAY;MAAU;MAAG,SAAS;MAC1G,UAAA;KACI,CAAA;KACN;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;MACM;MACJ,MAAK;MACL,SAAS,MAAM,SAAS;MACd;MACV,WAAW,UAAU,QAAQ,KAAK,KAAK,OAAO,KAAK,OAAO,OAAO,MAAM,OAAO,OAAO,CAAC;MACtF,OAAO;OAAE,MAAM;OAAQ,aAAa;MAAiC;KACtE,CAAA;KACA,KAAK,SAAS,KAAA,KAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,OAAO;OAAE,GAAG;OAAY,WAAW;MAAO;MAAI,UAAA,EAAE,KAAK,IAAI;KAAK,CAAA;IAC1F;;GAIT,IAAI;GACJ,IAAI,KAAK,SAAS,UAChB,UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IACM;IACJ,OAAO,MAAM;IACH;IACV,WAAW,UAAU,QAAQ,KAAK,KAAK,OAAO,KAAK,OAAO,MAAM,OAAO,KAAK;IAC5E,OAAO;KAAE,GAAG;KAAa,QAAQ;IAAU;IAE1C,UAAA,KAAK,SAAS,KAAI,WAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KAAqB,OAAO;KAAS,UAAA;IAAe,GAAvC,MAAuC,CAAC;GAC5E,CAAA;QAGV,UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;IACM;IACJ,MAAK;IACL,WAAW,KAAK,SAAS,WAAW,YAAY,KAAA;IAChD,OAAO,MAAM;IACb,aAAa,KAAK,WAAW,OAAO,EAAE,oBAAoB,IAAI,KAAA;IACpD;IACV,gBAAc,MAAM;IACpB,WAAW,UAAU,QAAQ,KAAK,KAAK,OAAO,KAAK,OAAO,MAAM,OAAO,KAAK;IAC5E,OAAO,MAAM,UAAU;KAAE,GAAG;KAAa,aAAa;IAA+B,IAAI;GAC1F,CAAA;GAGL,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;IAAZ,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO;MAAZ,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OAAO,OAAO;OAAmB,SAAS;OAAK,UAAA;MAAa,CAAA,GAC3D,eACE;;KACJ;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,OAAO,MAAM,UAAU,gBAAgB;MACvC,UAAA,MAAM,UAAU,EAAE,qBAAqB,IAAI,KAAK,SAAS,KAAA,IAAY,KAAK,EAAE,KAAK,IAAI;KACrF,CAAA;IACA;;EAET;;EAGA,MAAM,eAA8C,OAAO,YACzD,YAAY,KAAI,SAAQ,CAAC,GAAG,KAAK,MAAM,GAAG,KAAK,SAAS,IAAI,CAAC,CAC/D;;;;;;;EAQA,SAAgB,qBAAqB,EAAE,OAAO,SAAS,KAIpD;GACD,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,OAAO,KAAK,MAAM,MAAM,CAAC,CAAC,KAAI,QAAO,IAAI,MAAM,GAAG,CAAC,CAAC,EAAG,CAAC,CAAC;GACpF,MAAM,kBAAkB,CAAC,MAAM,YAAY,MAAM;GACjD,MAAM,UAAU,CAAC,MAAM,SAAS,MAAM,WAAW,MAAM;GAEvD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;IACG,CAAC,MAAM,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;KAAG,OAAO;KAAiB,MAAK;KAAU,UAAA,EAAE,iBAAiB;IAAK,CAAA;IACrF,OAAO,KAAI,UACV,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;KAAG,OAAO;KAAsB,UAAA,EAAE,iBAAiB,UAAU,KAAK;IAAK,CAAA,GACtE,OAAO,QAAQ,MAAM,MAAM,CAAC,CAC1B,QAAQ,CAAC,SAAS,IAAI,WAAW,GAAG,MAAM,EAAE,CAAC,CAAC,CAC9C,KAAK,CAAC,KAAK,WAAW;KACH,IAAI,MAAM,IAAI,QAAQ,GAAG,IAAI,CAAC;KAChD,MAAM,OAAO,aAAa;KAC1B,IAAI,SAAS,KAAA,GAAW,OAAO;KAC/B,IAAI,aAAa,MAAM,MAAM,MAAM,GAAG,OAAO;KAC7C,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MAEQ;MACN,OAAO;MACE;MACN;MACH,UAAU;KACX,GANM,GAMN;IAEL,CAAC,CACA,EAAA,GApBK,KAoBL,CACN;IACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,OAAO;KAAZ,UAAA;MACG,MAAM,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,OAAO;OAAc,MAAK;OAAU,UAAA,EAAE,mBAAmB;MAAK,CAAA;MACjF,MAAM,WAAW,CAAC,MAAM,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,OAAO;OAAc,MAAK;OAAU,UAAA,EAAE,qBAAqB;MAAK,CAAA;MACtG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,MAAK;OACL,OAAO;QAAE,GAAG;QAAe,GAAK,CAAC,MAAM,SAAS,CAAC,MAAM,UAAW,MAAM,SAAS;SAAE,SAAS;SAAK,QAAQ;QAAU,IAAI,CAAC;OAAG;OAC3H,UAAU,CAAC,MAAM,SAAS,MAAM;OAChC,SAAS,QAAQ;OAEhB,UAAA,EAAE,gBAAgB;MACb,CAAA;MACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,MAAK;OACL,OAAO;QAAE,GAAG;QAAY,GAAI,UAAU;SAAE,SAAS;SAAK,QAAQ;QAAU,IAAI,CAAC;OAAG;OAChF,UAAU;OACV,SAAS,QAAQ;OAEhB,UAAA,MAAM,SAAS,EAAE,eAAe,IAAI,EAAE,aAAa;MAC9C,CAAA;KACL;;GACL,EAAA,CAAA;EAEN;;;EC9RA,MAAM,gBAAqC;GACzC,SAAS;GACT,eAAe;GACf,KAAK;GACL,UAAU;EACZ;EAEA,MAAM,cAAmC;GACvC,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,oBAAyC;GAC7C,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,OAAO;EACT;EAEA,MAAM,oBAAyC;GAC7C,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,OAAO;EACT;;;;;EAMA,SAAgB,gBAAgB,OAA6B;GAC3D,MAAM,QAAQ,MAAM,iBAAgB,aAAY,QAAQ;GACxD,MAAM,EAAE,MAAM,OAAO,MAAM,SAAS,MAAM;GAE1C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;IAAZ,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;KAAI,OAAO;KAAc,UAAA,EAAE,KAAK;IAAM,CAAA,GACtC,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;KAAG,OAAO;KAAoB,UAAA,EAAE,qBAAqB;IAAK,CAAA,CACvD,EAAA,CAAA,GACJ,MAAM,YACH,iBAAA,GAAA,kBAAA,IAAA,CAAC,sBAAD;KAA6B;KAAO,SAAS;MAAE;MAAM;MAAO;MAAM;KAAQ;KAAM;IAAI,CAAA,IACpF,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;KAAG,OAAO;KAAmB,MAAK;KAAU,UAAA,EAAE,oBAAoB;IAAK,CAAA,CACxE;;EAET;;;EChDA,MAAa,KAAK;GAChB,KAAK;GACL,uBAAuB;GAEvB,kBAAkB;GAClB,gBAAgB;GAChB,iBAAiB;GACjB,gBAAgB;GAChB,iBAAiB;GAEjB,8BAA8B;GAC9B,4BAA4B;GAC5B,wBAAwB;GACxB,wBAAwB;GACxB,qBAAqB;GACrB,0BAA0B;GAC1B,yBAAyB;GACzB,sBAAsB;GACtB,gCAAgC;GAChC,2BAA2B;GAC3B,wBAAwB;GACxB,2BAA2B;GAC3B,uBAAuB;GACvB,0BAA0B;GAC1B,0BAA0B;GAC1B,6BAA6B;GAC7B,qCAAqC;GACrC,wBAAwB;GAExB,oBAAoB;GACpB,sBAAsB;GACtB,4BAA4B;GAE5B,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,gBAAgB;GAChB,oBAAoB;GACpB,mBAAmB;GACnB,qBAAqB;GACrB,uBAAuB;GACvB,uBAAuB;GACvB,sBAAsB;EACxB;EAEA,MAAa,KAAK;GAChB,KAAK;GACL,uBAAuB;GAEvB,kBAAkB;GAClB,gBAAgB;GAChB,iBAAiB;GACjB,gBAAgB;GAChB,iBAAiB;GAEjB,8BAA8B;GAC9B,4BAA4B;GAC5B,wBAAwB;GACxB,wBAAwB;GACxB,qBAAqB;GACrB,0BAA0B;GAC1B,yBAAyB;GACzB,sBAAsB;GACtB,gCAAgC;GAChC,2BAA2B;GAC3B,wBAAwB;GACxB,2BAA2B;GAC3B,uBAAuB;GACvB,0BAA0B;GAC1B,0BAA0B;GAC1B,6BAA6B;GAC7B,qCAAqC;GACrC,wBAAwB;GAExB,oBAAoB;GACpB,sBAAsB;GACtB,4BAA4B;GAE5B,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,gBAAgB;GAChB,oBAAoB;GACpB,mBAAmB;GACnB,qBAAqB;GACrB,uBAAuB;GACvB,uBAAuB;GACvB,sBAAsB;EACxB;;;ECtEA,MAAa,OAAO;;EAGpB,MAAa,YAAY;;EAGzB,MAAa,SAAS;GAAC;GAAY;GAAU;GAAS;EAAQ;;EAG9D,MAAM,iBAAiB;;EAGvB,IAAM,kBAAN,MAAsB;GAIS;;GAF7B,4BAA6B,IAAI,IAAoB;GAErD,YAAY,QAA6C;IAA5B,KAAA,SAAA;GAA6B;GAE1D,UAAgB;IACd,KAAK,UAAU,MAAM;GACvB;;GAGA,aAAa,UAA4B,MAA8B;IACrE,MAAM,SAAS,KAAK,OAAO,IAAI;IAC/B,IAAI,CAAC,OAAO,QAAQ,SAAS;IAC7B,IAAI,OAAO,iBAAiB,aAAa;IACzC,IAAI,aAAa,eAAe,WAAW;IAC3C,IAAI,OAAO,QAAQ,kBAAkB,SAAS,oBAAoB,UAAU;IAE5E,MAAM,UAAU,qBAAqB,SAAS,MAAM,KAAK,MAAM,KAAK,OAAO;IAC3E,KAAK,MAAM,UAAU,SAAS;KAC5B,IAAI,CAAC,KAAK,MAAM,QAAQ,MAAM,GAAG;KACjC,KAAK,KAAK,QAAQ,MAAM;IAC1B;GACF;;GAGA,MAAc,QAAsB,QAAyB;IAC3D,MAAM,MAAM,KAAK,IAAI;IACrB,MAAM,MAAM,GAAG,OAAO,KAAK,GAAG,OAAO;IACrC,MAAM,aAAa,OAAO,MAAM;IAChC,MAAM,OAAO,KAAK,UAAU,IAAI,GAAG;IACnC,IAAI,SAAS,KAAA,KAAa,MAAM,OAAO,YAAY,OAAO;IAC1D,IAAI;KACF,MAAM,aAAa,iBAAiB;KACpC,MAAM,MAAM,OAAO,aAAa,QAAQ,UAAU;KAClD,IAAI,QAAQ,QAAQ,MAAM,OAAO,GAAG,IAAI,YAAY,OAAO;KAC3D,OAAO,aAAa,QAAQ,YAAY,OAAO,GAAG,CAAC;IACrD,QAAQ,CAER;IACA,KAAK,UAAU,IAAI,KAAK,GAAG;IAC3B,OAAO;GACT;GAEA,KAAa,QAAsB,QAAsB;IACvD,MAAM,YAAY,OAAO,QAAQ;IACjC,MAAM,eAAe,IAAI,aAAa,KAAK,QAAQ,QAAQ,MAAM,GAAG;KAClE,GAAI,cAAc,YAAY,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,QAAQ,QAAQ,SAAS,EAAE;KAClF,GAAI,OAAO,QAAQ,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,OAAO,QAAQ,KAAK;KAEzE,KAAK,gBAAgB,OAAO,KAAK,GAAG,OAAO;IAC7C,CAAC;IACD,aAAa,gBAAgB;KAC3B,OAAO,MAAM;KACb,aAAa,MAAM;IACrB;GACF;GAEA,QAAgB,QAAsB,QAAwB;IAC5D,IAAI;IACJ,IAAI,OAAO,SAAS,eAClB,OAAO,OAAO,gBAAgB,aAC1B,cACA,OAAO,gBAAgB,gBACrB,cACA;SAEN,OAAO;IAET,MAAM,SAAS,OAAO,QAAQ;IAC9B,OAAO,WAAW,KAAA,KAAa,WAAW,KAAK,OAAO,GAAG,OAAO,GAAG;GACrE;GAEA,OAAe,QAAsB,QAAgB,WAA8B;IACjF,MAAM,QAAkB,CAAC;IACzB,IAAI,cAAc,WAAW,OAAO;IACpC,IAAI,OAAO,QAAQ,uBAAuB,OAAO,UAAU,KAAA,GACzD,MAAM,KAAK,MAAM,OAAO,OAAO;IAEjC,IAAI,cAAc,YAChB,MAAM,KAAK,MAAM,OAAO,QAAQ,QAAQ;IAE1C,OAAO,MAAM,KAAK,IAAI;GACxB;EACF;EAEA,SAAgB,MAAM,KAAoB;GACxC,MAAM,SAAS,IAAI,aAAa;GAChC,OAAY,QAAQ;GAuBpB,MAAM,aAAa,iBAAiB;IAnBlC,KAAK,YAAiC;KACpC,MAAM,WAAW,MAAM,MAAM,aAAa,EAAE,SAAS,EAAE,QAAQ,mBAAmB,EAAE,CAAC;KACrF,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM,0BAA0B,SAAS,QAAQ;KAC7E,OAAQ,MAAM,SAAS,KAAK;IAC9B;IACA,OAAO,OAAO,SAA0B;KACtC,IAAI;MACF,MAAM,WAAW,MAAM,MAAM,aAAa;OACxC,QAAQ;OACR,SAAS,EAAE,gBAAgB,mBAAmB;OAC9C,MAAM,KAAK,UAAU,IAAI;MAC3B,CAAC;MACD,MAAM,SAAU,MAAM,SAAS,KAAK;MACpC,OAAO;OAAE,IAAI,SAAS,MAAM,OAAO,OAAO;OAAM,OAAO,OAAO;MAAM;KACtE,SAAS,OAAO;MACd,OAAO;OAAE,IAAI;OAAO,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;MAAE;KACpF;IACF;GAEwC,CAAC;GAC3C,WAAgB,QAAQ;GAGxB,MAAM,YAAY,IAAI,OAAO,IAAI,mCAAmC;IAClE,OAAY,QAAQ;IACpB,WAAgB,QAAQ;GAC1B,CAAC;GACD,IAAI,mBAAmB,YAAY,GAAG,qCAAqC;GAE3E,MAAM,WAAW,IAAI,gBAAgB,MAAM;GAC3C,IAAI,mBAAmB,SAAS,QAAQ,GAAG,gCAAgC;GAG3E,IAAI,WAAW,IAAI,SAAS,KAAK,YAAY;GAC7C,MAAM,UAAU,IAAI,SAAS,KAAK,gBAAgB;IAChD,MAAM,OAAO,IAAI,SAAS,KAAK,YAAY;IAC3C,SAAS,aAAa,UAAU,IAAI;IACpC,WAAW;GACb,CAAC;GACD,IAAI,mBAAmB,QAAQ,GAAG,qCAAqC;GAKvE,MAAM,aAAa,IAAI,uBAAuB,WAAW,OAAO,WAAW;GAC3E,IAAI,aAAa,IAAI,OAAO,SAAS,WAAW;IAAE;IAAI;GAAG,CAAC,GAAG,mCAAmC;GAChG,MAAM,IAAI,IAAI,OAAO,KAAK,SAAS;GACnC,IAAI,MAAM,OAAO,oBAAoB,aAAa;IAGhD,MAAM,WAAW,IAAI,MAAM,QAAQ,kBAAkB;IACrD,MAAM,eAAe,SAAS,MAAK,UAAS,MAAM,QAAQ,OAAO,eAAe;IAChF,MAAM,WAAW,SAAS,QAAQ,KAAK,UAAU,KAAK,IAAI,KAAK,MAAM,QAAQ,SAAS,CAAC,GAAG,CAAC;IAC3F,MAAM,QAAQ,iBAAiB,KAAA,KAC1B,aAAa,QAAQ,SAAS,KAAK,IACpC,SAAS,SAAS,IAChB,WAAW,IACX;IACN,MAAM,OAAO,WAAW,OAAO;IAC/B,MAAM,IAAI,MAAM,SAAS;KACvB,MAAM;KACN,IAAI;KACJ;KACA,aAAa,EAAE,KAAK;KACpB,QAAQ;KACR,eAAe;MAAE,GAAG;MAAM;KAAE;IAC9B,GAAG,eAAe;GACpB,CAAC;GAGD,IAAI,OAAO,iBAAiB,eAAe,aAAa,eAAe,WACrE,aAAkB,kBAAkB;GAGtC,IAAI,OAAO,KAAK,8BAA8B;EAChD"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * dsh-messager 配置路由(host 端):给浏览器提供不受 settings 白名单门控的
3
+ * 配置读写通道(webServer 服务,dsh-market 同款「正门」)。
4
+ *
5
+ * - GET /dsh-messager/config —— 返回 messager 命名空间的脱敏视图
6
+ * (value/user/base/writable/revision,与 client ScopeLike 快照同构);
7
+ * - POST /dsh-messager/config —— 接受逐字段 ops(与 client ScopeWriteOp 同构),
8
+ * 经 ctx.settings.mutate 落库(host 侧不受 Web 白名单限制),
9
+ * 写后 settings 服务自动广播 settings/document-updated(全环境转发事件)。
10
+ *
11
+ * 安全:POST 要求同源(Origin/Referer 与 Host 匹配);响应不带 CORS 头,
12
+ * 跨站 JS 无法读取;GET 只读无副作用。
13
+ * 密钥:describe({ redactSecrets: true }) 自动脱敏,写入方向与设置页一致。
14
+ */
15
+ import type { IncomingMessage } from 'node:http';
16
+ import type { WebRoute } from '@deepseek-ai/dsh-host-webserver';
17
+ import { type SettingsNamespace } from '@deepseek-ai/dsh-settings';
18
+ import type { SettingsPathOp } from '@deepseek-ai/dsh-settings';
19
+ import type { ConfigView, ConfigWriteBody } from './config-shared.js';
20
+ /** 命名空间(与 host 注册一致)。 */
21
+ export declare const CONFIG_NAMESPACE: SettingsNamespace;
22
+ export type { ConfigView, ConfigWriteBody } from './config-shared.js';
23
+ /** 路由依赖的 settings 服务窄接口(便于测试替身)。 */
24
+ export interface SettingsServiceLike {
25
+ readonly writable: boolean;
26
+ describe(options?: {
27
+ redactSecrets?: boolean;
28
+ }): ReadonlyArray<{
29
+ ns: SettingsNamespace;
30
+ value: unknown;
31
+ revision: number;
32
+ base?: unknown;
33
+ user?: unknown;
34
+ }>;
35
+ mutate(ns: SettingsNamespace, ops: readonly SettingsPathOp[], expectedRevision?: number): Promise<void>;
36
+ }
37
+ /** 路由注册的宿主(webServer 服务窄接口)。 */
38
+ export interface WebServerLike {
39
+ register(route: WebRoute): () => void;
40
+ }
41
+ /** 把 settings 描述符映射为 client 视图;命名空间缺失 → unavailable。 */
42
+ export declare function configViewOf(settings: SettingsServiceLike): ConfigView;
43
+ /** 校验并规范化写请求体;非法 → undefined。 */
44
+ export declare function parseConfigWriteBody(raw: unknown): ConfigWriteBody | undefined;
45
+ /**
46
+ * 同源校验:Origin/Referer 存在时必须与请求 Host 匹配。
47
+ * POST 无来源头一律拒绝(纵深防御;跨站表单/fetch 都会被 CORS 挡在读之外)。
48
+ */
49
+ export declare function sameOrigin(request: IncomingMessage, requireOrigin: boolean): boolean;
50
+ /**
51
+ * 挂载配置路由(webServer 服务可用时调用)。
52
+ * @returns 卸载函数。
53
+ */
54
+ export declare function mountConfigRoutes(webServer: WebServerLike, settings: SettingsServiceLike): () => void;
55
+ //# sourceMappingURL=config-route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-route.d.ts","sourceRoot":"","sources":["../src/config-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,WAAW,CAAA;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AACrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAErE,yBAAyB;AACzB,eAAO,MAAM,gBAAgB,mBAAgC,CAAA;AAE7D,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAErE,oCAAoC;AACpC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,aAAa,CAAC;QAC7D,EAAE,EAAE,iBAAiB,CAAA;QACrB,KAAK,EAAE,OAAO,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,CAAC,EAAE,OAAO,CAAA;QACd,IAAI,CAAC,EAAE,OAAO,CAAA;KACf,CAAC,CAAA;IACF,MAAM,CAAC,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,SAAS,cAAc,EAAE,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACxG;AAED,gCAAgC;AAChC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,IAAI,CAAA;CACtC;AAID,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,mBAAmB,GAAG,UAAU,CActE;AAED,iCAAiC;AACjC,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAwB9E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,GAAG,OAAO,CAWpF;AAiED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAsBrG"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * dsh-messager 配置路由(host 端):给浏览器提供不受 settings 白名单门控的
3
+ * 配置读写通道(webServer 服务,dsh-market 同款「正门」)。
4
+ *
5
+ * - GET /dsh-messager/config —— 返回 messager 命名空间的脱敏视图
6
+ * (value/user/base/writable/revision,与 client ScopeLike 快照同构);
7
+ * - POST /dsh-messager/config —— 接受逐字段 ops(与 client ScopeWriteOp 同构),
8
+ * 经 ctx.settings.mutate 落库(host 侧不受 Web 白名单限制),
9
+ * 写后 settings 服务自动广播 settings/document-updated(全环境转发事件)。
10
+ *
11
+ * 安全:POST 要求同源(Origin/Referer 与 Host 匹配);响应不带 CORS 头,
12
+ * 跨站 JS 无法读取;GET 只读无副作用。
13
+ * 密钥:describe({ redactSecrets: true }) 自动脱敏,写入方向与设置页一致。
14
+ */
15
+ import { settingsNamespace } from '@deepseek-ai/dsh-settings';
16
+ /** 命名空间(与 host 注册一致)。 */
17
+ export const CONFIG_NAMESPACE = settingsNamespace('messager');
18
+ // ---- 纯逻辑(可单测) ----
19
+ /** 把 settings 描述符映射为 client 视图;命名空间缺失 → unavailable。 */
20
+ export function configViewOf(settings) {
21
+ const descriptor = settings.describe({ redactSecrets: true }).find(candidate => candidate.ns === CONFIG_NAMESPACE);
22
+ if (descriptor === undefined) {
23
+ return { status: 'unavailable', value: undefined, user: undefined, base: undefined, writable: settings.writable, mode: 'host' };
24
+ }
25
+ return {
26
+ status: 'ready',
27
+ value: descriptor.value,
28
+ user: descriptor.user,
29
+ base: descriptor.base,
30
+ writable: settings.writable,
31
+ mode: 'host',
32
+ revision: descriptor.revision,
33
+ };
34
+ }
35
+ /** 校验并规范化写请求体;非法 → undefined。 */
36
+ export function parseConfigWriteBody(raw) {
37
+ if (typeof raw !== 'object' || raw === null)
38
+ return undefined;
39
+ const body = raw;
40
+ const ops = body.ops;
41
+ if (!Array.isArray(ops))
42
+ return undefined;
43
+ const normalized = [];
44
+ for (const entry of ops) {
45
+ if (typeof entry !== 'object' || entry === null)
46
+ continue;
47
+ const op = entry;
48
+ if (op.op !== 'set' && op.op !== 'unset')
49
+ return undefined;
50
+ if (!Array.isArray(op.path) || op.path.length === 0 || op.path.some(segment => typeof segment !== 'string' || segment === '')) {
51
+ return undefined;
52
+ }
53
+ if (op.op === 'set' && !('value' in op))
54
+ return undefined;
55
+ normalized.push({ op: op.op, path: op.path, ...(op.op === 'set' ? { value: op.value } : {}) });
56
+ }
57
+ if (normalized.length === 0)
58
+ return undefined;
59
+ const expectedRevision = body.expectedRevision;
60
+ return {
61
+ ops: normalized,
62
+ ...(typeof expectedRevision === 'number' && Number.isInteger(expectedRevision)
63
+ ? { expectedRevision }
64
+ : {}),
65
+ };
66
+ }
67
+ /**
68
+ * 同源校验:Origin/Referer 存在时必须与请求 Host 匹配。
69
+ * POST 无来源头一律拒绝(纵深防御;跨站表单/fetch 都会被 CORS 挡在读之外)。
70
+ */
71
+ export function sameOrigin(request, requireOrigin) {
72
+ const host = request.headers.host;
73
+ const origin = request.headers.origin ?? request.headers.referer;
74
+ if (origin === undefined)
75
+ return !requireOrigin;
76
+ if (host === undefined)
77
+ return false;
78
+ try {
79
+ const parsed = new URL(origin);
80
+ return parsed.host === host;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ // ---- HTTP 层 ----
87
+ function sendJson(res, status, value) {
88
+ const body = JSON.stringify(value);
89
+ res.writeHead(status, { 'content-type': 'application/json; charset=utf-8' });
90
+ res.end(body);
91
+ }
92
+ /** 读取请求体(限制大小,防滥用)。 */
93
+ function readBody(request, limit = 64 * 1024) {
94
+ return new Promise((resolve, reject) => {
95
+ const chunks = [];
96
+ let total = 0;
97
+ request.on('data', (chunk) => {
98
+ total += chunk.length;
99
+ if (total > limit) {
100
+ reject(new Error('payload too large'));
101
+ request.destroy();
102
+ return;
103
+ }
104
+ chunks.push(chunk);
105
+ });
106
+ request.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
107
+ request.on('error', reject);
108
+ });
109
+ }
110
+ function handleGet(settings, res) {
111
+ sendJson(res, 200, configViewOf(settings));
112
+ }
113
+ async function handlePost(settings, request, res) {
114
+ if (!sameOrigin(request, true)) {
115
+ sendJson(res, 403, { ok: false, error: 'untrusted origin' });
116
+ return;
117
+ }
118
+ let raw;
119
+ try {
120
+ raw = JSON.parse(await readBody(request));
121
+ }
122
+ catch {
123
+ sendJson(res, 400, { ok: false, error: 'invalid JSON body' });
124
+ return;
125
+ }
126
+ const body = parseConfigWriteBody(raw);
127
+ if (body === undefined) {
128
+ sendJson(res, 400, { ok: false, error: 'invalid ops' });
129
+ return;
130
+ }
131
+ try {
132
+ await settings.mutate(CONFIG_NAMESPACE, body.ops, body.expectedRevision);
133
+ sendJson(res, 200, { ok: true });
134
+ }
135
+ catch (error) {
136
+ sendJson(res, 409, {
137
+ ok: false,
138
+ error: error instanceof Error ? error.message : String(error),
139
+ });
140
+ }
141
+ }
142
+ /**
143
+ * 挂载配置路由(webServer 服务可用时调用)。
144
+ * @returns 卸载函数。
145
+ */
146
+ export function mountConfigRoutes(webServer, settings) {
147
+ const routes = [
148
+ {
149
+ kind: 'exact',
150
+ path: '/dsh-messager/config',
151
+ handler: (request, response) => {
152
+ if (request.method === 'GET') {
153
+ handleGet(settings, response);
154
+ return;
155
+ }
156
+ if (request.method === 'POST') {
157
+ return handlePost(settings, request, response);
158
+ }
159
+ response.writeHead(405, { allow: 'GET, POST' });
160
+ response.end();
161
+ },
162
+ },
163
+ ];
164
+ const disposers = routes.map(route => webServer.register(route));
165
+ return () => {
166
+ for (const dispose of disposers)
167
+ dispose();
168
+ };
169
+ }
170
+ //# sourceMappingURL=config-route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-route.js","sourceRoot":"","sources":["../src/config-route.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * 配置路由的跨端共享类型(host 与浏览器 client 共用,不得 import 任何
3
+ * Node/浏览器专属模块)。
4
+ */
5
+ /** 配置路由路径(挂在 DSH webServer 上,同源访问)。 */
6
+ export declare const CONFIG_PATH = "/dsh-messager/config";
7
+ /** client ScopeLike 快照同构的配置视图。 */
8
+ export interface ConfigView {
9
+ status: 'ready' | 'unavailable';
10
+ value: unknown;
11
+ user: unknown;
12
+ base: unknown;
13
+ writable: boolean;
14
+ mode: 'host';
15
+ revision?: number;
16
+ }
17
+ /** client ScopeWriteOp 同构的写操作。 */
18
+ export interface ConfigWriteOp {
19
+ op: 'set' | 'unset';
20
+ path: string[];
21
+ value?: unknown;
22
+ }
23
+ /** POST /dsh-messager/config 的请求体。 */
24
+ export interface ConfigWriteBody {
25
+ ops: ConfigWriteOp[];
26
+ expectedRevision?: number;
27
+ }
28
+ //# sourceMappingURL=config-shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-shared.d.ts","sourceRoot":"","sources":["../src/config-shared.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uCAAuC;AACvC,eAAO,MAAM,WAAW,yBAAyB,CAAA;AAEjD,kCAAkC;AAClC,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,GAAG,aAAa,CAAA;IAC/B,KAAK,EAAE,OAAO,CAAA;IACd,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,OAAO,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,kCAAkC;AAClC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,KAAK,GAAG,OAAO,CAAA;IACnB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,sCAAsC;AACtC,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,aAAa,EAAE,CAAA;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 配置路由的跨端共享类型(host 与浏览器 client 共用,不得 import 任何
3
+ * Node/浏览器专属模块)。
4
+ */
5
+ /** 配置路由路径(挂在 DSH webServer 上,同源访问)。 */
6
+ export const CONFIG_PATH = '/dsh-messager/config';
7
+ //# sourceMappingURL=config-shared.js.map