UNPKG

song-ui-u

Version:

vue3 + js的PC前端组件库

1 lines 20.6 kB
{"version":3,"file":"index.vue.cjs","sources":["../../../../../packages/components/upload/src/index.vue"],"sourcesContent":["<script setup>\r\nimport { ref, computed, watch } from \"vue\";\r\nimport * as SparkMD5 from \"spark-md5\";\r\nimport { XProgress, XMessage, XIcon, XImage } from \"@ui-library/components\";\r\nimport { useNamespace } from \"@ui-library/hook\";\r\nimport { Upload, Pause, Plus, X } from \"song-ui-pro-icon\";\r\n\r\ndefineOptions({\r\n name: \"x-upload\",\r\n});\r\n\r\nconst props = defineProps({\r\n // 切片大小\r\n chunkSize: {\r\n type: Number,\r\n default: 1,\r\n },\r\n // 文件验证地址\r\n verifyUrl: {\r\n type: String,\r\n default: \"\",\r\n },\r\n\r\n // 上传地址\r\n uploadUrl: {\r\n type: String,\r\n default: \"\",\r\n },\r\n\r\n // 合并地址\r\n mergeUrl: {\r\n type: String,\r\n default: \"\",\r\n },\r\n\r\n showProgress: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n formData: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n headers: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n // 手动上传\r\n manualUpload: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n\r\n // type\r\n type: {\r\n type: String,\r\n default: \"normal\", // image, imageList\r\n },\r\n imageSize: {\r\n type: String,\r\n default: \"130\",\r\n },\r\n\r\n // 是否开启秒传\r\n isVerify: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n});\r\n\r\nconst ns = useNamespace(\"upload\");\r\n\r\nconst file = ref(null);\r\n\r\nconst chunkSize = computed(() => {\r\n return props.chunkSize * 1024 * 1024;\r\n});\r\n\r\nconst imageList = defineModel(\"imageList\", {\r\n type: Array,\r\n default: () => [],\r\n});\r\n\r\nconst imgUrl = defineModel(\"imgUrl\", {\r\n type: String,\r\n default: \"\",\r\n});\r\n\r\nconst fileList = defineModel(\"fileList\", {\r\n type: Array,\r\n default: () => [],\r\n});\r\n\r\nconst fileUrl = defineModel(\"fileUrl\", {\r\n type: String,\r\n default: \"\",\r\n});\r\n\r\nconst uploadedChunks = ref([]); // 已上传的分片索引\r\nconst isPaused = ref(false);\r\nconst uploadProgress = ref(0);\r\nconst fileHash = ref(\"\"); // 文件的哈希值(唯一标识)\r\nlet currentChunkIndex = 0;\r\n\r\nconst emits = defineEmits([\r\n \"success\",\r\n \"error\",\r\n \"beforeUpload\",\r\n \"afterUpload\",\r\n \"changeFile\",\r\n // 暂停\r\n \"pause\",\r\n // 继续\r\n \"resume\",\r\n // delete图片\r\n \"delete\",\r\n]);\r\n\r\n// 验证文件是否已存在(秒传)\r\nconst verifyUpload = async (fileHash, fileName) => {\r\n if (!props.isVerify) {\r\n return { exists: false };\r\n }\r\n\r\n try {\r\n const response = await fetch(props.verifyUrl, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify({\r\n fileHash,\r\n fileName,\r\n }),\r\n });\r\n const result = await response.json();\r\n return result;\r\n } catch (error) {\r\n XMessage({\r\n content: \"验证失败\",\r\n type: \"warning\",\r\n });\r\n return { exists: false };\r\n }\r\n};\r\n\r\n// 处理文件选择\r\nconst handleFileChange = async (event, files) => {\r\n file.value = files || event.target.files[0];\r\n\r\n uploadedChunks.value = [];\r\n currentChunkIndex = 0;\r\n uploadProgress.value = 0;\r\n\r\n // 计算文件哈希值\r\n fileHash.value = await calculateFileHash(file.value);\r\n\r\n // 触发 changeFile 事件\r\n emits(\"changeFile\", { file: file.value, fileHash: fileHash.value });\r\n\r\n // 验证文件是否已存在\r\n const { exists } = await verifyUpload(fileHash.value, file.value.name);\r\n if (exists) {\r\n XMessage({\r\n content: \"文件已存在\",\r\n type: \"success\",\r\n });\r\n uploadProgress.value = 100;\r\n return;\r\n }\r\n if (!props.manualUpload) {\r\n startUpload();\r\n }\r\n};\r\n\r\n// 计算文件哈希值\r\nconst calculateFileHash = (file) => {\r\n return new Promise((resolve, reject) => {\r\n const spark = new SparkMD5.ArrayBuffer();\r\n const reader = new FileReader();\r\n const fileChunkSize = 1 * 1024 * 1024;\r\n let currentChunk = 0;\r\n const chunks = Math.ceil(file.size / fileChunkSize);\r\n\r\n const loadNextChunk = () => {\r\n const start = currentChunk * fileChunkSize;\r\n const end = Math.min(start + fileChunkSize, file.size);\r\n reader.readAsArrayBuffer(file.slice(start, end));\r\n };\r\n\r\n reader.onload = (e) => {\r\n spark.append(e.target.result);\r\n currentChunk++;\r\n if (currentChunk < chunks) {\r\n loadNextChunk();\r\n } else {\r\n resolve(spark.end());\r\n }\r\n };\r\n\r\n reader.onerror = () => reject(\"文件哈希值计算失败\");\r\n loadNextChunk();\r\n });\r\n};\r\n\r\n// 开始上传\r\nconst startUpload = async () => {\r\n emits(\"beforeUpload\");\r\n\r\n if (!file.value) {\r\n XMessage({\r\n content: \"请选择文件\",\r\n type: \"warning\",\r\n });\r\n return;\r\n }\r\n isPaused.value = false;\r\n\r\n await uploadFileInChunks();\r\n};\r\n\r\n// 暂停上传\r\nconst pauseUpload = () => {\r\n emits(\"pause\");\r\n isPaused.value = true;\r\n};\r\n\r\n// 继续上传\r\nconst resumeUpload = async () => {\r\n isPaused.value = false;\r\n emits(\"resume\");\r\n await uploadFileInChunks();\r\n};\r\n\r\n// 分片上传逻辑\r\nconst uploadFileInChunks = async () => {\r\n while (currentChunkIndex < Math.ceil(file.value.size / chunkSize.value)) {\r\n if (isPaused.value) {\r\n return;\r\n }\r\n\r\n if (uploadedChunks.value.includes(currentChunkIndex)) {\r\n currentChunkIndex++;\r\n continue;\r\n }\r\n\r\n const chunk = file.value.slice(\r\n currentChunkIndex * chunkSize.value,\r\n (currentChunkIndex + 1) * chunkSize.value\r\n );\r\n\r\n const formData = new FormData();\r\n formData.append(\"file\", chunk);\r\n formData.append(\"fileName\", file.value.name);\r\n formData.append(\"fileHash\", fileHash.value);\r\n formData.append(\"chunkIndex\", currentChunkIndex);\r\n formData.append(\r\n \"totalChunks\",\r\n Math.ceil(file.value.size / chunkSize.value)\r\n );\r\n\r\n props.formData &&\r\n Object.keys(props.formData).forEach((key) => {\r\n formData.append(key, props.formData[key]);\r\n });\r\n\r\n try {\r\n await fetch(props.uploadUrl, {\r\n method: \"POST\",\r\n body: formData,\r\n headers: props.headers,\r\n });\r\n\r\n uploadedChunks.value.push(currentChunkIndex);\r\n currentChunkIndex++;\r\n uploadProgress.value = (\r\n (uploadedChunks.value.length /\r\n Math.ceil(file.value.size / chunkSize.value)) *\r\n 100\r\n ).toFixed(2);\r\n } catch (error) {\r\n console.error(\"上传失败:\", error);\r\n emits(\"error\", error); // 添加错误事件\r\n break;\r\n }\r\n }\r\n\r\n if (\r\n uploadedChunks.value.length === Math.ceil(file.value.size / chunkSize.value)\r\n ) {\r\n XMessage({\r\n content: \"上传完成\",\r\n type: \"success\",\r\n });\r\n await mergeChunks();\r\n emits(\"afterUpload\"); // 添加上传完成事件\r\n }\r\n};\r\n\r\n// 合并分片\r\nconst mergeChunks = async () => {\r\n try {\r\n const response = await fetch(props.mergeUrl, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify({\r\n fileName: file.value.name,\r\n fileHash: fileHash.value,\r\n totalChunks: Math.ceil(file.value.size / chunkSize.value),\r\n }),\r\n });\r\n\r\n const result = await response.json();\r\n\r\n emits(\"success\", result); // 添加成功事件\r\n } catch (error) {\r\n console.error(\"文件合并失败:\", error);\r\n emits(\"error\", error); // 添加错误事件\r\n }\r\n};\r\n\r\n// const preImageList = computed(() => {\r\n// return imageList.value.map((item) => {\r\n// return item.url;\r\n// });\r\n// });\r\n\r\n// handleDelImg\r\nconst handleDelImg = (index) => {\r\n imageList.value.splice(index, 1);\r\n emits(\"delete\", index);\r\n};\r\n\r\nconst upload = (files) => {\r\n return handleFileChange(null, files);\r\n};\r\n\r\ndefineExpose({\r\n upload,\r\n});\r\n</script>\r\n\r\n<template>\r\n <div :class=\"[ns.b(), ns.is('image', type != 'normal')]\">\r\n <div :class=\"[ns.e('wrapper')]\">\r\n <div :class=\"ns.e('image')\" v-if=\"type !== 'normal'\">\r\n <XImage\r\n v-if=\"imgUrl && type == 'image'\"\r\n :src=\"imgUrl\"\r\n :preview=\"true\"\r\n />\r\n <div\r\n :class=\"ns.e('upload-image')\"\r\n :style=\"{\r\n height: imageSize + 'px',\r\n width: imageSize + 'px',\r\n }\"\r\n >\r\n <XIcon size=\"50\">\r\n <Plus />\r\n </XIcon>\r\n </div>\r\n </div>\r\n\r\n <x-button v-if=\"type == 'normal'\" :icon=\"Upload\" type=\"primary\"\r\n >选择文件</x-button\r\n >\r\n <input\r\n type=\"file\"\r\n :accept=\"type != 'normal' ? 'image/*' : ''\"\r\n @change=\"handleFileChange\"\r\n :class=\"ns.e('input')\"\r\n />\r\n <span v-if=\"type == 'normal'\" :class=\"ns.e('warp-text')\">{{\r\n file?.name\r\n }}</span>\r\n </div>\r\n <div :class=\"ns.e('control')\">\r\n <div :class=\"ns.e('button')\" v-if=\"file && type == 'normal'\">\r\n <x-button\r\n size=\"small\"\r\n v-if=\"manualUpload\"\r\n circle\r\n type=\"success\"\r\n @click=\"startUpload\"\r\n :icon=\"Upload\"\r\n ></x-button>\r\n <x-button\r\n size=\"small\"\r\n v-if=\"!isPaused\"\r\n circle\r\n type=\"warning\"\r\n @click=\"pauseUpload\"\r\n >\r\n <XIcon>\r\n <Pause />\r\n </XIcon>\r\n </x-button>\r\n <x-button\r\n size=\"small\"\r\n v-else\r\n @click=\"resumeUpload\"\r\n circle\r\n type=\"success\"\r\n >\r\n <XIcon>\r\n <svg\r\n t=\"1744352467807\"\r\n class=\"icon\"\r\n viewBox=\"0 0 1024 1024\"\r\n version=\"1.1\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n p-id=\"3031\"\r\n width=\"200\"\r\n height=\"200\"\r\n >\r\n <path\r\n d=\"M899.117 526.883a30.04 30.04 0 0 1-3.976 5.365 29.922 29.922 0 0 1-1.548 1.58l-0.2 0.186a30.087 30.087 0 0 1-5.472 4.057L165.858 955.094c-0.047 0.027-0.1 0.046-0.143 0.073q-1.155 0.659-2.37 1.214c-0.145 0.066-0.289 0.132-0.434 0.2q-1.084 0.476-2.212 0.864c-0.238 0.083-0.475 0.165-0.713 0.241-0.645 0.205-1.3 0.386-1.963 0.548-0.348 0.085-0.7 0.168-1.044 0.24-0.56 0.116-1.126 0.213-1.7 0.3q-1.416 0.21-2.833 0.283h-0.016a29.977 29.977 0 0 1-4.5-0.107c-0.243-0.024-0.483-0.057-0.723-0.086a30.513 30.513 0 0 1-2.109-0.331 31.377 31.377 0 0 1-1.021-0.222c-0.6-0.139-1.191-0.293-1.78-0.469-0.331-0.1-0.658-0.2-0.984-0.315q-0.921-0.309-1.82-0.676c-0.241-0.1-0.479-0.2-0.716-0.307q-1.047-0.461-2.055-1c-0.108-0.058-0.215-0.118-0.322-0.177a29.753 29.753 0 0 1-8.652-7.174l-0.071-0.089a29.873 29.873 0 0 1-1.59-2.124c-0.3-0.439-0.589-0.885-0.866-1.34-0.108-0.179-0.233-0.341-0.338-0.524a29.859 29.859 0 0 1-4-16V95.886a30 30 0 0 1 44.981-26.984l722.265 417a30 30 0 0 1 10.988 40.981zM180.89 877.13l632.327-365.2L180.89 146.856V877.13z\"\r\n fill=\"#ffffff\"\r\n p-id=\"3032\"\r\n ></path>\r\n </svg>\r\n </XIcon>\r\n </x-button>\r\n </div>\r\n\r\n <div\r\n v-if=\"imageList.length > 0 && type == 'imageList'\"\r\n :class=\"ns.e('imageList')\"\r\n >\r\n <div :class=\"ns.e('img')\" v-for=\"(item, index) in imageList\">\r\n <div :class=\"ns.e('del-img')\" @click.stop=\"handleDelImg(index)\">\r\n <XIcon>\r\n <X />\r\n </XIcon>\r\n </div>\r\n <XImage\r\n fit=\"cover\"\r\n :key=\"item.name\"\r\n :src=\"item.url\"\r\n :preview=\"true\"\r\n :width=\"props.imageSize\"\r\n :height=\"props.imageSize\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div :class=\"ns.e('progress')\" v-if=\"showProgress && type == 'normal'\">\r\n <XProgress\r\n v-if=\"showProgress\"\r\n :value=\"uploadProgress\"\r\n height=\"10\"\r\n ></XProgress>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n"],"names":["useNamespace","ref","computed","_useModel","XMessage","SparkMD5"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAc;AASX;AACH;AACA,MAAM,KAAK,GAAG,OAyDZ,CAAC;AACH;AACA,MAAM,EAAE,GAAGA,oBAAY,CAAC,QAAQ,CAAC,CAAC;AAClC;AACA,MAAM,IAAI,GAAGC,OAAG,CAAC,IAAI,CAAC,CAAC;AACvB;AACA,MAAM,SAAS,GAAGC,YAAQ,CAAC,MAAM;AACjC,EAAE,OAAO,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC;AACvC,CAAC,CAAC,CAAC;AACH;AACA,MAAM,SAAS,GAAGC,YAAW,CAAA,OAAA,EAAC,WAG7B,CAAC,CAAC;AACH;AACA,MAAM,MAAM,GAAGA,YAAW,CAAC,OAAA,EAAA,QAG1B,CAAC,CAAC;AACH;AACA,MAAM,QAAQ,GAAGA,YAAW,CAAA,OAAA,EAAC,UAG5B,CAAC,CAAC;AACH;AACA,MAAM,OAAO,GAAGA,YAAW,CAAA,OAAA,EAAC,SAG3B,CAAC,CAAC;AACH;AACA,MAAM,cAAc,GAAGF,OAAG,CAAC,EAAE,CAAC,CAAC;AAC/B,MAAM,QAAQ,GAAGA,OAAG,CAAC,KAAK,CAAC,CAAC;AAC5B,MAAM,cAAc,GAAGA,OAAG,CAAC,CAAC,CAAC,CAAC;AAC9B,MAAM,QAAQ,GAAGA,OAAG,CAAC,EAAE,CAAC,CAAC;AACzB,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAC1B;AACA,MAAM,KAAK,GAAG,MAYZ,CAAC;AACH;AACA;AACA,MAAM,YAAY,GAAG,OAAO,QAAQ,EAAE,QAAQ,KAAK;AACnD,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;AACvB,IAAI,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC7B,GAAG;AACH;AACA,EAAE,IAAI;AACN,IAAI,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE;AAClD,MAAM,MAAM,EAAE,MAAM;AACpB,MAAM,OAAO,EAAE;AACf,QAAQ,cAAc,EAAE,kBAAkB;AAC1C,OAAO;AACP,MAAM,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;AAC3B,QAAQ,QAAQ;AAChB,QAAQ,QAAQ;AAChB,OAAO,CAAC;AACR,KAAK,CAAC,CAAC;AACP,IAAI,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzC,IAAI,OAAO,MAAM,CAAC;AAClB,GAAG,CAAC,OAAO,KAAK,EAAE;AAClB,IAAIG,gBAAQ,CAAC;AACb,MAAM,OAAO,EAAE,MAAM;AACrB,MAAM,IAAI,EAAE,SAAS;AACrB,KAAK,CAAC,CAAC;AACP,IAAI,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC7B,GAAG;AACH,CAAC,CAAC;AACF;AACA;AACA,MAAM,gBAAgB,GAAG,OAAO,KAAK,EAAE,KAAK,KAAK;AACjD,EAAE,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9C;AACA,EAAE,cAAc,CAAC,KAAK,GAAG,EAAE,CAAC;AAC5B,EAAE,iBAAiB,GAAG,CAAC,CAAC;AACxB,EAAE,cAAc,CAAC,KAAK,GAAG,CAAC,CAAC;AAC3B;AACA;AACA,EAAE,QAAQ,CAAC,KAAK,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACvD;AACA;AACA,EAAE,KAAK,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;AACtE;AACA;AACA,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACzE,EAAE,IAAI,MAAM,EAAE;AACd,IAAIA,gBAAQ,CAAC;AACb,MAAM,OAAO,EAAE,OAAO;AACtB,MAAM,IAAI,EAAE,SAAS;AACrB,KAAK,CAAC,CAAC;AACP,IAAI,cAAc,CAAC,KAAK,GAAG,GAAG,CAAC;AAC/B,IAAI,OAAO;AACX,GAAG;AACH,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE;AAC3B,IAAI,WAAW,EAAE,CAAC;AAClB,GAAG;AACH,CAAC,CAAC;AACF;AACA;AACA,MAAM,iBAAiB,GAAG,CAAC,IAAI,KAAK;AACpC,EAAE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC1C,IAAI,MAAM,KAAK,GAAG,IAAIC,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAC7C,IAAI,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;AACpC,IAAI,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC1C,IAAI,IAAI,YAAY,GAAG,CAAC,CAAC;AACzB,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC,CAAC;AACxD;AACA,IAAI,MAAM,aAAa,GAAG,MAAM;AAChC,MAAM,MAAM,KAAK,GAAG,YAAY,GAAG,aAAa,CAAC;AACjD,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7D,MAAM,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;AACvD,KAAK,CAAC;AACN;AACA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK;AAC3B,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACpC,MAAM,YAAY,EAAE,CAAC;AACrB,MAAM,IAAI,YAAY,GAAG,MAAM,EAAE;AACjC,QAAQ,aAAa,EAAE,CAAC;AACxB,OAAO,MAAM;AACb,QAAQ,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7B,OAAO;AACP,KAAK,CAAC;AACN;AACA,IAAI,MAAM,CAAC,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;AAC/C,IAAI,aAAa,EAAE,CAAC;AACpB,GAAG,CAAC,CAAC;AACL,CAAC,CAAC;AACF;AACA;AACA,MAAM,WAAW,GAAG,YAAY;AAChC,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;AACxB;AACA,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACnB,IAAID,gBAAQ,CAAC;AACb,MAAM,OAAO,EAAE,OAAO;AACtB,MAAM,IAAI,EAAE,SAAS;AACrB,KAAK,CAAC,CAAC;AACP,IAAI,OAAO;AACX,GAAG;AACH,EAAE,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;AACzB;AACA,EAAE,MAAM,kBAAkB,EAAE,CAAC;AAC7B,CAAC,CAAC;AACF;AACA;AACA,MAAM,WAAW,GAAG,MAAM;AAC1B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;AACjB,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;AACxB,CAAC,CAAC;AACF;AACA;AACA,MAAM,YAAY,GAAG,YAAY;AACjC,EAAE,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;AACzB,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;AAClB,EAAE,MAAM,kBAAkB,EAAE,CAAC;AAC7B,CAAC,CAAC;AACF;AACA;AACA,MAAM,kBAAkB,GAAG,YAAY;AACvC,EAAE,OAAO,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE;AAC3E,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE;AACxB,MAAM,OAAO;AACb,KAAK;AACL;AACA,IAAI,IAAI,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;AAC1D,MAAM,iBAAiB,EAAE,CAAC;AAC1B,MAAM,SAAS;AACf,KAAK;AACL;AACA,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK;AAClC,MAAM,iBAAiB,GAAG,SAAS,CAAC,KAAK;AACzC,MAAM,CAAC,iBAAiB,GAAG,CAAC,IAAI,SAAS,CAAC,KAAK;AAC/C,KAAK,CAAC;AACN;AACA,IAAI,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;AACpC,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACnC,IAAI,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACjD,IAAI,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;AAChD,IAAI,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;AACrD,IAAI,QAAQ,CAAC,MAAM;AACnB,MAAM,aAAa;AACnB,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;AAClD,KAAK,CAAC;AACN;AACA,IAAI,KAAK,CAAC,QAAQ;AAClB,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK;AACnD,QAAQ,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAClD,OAAO,CAAC,CAAC;AACT;AACA,IAAI,IAAI;AACR,MAAM,MAAM,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE;AACnC,QAAQ,MAAM,EAAE,MAAM;AACtB,QAAQ,IAAI,EAAE,QAAQ;AACtB,QAAQ,OAAO,EAAE,KAAK,CAAC,OAAO;AAC9B,OAAO,CAAC,CAAC;AACT;AACA,MAAM,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AACnD,MAAM,iBAAiB,EAAE,CAAC;AAC1B,MAAM,cAAc,CAAC,KAAK,GAAG;AAC7B,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM;AACpC,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;AACtD,QAAQ,GAAG;AACX,QAAQ,OAAO,CAAC,CAAC,CAAC,CAAC;AACnB,KAAK,CAAC,OAAO,KAAK,EAAE;AACpB,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACpC,MAAM,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC5B,MAAM,MAAM;AACZ,KAAK;AACL,GAAG;AACH;AACA,EAAE;AACF,IAAI,cAAc,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;AAChF,IAAI;AACJ,IAAIA,gBAAQ,CAAC;AACb,MAAM,OAAO,EAAE,MAAM;AACrB,MAAM,IAAI,EAAE,SAAS;AACrB,KAAK,CAAC,CAAC;AACP,IAAI,MAAM,WAAW,EAAE,CAAC;AACxB,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;AACzB,GAAG;AACH,CAAC,CAAC;AACF;AACA;AACA,MAAM,WAAW,GAAG,YAAY;AAChC,EAAE,IAAI;AACN,IAAI,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE;AACjD,MAAM,MAAM,EAAE,MAAM;AACpB,MAAM,OAAO,EAAE;AACf,QAAQ,cAAc,EAAE,kBAAkB;AAC1C,OAAO;AACP,MAAM,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;AAC3B,QAAQ,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;AACjC,QAAQ,QAAQ,EAAE,QAAQ,CAAC,KAAK;AAChC,QAAQ,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC;AACjE,OAAO,CAAC;AACR,KAAK,CAAC,CAAC;AACP;AACA,IAAI,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzC;AACA,IAAI,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC7B,GAAG,CAAC,OAAO,KAAK,EAAE;AAClB,IAAI,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACpC,IAAI,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC1B,GAAG;AACH,CAAC,CAAC;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,YAAY,GAAG,CAAC,KAAK,KAAK;AAChC,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACnC,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AACzB,CAAC,CAAC;AACF;AACA,MAAM,MAAM,GAAG,CAAC,KAAK,KAAK;AAC1B,EAAE,OAAO,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC,CAAC;AACF;AACA,QAAY,CAAC;AACb,EAAE,MAAM;AACR,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}