pcm-agents 0.6.11 → 0.6.13
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.
- package/dist/cjs/error-event-J_ZWIqWF.js +33 -0
- package/dist/cjs/error-event-J_ZWIqWF.js.map +1 -0
- package/dist/cjs/{index-CvEfNyEj.js → index-CRlt8Nv6.js} +53 -3
- package/dist/cjs/index-CRlt8Nv6.js.map +1 -0
- package/dist/cjs/index-WNdOTXnX.js +11068 -0
- package/dist/cjs/index-WNdOTXnX.js.map +1 -0
- package/dist/cjs/index.cjs.js +2 -2
- package/dist/cjs/loader.cjs.js +3 -5
- package/dist/cjs/loader.cjs.js.map +1 -1
- package/dist/cjs/message.service-DGUsA-FY.js +135 -0
- package/dist/cjs/message.service-DGUsA-FY.js.map +1 -0
- package/dist/cjs/{pcm-1zhanshi-mnms-modal_17.cjs.entry.js → pcm-1zhanshi-mnms-modal_21.cjs.entry.js} +3276 -216
- package/dist/cjs/pcm-1zhanshi-mnms-modal_21.cjs.entry.js.map +1 -0
- package/dist/cjs/pcm-agents.cjs.js +4 -6
- package/dist/cjs/pcm-agents.cjs.js.map +1 -1
- package/dist/cjs/pcm-message.cjs.entry.js +3 -3
- package/dist/cjs/pcm-message.cjs.entry.js.map +1 -1
- package/dist/cjs/pcm-message.entry.cjs.js.map +1 -1
- package/dist/cjs/pcm-mnms-video-modal.cjs.entry.js +8 -8
- package/dist/cjs/pcm-mnms-video-modal.cjs.entry.js.map +1 -1
- package/dist/cjs/pcm-mnms-video-modal.entry.cjs.js.map +1 -1
- package/dist/cjs/pcm-mnms-zp-modal.cjs.entry.js +29 -86
- package/dist/cjs/pcm-mnms-zp-modal.cjs.entry.js.map +1 -1
- package/dist/cjs/pcm-mnms-zp-modal.entry.cjs.js.map +1 -1
- package/dist/cjs/{sentry-reporter-BWFtw_aT.js → sentry-reporter-tpI4WdkE.js} +12 -40
- package/dist/cjs/sentry-reporter-tpI4WdkE.js.map +1 -0
- package/dist/collection/collection-manifest.json +5 -1
- package/dist/collection/components/pcm-1zhanshi-mnms-modal/pcm-1zhanshi-mnms-modal.js.map +1 -1
- package/dist/collection/components/pcm-app-chat-modal/pcm-app-chat-modal.css +986 -986
- package/dist/collection/components/pcm-app-chat-modal/pcm-app-chat-modal.js +7 -9
- package/dist/collection/components/pcm-app-chat-modal/pcm-app-chat-modal.js.map +1 -1
- package/dist/collection/components/pcm-button/pcm-button.css +199 -199
- package/dist/collection/components/pcm-button/pcm-button.js +6 -6
- package/dist/collection/components/pcm-button/pcm-button.js.map +1 -1
- package/dist/collection/components/pcm-card/pcm-card.css +259 -259
- package/dist/collection/components/pcm-card/pcm-card.js +1 -1
- package/dist/collection/components/pcm-card/pcm-card.js.map +1 -1
- package/dist/collection/components/pcm-chat-message/pcm-chat-message.css +554 -554
- package/dist/collection/components/pcm-chat-message/pcm-chat-message.js +3 -3
- package/dist/collection/components/pcm-chat-message/pcm-chat-message.js.map +1 -1
- package/dist/collection/components/pcm-drawer/pcm-drawer.css +102 -102
- package/dist/collection/components/pcm-drawer/pcm-drawer.js +1 -1
- package/dist/collection/components/pcm-drawer/pcm-drawer.js.map +1 -1
- package/dist/collection/components/pcm-hr-chat-modal/pcm-hr-chat-modal.css +854 -854
- package/dist/collection/components/pcm-hr-chat-modal/pcm-hr-chat-modal.js +5 -7
- package/dist/collection/components/pcm-hr-chat-modal/pcm-hr-chat-modal.js.map +1 -1
- package/dist/collection/components/pcm-htws-modal/pcm-htws-modal.css +95 -95
- package/dist/collection/components/pcm-htws-modal/pcm-htws-modal.js +1 -1
- package/dist/collection/components/pcm-htws-modal/pcm-htws-modal.js.map +1 -1
- package/dist/collection/components/pcm-hyzj-modal/pcm-hyzj-modal.js +2 -2
- package/dist/collection/components/pcm-hyzj-modal/pcm-hyzj-modal.js.map +1 -1
- package/dist/collection/components/pcm-jd-modal/pcm-jd-modal.css +312 -312
- package/dist/collection/components/pcm-jd-modal/pcm-jd-modal.js +1 -1
- package/dist/collection/components/pcm-jd-modal/pcm-jd-modal.js.map +1 -1
- package/dist/collection/components/pcm-jlpp-modal/pcm-jlpp-modal.js +2 -2
- package/dist/collection/components/pcm-jlpp-modal/pcm-jlpp-modal.js.map +1 -1
- package/dist/collection/components/pcm-message/pcm-message.css +64 -64
- package/dist/collection/components/pcm-message/pcm-message.js +2 -2
- package/dist/collection/components/pcm-message/pcm-message.js.map +1 -1
- package/dist/collection/components/pcm-mnct-modal/pcm-mnct-modal.css +1 -1
- package/dist/collection/components/pcm-mnct-modal/pcm-mnct-modal.js +2 -2
- package/dist/collection/components/pcm-mnct-modal/pcm-mnct-modal.js.map +1 -1
- package/dist/collection/components/pcm-mnms-modal/pcm-mnms-modal.js +67 -84
- package/dist/collection/components/pcm-mnms-modal/pcm-mnms-modal.js.map +1 -1
- package/dist/collection/components/pcm-mnms-video-modal/pcm-mnms-video-modal.js +2 -2
- package/dist/collection/components/pcm-mnms-video-modal/pcm-mnms-video-modal.js.map +1 -1
- package/dist/collection/components/pcm-mnms-zp-modal/pcm-mnms-zp-modal.js +67 -84
- package/dist/collection/components/pcm-mnms-zp-modal/pcm-mnms-zp-modal.js.map +1 -1
- package/dist/collection/components/pcm-mobile-input-btn/pcm-mobile-input-btn.css +140 -0
- package/dist/collection/components/pcm-mobile-input-btn/pcm-mobile-input-btn.js +307 -0
- package/dist/collection/components/pcm-mobile-input-btn/pcm-mobile-input-btn.js.map +1 -0
- package/dist/collection/components/pcm-mobile-input-btn/uploadNumberSDK.js +25 -0
- package/dist/collection/components/pcm-mobile-input-btn/uploadNumberSDK.js.map +1 -0
- package/dist/collection/components/pcm-mobile-upload-btn/pcm-mobile-upload-btn.css +127 -0
- package/dist/collection/components/pcm-mobile-upload-btn/pcm-mobile-upload-btn.js +350 -0
- package/dist/collection/components/pcm-mobile-upload-btn/pcm-mobile-upload-btn.js.map +1 -0
- package/dist/collection/components/pcm-mobile-upload-btn/uploadNumberSDK.js +25 -0
- package/dist/collection/components/pcm-mobile-upload-btn/uploadNumberSDK.js.map +1 -0
- package/dist/collection/components/pcm-msbg-modal/pcm-msbg-modal.js +2 -2
- package/dist/collection/components/pcm-msbg-modal/pcm-msbg-modal.js.map +1 -1
- package/dist/collection/components/pcm-qgqjl-modal/pcm-qgqjl-modal.css +1 -1
- package/dist/collection/components/pcm-qgqjl-modal/pcm-qgqjl-modal.js +2 -2
- package/dist/collection/components/pcm-qgqjl-modal/pcm-qgqjl-modal.js.map +1 -1
- package/dist/collection/components/pcm-time-count-down/pcm-time-count-down.css +0 -0
- package/dist/collection/components/pcm-time-count-down/pcm-time-count-down.js +106 -0
- package/dist/collection/components/pcm-time-count-down/pcm-time-count-down.js.map +1 -0
- package/dist/collection/components/pcm-upload/pcm-upload.css +0 -0
- package/dist/collection/components/pcm-upload/pcm-upload.js +408 -0
- package/dist/collection/components/pcm-upload/pcm-upload.js.map +1 -0
- package/dist/collection/components/pcm-zsk-chat-modal/pcm-zsk-chat-modal.css +969 -969
- package/dist/collection/components/pcm-zsk-chat-modal/pcm-zsk-chat-modal.js +3 -5
- package/dist/collection/components/pcm-zsk-chat-modal/pcm-zsk-chat-modal.js.map +1 -1
- package/dist/collection/components/pcm-zygh-modal/pcm-zygh-modal.css +68 -68
- package/dist/collection/components/pcm-zygh-modal/pcm-zygh-modal.js +4 -4
- package/dist/collection/components/pcm-zygh-modal/pcm-zygh-modal.js.map +1 -1
- package/dist/collection/global/global.css +401 -398
- package/dist/collection/global/markdown.css +1233 -1233
- package/dist/collection/global/message.js.map +1 -1
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/interfaces/chat.js.map +1 -1
- package/dist/collection/interfaces/events.js.map +1 -1
- package/dist/collection/services/message.service.js.map +1 -1
- package/dist/collection/utils/env.js +3 -0
- package/dist/collection/utils/env.js.map +1 -1
- package/dist/collection/utils/error-event.js.map +1 -1
- package/dist/collection/utils/init.js.map +1 -1
- package/dist/collection/utils/sentry-reporter.js.map +1 -1
- package/dist/collection/utils/utils.js +48 -24
- package/dist/collection/utils/utils.js.map +1 -1
- package/dist/components/index.js +3 -5482
- package/dist/components/index.js.map +1 -1
- package/dist/components/{p-AYWZDCn8.js → p-B0WOTw9J.js} +51 -4
- package/dist/components/p-B0WOTw9J.js.map +1 -0
- package/dist/components/{p-DUQ46MUh.js → p-BGXbWUJg.js} +3 -3
- package/dist/components/{p-DUQ46MUh.js.map → p-BGXbWUJg.js.map} +1 -1
- package/dist/{esm/sentry-reporter-BFBS363a.js → components/p-BW3r6Lrf.js} +5 -32
- package/dist/components/p-BW3r6Lrf.js.map +1 -0
- package/dist/{esm/app-globals-Chti62re.js → components/p-BdiUKin5.js} +9619 -4296
- package/dist/components/p-BdiUKin5.js.map +1 -0
- package/dist/components/{p-FjtoYPVY.js → p-BywzltXy.js} +10 -9
- package/dist/components/p-BywzltXy.js.map +1 -0
- package/dist/components/p-C2OsjtRx.js +208 -0
- package/dist/components/p-C2OsjtRx.js.map +1 -0
- package/dist/components/{p-D2Z8casl.js → p-CuIvbaWY.js} +5 -5
- package/dist/components/p-CuIvbaWY.js.map +1 -0
- package/dist/components/p-D0ZMoyH8.js +251 -0
- package/dist/components/p-D0ZMoyH8.js.map +1 -0
- package/dist/components/{p-CjbFHLT7.js → p-De3VHEUn.js} +7 -71
- package/dist/components/p-De3VHEUn.js.map +1 -0
- package/dist/components/p-Dv8qvK0w.js +2646 -0
- package/dist/components/p-Dv8qvK0w.js.map +1 -0
- package/dist/components/p-RD3mwuBX.js +226 -0
- package/dist/components/p-RD3mwuBX.js.map +1 -0
- package/dist/components/p-njngFX_n.js +80 -0
- package/dist/components/p-njngFX_n.js.map +1 -0
- package/dist/components/pcm-1zhanshi-mnms-modal.js +7 -7
- package/dist/components/pcm-1zhanshi-mnms-modal.js.map +1 -1
- package/dist/components/pcm-app-chat-modal.js +1 -1
- package/dist/components/pcm-button.js +2 -2
- package/dist/components/pcm-button.js.map +1 -1
- package/dist/components/pcm-card.js +3 -3
- package/dist/components/pcm-card.js.map +1 -1
- package/dist/components/pcm-chat-message.js +1 -1
- package/dist/components/pcm-drawer.js +1 -1
- package/dist/components/pcm-hr-chat-modal.js +5 -4
- package/dist/components/pcm-hr-chat-modal.js.map +1 -1
- package/dist/components/pcm-htws-modal.js +8 -7
- package/dist/components/pcm-htws-modal.js.map +1 -1
- package/dist/components/pcm-hyzj-modal.js +8 -7
- package/dist/components/pcm-hyzj-modal.js.map +1 -1
- package/dist/components/pcm-jd-modal.js +8 -7
- package/dist/components/pcm-jd-modal.js.map +1 -1
- package/dist/components/pcm-jlpp-modal.js +8 -7
- package/dist/components/pcm-jlpp-modal.js.map +1 -1
- package/dist/components/pcm-message.js +3 -3
- package/dist/components/pcm-message.js.map +1 -1
- package/dist/components/pcm-mnct-modal.js +8 -7
- package/dist/components/pcm-mnct-modal.js.map +1 -1
- package/dist/components/pcm-mnms-modal.js +60 -90
- package/dist/components/pcm-mnms-modal.js.map +1 -1
- package/dist/components/pcm-mnms-video-modal.js +8 -7
- package/dist/components/pcm-mnms-video-modal.js.map +1 -1
- package/dist/components/pcm-mnms-zp-modal.js +60 -90
- package/dist/components/pcm-mnms-zp-modal.js.map +1 -1
- package/dist/components/pcm-mobile-input-btn.d.ts +11 -0
- package/dist/components/pcm-mobile-input-btn.js +9 -0
- package/dist/components/pcm-mobile-input-btn.js.map +1 -0
- package/dist/components/pcm-mobile-upload-btn.d.ts +11 -0
- package/dist/components/pcm-mobile-upload-btn.js +9 -0
- package/dist/components/pcm-mobile-upload-btn.js.map +1 -0
- package/dist/components/pcm-msbg-modal.js +8 -7
- package/dist/components/pcm-msbg-modal.js.map +1 -1
- package/dist/components/pcm-qgqjl-modal.js +8 -7
- package/dist/components/pcm-qgqjl-modal.js.map +1 -1
- package/dist/components/pcm-time-count-down.d.ts +11 -0
- package/dist/components/pcm-time-count-down.js +9 -0
- package/dist/components/pcm-time-count-down.js.map +1 -0
- package/dist/components/pcm-upload.d.ts +11 -0
- package/dist/components/pcm-upload.js +9 -0
- package/dist/components/pcm-upload.js.map +1 -0
- package/dist/components/pcm-zsk-chat-modal.js +4 -4
- package/dist/components/pcm-zsk-chat-modal.js.map +1 -1
- package/dist/components/pcm-zygh-modal.js +8 -7
- package/dist/components/pcm-zygh-modal.js.map +1 -1
- package/dist/esm/error-event-C0FYX2-Z.js +31 -0
- package/dist/esm/error-event-C0FYX2-Z.js.map +1 -0
- package/dist/esm/{index-GyOE8SlD.js → index-BnNqOUZf.js} +51 -4
- package/dist/esm/index-BnNqOUZf.js.map +1 -0
- package/dist/esm/index-BuVfV0zo.js +11035 -0
- package/dist/esm/index-BuVfV0zo.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/loader.js +3 -5
- package/dist/esm/loader.js.map +1 -1
- package/dist/esm/message.service-DXVhHj6-.js +133 -0
- package/dist/esm/message.service-DXVhHj6-.js.map +1 -0
- package/dist/esm/{pcm-1zhanshi-mnms-modal_17.entry.js → pcm-1zhanshi-mnms-modal_21.entry.js} +3225 -169
- package/dist/esm/pcm-1zhanshi-mnms-modal_21.entry.js.map +1 -0
- package/dist/esm/pcm-agents.js +4 -6
- package/dist/esm/pcm-agents.js.map +1 -1
- package/dist/esm/pcm-message.entry.js +3 -3
- package/dist/esm/pcm-message.entry.js.map +1 -1
- package/dist/esm/pcm-mnms-video-modal.entry.js +5 -5
- package/dist/esm/pcm-mnms-video-modal.entry.js.map +1 -1
- package/dist/esm/pcm-mnms-zp-modal.entry.js +28 -85
- package/dist/esm/pcm-mnms-zp-modal.entry.js.map +1 -1
- package/dist/esm/sentry-reporter-CYzy4_8O.js +70 -0
- package/dist/esm/sentry-reporter-CYzy4_8O.js.map +1 -0
- package/dist/pcm-agents/index.esm.js +1 -1
- package/dist/pcm-agents/loader.esm.js.map +1 -1
- package/dist/pcm-agents/p-18a06873.entry.js +2 -0
- package/dist/pcm-agents/p-18a06873.entry.js.map +1 -0
- package/dist/pcm-agents/p-47e2e1d0.entry.js +2 -0
- package/dist/pcm-agents/p-47e2e1d0.entry.js.map +1 -0
- package/dist/pcm-agents/{p-3608c0c6.entry.js → p-7a582f00.entry.js} +2 -2
- package/dist/pcm-agents/p-7a582f00.entry.js.map +1 -0
- package/dist/pcm-agents/p-BhFnI70g.js +2 -0
- package/dist/pcm-agents/p-BhFnI70g.js.map +1 -0
- package/dist/pcm-agents/p-BuVfV0zo.js +3 -0
- package/dist/pcm-agents/p-BuVfV0zo.js.map +1 -0
- package/dist/pcm-agents/p-C0FYX2-Z.js +2 -0
- package/dist/pcm-agents/p-C0FYX2-Z.js.map +1 -0
- package/dist/pcm-agents/p-DXVhHj6-.js +2 -0
- package/dist/pcm-agents/p-DXVhHj6-.js.map +1 -0
- package/dist/pcm-agents/p-DkeaAFic.js +2 -0
- package/dist/pcm-agents/p-DkeaAFic.js.map +1 -0
- package/dist/pcm-agents/p-f5f96853.entry.js +245 -0
- package/dist/pcm-agents/p-f5f96853.entry.js.map +1 -0
- package/dist/pcm-agents/pcm-agents.esm.js +1 -1
- package/dist/pcm-agents/pcm-agents.esm.js.map +1 -1
- package/dist/pcm-agents/pcm-message.entry.esm.js.map +1 -1
- package/dist/pcm-agents/pcm-mnms-video-modal.entry.esm.js.map +1 -1
- package/dist/pcm-agents/pcm-mnms-zp-modal.entry.esm.js.map +1 -1
- package/dist/store/auth.store.js.map +1 -1
- package/dist/store/config.store.js.map +1 -1
- package/dist/types/components/pcm-mnms-modal/pcm-mnms-modal.d.ts +9 -4
- package/dist/types/components/pcm-mnms-zp-modal/pcm-mnms-zp-modal.d.ts +9 -4
- package/dist/types/components/pcm-mobile-input-btn/pcm-mobile-input-btn.d.ts +36 -0
- package/dist/types/components/pcm-mobile-input-btn/uploadNumberSDK.d.ts +9 -0
- package/dist/types/components/pcm-mobile-upload-btn/pcm-mobile-upload-btn.d.ts +44 -0
- package/dist/types/components/pcm-mobile-upload-btn/uploadNumberSDK.d.ts +9 -0
- package/dist/types/components/pcm-time-count-down/pcm-time-count-down.d.ts +15 -0
- package/dist/types/components/pcm-upload/pcm-upload.d.ts +54 -0
- package/dist/types/components/pcm-upload/type.d.ts +4 -0
- package/dist/types/components.d.ts +798 -30
- package/dist/types/stencil-public-runtime.d.ts +1 -1
- package/dist/types/utils/env.d.ts +2 -0
- package/dist/types/utils/utils.d.ts +30 -12
- package/package.json +70 -69
- package/dist/cjs/app-globals-BIO4q6tX.js +0 -5487
- package/dist/cjs/app-globals-BIO4q6tX.js.map +0 -1
- package/dist/cjs/exports-Dc-pQh4A.js +0 -4087
- package/dist/cjs/exports-Dc-pQh4A.js.map +0 -1
- package/dist/cjs/index-C_qhED9Z.js +0 -1538
- package/dist/cjs/index-C_qhED9Z.js.map +0 -1
- package/dist/cjs/index-CvEfNyEj.js.map +0 -1
- package/dist/cjs/pcm-1zhanshi-mnms-modal_17.cjs.entry.js.map +0 -1
- package/dist/cjs/sentry-reporter-BWFtw_aT.js.map +0 -1
- package/dist/components/p-75J0r72D.js +0 -4017
- package/dist/components/p-75J0r72D.js.map +0 -1
- package/dist/components/p-AYWZDCn8.js.map +0 -1
- package/dist/components/p-CR7WLzmM.js +0 -1303
- package/dist/components/p-CR7WLzmM.js.map +0 -1
- package/dist/components/p-CjbFHLT7.js.map +0 -1
- package/dist/components/p-D2Z8casl.js.map +0 -1
- package/dist/components/p-FjtoYPVY.js.map +0 -1
- package/dist/esm/app-globals-Chti62re.js.map +0 -1
- package/dist/esm/exports-Bs-zO1WZ.js +0 -4017
- package/dist/esm/exports-Bs-zO1WZ.js.map +0 -1
- package/dist/esm/index-Bq0K-WqZ.js +0 -1528
- package/dist/esm/index-Bq0K-WqZ.js.map +0 -1
- package/dist/esm/index-GyOE8SlD.js.map +0 -1
- package/dist/esm/pcm-1zhanshi-mnms-modal_17.entry.js.map +0 -1
- package/dist/esm/sentry-reporter-BFBS363a.js.map +0 -1
- package/dist/pcm-agents/p-2Gpw8rvH.js +0 -2
- package/dist/pcm-agents/p-2Gpw8rvH.js.map +0 -1
- package/dist/pcm-agents/p-3608c0c6.entry.js.map +0 -1
- package/dist/pcm-agents/p-60d7a0b0.entry.js +0 -2
- package/dist/pcm-agents/p-60d7a0b0.entry.js.map +0 -1
- package/dist/pcm-agents/p-9e6efc2d.entry.js +0 -2
- package/dist/pcm-agents/p-9e6efc2d.entry.js.map +0 -1
- package/dist/pcm-agents/p-BUV0S8Cc.js +0 -2
- package/dist/pcm-agents/p-BUV0S8Cc.js.map +0 -1
- package/dist/pcm-agents/p-Bq0K-WqZ.js +0 -3
- package/dist/pcm-agents/p-Bq0K-WqZ.js.map +0 -1
- package/dist/pcm-agents/p-Bs-zO1WZ.js +0 -2
- package/dist/pcm-agents/p-Bs-zO1WZ.js.map +0 -1
- package/dist/pcm-agents/p-CeRTfvY9.js +0 -2
- package/dist/pcm-agents/p-CeRTfvY9.js.map +0 -1
- package/dist/pcm-agents/p-e6c87a78.entry.js +0 -2
- package/dist/pcm-agents/p-e6c87a78.entry.js.map +0 -1
- /package/dist/types/{code/agents-sdk → Users/debugksir/Documents/pcm/sdk}/packages/pcm-agents/.stencil/store/auth.store.d.ts +0 -0
- /package/dist/types/{code/agents-sdk → Users/debugksir/Documents/pcm/sdk}/packages/pcm-agents/.stencil/store/config.store.d.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["pcm1zhanshiMnmsModalCss","globalCss","ZhanshiMnmsModal","modalTitle","token","isOpen","modalClosed","icon","zIndex","isShowHeader","isNeedClose","conversationId","defaultQuery","maxRecordingTime","fullscreen","customInputs","uploadSuccess","streamComplete","conversationStart","interviewComplete","tokenInvalid","someErrorEvent","recordingError","selectedFile","isUploading","uploadedFileInfo","showChatModal","jobDescription","isSubmitting","tokenInvalidListener","removeErrorListener","handleTokenChange","newToken","authStore","getToken","setToken","componentWillLoad","this","configStore","setItem","emit","ErrorEventBus","addErrorListener","errorDetail","document","addEventListener","disconnectedCallback","removeEventListener","handleClose","handleIsOpenChange","newValue","verifyApiKey","render","modalStyle","String","containerClass","overlayClass","isLoading","h","class","style","src","alt","onClick","botId","enableTTS","file_url","cos_key","file_name","interviewMode","_getDefaults","async","breaks","extensions","gfm","hooks","pedantic","renderer","silent","tokenizer","walkTokens","_defaults","changeDefaults","newDefaults","escapeTest","escapeReplace","RegExp","source","escapeTestNoEncode","escapeReplaceNoEncode","escapeReplacements","getEscapeReplacement","ch","escape","html","encode","test","replace","unescapeTest","unescape","_","n","toLowerCase","charAt","fromCharCode","parseInt","substring","caret","edit","regex","opt","obj","name","val","getRegex","cleanUrl","href","encodeURI","e","noopTest","exec","splitCells","tableRow","count","row","match","offset","str","escaped","curr","cells","split","i","trim","shift","length","pop","splice","push","rtrim","c","invert","l","suffLen","currChar","slice","findClosingBracket","b","indexOf","level","outputLink","cap","link","raw","lexer","title","text","state","inLink","type","tokens","inlineTokens","indentCodeCompensation","matchIndentToCode","indentToCode","map","node","matchIndentInNode","indentInNode","join","_Tokenizer","options","rules","constructor","space","block","newline","code","codeBlockStyle","fences","lang","inline","_escapes","heading","trimmed","depth","hr","blockquote","top","blockTokens","list","bull","isordered","ordered","start","loose","items","itemRegex","itemContents","endsWithBlankLine","endEarly","line","t","repeat","nextLine","indent","trimStart","search","blankLine","nextBulletRegex","Math","min","hrRegex","fencesBeginRegex","headingBeginRegex","rawLine","istask","ischecked","task","checked","trimEnd","spacers","filter","hasMultipleLineBreaks","some","pre","def","tag","table","item","header","align","rows","j","k","lheading","paragraph","inRawBlock","trimmedUrl","rtrimSlash","lastParenIndex","linkLen","reflink","links","nolink","emStrong","maskedSrc","prevChar","lDelim","nextChar","punctuation","lLength","rDelim","rLength","delimTotal","midDelimTotal","endReg","rDelimAst","rDelimUnd","lastIndex","lastCharLength","index","codespan","hasNonSpaceChars","hasSpaceCharsOnBothEnds","br","del","autolink","url","prevCapZero","_backpedal","inlineText","_paragraph","_label","_title","bullet","listItemStart","_tag","_comment","normal","reflinkSearch","_punctuation","blockSkip","anyPunctuation","_scheme","_email","_attribute","_href","strong","middle","endAst","endUnd","em","_extended_email","_Lexer","inlineQueue","Object","create","lex","lexInline","next","leading","tabs","lastToken","cutSrc","lastParagraphClipped","extTokenizer","call","startBlock","startIndex","Infinity","tempSrc","tempStart","forEach","getStartIndex","errMsg","charCodeAt","console","error","Error","keepPrevChar","keys","includes","lastIndexOf","startInline","_Renderer","infostring","quote","body","startatt","listitem","checkbox","tablerow","content","tablecell","flags","cleanHref","out","image","_TextRenderer","_Parser","textRenderer","parse","parser","parseInline","renderers","genericToken","ret","headingToken","codeToken","tableToken","cell","blockquoteToken","listToken","itemBody","unshift","htmlToken","paragraphToken","textToken","escapeToken","tagToken","linkToken","imageToken","strongToken","emToken","codespanToken","delToken","_Hooks","static","Set","preprocess","markdown","postprocess","Marked","defaults","setOptions","parseMarkdown","Parser","Renderer","TextRenderer","Lexer","Tokenizer","Hooks","args","use","callback","values","concat","childTokens","pack","opts","ext","prevRenderer","apply","extLevel","prop","rendererFunc","rendererKey","tokenizerFunc","tokenizerKey","prevTokenizer","hooksFunc","hooksKey","prevHook","passThroughHooks","has","arg","Promise","resolve","then","packWalktokens","origOpt","warn","throwError","onError","prototype","toString","all","catch","message","msg","reject","markedInstance","marked","getDefaults","pcmAppChatModalCss","markdownCss","pcmButtonCss","PcmButton","size","loading","disabled","shape","backgroundColor","textColor","borderColor","borderRadius","width","borderStyle","classes","customStyle","key","pcmCardCss","interruptPatterns","skipEmptyRows","regexString","widthRegex","colCount","reduce","colspan","col","output","getTableCell","emptyRow","rowspan","prevRow","matchAll","x","numCols","trimmedCell","prevCell","prevCols","max","rowSpanTarget","lib","pcmChatMessageCss","pcmDrawerCss","PcmDrawer","drawerTitle","height","closable","maskClosable","mask","closed","afterOpen","afterClose","bodyOverflowBeforeOpen","transitionEndHandler","open","close","visibleChanged","overflow","drawer","hostElement","shadowRoot","querySelector","once","cachedZIndex","getItem","handleMaskClick","drawerStyle","maskStyle","viewBox","focusable","fill","d","pcmHrChatModalCss","pcmHtwsModalCss","HtwsModal","showWorkspaceHistory","filePreviewMode","inputMode","freeInputText","handleFileChange","event","input","target","files","handleUploadClick","fileInput","click","clearSelectedFile","value","uploadFile","result","uploadFileToBackend","tags","SentryReporter","captureError","action","component","emitError","handleToggleInput","handleFreeInputChange","textarea","handleStartInterview","alert","stroke","stopPropagation","id","placeholder","onInput","rel","onChange","enableVoice","undefined","pcmHyzjModalCss","HyzjModal","hideFileUpload","Boolean","pcmJdModalCss","PcmJdModal","step","jobName","tagGroups","shuffledTagGroups","selectedAITags","selectedTags","salary","benefits","education","salaryRanges","educationRequirements","handleJobNameChange","handleNextStep","handlePositionAnalysis","handlePrevStep","response","sendHttpRequest","method","data","inputs","input_info","workflow_code","success","outputs","parsedOutput","JSON","tagGroup","initialSelectedTags","shuffled","group","allTags","defaultTags","optionalTags","floor","random","dimensionName","handleTagClick","category","currentTags","newTags","handleAITagClick","handleSubmitStructured","salaryRange","range","find","r","selectedBenefits","edu","jobInfo","entries","dimension","handleSubmitFree","job_info","renderTagGroup","option","isSelected","renderAITagGroups","renderLoadingState","htmlFor","pcmJlppModalCss","JlppModal","handleJobDescriptionChange","handleStartAnalysis","hideJdInput","hideResumeUpload","hasFileAndJob","pcmMnctModalCss","MnctModal","pcmMnmsModalCss","MnmsModal","mobileJdInputAble","mobileUploadAble","showCopyButton","showFeedbackButtons","resume_content","pcmUploadRef","getIsUploading","Message","info","onOk","detail","ref","el","maxFileSize","multiple","labelText","acceptFileSuffixList","uploadParams","onUploadChange","VALUES_TO_CHARSET","Map","Charset","label","freeze","Number","isInteger","set","toBit","toInt32","getBitMask","getBitOffset","findMSBSet","clz32","calculateBCHCode","poly","msbSetInPoly","VALUES_TO_MODE","Mode","bits","characterCountBitsSet","Int32Array","getCharacterCountBits","version","N1","N2","N3","N4","isDark","matrix","y","get","applyMaskPenaltyRule1Internal","isVertical","penalty","prevBit","numSameBitCells","bit","applyMaskPenaltyRule1","applyMaskPenaltyRule2","isFourWhite","from","to","applyMaskPenaltyRule3","numPenalties","applyMaskPenaltyRule4","numDarkCells","numTotalCells","fivePercentVariances","abs","calculateMaskPenalty","isApplyMask","temporary","intermediate","VALUES_TO_ECLEVEL","ECLevel","ECB","numDataCodewords","ECBlocks","ecBlocks","numTotalCodewords","numTotalECCodewords","numTotalDataCodewords","numECCodewordsPerBlock","numBlocks","Version","alignmentPatterns","getECBlocks","VERSIONS","Polynomial","field","coefficients","firstNonZero","array","subarray","isZero","getDegree","getCoefficient","degree","evaluate","a","coefficient","multiply","other","zero","otherCoefficients","otherLength","product","multiplyByMonomial","addOrSubtract","largerCoefficients","largerLength","smallerCoefficients","smallerLength","divide","quotient","remainder","denominatorLeadingTerm","invertDenominatorLeadingTerm","remainderDegree","degreeDiff","scale","term","iterationQuotient","buildPolynomial","GaloisField","one","generator","expTable","logTable","primitive","exp","log","QR_CODE_FIELD_256","getUnicodeCodes","maxCode","bytes","character","codePointAt","Uint8Array","charset","ASCII","ISO_8859_1","UTF_8","TextEncoder","LOAD_FACTOR","makeArray","ceil","BitArray","alloc","byteLength","xor","maskBits","append","writeToUint8Array","bitOffset","byteOffset","byte","clear","ByteMatrix","Int8Array","FORMAT_INFO_POLY","FORMAT_INFO_MASK","VERSION_INFO_POLY","FINDER_PATTERN_SHAPE","ALIGNMENT_PATTERN_SHAPE","FORMAT_INFO_COORDINATES","isEmpty","embedFinderPattern","pattern","embedHorizontalSeparator","embedVerticalSeparator","embedFinderPatternsAndSeparators","pdpWidth","hspWidth","vspHeight","embedTimingPatterns","embedAlignmentPattern","embedAlignmentPatterns","embedDarkModule","makeFormatInfoBits","ecLevel","formatInfo","bchCode","embedFormatInfo","formatInfoBits","makeVersionInfoBits","embedVersionInfo","versionInfoBits","bitIndex","embedCodewords","codewords","offsetX","upward","offsetY","embedFunctionPatterns","embedEncodingRegion","buildMatrix","BlockPair","ecCodewords","dataCodewords","buildGenerator","generators","lastGenerator","nextGenerator","Encoder","received","ecLength","dataBytes","infoCoefficients","base","numZeroCoefficients","zeroCoefficientsOffset","generateECCodewords","numECCodewords","buffer","injectECCodewords","maxNumECCodewords","maxNumDataCodewords","dataCodewordsOffset","blocks","appendTerminator","capacity","numBitsInLastByte","numPaddingCodewords","isByteMode","segment","mode","BYTE","isHanziMode","HANZI","appendModeInfo","appendECI","currentECIValue","ECI","appendFNC1Info","fnc1","indicator","FNC1_FIRST_POSITION","FNC1_SECOND_POSITION","getSegmentLength","appendLengthInfo","numLetters","willFit","numInputBits","numInputCodewords","chooseVersion","calculateBitsNeeded","segmentBlocks","bitsNeeded","head","chooseRecommendVersion","provisionalBitsNeeded","provisionalVersion","chooseBestMaskAndMatrix","bestMask","bestMatrix","minPenalty","MAX_CODE","Dict","bof","eof","unused","codes","reset","add","DictStream","dict","write","pipe","stream","writeByte","remain","writeBytes","compress","pixels","pixelIndex","nextCode","ByteStream","writeInt16","Base64Stream","pad","GIFImage","foreground","background","color","toDataURL","base64","Encoded","moduleSize","margin","colors","matrixSize","gif","assertContent","assertCharset","assertHints","hints","assertLevel","assertVersion","encode$1","segments","versionNumber","isFNC1Appended","Byte","uploadNumberSDK","number","isWorking","params","pcmMobileInputBtnCss","MobileUploadBtn","maxLength","uploadHeaders","QR_CODE_VALID_TIME","mobileUrl","setStartMobileUpload","startMobileUploadLoading","qrcodeStatus","ok","setStartMobileUploadWrapper","qrcodeUrl","setMobileUrlWrapper","encoder","qrcode","pollingQueryNumberInfo","num","res","resData","custom_data","setTimeout","handleStartMobileUpload","that","reqData","cfg","fromUserName","fromUserId","upload","update_id","now","theMobileUrl","PCM_DOMAIN","cancelLoading","cancelMobileUpload","mobile","isMobile","time","onFinished","marginTop","fontSize","navigator","clipboard","writeText","readOnly","pcmMobileUploadBtnCss","maxFileCount","file_list","is_knowledge_doc","maxSize","maxCount","customAccept","handleDelete","it","pcmMsbgModalCss","MsbgModal","file_urls","file_names","pcmQgqjlModalCss","QgqjlModal","pcmTimeCountDownCss","formatNumber","timeToHMS","hour","minute","second","TimeCountDown","finished","currentTime","watchStateHandler","timer","clearTimeout","pcmUploadCss","PcmUpload","uploadFailed","uploadChange","selectedFiles","FileUploadState","Uploading","file","file_size","Success","Failed","suffix","formatFileSize","uploadResult","emitUploadChange","uploadBtn","textDecoration","marginLeft","itemIndex","pcmZskChatModalCss","pcmZyghModalCss","ZyghModal","planningComplete","selectedPlanType","handlePlanTypeChange","handleStartPlanning","handlePlanningComplete","onInterviewComplete"],"sources":["src/components/pcm-1zhanshi-mnms-modal/pcm-1zhanshi-mnms-modal.css?tag=pcm-1zhanshi-mnms-modal&encapsulation=shadow","src/global/global.css?tag=pcm-1zhanshi-mnms-modal&encapsulation=shadow","src/components/pcm-1zhanshi-mnms-modal/pcm-1zhanshi-mnms-modal.tsx","node_modules/.pnpm/marked@9.1.6/node_modules/marked/lib/marked.esm.js","src/components/pcm-app-chat-modal/pcm-app-chat-modal.css?tag=pcm-app-chat-modal&encapsulation=shadow","src/global/markdown.css?tag=pcm-app-chat-modal&encapsulation=shadow","src/components/pcm-button/pcm-button.css?tag=pcm-button&encapsulation=shadow","src/components/pcm-button/pcm-button.tsx","src/components/pcm-card/pcm-card.css?tag=pcm-card&encapsulation=shadow","node_modules/.pnpm/marked-extended-tables@2.0.1_marked@9.1.6/node_modules/marked-extended-tables/lib/index.cjs","src/global/markdown.css?tag=pcm-chat-message&encapsulation=shadow","src/components/pcm-chat-message/pcm-chat-message.css?tag=pcm-chat-message&encapsulation=shadow","src/components/pcm-drawer/pcm-drawer.css?tag=pcm-drawer&encapsulation=shadow","src/components/pcm-drawer/pcm-drawer.tsx","src/components/pcm-hr-chat-modal/pcm-hr-chat-modal.css?tag=pcm-hr-chat-modal&encapsulation=shadow","src/components/pcm-htws-modal/pcm-htws-modal.css?tag=pcm-htws-modal&encapsulation=shadow","src/global/global.css?tag=pcm-htws-modal&encapsulation=shadow","src/components/pcm-htws-modal/pcm-htws-modal.tsx","src/components/pcm-hyzj-modal/pcm-hyzj-modal.css?tag=pcm-hyzj-modal&encapsulation=shadow","src/global/global.css?tag=pcm-hyzj-modal&encapsulation=shadow","src/components/pcm-hyzj-modal/pcm-hyzj-modal.tsx","src/components/pcm-jd-modal/pcm-jd-modal.css?tag=pcm-jd-modal&encapsulation=shadow","src/global/global.css?tag=pcm-jd-modal&encapsulation=shadow","src/components/pcm-jd-modal/pcm-jd-modal.tsx","src/components/pcm-jlpp-modal/pcm-jlpp-modal.css?tag=pcm-jlpp-modal&encapsulation=shadow","src/global/global.css?tag=pcm-jlpp-modal&encapsulation=shadow","src/components/pcm-jlpp-modal/pcm-jlpp-modal.tsx","src/components/pcm-mnct-modal/pcm-mnct-modal.css?tag=pcm-mnct-modal&encapsulation=shadow","src/global/global.css?tag=pcm-mnct-modal&encapsulation=shadow","src/components/pcm-mnct-modal/pcm-mnct-modal.tsx","src/components/pcm-mnms-modal/pcm-mnms-modal.css?tag=pcm-mnms-modal&encapsulation=shadow","src/global/global.css?tag=pcm-mnms-modal&encapsulation=shadow","src/components/pcm-mnms-modal/pcm-mnms-modal.tsx","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/Charset.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/utils.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/Mode.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/mask.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/ECLevel.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/ECB.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/ECBlocks.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/Version.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/reedsolomon/Polynomial.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/reedsolomon/GaloisField.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/encoding/index.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/BitArray.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/ByteMatrix.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/encoder/utils/matrix.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/encoder/BlockPair.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/reedsolomon/Encoder.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/encoder/utils/encoder.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/image/utils/lzw/Dict.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/image/utils/lzw/DictStream.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/image/utils/lzw/index.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/image/utils/ByteStream.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/image/utils/Base64Stream.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/common/image/GIFImage.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/encoder/Encoded.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/encoder/utils/asserts.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/encoder/Encoder.js","node_modules/.pnpm/@nuintun+qrcode@5.0.2/node_modules/@nuintun/qrcode/esm/encoder/segments/Byte.js","src/components/pcm-mobile-input-btn/uploadNumberSDK.ts","src/components/pcm-mobile-input-btn/pcm-mobile-input-btn.css?tag=pcm-mobile-input-btn&encapsulation=shadow","src/global/global.css?tag=pcm-mobile-input-btn&encapsulation=shadow","src/components/pcm-mobile-input-btn/pcm-mobile-input-btn.tsx","src/components/pcm-mobile-upload-btn/uploadNumberSDK.ts","src/components/pcm-mobile-upload-btn/pcm-mobile-upload-btn.css?tag=pcm-mobile-upload-btn&encapsulation=shadow","src/global/global.css?tag=pcm-mobile-upload-btn&encapsulation=shadow","src/components/pcm-mobile-upload-btn/pcm-mobile-upload-btn.tsx","src/components/pcm-msbg-modal/pcm-msbg-modal.css?tag=pcm-msbg-modal&encapsulation=shadow","src/global/global.css?tag=pcm-msbg-modal&encapsulation=shadow","src/components/pcm-msbg-modal/pcm-msbg-modal.tsx","src/components/pcm-qgqjl-modal/pcm-qgqjl-modal.css?tag=pcm-qgqjl-modal&encapsulation=shadow","src/global/global.css?tag=pcm-qgqjl-modal&encapsulation=shadow","src/components/pcm-qgqjl-modal/pcm-qgqjl-modal.tsx","src/components/pcm-time-count-down/pcm-time-count-down.css?tag=pcm-time-count-down&encapsulation=shadow","src/global/global.css?tag=pcm-time-count-down&encapsulation=shadow","src/components/pcm-time-count-down/pcm-time-count-down.tsx","src/components/pcm-upload/pcm-upload.css?tag=pcm-upload&encapsulation=shadow","src/global/global.css?tag=pcm-upload&encapsulation=shadow","src/components/pcm-upload/pcm-upload.tsx","src/components/pcm-zsk-chat-modal/pcm-zsk-chat-modal.css?tag=pcm-zsk-chat-modal&encapsulation=shadow","src/global/global.css?tag=pcm-zygh-modal&encapsulation=shadow","src/components/pcm-zygh-modal/pcm-zygh-modal.css?tag=pcm-zygh-modal&encapsulation=shadow","src/components/pcm-zygh-modal/pcm-zygh-modal.tsx"],"sourcesContent":[null,":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport {FileUploadResponse, verifyApiKey } from '../../utils/utils';\nimport { \n StreamCompleteEventData, \n ConversationStartEventData, \n InterviewCompleteEventData,\n RecordingErrorEventData,\n} from '../../interfaces/events';\nimport { ErrorEventBus, ErrorEventDetail } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store';\nimport { configStore } from '../../../store/config.store';\n\n/**\n * 模拟面试\n */\n\n@Component({\n tag: 'pcm-1zhanshi-mnms-modal',\n styleUrls: ['pcm-1zhanshi-mnms-modal.css', '../../global/global.css'],\n shadow: true,\n})\nexport class ZhanshiMnmsModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '模拟面试';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请开始模拟面试';\n\n /**\n * 视频录制最大时长(秒)默认120\n */\n @Prop() maxRecordingTime: number = 120;\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n /**\n * 自定义输入参数,传入customInputs.job_info时,会隐藏JD输入区域<br>\n */\n @Prop() customInputs: Record<string, string> = {};\n\n /**\n * 上传成功事件\n */\n @Event() uploadSuccess: EventEmitter<FileUploadResponse>;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() interviewComplete: EventEmitter<InterviewCompleteEventData>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 录制错误事件\n */\n @Event() recordingError: EventEmitter<RecordingErrorEventData>;\n\n @State() selectedFile: File | null = null;\n @State() isUploading: boolean = false;\n @State() uploadedFileInfo: FileUploadResponse | null = null;\n @State() showChatModal: boolean = false;\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n @State() jobDescription: string = '';\n @State() isSubmitting: boolean = false;\n\n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n\n componentWillLoad() {\n\n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n\n if (this.token) {\n authStore.setToken(this.token);\n }\n \n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n\n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.showChatModal = false;\n this.jobDescription = '';\n } else {\n await verifyApiKey(this.token);\n this.showChatModal = true;\n }\n }\n\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div >\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n fullscreen={this.fullscreen}\n botId=\"3022316191018903\"\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n maxRecordingTime={this.maxRecordingTime}\n enableTTS={false}\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n file_url: this.uploadedFileInfo?.cos_key,\n file_name: this.uploadedFileInfo?.file_name,\n }}\n interviewMode='video'\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} ","/**\n * marked v9.1.6 - a markdown parser\n * Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)\n * https://github.com/markedjs/marked\n */\n\n/**\n * DO NOT EDIT THIS FILE\n * The code in this file is generated from files in ./src/\n */\n\n/**\n * Gets the original marked default options.\n */\nfunction _getDefaults() {\n return {\n async: false,\n breaks: false,\n extensions: null,\n gfm: true,\n hooks: null,\n pedantic: false,\n renderer: null,\n silent: false,\n tokenizer: null,\n walkTokens: null\n };\n}\nlet _defaults = _getDefaults();\nfunction changeDefaults(newDefaults) {\n _defaults = newDefaults;\n}\n\n/**\n * Helpers\n */\nconst escapeTest = /[&<>\"']/;\nconst escapeReplace = new RegExp(escapeTest.source, 'g');\nconst escapeTestNoEncode = /[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/;\nconst escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');\nconst escapeReplacements = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n};\nconst getEscapeReplacement = (ch) => escapeReplacements[ch];\nfunction escape(html, encode) {\n if (encode) {\n if (escapeTest.test(html)) {\n return html.replace(escapeReplace, getEscapeReplacement);\n }\n }\n else {\n if (escapeTestNoEncode.test(html)) {\n return html.replace(escapeReplaceNoEncode, getEscapeReplacement);\n }\n }\n return html;\n}\nconst unescapeTest = /&(#(?:\\d+)|(?:#x[0-9A-Fa-f]+)|(?:\\w+));?/ig;\nfunction unescape(html) {\n // explicitly match decimal, hex, and named HTML entities\n return html.replace(unescapeTest, (_, n) => {\n n = n.toLowerCase();\n if (n === 'colon')\n return ':';\n if (n.charAt(0) === '#') {\n return n.charAt(1) === 'x'\n ? String.fromCharCode(parseInt(n.substring(2), 16))\n : String.fromCharCode(+n.substring(1));\n }\n return '';\n });\n}\nconst caret = /(^|[^\\[])\\^/g;\nfunction edit(regex, opt) {\n regex = typeof regex === 'string' ? regex : regex.source;\n opt = opt || '';\n const obj = {\n replace: (name, val) => {\n val = typeof val === 'object' && 'source' in val ? val.source : val;\n val = val.replace(caret, '$1');\n regex = regex.replace(name, val);\n return obj;\n },\n getRegex: () => {\n return new RegExp(regex, opt);\n }\n };\n return obj;\n}\nfunction cleanUrl(href) {\n try {\n href = encodeURI(href).replace(/%25/g, '%');\n }\n catch (e) {\n return null;\n }\n return href;\n}\nconst noopTest = { exec: () => null };\nfunction splitCells(tableRow, count) {\n // ensure that every cell-delimiting pipe has a space\n // before it to distinguish it from an escaped pipe\n const row = tableRow.replace(/\\|/g, (match, offset, str) => {\n let escaped = false;\n let curr = offset;\n while (--curr >= 0 && str[curr] === '\\\\')\n escaped = !escaped;\n if (escaped) {\n // odd number of slashes means | is escaped\n // so we leave it alone\n return '|';\n }\n else {\n // add space before unescaped |\n return ' |';\n }\n }), cells = row.split(/ \\|/);\n let i = 0;\n // First/last cell in a row cannot be empty if it has no leading/trailing pipe\n if (!cells[0].trim()) {\n cells.shift();\n }\n if (cells.length > 0 && !cells[cells.length - 1].trim()) {\n cells.pop();\n }\n if (count) {\n if (cells.length > count) {\n cells.splice(count);\n }\n else {\n while (cells.length < count)\n cells.push('');\n }\n }\n for (; i < cells.length; i++) {\n // leading or trailing whitespace is ignored per the gfm spec\n cells[i] = cells[i].trim().replace(/\\\\\\|/g, '|');\n }\n return cells;\n}\n/**\n * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').\n * /c*$/ is vulnerable to REDOS.\n *\n * @param str\n * @param c\n * @param invert Remove suffix of non-c chars instead. Default falsey.\n */\nfunction rtrim(str, c, invert) {\n const l = str.length;\n if (l === 0) {\n return '';\n }\n // Length of suffix matching the invert condition.\n let suffLen = 0;\n // Step left until we fail to match the invert condition.\n while (suffLen < l) {\n const currChar = str.charAt(l - suffLen - 1);\n if (currChar === c && !invert) {\n suffLen++;\n }\n else if (currChar !== c && invert) {\n suffLen++;\n }\n else {\n break;\n }\n }\n return str.slice(0, l - suffLen);\n}\nfunction findClosingBracket(str, b) {\n if (str.indexOf(b[1]) === -1) {\n return -1;\n }\n let level = 0;\n for (let i = 0; i < str.length; i++) {\n if (str[i] === '\\\\') {\n i++;\n }\n else if (str[i] === b[0]) {\n level++;\n }\n else if (str[i] === b[1]) {\n level--;\n if (level < 0) {\n return i;\n }\n }\n }\n return -1;\n}\n\nfunction outputLink(cap, link, raw, lexer) {\n const href = link.href;\n const title = link.title ? escape(link.title) : null;\n const text = cap[1].replace(/\\\\([\\[\\]])/g, '$1');\n if (cap[0].charAt(0) !== '!') {\n lexer.state.inLink = true;\n const token = {\n type: 'link',\n raw,\n href,\n title,\n text,\n tokens: lexer.inlineTokens(text)\n };\n lexer.state.inLink = false;\n return token;\n }\n return {\n type: 'image',\n raw,\n href,\n title,\n text: escape(text)\n };\n}\nfunction indentCodeCompensation(raw, text) {\n const matchIndentToCode = raw.match(/^(\\s+)(?:```)/);\n if (matchIndentToCode === null) {\n return text;\n }\n const indentToCode = matchIndentToCode[1];\n return text\n .split('\\n')\n .map(node => {\n const matchIndentInNode = node.match(/^\\s+/);\n if (matchIndentInNode === null) {\n return node;\n }\n const [indentInNode] = matchIndentInNode;\n if (indentInNode.length >= indentToCode.length) {\n return node.slice(indentToCode.length);\n }\n return node;\n })\n .join('\\n');\n}\n/**\n * Tokenizer\n */\nclass _Tokenizer {\n options;\n // TODO: Fix this rules type\n rules;\n lexer;\n constructor(options) {\n this.options = options || _defaults;\n }\n space(src) {\n const cap = this.rules.block.newline.exec(src);\n if (cap && cap[0].length > 0) {\n return {\n type: 'space',\n raw: cap[0]\n };\n }\n }\n code(src) {\n const cap = this.rules.block.code.exec(src);\n if (cap) {\n const text = cap[0].replace(/^ {1,4}/gm, '');\n return {\n type: 'code',\n raw: cap[0],\n codeBlockStyle: 'indented',\n text: !this.options.pedantic\n ? rtrim(text, '\\n')\n : text\n };\n }\n }\n fences(src) {\n const cap = this.rules.block.fences.exec(src);\n if (cap) {\n const raw = cap[0];\n const text = indentCodeCompensation(raw, cap[3] || '');\n return {\n type: 'code',\n raw,\n lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],\n text\n };\n }\n }\n heading(src) {\n const cap = this.rules.block.heading.exec(src);\n if (cap) {\n let text = cap[2].trim();\n // remove trailing #s\n if (/#$/.test(text)) {\n const trimmed = rtrim(text, '#');\n if (this.options.pedantic) {\n text = trimmed.trim();\n }\n else if (!trimmed || / $/.test(trimmed)) {\n // CommonMark requires space before trailing #s\n text = trimmed.trim();\n }\n }\n return {\n type: 'heading',\n raw: cap[0],\n depth: cap[1].length,\n text,\n tokens: this.lexer.inline(text)\n };\n }\n }\n hr(src) {\n const cap = this.rules.block.hr.exec(src);\n if (cap) {\n return {\n type: 'hr',\n raw: cap[0]\n };\n }\n }\n blockquote(src) {\n const cap = this.rules.block.blockquote.exec(src);\n if (cap) {\n const text = rtrim(cap[0].replace(/^ *>[ \\t]?/gm, ''), '\\n');\n const top = this.lexer.state.top;\n this.lexer.state.top = true;\n const tokens = this.lexer.blockTokens(text);\n this.lexer.state.top = top;\n return {\n type: 'blockquote',\n raw: cap[0],\n tokens,\n text\n };\n }\n }\n list(src) {\n let cap = this.rules.block.list.exec(src);\n if (cap) {\n let bull = cap[1].trim();\n const isordered = bull.length > 1;\n const list = {\n type: 'list',\n raw: '',\n ordered: isordered,\n start: isordered ? +bull.slice(0, -1) : '',\n loose: false,\n items: []\n };\n bull = isordered ? `\\\\d{1,9}\\\\${bull.slice(-1)}` : `\\\\${bull}`;\n if (this.options.pedantic) {\n bull = isordered ? bull : '[*+-]';\n }\n // Get next list item\n const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\\t ][^\\\\n]*)?(?:\\\\n|$))`);\n let raw = '';\n let itemContents = '';\n let endsWithBlankLine = false;\n // Check if current bullet point can start a new List Item\n while (src) {\n let endEarly = false;\n if (!(cap = itemRegex.exec(src))) {\n break;\n }\n if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)\n break;\n }\n raw = cap[0];\n src = src.substring(raw.length);\n let line = cap[2].split('\\n', 1)[0].replace(/^\\t+/, (t) => ' '.repeat(3 * t.length));\n let nextLine = src.split('\\n', 1)[0];\n let indent = 0;\n if (this.options.pedantic) {\n indent = 2;\n itemContents = line.trimStart();\n }\n else {\n indent = cap[2].search(/[^ ]/); // Find first non-space char\n indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent\n itemContents = line.slice(indent);\n indent += cap[1].length;\n }\n let blankLine = false;\n if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line\n raw += nextLine + '\\n';\n src = src.substring(nextLine.length + 1);\n endEarly = true;\n }\n if (!endEarly) {\n const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ \\t][^\\\\n]*)?(?:\\\\n|$))`);\n const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`);\n const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\\`\\`\\`|~~~)`);\n const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);\n // Check if following lines should be included in List Item\n while (src) {\n const rawLine = src.split('\\n', 1)[0];\n nextLine = rawLine;\n // Re-align to follow commonmark nesting rules\n if (this.options.pedantic) {\n nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' ');\n }\n // End list item if found code fences\n if (fencesBeginRegex.test(nextLine)) {\n break;\n }\n // End list item if found start of new heading\n if (headingBeginRegex.test(nextLine)) {\n break;\n }\n // End list item if found start of new bullet\n if (nextBulletRegex.test(nextLine)) {\n break;\n }\n // Horizontal rule found\n if (hrRegex.test(src)) {\n break;\n }\n if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible\n itemContents += '\\n' + nextLine.slice(indent);\n }\n else {\n // not enough indentation\n if (blankLine) {\n break;\n }\n // paragraph continuation unless last line was a different block level element\n if (line.search(/[^ ]/) >= 4) { // indented code block\n break;\n }\n if (fencesBeginRegex.test(line)) {\n break;\n }\n if (headingBeginRegex.test(line)) {\n break;\n }\n if (hrRegex.test(line)) {\n break;\n }\n itemContents += '\\n' + nextLine;\n }\n if (!blankLine && !nextLine.trim()) { // Check if current line is blank\n blankLine = true;\n }\n raw += rawLine + '\\n';\n src = src.substring(rawLine.length + 1);\n line = nextLine.slice(indent);\n }\n }\n if (!list.loose) {\n // If the previous item ended with a blank line, the list is loose\n if (endsWithBlankLine) {\n list.loose = true;\n }\n else if (/\\n *\\n *$/.test(raw)) {\n endsWithBlankLine = true;\n }\n }\n let istask = null;\n let ischecked;\n // Check for task list items\n if (this.options.gfm) {\n istask = /^\\[[ xX]\\] /.exec(itemContents);\n if (istask) {\n ischecked = istask[0] !== '[ ] ';\n itemContents = itemContents.replace(/^\\[[ xX]\\] +/, '');\n }\n }\n list.items.push({\n type: 'list_item',\n raw,\n task: !!istask,\n checked: ischecked,\n loose: false,\n text: itemContents,\n tokens: []\n });\n list.raw += raw;\n }\n // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic\n list.items[list.items.length - 1].raw = raw.trimEnd();\n list.items[list.items.length - 1].text = itemContents.trimEnd();\n list.raw = list.raw.trimEnd();\n // Item child tokens handled here at end because we needed to have the final item to trim it first\n for (let i = 0; i < list.items.length; i++) {\n this.lexer.state.top = false;\n list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);\n if (!list.loose) {\n // Check if list should be loose\n const spacers = list.items[i].tokens.filter(t => t.type === 'space');\n const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\\n.*\\n/.test(t.raw));\n list.loose = hasMultipleLineBreaks;\n }\n }\n // Set all items to loose if list is loose\n if (list.loose) {\n for (let i = 0; i < list.items.length; i++) {\n list.items[i].loose = true;\n }\n }\n return list;\n }\n }\n html(src) {\n const cap = this.rules.block.html.exec(src);\n if (cap) {\n const token = {\n type: 'html',\n block: true,\n raw: cap[0],\n pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',\n text: cap[0]\n };\n return token;\n }\n }\n def(src) {\n const cap = this.rules.block.def.exec(src);\n if (cap) {\n const tag = cap[1].toLowerCase().replace(/\\s+/g, ' ');\n const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';\n const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];\n return {\n type: 'def',\n tag,\n raw: cap[0],\n href,\n title\n };\n }\n }\n table(src) {\n const cap = this.rules.block.table.exec(src);\n if (cap) {\n if (!/[:|]/.test(cap[2])) {\n // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading\n return;\n }\n const item = {\n type: 'table',\n raw: cap[0],\n header: splitCells(cap[1]).map(c => {\n return { text: c, tokens: [] };\n }),\n align: cap[2].replace(/^\\||\\| *$/g, '').split('|'),\n rows: cap[3] && cap[3].trim() ? cap[3].replace(/\\n[ \\t]*$/, '').split('\\n') : []\n };\n if (item.header.length === item.align.length) {\n let l = item.align.length;\n let i, j, k, row;\n for (i = 0; i < l; i++) {\n const align = item.align[i];\n if (align) {\n if (/^ *-+: *$/.test(align)) {\n item.align[i] = 'right';\n }\n else if (/^ *:-+: *$/.test(align)) {\n item.align[i] = 'center';\n }\n else if (/^ *:-+ *$/.test(align)) {\n item.align[i] = 'left';\n }\n else {\n item.align[i] = null;\n }\n }\n }\n l = item.rows.length;\n for (i = 0; i < l; i++) {\n item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => {\n return { text: c, tokens: [] };\n });\n }\n // parse child tokens inside headers and cells\n // header child tokens\n l = item.header.length;\n for (j = 0; j < l; j++) {\n item.header[j].tokens = this.lexer.inline(item.header[j].text);\n }\n // cell child tokens\n l = item.rows.length;\n for (j = 0; j < l; j++) {\n row = item.rows[j];\n for (k = 0; k < row.length; k++) {\n row[k].tokens = this.lexer.inline(row[k].text);\n }\n }\n return item;\n }\n }\n }\n lheading(src) {\n const cap = this.rules.block.lheading.exec(src);\n if (cap) {\n return {\n type: 'heading',\n raw: cap[0],\n depth: cap[2].charAt(0) === '=' ? 1 : 2,\n text: cap[1],\n tokens: this.lexer.inline(cap[1])\n };\n }\n }\n paragraph(src) {\n const cap = this.rules.block.paragraph.exec(src);\n if (cap) {\n const text = cap[1].charAt(cap[1].length - 1) === '\\n'\n ? cap[1].slice(0, -1)\n : cap[1];\n return {\n type: 'paragraph',\n raw: cap[0],\n text,\n tokens: this.lexer.inline(text)\n };\n }\n }\n text(src) {\n const cap = this.rules.block.text.exec(src);\n if (cap) {\n return {\n type: 'text',\n raw: cap[0],\n text: cap[0],\n tokens: this.lexer.inline(cap[0])\n };\n }\n }\n escape(src) {\n const cap = this.rules.inline.escape.exec(src);\n if (cap) {\n return {\n type: 'escape',\n raw: cap[0],\n text: escape(cap[1])\n };\n }\n }\n tag(src) {\n const cap = this.rules.inline.tag.exec(src);\n if (cap) {\n if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {\n this.lexer.state.inLink = true;\n }\n else if (this.lexer.state.inLink && /^<\\/a>/i.test(cap[0])) {\n this.lexer.state.inLink = false;\n }\n if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\\s|>)/i.test(cap[0])) {\n this.lexer.state.inRawBlock = true;\n }\n else if (this.lexer.state.inRawBlock && /^<\\/(pre|code|kbd|script)(\\s|>)/i.test(cap[0])) {\n this.lexer.state.inRawBlock = false;\n }\n return {\n type: 'html',\n raw: cap[0],\n inLink: this.lexer.state.inLink,\n inRawBlock: this.lexer.state.inRawBlock,\n block: false,\n text: cap[0]\n };\n }\n }\n link(src) {\n const cap = this.rules.inline.link.exec(src);\n if (cap) {\n const trimmedUrl = cap[2].trim();\n if (!this.options.pedantic && /^</.test(trimmedUrl)) {\n // commonmark requires matching angle brackets\n if (!(/>$/.test(trimmedUrl))) {\n return;\n }\n // ending angle bracket cannot be escaped\n const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\\\');\n if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {\n return;\n }\n }\n else {\n // find closing parenthesis\n const lastParenIndex = findClosingBracket(cap[2], '()');\n if (lastParenIndex > -1) {\n const start = cap[0].indexOf('!') === 0 ? 5 : 4;\n const linkLen = start + cap[1].length + lastParenIndex;\n cap[2] = cap[2].substring(0, lastParenIndex);\n cap[0] = cap[0].substring(0, linkLen).trim();\n cap[3] = '';\n }\n }\n let href = cap[2];\n let title = '';\n if (this.options.pedantic) {\n // split pedantic href and title\n const link = /^([^'\"]*[^\\s])\\s+(['\"])(.*)\\2/.exec(href);\n if (link) {\n href = link[1];\n title = link[3];\n }\n }\n else {\n title = cap[3] ? cap[3].slice(1, -1) : '';\n }\n href = href.trim();\n if (/^</.test(href)) {\n if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {\n // pedantic allows starting angle bracket without ending angle bracket\n href = href.slice(1);\n }\n else {\n href = href.slice(1, -1);\n }\n }\n return outputLink(cap, {\n href: href ? href.replace(this.rules.inline._escapes, '$1') : href,\n title: title ? title.replace(this.rules.inline._escapes, '$1') : title\n }, cap[0], this.lexer);\n }\n }\n reflink(src, links) {\n let cap;\n if ((cap = this.rules.inline.reflink.exec(src))\n || (cap = this.rules.inline.nolink.exec(src))) {\n let link = (cap[2] || cap[1]).replace(/\\s+/g, ' ');\n link = links[link.toLowerCase()];\n if (!link) {\n const text = cap[0].charAt(0);\n return {\n type: 'text',\n raw: text,\n text\n };\n }\n return outputLink(cap, link, cap[0], this.lexer);\n }\n }\n emStrong(src, maskedSrc, prevChar = '') {\n let match = this.rules.inline.emStrong.lDelim.exec(src);\n if (!match)\n return;\n // _ can't be between two alphanumerics. \\p{L}\\p{N} includes non-english alphabet/numbers as well\n if (match[3] && prevChar.match(/[\\p{L}\\p{N}]/u))\n return;\n const nextChar = match[1] || match[2] || '';\n if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {\n // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)\n const lLength = [...match[0]].length - 1;\n let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;\n const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;\n endReg.lastIndex = 0;\n // Clip maskedSrc to same section of string as src (move to lexer?)\n maskedSrc = maskedSrc.slice(-1 * src.length + lLength);\n while ((match = endReg.exec(maskedSrc)) != null) {\n rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];\n if (!rDelim)\n continue; // skip single * in __abc*abc__\n rLength = [...rDelim].length;\n if (match[3] || match[4]) { // found another Left Delim\n delimTotal += rLength;\n continue;\n }\n else if (match[5] || match[6]) { // either Left or Right Delim\n if (lLength % 3 && !((lLength + rLength) % 3)) {\n midDelimTotal += rLength;\n continue; // CommonMark Emphasis Rules 9-10\n }\n }\n delimTotal -= rLength;\n if (delimTotal > 0)\n continue; // Haven't found enough closing delimiters\n // Remove extra characters. *a*** -> *a*\n rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);\n // char length can be >1 for unicode characters;\n const lastCharLength = [...match[0]][0].length;\n const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);\n // Create `em` if smallest delimiter has odd char count. *a***\n if (Math.min(lLength, rLength) % 2) {\n const text = raw.slice(1, -1);\n return {\n type: 'em',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text)\n };\n }\n // Create 'strong' if smallest delimiter has even char count. **a***\n const text = raw.slice(2, -2);\n return {\n type: 'strong',\n raw,\n text,\n tokens: this.lexer.inlineTokens(text)\n };\n }\n }\n }\n codespan(src) {\n const cap = this.rules.inline.code.exec(src);\n if (cap) {\n let text = cap[2].replace(/\\n/g, ' ');\n const hasNonSpaceChars = /[^ ]/.test(text);\n const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);\n if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n text = text.substring(1, text.length - 1);\n }\n text = escape(text, true);\n return {\n type: 'codespan',\n raw: cap[0],\n text\n };\n }\n }\n br(src) {\n const cap = this.rules.inline.br.exec(src);\n if (cap) {\n return {\n type: 'br',\n raw: cap[0]\n };\n }\n }\n del(src) {\n const cap = this.rules.inline.del.exec(src);\n if (cap) {\n return {\n type: 'del',\n raw: cap[0],\n text: cap[2],\n tokens: this.lexer.inlineTokens(cap[2])\n };\n }\n }\n autolink(src) {\n const cap = this.rules.inline.autolink.exec(src);\n if (cap) {\n let text, href;\n if (cap[2] === '@') {\n text = escape(cap[1]);\n href = 'mailto:' + text;\n }\n else {\n text = escape(cap[1]);\n href = text;\n }\n return {\n type: 'link',\n raw: cap[0],\n text,\n href,\n tokens: [\n {\n type: 'text',\n raw: text,\n text\n }\n ]\n };\n }\n }\n url(src) {\n let cap;\n if (cap = this.rules.inline.url.exec(src)) {\n let text, href;\n if (cap[2] === '@') {\n text = escape(cap[0]);\n href = 'mailto:' + text;\n }\n else {\n // do extended autolink path validation\n let prevCapZero;\n do {\n prevCapZero = cap[0];\n cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];\n } while (prevCapZero !== cap[0]);\n text = escape(cap[0]);\n if (cap[1] === 'www.') {\n href = 'http://' + cap[0];\n }\n else {\n href = cap[0];\n }\n }\n return {\n type: 'link',\n raw: cap[0],\n text,\n href,\n tokens: [\n {\n type: 'text',\n raw: text,\n text\n }\n ]\n };\n }\n }\n inlineText(src) {\n const cap = this.rules.inline.text.exec(src);\n if (cap) {\n let text;\n if (this.lexer.state.inRawBlock) {\n text = cap[0];\n }\n else {\n text = escape(cap[0]);\n }\n return {\n type: 'text',\n raw: cap[0],\n text\n };\n }\n }\n}\n\n/**\n * Block-Level Grammar\n */\n// Not all rules are defined in the object literal\n// @ts-expect-error\nconst block = {\n newline: /^(?: *(?:\\n|$))+/,\n code: /^( {4}[^\\n]+(?:\\n(?: *(?:\\n|$))*)?)+/,\n fences: /^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,\n hr: /^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,\n heading: /^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,\n blockquote: /^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/,\n list: /^( {0,3}bull)([ \\t][^\\n]+?)?(?:\\n|$)/,\n html: '^ {0,3}(?:' // optional indentation\n + '<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n+|$)' // (1)\n + '|comment[^\\\\n]*(\\\\n+|$)' // (2)\n + '|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>\\\\n*|$)' // (3)\n + '|<![A-Z][\\\\s\\\\S]*?(?:>\\\\n*|$)' // (4)\n + '|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>\\\\n*|$)' // (5)\n + '|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n *)+\\\\n|$)' // (6)\n + '|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n *)+\\\\n|$)' // (7) open tag\n + '|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n *)+\\\\n|$)' // (7) closing tag\n + ')',\n def: /^ {0,3}\\[(label)\\]: *(?:\\n *)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n *)?| *\\n *)(title))? *(?:\\n+|$)/,\n table: noopTest,\n lheading: /^(?!bull )((?:.|\\n(?!\\s*?\\n|bull ))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,\n // regex template, placeholders will be replaced according to different paragraph\n // interruption rules of commonmark and the original markdown spec:\n _paragraph: /^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\\n)[^\\n]+)*)/,\n text: /^[^\\n]+/\n};\nblock._label = /(?!\\s*\\])(?:\\\\.|[^\\[\\]\\\\])+/;\nblock._title = /(?:\"(?:\\\\\"?|[^\"\\\\])*\"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/;\nblock.def = edit(block.def)\n .replace('label', block._label)\n .replace('title', block._title)\n .getRegex();\nblock.bullet = /(?:[*+-]|\\d{1,9}[.)])/;\nblock.listItemStart = edit(/^( *)(bull) */)\n .replace('bull', block.bullet)\n .getRegex();\nblock.list = edit(block.list)\n .replace(/bull/g, block.bullet)\n .replace('hr', '\\\\n+(?=\\\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$))')\n .replace('def', '\\\\n+(?=' + block.def.source + ')')\n .getRegex();\nblock._tag = 'address|article|aside|base|basefont|blockquote|body|caption'\n + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'\n + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'\n + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'\n + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'\n + '|track|ul';\nblock._comment = /<!--(?!-?>)[\\s\\S]*?(?:-->|$)/;\nblock.html = edit(block.html, 'i')\n .replace('comment', block._comment)\n .replace('tag', block._tag)\n .replace('attribute', / +[a-zA-Z:_][\\w.:-]*(?: *= *\"[^\"\\n]*\"| *= *'[^'\\n]*'| *= *[^\\s\"'=<>`]+)?/)\n .getRegex();\nblock.lheading = edit(block.lheading)\n .replace(/bull/g, block.bullet) // lists can interrupt\n .getRegex();\nblock.paragraph = edit(block._paragraph)\n .replace('hr', block.hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs\n .replace('|table', '')\n .replace('blockquote', ' {0,3}>')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt\n .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks\n .getRegex();\nblock.blockquote = edit(block.blockquote)\n .replace('paragraph', block.paragraph)\n .getRegex();\n/**\n * Normal Block Grammar\n */\nblock.normal = { ...block };\n/**\n * GFM Block Grammar\n */\nblock.gfm = {\n ...block.normal,\n table: '^ *([^\\\\n ].*)\\\\n' // Header\n + ' {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)' // Align\n + '(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)' // Cells\n};\nblock.gfm.table = edit(block.gfm.table)\n .replace('hr', block.hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('blockquote', ' {0,3}>')\n .replace('code', ' {4}[^\\\\n]')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt\n .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks\n .getRegex();\nblock.gfm.paragraph = edit(block._paragraph)\n .replace('hr', block.hr)\n .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs\n .replace('table', block.gfm.table) // interrupt paragraphs with table\n .replace('blockquote', ' {0,3}>')\n .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt\n .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks\n .getRegex();\n/**\n * Pedantic grammar (original John Gruber's loose markdown specification)\n */\nblock.pedantic = {\n ...block.normal,\n html: edit('^ *(?:comment *(?:\\\\n|\\\\s*$)'\n + '|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)' // closed tag\n + '|<tag(?:\"[^\"]*\"|\\'[^\\']*\\'|\\\\s[^\\'\"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))')\n .replace('comment', block._comment)\n .replace(/tag/g, '(?!(?:'\n + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'\n + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'\n + '\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b')\n .getRegex(),\n def: /^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +([\"(][^\\n]+[\")]))? *(?:\\n+|$)/,\n heading: /^(#{1,6})(.*)(?:\\n+|$)/,\n fences: noopTest,\n lheading: /^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,\n paragraph: edit(block.normal._paragraph)\n .replace('hr', block.hr)\n .replace('heading', ' *#{1,6} *[^\\n]')\n .replace('lheading', block.lheading)\n .replace('blockquote', ' {0,3}>')\n .replace('|fences', '')\n .replace('|list', '')\n .replace('|html', '')\n .getRegex()\n};\n/**\n * Inline-Level Grammar\n */\n// Not all rules are defined in the object literal\n// @ts-expect-error\nconst inline = {\n escape: /^\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,\n autolink: /^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/,\n url: noopTest,\n tag: '^comment'\n + '|^</[a-zA-Z][\\\\w:-]*\\\\s*>' // self-closing tag\n + '|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>' // open tag\n + '|^<\\\\?[\\\\s\\\\S]*?\\\\?>' // processing instruction, e.g. <?php ?>\n + '|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>' // declaration, e.g. <!DOCTYPE html>\n + '|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>',\n link: /^!?\\[(label)\\]\\(\\s*(href)(?:\\s+(title))?\\s*\\)/,\n reflink: /^!?\\[(label)\\]\\[(ref)\\]/,\n nolink: /^!?\\[(ref)\\](?:\\[\\])?/,\n reflinkSearch: 'reflink|nolink(?!\\\\()',\n emStrong: {\n lDelim: /^(?:\\*+(?:((?!\\*)[punct])|[^\\s*]))|^_+(?:((?!_)[punct])|([^\\s_]))/,\n // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.\n // | Skip orphan inside strong | Consume to delim | (1) #*** | (2) a***#, a*** | (3) #***a, ***a | (4) ***# | (5) #***# | (6) a***a\n rDelimAst: /^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])/,\n rDelimUnd: /^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/ // ^- Not allowed for _\n },\n code: /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,\n br: /^( {2,}|\\\\)\\n(?!\\s*$)/,\n del: noopTest,\n text: /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,\n punctuation: /^((?![*_])[\\spunctuation])/\n};\n// list of unicode punctuation marks, plus any missing characters from CommonMark spec\ninline._punctuation = '\\\\p{P}$+<=>`^|~';\ninline.punctuation = edit(inline.punctuation, 'u').replace(/punctuation/g, inline._punctuation).getRegex();\n// sequences em should skip over [title](link), `code`, <html>\ninline.blockSkip = /\\[[^[\\]]*?\\]\\([^\\(\\)]*?\\)|`[^`]*?`|<[^<>]*?>/g;\ninline.anyPunctuation = /\\\\[punct]/g;\ninline._escapes = /\\\\([punct])/g;\ninline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();\ninline.emStrong.lDelim = edit(inline.emStrong.lDelim, 'u')\n .replace(/punct/g, inline._punctuation)\n .getRegex();\ninline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'gu')\n .replace(/punct/g, inline._punctuation)\n .getRegex();\ninline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'gu')\n .replace(/punct/g, inline._punctuation)\n .getRegex();\ninline.anyPunctuation = edit(inline.anyPunctuation, 'gu')\n .replace(/punct/g, inline._punctuation)\n .getRegex();\ninline._escapes = edit(inline._escapes, 'gu')\n .replace(/punct/g, inline._punctuation)\n .getRegex();\ninline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;\ninline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;\ninline.autolink = edit(inline.autolink)\n .replace('scheme', inline._scheme)\n .replace('email', inline._email)\n .getRegex();\ninline._attribute = /\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*\"[^\"]*\"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s\"'=<>`]+)?/;\ninline.tag = edit(inline.tag)\n .replace('comment', inline._comment)\n .replace('attribute', inline._attribute)\n .getRegex();\ninline._label = /(?:\\[(?:\\\\.|[^\\[\\]\\\\])*\\]|\\\\.|`[^`]*`|[^\\[\\]\\\\`])*?/;\ninline._href = /<(?:\\\\.|[^\\n<>\\\\])+>|[^\\s\\x00-\\x1f]*/;\ninline._title = /\"(?:\\\\\"?|[^\"\\\\])*\"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/;\ninline.link = edit(inline.link)\n .replace('label', inline._label)\n .replace('href', inline._href)\n .replace('title', inline._title)\n .getRegex();\ninline.reflink = edit(inline.reflink)\n .replace('label', inline._label)\n .replace('ref', block._label)\n .getRegex();\ninline.nolink = edit(inline.nolink)\n .replace('ref', block._label)\n .getRegex();\ninline.reflinkSearch = edit(inline.reflinkSearch, 'g')\n .replace('reflink', inline.reflink)\n .replace('nolink', inline.nolink)\n .getRegex();\n/**\n * Normal Inline Grammar\n */\ninline.normal = { ...inline };\n/**\n * Pedantic Inline Grammar\n */\ninline.pedantic = {\n ...inline.normal,\n strong: {\n start: /^__|\\*\\*/,\n middle: /^__(?=\\S)([\\s\\S]*?\\S)__(?!_)|^\\*\\*(?=\\S)([\\s\\S]*?\\S)\\*\\*(?!\\*)/,\n endAst: /\\*\\*(?!\\*)/g,\n endUnd: /__(?!_)/g\n },\n em: {\n start: /^_|\\*/,\n middle: /^()\\*(?=\\S)([\\s\\S]*?\\S)\\*(?!\\*)|^_(?=\\S)([\\s\\S]*?\\S)_(?!_)/,\n endAst: /\\*(?!\\*)/g,\n endUnd: /_(?!_)/g\n },\n link: edit(/^!?\\[(label)\\]\\((.*?)\\)/)\n .replace('label', inline._label)\n .getRegex(),\n reflink: edit(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/)\n .replace('label', inline._label)\n .getRegex()\n};\n/**\n * GFM Inline Grammar\n */\ninline.gfm = {\n ...inline.normal,\n escape: edit(inline.escape).replace('])', '~|])').getRegex(),\n _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,\n url: /^((?:ftp|https?):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/,\n _backpedal: /(?:[^?!.,:;*_'\"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'\"~)]+(?!$))+/,\n del: /^(~~?)(?=[^\\s~])([\\s\\S]*?[^\\s~])\\1(?=[^~]|$)/,\n text: /^([`~]+|[^`~])(?:(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|https?:\\/\\/|ftp:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)))/\n};\ninline.gfm.url = edit(inline.gfm.url, 'i')\n .replace('email', inline.gfm._extended_email)\n .getRegex();\n/**\n * GFM + Line Breaks Inline Grammar\n */\ninline.breaks = {\n ...inline.gfm,\n br: edit(inline.br).replace('{2,}', '*').getRegex(),\n text: edit(inline.gfm.text)\n .replace('\\\\b_', '\\\\b_| {2,}\\\\n')\n .replace(/\\{2,\\}/g, '*')\n .getRegex()\n};\n\n/**\n * Block Lexer\n */\nclass _Lexer {\n tokens;\n options;\n state;\n tokenizer;\n inlineQueue;\n constructor(options) {\n // TokenList cannot be created in one go\n // @ts-expect-error\n this.tokens = [];\n this.tokens.links = Object.create(null);\n this.options = options || _defaults;\n this.options.tokenizer = this.options.tokenizer || new _Tokenizer();\n this.tokenizer = this.options.tokenizer;\n this.tokenizer.options = this.options;\n this.tokenizer.lexer = this;\n this.inlineQueue = [];\n this.state = {\n inLink: false,\n inRawBlock: false,\n top: true\n };\n const rules = {\n block: block.normal,\n inline: inline.normal\n };\n if (this.options.pedantic) {\n rules.block = block.pedantic;\n rules.inline = inline.pedantic;\n }\n else if (this.options.gfm) {\n rules.block = block.gfm;\n if (this.options.breaks) {\n rules.inline = inline.breaks;\n }\n else {\n rules.inline = inline.gfm;\n }\n }\n this.tokenizer.rules = rules;\n }\n /**\n * Expose Rules\n */\n static get rules() {\n return {\n block,\n inline\n };\n }\n /**\n * Static Lex Method\n */\n static lex(src, options) {\n const lexer = new _Lexer(options);\n return lexer.lex(src);\n }\n /**\n * Static Lex Inline Method\n */\n static lexInline(src, options) {\n const lexer = new _Lexer(options);\n return lexer.inlineTokens(src);\n }\n /**\n * Preprocessing\n */\n lex(src) {\n src = src\n .replace(/\\r\\n|\\r/g, '\\n');\n this.blockTokens(src, this.tokens);\n let next;\n while (next = this.inlineQueue.shift()) {\n this.inlineTokens(next.src, next.tokens);\n }\n return this.tokens;\n }\n blockTokens(src, tokens = []) {\n if (this.options.pedantic) {\n src = src.replace(/\\t/g, ' ').replace(/^ +$/gm, '');\n }\n else {\n src = src.replace(/^( *)(\\t+)/gm, (_, leading, tabs) => {\n return leading + ' '.repeat(tabs.length);\n });\n }\n let token;\n let lastToken;\n let cutSrc;\n let lastParagraphClipped;\n while (src) {\n if (this.options.extensions\n && this.options.extensions.block\n && this.options.extensions.block.some((extTokenizer) => {\n if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n return true;\n }\n return false;\n })) {\n continue;\n }\n // newline\n if (token = this.tokenizer.space(src)) {\n src = src.substring(token.raw.length);\n if (token.raw.length === 1 && tokens.length > 0) {\n // if there's a single \\n as a spacer, it's terminating the last line,\n // so move it there so that we don't get unnecessary paragraph tags\n tokens[tokens.length - 1].raw += '\\n';\n }\n else {\n tokens.push(token);\n }\n continue;\n }\n // code\n if (token = this.tokenizer.code(src)) {\n src = src.substring(token.raw.length);\n lastToken = tokens[tokens.length - 1];\n // An indented code block cannot interrupt a paragraph.\n if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {\n lastToken.raw += '\\n' + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n }\n else {\n tokens.push(token);\n }\n continue;\n }\n // fences\n if (token = this.tokenizer.fences(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // heading\n if (token = this.tokenizer.heading(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // hr\n if (token = this.tokenizer.hr(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // blockquote\n if (token = this.tokenizer.blockquote(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // list\n if (token = this.tokenizer.list(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // html\n if (token = this.tokenizer.html(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // def\n if (token = this.tokenizer.def(src)) {\n src = src.substring(token.raw.length);\n lastToken = tokens[tokens.length - 1];\n if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {\n lastToken.raw += '\\n' + token.raw;\n lastToken.text += '\\n' + token.raw;\n this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n }\n else if (!this.tokens.links[token.tag]) {\n this.tokens.links[token.tag] = {\n href: token.href,\n title: token.title\n };\n }\n continue;\n }\n // table (gfm)\n if (token = this.tokenizer.table(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // lheading\n if (token = this.tokenizer.lheading(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // top-level paragraph\n // prevent paragraph consuming extensions by clipping 'src' to extension start\n cutSrc = src;\n if (this.options.extensions && this.options.extensions.startBlock) {\n let startIndex = Infinity;\n const tempSrc = src.slice(1);\n let tempStart;\n this.options.extensions.startBlock.forEach((getStartIndex) => {\n tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n if (typeof tempStart === 'number' && tempStart >= 0) {\n startIndex = Math.min(startIndex, tempStart);\n }\n });\n if (startIndex < Infinity && startIndex >= 0) {\n cutSrc = src.substring(0, startIndex + 1);\n }\n }\n if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {\n lastToken = tokens[tokens.length - 1];\n if (lastParagraphClipped && lastToken.type === 'paragraph') {\n lastToken.raw += '\\n' + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.pop();\n this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n }\n else {\n tokens.push(token);\n }\n lastParagraphClipped = (cutSrc.length !== src.length);\n src = src.substring(token.raw.length);\n continue;\n }\n // text\n if (token = this.tokenizer.text(src)) {\n src = src.substring(token.raw.length);\n lastToken = tokens[tokens.length - 1];\n if (lastToken && lastToken.type === 'text') {\n lastToken.raw += '\\n' + token.raw;\n lastToken.text += '\\n' + token.text;\n this.inlineQueue.pop();\n this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n }\n else {\n tokens.push(token);\n }\n continue;\n }\n if (src) {\n const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);\n if (this.options.silent) {\n console.error(errMsg);\n break;\n }\n else {\n throw new Error(errMsg);\n }\n }\n }\n this.state.top = true;\n return tokens;\n }\n inline(src, tokens = []) {\n this.inlineQueue.push({ src, tokens });\n return tokens;\n }\n /**\n * Lexing/Compiling\n */\n inlineTokens(src, tokens = []) {\n let token, lastToken, cutSrc;\n // String with links masked to avoid interference with em and strong\n let maskedSrc = src;\n let match;\n let keepPrevChar, prevChar;\n // Mask out reflinks\n if (this.tokens.links) {\n const links = Object.keys(this.tokens.links);\n if (links.length > 0) {\n while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {\n if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {\n maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);\n }\n }\n }\n }\n // Mask out other blocks\n while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {\n maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);\n }\n // Mask out escaped characters\n while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {\n maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);\n }\n while (src) {\n if (!keepPrevChar) {\n prevChar = '';\n }\n keepPrevChar = false;\n // extensions\n if (this.options.extensions\n && this.options.extensions.inline\n && this.options.extensions.inline.some((extTokenizer) => {\n if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n return true;\n }\n return false;\n })) {\n continue;\n }\n // escape\n if (token = this.tokenizer.escape(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // tag\n if (token = this.tokenizer.tag(src)) {\n src = src.substring(token.raw.length);\n lastToken = tokens[tokens.length - 1];\n if (lastToken && token.type === 'text' && lastToken.type === 'text') {\n lastToken.raw += token.raw;\n lastToken.text += token.text;\n }\n else {\n tokens.push(token);\n }\n continue;\n }\n // link\n if (token = this.tokenizer.link(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // reflink, nolink\n if (token = this.tokenizer.reflink(src, this.tokens.links)) {\n src = src.substring(token.raw.length);\n lastToken = tokens[tokens.length - 1];\n if (lastToken && token.type === 'text' && lastToken.type === 'text') {\n lastToken.raw += token.raw;\n lastToken.text += token.text;\n }\n else {\n tokens.push(token);\n }\n continue;\n }\n // em & strong\n if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // code\n if (token = this.tokenizer.codespan(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // br\n if (token = this.tokenizer.br(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // del (gfm)\n if (token = this.tokenizer.del(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // autolink\n if (token = this.tokenizer.autolink(src)) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // url (gfm)\n if (!this.state.inLink && (token = this.tokenizer.url(src))) {\n src = src.substring(token.raw.length);\n tokens.push(token);\n continue;\n }\n // text\n // prevent inlineText consuming extensions by clipping 'src' to extension start\n cutSrc = src;\n if (this.options.extensions && this.options.extensions.startInline) {\n let startIndex = Infinity;\n const tempSrc = src.slice(1);\n let tempStart;\n this.options.extensions.startInline.forEach((getStartIndex) => {\n tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n if (typeof tempStart === 'number' && tempStart >= 0) {\n startIndex = Math.min(startIndex, tempStart);\n }\n });\n if (startIndex < Infinity && startIndex >= 0) {\n cutSrc = src.substring(0, startIndex + 1);\n }\n }\n if (token = this.tokenizer.inlineText(cutSrc)) {\n src = src.substring(token.raw.length);\n if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started\n prevChar = token.raw.slice(-1);\n }\n keepPrevChar = true;\n lastToken = tokens[tokens.length - 1];\n if (lastToken && lastToken.type === 'text') {\n lastToken.raw += token.raw;\n lastToken.text += token.text;\n }\n else {\n tokens.push(token);\n }\n continue;\n }\n if (src) {\n const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);\n if (this.options.silent) {\n console.error(errMsg);\n break;\n }\n else {\n throw new Error(errMsg);\n }\n }\n }\n return tokens;\n }\n}\n\n/**\n * Renderer\n */\nclass _Renderer {\n options;\n constructor(options) {\n this.options = options || _defaults;\n }\n code(code, infostring, escaped) {\n const lang = (infostring || '').match(/^\\S*/)?.[0];\n code = code.replace(/\\n$/, '') + '\\n';\n if (!lang) {\n return '<pre><code>'\n + (escaped ? code : escape(code, true))\n + '</code></pre>\\n';\n }\n return '<pre><code class=\"language-'\n + escape(lang)\n + '\">'\n + (escaped ? code : escape(code, true))\n + '</code></pre>\\n';\n }\n blockquote(quote) {\n return `<blockquote>\\n${quote}</blockquote>\\n`;\n }\n html(html, block) {\n return html;\n }\n heading(text, level, raw) {\n // ignore IDs\n return `<h${level}>${text}</h${level}>\\n`;\n }\n hr() {\n return '<hr>\\n';\n }\n list(body, ordered, start) {\n const type = ordered ? 'ol' : 'ul';\n const startatt = (ordered && start !== 1) ? (' start=\"' + start + '\"') : '';\n return '<' + type + startatt + '>\\n' + body + '</' + type + '>\\n';\n }\n listitem(text, task, checked) {\n return `<li>${text}</li>\\n`;\n }\n checkbox(checked) {\n return '<input '\n + (checked ? 'checked=\"\" ' : '')\n + 'disabled=\"\" type=\"checkbox\">';\n }\n paragraph(text) {\n return `<p>${text}</p>\\n`;\n }\n table(header, body) {\n if (body)\n body = `<tbody>${body}</tbody>`;\n return '<table>\\n'\n + '<thead>\\n'\n + header\n + '</thead>\\n'\n + body\n + '</table>\\n';\n }\n tablerow(content) {\n return `<tr>\\n${content}</tr>\\n`;\n }\n tablecell(content, flags) {\n const type = flags.header ? 'th' : 'td';\n const tag = flags.align\n ? `<${type} align=\"${flags.align}\">`\n : `<${type}>`;\n return tag + content + `</${type}>\\n`;\n }\n /**\n * span level renderer\n */\n strong(text) {\n return `<strong>${text}</strong>`;\n }\n em(text) {\n return `<em>${text}</em>`;\n }\n codespan(text) {\n return `<code>${text}</code>`;\n }\n br() {\n return '<br>';\n }\n del(text) {\n return `<del>${text}</del>`;\n }\n link(href, title, text) {\n const cleanHref = cleanUrl(href);\n if (cleanHref === null) {\n return text;\n }\n href = cleanHref;\n let out = '<a href=\"' + href + '\"';\n if (title) {\n out += ' title=\"' + title + '\"';\n }\n out += '>' + text + '</a>';\n return out;\n }\n image(href, title, text) {\n const cleanHref = cleanUrl(href);\n if (cleanHref === null) {\n return text;\n }\n href = cleanHref;\n let out = `<img src=\"${href}\" alt=\"${text}\"`;\n if (title) {\n out += ` title=\"${title}\"`;\n }\n out += '>';\n return out;\n }\n text(text) {\n return text;\n }\n}\n\n/**\n * TextRenderer\n * returns only the textual part of the token\n */\nclass _TextRenderer {\n // no need for block level renderers\n strong(text) {\n return text;\n }\n em(text) {\n return text;\n }\n codespan(text) {\n return text;\n }\n del(text) {\n return text;\n }\n html(text) {\n return text;\n }\n text(text) {\n return text;\n }\n link(href, title, text) {\n return '' + text;\n }\n image(href, title, text) {\n return '' + text;\n }\n br() {\n return '';\n }\n}\n\n/**\n * Parsing & Compiling\n */\nclass _Parser {\n options;\n renderer;\n textRenderer;\n constructor(options) {\n this.options = options || _defaults;\n this.options.renderer = this.options.renderer || new _Renderer();\n this.renderer = this.options.renderer;\n this.renderer.options = this.options;\n this.textRenderer = new _TextRenderer();\n }\n /**\n * Static Parse Method\n */\n static parse(tokens, options) {\n const parser = new _Parser(options);\n return parser.parse(tokens);\n }\n /**\n * Static Parse Inline Method\n */\n static parseInline(tokens, options) {\n const parser = new _Parser(options);\n return parser.parseInline(tokens);\n }\n /**\n * Parse Loop\n */\n parse(tokens, top = true) {\n let out = '';\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n // Run any renderer extensions\n if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {\n const genericToken = token;\n const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);\n if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {\n out += ret || '';\n continue;\n }\n }\n switch (token.type) {\n case 'space': {\n continue;\n }\n case 'hr': {\n out += this.renderer.hr();\n continue;\n }\n case 'heading': {\n const headingToken = token;\n out += this.renderer.heading(this.parseInline(headingToken.tokens), headingToken.depth, unescape(this.parseInline(headingToken.tokens, this.textRenderer)));\n continue;\n }\n case 'code': {\n const codeToken = token;\n out += this.renderer.code(codeToken.text, codeToken.lang, !!codeToken.escaped);\n continue;\n }\n case 'table': {\n const tableToken = token;\n let header = '';\n // header\n let cell = '';\n for (let j = 0; j < tableToken.header.length; j++) {\n cell += this.renderer.tablecell(this.parseInline(tableToken.header[j].tokens), { header: true, align: tableToken.align[j] });\n }\n header += this.renderer.tablerow(cell);\n let body = '';\n for (let j = 0; j < tableToken.rows.length; j++) {\n const row = tableToken.rows[j];\n cell = '';\n for (let k = 0; k < row.length; k++) {\n cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: tableToken.align[k] });\n }\n body += this.renderer.tablerow(cell);\n }\n out += this.renderer.table(header, body);\n continue;\n }\n case 'blockquote': {\n const blockquoteToken = token;\n const body = this.parse(blockquoteToken.tokens);\n out += this.renderer.blockquote(body);\n continue;\n }\n case 'list': {\n const listToken = token;\n const ordered = listToken.ordered;\n const start = listToken.start;\n const loose = listToken.loose;\n let body = '';\n for (let j = 0; j < listToken.items.length; j++) {\n const item = listToken.items[j];\n const checked = item.checked;\n const task = item.task;\n let itemBody = '';\n if (item.task) {\n const checkbox = this.renderer.checkbox(!!checked);\n if (loose) {\n if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {\n item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;\n if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {\n item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;\n }\n }\n else {\n item.tokens.unshift({\n type: 'text',\n text: checkbox + ' '\n });\n }\n }\n else {\n itemBody += checkbox + ' ';\n }\n }\n itemBody += this.parse(item.tokens, loose);\n body += this.renderer.listitem(itemBody, task, !!checked);\n }\n out += this.renderer.list(body, ordered, start);\n continue;\n }\n case 'html': {\n const htmlToken = token;\n out += this.renderer.html(htmlToken.text, htmlToken.block);\n continue;\n }\n case 'paragraph': {\n const paragraphToken = token;\n out += this.renderer.paragraph(this.parseInline(paragraphToken.tokens));\n continue;\n }\n case 'text': {\n let textToken = token;\n let body = textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text;\n while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {\n textToken = tokens[++i];\n body += '\\n' + (textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text);\n }\n out += top ? this.renderer.paragraph(body) : body;\n continue;\n }\n default: {\n const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n if (this.options.silent) {\n console.error(errMsg);\n return '';\n }\n else {\n throw new Error(errMsg);\n }\n }\n }\n }\n return out;\n }\n /**\n * Parse Inline Tokens\n */\n parseInline(tokens, renderer) {\n renderer = renderer || this.renderer;\n let out = '';\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n // Run any renderer extensions\n if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {\n const ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);\n if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {\n out += ret || '';\n continue;\n }\n }\n switch (token.type) {\n case 'escape': {\n const escapeToken = token;\n out += renderer.text(escapeToken.text);\n break;\n }\n case 'html': {\n const tagToken = token;\n out += renderer.html(tagToken.text);\n break;\n }\n case 'link': {\n const linkToken = token;\n out += renderer.link(linkToken.href, linkToken.title, this.parseInline(linkToken.tokens, renderer));\n break;\n }\n case 'image': {\n const imageToken = token;\n out += renderer.image(imageToken.href, imageToken.title, imageToken.text);\n break;\n }\n case 'strong': {\n const strongToken = token;\n out += renderer.strong(this.parseInline(strongToken.tokens, renderer));\n break;\n }\n case 'em': {\n const emToken = token;\n out += renderer.em(this.parseInline(emToken.tokens, renderer));\n break;\n }\n case 'codespan': {\n const codespanToken = token;\n out += renderer.codespan(codespanToken.text);\n break;\n }\n case 'br': {\n out += renderer.br();\n break;\n }\n case 'del': {\n const delToken = token;\n out += renderer.del(this.parseInline(delToken.tokens, renderer));\n break;\n }\n case 'text': {\n const textToken = token;\n out += renderer.text(textToken.text);\n break;\n }\n default: {\n const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n if (this.options.silent) {\n console.error(errMsg);\n return '';\n }\n else {\n throw new Error(errMsg);\n }\n }\n }\n }\n return out;\n }\n}\n\nclass _Hooks {\n options;\n constructor(options) {\n this.options = options || _defaults;\n }\n static passThroughHooks = new Set([\n 'preprocess',\n 'postprocess'\n ]);\n /**\n * Process markdown before marked\n */\n preprocess(markdown) {\n return markdown;\n }\n /**\n * Process HTML after marked is finished\n */\n postprocess(html) {\n return html;\n }\n}\n\nclass Marked {\n defaults = _getDefaults();\n options = this.setOptions;\n parse = this.#parseMarkdown(_Lexer.lex, _Parser.parse);\n parseInline = this.#parseMarkdown(_Lexer.lexInline, _Parser.parseInline);\n Parser = _Parser;\n Renderer = _Renderer;\n TextRenderer = _TextRenderer;\n Lexer = _Lexer;\n Tokenizer = _Tokenizer;\n Hooks = _Hooks;\n constructor(...args) {\n this.use(...args);\n }\n /**\n * Run callback for every token\n */\n walkTokens(tokens, callback) {\n let values = [];\n for (const token of tokens) {\n values = values.concat(callback.call(this, token));\n switch (token.type) {\n case 'table': {\n const tableToken = token;\n for (const cell of tableToken.header) {\n values = values.concat(this.walkTokens(cell.tokens, callback));\n }\n for (const row of tableToken.rows) {\n for (const cell of row) {\n values = values.concat(this.walkTokens(cell.tokens, callback));\n }\n }\n break;\n }\n case 'list': {\n const listToken = token;\n values = values.concat(this.walkTokens(listToken.items, callback));\n break;\n }\n default: {\n const genericToken = token;\n if (this.defaults.extensions?.childTokens?.[genericToken.type]) {\n this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {\n values = values.concat(this.walkTokens(genericToken[childTokens], callback));\n });\n }\n else if (genericToken.tokens) {\n values = values.concat(this.walkTokens(genericToken.tokens, callback));\n }\n }\n }\n }\n return values;\n }\n use(...args) {\n const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };\n args.forEach((pack) => {\n // copy options to new object\n const opts = { ...pack };\n // set async to true if it was set to true before\n opts.async = this.defaults.async || opts.async || false;\n // ==-- Parse \"addon\" extensions --== //\n if (pack.extensions) {\n pack.extensions.forEach((ext) => {\n if (!ext.name) {\n throw new Error('extension name required');\n }\n if ('renderer' in ext) { // Renderer extensions\n const prevRenderer = extensions.renderers[ext.name];\n if (prevRenderer) {\n // Replace extension with func to run new extension but fall back if false\n extensions.renderers[ext.name] = function (...args) {\n let ret = ext.renderer.apply(this, args);\n if (ret === false) {\n ret = prevRenderer.apply(this, args);\n }\n return ret;\n };\n }\n else {\n extensions.renderers[ext.name] = ext.renderer;\n }\n }\n if ('tokenizer' in ext) { // Tokenizer Extensions\n if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {\n throw new Error(\"extension level must be 'block' or 'inline'\");\n }\n const extLevel = extensions[ext.level];\n if (extLevel) {\n extLevel.unshift(ext.tokenizer);\n }\n else {\n extensions[ext.level] = [ext.tokenizer];\n }\n if (ext.start) { // Function to check for start of token\n if (ext.level === 'block') {\n if (extensions.startBlock) {\n extensions.startBlock.push(ext.start);\n }\n else {\n extensions.startBlock = [ext.start];\n }\n }\n else if (ext.level === 'inline') {\n if (extensions.startInline) {\n extensions.startInline.push(ext.start);\n }\n else {\n extensions.startInline = [ext.start];\n }\n }\n }\n }\n if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens\n extensions.childTokens[ext.name] = ext.childTokens;\n }\n });\n opts.extensions = extensions;\n }\n // ==-- Parse \"overwrite\" extensions --== //\n if (pack.renderer) {\n const renderer = this.defaults.renderer || new _Renderer(this.defaults);\n for (const prop in pack.renderer) {\n const rendererFunc = pack.renderer[prop];\n const rendererKey = prop;\n const prevRenderer = renderer[rendererKey];\n // Replace renderer with func to run extension, but fall back if false\n renderer[rendererKey] = (...args) => {\n let ret = rendererFunc.apply(renderer, args);\n if (ret === false) {\n ret = prevRenderer.apply(renderer, args);\n }\n return ret || '';\n };\n }\n opts.renderer = renderer;\n }\n if (pack.tokenizer) {\n const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);\n for (const prop in pack.tokenizer) {\n const tokenizerFunc = pack.tokenizer[prop];\n const tokenizerKey = prop;\n const prevTokenizer = tokenizer[tokenizerKey];\n // Replace tokenizer with func to run extension, but fall back if false\n tokenizer[tokenizerKey] = (...args) => {\n let ret = tokenizerFunc.apply(tokenizer, args);\n if (ret === false) {\n ret = prevTokenizer.apply(tokenizer, args);\n }\n return ret;\n };\n }\n opts.tokenizer = tokenizer;\n }\n // ==-- Parse Hooks extensions --== //\n if (pack.hooks) {\n const hooks = this.defaults.hooks || new _Hooks();\n for (const prop in pack.hooks) {\n const hooksFunc = pack.hooks[prop];\n const hooksKey = prop;\n const prevHook = hooks[hooksKey];\n if (_Hooks.passThroughHooks.has(prop)) {\n hooks[hooksKey] = (arg) => {\n if (this.defaults.async) {\n return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => {\n return prevHook.call(hooks, ret);\n });\n }\n const ret = hooksFunc.call(hooks, arg);\n return prevHook.call(hooks, ret);\n };\n }\n else {\n hooks[hooksKey] = (...args) => {\n let ret = hooksFunc.apply(hooks, args);\n if (ret === false) {\n ret = prevHook.apply(hooks, args);\n }\n return ret;\n };\n }\n }\n opts.hooks = hooks;\n }\n // ==-- Parse WalkTokens extensions --== //\n if (pack.walkTokens) {\n const walkTokens = this.defaults.walkTokens;\n const packWalktokens = pack.walkTokens;\n opts.walkTokens = function (token) {\n let values = [];\n values.push(packWalktokens.call(this, token));\n if (walkTokens) {\n values = values.concat(walkTokens.call(this, token));\n }\n return values;\n };\n }\n this.defaults = { ...this.defaults, ...opts };\n });\n return this;\n }\n setOptions(opt) {\n this.defaults = { ...this.defaults, ...opt };\n return this;\n }\n lexer(src, options) {\n return _Lexer.lex(src, options ?? this.defaults);\n }\n parser(tokens, options) {\n return _Parser.parse(tokens, options ?? this.defaults);\n }\n #parseMarkdown(lexer, parser) {\n return (src, options) => {\n const origOpt = { ...options };\n const opt = { ...this.defaults, ...origOpt };\n // Show warning if an extension set async to true but the parse was called with async: false\n if (this.defaults.async === true && origOpt.async === false) {\n if (!opt.silent) {\n console.warn('marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored.');\n }\n opt.async = true;\n }\n const throwError = this.#onError(!!opt.silent, !!opt.async);\n // throw error in case of non string input\n if (typeof src === 'undefined' || src === null) {\n return throwError(new Error('marked(): input parameter is undefined or null'));\n }\n if (typeof src !== 'string') {\n return throwError(new Error('marked(): input parameter is of type '\n + Object.prototype.toString.call(src) + ', string expected'));\n }\n if (opt.hooks) {\n opt.hooks.options = opt;\n }\n if (opt.async) {\n return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)\n .then(src => lexer(src, opt))\n .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)\n .then(tokens => parser(tokens, opt))\n .then(html => opt.hooks ? opt.hooks.postprocess(html) : html)\n .catch(throwError);\n }\n try {\n if (opt.hooks) {\n src = opt.hooks.preprocess(src);\n }\n const tokens = lexer(src, opt);\n if (opt.walkTokens) {\n this.walkTokens(tokens, opt.walkTokens);\n }\n let html = parser(tokens, opt);\n if (opt.hooks) {\n html = opt.hooks.postprocess(html);\n }\n return html;\n }\n catch (e) {\n return throwError(e);\n }\n };\n }\n #onError(silent, async) {\n return (e) => {\n e.message += '\\nPlease report this to https://github.com/markedjs/marked.';\n if (silent) {\n const msg = '<p>An error occurred:</p><pre>'\n + escape(e.message + '', true)\n + '</pre>';\n if (async) {\n return Promise.resolve(msg);\n }\n return msg;\n }\n if (async) {\n return Promise.reject(e);\n }\n throw e;\n };\n }\n}\n\nconst markedInstance = new Marked();\nfunction marked(src, opt) {\n return markedInstance.parse(src, opt);\n}\n/**\n * Sets the default options.\n *\n * @param options Hash of options\n */\nmarked.options =\n marked.setOptions = function (options) {\n markedInstance.setOptions(options);\n marked.defaults = markedInstance.defaults;\n changeDefaults(marked.defaults);\n return marked;\n };\n/**\n * Gets the original marked default options.\n */\nmarked.getDefaults = _getDefaults;\nmarked.defaults = _defaults;\n/**\n * Use Extension\n */\nmarked.use = function (...args) {\n markedInstance.use(...args);\n marked.defaults = markedInstance.defaults;\n changeDefaults(marked.defaults);\n return marked;\n};\n/**\n * Run callback for every token\n */\nmarked.walkTokens = function (tokens, callback) {\n return markedInstance.walkTokens(tokens, callback);\n};\n/**\n * Compiles markdown to HTML without enclosing `p` tag.\n *\n * @param src String of markdown source to be compiled\n * @param options Hash of options\n * @return String of compiled HTML\n */\nmarked.parseInline = markedInstance.parseInline;\n/**\n * Expose\n */\nmarked.Parser = _Parser;\nmarked.parser = _Parser.parse;\nmarked.Renderer = _Renderer;\nmarked.TextRenderer = _TextRenderer;\nmarked.Lexer = _Lexer;\nmarked.lexer = _Lexer.lex;\nmarked.Tokenizer = _Tokenizer;\nmarked.Hooks = _Hooks;\nmarked.parse = marked;\nconst options = marked.options;\nconst setOptions = marked.setOptions;\nconst use = marked.use;\nconst walkTokens = marked.walkTokens;\nconst parseInline = marked.parseInline;\nconst parse = marked;\nconst parser = _Parser.parse;\nconst lexer = _Lexer.lex;\n\nexport { _Hooks as Hooks, _Lexer as Lexer, Marked, _Parser as Parser, _Renderer as Renderer, _TextRenderer as TextRenderer, _Tokenizer as Tokenizer, _defaults as defaults, _getDefaults as getDefaults, lexer, marked, options, parse, parseInline, parser, setOptions, use, walkTokens };\n//# sourceMappingURL=marked.esm.js.map\n",":host {\n display: block;\n font-size: 16px;\n}\n\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n overflow-y: auto;\n padding: 20px;\n z-index: 1000;\n}\n\n/* 全屏模式下的overlay样式 */\n.fullscreen-overlay {\n padding: 0;\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: 100%;\n}\n\n.modal-container {\n background: white;\n border-radius: 8px;\n width: 100%;\n max-width: 900px;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* 确保内容区域也使用 flex 布局并占满剩余空间 */\n.modal-container.fullscreen>div:not(.modal-header):not(.initial-upload) {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n /* 防止内容溢出 */\n height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 800px;\n /* height: 80vh; */\n /* max-height: 700px; */\n min-width: 320px;\n min-height: 400px;\n}\n\n.video-preview.placeholder {\n display: flex;\n justify-content: center;\n align-items: center;\n background: #EAEAEA;\n}\n\n.placeholder-status {\n color: #00000066;\n}\n\n.placeholder-status p{\n font-size: 16px;\n}\n\n.waiting-message p {\n margin: 0;\n font-size: 16px;\n color: white;\n font-weight: 500;\n}\n\n.recording-container {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.video-container {\n width: 100%;\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n margin-bottom: 20px;\n}\n\n.video-area {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.stop-recording-button {\n width: 100%;\n height: 100%;\n font-size: 16px;\n background: #f44336;\n border-radius: 6px;\n color: white;\n border: none;\n cursor: pointer;\n}\n\n.stop-recording-button:hover {\n background: #d32f2f;\n}\n\n.play-audio-container {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n /* 防止头部被压缩 */\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.header-left div {\n font-size: 16px;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n.chat-container {\n background-image: url(https://pub.pincaimao.com/static/web/images/login/bg_login_m.png);\n background-size: 100%;\n height: 100%;\n border-radius: 0px 0px 8px 8px;\n}\n\n.chat-history {\n position: relative;\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n height: 400px;\n}\n\n/* 添加全屏模式下的样式 */\n.fullscreen .chat-history {\n height: auto;\n flex: 1 1 auto;\n}\n\n.message-input {\n padding: 16px;\n border-top: 1px solid #eee;\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.message-input input {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #ddd;\n border-radius: 4px;\n outline: none;\n transition: border-color 0.2s ease;\n}\n\n.message-input input:focus {\n border-color: #bbb;\n}\n\n/* 消息样式 */\n.message {\n margin-bottom: 16px;\n opacity: 1;\n transition: opacity 0.3s ease;\n}\n\n.message-content {\n max-width: 70%;\n padding: 8px 12px;\n border-radius: 8px;\n word-break: break-word;\n}\n\n.message-content p {\n margin: 0;\n word-break: break-word;\n}\n\n.user-message {\n display: flex;\n justify-content: flex-end;\n}\n\n.agent-message {\n display: flex;\n justify-content: flex-start;\n}\n\n.user-message .message-content {\n background-color: #007bff;\n color: white;\n}\n\n.agent-message .message-content {\n background-color: #f1f1f1;\n}\n\n.message-time {\n font-size: 12px;\n color: #999;\n margin-top: 4px;\n display: block;\n}\n\n/* 发送按钮样式 */\n.send-button {\n width: 38px;\n height: 38px;\n border-radius: 16px;\n background: #0d75fb;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: background-color 0.2s ease;\n}\n\n.send-button img {\n width: 24px;\n height: 24px;\n}\n\n.send-button:hover {\n background: #0a62d6;\n}\n\n.send-button.disabled {\n background: #d9d9d9;\n cursor: not-allowed;\n}\n\n.empty-state {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n color: #999;\n text-align: center;\n}\n\n.loading-container {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n background-color: rgba(255, 255, 255, 0.98);\n z-index: 1;\n opacity: 1;\n transition: opacity 0.3s ease;\n}\n\n.loading-container p {\n margin-top: 16px;\n color: #666;\n font-size: 14px;\n}\n\n.loading-spinner {\n width: 40px;\n height: 40px;\n border: 3px solid #f3f3f3;\n border-top: 3px solid #1890ff;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n}\n\n/* 修改 messages-wrapper 的样式 */\n.messages-wrapper {\n width: 100%;\n min-height: 100%;\n display: flex;\n flex-direction: column;\n /* 当内容少时,将内容放在底部 */\n justify-content: flex-end;\n}\n\n/* 当有很多消息时,取消固定在底部 */\n.messages-wrapper.has-overflow {\n justify-content: flex-start;\n}\n\n.suggested-questions {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 16px;\n}\n\n.suggested-question {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n background-color: #f3f4f6;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n color: #374151;\n transition: background-color 0.2s;\n}\n\n.suggested-question:hover {\n background-color: #e5e7eb;\n}\n\n.arrow-right {\n margin-left: 8px;\n}\n\n.loading-suggestions {\n display: flex;\n justify-content: center;\n padding: 16px;\n}\n\n.loading-spinner-small {\n width: 20px;\n height: 20px;\n border: 2px solid #e5e7eb;\n border-top-color: #6b7280;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n/* 添加上传按钮样式 */\n.upload-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n border-radius: 4px;\n transition: background-color 0.2s;\n}\n\n.upload-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.upload-button svg {\n width: 20px;\n height: 20px;\n}\n\n/* 隐藏原生文件输入框 */\n.file-input {\n display: none;\n}\n\n/* 添加文件名显示区域样式 */\n.selected-file {\n font-size: 12px;\n color: #666;\n margin-left: 8px;\n max-width: 150px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.input-wrapper {\n flex: 1;\n display: flex;\n align-items: center;\n border: 1px solid #ddd;\n border-radius: 4px;\n padding: 0 4px;\n background: white;\n}\n\n.input-wrapper input {\n border: none;\n flex: 1;\n padding: 8px;\n outline: none;\n}\n\n.input-wrapper:focus-within {\n border-color: #bbb;\n}\n\n/* 文件预览区域样式 */\n.file-preview {\n padding: 8px 16px;\n border-top: 1px solid #eee;\n background-color: #f9f9f9;\n}\n\n.recording-section {\n border-top: 1px solid #eee;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 10px 20px 0px 20px;\n border-radius: 14px 14px 0 0;\n flex: 0 0 auto;\n}\n\n.recording-section .video-preview {\n width: 100%;\n height: 200px;\n max-width: 400px;\n position: relative;\n margin-bottom: 10px;\n border: 1px solid #ddd;\n border-radius: 12px;\n overflow: hidden;\n}\n\n.recording-section video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n/* 修改 recording-status 样式 */\n.recording-status {\n position: absolute;\n top: 10px;\n left: 10px;\n background-color: rgba(0, 0, 0, 0.6);\n color: white;\n padding: 4px 8px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 14px;\n z-index: 2;\n}\n\n.recording-status .recording-dot {\n display: inline-block;\n width: 10px;\n height: 10px;\n background-color: red;\n border-radius: 50%;\n margin-right: 5px;\n animation: blink 1s infinite;\n}\n\n.recording-status.warning {\n color: #ff4d4f;\n animation: blink 1s infinite;\n}\n\n@keyframes blink {\n 0% {\n opacity: 1;\n }\n\n 50% {\n opacity: 0.5;\n }\n\n 100% {\n opacity: 1;\n }\n}\n\n.recording-section .stop-recording-button {\n background-color: #f44336;\n color: white;\n border: none;\n cursor: pointer;\n font-weight: bold;\n}\n\n.recording-section .stop-recording-button:hover {\n background-color: #d32f2f;\n}\n\n.fullscreen {\n width: 100vw;\n border-radius: 0;\n height: 100vh;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n}\n\n.recording-controls {\n margin-top: 10px;\n height: 53px;\n width: 100%;\n max-width: 400px;\n display: flex;\n justify-content: center;\n}\n\n.recording-controls .waiting-message {\n text-align: center;\n color: white;\n font-size: 16px;\n background-color: #0D75FB;\n border-radius: 6px;\n width: 95%;\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n}\n\n.recording-controls .waiting-message.loading {\n background: #faad14;\n}\n\n.recording-controls .waiting-message p {\n margin: 0;\n font-size: 16px;\n color: white;\n font-weight: 500;\n}\n\n.recording-controls .stop-recording-button {\n background-color: #dc3545;\n color: white;\n border: none;\n cursor: pointer;\n font-size: 16px;\n}\n\n.recording-controls .stop-recording-button:hover {\n background-color: #c82333;\n}\n\n/* 添加禁用状态的样式 */\n.recording-controls .stop-recording-button.disabled {\n background: #ccc;\n cursor: not-allowed;\n}\n\n.recording-controls .stop-recording-button.disabled:hover {\n background: #ccc;\n}\n\n/* 添加进度条和数字进度的样式 */\n.progress-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n max-width: 400px;\n margin-top: 10px;\n padding: 0 5px;\n}\n\n.progress-bar-container {\n height: 4px;\n background-color: #E5E5E5;\n border-radius: 2px;\n overflow: hidden;\n margin-right: 10px;\n width: 75px;\n}\n\n.progress-bar {\n height: 100%;\n background-image: linear-gradient(111deg, #4A9FFF 0%, #1058FF 100%);\n border-radius: 2px;\n transition: width 0.3s ease;\n}\n\n.progress-text {\n font-size: 14px;\n color: #666;\n white-space: nowrap;\n}\n\n/* 重新设计文本输入区域样式 */\n.text-input-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n padding: 0px 16px 16px 16px;\n border-radius: 8px;\n border: none;\n /* 确保容器本身没有边框 */\n}\n\n/* 修改文本输入框样式 */\n.text-answer-input {\n flex: 1;\n min-height: 80px;\n padding: 12px 12px 0px 12px;\n border: 1px solid #ddd;\n border-radius: 8px 8px 0 0;\n resize: none;\n font-size: 16px;\n background-color: #fff;\n border-bottom: none;\n outline: none;\n /* 移除默认的焦点轮廓 */\n}\n\n/* 修改工具栏样式 */\n.input-toolbar {\n display: flex;\n justify-content: end;\n align-items: center;\n padding: 8px 12px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-top: none;\n border-radius: 0 0 8px 8px;\n}\n\n/* 当输入框获得焦点时,修改边框颜色 */\n.text-answer-input:focus {\n border-color: rgb(74, 144, 226);\n border-bottom: none;\n}\n\n.text-answer-input:focus+.input-toolbar {\n border-color: rgb(74, 144, 226);\n border-top: none;\n}\n\n/* 左侧工具按钮区域 */\n.toolbar-actions {\n width: 32px;\n height: 32px;\n display: flex;\n justify-content: center;\n align-items: center;\n margin-right: 10px;\n border: 1px solid #d9d9d9;\n border-radius: 6px;\n}\n\n.toolbar-actions:hover {\n background-color: #f0f0f0;\n}\n\n/* 修改工具按钮样式,确保居中 */\n.toolbar-button {\n background: transparent;\n border: none;\n color: #666;\n cursor: pointer;\n padding: 0;\n margin: 0;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* 确保按钮内部的内容也居中 */\n.toolbar-button > div,\n.toolbar-button > svg {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* 发送按钮样式 */\n.submit-text-button {\n padding: 6px 16px;\n background-color: #4a90e2;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background-color 0.2s;\n}\n\n.submit-text-button:hover:not(.disabled) {\n background-color: #3a7bc8;\n}\n\n.submit-text-button.disabled {\n background-color: #b3b3b3;\n cursor: not-allowed;\n}\n\n/* 语音输入按钮样式 */\n.toolbar-button.recording {\n background-color: rgba(255, 0, 0, 0.1);\n color: #ff3b30;\n animation: pulse 1.5s infinite;\n}\n\n.toolbar-button.converting {\n background-color: rgba(0, 122, 255, 0.1);\n color: #007aff;\n}\n\n.toolbar-button .recording-time {\n font-size: 12px;\n margin-left: 4px;\n}\n\n.converting-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.converting-indicator svg {\n animation: spin 1.5s linear infinite;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes pulse {\n 0% {\n box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.4);\n }\n\n 70% {\n box-shadow: 0 0 0 6px rgba(255, 0, 0, 0);\n }\n\n 100% {\n box-shadow: 0 0 0 0 rgba(255, 0, 0, 0);\n }\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 0;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 工作区样式 */\n.workspace-section {\n width: 100%;\n padding: 0px 16px 16px;\n}\n\n.workspace-toolbar {\n display: flex;\n justify-content: end;\n align-items: center;\n gap: 12px;\n}\n\n.workspace-button {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid #d9d9d9;\n border-radius: 6px;\n background: white;\n color: #666;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.workspace-button:hover {\n border-color: #4096ff;\n color: #4096ff;\n box-shadow: 0 2px 4px rgba(64, 150, 255, 0.1);\n}\n\n.workspace-button svg {\n flex-shrink: 0;\n}\n\n\n/* 历史会话抽屉样式 */\n.history-drawer-content {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n\n.conversation-list {\n flex: 1;\n overflow-y: auto;\n padding: 8px 0;\n}\n\n.loading-conversations,\n.empty-conversations {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: #999;\n}\n\n.loading-conversations .loading-spinner-small {\n margin-bottom: 12px;\n}\n\n.conversation-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n margin: 0 8px 4px 8px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n border: 1px solid transparent;\n}\n\n.conversation-item:hover {\n background: #f5f5f5;\n}\n\n.conversation-item.active {\n background: #e6f7ff;\n border-color: #1890ff;\n}\n\n.conversation-info {\n flex: 1;\n min-width: 0;\n}\n\n.conversation-title {\n font-size: 14px;\n font-weight: 500;\n color: #262626;\n margin-bottom: 4px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.conversation-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #8c8c8c;\n}\n\n.conversation-time {\n flex-shrink: 0;\n}\n\n.message-count {\n flex-shrink: 0;\n}\n\n.conversation-status {\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.conversation-status.completed {\n background: #f6ffed;\n color: #52c41a;\n}\n\n.conversation-status.running {\n background: #fff7e6;\n color: #fa8c16;\n}\n\n.current-indicator {\n flex-shrink: 0;\n color: #1890ff;\n margin-left: 8px;\n}","\n.markdown-body {\n --base-size-4: 4px;\n --base-size-8: 8px;\n --base-size-16: 16px;\n --base-size-24: 24px;\n --base-size-40: 40px;\n --base-text-weight-normal: 400;\n --base-text-weight-medium: 500;\n --base-text-weight-semibold: 600;\n --fontStack-monospace: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;\n --fgColor-accent: Highlight;\n }\n \n @media (prefers-color-scheme: dark) {\n \n .markdown-body,\n [data-theme=\"dark\"] {\n /* dark */\n color-scheme: dark;\n --focus-outlineColor: #0969da;\n --fgColor-default: #1f2328;\n --fgColor-muted: #59636e;\n --fgColor-accent: #0969da;\n --fgColor-success: #1a7f37;\n --fgColor-attention: #9a6700;\n --fgColor-danger: #d1242f;\n --fgColor-done: #8250df;\n --bgColor-default: #ffffff;\n --bgColor-muted: #f6f8fa;\n --bgColor-neutral-muted: #818b981f;\n --bgColor-attention-muted: #fff8c5;\n --borderColor-default: #d1d9e0;\n --borderColor-muted: #d1d9e0b3;\n --borderColor-neutral-muted: #d1d9e0b3;\n --borderColor-accent-emphasis: #0969da;\n --borderColor-success-emphasis: #1a7f37;\n --borderColor-attention-emphasis: #9a6700;\n --borderColor-danger-emphasis: #cf222e;\n --borderColor-done-emphasis: #8250df;\n --color-prettylights-syntax-comment: #59636e;\n --color-prettylights-syntax-constant: #0550ae;\n --color-prettylights-syntax-constant-other-reference-link: #0a3069;\n --color-prettylights-syntax-entity: #6639ba;\n --color-prettylights-syntax-storage-modifier-import: #1f2328;\n --color-prettylights-syntax-entity-tag: #0550ae;\n --color-prettylights-syntax-keyword: #cf222e;\n --color-prettylights-syntax-string: #0a3069;\n --color-prettylights-syntax-variable: #953800;\n --color-prettylights-syntax-brackethighlighter-unmatched: #82071e;\n --color-prettylights-syntax-brackethighlighter-angle: #59636e;\n --color-prettylights-syntax-invalid-illegal-text: #f6f8fa;\n --color-prettylights-syntax-invalid-illegal-bg: #82071e;\n --color-prettylights-syntax-carriage-return-text: #f6f8fa;\n --color-prettylights-syntax-carriage-return-bg: #cf222e;\n --color-prettylights-syntax-string-regexp: #116329;\n --color-prettylights-syntax-markup-list: #3b2300;\n --color-prettylights-syntax-markup-heading: #0550ae;\n --color-prettylights-syntax-markup-italic: #1f2328;\n --color-prettylights-syntax-markup-bold: #1f2328;\n --color-prettylights-syntax-markup-deleted-text: #82071e;\n --color-prettylights-syntax-markup-deleted-bg: #ffebe9;\n --color-prettylights-syntax-markup-inserted-text: #116329;\n --color-prettylights-syntax-markup-inserted-bg: #dafbe1;\n --color-prettylights-syntax-markup-changed-text: #953800;\n --color-prettylights-syntax-markup-changed-bg: #ffd8b5;\n --color-prettylights-syntax-markup-ignored-text: #d1d9e0;\n --color-prettylights-syntax-markup-ignored-bg: #0550ae;\n --color-prettylights-syntax-meta-diff-range: #8250df;\n --color-prettylights-syntax-sublimelinter-gutter-mark: #818b98;\n }\n }\n \n @media (prefers-color-scheme: light) {\n \n .markdown-body,\n [data-theme=\"light\"] {\n /* light */\n color-scheme: light;\n --focus-outlineColor: #0969da;\n --fgColor-default: #1f2328;\n --fgColor-muted: #59636e;\n --fgColor-accent: #0969da;\n --fgColor-success: #1a7f37;\n --fgColor-attention: #9a6700;\n --fgColor-danger: #d1242f;\n --fgColor-done: #8250df;\n --bgColor-default: #ffffff;\n --bgColor-muted: #f6f8fa;\n --bgColor-neutral-muted: #818b981f;\n --bgColor-attention-muted: #fff8c5;\n --borderColor-default: #d1d9e0;\n --borderColor-muted: #d1d9e0b3;\n --borderColor-neutral-muted: #d1d9e0b3;\n --borderColor-accent-emphasis: #0969da;\n --borderColor-success-emphasis: #1a7f37;\n --borderColor-attention-emphasis: #9a6700;\n --borderColor-danger-emphasis: #cf222e;\n --borderColor-done-emphasis: #8250df;\n --color-prettylights-syntax-comment: #59636e;\n --color-prettylights-syntax-constant: #0550ae;\n --color-prettylights-syntax-constant-other-reference-link: #0a3069;\n --color-prettylights-syntax-entity: #6639ba;\n --color-prettylights-syntax-storage-modifier-import: #1f2328;\n --color-prettylights-syntax-entity-tag: #0550ae;\n --color-prettylights-syntax-keyword: #cf222e;\n --color-prettylights-syntax-string: #0a3069;\n --color-prettylights-syntax-variable: #953800;\n --color-prettylights-syntax-brackethighlighter-unmatched: #82071e;\n --color-prettylights-syntax-brackethighlighter-angle: #59636e;\n --color-prettylights-syntax-invalid-illegal-text: #f6f8fa;\n --color-prettylights-syntax-invalid-illegal-bg: #82071e;\n --color-prettylights-syntax-carriage-return-text: #f6f8fa;\n --color-prettylights-syntax-carriage-return-bg: #cf222e;\n --color-prettylights-syntax-string-regexp: #116329;\n --color-prettylights-syntax-markup-list: #3b2300;\n --color-prettylights-syntax-markup-heading: #0550ae;\n --color-prettylights-syntax-markup-italic: #1f2328;\n --color-prettylights-syntax-markup-bold: #1f2328;\n --color-prettylights-syntax-markup-deleted-text: #82071e;\n --color-prettylights-syntax-markup-deleted-bg: #ffebe9;\n --color-prettylights-syntax-markup-inserted-text: #116329;\n --color-prettylights-syntax-markup-inserted-bg: #dafbe1;\n --color-prettylights-syntax-markup-changed-text: #953800;\n --color-prettylights-syntax-markup-changed-bg: #ffd8b5;\n --color-prettylights-syntax-markup-ignored-text: #d1d9e0;\n --color-prettylights-syntax-markup-ignored-bg: #0550ae;\n --color-prettylights-syntax-meta-diff-range: #8250df;\n --color-prettylights-syntax-sublimelinter-gutter-mark: #818b98;\n }\n }\n \n .markdown-body {\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\";\n font-size: 16px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n \n .markdown-body .octicon {\n display: inline-block;\n fill: currentColor;\n vertical-align: text-bottom;\n }\n \n .markdown-body h1:hover .anchor .octicon-link:before,\n .markdown-body h2:hover .anchor .octicon-link:before,\n .markdown-body h3:hover .anchor .octicon-link:before,\n .markdown-body h4:hover .anchor .octicon-link:before,\n .markdown-body h5:hover .anchor .octicon-link:before,\n .markdown-body h6:hover .anchor .octicon-link:before {\n width: 16px;\n height: 16px;\n content: ' ';\n display: inline-block;\n background-color: currentColor;\n -webkit-mask-image: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>\");\n mask-image: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>\");\n }\n \n .markdown-body details,\n .markdown-body figcaption,\n .markdown-body figure {\n display: block;\n }\n \n .markdown-body summary {\n display: list-item;\n }\n \n .markdown-body [hidden] {\n display: none !important;\n }\n \n .markdown-body a {\n background-color: transparent;\n color: var(--fgColor-accent);\n text-decoration: none;\n }\n \n .markdown-body abbr[title] {\n border-bottom: none;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n \n .markdown-body b,\n .markdown-body strong {\n font-weight: var(--base-text-weight-semibold, 600);\n }\n \n .markdown-body dfn {\n font-style: italic;\n }\n \n .markdown-body h1 {\n margin: .67em 0;\n font-weight: var(--base-text-weight-semibold, 600);\n padding-bottom: .3em;\n font-size: 1.5em;\n border-bottom: 1px solid var(--borderColor-muted);\n }\n \n .markdown-body mark {\n background-color: var(--bgColor-attention-muted);\n color: var(--fgColor-default);\n }\n \n .markdown-body small {\n font-size: 90%;\n }\n \n .markdown-body sub,\n .markdown-body sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n \n .markdown-body sub {\n bottom: -0.25em;\n }\n \n .markdown-body sup {\n top: -0.5em;\n }\n \n .markdown-body img {\n border-style: none;\n max-width: 100%;\n box-sizing: content-box;\n }\n \n .markdown-body code,\n .markdown-body kbd,\n .markdown-body pre,\n .markdown-body samp {\n font-family: monospace;\n font-size: 1em;\n }\n \n .markdown-body figure {\n margin: 1em var(--base-size-40);\n }\n \n .markdown-body hr {\n box-sizing: content-box;\n overflow: hidden;\n background: transparent;\n border-bottom: 1px solid var(--borderColor-muted);\n height: .25em;\n padding: 0;\n margin: var(--base-size-24) 0;\n background-color: var(--borderColor-default);\n border: 0;\n }\n \n .markdown-body input {\n font: inherit;\n margin: 0;\n overflow: visible;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n }\n \n .markdown-body [type=button],\n .markdown-body [type=reset],\n .markdown-body [type=submit] {\n -webkit-appearance: button;\n appearance: button;\n }\n \n .markdown-body [type=checkbox],\n .markdown-body [type=radio] {\n box-sizing: border-box;\n padding: 0;\n }\n \n .markdown-body [type=number]::-webkit-inner-spin-button,\n .markdown-body [type=number]::-webkit-outer-spin-button {\n height: auto;\n }\n \n .markdown-body [type=search]::-webkit-search-cancel-button,\n .markdown-body [type=search]::-webkit-search-decoration {\n -webkit-appearance: none;\n appearance: none;\n }\n \n .markdown-body ::-webkit-input-placeholder {\n color: inherit;\n opacity: .54;\n }\n \n .markdown-body ::-webkit-file-upload-button {\n -webkit-appearance: button;\n appearance: button;\n font: inherit;\n }\n \n .markdown-body a:hover {\n text-decoration: underline;\n }\n \n .markdown-body ::placeholder {\n color: var(--fgColor-muted);\n opacity: 1;\n }\n \n .markdown-body hr::before {\n display: table;\n content: \"\";\n }\n \n .markdown-body hr::after {\n display: table;\n clear: both;\n content: \"\";\n }\n \n .markdown-body table {\n border-spacing: 0;\n border-collapse: collapse;\n display: block;\n width: max-content;\n max-width: 100%;\n overflow: auto;\n font-variant: tabular-nums;\n }\n \n .markdown-body td,\n .markdown-body th {\n padding: 0;\n }\n \n .markdown-body details summary {\n cursor: pointer;\n }\n \n .markdown-body a:focus,\n .markdown-body [role=button]:focus,\n .markdown-body input[type=radio]:focus,\n .markdown-body input[type=checkbox]:focus {\n outline: 2px solid var(--focus-outlineColor);\n outline-offset: -2px;\n box-shadow: none;\n }\n \n .markdown-body a:focus:not(:focus-visible),\n .markdown-body [role=button]:focus:not(:focus-visible),\n .markdown-body input[type=radio]:focus:not(:focus-visible),\n .markdown-body input[type=checkbox]:focus:not(:focus-visible) {\n outline: solid 1px transparent;\n }\n \n .markdown-body a:focus-visible,\n .markdown-body [role=button]:focus-visible,\n .markdown-body input[type=radio]:focus-visible,\n .markdown-body input[type=checkbox]:focus-visible {\n outline: 2px solid var(--focus-outlineColor);\n outline-offset: -2px;\n box-shadow: none;\n }\n \n .markdown-body a:not([class]):focus,\n .markdown-body a:not([class]):focus-visible,\n .markdown-body input[type=radio]:focus,\n .markdown-body input[type=radio]:focus-visible,\n .markdown-body input[type=checkbox]:focus,\n .markdown-body input[type=checkbox]:focus-visible {\n outline-offset: 0;\n }\n \n .markdown-body kbd {\n display: inline-block;\n padding: var(--base-size-4);\n font: 11px var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);\n line-height: 10px;\n color: var(--fgColor-default);\n vertical-align: middle;\n background-color: var(--bgColor-muted);\n border: solid 1px var(--borderColor-neutral-muted);\n border-bottom-color: var(--borderColor-neutral-muted);\n border-radius: 6px;\n box-shadow: inset 0 -1px 0 var(--borderColor-neutral-muted);\n }\n \n .markdown-body h1,\n .markdown-body h2,\n .markdown-body h3,\n .markdown-body h4,\n .markdown-body h5,\n .markdown-body h6 {\n margin-top: var(--base-size-24);\n margin-bottom: var(--base-size-16);\n font-weight: var(--base-text-weight-semibold, 600);\n line-height: 1.25;\n }\n \n .markdown-body h2 {\n font-weight: var(--base-text-weight-semibold, 600);\n padding-bottom: .3em;\n font-size: 1.2em;\n border-bottom: 1px solid var(--borderColor-muted);\n }\n \n .markdown-body h3 {\n font-weight: var(--base-text-weight-semibold, 600);\n font-size: 1.05em;\n }\n \n .markdown-body h4 {\n font-weight: var(--base-text-weight-semibold, 600);\n font-size: 0.875em;\n }\n \n .markdown-body h5 {\n font-weight: var(--base-text-weight-semibold, 600);\n font-size: .85em;\n }\n \n .markdown-body h6 {\n font-weight: var(--base-text-weight-semibold, 600);\n font-size: .80em;\n color: var(--fgColor-muted);\n }\n \n .markdown-body p {\n margin-top: 0;\n margin-bottom: 10px;\n }\n \n .markdown-body blockquote {\n margin: 0;\n padding: 0 1em;\n color: var(--fgColor-muted);\n border-left: .25em solid var(--borderColor-default);\n }\n \n .markdown-body ul,\n .markdown-body ol {\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 2em;\n }\n \n .markdown-body ol ol,\n .markdown-body ul ol {\n list-style-type: lower-roman;\n }\n \n .markdown-body ul ul ol,\n .markdown-body ul ol ol,\n .markdown-body ol ul ol,\n .markdown-body ol ol ol {\n list-style-type: lower-alpha;\n }\n \n .markdown-body dd {\n margin-left: 0;\n }\n \n .markdown-body tt,\n .markdown-body code,\n .markdown-body samp {\n font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);\n font-size: 12px;\n }\n \n .markdown-body pre {\n margin-top: 0;\n margin-bottom: 0;\n font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);\n font-size: 12px;\n word-wrap: normal;\n }\n \n .markdown-body .octicon {\n display: inline-block;\n overflow: visible !important;\n vertical-align: text-bottom;\n fill: currentColor;\n }\n \n .markdown-body input::-webkit-outer-spin-button,\n .markdown-body input::-webkit-inner-spin-button {\n margin: 0;\n appearance: none;\n }\n \n .markdown-body .mr-2 {\n margin-right: var(--base-size-8, 8px) !important;\n }\n \n .markdown-body::before {\n display: table;\n content: \"\";\n }\n \n .markdown-body::after {\n display: table;\n clear: both;\n content: \"\";\n }\n \n .markdown-body>*:first-child {\n margin-top: 0 !important;\n }\n \n .markdown-body>*:last-child {\n margin-bottom: 0 !important;\n }\n \n .markdown-body a:not([href]) {\n color: inherit;\n text-decoration: none;\n }\n \n .markdown-body .absent {\n color: var(--fgColor-danger);\n }\n \n .markdown-body .anchor {\n float: left;\n padding-right: var(--base-size-4);\n margin-left: -20px;\n line-height: 1;\n }\n \n .markdown-body .anchor:focus {\n outline: none;\n }\n \n .markdown-body p,\n .markdown-body blockquote,\n .markdown-body ul,\n .markdown-body ol,\n .markdown-body dl,\n .markdown-body table,\n .markdown-body pre,\n .markdown-body details {\n margin-top: 0;\n margin-bottom: var(--base-size-16);\n font-size: 16px;\n font-weight: 400;\n }\n \n .markdown-body blockquote>:first-child {\n margin-top: 0;\n }\n \n .markdown-body blockquote>:last-child {\n margin-bottom: 0;\n }\n \n .markdown-body h1 .octicon-link,\n .markdown-body h2 .octicon-link,\n .markdown-body h3 .octicon-link,\n .markdown-body h4 .octicon-link,\n .markdown-body h5 .octicon-link,\n .markdown-body h6 .octicon-link {\n color: var(--fgColor-default);\n vertical-align: middle;\n visibility: hidden;\n }\n \n .markdown-body h1:hover .anchor,\n .markdown-body h2:hover .anchor,\n .markdown-body h3:hover .anchor,\n .markdown-body h4:hover .anchor,\n .markdown-body h5:hover .anchor,\n .markdown-body h6:hover .anchor {\n text-decoration: none;\n }\n \n .markdown-body h1:hover .anchor .octicon-link,\n .markdown-body h2:hover .anchor .octicon-link,\n .markdown-body h3:hover .anchor .octicon-link,\n .markdown-body h4:hover .anchor .octicon-link,\n .markdown-body h5:hover .anchor .octicon-link,\n .markdown-body h6:hover .anchor .octicon-link {\n visibility: visible;\n }\n \n .markdown-body h1 tt,\n .markdown-body h1 code,\n .markdown-body h2 tt,\n .markdown-body h2 code,\n .markdown-body h3 tt,\n .markdown-body h3 code,\n .markdown-body h4 tt,\n .markdown-body h4 code,\n .markdown-body h5 tt,\n .markdown-body h5 code,\n .markdown-body h6 tt,\n .markdown-body h6 code {\n padding: 0 .2em;\n font-size: inherit;\n }\n \n .markdown-body summary h1,\n .markdown-body summary h2,\n .markdown-body summary h3,\n .markdown-body summary h4,\n .markdown-body summary h5,\n .markdown-body summary h6 {\n display: inline-block;\n }\n \n .markdown-body summary h1 .anchor,\n .markdown-body summary h2 .anchor,\n .markdown-body summary h3 .anchor,\n .markdown-body summary h4 .anchor,\n .markdown-body summary h5 .anchor,\n .markdown-body summary h6 .anchor {\n margin-left: -40px;\n }\n \n .markdown-body summary h1,\n .markdown-body summary h2 {\n padding-bottom: 0;\n border-bottom: 0;\n }\n \n .markdown-body ul.no-list,\n .markdown-body ol.no-list {\n padding: 0;\n list-style-type: none;\n }\n \n .markdown-body ol[type=\"a s\"] {\n list-style-type: lower-alpha;\n }\n \n .markdown-body ol[type=\"A s\"] {\n list-style-type: upper-alpha;\n }\n \n .markdown-body ol[type=\"i s\"] {\n list-style-type: lower-roman;\n }\n \n .markdown-body ol[type=\"I s\"] {\n list-style-type: upper-roman;\n }\n \n .markdown-body ol[type=\"1\"] {\n list-style-type: decimal;\n }\n \n .markdown-body div>ol:not([type]) {\n list-style-type: decimal;\n }\n \n .markdown-body ul ul,\n .markdown-body ul ol,\n .markdown-body ol ol,\n .markdown-body ol ul {\n margin-top: 0;\n margin-bottom: 0;\n }\n \n .markdown-body li>p {\n margin-top: var(--base-size-16);\n }\n \n .markdown-body li+li {\n margin-top: .25em;\n }\n \n .markdown-body dl {\n padding: 0;\n }\n \n .markdown-body dl dt {\n padding: 0;\n margin-top: var(--base-size-16);\n font-size: 1em;\n font-style: italic;\n font-weight: var(--base-text-weight-semibold, 600);\n }\n \n .markdown-body dl dd {\n padding: 0 var(--base-size-16);\n margin-bottom: var(--base-size-16);\n }\n \n .markdown-body table th {\n font-weight: var(--base-text-weight-semibold, 600);\n }\n \n .markdown-body table th,\n .markdown-body table td {\n padding: 6px 13px;\n border: 1px solid var(--borderColor-default);\n }\n \n .markdown-body table td>:last-child {\n margin-bottom: 0;\n }\n \n .markdown-body table tr {\n background-color: var(--bgColor-default);\n border-top: 1px solid var(--borderColor-muted);\n }\n \n .markdown-body table tr:nth-child(2n) {\n background-color: var(--bgColor-muted);\n }\n \n .markdown-body table img {\n background-color: transparent;\n }\n \n .markdown-body img[align=right] {\n padding-left: 20px;\n }\n \n .markdown-body img[align=left] {\n padding-right: 20px;\n }\n \n .markdown-body .emoji {\n max-width: none;\n vertical-align: text-top;\n background-color: transparent;\n }\n \n .markdown-body span.frame {\n display: block;\n overflow: hidden;\n }\n \n .markdown-body span.frame>span {\n display: block;\n float: left;\n width: auto;\n padding: 7px;\n margin: 13px 0 0;\n overflow: hidden;\n border: 1px solid var(--borderColor-default);\n }\n \n .markdown-body span.frame span img {\n display: block;\n float: left;\n }\n \n .markdown-body span.frame span span {\n display: block;\n padding: 5px 0 0;\n clear: both;\n color: var(--fgColor-default);\n }\n \n .markdown-body span.align-center {\n display: block;\n overflow: hidden;\n clear: both;\n }\n \n .markdown-body span.align-center>span {\n display: block;\n margin: 13px auto 0;\n overflow: hidden;\n text-align: center;\n }\n \n .markdown-body span.align-center span img {\n margin: 0 auto;\n text-align: center;\n }\n \n .markdown-body span.align-right {\n display: block;\n overflow: hidden;\n clear: both;\n }\n \n .markdown-body span.align-right>span {\n display: block;\n margin: 13px 0 0;\n overflow: hidden;\n text-align: right;\n }\n \n .markdown-body span.align-right span img {\n margin: 0;\n text-align: right;\n }\n \n .markdown-body span.float-left {\n display: block;\n float: left;\n margin-right: 13px;\n overflow: hidden;\n }\n \n .markdown-body span.float-left span {\n margin: 13px 0 0;\n }\n \n .markdown-body span.float-right {\n display: block;\n float: right;\n margin-left: 13px;\n overflow: hidden;\n }\n \n .markdown-body span.float-right>span {\n display: block;\n margin: 13px auto 0;\n overflow: hidden;\n text-align: right;\n }\n \n .markdown-body code,\n .markdown-body tt {\n padding: .2em .4em;\n margin: 0;\n font-size: 85%;\n white-space: break-spaces;\n background-color: var(--bgColor-neutral-muted);\n border-radius: 6px;\n }\n \n .markdown-body code br,\n .markdown-body tt br {\n display: none;\n }\n \n .markdown-body del code {\n text-decoration: inherit;\n }\n \n .markdown-body samp {\n font-size: 85%;\n }\n \n .markdown-body pre code {\n font-size: 100%;\n }\n \n .markdown-body pre>code {\n padding: 0;\n margin: 0;\n word-break: normal;\n white-space: pre;\n background: transparent;\n border: 0;\n }\n \n .markdown-body .highlight {\n margin-bottom: var(--base-size-16);\n }\n \n .markdown-body .highlight pre {\n margin-bottom: 0;\n word-break: normal;\n }\n \n .markdown-body .highlight pre,\n .markdown-body pre {\n padding: var(--base-size-16);\n overflow: auto;\n font-size: 85%;\n line-height: 1.45;\n color: var(--fgColor-default);\n background-color: var(--bgColor-muted);\n border-radius: 6px;\n }\n \n .markdown-body pre code,\n .markdown-body pre tt {\n display: inline;\n max-width: auto;\n padding: 0;\n margin: 0;\n overflow: visible;\n line-height: inherit;\n word-wrap: normal;\n background-color: transparent;\n border: 0;\n }\n \n .markdown-body .csv-data td,\n .markdown-body .csv-data th {\n padding: 5px;\n overflow: hidden;\n font-size: 12px;\n line-height: 1;\n text-align: left;\n white-space: nowrap;\n }\n \n .markdown-body .csv-data .blob-num {\n padding: 10px var(--base-size-8) 9px;\n text-align: right;\n background: var(--bgColor-default);\n border: 0;\n }\n \n .markdown-body .csv-data tr {\n border-top: 0;\n }\n \n .markdown-body .csv-data th {\n font-weight: var(--base-text-weight-semibold, 600);\n background: var(--bgColor-muted);\n border-top: 0;\n }\n \n .markdown-body [data-footnote-ref]::before {\n content: \"[\";\n }\n \n .markdown-body [data-footnote-ref]::after {\n content: \"]\";\n }\n \n .markdown-body .footnotes {\n font-size: 12px;\n color: var(--fgColor-muted);\n border-top: 1px solid var(--borderColor-default);\n }\n \n .markdown-body .footnotes ol {\n padding-left: var(--base-size-16);\n }\n \n .markdown-body .footnotes ol ul {\n display: inline-block;\n padding-left: var(--base-size-16);\n margin-top: var(--base-size-16);\n }\n \n .markdown-body .footnotes li {\n position: relative;\n }\n \n .markdown-body .footnotes li:target::before {\n position: absolute;\n top: calc(var(--base-size-8)*-1);\n right: calc(var(--base-size-8)*-1);\n bottom: calc(var(--base-size-8)*-1);\n left: calc(var(--base-size-24)*-1);\n pointer-events: none;\n content: \"\";\n border: 2px solid var(--borderColor-accent-emphasis);\n border-radius: 6px;\n }\n \n .markdown-body .footnotes li:target {\n color: var(--fgColor-default);\n }\n \n .markdown-body .footnotes .data-footnote-backref g-emoji {\n font-family: monospace;\n }\n \n .markdown-body body:has(:modal) {\n padding-right: var(--dialog-scrollgutter) !important;\n }\n \n .markdown-body .pl-c {\n color: var(--color-prettylights-syntax-comment);\n }\n \n .markdown-body .pl-c1,\n .markdown-body .pl-s .pl-v {\n color: var(--color-prettylights-syntax-constant);\n }\n \n .markdown-body .pl-e,\n .markdown-body .pl-en {\n color: var(--color-prettylights-syntax-entity);\n }\n \n .markdown-body .pl-smi,\n .markdown-body .pl-s .pl-s1 {\n color: var(--color-prettylights-syntax-storage-modifier-import);\n }\n \n .markdown-body .pl-ent {\n color: var(--color-prettylights-syntax-entity-tag);\n }\n \n .markdown-body .pl-k {\n color: var(--color-prettylights-syntax-keyword);\n }\n \n .markdown-body .pl-s,\n .markdown-body .pl-pds,\n .markdown-body .pl-s .pl-pse .pl-s1,\n .markdown-body .pl-sr,\n .markdown-body .pl-sr .pl-cce,\n .markdown-body .pl-sr .pl-sre,\n .markdown-body .pl-sr .pl-sra {\n color: var(--color-prettylights-syntax-string);\n }\n \n .markdown-body .pl-v,\n .markdown-body .pl-smw {\n color: var(--color-prettylights-syntax-variable);\n }\n \n .markdown-body .pl-bu {\n color: var(--color-prettylights-syntax-brackethighlighter-unmatched);\n }\n \n .markdown-body .pl-ii {\n color: var(--color-prettylights-syntax-invalid-illegal-text);\n background-color: var(--color-prettylights-syntax-invalid-illegal-bg);\n }\n \n .markdown-body .pl-c2 {\n color: var(--color-prettylights-syntax-carriage-return-text);\n background-color: var(--color-prettylights-syntax-carriage-return-bg);\n }\n \n .markdown-body .pl-sr .pl-cce {\n font-weight: bold;\n color: var(--color-prettylights-syntax-string-regexp);\n }\n \n .markdown-body .pl-ml {\n color: var(--color-prettylights-syntax-markup-list);\n }\n \n .markdown-body .pl-mh,\n .markdown-body .pl-mh .pl-en,\n .markdown-body .pl-ms {\n font-weight: bold;\n color: var(--color-prettylights-syntax-markup-heading);\n }\n \n .markdown-body .pl-mi {\n font-style: italic;\n color: var(--color-prettylights-syntax-markup-italic);\n }\n \n .markdown-body .pl-mb {\n font-weight: bold;\n color: var(--color-prettylights-syntax-markup-bold);\n }\n \n .markdown-body .pl-md {\n color: var(--color-prettylights-syntax-markup-deleted-text);\n background-color: var(--color-prettylights-syntax-markup-deleted-bg);\n }\n \n .markdown-body .pl-mi1 {\n color: var(--color-prettylights-syntax-markup-inserted-text);\n background-color: var(--color-prettylights-syntax-markup-inserted-bg);\n }\n \n .markdown-body .pl-mc {\n color: var(--color-prettylights-syntax-markup-changed-text);\n background-color: var(--color-prettylights-syntax-markup-changed-bg);\n }\n \n .markdown-body .pl-mi2 {\n color: var(--color-prettylights-syntax-markup-ignored-text);\n background-color: var(--color-prettylights-syntax-markup-ignored-bg);\n }\n \n .markdown-body .pl-mdr {\n font-weight: bold;\n color: var(--color-prettylights-syntax-meta-diff-range);\n }\n \n .markdown-body .pl-ba {\n color: var(--color-prettylights-syntax-brackethighlighter-angle);\n }\n \n .markdown-body .pl-sg {\n color: var(--color-prettylights-syntax-sublimelinter-gutter-mark);\n }\n \n .markdown-body .pl-corl {\n text-decoration: underline;\n color: var(--color-prettylights-syntax-constant-other-reference-link);\n }\n \n .markdown-body [role=button]:focus:not(:focus-visible),\n .markdown-body [role=tabpanel][tabindex=\"0\"]:focus:not(:focus-visible),\n .markdown-body button:focus:not(:focus-visible),\n .markdown-body summary:focus:not(:focus-visible),\n .markdown-body a:focus:not(:focus-visible) {\n outline: none;\n box-shadow: none;\n }\n \n .markdown-body [tabindex=\"0\"]:focus:not(:focus-visible),\n .markdown-body details-dialog:focus:not(:focus-visible) {\n outline: none;\n }\n \n .markdown-body g-emoji {\n display: inline-block;\n min-width: 1ch;\n font-family: \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 1em;\n font-style: normal !important;\n font-weight: var(--base-text-weight-normal, 400);\n line-height: 1;\n vertical-align: -0.075em;\n }\n \n .markdown-body g-emoji img {\n width: 1em;\n height: 1em;\n }\n \n .markdown-body .task-list-item {\n list-style-type: none;\n }\n \n .markdown-body .task-list-item label {\n font-weight: var(--base-text-weight-normal, 400);\n }\n \n .markdown-body .task-list-item.enabled label {\n cursor: pointer;\n }\n \n .markdown-body .task-list-item+.task-list-item {\n margin-top: var(--base-size-4);\n }\n \n .markdown-body .task-list-item .handle {\n display: none;\n }\n \n .markdown-body .task-list-item-checkbox {\n margin: 0 .2em .25em -1.4em;\n vertical-align: middle;\n }\n \n .markdown-body ul:dir(rtl) .task-list-item-checkbox {\n margin: 0 -1.6em .25em .2em;\n }\n \n .markdown-body ol:dir(rtl) .task-list-item-checkbox {\n margin: 0 -1.6em .25em .2em;\n }\n \n .markdown-body .contains-task-list:hover .task-list-item-convert-container,\n .markdown-body .contains-task-list:focus-within .task-list-item-convert-container {\n display: block;\n width: auto;\n height: 24px;\n overflow: visible;\n clip: auto;\n }\n \n .markdown-body ::-webkit-calendar-picker-indicator {\n filter: invert(50%);\n }\n \n .markdown-body .markdown-alert {\n padding: var(--base-size-8) var(--base-size-16);\n margin-bottom: var(--base-size-16);\n color: inherit;\n border-left: .25em solid var(--borderColor-default);\n }\n \n .markdown-body .markdown-alert>:first-child {\n margin-top: 0;\n }\n \n .markdown-body .markdown-alert>:last-child {\n margin-bottom: 0;\n }\n \n .markdown-body .markdown-alert .markdown-alert-title {\n display: flex;\n font-weight: var(--base-text-weight-medium, 500);\n align-items: center;\n line-height: 1;\n }\n \n .markdown-body .markdown-alert.markdown-alert-note {\n border-left-color: var(--borderColor-accent-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title {\n color: var(--fgColor-accent);\n }\n \n .markdown-body .markdown-alert.markdown-alert-important {\n border-left-color: var(--borderColor-done-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title {\n color: var(--fgColor-done);\n }\n \n .markdown-body .markdown-alert.markdown-alert-warning {\n border-left-color: var(--borderColor-attention-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title {\n color: var(--fgColor-attention);\n }\n \n .markdown-body .markdown-alert.markdown-alert-tip {\n border-left-color: var(--borderColor-success-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title {\n color: var(--fgColor-success);\n }\n \n .markdown-body .markdown-alert.markdown-alert-caution {\n border-left-color: var(--borderColor-danger-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title {\n color: var(--fgColor-danger);\n }\n \n .markdown-body>*:first-child>.heading-element:first-child {\n margin-top: 0 !important;\n }\n \n .markdown-body .highlight pre:has(+.zeroclipboard-container) {\n min-height: 52px;\n }",":host {\n display: inline-block;\n}\n\n.pcm-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-weight: 400;\n white-space: nowrap;\n text-align: center;\n background-image: none;\n border: 1px solid transparent;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);\n user-select: none;\n touch-action: manipulation;\n height: 32px;\n padding: 0 15px;\n font-size: 14px;\n border-radius: 4px;\n color: rgba(0, 0, 0, 0.85);\n background-color: white;\n border-color: #d9d9d9;\n outline: none;\n}\n\n.pcm-button:hover {\n border-color: #40a9ff;\n color: #40a9ff;\n}\n\n.pcm-button:active {\n border-color: #096dd9;\n color: #096dd9;\n}\n\n/* 按钮类型样式 */\n.pcm-button-default {\n background-color: white;\n border-color: #d9d9d9;\n color: rgba(0, 0, 0, 0.85);\n}\n\n.pcm-button-primary {\n background-color: #1677FF;\n border-color: #1677FF;\n color: white;\n}\n\n.pcm-button-primary:hover {\n background-color: #40a9ff;\n border-color: #40a9ff;\n color: white;\n}\n\n.pcm-button-primary:active {\n background-color: #096dd9;\n border-color: #096dd9;\n color: white;\n}\n\n.pcm-button-dashed {\n background-color: white;\n border-color: #d9d9d9;\n border-style: dashed;\n}\n\n.pcm-button-text {\n background-color: transparent;\n border-color: transparent;\n color: rgba(0, 0, 0, 0.85);\n box-shadow: none;\n}\n\n.pcm-button-text:hover {\n background-color: rgba(0, 0, 0, 0.05);\n border-color: transparent;\n color: rgba(0, 0, 0, 0.85);\n}\n\n.pcm-button-link {\n background-color: transparent;\n border-color: transparent;\n color: #1677FF;\n box-shadow: none;\n}\n\n.pcm-button-link:hover {\n color: #40a9ff;\n background-color: transparent;\n border-color: transparent;\n}\n\n/* 按钮尺寸样式 */\n.pcm-button-large {\n height: 40px;\n padding: 0 20px;\n font-size: 16px;\n}\n\n.pcm-button-small {\n height: 24px;\n padding: 0 7px;\n font-size: 12px;\n}\n\n/* 按钮形状样式 */\n.pcm-button-circle {\n min-width: 32px;\n padding: 0;\n border-radius: 50%;\n}\n\n.pcm-button-large.pcm-button-circle {\n min-width: 40px;\n}\n\n.pcm-button-small.pcm-button-circle {\n min-width: 24px;\n}\n\n.pcm-button-round {\n border-radius: 40px;\n}\n\n/* 按钮加载状态样式 */\n.pcm-button-loading {\n opacity: 0.65;\n cursor: default;\n}\n\n.loading-icon {\n width: 14px;\n height: 14px;\n margin-right: 8px;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: loading-spin 1s infinite linear;\n display: inline-block;\n}\n\n@keyframes loading-spin {\n 0% { \n transform: rotate(0deg); \n }\n 100% { \n transform: rotate(360deg); \n }\n}\n\n/* 按钮禁用状态样式 */\n.pcm-button-disabled {\n cursor: not-allowed;\n opacity: 0.65;\n}\n\n.pcm-button-disabled:hover,\n.pcm-button-disabled:active {\n color: rgba(0, 0, 0, 0.25);\n background-color: #f5f5f5;\n border-color: #d9d9d9;\n}\n\n.pcm-button-primary.pcm-button-disabled:hover,\n.pcm-button-primary.pcm-button-disabled:active {\n background-color: #1677FF;\n border-color: #1677FF;\n color: white;\n}\n\n/* 图标样式 */\n.button-icon {\n margin-right: 8px;\n display: inline-flex;\n align-items: center;\n}\n\n.button-icon img {\n width: 16px;\n height: 16px;\n}\n\n.pcm-button-small .button-icon img {\n width: 12px;\n height: 12px;\n}\n\n.pcm-button-large .button-icon img {\n width: 18px;\n height: 18px;\n}\n\n/* 块级按钮样式 */\n.pcm-button-block {\n width: 100%;\n display: flex;\n}\n","import { Component, Prop, h} from '@stencil/core';\n\n/**\n * 按钮组件\n * 一个简化版的类似于 ant-design 的按钮组件,支持自定义文字、颜色、圆角等属性\n */\n@Component({\n tag: 'pcm-button',\n styleUrl: 'pcm-button.css',\n shadow: true,\n})\nexport class PcmButton {\n /**\n * 按钮类型\n * 可选值: 'primary', 'default', 'dashed', 'text', 'link'\n */\n @Prop() type: 'primary' | 'default' | 'dashed' | 'text' | 'link' = 'default';\n\n /**\n * 按钮尺寸\n * 可选值: 'large', 'middle', 'small'\n */\n @Prop() size: 'large' | 'middle' | 'small' = 'middle';\n\n /**\n * 是否为加载状态\n */\n @Prop() loading: boolean = false;\n\n /**\n * 是否为禁用状态\n */\n @Prop() disabled: boolean = false;\n\n /**\n * 设置按钮的图标\n * 使用图标的URL或者base64字符串\n */\n @Prop() icon: string = 'https://pub.pincaimao.com/static/common/i_pcm_logo.png';\n\n\n /**\n * 自定义按钮形状\n * 可选值: 'default', 'circle', 'round'\n */\n @Prop() shape: 'default' | 'circle' | 'round' = 'default';\n\n /**\n * 自定义按钮背景色\n */\n @Prop() backgroundColor: string = '';\n\n /**\n * 自定义按钮文字颜色\n */\n @Prop() textColor: string = '';\n\n /**\n * 自定义按钮边框颜色\n */\n @Prop() borderColor: string = '';\n\n /**\n * 自定义按钮圆角大小(像素)\n */\n @Prop() borderRadius: number = null;\n\n /**\n * 按钮宽度(像素或百分比)\n */\n @Prop() width: string = '';\n\n /**\n * 是否为块级按钮(宽度撑满父元素)\n */\n @Prop() block: boolean = false;\n\n /**\n * 按钮边框样式\n * 可选值: 'solid', 'dashed', 'dotted', 'none'\n */\n @Prop() borderStyle: 'solid' | 'dashed' | 'dotted' | 'none' = 'solid';\n\n render() {\n // 计算样式类名\n const classes = {\n 'pcm-button': true,\n [`pcm-button-${this.type}`]: true,\n [`pcm-button-${this.size}`]: true,\n [`pcm-button-${this.shape}`]: true,\n 'pcm-button-loading': this.loading,\n 'pcm-button-disabled': this.disabled,\n 'pcm-button-block': this.block\n };\n\n // 计算自定义样式\n const customStyle = {};\n if (this.backgroundColor) {\n customStyle['backgroundColor'] = this.backgroundColor;\n }\n if (this.textColor) {\n customStyle['color'] = this.textColor;\n }\n if (this.borderColor) {\n customStyle['borderColor'] = this.borderColor;\n }\n if (this.borderRadius !== null) {\n customStyle['borderRadius'] = `${this.borderRadius}px`;\n }\n if (this.width) {\n customStyle['width'] = this.width;\n }\n if (this.borderStyle) {\n customStyle['borderStyle'] = this.borderStyle;\n }\n\n return (\n <button\n class={Object.keys(classes).filter(key => classes[key]).join(' ')}\n style={customStyle}\n disabled={this.disabled}\n type=\"button\"\n >\n {this.loading && (\n <span class=\"loading-icon\"></span>\n )}\n {this.icon && !this.loading && (\n <span class=\"button-icon\">\n <img src={this.icon} alt=\"\" />\n </span>\n )}\n <slot />\n </button>\n );\n }\n}\n",":host {\n display: block;\n}\n\n/* 加载和错误状态样式 */\n.loading-container,\n.error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 200px;\n width: 100%;\n color: #86909C;\n font-size: 14px;\n text-align: center;\n}\n\n.loading-spinner {\n width: 32px;\n height: 32px;\n border: 3px solid #f3f3f3;\n border-top: 3px solid #1677FF;\n border-radius: 50%;\n margin-bottom: 12px;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.error-icon {\n width: 32px;\n height: 32px;\n background-color: #FFF0F0;\n color: #F53F3F;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 20px;\n font-weight: bold;\n margin-bottom: 12px;\n}\n\n.error-message {\n color: #86909C;\n max-width: 80%;\n}\n\n.card-container {\n border-radius: 8px;\n padding: 16px;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n flex-direction: column;\n background-color: #ffffff;\n border: 1px solid #E5E6EB;\n position: relative;\n height: 100%;\n min-width: 300px;\n}\n\n.card-container:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 21, 41, 0.08);\n}\n\n.card-header {\n display: flex;\n width: 100%;\n padding-bottom: 16px;\n gap: 12px;\n}\n\n.card-icon {\n width: 64px;\n height: 64px;\n margin-right: 12px;\n flex-shrink: 0;\n overflow: hidden;\n border-radius: 2px;\n background-color: #f8f9fa;\n}\n\n.card-icon img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n\n.card-info {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.title-row {\n display: flex;\n align-items: center;\n}\n\n.title-wrapper {\n flex: 1;\n margin-right: 8px;\n overflow: hidden;\n}\n\n.card-title {\n font-size: 18px;\n font-weight: 700;\n color: #1D2129;\n line-height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: block;\n width: 100%;\n}\n\n.chat-tag {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n padding: 0 8px;\n background-color: #F2F7E8;\n color: #56961F;\n font-size: 12px;\n border-radius: 4px;\n font-weight: 500;\n flex-shrink: 0;\n}\n\n.author-row {\n display: flex;\n align-items: center;\n margin-top: 8px;\n}\n\n.author-avatar {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n margin-right: 4px;\n background-color: #f8f9fa;\n overflow: hidden;\n}\n\n.author-name {\n font-size: 12px;\n color: #86909C;\n}\n\n.card-description {\n font-size: 12px;\n color: #86909C;\n margin-top: 8px;\n line-height: 18px;\n height: 54px;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: pre-line;\n word-break: break-word;\n}\n\n.card-footer {\n padding-top: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-top: 1px solid #E5E6EB;\n}\n\n.stats-container {\n display: flex;\n align-items: center;\n flex: 1;\n}\n\n.stat-item {\n display: flex;\n align-items: center;\n margin-right: 8px;\n color: #86909C;\n}\n\n.stat-icon {\n width: 16px;\n height: 16px;\n margin-right: 4px;\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n}\n\n.user-icon {\n /* 为图标添加SVG背景 */\n background-image: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' focusable='false' aria-hidden='true'%3E%3Cpath d='M12 14c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6Zm0-10C9.8 4 8 5.8 8 8s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4Z' fill='currentColor'%3E%3C/path%3E%3Cpath d='M21.9 20.6c-.1-.2-2.3-5.6-9.9-5.6-7.6 0-9.8 5.4-9.9 5.6-.2.5 0 1.1.6 1.3.5.2 1.1 0 1.3-.5 0-.2 1.8-4.4 8-4.4s8 4.2 8.1 4.4c.2.5.8.8 1.3.5.5-.2.7-.8.5-1.3Z' fill='currentColor'%3E%3C/path%3E%3C/svg%3E\");\n}\n\n.star-icon {\n /* 为图标添加SVG背景 */\n background-image: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' focusable='false' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M12 5.03 9.57 9.1c-.17.3-.46.5-.8.55l-4.3.79 3 3.46c.22.26.32.6.28.93l-.62 4.46 4.41-1.9c.3-.12.63-.12.92 0l4.4 1.9-.6-4.46c-.05-.34.05-.67.27-.93l3-3.46-4.3-.79a1.17 1.17 0 0 1-.8-.55L12 5.03Zm-1-2.46a1.16 1.16 0 0 1 2 0l3.03 5.07 5.51 1c.89.17 1.26 1.24.68 1.92l-3.8 4.4.77 5.71c.13.9-.78 1.6-1.61 1.23L12 19.5l-5.58 2.4a1.17 1.17 0 0 1-1.61-1.23l.78-5.7-3.8-4.4a1.17 1.17 0 0 1 .67-1.92l5.51-1L11 2.56Z' fill='currentColor'%3E%3C/path%3E%3C/svg%3E\");\n}\n\n.video-icon {\n /* 为图标添加SVG背景 */\n background-image: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' focusable='false' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4 2a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H4Zm0 2h16v16H4V4Zm5.5 3.13A1 1 0 0 0 8 8v8a1 1 0 0 0 1.5.87l7-4a1 1 0 0 0 0-1.74l-7-4ZM13.98 12 10 14.28V9.72L13.98 12Z' fill='currentColor'%3E%3C/path%3E%3C/svg%3E\");\n}\n\n.stat-value {\n font-size: 12px;\n}\n\n.use-button {\n font-size: 12px;\n color: #86909C;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.use-button:hover {\n color: #1677FF;\n}\n\n/* 响应式样式 */\n@media screen and (max-width: 768px) {\n .card-container {\n padding: 12px;\n }\n \n .card-header {\n gap: 8px;\n padding-bottom: 12px;\n }\n \n .card-icon {\n width: 48px;\n height: 48px;\n }\n \n .card-title {\n font-size: 16px;\n line-height: 20px;\n }\n \n .card-description {\n font-size: 12px;\n line-height: 16px;\n height: 48px;\n }\n} ","'use strict';\n\nfunction index({ interruptPatterns = [], skipEmptyRows = true } = {}) {\n return {\n extensions: [\n {\n name: 'spanTable',\n level: 'block', // Is this a block-level or inline-level tokenizer?\n start(src) { return src.match(/\\n *([^\\n ].*\\|.*)\\n/m)?.index; }, // Hint to Marked.js to stop and check for a match\n tokenizer(src, tokens) {\n // const regex = this.tokenizer.rules.block.table;\n let regexString = '^ *([^\\\\n ].*\\\\|.*\\\\n(?: *[^\\\\s].*\\\\n)*?)' // Header\n + ' {0,3}(?:\\\\| *)?(:?-+(?: *(?:100|[1-9][0-9]?%) *-+)?:? *(?:\\\\| *:?-+(?: *(?:100|[1-9][0-9]?%) *-+)?:? *)*)(?:\\\\| *)?' // Align\n + '(?:\\\\n((?:(?! *\\\\n| {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})' // Cells\n + '(?:\\\\n+|$)| {0,3}#{1,6}(?:\\\\s|$)| {0,3}>| {4}[^\\\\n]| {0,3}(?:`{3,}'\n + '(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n| {0,3}(?:[*+-]|1[.)]) |'\n + '<\\\\/?(?:address|article|aside|base|basefont|blockquote|body'\n + '|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt'\n + '|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]'\n + '|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem'\n + '|meta|nav|noframes|ol|optgroup|option|p|param|section|source'\n + '|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)'\n + '(?: +|\\\\n|\\\\/?>)|<(?:script|pre|style|textarea|!--)endRegex).*(?:\\\\n|$))*)\\\\n*|$)'; // Cells\n\n regexString = regexString.replace('endRegex', interruptPatterns.map(str => `|(?:${str})`).join(''));\n const widthRegex = / *(?:100|[1-9][0-9]?%) */g;\n const regex = new RegExp(regexString);\n const cap = regex.exec(src);\n\n if (cap) {\n const item = {\n type: 'spanTable',\n header: cap[1].replace(/\\n$/, '').split('\\n'),\n align: cap[2].replace(widthRegex, '').replace(/^ *|\\| *$/g, '').split(/ *\\| */),\n rows: cap[3]?.trim() ? cap[3].replace(/\\n[ \\t]*$/, '').split('\\n') : [],\n width: cap[2].replace(/:/g, '').replace(/-+| /g, '').split('|')\n };\n\n // Get first header row to determine how many columns\n item.header[0] = splitCells(item.header[0]);\n\n const colCount = item.header[0].reduce((length, header) => {\n return length + header.colspan;\n }, 0);\n\n if (colCount === item.align.length) {\n item.raw = cap[0];\n\n let i, j, k, row;\n\n // Get alignment row (:---:)\n let l = item.align.length;\n\n for (i = 0; i < l; i++) {\n if (/^ *-+: *$/.test(item.align[i])) {\n item.align[i] = 'right';\n } else if (/^ *:-+: *$/.test(item.align[i])) {\n item.align[i] = 'center';\n } else if (/^ *:-+ *$/.test(item.align[i])) {\n item.align[i] = 'left';\n } else {\n item.align[i] = null;\n }\n }\n\n // Get any remaining header rows\n l = item.header.length;\n for (i = 1; i < l; i++) {\n item.header[i] = splitCells(item.header[i], colCount, item.header[i - 1], skipEmptyRows);\n }\n\n // Get main table cells\n l = item.rows.length;\n for (i = 0; i < l; i++) {\n item.rows[i] = splitCells(item.rows[i], colCount, item.rows[i - 1], skipEmptyRows);\n }\n\n // header child tokens\n l = item.header.length;\n for (j = 0; j < l; j++) {\n row = item.header[j];\n for (k = 0; k < row.length; k++) {\n row[k].tokens = [];\n this.lexer.inline(row[k].text, row[k].tokens);\n }\n }\n\n // cell child tokens\n l = item.rows.length;\n for (j = 0; j < l; j++) {\n row = item.rows[j];\n for (k = 0; k < row.length; k++) {\n row[k].tokens = [];\n this.lexer.inline(row[k].text, row[k].tokens);\n }\n }\n return item;\n }\n }\n },\n renderer(token) {\n let i, j, row, cell, col, text;\n let output = '<table>';\n output += '<thead>';\n for (i = 0; i < token.header.length; i++) {\n row = token.header[i];\n let col = 0;\n output += '<tr>';\n for (j = 0; j < row.length; j++) {\n cell = row[j];\n text = this.parser.parseInline(cell.tokens);\n output += getTableCell(text, cell, 'th', token.align[col], token.width[col]);\n col += cell.colspan;\n }\n output += '</tr>';\n }\n output += '</thead>';\n if (token.rows.length) {\n output += '<tbody>';\n for (i = 0; i < token.rows.length; i++) {\n row = token.rows[i];\n col = 0;\n if (!row[0].emptyRow) {\n output += '<tr>';\n for (j = 0; j < row.length; j++) {\n cell = row[j];\n text = this.parser.parseInline(cell.tokens);\n output += getTableCell(text, cell, 'td', token.align[col], token.width[col]);\n col += cell.colspan;\n }\n output += '</tr>';\n }\n }\n output += '</tbody>';\n }\n output += '</table>';\n return output;\n }\n }\n ]\n };\n}\n\nconst getTableCell = (text, cell, type, align, width) => {\n if (!cell.rowspan) {\n return '';\n }\n const tag = `<${type}`\n + `${cell.colspan > 1 ? ` colspan=${cell.colspan}` : ''}`\n + `${cell.rowspan > 1 ? ` rowspan=${cell.rowspan}` : ''}`\n + `${align ? ` align=${align}` : ''}`\n + `${width ? ` width=${width}` : ''}>`;\n return `${tag + text}</${type}>\\n`;\n};\n\nconst splitCells = (tableRow, count, prevRow = [], skipEmptyRows) => {\n const cells = [...tableRow.trim().matchAll(/(?:[^|\\\\]|\\\\.?)+(?:\\|+|$)/g)].map((x) => x[0]);\n\n // Remove first/last cell in a row if whitespace only and no leading/trailing pipe\n if (!cells[0]?.trim()) { cells.shift(); }\n if (!cells[cells.length - 1]?.trim()) { cells.pop(); }\n\n let numCols = 0;\n let i, j, trimmedCell, prevCell, prevCols;\n\n for (i = 0; i < cells.length; i++) {\n trimmedCell = cells[i].split(/\\|+$/)[0];\n cells[i] = {\n rowspan: 1,\n colspan: Math.max(cells[i].length - trimmedCell.length, 1),\n text: trimmedCell.trim().replace(/\\\\\\|/g, '|')\n // display escaped pipes as normal character\n };\n\n // Handle Rowspan\n if (trimmedCell.slice(-1) === '^' && prevRow.length) {\n // Find matching cell in previous row\n prevCols = 0;\n for (j = 0; j < prevRow.length; j++) {\n prevCell = prevRow[j];\n if ((prevCols === numCols) && (prevCell.colspan === cells[i].colspan)) {\n // merge into matching cell in previous row (the \"target\")\n cells[i].rowSpanTarget = prevCell.rowSpanTarget ?? prevCell;\n cells[i].rowSpanTarget.text += ` ${cells[i].text.slice(0, -1)}`;\n cells[i].rowSpanTarget.rowspan += 1;\n cells[i].rowspan = 0;\n break;\n }\n prevCols += prevCell.colspan;\n if (prevCols > numCols) { break; }\n }\n }\n\n numCols += cells[i].colspan;\n }\n\n // If all cells have been merged, flag as an empty row\n if (cells.length > 0 && skipEmptyRows && cells.length === cells.filter((cell) => { return cell.rowspan === 0; }).length) {\n cells[0].emptyRow = true;\n for (i = 0; i < cells.length; i++) {\n cells[i].rowSpanTarget.rowspan -= 1;\n }\n }\n\n // Force main cell rows to match header column count\n if (numCols > count) {\n cells.splice(count);\n } else {\n while (numCols < count) {\n cells.push({\n rowspan: 1,\n colspan: 1,\n text: ''\n });\n numCols += 1;\n }\n }\n return cells;\n};\n\nmodule.exports = index;\n","\n.markdown-body {\n --base-size-4: 4px;\n --base-size-8: 8px;\n --base-size-16: 16px;\n --base-size-24: 24px;\n --base-size-40: 40px;\n --base-text-weight-normal: 400;\n --base-text-weight-medium: 500;\n --base-text-weight-semibold: 600;\n --fontStack-monospace: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;\n --fgColor-accent: Highlight;\n }\n \n @media (prefers-color-scheme: dark) {\n \n .markdown-body,\n [data-theme=\"dark\"] {\n /* dark */\n color-scheme: dark;\n --focus-outlineColor: #0969da;\n --fgColor-default: #1f2328;\n --fgColor-muted: #59636e;\n --fgColor-accent: #0969da;\n --fgColor-success: #1a7f37;\n --fgColor-attention: #9a6700;\n --fgColor-danger: #d1242f;\n --fgColor-done: #8250df;\n --bgColor-default: #ffffff;\n --bgColor-muted: #f6f8fa;\n --bgColor-neutral-muted: #818b981f;\n --bgColor-attention-muted: #fff8c5;\n --borderColor-default: #d1d9e0;\n --borderColor-muted: #d1d9e0b3;\n --borderColor-neutral-muted: #d1d9e0b3;\n --borderColor-accent-emphasis: #0969da;\n --borderColor-success-emphasis: #1a7f37;\n --borderColor-attention-emphasis: #9a6700;\n --borderColor-danger-emphasis: #cf222e;\n --borderColor-done-emphasis: #8250df;\n --color-prettylights-syntax-comment: #59636e;\n --color-prettylights-syntax-constant: #0550ae;\n --color-prettylights-syntax-constant-other-reference-link: #0a3069;\n --color-prettylights-syntax-entity: #6639ba;\n --color-prettylights-syntax-storage-modifier-import: #1f2328;\n --color-prettylights-syntax-entity-tag: #0550ae;\n --color-prettylights-syntax-keyword: #cf222e;\n --color-prettylights-syntax-string: #0a3069;\n --color-prettylights-syntax-variable: #953800;\n --color-prettylights-syntax-brackethighlighter-unmatched: #82071e;\n --color-prettylights-syntax-brackethighlighter-angle: #59636e;\n --color-prettylights-syntax-invalid-illegal-text: #f6f8fa;\n --color-prettylights-syntax-invalid-illegal-bg: #82071e;\n --color-prettylights-syntax-carriage-return-text: #f6f8fa;\n --color-prettylights-syntax-carriage-return-bg: #cf222e;\n --color-prettylights-syntax-string-regexp: #116329;\n --color-prettylights-syntax-markup-list: #3b2300;\n --color-prettylights-syntax-markup-heading: #0550ae;\n --color-prettylights-syntax-markup-italic: #1f2328;\n --color-prettylights-syntax-markup-bold: #1f2328;\n --color-prettylights-syntax-markup-deleted-text: #82071e;\n --color-prettylights-syntax-markup-deleted-bg: #ffebe9;\n --color-prettylights-syntax-markup-inserted-text: #116329;\n --color-prettylights-syntax-markup-inserted-bg: #dafbe1;\n --color-prettylights-syntax-markup-changed-text: #953800;\n --color-prettylights-syntax-markup-changed-bg: #ffd8b5;\n --color-prettylights-syntax-markup-ignored-text: #d1d9e0;\n --color-prettylights-syntax-markup-ignored-bg: #0550ae;\n --color-prettylights-syntax-meta-diff-range: #8250df;\n --color-prettylights-syntax-sublimelinter-gutter-mark: #818b98;\n }\n }\n \n @media (prefers-color-scheme: light) {\n \n .markdown-body,\n [data-theme=\"light\"] {\n /* light */\n color-scheme: light;\n --focus-outlineColor: #0969da;\n --fgColor-default: #1f2328;\n --fgColor-muted: #59636e;\n --fgColor-accent: #0969da;\n --fgColor-success: #1a7f37;\n --fgColor-attention: #9a6700;\n --fgColor-danger: #d1242f;\n --fgColor-done: #8250df;\n --bgColor-default: #ffffff;\n --bgColor-muted: #f6f8fa;\n --bgColor-neutral-muted: #818b981f;\n --bgColor-attention-muted: #fff8c5;\n --borderColor-default: #d1d9e0;\n --borderColor-muted: #d1d9e0b3;\n --borderColor-neutral-muted: #d1d9e0b3;\n --borderColor-accent-emphasis: #0969da;\n --borderColor-success-emphasis: #1a7f37;\n --borderColor-attention-emphasis: #9a6700;\n --borderColor-danger-emphasis: #cf222e;\n --borderColor-done-emphasis: #8250df;\n --color-prettylights-syntax-comment: #59636e;\n --color-prettylights-syntax-constant: #0550ae;\n --color-prettylights-syntax-constant-other-reference-link: #0a3069;\n --color-prettylights-syntax-entity: #6639ba;\n --color-prettylights-syntax-storage-modifier-import: #1f2328;\n --color-prettylights-syntax-entity-tag: #0550ae;\n --color-prettylights-syntax-keyword: #cf222e;\n --color-prettylights-syntax-string: #0a3069;\n --color-prettylights-syntax-variable: #953800;\n --color-prettylights-syntax-brackethighlighter-unmatched: #82071e;\n --color-prettylights-syntax-brackethighlighter-angle: #59636e;\n --color-prettylights-syntax-invalid-illegal-text: #f6f8fa;\n --color-prettylights-syntax-invalid-illegal-bg: #82071e;\n --color-prettylights-syntax-carriage-return-text: #f6f8fa;\n --color-prettylights-syntax-carriage-return-bg: #cf222e;\n --color-prettylights-syntax-string-regexp: #116329;\n --color-prettylights-syntax-markup-list: #3b2300;\n --color-prettylights-syntax-markup-heading: #0550ae;\n --color-prettylights-syntax-markup-italic: #1f2328;\n --color-prettylights-syntax-markup-bold: #1f2328;\n --color-prettylights-syntax-markup-deleted-text: #82071e;\n --color-prettylights-syntax-markup-deleted-bg: #ffebe9;\n --color-prettylights-syntax-markup-inserted-text: #116329;\n --color-prettylights-syntax-markup-inserted-bg: #dafbe1;\n --color-prettylights-syntax-markup-changed-text: #953800;\n --color-prettylights-syntax-markup-changed-bg: #ffd8b5;\n --color-prettylights-syntax-markup-ignored-text: #d1d9e0;\n --color-prettylights-syntax-markup-ignored-bg: #0550ae;\n --color-prettylights-syntax-meta-diff-range: #8250df;\n --color-prettylights-syntax-sublimelinter-gutter-mark: #818b98;\n }\n }\n \n .markdown-body {\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\";\n font-size: 16px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n \n .markdown-body .octicon {\n display: inline-block;\n fill: currentColor;\n vertical-align: text-bottom;\n }\n \n .markdown-body h1:hover .anchor .octicon-link:before,\n .markdown-body h2:hover .anchor .octicon-link:before,\n .markdown-body h3:hover .anchor .octicon-link:before,\n .markdown-body h4:hover .anchor .octicon-link:before,\n .markdown-body h5:hover .anchor .octicon-link:before,\n .markdown-body h6:hover .anchor .octicon-link:before {\n width: 16px;\n height: 16px;\n content: ' ';\n display: inline-block;\n background-color: currentColor;\n -webkit-mask-image: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>\");\n mask-image: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>\");\n }\n \n .markdown-body details,\n .markdown-body figcaption,\n .markdown-body figure {\n display: block;\n }\n \n .markdown-body summary {\n display: list-item;\n }\n \n .markdown-body [hidden] {\n display: none !important;\n }\n \n .markdown-body a {\n background-color: transparent;\n color: var(--fgColor-accent);\n text-decoration: none;\n }\n \n .markdown-body abbr[title] {\n border-bottom: none;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n \n .markdown-body b,\n .markdown-body strong {\n font-weight: var(--base-text-weight-semibold, 600);\n }\n \n .markdown-body dfn {\n font-style: italic;\n }\n \n .markdown-body h1 {\n margin: .67em 0;\n font-weight: var(--base-text-weight-semibold, 600);\n padding-bottom: .3em;\n font-size: 1.5em;\n border-bottom: 1px solid var(--borderColor-muted);\n }\n \n .markdown-body mark {\n background-color: var(--bgColor-attention-muted);\n color: var(--fgColor-default);\n }\n \n .markdown-body small {\n font-size: 90%;\n }\n \n .markdown-body sub,\n .markdown-body sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n \n .markdown-body sub {\n bottom: -0.25em;\n }\n \n .markdown-body sup {\n top: -0.5em;\n }\n \n .markdown-body img {\n border-style: none;\n max-width: 100%;\n box-sizing: content-box;\n }\n \n .markdown-body code,\n .markdown-body kbd,\n .markdown-body pre,\n .markdown-body samp {\n font-family: monospace;\n font-size: 1em;\n }\n \n .markdown-body figure {\n margin: 1em var(--base-size-40);\n }\n \n .markdown-body hr {\n box-sizing: content-box;\n overflow: hidden;\n background: transparent;\n border-bottom: 1px solid var(--borderColor-muted);\n height: .25em;\n padding: 0;\n margin: var(--base-size-24) 0;\n background-color: var(--borderColor-default);\n border: 0;\n }\n \n .markdown-body input {\n font: inherit;\n margin: 0;\n overflow: visible;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n }\n \n .markdown-body [type=button],\n .markdown-body [type=reset],\n .markdown-body [type=submit] {\n -webkit-appearance: button;\n appearance: button;\n }\n \n .markdown-body [type=checkbox],\n .markdown-body [type=radio] {\n box-sizing: border-box;\n padding: 0;\n }\n \n .markdown-body [type=number]::-webkit-inner-spin-button,\n .markdown-body [type=number]::-webkit-outer-spin-button {\n height: auto;\n }\n \n .markdown-body [type=search]::-webkit-search-cancel-button,\n .markdown-body [type=search]::-webkit-search-decoration {\n -webkit-appearance: none;\n appearance: none;\n }\n \n .markdown-body ::-webkit-input-placeholder {\n color: inherit;\n opacity: .54;\n }\n \n .markdown-body ::-webkit-file-upload-button {\n -webkit-appearance: button;\n appearance: button;\n font: inherit;\n }\n \n .markdown-body a:hover {\n text-decoration: underline;\n }\n \n .markdown-body ::placeholder {\n color: var(--fgColor-muted);\n opacity: 1;\n }\n \n .markdown-body hr::before {\n display: table;\n content: \"\";\n }\n \n .markdown-body hr::after {\n display: table;\n clear: both;\n content: \"\";\n }\n \n .markdown-body table {\n border-spacing: 0;\n border-collapse: collapse;\n display: block;\n width: max-content;\n max-width: 100%;\n overflow: auto;\n font-variant: tabular-nums;\n }\n \n .markdown-body td,\n .markdown-body th {\n padding: 0;\n }\n \n .markdown-body details summary {\n cursor: pointer;\n }\n \n .markdown-body a:focus,\n .markdown-body [role=button]:focus,\n .markdown-body input[type=radio]:focus,\n .markdown-body input[type=checkbox]:focus {\n outline: 2px solid var(--focus-outlineColor);\n outline-offset: -2px;\n box-shadow: none;\n }\n \n .markdown-body a:focus:not(:focus-visible),\n .markdown-body [role=button]:focus:not(:focus-visible),\n .markdown-body input[type=radio]:focus:not(:focus-visible),\n .markdown-body input[type=checkbox]:focus:not(:focus-visible) {\n outline: solid 1px transparent;\n }\n \n .markdown-body a:focus-visible,\n .markdown-body [role=button]:focus-visible,\n .markdown-body input[type=radio]:focus-visible,\n .markdown-body input[type=checkbox]:focus-visible {\n outline: 2px solid var(--focus-outlineColor);\n outline-offset: -2px;\n box-shadow: none;\n }\n \n .markdown-body a:not([class]):focus,\n .markdown-body a:not([class]):focus-visible,\n .markdown-body input[type=radio]:focus,\n .markdown-body input[type=radio]:focus-visible,\n .markdown-body input[type=checkbox]:focus,\n .markdown-body input[type=checkbox]:focus-visible {\n outline-offset: 0;\n }\n \n .markdown-body kbd {\n display: inline-block;\n padding: var(--base-size-4);\n font: 11px var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);\n line-height: 10px;\n color: var(--fgColor-default);\n vertical-align: middle;\n background-color: var(--bgColor-muted);\n border: solid 1px var(--borderColor-neutral-muted);\n border-bottom-color: var(--borderColor-neutral-muted);\n border-radius: 6px;\n box-shadow: inset 0 -1px 0 var(--borderColor-neutral-muted);\n }\n \n .markdown-body h1,\n .markdown-body h2,\n .markdown-body h3,\n .markdown-body h4,\n .markdown-body h5,\n .markdown-body h6 {\n margin-top: var(--base-size-24);\n margin-bottom: var(--base-size-16);\n font-weight: var(--base-text-weight-semibold, 600);\n line-height: 1.25;\n }\n \n .markdown-body h2 {\n font-weight: var(--base-text-weight-semibold, 600);\n padding-bottom: .3em;\n font-size: 1.2em;\n border-bottom: 1px solid var(--borderColor-muted);\n }\n \n .markdown-body h3 {\n font-weight: var(--base-text-weight-semibold, 600);\n font-size: 1.05em;\n }\n \n .markdown-body h4 {\n font-weight: var(--base-text-weight-semibold, 600);\n font-size: 0.875em;\n }\n \n .markdown-body h5 {\n font-weight: var(--base-text-weight-semibold, 600);\n font-size: .85em;\n }\n \n .markdown-body h6 {\n font-weight: var(--base-text-weight-semibold, 600);\n font-size: .80em;\n color: var(--fgColor-muted);\n }\n \n .markdown-body p {\n margin-top: 0;\n margin-bottom: 10px;\n }\n \n .markdown-body blockquote {\n margin: 0;\n padding: 0 1em;\n color: var(--fgColor-muted);\n border-left: .25em solid var(--borderColor-default);\n }\n \n .markdown-body ul,\n .markdown-body ol {\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 2em;\n }\n \n .markdown-body ol ol,\n .markdown-body ul ol {\n list-style-type: lower-roman;\n }\n \n .markdown-body ul ul ol,\n .markdown-body ul ol ol,\n .markdown-body ol ul ol,\n .markdown-body ol ol ol {\n list-style-type: lower-alpha;\n }\n \n .markdown-body dd {\n margin-left: 0;\n }\n \n .markdown-body tt,\n .markdown-body code,\n .markdown-body samp {\n font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);\n font-size: 12px;\n }\n \n .markdown-body pre {\n margin-top: 0;\n margin-bottom: 0;\n font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace);\n font-size: 12px;\n word-wrap: normal;\n }\n \n .markdown-body .octicon {\n display: inline-block;\n overflow: visible !important;\n vertical-align: text-bottom;\n fill: currentColor;\n }\n \n .markdown-body input::-webkit-outer-spin-button,\n .markdown-body input::-webkit-inner-spin-button {\n margin: 0;\n appearance: none;\n }\n \n .markdown-body .mr-2 {\n margin-right: var(--base-size-8, 8px) !important;\n }\n \n .markdown-body::before {\n display: table;\n content: \"\";\n }\n \n .markdown-body::after {\n display: table;\n clear: both;\n content: \"\";\n }\n \n .markdown-body>*:first-child {\n margin-top: 0 !important;\n }\n \n .markdown-body>*:last-child {\n margin-bottom: 0 !important;\n }\n \n .markdown-body a:not([href]) {\n color: inherit;\n text-decoration: none;\n }\n \n .markdown-body .absent {\n color: var(--fgColor-danger);\n }\n \n .markdown-body .anchor {\n float: left;\n padding-right: var(--base-size-4);\n margin-left: -20px;\n line-height: 1;\n }\n \n .markdown-body .anchor:focus {\n outline: none;\n }\n \n .markdown-body p,\n .markdown-body blockquote,\n .markdown-body ul,\n .markdown-body ol,\n .markdown-body dl,\n .markdown-body table,\n .markdown-body pre,\n .markdown-body details {\n margin-top: 0;\n margin-bottom: var(--base-size-16);\n font-size: 16px;\n font-weight: 400;\n }\n \n .markdown-body blockquote>:first-child {\n margin-top: 0;\n }\n \n .markdown-body blockquote>:last-child {\n margin-bottom: 0;\n }\n \n .markdown-body h1 .octicon-link,\n .markdown-body h2 .octicon-link,\n .markdown-body h3 .octicon-link,\n .markdown-body h4 .octicon-link,\n .markdown-body h5 .octicon-link,\n .markdown-body h6 .octicon-link {\n color: var(--fgColor-default);\n vertical-align: middle;\n visibility: hidden;\n }\n \n .markdown-body h1:hover .anchor,\n .markdown-body h2:hover .anchor,\n .markdown-body h3:hover .anchor,\n .markdown-body h4:hover .anchor,\n .markdown-body h5:hover .anchor,\n .markdown-body h6:hover .anchor {\n text-decoration: none;\n }\n \n .markdown-body h1:hover .anchor .octicon-link,\n .markdown-body h2:hover .anchor .octicon-link,\n .markdown-body h3:hover .anchor .octicon-link,\n .markdown-body h4:hover .anchor .octicon-link,\n .markdown-body h5:hover .anchor .octicon-link,\n .markdown-body h6:hover .anchor .octicon-link {\n visibility: visible;\n }\n \n .markdown-body h1 tt,\n .markdown-body h1 code,\n .markdown-body h2 tt,\n .markdown-body h2 code,\n .markdown-body h3 tt,\n .markdown-body h3 code,\n .markdown-body h4 tt,\n .markdown-body h4 code,\n .markdown-body h5 tt,\n .markdown-body h5 code,\n .markdown-body h6 tt,\n .markdown-body h6 code {\n padding: 0 .2em;\n font-size: inherit;\n }\n \n .markdown-body summary h1,\n .markdown-body summary h2,\n .markdown-body summary h3,\n .markdown-body summary h4,\n .markdown-body summary h5,\n .markdown-body summary h6 {\n display: inline-block;\n }\n \n .markdown-body summary h1 .anchor,\n .markdown-body summary h2 .anchor,\n .markdown-body summary h3 .anchor,\n .markdown-body summary h4 .anchor,\n .markdown-body summary h5 .anchor,\n .markdown-body summary h6 .anchor {\n margin-left: -40px;\n }\n \n .markdown-body summary h1,\n .markdown-body summary h2 {\n padding-bottom: 0;\n border-bottom: 0;\n }\n \n .markdown-body ul.no-list,\n .markdown-body ol.no-list {\n padding: 0;\n list-style-type: none;\n }\n \n .markdown-body ol[type=\"a s\"] {\n list-style-type: lower-alpha;\n }\n \n .markdown-body ol[type=\"A s\"] {\n list-style-type: upper-alpha;\n }\n \n .markdown-body ol[type=\"i s\"] {\n list-style-type: lower-roman;\n }\n \n .markdown-body ol[type=\"I s\"] {\n list-style-type: upper-roman;\n }\n \n .markdown-body ol[type=\"1\"] {\n list-style-type: decimal;\n }\n \n .markdown-body div>ol:not([type]) {\n list-style-type: decimal;\n }\n \n .markdown-body ul ul,\n .markdown-body ul ol,\n .markdown-body ol ol,\n .markdown-body ol ul {\n margin-top: 0;\n margin-bottom: 0;\n }\n \n .markdown-body li>p {\n margin-top: var(--base-size-16);\n }\n \n .markdown-body li+li {\n margin-top: .25em;\n }\n \n .markdown-body dl {\n padding: 0;\n }\n \n .markdown-body dl dt {\n padding: 0;\n margin-top: var(--base-size-16);\n font-size: 1em;\n font-style: italic;\n font-weight: var(--base-text-weight-semibold, 600);\n }\n \n .markdown-body dl dd {\n padding: 0 var(--base-size-16);\n margin-bottom: var(--base-size-16);\n }\n \n .markdown-body table th {\n font-weight: var(--base-text-weight-semibold, 600);\n }\n \n .markdown-body table th,\n .markdown-body table td {\n padding: 6px 13px;\n border: 1px solid var(--borderColor-default);\n }\n \n .markdown-body table td>:last-child {\n margin-bottom: 0;\n }\n \n .markdown-body table tr {\n background-color: var(--bgColor-default);\n border-top: 1px solid var(--borderColor-muted);\n }\n \n .markdown-body table tr:nth-child(2n) {\n background-color: var(--bgColor-muted);\n }\n \n .markdown-body table img {\n background-color: transparent;\n }\n \n .markdown-body img[align=right] {\n padding-left: 20px;\n }\n \n .markdown-body img[align=left] {\n padding-right: 20px;\n }\n \n .markdown-body .emoji {\n max-width: none;\n vertical-align: text-top;\n background-color: transparent;\n }\n \n .markdown-body span.frame {\n display: block;\n overflow: hidden;\n }\n \n .markdown-body span.frame>span {\n display: block;\n float: left;\n width: auto;\n padding: 7px;\n margin: 13px 0 0;\n overflow: hidden;\n border: 1px solid var(--borderColor-default);\n }\n \n .markdown-body span.frame span img {\n display: block;\n float: left;\n }\n \n .markdown-body span.frame span span {\n display: block;\n padding: 5px 0 0;\n clear: both;\n color: var(--fgColor-default);\n }\n \n .markdown-body span.align-center {\n display: block;\n overflow: hidden;\n clear: both;\n }\n \n .markdown-body span.align-center>span {\n display: block;\n margin: 13px auto 0;\n overflow: hidden;\n text-align: center;\n }\n \n .markdown-body span.align-center span img {\n margin: 0 auto;\n text-align: center;\n }\n \n .markdown-body span.align-right {\n display: block;\n overflow: hidden;\n clear: both;\n }\n \n .markdown-body span.align-right>span {\n display: block;\n margin: 13px 0 0;\n overflow: hidden;\n text-align: right;\n }\n \n .markdown-body span.align-right span img {\n margin: 0;\n text-align: right;\n }\n \n .markdown-body span.float-left {\n display: block;\n float: left;\n margin-right: 13px;\n overflow: hidden;\n }\n \n .markdown-body span.float-left span {\n margin: 13px 0 0;\n }\n \n .markdown-body span.float-right {\n display: block;\n float: right;\n margin-left: 13px;\n overflow: hidden;\n }\n \n .markdown-body span.float-right>span {\n display: block;\n margin: 13px auto 0;\n overflow: hidden;\n text-align: right;\n }\n \n .markdown-body code,\n .markdown-body tt {\n padding: .2em .4em;\n margin: 0;\n font-size: 85%;\n white-space: break-spaces;\n background-color: var(--bgColor-neutral-muted);\n border-radius: 6px;\n }\n \n .markdown-body code br,\n .markdown-body tt br {\n display: none;\n }\n \n .markdown-body del code {\n text-decoration: inherit;\n }\n \n .markdown-body samp {\n font-size: 85%;\n }\n \n .markdown-body pre code {\n font-size: 100%;\n }\n \n .markdown-body pre>code {\n padding: 0;\n margin: 0;\n word-break: normal;\n white-space: pre;\n background: transparent;\n border: 0;\n }\n \n .markdown-body .highlight {\n margin-bottom: var(--base-size-16);\n }\n \n .markdown-body .highlight pre {\n margin-bottom: 0;\n word-break: normal;\n }\n \n .markdown-body .highlight pre,\n .markdown-body pre {\n padding: var(--base-size-16);\n overflow: auto;\n font-size: 85%;\n line-height: 1.45;\n color: var(--fgColor-default);\n background-color: var(--bgColor-muted);\n border-radius: 6px;\n }\n \n .markdown-body pre code,\n .markdown-body pre tt {\n display: inline;\n max-width: auto;\n padding: 0;\n margin: 0;\n overflow: visible;\n line-height: inherit;\n word-wrap: normal;\n background-color: transparent;\n border: 0;\n }\n \n .markdown-body .csv-data td,\n .markdown-body .csv-data th {\n padding: 5px;\n overflow: hidden;\n font-size: 12px;\n line-height: 1;\n text-align: left;\n white-space: nowrap;\n }\n \n .markdown-body .csv-data .blob-num {\n padding: 10px var(--base-size-8) 9px;\n text-align: right;\n background: var(--bgColor-default);\n border: 0;\n }\n \n .markdown-body .csv-data tr {\n border-top: 0;\n }\n \n .markdown-body .csv-data th {\n font-weight: var(--base-text-weight-semibold, 600);\n background: var(--bgColor-muted);\n border-top: 0;\n }\n \n .markdown-body [data-footnote-ref]::before {\n content: \"[\";\n }\n \n .markdown-body [data-footnote-ref]::after {\n content: \"]\";\n }\n \n .markdown-body .footnotes {\n font-size: 12px;\n color: var(--fgColor-muted);\n border-top: 1px solid var(--borderColor-default);\n }\n \n .markdown-body .footnotes ol {\n padding-left: var(--base-size-16);\n }\n \n .markdown-body .footnotes ol ul {\n display: inline-block;\n padding-left: var(--base-size-16);\n margin-top: var(--base-size-16);\n }\n \n .markdown-body .footnotes li {\n position: relative;\n }\n \n .markdown-body .footnotes li:target::before {\n position: absolute;\n top: calc(var(--base-size-8)*-1);\n right: calc(var(--base-size-8)*-1);\n bottom: calc(var(--base-size-8)*-1);\n left: calc(var(--base-size-24)*-1);\n pointer-events: none;\n content: \"\";\n border: 2px solid var(--borderColor-accent-emphasis);\n border-radius: 6px;\n }\n \n .markdown-body .footnotes li:target {\n color: var(--fgColor-default);\n }\n \n .markdown-body .footnotes .data-footnote-backref g-emoji {\n font-family: monospace;\n }\n \n .markdown-body body:has(:modal) {\n padding-right: var(--dialog-scrollgutter) !important;\n }\n \n .markdown-body .pl-c {\n color: var(--color-prettylights-syntax-comment);\n }\n \n .markdown-body .pl-c1,\n .markdown-body .pl-s .pl-v {\n color: var(--color-prettylights-syntax-constant);\n }\n \n .markdown-body .pl-e,\n .markdown-body .pl-en {\n color: var(--color-prettylights-syntax-entity);\n }\n \n .markdown-body .pl-smi,\n .markdown-body .pl-s .pl-s1 {\n color: var(--color-prettylights-syntax-storage-modifier-import);\n }\n \n .markdown-body .pl-ent {\n color: var(--color-prettylights-syntax-entity-tag);\n }\n \n .markdown-body .pl-k {\n color: var(--color-prettylights-syntax-keyword);\n }\n \n .markdown-body .pl-s,\n .markdown-body .pl-pds,\n .markdown-body .pl-s .pl-pse .pl-s1,\n .markdown-body .pl-sr,\n .markdown-body .pl-sr .pl-cce,\n .markdown-body .pl-sr .pl-sre,\n .markdown-body .pl-sr .pl-sra {\n color: var(--color-prettylights-syntax-string);\n }\n \n .markdown-body .pl-v,\n .markdown-body .pl-smw {\n color: var(--color-prettylights-syntax-variable);\n }\n \n .markdown-body .pl-bu {\n color: var(--color-prettylights-syntax-brackethighlighter-unmatched);\n }\n \n .markdown-body .pl-ii {\n color: var(--color-prettylights-syntax-invalid-illegal-text);\n background-color: var(--color-prettylights-syntax-invalid-illegal-bg);\n }\n \n .markdown-body .pl-c2 {\n color: var(--color-prettylights-syntax-carriage-return-text);\n background-color: var(--color-prettylights-syntax-carriage-return-bg);\n }\n \n .markdown-body .pl-sr .pl-cce {\n font-weight: bold;\n color: var(--color-prettylights-syntax-string-regexp);\n }\n \n .markdown-body .pl-ml {\n color: var(--color-prettylights-syntax-markup-list);\n }\n \n .markdown-body .pl-mh,\n .markdown-body .pl-mh .pl-en,\n .markdown-body .pl-ms {\n font-weight: bold;\n color: var(--color-prettylights-syntax-markup-heading);\n }\n \n .markdown-body .pl-mi {\n font-style: italic;\n color: var(--color-prettylights-syntax-markup-italic);\n }\n \n .markdown-body .pl-mb {\n font-weight: bold;\n color: var(--color-prettylights-syntax-markup-bold);\n }\n \n .markdown-body .pl-md {\n color: var(--color-prettylights-syntax-markup-deleted-text);\n background-color: var(--color-prettylights-syntax-markup-deleted-bg);\n }\n \n .markdown-body .pl-mi1 {\n color: var(--color-prettylights-syntax-markup-inserted-text);\n background-color: var(--color-prettylights-syntax-markup-inserted-bg);\n }\n \n .markdown-body .pl-mc {\n color: var(--color-prettylights-syntax-markup-changed-text);\n background-color: var(--color-prettylights-syntax-markup-changed-bg);\n }\n \n .markdown-body .pl-mi2 {\n color: var(--color-prettylights-syntax-markup-ignored-text);\n background-color: var(--color-prettylights-syntax-markup-ignored-bg);\n }\n \n .markdown-body .pl-mdr {\n font-weight: bold;\n color: var(--color-prettylights-syntax-meta-diff-range);\n }\n \n .markdown-body .pl-ba {\n color: var(--color-prettylights-syntax-brackethighlighter-angle);\n }\n \n .markdown-body .pl-sg {\n color: var(--color-prettylights-syntax-sublimelinter-gutter-mark);\n }\n \n .markdown-body .pl-corl {\n text-decoration: underline;\n color: var(--color-prettylights-syntax-constant-other-reference-link);\n }\n \n .markdown-body [role=button]:focus:not(:focus-visible),\n .markdown-body [role=tabpanel][tabindex=\"0\"]:focus:not(:focus-visible),\n .markdown-body button:focus:not(:focus-visible),\n .markdown-body summary:focus:not(:focus-visible),\n .markdown-body a:focus:not(:focus-visible) {\n outline: none;\n box-shadow: none;\n }\n \n .markdown-body [tabindex=\"0\"]:focus:not(:focus-visible),\n .markdown-body details-dialog:focus:not(:focus-visible) {\n outline: none;\n }\n \n .markdown-body g-emoji {\n display: inline-block;\n min-width: 1ch;\n font-family: \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 1em;\n font-style: normal !important;\n font-weight: var(--base-text-weight-normal, 400);\n line-height: 1;\n vertical-align: -0.075em;\n }\n \n .markdown-body g-emoji img {\n width: 1em;\n height: 1em;\n }\n \n .markdown-body .task-list-item {\n list-style-type: none;\n }\n \n .markdown-body .task-list-item label {\n font-weight: var(--base-text-weight-normal, 400);\n }\n \n .markdown-body .task-list-item.enabled label {\n cursor: pointer;\n }\n \n .markdown-body .task-list-item+.task-list-item {\n margin-top: var(--base-size-4);\n }\n \n .markdown-body .task-list-item .handle {\n display: none;\n }\n \n .markdown-body .task-list-item-checkbox {\n margin: 0 .2em .25em -1.4em;\n vertical-align: middle;\n }\n \n .markdown-body ul:dir(rtl) .task-list-item-checkbox {\n margin: 0 -1.6em .25em .2em;\n }\n \n .markdown-body ol:dir(rtl) .task-list-item-checkbox {\n margin: 0 -1.6em .25em .2em;\n }\n \n .markdown-body .contains-task-list:hover .task-list-item-convert-container,\n .markdown-body .contains-task-list:focus-within .task-list-item-convert-container {\n display: block;\n width: auto;\n height: 24px;\n overflow: visible;\n clip: auto;\n }\n \n .markdown-body ::-webkit-calendar-picker-indicator {\n filter: invert(50%);\n }\n \n .markdown-body .markdown-alert {\n padding: var(--base-size-8) var(--base-size-16);\n margin-bottom: var(--base-size-16);\n color: inherit;\n border-left: .25em solid var(--borderColor-default);\n }\n \n .markdown-body .markdown-alert>:first-child {\n margin-top: 0;\n }\n \n .markdown-body .markdown-alert>:last-child {\n margin-bottom: 0;\n }\n \n .markdown-body .markdown-alert .markdown-alert-title {\n display: flex;\n font-weight: var(--base-text-weight-medium, 500);\n align-items: center;\n line-height: 1;\n }\n \n .markdown-body .markdown-alert.markdown-alert-note {\n border-left-color: var(--borderColor-accent-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title {\n color: var(--fgColor-accent);\n }\n \n .markdown-body .markdown-alert.markdown-alert-important {\n border-left-color: var(--borderColor-done-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title {\n color: var(--fgColor-done);\n }\n \n .markdown-body .markdown-alert.markdown-alert-warning {\n border-left-color: var(--borderColor-attention-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title {\n color: var(--fgColor-attention);\n }\n \n .markdown-body .markdown-alert.markdown-alert-tip {\n border-left-color: var(--borderColor-success-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title {\n color: var(--fgColor-success);\n }\n \n .markdown-body .markdown-alert.markdown-alert-caution {\n border-left-color: var(--borderColor-danger-emphasis);\n }\n \n .markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title {\n color: var(--fgColor-danger);\n }\n \n .markdown-body>*:first-child>.heading-element:first-child {\n margin-top: 0 !important;\n }\n \n .markdown-body .highlight pre:has(+.zeroclipboard-container) {\n min-height: 52px;\n }",":host {\n display: block;\n width: 100%;\n}\n\n.message-round {\n margin-bottom: 16px;\n width: 100%;\n}\n\n.user-message-container {\n display: flex;\n flex-direction: row-reverse;\n align-items: flex-start;\n margin-bottom: 15px;\n position: relative;\n}\n\n.assistant-message-container {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n margin-bottom: 15px;\n position: relative;\n}\n\n/* 添加消息气泡样式 */\n.message-bubble {\n max-width: 85%;\n position: relative;\n}\n\n/* 用户消息气泡样式 */\n.user-message {\n padding: 5px 10px;\n background: #f5f7ff;\n font-size: 14px;\n color: #1F2328;\n border-radius: 6px;\n box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);\n}\n\n/* 助手消息气泡样式 */\n.assistant-message {\n padding: 15px 10px;\n background-color: #fff;\n border-radius: 6px;\n font-size: 14px;\n color: #1F2328;\n box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);\n}\n\n.message-time {\n font-size: 12px;\n color: #999;\n margin-top: 4px;\n}\n\n/* 用户消息时间样式 */\n.user-message-container .message-time {\n color: rgba(255, 255, 255, 0.7);\n}\n\n.loading-dots {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background-color: #f0f0f0;\n border-radius: 18px;\n border-top-left-radius: 4px;\n}\n\n.loading-dots span {\n width: 8px;\n height: 8px;\n margin: 0 3px;\n background-color: #999;\n border-radius: 50%;\n display: inline-block;\n animation: dot-pulse 1.5s infinite ease-in-out;\n}\n\n.loading-dots span:nth-child(2) {\n animation-delay: 0.2s;\n}\n\n.loading-dots span:nth-child(3) {\n animation-delay: 0.4s;\n}\n\n@keyframes dot-pulse {\n\n 0%,\n 80%,\n 100% {\n transform: scale(0.8);\n opacity: 0.5;\n }\n\n 40% {\n transform: scale(1.2);\n opacity: 1;\n }\n}\n\n.file-view {\n margin-top: 8px;\n padding: 12px;\n background-color: #f8f9fa;\n border: 1px solid #e9ecef;\n border-radius: 6px;\n font-size: 14px;\n word-break: break-all;\n color: #2c3e50;\n line-height: 1.5;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.input-view {\n margin-top: 8px;\n margin-bottom: 10px;\n padding-bottom: 10px;\n border: 1px solid #e9ecef;\n border-radius: 6px;\n overflow: hidden;\n background-color: #ffffff;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n\n.input-label-container {\n display: flex;\n align-items: center;\n margin-bottom: 4px;\n background-color: #f8f9fa;\n border-bottom: 1px solid #e9ecef;\n padding: 8px 12px;\n}\n\n.copy-input-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #8c8c8c;\n opacity: 0.7;\n transition: opacity 0.2s ease;\n margin-left: 5px;\n}\n\n.copy-input-button:hover {\n opacity: 1;\n color: #1677ff;\n}\n\n.input-label {\n font-size: 13px;\n font-weight: 600;\n color: #495057;\n}\n\n.input-value {\n padding: 12px 12px 0px;\n font-size: 14px;\n line-height: 1.5;\n color: #2c3e50;\n background-color: #ffffff;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.input-metadata {\n font-size: 13px;\n margin-top: 8px;\n}\n\n/* 基本的消息操作按钮位置 */\n.message-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n transition: opacity 0.2s ease;\n margin-top: 15px;\n}\n\n\n.action-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid #d9d9d9;\n border-radius: 6px;\n padding: 4px 15px;\n font-size: 14px;\n height: 32px;\n background-color: white;\n cursor: pointer;\n color: rgba(0, 0, 0, 0.88);\n transition: all 0.2s;\n}\n\n.action-button:hover {\n color: #1677ff;\n border-color: #1677ff;\n}\n\n.action-button.primary {\n color: #1677ff;\n border-color: #1677ff;\n}\n\n.action-button.primary:hover {\n color: #4096ff;\n border-color: #4096ff;\n}\n\n.action-button.icon-only {\n padding: 4px 8px;\n margin-right: 9px;\n}\n\n.button-icon {\n margin-right: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.icon-only .button-icon {\n margin-right: 0;\n}\n\n.file-list {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n margin-top: 8px;\n}\n\n.file-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 80px;\n cursor: pointer;\n padding: 8px;\n border-radius: 4px;\n transition: background-color 0.3s;\n margin: 5px 10px;\n}\n\n.file-item:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.file-icon {\n margin-bottom: 4px;\n}\n\n.file-name {\n font-size: 12px;\n text-align: center;\n width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: #8B4513;\n}\n\n.action-button.active {\n color: #1677ff;\n background-color: rgba(22, 119, 255, 0.1);\n}\n\n.action-button.active .button-icon svg {\n stroke: #1677ff;\n}\n\n.inputs-container {\n margin-top: 8px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n\n.file-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.file-item {\n display: flex;\n align-items: center;\n padding: 8px 12px;\n background-color: #f5f5f5;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s;\n}\n\n.file-item:hover {\n background-color: #e8e8e8;\n}\n\n.file-icon {\n margin-right: 8px;\n}\n\n.file-name {\n font-size: 14px;\n color: #333;\n word-break: break-word;\n}\n\n.input-view {\n background-color: #f9f9f9;\n border-radius: 8px;\n padding: 12px;\n border: 1px solid #e8e8e8;\n}\n\n.input-label-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.input-label {\n font-weight: 500;\n color: #333;\n}\n\n.input-value {\n color: #666;\n line-height: 1.5;\n word-break: break-word;\n max-height: 200px;\n overflow-y: auto;\n}\n\n.copy-input-button {\n background: none;\n border: none;\n cursor: pointer;\n color: #1677ff;\n padding: 4px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.copy-input-button:hover {\n background-color: rgba(22, 119, 255, 0.1);\n}\n\n.input-metadata {\n font-size: 14px;\n color: #666;\n padding: 4px 0;\n}\n\n/* 文件卡片样式 */\n.file-card {\n display: flex;\n align-items: center;\n padding: 12px;\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 200px 100px no-repeat, #fff;\n border-radius: 8px;\n cursor: pointer;\n transition: background-color 0.2s;\n border: 1px solid #e8e8e8;\n margin-top: 8px;\n}\n\n.file-card:hover {\n background-color: #f0f0f0;\n}\n\n.file-card-icon {\n margin-right: 12px;\n flex-shrink: 0;\n border-radius: 12px;\n background: #0d75fb;\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.file-card-icon img {\n width: 40px;\n height: 40px;\n}\n\n.file-card-content {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.file-card-type {\n font-size: 14px;\n color: #8c8c8c;\n margin-bottom: 4px;\n}\n\n.file-card-name {\n font-size: 16px;\n font-weight: 500;\n color: #333;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: 100%;\n}\n\n/* 复制按钮样式 */\n.copy-card-button {\n background: none;\n border: none;\n cursor: pointer;\n color: #8c8c8c;\n padding: 8px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 8px;\n transition: color 0.2s;\n}\n\n.copy-card-button:hover {\n color: #1677ff;\n}\n\n.avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n\n.user-avatar {\n margin-left: 8px;\n}\n\n.assistant-avatar {\n margin-right: 8px;\n}\n\n.retry-button {\n background-color: #ff6b35 !important;\n color: white !important;\n border: none !important;\n}\n\n.retry-button:hover {\n background-color: #e55a2b !important;\n}\n\n.retry-button .button-icon {\n margin-right: 4px;\n}\n\n/* 视频容器样式 */\n.video-inputs-container {\n display: flex;\n flex-direction: column;\n align-items: end;\n}\n\n.video-container {\n margin-top: 0px;\n border-radius: 8px;\n overflow: hidden;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n background-color: #000;\n width: 250px;\n height: auto;\n max-height: 250px;\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.video-container:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n}\n\n.video-container video {\n display: block;\n width: 100%;\n max-width: 500px;\n height: auto;\n border-radius: 8px;\n}\n\n.video-container video:focus {\n outline: none;\n}\n\n/* 视频加载状态样式 */\n.video-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n background-color: #f8f9fa;\n border-radius: 8px;\n color: #666;\n font-size: 14px;\n}\n\n.loading-spinner {\n width: 24px;\n height: 24px;\n border: 2px solid #e9ecef;\n border-top: 2px solid #1677ff;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n margin-bottom: 12px;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n/* 响应式设计 */\n@media (max-width: 768px) {\n .video-container {\n width: 100%;\n max-width: 300px;\n }\n}",":host {\n display: block;\n}\n\n.drawer-container {\n position: fixed;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n overflow: visible;\n}\n\n.drawer-mask {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.45);\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.mask-visible {\n opacity: 1;\n visibility: visible;\n}\n\n.drawer-content {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n background-color: #fff;\n box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.23, 1, 0.32, 1);\n}\n\n.drawer-content-visible {\n transform: translateX(0);\n}\n\n.drawer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n color: rgba(0, 0, 0, 0.85);\n border-bottom: 1px solid #f0f0f0;\n}\n\n.drawer-title {\n flex: 1;\n margin: 0;\n font-size: 16px;\n line-height: 22px;\n font-weight: 500;\n color: rgba(0, 0, 0, 0.85);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.drawer-close {\n padding: 0;\n background: transparent;\n border: none;\n outline: none;\n cursor: pointer;\n font-size: 16px;\n color: rgba(0, 0, 0, 0.45);\n transition: color 0.3s;\n}\n\n.drawer-close:hover {\n color: rgba(0, 0, 0, 0.85);\n}\n\n.drawer-body {\n flex: 1;\n padding: 24px;\n overflow: auto;\n}\n\n/* 响应式样式 */\n@media (max-width: 768px) {\n .drawer-content {\n width: 100% !important;\n }\n \n .drawer-header {\n padding: 12px 16px;\n }\n \n .drawer-body {\n padding: 16px;\n }\n} ","import { Component, Prop, h, Event, EventEmitter, Watch, Method, Element, State } from '@stencil/core';\nimport { configStore } from '../../../store/config.store';\n\n/**\n * 抽屉组件\n * 从屏幕边缘滑出的浮层面板,类似 Ant Design 的 Drawer 组件\n */\n@Component({\n tag: 'pcm-drawer',\n styleUrl: 'pcm-drawer.css',\n shadow: true,\n})\nexport class PcmDrawer {\n /**\n * 抽屉是否可见\n */\n @Prop({ mutable: true, reflect: true }) isOpen: boolean = false;\n\n /**\n * 抽屉标题\n */\n @Prop() drawerTitle: string = '';\n\n /**\n * 宽度,可以是像素值或百分比\n */\n @Prop() width: string = '378px';\n\n /**\n * 高度,在 placement 为 top 或 bottom 时使用\n */\n @Prop() height: string = '378px';\n\n /**\n * 是否显示关闭按钮\n */\n @Prop() closable: boolean = true;\n\n /**\n * 点击蒙层是否允许关闭\n */\n @Prop() maskClosable: boolean = true;\n\n /**\n * 是否显示蒙层\n */\n @Prop() mask: boolean = true;\n\n /**\n * 抽屉关闭后的回调\n */\n @Event() closed: EventEmitter<void>;\n\n /**\n * 抽屉打开后的回调\n */\n @Event() afterOpen: EventEmitter<void>;\n\n /**\n * 抽屉关闭后的回调\n */\n @Event() afterClose: EventEmitter<void>;\n\n @Element() hostElement: HTMLElement;\n\n @State() zIndex: number = 1000;\n\n private bodyOverflowBeforeOpen: string = '';\n private transitionEndHandler: () => void;\n\n /**\n * 打开抽屉\n */\n @Method()\n async open() {\n this.isOpen = true;\n }\n\n /**\n * 关闭抽屉\n */\n @Method()\n async close() {\n this.isOpen = false;\n }\n\n @Watch('isOpen')\n visibleChanged(newValue: boolean) {\n if (newValue) {\n // 打开抽屉时,禁止背景滚动\n this.bodyOverflowBeforeOpen = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n \n // 添加过渡结束事件监听器\n const drawer = this.hostElement.shadowRoot.querySelector('.drawer-content') as HTMLElement;\n if (drawer) {\n this.transitionEndHandler = () => {\n this.afterOpen.emit();\n };\n drawer.addEventListener('transitionend', this.transitionEndHandler, { once: true });\n }\n } else {\n // 关闭抽屉时,恢复背景滚动\n document.body.style.overflow = this.bodyOverflowBeforeOpen;\n \n // 添加过渡结束事件监听器\n const drawer = this.hostElement.shadowRoot.querySelector('.drawer-content') as HTMLElement;\n if (drawer) {\n this.transitionEndHandler = () => {\n this.afterClose.emit();\n };\n drawer.addEventListener('transitionend', this.transitionEndHandler, { once: true });\n }\n }\n }\n\n componentWillLoad() {\n // 尝试从缓存中读取 zIndex\n const cachedZIndex = configStore.getItem<number>('modal-zIndex');\n if (cachedZIndex) {\n this.zIndex = cachedZIndex;\n }\n }\n\n disconnectedCallback() {\n // 组件卸载时恢复背景滚动\n if (this.isOpen) {\n document.body.style.overflow = this.bodyOverflowBeforeOpen;\n }\n \n // 移除事件监听器\n const drawer = this.hostElement.shadowRoot?.querySelector('.drawer-content') as HTMLElement;\n if (drawer && this.transitionEndHandler) {\n drawer.removeEventListener('transitionend', this.transitionEndHandler);\n }\n }\n\n private handleMaskClick = () => {\n if (this.maskClosable) {\n this.handleClose();\n }\n };\n\n private handleClose = () => {\n this.isOpen = false;\n this.closed.emit();\n };\n\n render() {\n const drawerStyle = {\n width: this.width,\n zIndex: `${this.zIndex + 1}`,\n };\n\n const maskStyle = {\n zIndex: `${this.zIndex}`,\n };\n\n return (\n <div class={{ 'drawer-container': true, 'drawer-open': this.isOpen }}>\n {this.mask && (\n <div \n class={{ 'drawer-mask': true, 'mask-visible': this.isOpen }} \n style={maskStyle}\n onClick={this.handleMaskClick}\n ></div>\n )}\n <div \n class={{ 'drawer-content': true, 'drawer-content-visible': this.isOpen }} \n style={drawerStyle}\n >\n <div class=\"drawer-header\">\n {this.drawerTitle && <div class=\"drawer-title\">{this.drawerTitle}</div>}\n {this.closable && (\n <button class=\"drawer-close\" onClick={this.handleClose}>\n <svg viewBox=\"64 64 896 896\" focusable=\"false\" data-icon=\"close\" width=\"1em\" height=\"1em\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z\"></path>\n </svg>\n </button>\n )}\n </div>\n <div class=\"drawer-body\">\n <slot></slot>\n </div>\n </div>\n </div>\n );\n }\n} ",":host {\n display: block;\n}\n\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n overflow-y: auto;\n padding: 20px;\n z-index: 1000;\n}\n\n/* 全屏模式下取消 padding */\n.fullscreen-overlay {\n padding: 0;\n}\n\n.modal-container {\n background: white;\n border-radius: 8px;\n width: 100%;\n max-width: 800px;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n}\n\n/* 全屏模式样式 */\n.modal-container.fullscreen {\n width: 100vw;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n height: 100vh;\n max-height: 100vh;\n}\n\n/* 确保内容区域也使用 flex 布局并占满剩余空间 */\n.modal-container.fullscreen > div:not(.modal-header):not(.initial-upload) {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden; /* 防止内容溢出 */\n height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 800px;\n /* height: 80vh; */\n /* max-height: 700px; */\n min-width: 320px;\n min-height: 400px;\n}\n\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n /* height: 90vh; */\n }\n\n .modal-overlay {\n padding: 0;\n }\n\n .modal-container.fullscreen {\n /* 支持 iOS Safari */\n height: -webkit-fill-available;\n max-height: -webkit-fill-available;\n /* 确保内容不会被顶部状态栏和底部工具栏遮挡 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n\n}\n.video-preview.placeholder {\n display: flex;\n justify-content: center;\n align-items: center;\n background: #EAEAEA;\n}\n\n.placeholder-status {\n color: #00000066;\n}\n\n.placeholder-status p{\n font-size: 16px;\n}\n\n.waiting-message p {\n margin: 0;\n font-size: 16px;\n color: white;\n font-weight: 500;\n}\n\n.recording-container {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n\n\n.video-area {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.stop-recording-button {\n width: 100%;\n height: 100%;\n font-size: 16px;\n background: #f44336;\n border-radius: 6px;\n color: white;\n border: none;\n cursor: pointer;\n}\n\n.stop-recording-button:hover {\n background: #d32f2f;\n}\n\n.play-audio-container {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0; /* 防止头部被压缩 */\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.header-left div {\n font-size: 16px;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n.chat-history {\n position: relative;\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n min-height: 200px;\n background: url(https://pcm-resource-1312611446.cos.ap-guangzhou.myqcloud.com/web/sdk/chat_bg.png);\n background-size: 100%;\n}\n\n/* 添加全屏模式下的样式 */\n.fullscreen .chat-history {\n height: auto;\n flex: 1 1 auto;\n}\n\n\n.message-input {\n padding: 16px;\n border-top: 1px solid #eee;\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.message-input input {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #ddd;\n border-radius: 4px;\n outline: none;\n transition: border-color 0.2s ease;\n}\n\n.message-input input:focus {\n border-color: #bbb;\n}\n\n/* 消息样式 */\n.message {\n margin-bottom: 16px;\n opacity: 1;\n transition: opacity 0.3s ease;\n}\n\n.message-content {\n max-width: 70%;\n padding: 8px 12px;\n border-radius: 8px;\n word-break: break-word;\n}\n\n.message-content p {\n margin: 0;\n word-break: break-word;\n}\n\n.user-message {\n display: flex;\n justify-content: flex-end;\n}\n\n.agent-message {\n display: flex;\n justify-content: flex-start;\n}\n\n.user-message .message-content {\n background-color: #007bff;\n color: white;\n}\n\n.agent-message .message-content {\n background-color: #f1f1f1;\n}\n\n.message-time {\n font-size: 12px;\n color: #999;\n margin-top: 4px;\n display: block;\n}\n\n.send-button {\n background-color: #1890ff;\n color: white;\n border: none;\n border-radius: 4px;\n padding: 8px 16px;\n cursor: pointer;\n font-weight: 500;\n}\n\n.send-button:disabled {\n background-color: #ccc;\n cursor: not-allowed;\n}\n\n.empty-state {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n color: #999;\n text-align: center;\n}\n\n.loading-container {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n background-color: rgba(255, 255, 255, 0.98);\n z-index: 1;\n opacity: 1;\n transition: opacity 0.3s ease;\n}\n\n.loading-container p {\n margin-top: 16px;\n color: #666;\n font-size: 14px;\n}\n\n.loading-spinner {\n width: 40px;\n height: 40px;\n border: 3px solid #f3f3f3;\n border-top: 3px solid #1890ff;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n}\n\n/* 修改 messages-wrapper 的样式 */\n.messages-wrapper {\n width: 100%;\n min-height: 100%;\n display: flex;\n flex-direction: column;\n /* 当内容少时,将内容放在底部 */\n justify-content: flex-end;\n}\n\n/* 当有很多消息时,取消固定在底部 */\n.messages-wrapper.has-overflow {\n justify-content: flex-start;\n}\n\n.suggested-questions {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 16px;\n}\n\n.suggested-question {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n background-color: #f3f4f6;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n color: #374151;\n transition: background-color 0.2s;\n}\n\n.suggested-question:hover {\n background-color: #e5e7eb;\n}\n\n.arrow-right {\n margin-left: 8px;\n}\n\n.loading-suggestions {\n display: flex;\n justify-content: center;\n padding: 16px;\n}\n\n.loading-spinner-small {\n width: 20px;\n height: 20px;\n border: 2px solid #e5e7eb;\n border-top-color: #6b7280;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n/* 添加上传按钮样式 */\n.upload-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n border-radius: 4px;\n transition: background-color 0.2s;\n}\n\n.upload-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.upload-button svg {\n width: 20px;\n height: 20px;\n}\n\n/* 隐藏原生文件输入框 */\n.file-input {\n display: none;\n}\n\n/* 添加文件名显示区域样式 */\n.selected-file {\n font-size: 12px;\n color: #666;\n margin-left: 8px;\n max-width: 150px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.input-wrapper {\n flex: 1;\n display: flex;\n align-items: center;\n border: 1px solid #ddd;\n border-radius: 4px;\n padding: 0 4px;\n background: white;\n}\n\n.input-wrapper input {\n border: none;\n flex: 1;\n padding: 8px;\n outline: none;\n}\n\n.input-wrapper:focus-within {\n border-color: #bbb;\n}\n\n/* 文件预览区域样式 */\n\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #999;\n cursor: pointer;\n padding: 4px 8px;\n font-size: 16px;\n line-height: 1;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.remove-file:hover {\n background-color: #f0f0f0;\n color: #666;\n}\n\n.initial-upload {\n padding: 16px;\n display: flex;\n flex-direction: column;\n align-items: center;\n height: 100%;\n}\n\n.upload-section {\n max-width: 600px;\n width: 100%;\n text-align: center;\n}\n\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n}\n\n.submit-button:disabled {\n background: #ccc;\n cursor: not-allowed;\n}\n\n.submit-button:hover:not(:disabled) {\n background: #40a9ff;\n}\n\n.category-select,\n.dimension-select {\n margin: 30px 0;\n}\n\n.category-options,\n.dimension-options {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n margin-top: 10px;\n}\n\n.category-button,\n.dimension-button {\n padding: 12px 16px;\n border: 1px solid #E5E5E5;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n transition: all 0.3s;\n}\n\n.category-button:hover,\n.dimension-button:hover {\n background: #f5f5f5;\n}\n\n.category-button.selected {\n background-image: linear-gradient(111deg, #4A9FFF 0%, #1058FF 100%);\n color: white;\n}\n\n.dimension-button.selected {\n background-image: linear-gradient(111deg, #4A9FFF 0%, #1058FF 100%);\n color: white;\n}\n\n.recording-section {\n border-top: 1px solid #eee;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px;\n border-radius: 14px 14px 0 0;\n flex: 0 0 auto;\n}\n\n.recording-section .video-preview {\n width: 100%;\n height: 200px;\n max-width: 400px;\n position: relative;\n margin-bottom: 10px;\n border: 1px solid #ddd;\n border-radius: 12px;\n overflow: hidden;\n}\n\n.recording-section video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n/* 修改 recording-status 样式 */\n.recording-status {\n position: absolute;\n top: 10px;\n left: 10px;\n background-color: rgba(0, 0, 0, 0.6);\n color: white;\n padding: 4px 8px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 14px;\n z-index: 2;\n}\n\n.recording-status .recording-dot {\n display: inline-block;\n width: 10px;\n height: 10px;\n background-color: red;\n border-radius: 50%;\n margin-right: 5px;\n animation: blink 1s infinite;\n}\n\n.recording-status.warning {\n color: #ff4d4f;\n animation: blink 1s infinite;\n}\n\n@keyframes blink {\n 0% {\n opacity: 1;\n }\n\n 50% {\n opacity: 0.5;\n }\n\n 100% {\n opacity: 1;\n }\n}\n\n.recording-section .stop-recording-button {\n background-color: #f44336;\n color: white;\n border: none;\n cursor: pointer;\n font-weight: bold;\n}\n\n.recording-section .stop-recording-button:hover {\n background-color: #d32f2f;\n}\n\n.fullscreen {\n width: 100vw;\n border-radius: 0;\n height: 100vh;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n}\n\n.recording-controls {\n margin-top: 10px;\n height: 53px;\n width: 100%;\n max-width: 400px;\n display: flex;\n justify-content: center;\n}\n\n.recording-controls .waiting-message {\n text-align: center;\n color: white;\n font-size: 16px;\n background-image: linear-gradient(100deg, #4A9FFF 0%, #1058FF 100%);\n border-radius: 6px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n width: 95%;\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n}\n\n.recording-controls .waiting-message.loading {\n background: #faad14;\n}\n\n.recording-controls .waiting-message p {\n margin: 0;\n font-size: 16px;\n color: white;\n font-weight: 500;\n}\n\n.recording-controls .stop-recording-button {\n background-color: #dc3545;\n color: white;\n border: none;\n cursor: pointer;\n font-size: 16px;\n}\n\n.recording-controls .stop-recording-button:hover {\n background-color: #c82333;\n}\n\n/* 添加禁用状态的样式 */\n.recording-controls .stop-recording-button.disabled {\n background: #ccc;\n cursor: not-allowed;\n}\n\n.recording-controls .stop-recording-button.disabled:hover {\n background: #ccc;\n}\n\n/* 添加进度条和数字进度的样式 */\n.progress-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n max-width: 400px;\n margin-top: 10px;\n padding: 0 5px;\n}\n\n.progress-bar-container {\n height: 4px;\n background-color: #E5E5E5;\n border-radius: 2px;\n overflow: hidden;\n margin-right: 10px;\n width: 75px;\n}\n\n.progress-bar {\n height: 100%;\n background-image: linear-gradient(111deg, #4A9FFF 0%, #1058FF 100%);\n border-radius: 2px;\n transition: width 0.3s ease;\n}\n\n.progress-text {\n font-size: 14px;\n color: #666;\n white-space: nowrap;\n}","/* 输入模式切换 */\n.input-mode-toggle {\n display: flex;\n align-items: center;\n margin-bottom: 16px;\n}\n \n.input-mode-toggle span {\n color: #333;\n margin-right: 12px;\n}\n \n.toggle-button {\n display: flex;\n align-items: center;\n background: none;\n border: none;\n color: #2E6EDF;\n cursor: pointer;\n font-size: 14px;\n padding: 4px 8px;\n}\n \n.toggle-button svg {\n margin-right: 4px;\n}\n\n/* 自由输入模式 */\n.free-input {\n width: 100%;\n}\n\n.textarea-container {\n margin-bottom: 16px;\n}\n\n.textarea-container label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.textarea-container textarea {\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 14px;\n resize: vertical;\n background-color: #f9f9f9;\n min-height: 150px;\n width: 100%;\n padding: 12px 16px;\n margin-bottom: 20px;\n max-width: 100%;\n box-sizing: border-box;\n word-wrap: break-word;\n}\n\n.textarea-container textarea:focus {\n outline: none;\n border-color: #2E6EDF;\n box-shadow: 0 0 0 2px rgba(46, 110, 223, 0.2);\n}\n\n.required {\n color: #f56c6c;\n}\n\n.input-guide {\n background-color: #f5f7fa;\n border-radius: 4px;\n padding: 12px 16px;\n margin-bottom: 20px;\n max-width: 100%;\n box-sizing: border-box;\n word-wrap: break-word;\n}\n\n.guide-title {\n font-weight: 500;\n color: #333;\n margin-bottom: 8px;\n}\n\n.guide-content {\n color: #666;\n font-size: 13px;\n max-width: 100%;\n word-wrap: break-word;\n}\n\n.guide-content div {\n margin-bottom: 4px;\n}\n\n",":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { uploadFileToBackend, FileUploadResponse, verifyApiKey } from '../../utils/utils';\nimport { ConversationStartEventData, InterviewCompleteEventData, StreamCompleteEventData } from '../../components';\nimport { ErrorEventBus, ErrorEventDetail } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store';\nimport { configStore } from '../../../store/config.store';\nimport { SentryReporter } from '../../utils/sentry-reporter';\n\n/**\n * 劳动合同卫士\n */\n\n@Component({\n tag: 'pcm-htws-modal',\n styleUrls: ['pcm-htws-modal.css', '../../global/global.css'],\n shadow: true,\n})\nexport class HtwsModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '劳动合同卫士';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请开始分析';\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n /**\n * 自定义输入参数,传入customInputs.input时,会自动切换到自由输入模式<br>\n */\n @Prop() customInputs: Record<string, string> = {};\n\n /**\n * 是否显示工作区历史会话按钮\n */\n @Prop() showWorkspaceHistory: boolean = false;\n\n /**\n * 上传成功事件\n */\n @Event() uploadSuccess: EventEmitter<FileUploadResponse>;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() interviewComplete: EventEmitter<InterviewCompleteEventData>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 附件预览模式\n * 'drawer': 在右侧抽屉中预览\n * 'window': 在新窗口中打开\n */\n @Prop() filePreviewMode: 'drawer' | 'window' = 'window';\n\n @State() selectedFile: File | null = null;\n @State() isUploading: boolean = false;\n @State() uploadedFileInfo: FileUploadResponse | null = null;\n @State() showChatModal: boolean = false;\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n @State() isSubmitting: boolean = false;\n\n // 添加输入模式状态\n @State() inputMode: 'upload' | 'free' = 'upload';\n\n // 自由输入模式的文本\n @State() freeInputText: string = '';\n\n \n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n\n componentWillLoad() {\n\n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n if (this.token) {\n authStore.setToken(this.token);\n }\n\n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n \n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n private handleFileChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length > 0) {\n this.selectedFile = input.files[0];\n }\n };\n\n private handleUploadClick = () => {\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n fileInput?.click();\n };\n\n private clearSelectedFile = () => {\n this.selectedFile = null;\n this.uploadedFileInfo = null;\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n if (fileInput) {\n fileInput.value = '';\n }\n };\n\n private async uploadFile() {\n if (!this.selectedFile) return;\n\n this.isUploading = true;\n\n try {\n // 使用 uploadFileToBackend 工具函数上传文件\n const result = await uploadFileToBackend(this.selectedFile, {\n }, {\n 'tags': ['other']\n });\n\n this.uploadedFileInfo = result;\n this.uploadSuccess.emit(result);\n } catch (error) {\n console.error('文件上传错误:', error);\n this.clearSelectedFile();\n SentryReporter.captureError(error, {\n action: 'uploadFile',\n component: 'pcm-htws-modal',\n title: '文件上传失败'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '文件上传失败,请重试'\n });\n } finally {\n this.isUploading = false;\n }\n }\n\n // 添加切换输入模式的方法\n private handleToggleInput = () => {\n this.inputMode = this.inputMode === 'upload' ? 'free' : 'upload';\n };\n\n // 添加自由输入文本变更处理方法\n private handleFreeInputChange = (event: Event) => {\n const textarea = event.target as HTMLTextAreaElement;\n this.freeInputText = textarea.value;\n };\n\n private handleStartInterview = async () => {\n if (this.inputMode === 'upload' && !this.selectedFile) {\n alert('请上传合同文件');\n return;\n }\n\n if (this.inputMode === 'free' && !this.freeInputText.trim()) {\n alert('请输入合同内容');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n if (this.inputMode === 'upload') {\n // 如果还没上传,先上传文件\n if (!this.uploadedFileInfo) {\n await this.uploadFile();\n if (!this.uploadedFileInfo) {\n this.isSubmitting = false;\n return; // 上传失败\n }\n }\n }\n\n // 直接显示聊天模态框\n this.showChatModal = true;\n } catch (error) {\n console.error('开始分析时出错:', error);\n SentryReporter.captureError(error, {\n action: 'handleStartInterview',\n component: 'pcm-htws-modal',\n title: '开始分析时出错'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '开始分析时出错,请重试'\n });\n } finally {\n this.isSubmitting = false;\n }\n };\n\n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.clearSelectedFile();\n this.showChatModal = false;\n this.freeInputText = '';\n this.inputMode = 'upload'; // 重置为默认上传模式\n } else {\n if (this.customInputs && this.customInputs.input) {\n // 如果有 input,直接切换到自由输入模式并填充内容\n this.inputMode = 'free';\n this.freeInputText = this.customInputs.input;\n }\n await verifyApiKey(this.token);\n\n if (this.conversationId) {\n // 如果有会话ID,直接显示聊天模态框\n this.showChatModal = true;\n }\n }\n }\n\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n {/* 输入界面 - 仅在不显示聊天模态框且没有会话ID时显示 */}\n {!this.showChatModal && !this.conversationId && (\n <div class=\"input-container\">\n {/* 输入模式切换 */}\n <div class=\"input-mode-toggle\">\n <span>合同内容</span>\n <button\n class=\"toggle-button\"\n onClick={this.handleToggleInput}\n >\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n 切换输入\n </button>\n </div>\n\n {/* 上传模式 */}\n {this.inputMode === 'upload' && (\n <div class=\"resume-upload-section\">\n <div class=\"upload-area\" onClick={this.handleUploadClick}>\n {this.selectedFile ? (\n <div class=\"file-item\">\n <div class=\"file-item-content\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">{this.selectedFile.name}</span>\n </div>\n <button class=\"remove-file\" onClick={(e) => {\n e.stopPropagation();\n this.clearSelectedFile();\n }}>×</button>\n </div>\n ) : (\n <div class=\"upload-placeholder\">\n <img src='https://pub.pincaimao.com/static/web/images/home/i_upload.png'></img>\n <p class='upload-text'>点击上传合同</p>\n <p class=\"upload-hint\">支持markdown、pdf、docx、doc、md 格式</p>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* 自由输入模式 */}\n {this.inputMode === 'free' && (\n <div class=\"free-input\">\n <div class=\"textarea-container\">\n <textarea\n id=\"free-input-text\"\n placeholder=\"请输入合同内容\"\n rows={8}\n value={this.freeInputText}\n onInput={this.handleFreeInputChange}\n ></textarea>\n </div>\n\n <div class=\"input-guide\">\n <div class=\"guide-title\">输入提示:</div>\n <div class=\"guide-content\">\n <div>• 请输入完整的劳动合同内容</div>\n <div>• 包括甲方(公司)、乙方(员工)信息</div>\n <div>• 合同期限、工作内容、工作地点</div>\n <div>• 工作时间、休息休假、劳动报酬</div>\n <div>• 社会保险、劳动保护、劳动条件</div>\n <div>• 合同变更、解除和终止条件等</div>\n </div>\n </div>\n </div>\n )}\n\n <button\n class=\"submit-button\"\n disabled={(this.inputMode === 'upload' && !this.selectedFile) ||\n (this.inputMode === 'free' && !this.freeInputText.trim()) ||\n this.isUploading ||\n this.isSubmitting}\n onClick={this.handleStartInterview}\n >\n {this.isUploading ? '上传中...' : this.isSubmitting ? '处理中...' : '开始分析'}\n </button>\n\n <div class=\"ai-disclaimer\">\n <p>所有内容均由AI生成仅供参考</p>\n <p class=\"beian-info\">\n <span>中央网信办生成式人工智能服务备案号</span>:\n <a href=\"https://www.pincaimao.com\" target=\"_blank\" rel=\"noopener noreferrer\">Hunan-PinCaiMao-202412310003</a>\n </p>\n </div>\n\n <input\n type=\"file\"\n class=\"file-input\"\n onChange={this.handleFileChange}\n />\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div>\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n fullscreen={this.fullscreen}\n showWorkspaceHistory={this.showWorkspaceHistory}\n botId=\"3022316191018882\"\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n enableVoice={false}\n filePreviewMode={this.filePreviewMode}\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n file_url: this.inputMode === 'upload' ? this.uploadedFileInfo?.cos_key : undefined,\n file_name: this.customInputs?.file_name || this.uploadedFileInfo?.file_name,\n input: this.inputMode === 'free' ? this.freeInputText : undefined\n }}\n interviewMode=\"text\"\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} ",null,":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { uploadFileToBackend, FileUploadResponse, verifyApiKey } from '../../utils/utils';\nimport { ConversationStartEventData, InterviewCompleteEventData, StreamCompleteEventData } from '../../components';\nimport { ErrorEventBus, ErrorEventDetail } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store';\nimport { configStore } from '../../../store/config.store';\nimport { SentryReporter } from '../../utils/sentry-reporter';\n\n/**\n * 会议总结助手\n */\n\n@Component({\n tag: 'pcm-hyzj-modal',\n styleUrls: ['pcm-hyzj-modal.css', '../../global/global.css'],\n shadow: true,\n})\nexport class HyzjModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '会议总结助手';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请开始总结';\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n /**\n * 自定义输入参数<br>\n * 传入customInputs.file_url时,会直接开始聊天。<br>\n */\n @Prop() customInputs: Record<string, string> = {};\n\n /**\n * 是否显示工作区历史会话按钮\n */\n @Prop() showWorkspaceHistory: boolean = false;\n\n /**\n * 上传成功事件\n */\n @Event() uploadSuccess: EventEmitter<FileUploadResponse>;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() interviewComplete: EventEmitter<InterviewCompleteEventData>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 附件预览模式\n * 'drawer': 在右侧抽屉中预览\n * 'window': 在新窗口中打开\n */\n @Prop() filePreviewMode: 'drawer' | 'window' = 'window';\n\n @State() selectedFile: File | null = null;\n @State() isUploading: boolean = false;\n @State() uploadedFileInfo: FileUploadResponse | null = null;\n @State() showChatModal: boolean = false;\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n @State() isSubmitting: boolean = false;\n\n\n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n\n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.clearSelectedFile();\n this.showChatModal = false;\n } else {\n await verifyApiKey(this.token);\n \n // 如果有会话ID或者有file_url参数,直接显示聊天模态框\n if (this.conversationId || this.customInputs?.file_url) {\n this.showChatModal = true;\n }\n }\n }\n\n\n componentWillLoad() {\n\n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n if (this.token) {\n authStore.setToken(this.token);\n }\n\n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n\n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n private handleFileChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length > 0) {\n this.selectedFile = input.files[0];\n }\n };\n\n private handleUploadClick = () => {\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n fileInput?.click();\n };\n\n private clearSelectedFile = () => {\n this.selectedFile = null;\n this.uploadedFileInfo = null;\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n if (fileInput) {\n fileInput.value = '';\n }\n };\n\n private async uploadFile() {\n if (!this.selectedFile) return;\n\n this.isUploading = true;\n\n try {\n // 使用 uploadFileToBackend 工具函数上传文件\n const result = await uploadFileToBackend(this.selectedFile, {\n }, {\n 'tags': ['other']\n });\n\n this.uploadedFileInfo = result;\n this.uploadSuccess.emit(result);\n } catch (error) {\n console.error('文件上传错误:', error);\n this.clearSelectedFile();\n SentryReporter.captureError(error, {\n action: 'uploadFile',\n component: 'pcm-hyzj-modal',\n title: '文件上传失败'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '文件上传失败,请重试'\n });\n } finally {\n this.isUploading = false;\n }\n }\n\n private handleStartInterview = async () => {\n if (!this.selectedFile) {\n alert('请上传面试内容');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n // 如果还没上传,先上传文件\n if (!this.uploadedFileInfo) {\n await this.uploadFile();\n if (!this.uploadedFileInfo) {\n this.isSubmitting = false;\n return; // 上传失败\n }\n }\n\n // 直接显示聊天模态框\n this.showChatModal = true;\n } catch (error) {\n console.error('开始面试时出错:', error);\n SentryReporter.captureError(error, {\n action: 'handleStartInterview',\n component: 'pcm-hyzj-modal',\n title: '开始面试时出错'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '开始面试时出错,请重试'\n });\n } finally {\n this.isSubmitting = false;\n }\n };\n\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n // 判断是否隐藏文件上传区域\n const hideFileUpload = Boolean(this.customInputs && this.customInputs.file_url);\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n {/* 上传界面 - 仅在不显示聊天模态框且没有会话ID且没有customInputs.file_url时显示 */}\n {!this.showChatModal && !this.conversationId && !hideFileUpload && (\n <div class=\"input-container\">\n {/* 上传会议纪要上传区域 */}\n <div class=\"resume-upload-section\">\n <label>上传会议纪要</label>\n <div class=\"upload-area\" onClick={this.handleUploadClick}>\n {this.selectedFile ? (\n <div class=\"file-item\">\n <div class=\"file-item-content\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">{this.selectedFile.name}</span>\n </div>\n <button class=\"remove-file\" onClick={(e) => {\n e.stopPropagation();\n this.clearSelectedFile();\n }}>×</button>\n </div>\n ) : (\n <div class=\"upload-placeholder\">\n <img src='https://pub.pincaimao.com/static/web/images/home/i_upload.png'></img>\n <p class='upload-text'>点击上传会议纪要</p>\n <p class=\"upload-hint\">支持 mp3、markdown、pdf、docx、doc、md 格式</p>\n </div>\n )}\n </div>\n </div>\n\n <button\n class=\"submit-button\"\n disabled={!this.selectedFile || this.isUploading || this.isSubmitting}\n onClick={this.handleStartInterview}\n >\n {this.isUploading ? '上传中...' : this.isSubmitting ? '处理中...' : '开始分析'}\n </button>\n\n <div class=\"ai-disclaimer\">\n <p>所有内容均由AI生成仅供参考</p>\n <p class=\"beian-info\">\n <span>中央网信办生成式人工智能服务备案号</span>:\n <a href=\"https://www.pincaimao.com\" target=\"_blank\" rel=\"noopener noreferrer\">Hunan-PinCaiMao-202412310003</a>\n </p>\n </div>\n\n <input\n type=\"file\"\n class=\"file-input\"\n onChange={this.handleFileChange}\n />\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div >\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n fullscreen={this.fullscreen}\n showWorkspaceHistory={this.showWorkspaceHistory}\n botId=\"3022316191018885\"\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n enableVoice={false}\n filePreviewMode={this.filePreviewMode}\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n file_url: this.customInputs?.file_url || this.uploadedFileInfo?.cos_key,\n file_name: this.customInputs?.file_name || this.uploadedFileInfo?.file_name\n }}\n interviewMode=\"text\"\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} ","/* 输入模式切换 */\n.input-mode-toggle {\n display: flex;\n align-items: center;\n margin-bottom: 16px;\n}\n \n.input-mode-toggle span {\n color: #333;\n margin-right: 12px;\n}\n \n.toggle-button {\n display: flex;\n align-items: center;\n background: none;\n border: none;\n color: #2E6EDF;\n cursor: pointer;\n font-size: 14px;\n padding: 4px 8px;\n}\n \n.toggle-button svg {\n margin-right: 4px;\n}\n \n.toggle-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n \n/* 结构化输入模式 */\n.structured-input {\n width: 100%;\n}\n \n.job-name-input {\n margin-bottom: 20px;\n}\n \n.job-name-input label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n \n.job-name-input input {\n width: 95%;\n padding: 10px 12px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 14px;\n background-color: #f9f9f9;\n}\n\n.job-name-input input:focus {\n outline: none;\n border-color: #2E6EDF;\n box-shadow: 0 0 0 2px rgba(46, 110, 223, 0.2);\n}\n\n.required {\n color: #f56c6c;\n}\n\n/* 按钮容器 */\n.button-container {\n display: flex;\n justify-content: center;\n margin-top: 24px;\n gap: 12px;\n max-width: 100%;\n box-sizing: border-box;\n flex-wrap: wrap;\n}\n\n\n.next-button {\n background-color: #2E6EDF;\n color: white;\n}\n\n.next-button:hover {\n background-color: #2457b8;\n}\n\n.next-button:disabled {\n background-color: #a0c0e8;\n cursor: not-allowed;\n}\n\n.prev-button {\n background-color: #f0f0f0 !important;\n color: #333 !important;\n}\n\n.prev-button:hover {\n background-color: #e0e0e0;\n}\n\n/* 标签选择 */\n.tag-selection {\n width: 100%;\n}\n\n.tag-selection-content {\n width: 100%;\n}\n\n.section-title {\n font-weight: 600;\n color: #333;\n margin-bottom: 12px;\n font-size: 16px;\n}\n\n.ai-tags-section, .basic-tags-section {\n margin-bottom: 24px;\n}\n\n.tag-group {\n margin-bottom: 16px;\n}\n\n.tag-title {\n color: #555;\n margin-bottom: 8px;\n font-weight: 500;\n}\n\n.tag-container {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n.tag {\n display: inline-flex;\n align-items: center;\n padding: 6px 12px;\n border-radius: 4px;\n background-color: #f5f5f5;\n border: 1px solid #e0e0e0;\n color: #333;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.2s;\n max-width: 100%;\n box-sizing: border-box;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tag:hover {\n background-color: #e8e8e8;\n}\n\n.tag-selected {\n background-color: #e6f0ff;\n border-color: #2E6EDF;\n color: #2E6EDF;\n}\n\n/* 加载状态 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 0;\n background-color: #f9f9f9;\n border-radius: 8px;\n margin: 20px 0;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n.loading-spinner {\n width: 40px;\n height: 40px;\n border: 3px solid rgba(46, 110, 223, 0.2);\n border-radius: 50%;\n border-top-color: #2E6EDF;\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.loading-text {\n text-align: center;\n color: #333;\n font-weight: 500;\n}\n\n.loading-subtext {\n color: #888;\n font-size: 14px;\n margin-top: 4px;\n}\n\n/* 自由输入模式 */\n.free-input {\n width: 100%;\n}\n\n.textarea-container {\n margin-bottom: 16px;\n}\n\n.textarea-container label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.textarea-container textarea {\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 14px;\n resize: vertical;\n background-color: #f9f9f9;\n min-height: 150px;\n width: 100%;\n padding: 12px 16px;\n margin-bottom: 20px;\n max-width: 100%;\n box-sizing: border-box;\n word-wrap: break-word;\n}\n\n.textarea-container textarea:focus {\n outline: none;\n border-color: #2E6EDF;\n box-shadow: 0 0 0 2px rgba(46, 110, 223, 0.2);\n}\n\n.input-guide {\n background-color: #f5f7fa;\n border-radius: 4px;\n padding: 12px 16px;\n margin-bottom: 20px;\n max-width: 100%;\n box-sizing: border-box;\n word-wrap: break-word;\n}\n\n.guide-title {\n font-weight: 500;\n color: #333;\n margin-bottom: 8px;\n}\n\n.guide-content {\n color: #666;\n font-size: 13px;\n max-width: 100%;\n word-wrap: break-word;\n}\n\n.guide-content div {\n margin-bottom: 4px;\n}\n\n\n/* 响应式调整 */\n@media (max-width: 768px) {\n \n .tag-container {\n gap: 7px;\n }\n \n .tag {\n padding: 4px 8px;\n font-size: 12px;\n }\n}\n\n@media (max-width: 480px) {\n .button-container {\n flex-direction: column;\n align-items: center;\n }\n \n .next-button, .prev-button, .submit-button {\n width: 100%;\n margin-bottom: 8px;\n }\n \n .tag {\n max-width: calc(50% - 8px);\n }\n}\n\n.tag-selection, \n.tag-selection-content,\n.ai-tags-section, \n.basic-tags-section,\n.structured-input,\n.free-input {\n max-width: 100%;\n box-sizing: border-box;\n}",":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { sendHttpRequest, verifyApiKey } from '../../utils/utils';\nimport { ConversationStartEventData, InterviewCompleteEventData, StreamCompleteEventData } from '../../components';\nimport { ErrorEventBus, ErrorEventDetail } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store';\nimport { configStore } from '../../../store/config.store';\nimport { SentryReporter } from '../../utils/sentry-reporter';\n\n/**\n * 职位生成组件\n */\n\n@Component({\n tag: 'pcm-jd-modal',\n styleUrls: ['pcm-jd-modal.css', '../../global/global.css'],\n shadow: true,\n})\nexport class PcmJdModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '职位生成';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请帮我生成职位信息';\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n /**\n * 自定义输入参数,传入customInputs.job_info时,会隐藏JD输入区域<br>\n */\n @Prop() customInputs: Record<string, string> = {};\n\n /**\n * 是否显示工作区历史会话按钮\n */\n @Prop() showWorkspaceHistory: boolean = false;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() interviewComplete: EventEmitter<InterviewCompleteEventData>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 附件预览模式\n * 'drawer': 在右侧抽屉中预览\n * 'window': 在新窗口中打开\n */\n @Prop() filePreviewMode: 'drawer' | 'window' = 'window';\n\n @State() showChatModal: boolean = false;\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n // 输入模式:structured(点选模式) 或 free(表单模式)\n @State() inputMode: 'structured' | 'free' = 'structured';\n\n // 步骤:input(输入职位名称) 或 review(选择标签)\n @State() step: 'input' | 'review' = 'input';\n\n // 职位名称\n @State() jobName: string = '';\n\n // 自由输入模式的文本\n @State() freeInputText: string = '';\n\n // 是否正在加载标签\n @State() isLoading: boolean = false;\n\n // 是否正在提交\n @State() isSubmitting: boolean = false;\n\n // 标签组\n @State() tagGroups: { dimensionName: string; defaultTags: string[]; optionalTags: string[] }[] = [];\n\n // 洗牌后的标签组\n @State() shuffledTagGroups: { dimensionName: string; tags: string[] }[] = [];\n\n // 选中的AI标签\n @State() selectedAITags: { [key: string]: string[] } = {};\n\n // 选中的基础标签\n @State() selectedTags: {\n salary: string;\n benefits: string[];\n education: string;\n } = {\n salary: '',\n benefits: [],\n education: ''\n };\n\n\n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n \n\n componentWillLoad() {\n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n if (this.token) {\n authStore.setToken(this.token);\n }\n\n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n\n // 薪资范围选项\n private salaryRanges = [\n { text: '3k-5k', value: '3k_5k' },\n { text: '5k-8k', value: '5k_8k' },\n { text: '8k-12k', value: '8k_12k' },\n { text: '12k-15k', value: '12k_15k' },\n { text: '15k-20k', value: '15k_20k' },\n { text: '20k以上', value: 'above_20k' },\n ];\n\n // 福利待遇选项\n private benefits = [\n { text: '五险一金', value: '五险一金' },\n { text: '年终奖', value: '年终奖' },\n { text: '带薪年假', value: '带薪年假' },\n { text: '加班补贴', value: '加班补贴' },\n { text: '餐补', value: '餐补' },\n { text: '交通补贴', value: '交通补贴' },\n { text: '节日福利', value: '节日福利' },\n { text: '团队建设', value: '团队建设' },\n ];\n\n // 学历要求选项\n private educationRequirements = [\n { text: '大专', value: '大专' },\n { text: '本科', value: '本科' },\n { text: '硕士', value: '硕士' },\n { text: '博士', value: '博士' },\n { text: '学历不限', value: '学历不限' },\n ];\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n private handleToggleInput = () => {\n this.inputMode = this.inputMode === 'structured' ? 'free' : 'structured';\n };\n\n private handleJobNameChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n this.jobName = input.value;\n };\n\n private handleFreeInputChange = (event: Event) => {\n const textarea = event.target as HTMLTextAreaElement;\n this.freeInputText = textarea.value;\n };\n\n private handleNextStep = async () => {\n if (!this.jobName.trim()) {\n alert('请输入职位名称');\n return;\n }\n\n this.step = 'review';\n await this.handlePositionAnalysis(this.jobName);\n };\n\n private handlePrevStep = () => {\n this.step = 'input';\n };\n\n private async handlePositionAnalysis(jobName: string) {\n if (!jobName.trim()) return;\n\n this.isLoading = true;\n\n try {\n const response = await sendHttpRequest({\n url: '/sdk/v1/chat/workflow/block-run',\n method: 'POST',\n data: {\n inputs: {\n input_info: jobName\n },\n workflow_code: \"generate_jd_tags\"\n }\n });\n\n if (response.success && response.data?.data.outputs?.text) {\n try {\n const parsedOutput = JSON.parse(response.data.data.outputs.text);\n this.tagGroups = parsedOutput.tagGroup || [];\n\n // 自动选中所有默认标签\n const initialSelectedTags: { [key: string]: string[] } = {};\n\n // 洗牌处理标签\n const shuffled = (parsedOutput.tagGroup || []).map(group => {\n // 将默认标签和可选标签合并\n const allTags = [...(group.defaultTags || []), ...(group.optionalTags || [])];\n\n // Fisher-Yates 洗牌算法打乱标签顺序\n for (let i = allTags.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [allTags[i], allTags[j]] = [allTags[j], allTags[i]];\n }\n\n // 设置默认选中的标签\n if (group.defaultTags && group.defaultTags.length > 0) {\n initialSelectedTags[group.dimensionName] = [...group.defaultTags];\n }\n\n return {\n dimensionName: group.dimensionName,\n tags: allTags\n };\n });\n\n this.shuffledTagGroups = shuffled;\n this.selectedAITags = initialSelectedTags;\n } catch (error) {\n SentryReporter.captureError(error, {\n action: 'handlePositionAnalysis',\n component: 'pcm-jd-modal',\n title: '解析前置标签时错误'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '解析前置标签时错误'\n });\n }\n }\n } catch (error) {\n console.error('工作流运行错误:', error);\n } finally {\n this.isLoading = false;\n }\n }\n\n private handleTagClick = (category: 'salary' | 'benefits' | 'education', value: string) => {\n if (category === 'benefits') {\n const currentTags = [...this.selectedTags.benefits];\n const newTags = currentTags.includes(value)\n ? currentTags.filter(t => t !== value)\n : [...currentTags, value];\n\n this.selectedTags = {\n ...this.selectedTags,\n benefits: newTags\n };\n } else {\n this.selectedTags = {\n ...this.selectedTags,\n [category]: this.selectedTags[category] === value ? '' : value\n };\n }\n };\n\n private handleAITagClick = (dimensionName: string, tag: string) => {\n const currentTags = this.selectedAITags[dimensionName] || [];\n const newTags = currentTags.includes(tag)\n ? currentTags.filter(t => t !== tag)\n : [...currentTags, tag];\n\n this.selectedAITags = {\n ...this.selectedAITags,\n [dimensionName]: newTags\n };\n };\n\n private handleSubmitStructured = async () => {\n this.isSubmitting = true;\n\n try {\n // 处理薪资范围标签\n let salaryRange = '';\n if (this.selectedTags.salary) {\n const range = this.salaryRanges.find(r => r.value === this.selectedTags.salary);\n if (range) {\n salaryRange = range.text;\n }\n }\n\n // 处理福利待遇标签\n const selectedBenefits = this.selectedTags.benefits.join('、');\n\n // 处理学历要求标签\n let education = '';\n if (this.selectedTags.education) {\n const edu = this.educationRequirements.find(e => e.value === this.selectedTags.education);\n if (edu) {\n education = edu.text;\n }\n }\n\n // 构建职位描述\n let jobInfo = `职位名称:${this.jobName}\\n`;\n\n if (salaryRange) {\n jobInfo += `薪资范围:${salaryRange}\\n`;\n }\n\n if (selectedBenefits) {\n jobInfo += `福利待遇:${selectedBenefits}\\n`;\n }\n\n if (education) {\n jobInfo += `学历要求:${education}\\n`;\n }\n\n // 添加AI标签\n Object.entries(this.selectedAITags).forEach(([dimension, tags]) => {\n if (tags.length > 0) {\n jobInfo += `${dimension}:${tags.join('、')}\\n`;\n }\n });\n\n // 显示聊天模态框\n this.showChatModal = true;\n this.jobDescription = jobInfo;\n } catch (error) {\n console.error('提交结构化数据时出错:', error);\n SentryReporter.captureError(error, {\n action: 'handleSubmitStructured',\n component: 'pcm-jd-modal',\n title: '提交数据时出错'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '提交数据时出错,请重试'\n });\n } finally {\n this.isSubmitting = false;\n }\n };\n\n private handleSubmitFree = async () => {\n if (!this.freeInputText.trim()) {\n alert('请输入职位需求信息');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n // 直接使用自由输入的文本作为职位描述\n this.jobDescription = this.freeInputText;\n\n // 显示聊天模态框\n this.showChatModal = true;\n } catch (error) {\n console.error('提交自由输入数据时出错:', error);\n SentryReporter.captureError(error, {\n action: 'handleSubmitFree',\n component: 'pcm-jd-modal',\n title: '提交数据时出错'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '提交数据时出错,请重试'\n });\n } finally {\n this.isSubmitting = false;\n }\n };\n\n @State() jobDescription: string = '';\n\n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.showChatModal = false;\n this.jobDescription = '';\n this.jobName = '';\n this.freeInputText = '';\n this.step = 'input';\n this.inputMode = 'structured';\n this.tagGroups = [];\n this.shuffledTagGroups = [];\n this.selectedAITags = {};\n this.selectedTags = {\n salary: '',\n benefits: [],\n education: ''\n };\n } else {\n if (this.customInputs && this.customInputs.job_info) {\n this.jobDescription = this.customInputs.job_info;\n // 如果有 job_info,直接切换到自由输入模式并填充内容\n this.inputMode = 'free';\n this.freeInputText = this.customInputs.job_info;\n }\n await verifyApiKey(this.token);\n if (this.conversationId) {\n // 如果有会话ID,直接显示聊天模态框\n this.showChatModal = true;\n }\n }\n }\n\n\n // 渲染标签组\n private renderTagGroup(title: string, options: { text: string, value: string }[], category: 'salary' | 'benefits' | 'education') {\n return (\n <div class=\"tag-group\">\n <div class=\"tag-title\">{title}</div>\n <div class=\"tag-container\">\n {options.map(option => {\n const isSelected = category === 'benefits'\n ? this.selectedTags.benefits.includes(option.value)\n : this.selectedTags[category] === option.value;\n\n return (\n <div\n class={{\n 'tag': true,\n 'tag-selected': isSelected\n }}\n onClick={() => this.handleTagClick(category, option.value)}\n >\n {option.text}\n </div>\n );\n })}\n </div>\n </div>\n );\n }\n\n // 渲染AI标签组\n private renderAITagGroups() {\n return (\n <div class=\"ai-tag-groups\">\n {this.shuffledTagGroups.map(group => (\n <div class=\"tag-group\">\n <div class=\"tag-title\">{group.dimensionName}</div>\n <div class=\"tag-container\">\n {group.tags.map(tag => {\n const isSelected = (this.selectedAITags[group.dimensionName] || []).includes(tag);\n return (\n <div\n class={{\n 'tag': true,\n 'tag-selected': isSelected\n }}\n onClick={() => this.handleAITagClick(group.dimensionName, tag)}\n >\n {tag}\n </div>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n );\n }\n\n // 渲染加载状态\n private renderLoadingState() {\n return (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <div class=\"loading-text\">\n <div>AI 正在分析职位信息</div>\n <div class=\"loading-subtext\">请稍候...</div>\n </div>\n </div>\n );\n }\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n // 修正这里的逻辑,确保当 customInputs.job_info 存在时不隐藏输入区域,而是显示自由输入模式\n const hideJdInput = false;\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n {/* 输入界面 - 仅在不显示聊天模态框且没有会话ID时显示 */}\n {!this.showChatModal && !this.conversationId && !hideJdInput && (\n <div class=\"input-container\">\n {/* 输入模式切换 */}\n <div class=\"input-mode-toggle\">\n <span>职位需求信息</span>\n <button\n class=\"toggle-button\"\n onClick={this.handleToggleInput}\n disabled={this.isLoading}\n >\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n 切换输入\n </button>\n </div>\n\n {/* 结构化输入模式 */}\n {this.inputMode === 'structured' && (\n <div class=\"structured-input\">\n {/* 第一步:输入职位名称 */}\n {this.step === 'input' && (\n <div class=\"job-name-input\">\n <label htmlFor=\"job-name\">\n 职位名称 <span class=\"required\">*</span>\n </label>\n <input\n id=\"job-name\"\n type=\"text\"\n placeholder=\"请输入职位名称\"\n value={this.jobName}\n onInput={this.handleJobNameChange}\n disabled={this.isLoading}\n />\n <div class=\"button-container\">\n <button\n class=\"submit-button next-button\"\n onClick={this.handleNextStep}\n disabled={!this.jobName.trim() || this.isLoading}\n >\n 下一步\n </button>\n </div>\n </div>\n )}\n\n {/* 第二步:选择标签 */}\n {this.step === 'review' && (\n <div class=\"tag-selection\">\n {this.isLoading ? (\n this.renderLoadingState()\n ) : (\n <div class=\"tag-selection-content\">\n {/* AI推荐标签 */}\n {this.tagGroups.length > 0 && (\n <div class=\"ai-tags-section\">\n <div class=\"section-title\">AI 推荐标签</div>\n {this.renderAITagGroups()}\n </div>\n )}\n\n {/* 基础标签 */}\n {this.tagGroups.length > 0 && (\n <div class=\"basic-tags-section\">\n {this.renderTagGroup('月薪范围', this.salaryRanges, 'salary')}\n {this.renderTagGroup('福利待遇', this.benefits, 'benefits')}\n {this.renderTagGroup('学历要求', this.educationRequirements, 'education')}\n </div>\n )}\n\n <div class=\"button-container\">\n <button\n class=\"submit-button prev-button\"\n onClick={this.handlePrevStep}\n >\n 上一步\n </button>\n <button\n class=\"submit-button\"\n onClick={this.handleSubmitStructured}\n disabled={this.isSubmitting}\n >\n {this.isSubmitting ? '处理中...' : '生成JD'}\n </button>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n )}\n\n {/* 自由输入模式 */}\n {this.inputMode === 'free' && (\n <div class=\"free-input\">\n <div class=\"textarea-container\">\n <label htmlFor=\"free-input-text\">\n JD信息 <span class=\"required\">*</span>\n </label>\n <textarea\n id=\"free-input-text\"\n placeholder=\"请按照下方提示格式输入职位需求信息\"\n rows={8}\n value={this.freeInputText}\n onInput={this.handleFreeInputChange}\n ></textarea>\n </div>\n\n <div class=\"input-guide\">\n <div class=\"guide-title\">输入格式参考:</div>\n <div class=\"guide-content\">\n <div>• 职位名称 - 明确定义职位的名称</div>\n <div>• 薪资范围 - 明确该岗位的月薪或年薪</div>\n <div>• 福利待遇 - 该职位的福利待遇,如:五险一金、年休假、下午茶等</div>\n <div>• 工作职责 - 描述工作内容</div>\n <div>• 任职资格 - 包括学历、经验和技术要求</div>\n <div>• 工作地点与性质 - 全职/兼职、远程/办公室</div>\n </div>\n </div>\n\n <div class=\"button-container\">\n <button\n class=\"submit-button\"\n onClick={this.handleSubmitFree}\n disabled={!this.freeInputText.trim() || this.isSubmitting}\n >\n {this.isSubmitting ? '处理中...' : '生成JD'}\n </button>\n </div>\n </div>\n )}\n\n <div class=\"ai-disclaimer\">\n <p>所有内容均由AI生成仅供参考</p>\n <p class=\"beian-info\">\n <span>中央网信办生成式人工智能服务备案号</span>:\n <a href=\"https://www.pincaimao.com\" target=\"_blank\" rel=\"noopener noreferrer\">Hunan-PinCaiMao-202412310003</a>\n </p>\n </div>\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div>\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n fullscreen={this.fullscreen}\n showWorkspaceHistory={this.showWorkspaceHistory}\n botId=\"3022316191018873\"\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n enableVoice={false}\n filePreviewMode={this.filePreviewMode}\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n job_info: this.customInputs?.job_info || this.jobDescription\n }}\n interviewMode=\"text\"\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} ",null,":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { uploadFileToBackend, FileUploadResponse, verifyApiKey } from '../../utils/utils';\nimport { ConversationStartEventData, ErrorEventDetail, InterviewCompleteEventData, StreamCompleteEventData } from '../../components';\nimport { ErrorEventBus } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store';\nimport { configStore } from '../../../store/config.store';\nimport { SentryReporter } from '../../utils/sentry-reporter';\n\n/**\n * 简历匹配\n */\n\n@Component({\n tag: 'pcm-jlpp-modal',\n styleUrls: ['pcm-jlpp-modal.css', '../../global/global.css'],\n shadow: true,\n})\nexport class JlppModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '简历剖析助手';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请开始分析';\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n\n /**\n * 自定义输入参数,传入customInputs.job_info时,会隐藏JD输入区域<br>\n * 传入customInputs.file_url时,会隐藏简历上传区域。<br>\n * 传入customInputs.file_url和customInputs.job_info时,会直接开始聊天。<br>\n */\n @Prop() customInputs: Record<string, string> = {};\n\n /**\n * 是否显示工作区历史会话按钮\n */\n @Prop() showWorkspaceHistory: boolean = false;\n\n /**\n * 上传成功事件\n */\n @Event() uploadSuccess: EventEmitter<FileUploadResponse>;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() interviewComplete: EventEmitter<InterviewCompleteEventData>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 附件预览模式\n * 'drawer': 在右侧抽屉中预览\n * 'window': 在新窗口中打开\n */\n @Prop() filePreviewMode: 'drawer' | 'window' = 'window';\n\n @State() selectedFile: File | null = null;\n @State() isUploading: boolean = false;\n @State() uploadedFileInfo: FileUploadResponse | null = null;\n @State() showChatModal: boolean = false;\n @State() jobDescription: string = '';\n @State() isSubmitting: boolean = false;\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n\n\n\n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.clearSelectedFile();\n this.showChatModal = false;\n this.jobDescription = '';\n\n } else {\n if (this.customInputs && this.customInputs.job_info) {\n this.jobDescription = this.customInputs.job_info;\n }\n await verifyApiKey(this.token);\n \n // 如果有会话ID或者同时有 file_url 和 job_info,直接显示聊天模态框\n if (this.conversationId || (this.customInputs?.file_url && this.customInputs?.job_info)) {\n this.showChatModal = true;\n }\n }\n }\n\n \n componentWillLoad() {\n\n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n if (this.token) {\n authStore.setToken(this.token);\n }\n \n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n\n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n private handleFileChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length > 0) {\n this.selectedFile = input.files[0];\n }\n };\n\n private handleUploadClick = () => {\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n fileInput?.click();\n };\n\n private clearSelectedFile = () => {\n this.selectedFile = null;\n this.uploadedFileInfo = null;\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n if (fileInput) {\n fileInput.value = '';\n }\n };\n\n private handleJobDescriptionChange = (event: Event) => {\n const textarea = event.target as HTMLTextAreaElement;\n this.jobDescription = textarea.value;\n };\n\n private async uploadFile() {\n if (!this.selectedFile) return;\n\n this.isUploading = true;\n\n try {\n const result = await uploadFileToBackend(this.selectedFile, {\n }, {\n 'tags': ['resume']\n });\n\n this.uploadedFileInfo = result;\n this.uploadSuccess.emit(result);\n } catch (error) {\n console.error('文件上传错误:', error);\n this.clearSelectedFile();\n SentryReporter.captureError(error, {\n action: 'uploadFile',\n component: 'pcm-jlpp-modal',\n title: '文件上传失败'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '文件上传失败,请重试'\n });\n } finally {\n this.isUploading = false;\n }\n }\n\n private handleStartAnalysis = async () => {\n if (!this.selectedFile) {\n alert('请上传简历');\n return;\n }\n\n // 如果没有预设的job_info,则需要检查用户输入\n if (!this.customInputs?.job_info && !this.jobDescription.trim()) {\n alert('请输入职位描述');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n // 如果还没上传,先上传文件\n if (!this.uploadedFileInfo) {\n await this.uploadFile();\n if (!this.uploadedFileInfo) {\n this.isSubmitting = false;\n return; // 上传失败\n }\n }\n\n // 直接显示聊天模态框\n this.showChatModal = true;\n } catch (error) {\n console.error('开始分析时出错:', error);\n SentryReporter.captureError(error, {\n action: 'handleStartAnalysis',\n component: 'pcm-jlpp-modal',\n title: '开始分析时出错'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '开始分析时出错,请重试'\n });\n } finally {\n this.isSubmitting = false;\n }\n };\n\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n // 确保当 customInputs.job_info 存在时,hideJdInput 为 true\n const hideJdInput = Boolean(this.customInputs && this.customInputs.job_info);\n \n // 判断是否隐藏简历上传区域\n const hideResumeUpload = Boolean(this.customInputs && this.customInputs.file_url);\n \n // 判断是否同时提供了file_url和job_info\n const hasFileAndJob = Boolean(this.customInputs?.file_url && this.customInputs?.job_info);\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n {/* 输入界面 - 仅在不显示聊天模态框且没有会话ID且没有同时提供file_url和job_info时显示 */}\n {!this.showChatModal && !this.conversationId && !hasFileAndJob && (\n <div class=\"input-container\">\n {/* JD输入区域 - 仅在没有parsedCustomInputs.job_info时显示 */}\n {!hideJdInput && (\n <div class=\"jd-input-section\">\n <label htmlFor=\"job-description\">请输入职位描述 (JD)</label>\n <textarea\n id=\"job-description\"\n class=\"job-description-textarea\"\n placeholder=\"请输入职位描述,包括职责、要求等信息...\"\n rows={6}\n value={this.jobDescription}\n onInput={this.handleJobDescriptionChange}\n ></textarea>\n </div>\n )}\n\n {/* 简历上传区域 - 仅在没有customInputs.file_url时显示 */}\n {!hideResumeUpload && (\n <div class=\"resume-upload-section\">\n <label>上传简历</label>\n <div class=\"upload-area\" onClick={this.handleUploadClick}>\n {this.selectedFile ? (\n <div class=\"file-item\">\n <div class=\"file-item-content\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">{this.selectedFile.name}</span>\n </div>\n <button class=\"remove-file\" onClick={(e) => {\n e.stopPropagation();\n this.clearSelectedFile();\n }}>×</button>\n </div>\n ) : (\n <div class=\"upload-placeholder\">\n <img src='https://pub.pincaimao.com/static/web/images/home/i_upload.png'></img>\n <p class='upload-text'>点击上传简历</p>\n <p class=\"upload-hint\">支持 txt、markdown、pdf、docx、doc、md 格式</p>\n </div>\n )}\n </div>\n </div>\n )}\n\n <button\n class=\"submit-button\"\n disabled={(!hideResumeUpload && !this.selectedFile) || (!hideJdInput && !this.jobDescription.trim()) || this.isUploading || this.isSubmitting}\n onClick={this.handleStartAnalysis}\n >\n {this.isUploading ? '上传中...' : this.isSubmitting ? '处理中...' : '开始分析'}\n </button>\n\n <div class=\"ai-disclaimer\">\n <p>所有内容均由AI生成仅供参考</p>\n <p class=\"beian-info\">\n <span>中央网信办生成式人工智能服务备案号</span>:\n <a href=\"https://www.pincaimao.com\" target=\"_blank\" rel=\"noopener noreferrer\">Hunan-PinCaiMao-202412310003</a>\n </p>\n </div>\n\n <input\n type=\"file\"\n class=\"file-input\"\n onChange={this.handleFileChange}\n />\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div >\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n fullscreen={this.fullscreen}\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n enableTTS={false}\n filePreviewMode={this.filePreviewMode}\n showWorkspaceHistory={this.showWorkspaceHistory}\n botId=\"3022316191018881\"\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n file_url: this.customInputs?.file_url || this.uploadedFileInfo?.cos_key,\n file_name: this.customInputs?.file_name || this.uploadedFileInfo?.file_name,\n job_info: this.customInputs?.job_info || this.jobDescription\n }}\n interviewMode=\"text\"\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} ","\n",":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { uploadFileToBackend, FileUploadResponse, verifyApiKey } from '../../utils/utils';\nimport { ConversationStartEventData, InterviewCompleteEventData, StreamCompleteEventData } from '../../components';\nimport { ErrorEventBus, ErrorEventDetail } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store';\nimport { configStore } from '../../../store/config.store';\nimport { SentryReporter } from '../../utils/sentry-reporter';\n\n/**\n * 模拟出题大师\n */\n\n@Component({\n tag: 'pcm-mnct-modal',\n styleUrls: ['pcm-mnct-modal.css', '../../global/global.css'],\n shadow: true,\n})\nexport class MnctModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '面试出题大师';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请开始出题';\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n /**\n * 自定义输入参数,传入customInputs.job_info时,会隐藏JD输入区域<br>\n * 传入customInputs.file_url时,会隐藏简历上传区域。<br>\n * 传入customInputs.file_url和customInputs.job_info时,会直接开始聊天。<br>\n */\n @Prop() customInputs: Record<string, string> = {};\n\n /**\n * 是否显示工作区历史会话按钮\n */\n @Prop() showWorkspaceHistory: boolean = false;\n\n\n /**\n * 上传成功事件\n */\n @Event() uploadSuccess: EventEmitter<FileUploadResponse>;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() interviewComplete: EventEmitter<InterviewCompleteEventData>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 附件预览模式\n * 'drawer': 在右侧抽屉中预览\n * 'window': 在新窗口中打开\n */\n @Prop() filePreviewMode: 'drawer' | 'window' = 'window';\n\n @State() selectedFile: File | null = null;\n @State() isUploading: boolean = false;\n @State() uploadedFileInfo: FileUploadResponse | null = null;\n @State() showChatModal: boolean = false;\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n @State() jobDescription: string = '';\n @State() isSubmitting: boolean = false;\n\n\n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n\n\n \n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.clearSelectedFile();\n this.showChatModal = false;\n this.jobDescription = '';\n\n } else {\n if (this.customInputs && this.customInputs.job_info) {\n this.jobDescription = this.customInputs.job_info;\n }\n\n await verifyApiKey(this.token);\n\n // 如果有会话ID或者同时有file_url和job_info,直接显示聊天模态框\n if (this.conversationId || (this.customInputs?.file_url && this.customInputs?.job_info)) {\n this.showChatModal = true;\n }\n }\n }\n\n\n\n componentWillLoad() {\n\n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n if (this.token) {\n authStore.setToken(this.token);\n }\n\n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n private handleFileChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length > 0) {\n this.selectedFile = input.files[0];\n }\n };\n\n private handleUploadClick = () => {\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n fileInput?.click();\n };\n\n private clearSelectedFile = () => {\n this.selectedFile = null;\n this.uploadedFileInfo = null;\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n if (fileInput) {\n fileInput.value = '';\n }\n };\n\n private async uploadFile() {\n if (!this.selectedFile) return;\n\n this.isUploading = true;\n\n try {\n // 使用 uploadFileToBackend 工具函数上传文件\n const result = await uploadFileToBackend(this.selectedFile, {\n }, {\n 'tags': ['resume']\n });\n\n this.uploadedFileInfo = result;\n this.uploadSuccess.emit(result);\n } catch (error) {\n console.error('文件上传错误:', error);\n this.clearSelectedFile();\n SentryReporter.captureError(error, {\n action: 'uploadFile',\n component: 'pcm-mnct-modal',\n title: '文件上传失败'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '文件上传失败,请重试'\n });\n } finally {\n this.isUploading = false;\n }\n }\n\n private handleJobDescriptionChange = (event: Event) => {\n const textarea = event.target as HTMLTextAreaElement;\n this.jobDescription = textarea.value;\n };\n\n private handleStartInterview = async () => {\n if (!this.selectedFile) {\n alert('请上传简历');\n return;\n }\n\n // 如果没有预设的job_info,则需要检查用户输入\n if (!this.customInputs?.job_info && !this.jobDescription.trim()) {\n alert('请输入职位描述');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n // 如果还没上传,先上传文件\n if (!this.uploadedFileInfo) {\n await this.uploadFile();\n if (!this.uploadedFileInfo) {\n this.isSubmitting = false;\n return; // 上传失败\n }\n }\n\n // 直接显示聊天模态框\n this.showChatModal = true;\n } catch (error) {\n console.error('开始面试时出错:', error);\n SentryReporter.captureError(error, {\n action: 'handleStartInterview',\n component: 'pcm-mnct-modal',\n title: '开始面试时出错'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '开始面试时出错,请重试'\n });\n } finally {\n this.isSubmitting = false;\n }\n };\n\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n // 判断是否隐藏JD输入区域\n const hideJdInput = Boolean(this.customInputs && this.customInputs.job_info);\n \n // 判断是否隐藏简历上传区域\n const hideResumeUpload = Boolean(this.customInputs && this.customInputs.file_url);\n \n // 判断是否同时提供了file_url和job_info\n const hasFileAndJob = Boolean(this.customInputs?.file_url && this.customInputs?.job_info);\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n {/* 上传界面 - 仅在不显示聊天模态框且没有会话ID且没有同时提供file_url和job_info时显示 */}\n {!this.showChatModal && !this.conversationId && !hasFileAndJob && (\n <div class=\"input-container\">\n {/* JD输入区域 - 仅在没有customInputs.job_info时显示 */}\n {!hideJdInput && (\n <div class=\"jd-input-section\">\n <label htmlFor=\"job-description\">请输入职位描述 (JD)</label>\n <textarea\n id=\"job-description\"\n class=\"job-description-textarea\"\n placeholder=\"请输入职位描述,包括职责、要求等信息...\"\n rows={6}\n value={this.jobDescription}\n onInput={this.handleJobDescriptionChange}\n ></textarea>\n </div>\n )}\n\n {/* 简历上传区域 - 仅在没有customInputs.file_url时显示 */}\n {!hideResumeUpload && (\n <div class=\"resume-upload-section\">\n <label>上传简历</label>\n <div class=\"upload-area\" onClick={this.handleUploadClick}>\n {this.selectedFile ? (\n <div class=\"file-item\">\n <div class=\"file-item-content\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">{this.selectedFile.name}</span>\n </div>\n <button class=\"remove-file\" onClick={(e) => {\n e.stopPropagation();\n this.clearSelectedFile();\n }}>×</button>\n </div>\n ) : (\n <div class=\"upload-placeholder\">\n <img src='https://pub.pincaimao.com/static/web/images/home/i_upload.png'></img>\n <p class='upload-text'>点击上传简历</p>\n <p class=\"upload-hint\">支持 txt、markdown、pdf、docx、doc、md 格式</p>\n </div>\n )}\n </div>\n </div>\n )}\n\n <button\n class=\"submit-button\"\n disabled={((!hideResumeUpload && !this.selectedFile) || \n (!hideJdInput && !this.jobDescription.trim())) || \n this.isUploading || this.isSubmitting}\n onClick={this.handleStartInterview}\n >\n {this.isUploading ? '上传中...' : this.isSubmitting ? '处理中...' : '开始分析'}\n </button>\n\n <div class=\"ai-disclaimer\">\n <p>所有内容均由AI生成仅供参考</p>\n <p class=\"beian-info\">\n <span>中央网信办生成式人工智能服务备案号</span>:\n <a href=\"https://www.pincaimao.com\" target=\"_blank\" rel=\"noopener noreferrer\">Hunan-PinCaiMao-202412310003</a>\n </p>\n </div>\n\n <input\n type=\"file\"\n class=\"file-input\"\n onChange={this.handleFileChange}\n />\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div>\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n fullscreen={this.fullscreen}\n showWorkspaceHistory={this.showWorkspaceHistory}\n botId=\"3022316191018876\"\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n filePreviewMode={this.filePreviewMode}\n enableVoice={false}\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n file_url: this.customInputs?.file_url || this.uploadedFileInfo?.cos_key,\n file_name: this.customInputs?.file_name || this.uploadedFileInfo?.file_name,\n job_info: this.customInputs?.job_info || this.jobDescription\n }}\n interviewMode=\"text\"\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} ",null,":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { FileUploadResponse, verifyApiKey } from '../../utils/utils';\nimport {\n StreamCompleteEventData,\n ConversationStartEventData,\n InterviewCompleteEventData,\n RecordingErrorEventData,\n} from '../../interfaces/events';\nimport { ErrorEventBus, ErrorEventDetail } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store';\nimport { configStore } from '../../../store/config.store';\nimport { Message } from '../../services/message.service';\n\n/**\n * 模拟面试\n */\n\n@Component({\n tag: 'pcm-mnms-modal',\n styleUrls: ['pcm-mnms-modal.css', '../../global/global.css'],\n shadow: true,\n})\nexport class MnmsModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '模拟面试';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请开始模拟面试';\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n /**\n * 自定义输入参数,传入customInputs.job_info时,会隐藏JD输入区域。<br>\n * 传入customInputs.file_url或customInputs.resume_content时,会隐藏简历上传区域。<br>\n * 传入customInputs.file_url(或customInputs.resume_content)和customInputs.job_info时,会直接开始聊天。<br>\n * customInputs.resume_content:可传入json字符串,或纯文本字符串,字符串内容为简历内容。<br>\n * customInputs.url_callback:可传入url字符串,当报告生成后,会调用该url进行回调。该url请使用post请求,接收报告字段为report_content,会话id字段为conversation_id。\n */\n @Prop() customInputs: Record<string, string> = {};\n\n /**\n * 是否显示工作区历史会话按钮\n */\n @Prop() showWorkspaceHistory: boolean = false;\n\n /**\n * 是否开启移动端上传(仅PC端生效)\n */\n @Prop() mobileJdInputAble: boolean = false;\n\n /**\n * 是否开启移动端上传(仅PC端生效)\n */\n @Prop() mobileUploadAble: boolean = false;\n\n /**\n * 上传成功事件\n */\n @Event() uploadSuccess: EventEmitter<FileUploadResponse>;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() interviewComplete: EventEmitter<InterviewCompleteEventData>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 附件预览模式\n * 'drawer': 在右侧抽屉中预览\n * 'window': 在新窗口中打开\n */\n @Prop() filePreviewMode: 'drawer' | 'window' = 'window';\n\n /**\n * 面试模式:text - 文本模式,video - 视频模式\n */\n @Prop() interviewMode: 'text' | 'video' = 'text';\n\n /**\n * 录制错误事件\n */\n @Event() recordingError: EventEmitter<RecordingErrorEventData>;\n\n /**\n * 是否显示复制按钮\n */\n @Prop() showCopyButton: boolean = true;\n\n /**\n * 是否显示点赞点踩按钮\n */\n @Prop() showFeedbackButtons: boolean = true;\n\n\n @State() selectedFile: File | null = null;\n @State() isUploading: boolean = false;\n @State() uploadedFileInfo: FileUploadResponse | null = null;\n @State() showChatModal: boolean = false;\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n @State() jobDescription: string = '';\n @State() isSubmitting: boolean = false;\n\n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n\n\n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.showChatModal = false;\n this.jobDescription = '';\n\n } else {\n if (this.customInputs && this.customInputs.job_info) {\n this.jobDescription = this.customInputs.job_info;\n }\n\n await verifyApiKey(this.token);\n\n // 如果同时有 file_url 和 job_info,或者有会话ID,直接显示聊天模态框\n if (((this.customInputs?.file_url || this.customInputs?.resume_content) && this.customInputs?.job_info) || this.conversationId) {\n this.showChatModal = true;\n }\n }\n }\n\n\n\n componentWillLoad() {\n\n\n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n\n if (this.token) {\n authStore.setToken(this.token);\n }\n\n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n\n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n private handleJobDescriptionChange = (event: Event) => {\n const textarea = event.target as HTMLTextAreaElement;\n this.jobDescription = textarea.value;\n };\n\n private handleStartInterview = async () => {\n // 如果没有预设的job_info,则需要检查用户输入\n if (!this.customInputs?.job_info && !this.jobDescription.trim()) {\n alert('请输入职位描述');\n return;\n }\n this.isSubmitting = true;\n // 判断文件是否正在上传\n if (await this.pcmUploadRef?.getIsUploading?.()) {\n Message.info('文件上传中,请稍后');\n return;\n }\n this.showChatModal = true;\n };\n\n private pcmUploadRef;\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n // 修正这里的逻辑,确保当 customInputs.job_info 存在时,hideJdInput 为 true\n const hideJdInput = Boolean(this.customInputs && this.customInputs.job_info);\n\n // 判断是否隐藏简历上传区域 - 当有file_url或resume_content时都隐藏\n const hideResumeUpload = Boolean(this.customInputs && (this.customInputs.file_url || this.customInputs.resume_content));\n\n // 判断是否同时提供了(file_url或resume_content)和job_info\n const hasFileAndJob = Boolean((this.customInputs?.file_url || this.customInputs?.resume_content) && this.customInputs?.job_info);\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n {/* 上传界面 - 仅在不显示聊天模态框且没有会话ID且没有同时提供file_url和job_info时显示 */}\n {!this.showChatModal && !this.conversationId && !hasFileAndJob && (\n <div class=\"input-container\">\n {/* JD输入区域 - 仅在没有customInputs.job_info时显示 */}\n {!hideJdInput && (\n <div class=\"jd-input-section\">\n <label htmlFor=\"job-description\">请输入职位描述 (JD)</label>\n {\n !!this.mobileJdInputAble && (\n <pcm-mobile-input-btn\n name=\"职位描述\"\n onOk={(e) => {\n this.jobDescription = e.detail;\n }}\n />\n )\n }\n <textarea\n id=\"job-description\"\n class=\"job-description-textarea\"\n placeholder=\"请输入职位描述,包括职责、要求等信息...\"\n rows={6}\n value={this.jobDescription}\n onInput={this.handleJobDescriptionChange}\n ></textarea>\n </div>\n )}\n\n {/* 简历上传区域 - 仅在没有customInputs.file_url或customInputs.resume_content时显示 */}\n {\n !hideResumeUpload && (\n <pcm-upload\n ref={el => this.pcmUploadRef = el}\n maxFileSize={15 * 1024 * 1024}\n multiple={false}\n mobileUploadAble={this.mobileUploadAble}\n labelText=\"上传简历(选填)\"\n acceptFileSuffixList={['.txt', '.md', '.pdf', '.docx', '.doc']}\n uploadParams={{\n tags: ['resume'],\n }}\n onUploadChange={(e) => {\n const result: FileUploadResponse[] = e.detail ?? [];\n this.uploadedFileInfo = result[0];\n this.uploadSuccess.emit(this.uploadedFileInfo);\n }}\n />\n )\n }\n\n <button\n class=\"submit-button\"\n disabled={(!hideJdInput && !this.jobDescription.trim()) || this.isUploading || this.isSubmitting}\n onClick={this.handleStartInterview}\n >\n {this.isUploading ? '上传中...' : this.isSubmitting ? '处理中...' : '开始分析'}\n </button>\n\n <div class=\"ai-disclaimer\">\n <p>所有内容均由AI生成仅供参考</p>\n <p class=\"beian-info\">\n <span>中央网信办生成式人工智能服务备案号</span>:\n <a href=\"https://www.pincaimao.com\" target=\"_blank\" rel=\"noopener noreferrer\">Hunan-PinCaiMao-202412310003</a>\n </p>\n </div>\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div >\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n fullscreen={this.fullscreen}\n showWorkspaceHistory={this.showWorkspaceHistory}\n botId=\"3022316191018884\"\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n enableTTS={false}\n filePreviewMode={this.filePreviewMode}\n showCopyButton={this.showCopyButton}\n showFeedbackButtons={this.showFeedbackButtons}\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n file_url: this.customInputs?.file_url || this.uploadedFileInfo?.cos_key,\n file_name: this.customInputs?.file_name || this.uploadedFileInfo?.file_name,\n job_info: this.customInputs?.job_info || this.jobDescription,\n resume_content: this.customInputs?.resume_content\n }}\n interviewMode={this.interviewMode}\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} ","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module Charset\n */\nconst VALUES_TO_CHARSET = new Map();\nfunction fromCharsetValue(value) {\n const charset = VALUES_TO_CHARSET.get(value);\n if (charset != null) {\n return charset;\n }\n throw Error('illegal charset value');\n}\nclass Charset {\n #label;\n #values;\n // See: https://en.wikipedia.org/wiki/Extended_Channel_Interpretation\n static CP437 = new Charset('cp437', 2, 0);\n static ISO_8859_1 = new Charset('iso-8859-1', 3, 1);\n static ISO_8859_2 = new Charset('iso-8859-2', 4);\n static ISO_8859_3 = new Charset('iso-8859-3', 5);\n static ISO_8859_4 = new Charset('iso-8859-4', 6);\n static ISO_8859_5 = new Charset('iso-8859-5', 7);\n static ISO_8859_6 = new Charset('iso-8859-6', 8);\n static ISO_8859_7 = new Charset('iso-8859-7', 9);\n static ISO_8859_8 = new Charset('iso-8859-8', 10);\n static ISO_8859_9 = new Charset('iso-8859-9', 11);\n static ISO_8859_10 = new Charset('iso-8859-10', 12);\n static ISO_8859_11 = new Charset('iso-8859-11', 13);\n static ISO_8859_13 = new Charset('iso-8859-13', 15);\n static ISO_8859_14 = new Charset('iso-8859-14', 16);\n static ISO_8859_15 = new Charset('iso-8859-15', 17);\n static ISO_8859_16 = new Charset('iso-8859-16', 18);\n static SHIFT_JIS = new Charset('shift-jis', 20);\n static CP1250 = new Charset('cp1250', 21);\n static CP1251 = new Charset('cp1251', 22);\n static CP1252 = new Charset('cp1252', 23);\n static CP1256 = new Charset('cp1256', 24);\n static UTF_16BE = new Charset('utf-16be', 25);\n static UTF_8 = new Charset('utf-8', 26);\n static ASCII = new Charset('ascii', 27);\n static BIG5 = new Charset('big5', 28);\n static GB2312 = new Charset('gb2312', 29);\n static EUC_KR = new Charset('euc-kr', 30);\n static GBK = new Charset('gbk', 31);\n static GB18030 = new Charset('gb18030', 32);\n static UTF_16LE = new Charset('utf-16le', 33);\n static UTF_32BE = new Charset('utf-32be', 34);\n static UTF_32LE = new Charset('utf-32le', 35);\n static ISO_646_INV = new Charset('iso-646-inv', 170);\n static BINARY = new Charset('binary', 899);\n /**\n * @constructor\n * @param label The label of charset.\n * @param values The values of charset.\n */\n constructor(label, ...values) {\n this.#label = label;\n this.#values = Object.freeze(values);\n for (const value of values) {\n if (value >= 0 && value <= 999999 && Number.isInteger(value)) {\n VALUES_TO_CHARSET.set(value, this);\n } else {\n throw new Error('illegal extended channel interpretation value');\n }\n }\n }\n /**\n * @property label\n * @description Get the label of charset.\n */\n get label() {\n return this.#label;\n }\n /**\n * @property values\n * @description Get the values of charset.\n */\n get values() {\n return this.#values;\n }\n}\n\nexport { Charset, fromCharsetValue };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module utils\n */\nfunction toBit(value) {\n return value & 0x01;\n}\nfunction toInt32(value) {\n return value | 0;\n}\nfunction round(value) {\n return toInt32(value + (value < 0 ? -0.5 : 0.5));\n}\nfunction getBitMask(value) {\n return 1 << getBitOffset(value);\n}\nfunction getBitOffset(value) {\n return value & 0x1f;\n}\nfunction charAt(value, index) {\n const character = value.at(index);\n return character != null ? character : '';\n}\n// Get hamming weight of int32.\nfunction hammingWeight(value) {\n // HD, Figure 5-2.\n value = value - ((value >> 1) & 0x55555555);\n value = (value & 0x33333333) + ((value >> 2) & 0x33333333);\n return (((value + (value >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;\n}\n// Return the position of the most significant bit set (to one) in the \"value\". The most\n// significant bit is position 32. If there is no bit set, return 0. Examples:\n// - findMSBSet(0) => 0\n// - findMSBSet(1) => 1\n// - findMSBSet(255) => 8\nfunction findMSBSet(value) {\n return 32 - Math.clz32(value);\n}\n// Calculate BCH (Bose-Chaudhuri-Hocquenghem) code for \"value\" using polynomial \"poly\". The BCH\n// code is used for encoding type information and version information.\n// Example: Calculation of version information of 7.\n// f(x) is created from 7.\n// - 7 = 000111 in 6 bits\n// - f(x) = x^2 + x^1 + x^0\n// g(x) is given by the standard (p. 67)\n// - g(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1\n// Multiply f(x) by x^(18 - 6)\n// - f'(x) = f(x) * x^(18 - 6)\n// - f'(x) = x^14 + x^13 + x^12\n// Calculate the remainder of f'(x) / g(x)\n// x^2\n// __________________________________________________\n// g(x) )x^14 + x^13 + x^12\n// x^14 + x^13 + x^12 + x^11 + x^10 + x^7 + x^4 + x^2\n// --------------------------------------------------\n// x^11 + x^10 + x^7 + x^4 + x^2\n//\n// The remainder is x^11 + x^10 + x^7 + x^4 + x^2\n// Encode it in binary: 110010010100\n// The return value is 0xc94 (1100 1001 0100)\n//\n// Since all coefficients in the polynomials are 1 or 0, we can do the calculation by bit\n// operations. We don't care if coefficients are positive or negative.\nfunction calculateBCHCode(value, poly) {\n // If poly is \"1 1111 0010 0101\" (version info poly), msbSetInPoly is 13. We'll subtract 1\n // from 13 to make it 12.\n const msbSetInPoly = findMSBSet(poly);\n value <<= msbSetInPoly - 1;\n // Do the division business using exclusive-or operations.\n while (findMSBSet(value) >= msbSetInPoly) {\n value ^= poly << (findMSBSet(value) - msbSetInPoly);\n }\n // Now the \"value\" is the remainder (i.e. the BCH code).\n return value;\n}\nfunction accumulate(array, start = 0, end = array.length) {\n let total = 0;\n for (let i = start; i < end; i++) {\n total += array[i];\n }\n return total;\n}\n\nexport { accumulate, calculateBCHCode, charAt, findMSBSet, getBitMask, getBitOffset, hammingWeight, round, toBit, toInt32 };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module Mode\n */\nconst VALUES_TO_MODE = new Map();\nfunction fromModeBits(bits) {\n const mode = VALUES_TO_MODE.get(bits);\n if (mode != null) {\n return mode;\n }\n throw new Error('illegal mode bits');\n}\nclass Mode {\n #bits;\n #characterCountBitsSet;\n static TERMINATOR = new Mode([0, 0, 0], 0x00);\n static NUMERIC = new Mode([10, 12, 14], 0x01);\n static ALPHANUMERIC = new Mode([9, 11, 13], 0x02);\n static STRUCTURED_APPEND = new Mode([0, 0, 0], 0x03);\n static BYTE = new Mode([8, 16, 16], 0x04);\n static ECI = new Mode([0, 0, 0], 0x07);\n static KANJI = new Mode([8, 10, 12], 0x08);\n static FNC1_FIRST_POSITION = new Mode([0, 0, 0], 0x05);\n static FNC1_SECOND_POSITION = new Mode([0, 0, 0], 0x09);\n static HANZI = new Mode([8, 10, 12], 0x0d);\n constructor(characterCountBitsSet, bits) {\n this.#bits = bits;\n this.#characterCountBitsSet = new Int32Array(characterCountBitsSet);\n VALUES_TO_MODE.set(bits, this);\n }\n get bits() {\n return this.#bits;\n }\n getCharacterCountBits({ version }) {\n let offset;\n if (version <= 9) {\n offset = 0;\n } else if (version <= 26) {\n offset = 1;\n } else {\n offset = 2;\n }\n return this.#characterCountBitsSet[offset];\n }\n}\n\nexport { Mode, fromModeBits };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { toInt32 } from './utils.js';\n\n/**\n * @module mask\n */\n// Penalty weights.\nconst N1 = 3;\nconst N2 = 3;\nconst N3 = 40;\nconst N4 = 10;\n// Is dark point.\nfunction isDark(matrix, x, y) {\n return matrix.get(x, y) === 1;\n}\n// Helper function for applyMaskPenaltyRule1. We need this for doing this calculation in both\n// horizontal and vertical orders respectively.\nfunction applyMaskPenaltyRule1Internal(matrix, isVertical) {\n let penalty = 0;\n const { size } = matrix;\n for (let y = 0; y < size; y++) {\n let prevBit = -1;\n let numSameBitCells = 0;\n for (let x = 0; x < size; x++) {\n const bit = isVertical ? matrix.get(y, x) : matrix.get(x, y);\n if (bit === prevBit) {\n numSameBitCells++;\n } else {\n if (numSameBitCells >= 5) {\n penalty += N1 + (numSameBitCells - 5);\n }\n // set prev bit.\n prevBit = bit;\n // include the cell itself.\n numSameBitCells = 1;\n }\n }\n if (numSameBitCells >= 5) {\n penalty += N1 + (numSameBitCells - 5);\n }\n }\n return penalty;\n}\n// Apply mask penalty rule 1 and return the penalty. Find repetitive cells with the same color and\n// give penalty to them. Example: 00000 or 11111.\nfunction applyMaskPenaltyRule1(matrix) {\n return applyMaskPenaltyRule1Internal(matrix) + applyMaskPenaltyRule1Internal(matrix, true);\n}\n// Apply mask penalty rule 2 and return the penalty. Find 2x2 blocks with the same color and give\n// penalty to them. This is actually equivalent to the spec's rule, which is to find MxN blocks and give a\n// penalty proportional to (M-1)x(N-1), because this is the number of 2x2 blocks inside such a block.\nfunction applyMaskPenaltyRule2(matrix) {\n let penalty = 0;\n const size = matrix.size - 1;\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n const bit = matrix.get(x, y);\n if (\n // Find 2x2 blocks with the same color.\n bit === matrix.get(x + 1, y) &&\n bit === matrix.get(x, y + 1) &&\n bit === matrix.get(x + 1, y + 1)\n ) {\n penalty += N2;\n }\n }\n }\n return penalty;\n}\n// Is is four white, check on horizontal and vertical.\nfunction isFourWhite(matrix, offset, from, to, isVertical) {\n if (from < 0 || to > matrix.size) {\n return false;\n }\n for (let i = from; i < to; i++) {\n if (isVertical ? isDark(matrix, offset, i) : isDark(matrix, i, offset)) {\n return false;\n }\n }\n return true;\n}\n// Apply mask penalty rule 3 and return the penalty. Find consecutive runs of 1:1:3:1:1:4\n// starting with black, or 4:1:1:3:1:1 starting with white, and give penalty to them. If we\n// find patterns like 000010111010000, we give penalty once.\nfunction applyMaskPenaltyRule3(matrix) {\n let numPenalties = 0;\n const { size } = matrix;\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n if (\n // Find consecutive runs of 1:1:3:1:1:4 or 4:1:1:3:1:1, patterns like 000010111010000.\n x + 6 < size &&\n isDark(matrix, x, y) &&\n !isDark(matrix, x + 1, y) &&\n isDark(matrix, x + 2, y) &&\n isDark(matrix, x + 3, y) &&\n isDark(matrix, x + 4, y) &&\n !isDark(matrix, x + 5, y) &&\n isDark(matrix, x + 6, y) &&\n (isFourWhite(matrix, y, x - 4, x) || isFourWhite(matrix, y, x + 7, x + 11))\n ) {\n numPenalties++;\n }\n if (\n // Find consecutive runs of 1:1:3:1:1:4 or 4:1:1:3:1:1, patterns like 000010111010000.\n y + 6 < size &&\n isDark(matrix, x, y) &&\n !isDark(matrix, x, y + 1) &&\n isDark(matrix, x, y + 2) &&\n isDark(matrix, x, y + 3) &&\n isDark(matrix, x, y + 4) &&\n !isDark(matrix, x, y + 5) &&\n isDark(matrix, x, y + 6) &&\n (isFourWhite(matrix, x, y - 4, y, true) || isFourWhite(matrix, x, y + 7, y + 11, true))\n ) {\n numPenalties++;\n }\n }\n }\n return numPenalties * N3;\n}\n// Apply mask penalty rule 4 and return the penalty. Calculate the ratio of dark cells and give\n// penalty if the ratio is far from 50%. It gives 10 penalty for 5% distance.\nfunction applyMaskPenaltyRule4(matrix) {\n let numDarkCells = 0;\n const { size } = matrix;\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n if (isDark(matrix, x, y)) {\n numDarkCells++;\n }\n }\n }\n const numTotalCells = size * size;\n const fivePercentVariances = toInt32((Math.abs(numDarkCells * 2 - numTotalCells) * 10) / numTotalCells);\n return fivePercentVariances * N4;\n}\n// The mask penalty calculation is complicated. See Table 11 of ISO/IEC 18004:2015(E)(p.54) for details.\n// Basically it applies four rules and summate all penalties.\nfunction calculateMaskPenalty(matrix) {\n return (\n applyMaskPenaltyRule1(matrix) +\n applyMaskPenaltyRule2(matrix) +\n applyMaskPenaltyRule3(matrix) +\n applyMaskPenaltyRule4(matrix)\n );\n}\n// Return is apply mask at \"x\" and \"y\". See 7.8 of ISO/IEC 18004:2015(E)(p.50) for mask pattern conditions.\nfunction isApplyMask(mask, x, y) {\n let temporary;\n let intermediate;\n switch (mask) {\n case 0:\n intermediate = (y + x) & 0x01;\n break;\n case 1:\n intermediate = y & 0x01;\n break;\n case 2:\n intermediate = x % 3;\n break;\n case 3:\n intermediate = (y + x) % 3;\n break;\n case 4:\n intermediate = (toInt32(y / 2) + toInt32(x / 3)) & 0x01;\n break;\n case 5:\n temporary = y * x;\n intermediate = (temporary & 0x01) + (temporary % 3);\n break;\n case 6:\n temporary = y * x;\n intermediate = ((temporary & 0x01) + (temporary % 3)) & 0x01;\n break;\n case 7:\n intermediate = (((y * x) % 3) + ((y + x) & 0x01)) & 0x01;\n break;\n default:\n throw new Error(`illegal mask: ${mask}`);\n }\n return intermediate === 0;\n}\n\nexport { calculateMaskPenalty, isApplyMask };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module ECLevel\n */\nconst VALUES_TO_ECLEVEL = new Map();\nfunction fromECLevelBits(bits) {\n const ecLevel = VALUES_TO_ECLEVEL.get(bits);\n if (ecLevel != null) {\n return ecLevel;\n }\n throw new Error('illegal error correction bits');\n}\nclass ECLevel {\n #name;\n #bits;\n #level;\n // L = ~7% correction.\n static L = new ECLevel('L', 0, 0x01);\n // L = ~15% correction.\n static M = new ECLevel('M', 1, 0x00);\n // L = ~25% correction.\n static Q = new ECLevel('Q', 2, 0x03);\n // L = ~30% correction.\n static H = new ECLevel('H', 3, 0x02);\n constructor(name, level, bits) {\n this.#bits = bits;\n this.#name = name;\n this.#level = level;\n VALUES_TO_ECLEVEL.set(bits, this);\n }\n get bits() {\n return this.#bits;\n }\n get name() {\n return this.#name;\n }\n get level() {\n return this.#level;\n }\n}\n\nexport { ECLevel, fromECLevelBits };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module ECB\n */\nclass ECB {\n #count;\n #numDataCodewords;\n constructor(count, numDataCodewords) {\n this.#count = count;\n this.#numDataCodewords = numDataCodewords;\n }\n get count() {\n return this.#count;\n }\n get numDataCodewords() {\n return this.#numDataCodewords;\n }\n}\n\nexport { ECB };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module ECBlocks\n */\nclass ECBlocks {\n #ecBlocks;\n #numTotalCodewords;\n #numTotalECCodewords;\n #numTotalDataCodewords;\n #numECCodewordsPerBlock;\n constructor(numECCodewordsPerBlock, ...ecBlocks) {\n let numBlocks = 0;\n let numTotalDataCodewords = 0;\n for (const { count, numDataCodewords } of ecBlocks) {\n numBlocks += count;\n numTotalDataCodewords += numDataCodewords * count;\n }\n const numTotalECCodewords = numECCodewordsPerBlock * numBlocks;\n this.#ecBlocks = ecBlocks;\n this.#numTotalECCodewords = numTotalECCodewords;\n this.#numTotalDataCodewords = numTotalDataCodewords;\n this.#numECCodewordsPerBlock = numECCodewordsPerBlock;\n this.#numTotalCodewords = numTotalDataCodewords + numTotalECCodewords;\n }\n get ecBlocks() {\n return this.#ecBlocks;\n }\n get numTotalCodewords() {\n return this.#numTotalCodewords;\n }\n get numTotalECCodewords() {\n return this.#numTotalECCodewords;\n }\n get numTotalDataCodewords() {\n return this.#numTotalDataCodewords;\n }\n get numECCodewordsPerBlock() {\n return this.#numECCodewordsPerBlock;\n }\n}\n\nexport { ECBlocks };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { ECB } from './ECB.js';\nimport { ECBlocks } from './ECBlocks.js';\nimport { BitMatrix } from './BitMatrix.js';\nimport { hammingWeight } from './utils.js';\n\n/**\n * @module Version\n */\nconst MIN_VERSION_SIZE = 21;\nconst MAX_VERSION_SIZE = 177;\nconst VERSION_DECODE_TABLE = [\n // Version 7 - 11.\n 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6,\n // Version 12 - 16.\n 0x0c762, 0x0d847, 0x0e60d, 0x0f928, 0x10b78,\n // Version 17 - 21.\n 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683,\n // Version 22 - 26.\n 0x168c9, 0x177ec, 0x18ec4, 0x191e1, 0x1afab,\n // Version 27 - 31.\n 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, 0x1f250,\n // Version 32 - 36.\n 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b,\n // Version 37 - 40.\n 0x2542e, 0x26a64, 0x27541, 0x28c69\n];\n// Version > 2 has alignment patterns.\nconst MIN_VERSION_SIZE_WITH_ALIGNMENTS = 25;\nclass Version {\n #size;\n #version;\n #ecBlocks;\n #alignmentPatterns;\n constructor(version, alignmentPatterns, ...ecBlocks) {\n this.#version = version;\n this.#ecBlocks = ecBlocks;\n this.#size = 17 + 4 * version;\n this.#alignmentPatterns = alignmentPatterns;\n }\n get size() {\n return this.#size;\n }\n get version() {\n return this.#version;\n }\n get alignmentPatterns() {\n return this.#alignmentPatterns;\n }\n getECBlocks({ level }) {\n return this.#ecBlocks[level];\n }\n}\nconst VERSIONS = [\n new Version(\n 1,\n [],\n new ECBlocks(7, new ECB(1, 19)),\n new ECBlocks(10, new ECB(1, 16)),\n new ECBlocks(13, new ECB(1, 13)),\n new ECBlocks(17, new ECB(1, 9))\n ),\n new Version(\n 2,\n [6, 18],\n new ECBlocks(10, new ECB(1, 34)),\n new ECBlocks(16, new ECB(1, 28)),\n new ECBlocks(22, new ECB(1, 22)),\n new ECBlocks(28, new ECB(1, 16))\n ),\n new Version(\n 3,\n [6, 22],\n new ECBlocks(15, new ECB(1, 55)),\n new ECBlocks(26, new ECB(1, 44)),\n new ECBlocks(18, new ECB(2, 17)),\n new ECBlocks(22, new ECB(2, 13))\n ),\n new Version(\n 4,\n [6, 26],\n new ECBlocks(20, new ECB(1, 80)),\n new ECBlocks(18, new ECB(2, 32)),\n new ECBlocks(26, new ECB(2, 24)),\n new ECBlocks(16, new ECB(4, 9))\n ),\n new Version(\n 5,\n [6, 30],\n new ECBlocks(26, new ECB(1, 108)),\n new ECBlocks(24, new ECB(2, 43)),\n new ECBlocks(18, new ECB(2, 15), new ECB(2, 16)),\n new ECBlocks(22, new ECB(2, 11), new ECB(2, 12))\n ),\n new Version(\n 6,\n [6, 34],\n new ECBlocks(18, new ECB(2, 68)),\n new ECBlocks(16, new ECB(4, 27)),\n new ECBlocks(24, new ECB(4, 19)),\n new ECBlocks(28, new ECB(4, 15))\n ),\n new Version(\n 7,\n [6, 22, 38],\n new ECBlocks(20, new ECB(2, 78)),\n new ECBlocks(18, new ECB(4, 31)),\n new ECBlocks(18, new ECB(2, 14), new ECB(4, 15)),\n new ECBlocks(26, new ECB(4, 13), new ECB(1, 14))\n ),\n new Version(\n 8,\n [6, 24, 42],\n new ECBlocks(24, new ECB(2, 97)),\n new ECBlocks(22, new ECB(2, 38), new ECB(2, 39)),\n new ECBlocks(22, new ECB(4, 18), new ECB(2, 19)),\n new ECBlocks(26, new ECB(4, 14), new ECB(2, 15))\n ),\n new Version(\n 9,\n [6, 26, 46],\n new ECBlocks(30, new ECB(2, 116)),\n new ECBlocks(22, new ECB(3, 36), new ECB(2, 37)),\n new ECBlocks(20, new ECB(4, 16), new ECB(4, 17)),\n new ECBlocks(24, new ECB(4, 12), new ECB(4, 13))\n ),\n new Version(\n 10,\n [6, 28, 50],\n new ECBlocks(18, new ECB(2, 68), new ECB(2, 69)),\n new ECBlocks(26, new ECB(4, 43), new ECB(1, 44)),\n new ECBlocks(24, new ECB(6, 19), new ECB(2, 20)),\n new ECBlocks(28, new ECB(6, 15), new ECB(2, 16))\n ),\n new Version(\n 11,\n [6, 30, 54],\n new ECBlocks(20, new ECB(4, 81)),\n new ECBlocks(30, new ECB(1, 50), new ECB(4, 51)),\n new ECBlocks(28, new ECB(4, 22), new ECB(4, 23)),\n new ECBlocks(24, new ECB(3, 12), new ECB(8, 13))\n ),\n new Version(\n 12,\n [6, 32, 58],\n new ECBlocks(24, new ECB(2, 92), new ECB(2, 93)),\n new ECBlocks(22, new ECB(6, 36), new ECB(2, 37)),\n new ECBlocks(26, new ECB(4, 20), new ECB(6, 21)),\n new ECBlocks(28, new ECB(7, 14), new ECB(4, 15))\n ),\n new Version(\n 13,\n [6, 34, 62],\n new ECBlocks(26, new ECB(4, 107)),\n new ECBlocks(22, new ECB(8, 37), new ECB(1, 38)),\n new ECBlocks(24, new ECB(8, 20), new ECB(4, 21)),\n new ECBlocks(22, new ECB(12, 11), new ECB(4, 12))\n ),\n new Version(\n 14,\n [6, 26, 46, 66],\n new ECBlocks(30, new ECB(3, 115), new ECB(1, 116)),\n new ECBlocks(24, new ECB(4, 40), new ECB(5, 41)),\n new ECBlocks(20, new ECB(11, 16), new ECB(5, 17)),\n new ECBlocks(24, new ECB(11, 12), new ECB(5, 13))\n ),\n new Version(\n 15,\n [6, 26, 48, 70],\n new ECBlocks(22, new ECB(5, 87), new ECB(1, 88)),\n new ECBlocks(24, new ECB(5, 41), new ECB(5, 42)),\n new ECBlocks(30, new ECB(5, 24), new ECB(7, 25)),\n new ECBlocks(24, new ECB(11, 12), new ECB(7, 13))\n ),\n new Version(\n 16,\n [6, 26, 50, 74],\n new ECBlocks(24, new ECB(5, 98), new ECB(1, 99)),\n new ECBlocks(28, new ECB(7, 45), new ECB(3, 46)),\n new ECBlocks(24, new ECB(15, 19), new ECB(2, 20)),\n new ECBlocks(30, new ECB(3, 15), new ECB(13, 16))\n ),\n new Version(\n 17,\n [6, 30, 54, 78],\n new ECBlocks(28, new ECB(1, 107), new ECB(5, 108)),\n new ECBlocks(28, new ECB(10, 46), new ECB(1, 47)),\n new ECBlocks(28, new ECB(1, 22), new ECB(15, 23)),\n new ECBlocks(28, new ECB(2, 14), new ECB(17, 15))\n ),\n new Version(\n 18,\n [6, 30, 56, 82],\n new ECBlocks(30, new ECB(5, 120), new ECB(1, 121)),\n new ECBlocks(26, new ECB(9, 43), new ECB(4, 44)),\n new ECBlocks(28, new ECB(17, 22), new ECB(1, 23)),\n new ECBlocks(28, new ECB(2, 14), new ECB(19, 15))\n ),\n new Version(\n 19,\n [6, 30, 58, 86],\n new ECBlocks(28, new ECB(3, 113), new ECB(4, 114)),\n new ECBlocks(26, new ECB(3, 44), new ECB(11, 45)),\n new ECBlocks(26, new ECB(17, 21), new ECB(4, 22)),\n new ECBlocks(26, new ECB(9, 13), new ECB(16, 14))\n ),\n new Version(\n 20,\n [6, 34, 62, 90],\n new ECBlocks(28, new ECB(3, 107), new ECB(5, 108)),\n new ECBlocks(26, new ECB(3, 41), new ECB(13, 42)),\n new ECBlocks(30, new ECB(15, 24), new ECB(5, 25)),\n new ECBlocks(28, new ECB(15, 15), new ECB(10, 16))\n ),\n new Version(\n 21,\n [6, 28, 50, 72, 94],\n new ECBlocks(28, new ECB(4, 116), new ECB(4, 117)),\n new ECBlocks(26, new ECB(17, 42)),\n new ECBlocks(28, new ECB(17, 22), new ECB(6, 23)),\n new ECBlocks(30, new ECB(19, 16), new ECB(6, 17))\n ),\n new Version(\n 22,\n [6, 26, 50, 74, 98],\n new ECBlocks(28, new ECB(2, 111), new ECB(7, 112)),\n new ECBlocks(28, new ECB(17, 46)),\n new ECBlocks(30, new ECB(7, 24), new ECB(16, 25)),\n new ECBlocks(24, new ECB(34, 13))\n ),\n new Version(\n 23,\n [6, 30, 54, 78, 102],\n new ECBlocks(30, new ECB(4, 121), new ECB(5, 122)),\n new ECBlocks(28, new ECB(4, 47), new ECB(14, 48)),\n new ECBlocks(30, new ECB(11, 24), new ECB(14, 25)),\n new ECBlocks(30, new ECB(16, 15), new ECB(14, 16))\n ),\n new Version(\n 24,\n [6, 28, 54, 80, 106],\n new ECBlocks(30, new ECB(6, 117), new ECB(4, 118)),\n new ECBlocks(28, new ECB(6, 45), new ECB(14, 46)),\n new ECBlocks(30, new ECB(11, 24), new ECB(16, 25)),\n new ECBlocks(30, new ECB(30, 16), new ECB(2, 17))\n ),\n new Version(\n 25,\n [6, 32, 58, 84, 110],\n new ECBlocks(26, new ECB(8, 106), new ECB(4, 107)),\n new ECBlocks(28, new ECB(8, 47), new ECB(13, 48)),\n new ECBlocks(30, new ECB(7, 24), new ECB(22, 25)),\n new ECBlocks(30, new ECB(22, 15), new ECB(13, 16))\n ),\n new Version(\n 26,\n [6, 30, 58, 86, 114],\n new ECBlocks(28, new ECB(10, 114), new ECB(2, 115)),\n new ECBlocks(28, new ECB(19, 46), new ECB(4, 47)),\n new ECBlocks(28, new ECB(28, 22), new ECB(6, 23)),\n new ECBlocks(30, new ECB(33, 16), new ECB(4, 17))\n ),\n new Version(\n 27,\n [6, 34, 62, 90, 118],\n new ECBlocks(30, new ECB(8, 122), new ECB(4, 123)),\n new ECBlocks(28, new ECB(22, 45), new ECB(3, 46)),\n new ECBlocks(30, new ECB(8, 23), new ECB(26, 24)),\n new ECBlocks(30, new ECB(12, 15), new ECB(28, 16))\n ),\n new Version(\n 28,\n [6, 26, 50, 74, 98, 122],\n new ECBlocks(30, new ECB(3, 117), new ECB(10, 118)),\n new ECBlocks(28, new ECB(3, 45), new ECB(23, 46)),\n new ECBlocks(30, new ECB(4, 24), new ECB(31, 25)),\n new ECBlocks(30, new ECB(11, 15), new ECB(31, 16))\n ),\n new Version(\n 29,\n [6, 30, 54, 78, 102, 126],\n new ECBlocks(30, new ECB(7, 116), new ECB(7, 117)),\n new ECBlocks(28, new ECB(21, 45), new ECB(7, 46)),\n new ECBlocks(30, new ECB(1, 23), new ECB(37, 24)),\n new ECBlocks(30, new ECB(19, 15), new ECB(26, 16))\n ),\n new Version(\n 30,\n [6, 26, 52, 78, 104, 130],\n new ECBlocks(30, new ECB(5, 115), new ECB(10, 116)),\n new ECBlocks(28, new ECB(19, 47), new ECB(10, 48)),\n new ECBlocks(30, new ECB(15, 24), new ECB(25, 25)),\n new ECBlocks(30, new ECB(23, 15), new ECB(25, 16))\n ),\n new Version(\n 31,\n [6, 30, 56, 82, 108, 134],\n new ECBlocks(30, new ECB(13, 115), new ECB(3, 116)),\n new ECBlocks(28, new ECB(2, 46), new ECB(29, 47)),\n new ECBlocks(30, new ECB(42, 24), new ECB(1, 25)),\n new ECBlocks(30, new ECB(23, 15), new ECB(28, 16))\n ),\n new Version(\n 32,\n [6, 34, 60, 86, 112, 138],\n new ECBlocks(30, new ECB(17, 115)),\n new ECBlocks(28, new ECB(10, 46), new ECB(23, 47)),\n new ECBlocks(30, new ECB(10, 24), new ECB(35, 25)),\n new ECBlocks(30, new ECB(19, 15), new ECB(35, 16))\n ),\n new Version(\n 33,\n [6, 30, 58, 86, 114, 142],\n new ECBlocks(30, new ECB(17, 115), new ECB(1, 116)),\n new ECBlocks(28, new ECB(14, 46), new ECB(21, 47)),\n new ECBlocks(30, new ECB(29, 24), new ECB(19, 25)),\n new ECBlocks(30, new ECB(11, 15), new ECB(46, 16))\n ),\n new Version(\n 34,\n [6, 34, 62, 90, 118, 146],\n new ECBlocks(30, new ECB(13, 115), new ECB(6, 116)),\n new ECBlocks(28, new ECB(14, 46), new ECB(23, 47)),\n new ECBlocks(30, new ECB(44, 24), new ECB(7, 25)),\n new ECBlocks(30, new ECB(59, 16), new ECB(1, 17))\n ),\n new Version(\n 35,\n [6, 30, 54, 78, 102, 126, 150],\n new ECBlocks(30, new ECB(12, 121), new ECB(7, 122)),\n new ECBlocks(28, new ECB(12, 47), new ECB(26, 48)),\n new ECBlocks(30, new ECB(39, 24), new ECB(14, 25)),\n new ECBlocks(30, new ECB(22, 15), new ECB(41, 16))\n ),\n new Version(\n 36,\n [6, 24, 50, 76, 102, 128, 154],\n new ECBlocks(30, new ECB(6, 121), new ECB(14, 122)),\n new ECBlocks(28, new ECB(6, 47), new ECB(34, 48)),\n new ECBlocks(30, new ECB(46, 24), new ECB(10, 25)),\n new ECBlocks(30, new ECB(2, 15), new ECB(64, 16))\n ),\n new Version(\n 37,\n [6, 28, 54, 80, 106, 132, 158],\n new ECBlocks(30, new ECB(17, 122), new ECB(4, 123)),\n new ECBlocks(28, new ECB(29, 46), new ECB(14, 47)),\n new ECBlocks(30, new ECB(49, 24), new ECB(10, 25)),\n new ECBlocks(30, new ECB(24, 15), new ECB(46, 16))\n ),\n new Version(\n 38,\n [6, 32, 58, 84, 110, 136, 162],\n new ECBlocks(30, new ECB(4, 122), new ECB(18, 123)),\n new ECBlocks(28, new ECB(13, 46), new ECB(32, 47)),\n new ECBlocks(30, new ECB(48, 24), new ECB(14, 25)),\n new ECBlocks(30, new ECB(42, 15), new ECB(32, 16))\n ),\n new Version(\n 39,\n [6, 26, 54, 82, 110, 138, 166],\n new ECBlocks(30, new ECB(20, 117), new ECB(4, 118)),\n new ECBlocks(28, new ECB(40, 47), new ECB(7, 48)),\n new ECBlocks(30, new ECB(43, 24), new ECB(22, 25)),\n new ECBlocks(30, new ECB(10, 15), new ECB(67, 16))\n ),\n new Version(\n 40,\n [6, 30, 58, 86, 114, 142, 170],\n new ECBlocks(30, new ECB(19, 118), new ECB(6, 119)),\n new ECBlocks(28, new ECB(18, 47), new ECB(31, 48)),\n new ECBlocks(30, new ECB(34, 24), new ECB(34, 25)),\n new ECBlocks(30, new ECB(20, 15), new ECB(61, 16))\n )\n];\nfunction decodeVersion(version1, version2) {\n let bestDiff = 32;\n let bestVersion = 0;\n const { length } = VERSION_DECODE_TABLE;\n for (let i = 0; i < length; i++) {\n const maskedVersion = VERSION_DECODE_TABLE[i];\n // Do the version info bits match exactly done?\n if (version1 === maskedVersion || version2 === maskedVersion) {\n return VERSIONS[i + 6];\n }\n // Otherwise see if this is the closest to a real version info bit string we have seen so far.\n let bitsDiff = hammingWeight(version1 ^ maskedVersion);\n if (bitsDiff < bestDiff) {\n bestDiff = bitsDiff;\n bestVersion = i + 7;\n }\n if (version1 !== version2) {\n // Also try the other option.\n bitsDiff = hammingWeight(version2 ^ maskedVersion);\n if (bitsDiff < bestDiff) {\n bestDiff = bitsDiff;\n bestVersion = i + 7;\n }\n }\n }\n // We can tolerate up to 3 bits of error since no two version info codewords will differ in less than 8 bits.\n if (bestDiff <= 3 && bestVersion >= 7) {\n return VERSIONS[bestVersion - 1];\n }\n // If we didn't find a close enough match, fail.\n throw new Error('unable to decode version');\n}\n// See ISO 18004:2006 Annex E\nfunction buildFunctionPattern({ size, version, alignmentPatterns }) {\n // Alignment patterns\n const { length } = alignmentPatterns;\n const matrix = new BitMatrix(size);\n const max = length - 1;\n // Top left finder pattern + separator + format.\n matrix.setRegion(0, 0, 9, 9);\n // Top right finder pattern + separator + format.\n matrix.setRegion(size - 8, 0, 8, 9);\n // Bottom left finder pattern + separator + format.\n matrix.setRegion(0, size - 8, 9, 8);\n for (let x = 0; x < length; x++) {\n const top = alignmentPatterns[x] - 2;\n for (let y = 0; y < length; y++) {\n if ((x !== 0 || (y !== 0 && y !== max)) && (x !== max || y !== 0)) {\n matrix.setRegion(alignmentPatterns[y] - 2, top, 5, 5);\n }\n // Else no o alignment patterns near the three finder patterns.\n }\n }\n // Vertical timing pattern.\n matrix.setRegion(6, 9, 1, size - 17);\n // Horizontal timing pattern.\n matrix.setRegion(9, 6, size - 17, 1);\n if (version > 6) {\n // Version info, top right.\n matrix.setRegion(size - 11, 0, 3, 6);\n // Version info, bottom left.\n matrix.setRegion(0, size - 11, 6, 3);\n }\n return matrix;\n}\n\nexport {\n MAX_VERSION_SIZE,\n MIN_VERSION_SIZE,\n MIN_VERSION_SIZE_WITH_ALIGNMENTS,\n VERSIONS,\n Version,\n buildFunctionPattern,\n decodeVersion\n};\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module Polynomial\n */\nclass Polynomial {\n #field;\n #coefficients;\n constructor(field, coefficients) {\n const { length } = coefficients;\n if (length <= 0) {\n throw new Error('polynomial coefficients cannot empty');\n }\n this.#field = field;\n if (length > 1 && coefficients[0] === 0) {\n // Leading term must be non-zero for anything except the constant polynomial \"0\".\n let firstNonZero = 1;\n while (firstNonZero < length && coefficients[firstNonZero] === 0) {\n firstNonZero++;\n }\n if (firstNonZero === length) {\n this.#coefficients = new Int32Array([0]);\n } else {\n const array = new Int32Array(length - firstNonZero);\n array.set(coefficients.subarray(firstNonZero));\n this.#coefficients = array;\n }\n } else {\n this.#coefficients = coefficients;\n }\n }\n get coefficients() {\n return this.#coefficients;\n }\n isZero() {\n return this.#coefficients[0] === 0;\n }\n getDegree() {\n return this.#coefficients.length - 1;\n }\n getCoefficient(degree) {\n const coefficients = this.#coefficients;\n return coefficients[coefficients.length - 1 - degree];\n }\n evaluate(a) {\n if (a === 0) {\n // Just return the x^0 coefficient.\n return this.getCoefficient(0);\n }\n let result;\n const coefficients = this.#coefficients;\n if (a === 1) {\n // Just the sum of the coefficients.\n result = 0;\n for (const coefficient of coefficients) {\n result ^= coefficient;\n }\n return result;\n }\n [result] = coefficients;\n const field = this.#field;\n const { length } = coefficients;\n for (let i = 1; i < length; i++) {\n result = field.multiply(a, result) ^ coefficients[i];\n }\n return result;\n }\n multiply(other) {\n const field = this.#field;\n const coefficients = this.#coefficients;\n const { length } = coefficients;\n if (other instanceof Polynomial) {\n if (this.isZero() || other.isZero()) {\n return field.zero;\n }\n const otherCoefficients = other.#coefficients;\n const otherLength = otherCoefficients.length;\n const product = new Int32Array(length + otherLength - 1);\n for (let i = 0; i < length; i++) {\n const coefficient = coefficients[i];\n for (let j = 0; j < otherLength; j++) {\n product[i + j] ^= field.multiply(coefficient, otherCoefficients[j]);\n }\n }\n return new Polynomial(field, product);\n }\n if (other === 0) {\n return field.zero;\n }\n if (other === 1) {\n return this;\n }\n const product = new Int32Array(length);\n for (let i = 0; i < length; i++) {\n product[i] = field.multiply(coefficients[i], other);\n }\n return new Polynomial(field, product);\n }\n multiplyByMonomial(degree, coefficient) {\n const field = this.#field;\n if (coefficient === 0) {\n return field.zero;\n }\n const coefficients = this.#coefficients;\n const { length } = coefficients;\n const product = new Int32Array(length + degree);\n for (let i = 0; i < length; i++) {\n product[i] = field.multiply(coefficients[i], coefficient);\n }\n return new Polynomial(field, product);\n }\n addOrSubtract(other) {\n if (this.isZero()) {\n return other;\n }\n if (other.isZero()) {\n return this;\n }\n let largerCoefficients = other.#coefficients;\n let largerLength = largerCoefficients.length;\n let smallerCoefficients = this.#coefficients;\n let smallerLength = smallerCoefficients.length;\n if (largerLength < smallerLength) {\n [largerLength, smallerLength] = [smallerLength, largerLength];\n [largerCoefficients, smallerCoefficients] = [smallerCoefficients, largerCoefficients];\n }\n // Diff index offset.\n const offset = largerLength - smallerLength;\n const coefficients = new Int32Array(largerLength);\n // Copy high-order terms only found in higher-degree polynomial's coefficients.\n coefficients.set(largerCoefficients.subarray(0, offset));\n for (let i = offset; i < largerLength; i++) {\n coefficients[i] = smallerCoefficients[i - offset] ^ largerCoefficients[i];\n }\n return new Polynomial(this.#field, coefficients);\n }\n divide(other) {\n const field = this.#field;\n let quotient = field.zero;\n let remainder = this;\n const denominatorLeadingTerm = other.getCoefficient(other.getDegree());\n const invertDenominatorLeadingTerm = field.invert(denominatorLeadingTerm);\n while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {\n const remainderDegree = remainder.getDegree();\n const degreeDiff = remainderDegree - other.getDegree();\n const scale = field.multiply(remainder.getCoefficient(remainderDegree), invertDenominatorLeadingTerm);\n const term = other.multiplyByMonomial(degreeDiff, scale);\n const iterationQuotient = field.buildPolynomial(degreeDiff, scale);\n quotient = quotient.addOrSubtract(iterationQuotient);\n remainder = remainder.addOrSubtract(term);\n }\n return [quotient, remainder];\n }\n}\n\nexport { Polynomial };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { Polynomial } from './Polynomial.js';\n\n/**\n * @module GaloisField\n */\nclass GaloisField {\n #size;\n #one;\n #zero;\n #generator;\n #expTable;\n #logTable;\n constructor(primitive, size, generator) {\n let x = 1;\n const expTable = new Int32Array(size);\n for (let i = 0; i < size; i++) {\n expTable[i] = x;\n // We're assuming the generator alpha is 2.\n x *= 2;\n if (x >= size) {\n x ^= primitive;\n x &= size - 1;\n }\n }\n const logTable = new Int32Array(size);\n for (let i = 0, length = size - 1; i < length; i++) {\n logTable[expTable[i]] = i;\n }\n this.#size = size;\n this.#expTable = expTable;\n this.#logTable = logTable;\n this.#generator = generator;\n this.#one = new Polynomial(this, new Int32Array([1]));\n this.#zero = new Polynomial(this, new Int32Array([0]));\n }\n get size() {\n return this.#size;\n }\n get one() {\n return this.#one;\n }\n get zero() {\n return this.#zero;\n }\n get generator() {\n return this.#generator;\n }\n exp(a) {\n return this.#expTable[a];\n }\n log(a) {\n return this.#logTable[a];\n }\n invert(a) {\n return this.#expTable[this.#size - this.#logTable[a] - 1];\n }\n multiply(a, b) {\n if (a === 0 || b === 0) {\n return 0;\n }\n const logTable = this.#logTable;\n return this.#expTable[(logTable[a] + logTable[b]) % (this.#size - 1)];\n }\n buildPolynomial(degree, coefficient) {\n if (coefficient === 0) {\n return this.#zero;\n }\n const coefficients = new Int32Array(degree + 1);\n coefficients[0] = coefficient;\n return new Polynomial(this, coefficients);\n }\n}\nconst QR_CODE_FIELD_256 = new GaloisField(0x011d, 256, 0);\n\nexport { GaloisField, QR_CODE_FIELD_256 };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { Charset } from '../Charset.js';\n\n/**\n * @module index\n */\nfunction getUnicodeCodes(content, maxCode) {\n const bytes = [];\n for (const character of content) {\n const code = character.codePointAt(0);\n // If gt max code, push \"?\".\n bytes.push(code == null || code > maxCode ? 63 : code);\n }\n return new Uint8Array(bytes);\n}\nfunction encode(content, charset) {\n switch (charset) {\n case Charset.ASCII:\n return getUnicodeCodes(content, 0x7f);\n case Charset.ISO_8859_1:\n return getUnicodeCodes(content, 0xff);\n case Charset.UTF_8:\n return new TextEncoder().encode(content);\n default:\n throw Error(`built-in encode not support charset: ${charset.label}`);\n }\n}\nfunction decode(bytes, charset) {\n try {\n return new TextDecoder(charset.label).decode(bytes);\n } catch {\n throw Error(`built-in decode not support charset: ${charset.label}`);\n }\n}\n\nexport { decode, encode };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { getBitMask, toBit, getBitOffset, toInt32 } from './utils.js';\n\n/**\n * @module BitArray\n */\nconst LOAD_FACTOR = 0.75;\nfunction offset(index) {\n return toInt32(index / 32);\n}\nfunction makeArray(length) {\n return new Int32Array(Math.ceil(length / 32));\n}\nclass BitArray {\n #length;\n #bits;\n constructor(length = 0) {\n this.#length = length;\n this.#bits = makeArray(length);\n }\n #alloc(length) {\n const bits = this.#bits;\n if (length > bits.length * 32) {\n const array = makeArray(Math.ceil(length / LOAD_FACTOR));\n array.set(bits);\n this.#bits = array;\n }\n this.#length = length;\n }\n get length() {\n return this.#length;\n }\n get byteLength() {\n return Math.ceil(this.#length / 8);\n }\n set(index) {\n this.#bits[offset(index)] |= getBitMask(index);\n }\n get(index) {\n return toBit(this.#bits[offset(index)] >>> getBitOffset(index));\n }\n xor(mask) {\n const bits = this.#bits;\n const maskBits = mask.#bits;\n const length = Math.min(this.#length, mask.#length);\n for (let i = 0; i < length; i++) {\n // The last int could be incomplete (i.e. not have 32 bits in\n // it) but there is no problem since 0 XOR 0 == 0.\n bits[i] ^= maskBits[i];\n }\n }\n append(value, length = 1) {\n let index = this.#length;\n if (value instanceof BitArray) {\n length = value.#length;\n this.#alloc(index + length);\n for (let i = 0; i < length; i++) {\n if (value.get(i) !== 0) {\n this.set(index);\n }\n index++;\n }\n } else {\n this.#alloc(index + length);\n for (let i = length - 1; i >= 0; i--) {\n if (toBit(value >>> i) !== 0) {\n this.set(index);\n }\n index++;\n }\n }\n }\n writeToUint8Array(bitOffset, target, byteOffset, byteLength) {\n for (let i = 0; i < byteLength; i++) {\n let byte = 0;\n for (let j = 0; j < 8; j++) {\n if (this.get(bitOffset++) !== 0) {\n byte |= 1 << (7 - j);\n }\n }\n target[byteOffset + i] = byte;\n }\n }\n clear() {\n this.#bits.fill(0);\n }\n}\n\nexport { BitArray };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module ByteMatrix\n */\nclass ByteMatrix {\n #size;\n #bytes;\n constructor(size) {\n this.#size = size;\n this.#bytes = new Int8Array(size * size);\n }\n get size() {\n return this.#size;\n }\n set(x, y, value) {\n this.#bytes[y * this.#size + x] = value;\n }\n get(x, y) {\n return this.#bytes[y * this.#size + x];\n }\n clear(value) {\n this.#bytes.fill(value);\n }\n}\n\nexport { ByteMatrix };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { isApplyMask } from '../../common/mask.js';\nimport { BitArray } from '../../common/BitArray.js';\nimport { ByteMatrix } from '../../common/ByteMatrix.js';\nimport { calculateBCHCode } from '../../common/utils.js';\nimport { VERSIONS } from '../../common/Version.js';\n\n/**\n * @module matrix\n */\n// Format information poly: 101 0011 0111.\nconst FORMAT_INFO_POLY = 0x537;\n// Format information mask.\nconst FORMAT_INFO_MASK = 0x5412;\n// Version information poly: 1 1111 0010 0101.\nconst VERSION_INFO_POLY = 0x1f25;\n// Finder pattern shape.\nconst FINDER_PATTERN_SHAPE = [\n [1, 1, 1, 1, 1, 1, 1],\n [1, 0, 0, 0, 0, 0, 1],\n [1, 0, 1, 1, 1, 0, 1],\n [1, 0, 1, 1, 1, 0, 1],\n [1, 0, 1, 1, 1, 0, 1],\n [1, 0, 0, 0, 0, 0, 1],\n [1, 1, 1, 1, 1, 1, 1]\n];\n// Alignment pattern shape.\nconst ALIGNMENT_PATTERN_SHAPE = [\n [1, 1, 1, 1, 1],\n [1, 0, 0, 0, 1],\n [1, 0, 1, 0, 1],\n [1, 0, 0, 0, 1],\n [1, 1, 1, 1, 1]\n];\n// Format information coordinates.\nconst FORMAT_INFO_COORDINATES = [\n [8, 0],\n [8, 1],\n [8, 2],\n [8, 3],\n [8, 4],\n [8, 5],\n [8, 7],\n [8, 8],\n [7, 8],\n [5, 8],\n [4, 8],\n [3, 8],\n [2, 8],\n [1, 8],\n [0, 8]\n];\n// Is empty point.\nfunction isEmpty(matrix, x, y) {\n return matrix.get(x, y) === -1;\n}\nfunction embedFinderPattern(matrix, x, y) {\n for (let i = 0; i < 7; i++) {\n const pattern = FINDER_PATTERN_SHAPE[i];\n for (let j = 0; j < 7; j++) {\n matrix.set(x + j, y + i, pattern[j]);\n }\n }\n}\nfunction embedHorizontalSeparator(matrix, x, y) {\n for (let j = 0; j < 8; j++) {\n matrix.set(x + j, y, 0);\n }\n}\nfunction embedVerticalSeparator(matrix, x, y) {\n for (let i = 0; i < 7; i++) {\n matrix.set(x, y + i, 0);\n }\n}\n// Embed finder patterns and surrounding vertical/horizontal separators.\nfunction embedFinderPatternsAndSeparators(matrix) {\n // Embed three big squares at corners.\n const pdpWidth = 7;\n // Embed horizontal separation patterns around the squares.\n const hspWidth = 8;\n // Embed vertical separation patterns around the squares.\n const vspHeight = 7;\n // Matrix width\n const { size } = matrix;\n // Left top corner.\n embedFinderPattern(matrix, 0, 0);\n // Right top corner.\n embedFinderPattern(matrix, size - pdpWidth, 0);\n // Left bottom corner.\n embedFinderPattern(matrix, 0, size - pdpWidth);\n // Left top corner.\n embedHorizontalSeparator(matrix, 0, hspWidth - 1);\n // Right top corner.\n embedHorizontalSeparator(matrix, size - hspWidth, hspWidth - 1);\n // Left bottom corner.\n embedHorizontalSeparator(matrix, 0, size - hspWidth);\n // Left top corner.\n embedVerticalSeparator(matrix, vspHeight, 0);\n // Right top corner.\n embedVerticalSeparator(matrix, size - vspHeight - 1, 0);\n // Left bottom corner.\n embedVerticalSeparator(matrix, vspHeight, size - vspHeight);\n}\nfunction embedTimingPatterns(matrix) {\n const size = matrix.size - 8;\n // -8 is for skipping position detection patterns (7: size)\n // separation patterns (1: size). Thus, 8 = 7 + 1.\n for (let x = 8; x < size; x++) {\n const bit = (x + 1) & 0x01;\n // Horizontal line.\n if (isEmpty(matrix, x, 6)) {\n matrix.set(x, 6, bit);\n }\n }\n // -8 is for skipping position detection patterns (7: size)\n // separation patterns (1: size). Thus, 8 = 7 + 1.\n for (let y = 8; y < size; y++) {\n const bit = (y + 1) & 0x01;\n // Vertical line.\n if (isEmpty(matrix, 6, y)) {\n matrix.set(6, y, bit);\n }\n }\n}\nfunction embedAlignmentPattern(matrix, x, y) {\n for (let i = 0; i < 5; i++) {\n const pattern = ALIGNMENT_PATTERN_SHAPE[i];\n for (let j = 0; j < 5; j++) {\n matrix.set(x + j, y + i, pattern[j]);\n }\n }\n}\n// Embed position alignment patterns if need be.\nfunction embedAlignmentPatterns(matrix, { version }) {\n if (version >= 2) {\n const { alignmentPatterns } = VERSIONS[version - 1];\n const { length } = alignmentPatterns;\n for (let i = 0; i < length; i++) {\n const y = alignmentPatterns[i];\n for (let j = 0; j < length; j++) {\n const x = alignmentPatterns[j];\n if (isEmpty(matrix, x, y)) {\n // If the cell is unset, we embed the position alignment pattern here.\n // -2 is necessary since the x/y coordinates point to the center of the pattern, not the\n // left top corner.\n embedAlignmentPattern(matrix, x - 2, y - 2);\n }\n }\n }\n }\n}\n// Embed the lonely dark dot at left bottom corner. ISO/IEC 18004:2015(E)(p.56)\nfunction embedDarkModule(matrix) {\n matrix.set(8, matrix.size - 8, 1);\n}\n// Make bit vector of format information. On success, store the result in \"bits\".\n// Encode error correction level and mask pattern. See 8.9 of\n// ISO/IEC 18004:2015(E)(p.55) for details.\nfunction makeFormatInfoBits(bits, ecLevel, mask) {\n const formatInfo = (ecLevel.bits << 3) | mask;\n bits.append(formatInfo, 5);\n const bchCode = calculateBCHCode(formatInfo, FORMAT_INFO_POLY);\n bits.append(bchCode, 10);\n const maskBits = new BitArray();\n maskBits.append(FORMAT_INFO_MASK, 15);\n bits.xor(maskBits);\n}\n// Embed format information. On success, modify the matrix.\nfunction embedFormatInfo(matrix, ecLevel, mask) {\n const formatInfoBits = new BitArray();\n makeFormatInfoBits(formatInfoBits, ecLevel, mask);\n const { size } = matrix;\n const { length } = formatInfoBits;\n for (let i = 0; i < length; i++) {\n // Type info bits at the left top corner.\n const [x, y] = FORMAT_INFO_COORDINATES[i];\n // Place bits in LSB to MSB order. LSB (least significant bit) is the last value in formatInfoBits.\n const bit = formatInfoBits.get(length - 1 - i);\n matrix.set(x, y, bit);\n if (i < 8) {\n // Right top corner.\n matrix.set(size - i - 1, 8, bit);\n } else {\n // Left bottom corner.\n matrix.set(8, size - 7 + (i - 8), bit);\n }\n }\n // Then, embed the dark dot at the left bottom corner.\n embedDarkModule(matrix);\n}\n// Make bit vector of version information. On success, store the result in \"bits\".\n// See 7.10 of ISO/IEC 18004:2015(E)(p.58) for details.\nfunction makeVersionInfoBits(bits, version) {\n bits.append(version, 6);\n const bchCode = calculateBCHCode(version, VERSION_INFO_POLY);\n bits.append(bchCode, 12);\n}\n// Embed version information if need be. On success, modify the matrix.\n// See 7.10 of ISO/IEC 18004:2015(E)(p.58) for how to embed version information.\nfunction embedVersionInfo(matrix, { version }) {\n if (version >= 7) {\n const versionInfoBits = new BitArray();\n makeVersionInfoBits(versionInfoBits, version);\n // It will decrease from 17 to 0.\n let bitIndex = 6 * 3 - 1;\n const { size } = matrix;\n for (let i = 0; i < 6; i++) {\n for (let j = 0; j < 3; j++) {\n // Place bits in LSB (least significant bit) to MSB order.\n const bit = versionInfoBits.get(bitIndex--);\n // Left bottom corner.\n matrix.set(i, size - 11 + j, bit);\n // Right bottom corner.\n matrix.set(size - 11 + j, i, bit);\n }\n }\n }\n}\n// Embed \"codewords\". On success, modify the matrix.\n// See 7.7.3 of ISO/IEC 18004:2015(E)(p.46) for how to embed codewords.\nfunction embedCodewords(matrix, codewords, mask) {\n let bitIndex = 0;\n const { size } = matrix;\n const { length } = codewords;\n // Start from the right bottom cell.\n for (let x = size - 1; x >= 1; x -= 2) {\n // Skip the vertical timing pattern.\n if (x === 6) {\n x = 5;\n }\n for (let y = 0; y < size; y++) {\n for (let i = 0; i < 2; i++) {\n const offsetX = x - i;\n const upward = ((x + 1) & 2) === 0;\n const offsetY = upward ? size - 1 - y : y;\n // Skip the cell if it's not empty.\n if (isEmpty(matrix, offsetX, offsetY)) {\n // Padding bit. If there is no bit left, we'll fill the left cells with 0.\n let bit = 0;\n if (bitIndex < length) {\n bit = codewords.get(bitIndex++);\n }\n // Is apply mask.\n if (isApplyMask(mask, offsetX, offsetY)) {\n bit ^= 1;\n }\n matrix.set(offsetX, offsetY, bit);\n }\n }\n }\n }\n}\n// Embed function patterns. On success, modify the matrix.\n// The function patterns are:\n// - Finder patterns and separators\n// - Alignment patterns, if version >= 2\n// - Timing patterns\nfunction embedFunctionPatterns(matrix, version) {\n // Let's get started with embedding big squares at corners.\n embedFinderPatternsAndSeparators(matrix);\n // Alignment patterns appear if version >= 2.\n embedAlignmentPatterns(matrix, version);\n // Timing patterns should be embedded after position adj. patterns.\n embedTimingPatterns(matrix);\n}\n// Embed encoding region. On success, modify the matrix.\n// The encoding region are:\n// - Format Info\n// - Version Info, if version >= 7\n// - Data with correction\nfunction embedEncodingRegion(matrix, codewords, version, ecLevel, mask) {\n // Type information appear with any version.\n embedFormatInfo(matrix, ecLevel, mask);\n // Version info appear if version >= 7.\n embedVersionInfo(matrix, version);\n // Data should be embedded at end.\n embedCodewords(matrix, codewords, mask);\n}\n// Build 2D matrix of QR Code from \"codewords\" with \"ecLevel\", \"version\" and \"getMaskPattern\". On\n// success, store the result in \"matrix\".\nfunction buildMatrix(codewords, version, ecLevel, mask) {\n const matrix = new ByteMatrix(version.size);\n // Clear matrix.\n matrix.clear(-1);\n // Embed function patterns.\n embedFunctionPatterns(matrix, version);\n // Embed encoding region.\n embedEncodingRegion(matrix, codewords, version, ecLevel, mask);\n return matrix;\n}\n\nexport { buildMatrix };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module BlockPair\n */\nclass BlockPair {\n #ecCodewords;\n #dataCodewords;\n constructor(dataCodewords, ecCodewords) {\n this.#ecCodewords = ecCodewords;\n this.#dataCodewords = dataCodewords;\n }\n get ecCodewords() {\n return this.#ecCodewords;\n }\n get dataCodewords() {\n return this.#dataCodewords;\n }\n}\n\nexport { BlockPair };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { Polynomial } from './Polynomial.js';\nimport { QR_CODE_FIELD_256 } from './GaloisField.js';\n\n/**\n * @module Encoder\n */\nfunction buildGenerator(field, generators, degree) {\n const { length } = generators;\n if (degree >= length) {\n const { generator } = field;\n let lastGenerator = generators[length - 1];\n for (let i = length; i <= degree; i++) {\n const coefficients = new Int32Array([1, field.exp(i - 1 + generator)]);\n const nextGenerator = lastGenerator.multiply(new Polynomial(field, coefficients));\n generators.push(nextGenerator);\n lastGenerator = nextGenerator;\n }\n }\n return generators[degree];\n}\nclass Encoder {\n #field;\n #generators;\n constructor(field = QR_CODE_FIELD_256) {\n this.#field = field;\n this.#generators = [new Polynomial(field, new Int32Array([1]))];\n }\n encode(received, ecLength) {\n const dataBytes = received.length - ecLength;\n const infoCoefficients = new Int32Array(dataBytes);\n const generator = buildGenerator(this.#field, this.#generators, ecLength);\n infoCoefficients.set(received.subarray(0, dataBytes));\n const base = new Polynomial(this.#field, infoCoefficients);\n const info = base.multiplyByMonomial(ecLength, 1);\n const [, remainder] = info.divide(generator);\n const { coefficients } = remainder;\n const numZeroCoefficients = ecLength - coefficients.length;\n const zeroCoefficientsOffset = dataBytes + numZeroCoefficients;\n received.fill(0, dataBytes, zeroCoefficientsOffset);\n received.set(coefficients, zeroCoefficientsOffset);\n }\n}\n\nexport { Encoder };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { Mode } from '../../common/Mode.js';\nimport { buildMatrix } from './matrix.js';\nimport { BitArray } from '../../common/BitArray.js';\nimport { BlockPair } from '../BlockPair.js';\nimport { VERSIONS } from '../../common/Version.js';\nimport { calculateMaskPenalty } from '../../common/mask.js';\nimport { Encoder } from '../../common/reedsolomon/Encoder.js';\n\n/**\n * @module encoder\n */\nfunction generateECCodewords(codewords, numECCodewords) {\n const numDataCodewords = codewords.length;\n const buffer = new Int32Array(numDataCodewords + numECCodewords);\n // Copy data codewords.\n buffer.set(codewords);\n // Reed solomon encode.\n new Encoder().encode(buffer, numECCodewords);\n // Get ec codewords.\n return new Uint8Array(buffer.subarray(numDataCodewords));\n}\nfunction injectECCodewords(bits, { ecBlocks, numECCodewordsPerBlock }) {\n // Step 1. Divide data bytes into blocks and generate error correction bytes for them. We'll\n // store the divided data bytes blocks and error correction bytes blocks into \"blocks\".\n let maxNumECCodewords = 0;\n let maxNumDataCodewords = 0;\n let dataCodewordsOffset = 0;\n // Block pair.\n const blocks = [];\n for (const { count, numDataCodewords } of ecBlocks) {\n for (let i = 0; i < count; i++) {\n const dataCodewords = new Uint8Array(numDataCodewords);\n bits.writeToUint8Array(dataCodewordsOffset * 8, dataCodewords, 0, numDataCodewords);\n const ecCodewords = generateECCodewords(dataCodewords, numECCodewordsPerBlock);\n blocks.push(new BlockPair(dataCodewords, ecCodewords));\n dataCodewordsOffset += numDataCodewords;\n maxNumECCodewords = Math.max(maxNumECCodewords, ecCodewords.length);\n maxNumDataCodewords = Math.max(maxNumDataCodewords, numDataCodewords);\n }\n }\n const codewords = new BitArray();\n // First, place data blocks.\n for (let i = 0; i < maxNumDataCodewords; i++) {\n for (const { dataCodewords } of blocks) {\n if (i < dataCodewords.length) {\n codewords.append(dataCodewords[i], 8);\n }\n }\n }\n // Then, place error correction blocks.\n for (let i = 0; i < maxNumECCodewords; i++) {\n for (const { ecCodewords } of blocks) {\n if (i < ecCodewords.length) {\n codewords.append(ecCodewords[i], 8);\n }\n }\n }\n return codewords;\n}\nfunction appendTerminator(bits, numDataCodewords) {\n const capacity = numDataCodewords * 8;\n // Append terminator if there is enough space (value is 0000).\n for (let i = 0; i < 4 && bits.length < capacity; i++) {\n bits.append(0);\n }\n // Append terminator. See 7.4.9 of ISO/IEC 18004:2015(E)(p.32) for details.\n // If the last byte isn't 8-bit aligned, we'll add padding bits.\n const numBitsInLastByte = bits.length & 0x07;\n if (numBitsInLastByte > 0) {\n for (let i = numBitsInLastByte; i < 8; i++) {\n bits.append(0);\n }\n }\n // If we have more space, we'll fill the space with padding patterns defined in 8.4.9 (p.24).\n const numPaddingCodewords = numDataCodewords - bits.byteLength;\n for (let i = 0; i < numPaddingCodewords; i++) {\n bits.append(i & 0x01 ? 0x11 : 0xec, 8);\n }\n}\nfunction isByteMode(segment) {\n return segment.mode === Mode.BYTE;\n}\nfunction isHanziMode(segment) {\n return segment.mode === Mode.HANZI;\n}\nfunction appendModeInfo(bits, mode) {\n bits.append(mode.bits, 4);\n}\nfunction appendECI(bits, segment, currentECIValue) {\n if (isByteMode(segment)) {\n const [value] = segment.charset.values;\n if (value !== currentECIValue) {\n bits.append(Mode.ECI.bits, 4);\n // See 7.4.2.2 of ISO/IEC 18004:2015(E)(p.24) for details.\n if (value <= 127) {\n bits.append(value, 8);\n } else if (value <= 16383) {\n bits.append(0x8000 | value, 16);\n } else {\n bits.append(0xc00000 | value, 24);\n }\n return value;\n }\n }\n return currentECIValue;\n}\nfunction appendFNC1Info(bits, fnc1) {\n const [mode, indicator] = fnc1;\n // Append FNC1 if applicable.\n switch (mode) {\n case 'GS1':\n // GS1 formatted codes are prefixed with a FNC1 in first position mode header.\n appendModeInfo(bits, Mode.FNC1_FIRST_POSITION);\n break;\n case 'AIM':\n // AIM formatted codes are prefixed with a FNC1 in first position mode header.\n appendModeInfo(bits, Mode.FNC1_SECOND_POSITION);\n // Append AIM application indicator.\n bits.append(indicator, 8);\n break;\n }\n}\nfunction getSegmentLength(segment, bits) {\n // Byte segment use byte Length.\n if (isByteMode(segment)) {\n return bits.byteLength;\n }\n // Other segments use the real length of characters.\n // All rest segments content codePointAt at 0x0000 to 0xffff, so use length directly.\n return segment.content.length;\n}\nfunction appendLengthInfo(bits, mode, version, numLetters) {\n bits.append(numLetters, mode.getCharacterCountBits(version));\n}\nfunction willFit(numInputBits, version, ecLevel) {\n // In the following comments, we use numbers of Version 7-H.\n const ecBlocks = version.getECBlocks(ecLevel);\n const numInputCodewords = Math.ceil(numInputBits / 8);\n return ecBlocks.numTotalDataCodewords >= numInputCodewords;\n}\nfunction chooseVersion(numInputBits, ecLevel) {\n for (const version of VERSIONS) {\n if (willFit(numInputBits, version, ecLevel)) {\n return version;\n }\n }\n throw new Error('data too big for all versions');\n}\nfunction calculateBitsNeeded(segmentBlocks, version) {\n let bitsNeeded = 0;\n for (const { mode, head, body } of segmentBlocks) {\n bitsNeeded += head.length + mode.getCharacterCountBits(version) + body.length;\n }\n return bitsNeeded;\n}\nfunction chooseRecommendVersion(segmentBlocks, ecLevel) {\n // Hard part: need to know version to know how many bits length takes. But need to know how many\n // bits it takes to know version. First we take a guess at version by assuming version will be\n // the minimum, 1:\n const provisionalBitsNeeded = calculateBitsNeeded(segmentBlocks, VERSIONS[0]);\n const provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);\n // Use that guess to calculate the right version. I am still not sure this works in 100% of cases.\n const bitsNeeded = calculateBitsNeeded(segmentBlocks, provisionalVersion);\n return chooseVersion(bitsNeeded, ecLevel);\n}\nfunction chooseBestMaskAndMatrix(codewords, version, ecLevel) {\n let bestMask = 0;\n let bestMatrix = buildMatrix(codewords, version, ecLevel, bestMask);\n let minPenalty = calculateMaskPenalty(bestMatrix);\n // We try all rest mask patterns to choose the best one.\n for (let mask = 1; mask < 8; mask++) {\n const matrix = buildMatrix(codewords, version, ecLevel, mask);\n const penalty = calculateMaskPenalty(matrix);\n // Lower penalty is better.\n if (penalty < minPenalty) {\n bestMask = mask;\n bestMatrix = matrix;\n minPenalty = penalty;\n }\n }\n return [bestMask, bestMatrix];\n}\n\nexport {\n appendECI,\n appendFNC1Info,\n appendLengthInfo,\n appendModeInfo,\n appendTerminator,\n calculateBitsNeeded,\n chooseBestMaskAndMatrix,\n chooseRecommendVersion,\n getSegmentLength,\n injectECCodewords,\n isByteMode,\n isHanziMode,\n willFit\n};\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module Dict\n * @see https://github.com/google/dart-gif-encoder\n */\n// The highest code that can be defined in the CodeBook.\nconst MAX_CODE = (1 << 12) - 1;\n/**\n * A dict contains codes defined during LZW compression. It's a mapping from a string\n * of pixels to the code that represents it. The codes are stored in a trie which is\n * represented as a map. Codes may be up to 12 bits. The size of the codebook is always\n * the minimum power of 2 needed to represent all the codes and automatically increases\n * as new codes are defined.\n */\nclass Dict {\n #bof;\n #eof;\n #bits;\n #depth;\n #size;\n #unused;\n #codes;\n constructor(depth) {\n const bof = 1 << depth;\n const eof = bof + 1;\n this.#bof = bof;\n this.#eof = eof;\n this.#depth = depth;\n this.reset();\n }\n get bof() {\n return this.#bof;\n }\n get eof() {\n return this.#eof;\n }\n get bits() {\n return this.#bits;\n }\n get depth() {\n return this.#depth;\n }\n reset() {\n const bits = this.#depth + 1;\n this.#bits = bits;\n this.#size = 1 << bits;\n this.#codes = new Map();\n this.#unused = this.#eof + 1;\n }\n add(code, index) {\n let unused = this.#unused;\n if (unused > MAX_CODE) {\n return false;\n }\n this.#codes.set((code << 8) | index, unused++);\n let bits = this.#bits;\n let size = this.#size;\n if (unused > size) {\n size = 1 << ++bits;\n }\n this.#bits = bits;\n this.#size = size;\n this.#unused = unused;\n return true;\n }\n get(code, index) {\n return this.#codes.get((code << 8) | index);\n }\n}\n\nexport { Dict };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module DictStream\n * @see https://github.com/google/dart-gif-encoder\n */\nclass DictStream {\n #bits = 0;\n #dict;\n #buffer = 0;\n #bytes = [];\n constructor(dict) {\n this.#dict = dict;\n }\n write(code) {\n let bits = this.#bits;\n let buffer = this.#buffer | (code << bits);\n bits += this.#dict.bits;\n const bytes = this.#bytes;\n while (bits >= 8) {\n bytes.push(buffer & 0xff);\n buffer >>= 8;\n bits -= 8;\n }\n this.#bits = bits;\n this.#buffer = buffer;\n }\n pipe(stream) {\n const bytes = this.#bytes;\n // Add the remaining bits. (Unused bits are set to zero.)\n if (this.#bits > 0) {\n bytes.push(this.#buffer);\n }\n stream.writeByte(this.#dict.depth);\n // Divide it up into blocks with a size in front of each block.\n const { length } = bytes;\n for (let i = 0; i < length; ) {\n const remain = length - i;\n if (remain >= 255) {\n stream.writeByte(0xff);\n stream.writeBytes(bytes, i, 255);\n i += 255;\n } else {\n stream.writeByte(remain);\n stream.writeBytes(bytes, i, remain);\n i = length;\n }\n }\n stream.writeByte(0);\n }\n}\n\nexport { DictStream };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { Dict } from './Dict.js';\nimport { DictStream } from './DictStream.js';\n\n/**\n * @module index\n * @see https://github.com/google/dart-gif-encoder\n */\nfunction compress(pixels, depth, stream) {\n const dict = new Dict(depth);\n const buffer = new DictStream(dict);\n buffer.write(dict.bof);\n if (pixels.length > 0) {\n let code = pixels[0];\n const { length } = pixels;\n for (let i = 1; i < length; i++) {\n const pixelIndex = pixels[i];\n const nextCode = dict.get(code, pixelIndex);\n if (nextCode != null) {\n code = nextCode;\n } else {\n buffer.write(code);\n // Reset dict when full.\n if (!dict.add(code, pixelIndex)) {\n buffer.write(dict.bof);\n dict.reset();\n }\n code = pixelIndex;\n }\n }\n buffer.write(code);\n }\n buffer.write(dict.eof);\n buffer.pipe(stream);\n}\n\nexport { compress };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\n/**\n * @module ByteStream\n */\nclass ByteStream {\n #bytes = [];\n get bytes() {\n return this.#bytes;\n }\n writeByte(value) {\n this.#bytes.push(value & 0xff);\n }\n writeInt16(value) {\n this.#bytes.push(value & 0xff, (value >> 8) & 0xff);\n }\n writeBytes(bytes, offset = 0, length = bytes.length) {\n const buffer = this.#bytes;\n for (let i = 0; i < length; i++) {\n buffer.push(bytes[offset + i] & 0xff);\n }\n }\n}\n\nexport { ByteStream };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { ByteStream } from './ByteStream.js';\n\n/**\n * @module Base64Stream\n */\nconst { fromCharCode } = String;\nfunction encode(byte) {\n byte &= 0x3f;\n if (byte >= 0) {\n if (byte < 26) {\n // A.\n return 0x41 + byte;\n } else if (byte < 52) {\n // a.\n return 0x61 + (byte - 26);\n } else if (byte < 62) {\n // 0.\n return 0x30 + (byte - 52);\n } else if (byte === 62) {\n // +.\n return 0x2b;\n } else if (byte === 63) {\n // /.\n return 0x2f;\n }\n }\n throw new Error(`illegal char: ${fromCharCode(byte)}`);\n}\nclass Base64Stream {\n #bits = 0;\n #buffer = 0;\n #length = 0;\n #stream = new ByteStream();\n get bytes() {\n return this.#stream.bytes;\n }\n write(byte) {\n let bits = this.#bits + 8;\n const stream = this.#stream;\n const buffer = (this.#buffer << 8) | (byte & 0xff);\n while (bits >= 6) {\n stream.writeByte(encode(buffer >>> (bits - 6)));\n bits -= 6;\n }\n this.#length++;\n this.#bits = bits;\n this.#buffer = buffer;\n }\n close() {\n const bits = this.#bits;\n const stream = this.#stream;\n if (bits > 0) {\n stream.writeByte(encode(this.#buffer << (6 - bits)));\n this.#bits = 0;\n this.#buffer = 0;\n }\n const length = this.#length;\n if (length % 3 != 0) {\n // Padding.\n const pad = 3 - (length % 3);\n for (let i = 0; i < pad; i++) {\n // =.\n stream.writeByte(0x3d);\n }\n }\n }\n}\n\nexport { Base64Stream, fromCharCode };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { compress } from './utils/lzw/index.js';\nimport { ByteStream } from './utils/ByteStream.js';\nimport { Base64Stream, fromCharCode } from './utils/Base64Stream.js';\n\n/**\n * @module GIFImage\n */\nclass GIFImage {\n #width;\n #height;\n #foreground;\n #background;\n #pixels = [];\n constructor(width, height, { foreground = [0x00, 0x00, 0x00], background = [0xff, 0xff, 0xff] } = {}) {\n this.#width = width;\n this.#height = height;\n this.#foreground = foreground;\n this.#background = background;\n }\n #encode() {\n const width = this.#width;\n const height = this.#height;\n const stream = new ByteStream();\n const background = this.#background;\n const foreground = this.#foreground;\n // GIF signature: GIF89a.\n stream.writeBytes([0x47, 0x49, 0x46, 0x38, 0x39, 0x61]);\n // Logical screen descriptor.\n stream.writeInt16(width);\n stream.writeInt16(height);\n stream.writeBytes([0x80, 0, 0]);\n // Global background color palette.\n stream.writeBytes([background[0], background[1], background[2]]);\n // Global foreground color palette.\n stream.writeBytes([foreground[0], foreground[1], foreground[2]]);\n // Image descriptor.\n stream.writeByte(0x2c);\n stream.writeInt16(0);\n stream.writeInt16(0);\n stream.writeInt16(width);\n stream.writeInt16(height);\n stream.writeByte(0);\n // Compress pixels to stream.\n compress(this.#pixels, 2, stream);\n // GIF terminator.\n stream.writeByte(0x3b);\n return stream.bytes;\n }\n set(x, y, color) {\n this.#pixels[y * this.#width + x] = color;\n }\n toDataURL() {\n const bytes = this.#encode();\n const stream = new Base64Stream();\n for (const byte of bytes) {\n stream.write(byte);\n }\n stream.close();\n const base64 = stream.bytes;\n let url = 'data:image/gif;base64,';\n for (const byte of base64) {\n url += fromCharCode(byte);\n }\n return url;\n }\n}\n\nexport { GIFImage };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { toInt32 } from '../common/utils.js';\nimport { GIFImage } from '../common/image/GIFImage.js';\n\n/**\n * @module Encoded\n */\nclass Encoded {\n #mask;\n #level;\n #version;\n #matrix;\n constructor(matrix, version, level, mask) {\n this.#mask = mask;\n this.#level = level;\n this.#matrix = matrix;\n this.#version = version;\n }\n /**\n * @property matrix\n * @description Get the size of qrcode.\n */\n get size() {\n return this.#matrix.size;\n }\n /**\n * @property mask\n * @description Get the mask of qrcode.\n */\n get mask() {\n return this.#mask;\n }\n /**\n * @property level\n * @description Get the error correction level of qrcode.\n */\n get level() {\n return this.#level.name;\n }\n /**\n * @property version\n * @description Get the version of qrcode.\n */\n get version() {\n return this.#version.version;\n }\n /**\n * @method get\n * @description Get the bit value of the specified coordinate of qrcode.\n */\n get(x, y) {\n const { size } = this.#matrix;\n if (x < 0 || y < 0 || x >= size || y >= size) {\n throw new Error(`illegal coordinate: [${x}, ${y}]`);\n }\n return this.#matrix.get(x, y);\n }\n /**\n * @method toDataURL\n * @param moduleSize The size of one qrcode module\n * @param options Set rest options of gif, like margin, foreground and background.\n */\n toDataURL(moduleSize = 2, { margin = moduleSize * 4, ...colors } = {}) {\n moduleSize = Math.max(1, moduleSize >> 0);\n margin = Math.max(0, margin >> 0);\n const matrix = this.#matrix;\n const matrixSize = matrix.size;\n const size = moduleSize * matrixSize + margin * 2;\n const gif = new GIFImage(size, size, colors);\n const max = size - margin;\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n if (x >= margin && x < max && y >= margin && y < max) {\n const offsetX = toInt32((x - margin) / moduleSize);\n const offsetY = toInt32((y - margin) / moduleSize);\n gif.set(x, y, matrix.get(offsetX, offsetY));\n } else {\n // Margin pixels.\n gif.set(x, y, 0);\n }\n }\n }\n return gif.toDataURL();\n }\n}\n\nexport { Encoded };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { Charset } from '../../common/Charset.js';\n\n/**\n * @module asserts\n */\nfunction assertContent(content) {\n if (content === '') {\n throw new Error('segment content should be at least 1 character');\n }\n}\nfunction assertCharset(charset) {\n if (!(charset instanceof Charset)) {\n throw new Error('illegal charset');\n }\n}\nfunction assertHints(hints) {\n const { fnc1 } = hints;\n // FNC1.\n if (fnc1 != null) {\n const [mode] = fnc1;\n if (mode !== 'GS1' && mode !== 'AIM') {\n throw new Error('illegal fn1 hint');\n }\n if (mode === 'AIM') {\n const [, indicator] = fnc1;\n if (indicator < 0 || indicator > 0xff || !Number.isInteger(indicator)) {\n throw new Error('illegal fn1 application indicator');\n }\n }\n }\n}\nfunction assertLevel(level) {\n if (['L', 'M', 'Q', 'H'].indexOf(level) < 0) {\n throw new Error('illegal error correction level');\n }\n}\nfunction assertVersion(version) {\n if (version !== 'Auto') {\n if (version < 1 || version > 40 || !Number.isInteger(version)) {\n throw new Error('illegal version');\n }\n }\n}\n\nexport { assertCharset, assertContent, assertHints, assertLevel, assertVersion };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport {\n getSegmentLength,\n appendECI,\n appendFNC1Info,\n appendModeInfo,\n isHanziMode,\n chooseRecommendVersion,\n calculateBitsNeeded,\n willFit,\n appendLengthInfo,\n appendTerminator,\n injectECCodewords,\n chooseBestMaskAndMatrix\n} from './utils/encoder.js';\nimport { Encoded } from './Encoded.js';\nimport { Charset } from '../common/Charset.js';\nimport { ECLevel } from '../common/ECLevel.js';\nimport { BitArray } from '../common/BitArray.js';\nimport { VERSIONS } from '../common/Version.js';\nimport { encode } from '../common/encoding/index.js';\nimport { assertHints, assertLevel, assertVersion } from './utils/asserts.js';\n\n/**\n * @module Encoder\n */\nclass Encoder {\n #hints;\n #level;\n #encode;\n #version;\n /**\n * @constructor\n * @param options The options of encoder.\n */\n constructor({ hints = {}, level = 'L', version = 'Auto', encode: encode$1 = encode } = {}) {\n assertHints(hints);\n assertLevel(level);\n assertVersion(version);\n this.#hints = hints;\n this.#encode = encode$1;\n this.#version = version;\n this.#level = ECLevel[level];\n }\n /**\n * @method encode\n * @description Encode the segments.\n * @param segments The segments.\n */\n encode(...segments) {\n const ecLevel = this.#level;\n const encode = this.#encode;\n const { fnc1 } = this.#hints;\n const versionNumber = this.#version;\n const segmentBlocks = [];\n // Only append FNC1 once.\n let isFNC1Appended = false;\n // Current ECI value.\n let [currentECIValue] = Charset.ISO_8859_1.values;\n // Init segments.\n for (const segment of segments) {\n const { mode } = segment;\n const head = new BitArray();\n const body = segment.encode(encode);\n const length = getSegmentLength(segment, body);\n // Append ECI segment if applicable.\n currentECIValue = appendECI(head, segment, currentECIValue);\n // Append FNC1 if applicable.\n if (fnc1 != null && !isFNC1Appended) {\n isFNC1Appended = true;\n appendFNC1Info(head, fnc1);\n }\n // With ECI in place, Write the mode marker.\n appendModeInfo(head, mode);\n // If is Hanzi mode append GB2312 subset.\n if (isHanziMode(segment)) {\n head.append(1, 4);\n }\n // Push segment block.\n segmentBlocks.push({ mode, head, body, length });\n }\n let version;\n if (versionNumber === 'Auto') {\n version = chooseRecommendVersion(segmentBlocks, ecLevel);\n } else {\n version = VERSIONS[versionNumber - 1];\n const bitsNeeded = calculateBitsNeeded(segmentBlocks, version);\n if (!willFit(bitsNeeded, version, ecLevel)) {\n throw new Error('data too big for requested version');\n }\n }\n const buffer = new BitArray();\n for (const { mode, head, body, length } of segmentBlocks) {\n buffer.append(head);\n appendLengthInfo(buffer, mode, version, length);\n buffer.append(body);\n }\n const ecBlocks = version.getECBlocks(ecLevel);\n appendTerminator(buffer, ecBlocks.numTotalDataCodewords);\n const codewords = injectECCodewords(buffer, ecBlocks);\n const [mask, matrix] = chooseBestMaskAndMatrix(codewords, version, ecLevel);\n return new Encoded(matrix, version, ecLevel, mask);\n }\n}\n\nexport { Encoder };\n","/**\n * @module QRCode\n * @package @nuintun/qrcode\n * @license MIT\n * @version 5.0.2\n * @author nuintun <nuintun@qq.com>\n * @description A pure JavaScript QRCode encode and decode library.\n * @see https://github.com/nuintun/qrcode#readme\n */\n\nimport { Mode } from '../../common/Mode.js';\nimport { Charset } from '../../common/Charset.js';\nimport { BitArray } from '../../common/BitArray.js';\nimport { assertContent, assertCharset } from '../utils/asserts.js';\n\n/**\n * @module Byte\n */\nclass Byte {\n #content;\n #charset;\n /**\n * @constructor\n * @param content The content to encode.\n * @param charset The charset of the content.\n */\n constructor(content, charset = Charset.ISO_8859_1) {\n assertContent(content);\n assertCharset(charset);\n this.#content = content;\n this.#charset = charset;\n }\n /**\n * @property mode\n * @description The mode of the segment.\n */\n get mode() {\n return Mode.BYTE;\n }\n /**\n * @property content\n * @description The content of the segment.\n */\n get content() {\n return this.#content;\n }\n /**\n * @property charset\n * @description The charset of the content.\n */\n get charset() {\n return this.#charset;\n }\n /**\n * @method encode\n * @description Encode the segment.\n * @param encode The text encode function.\n */\n encode(encode) {\n const bits = new BitArray();\n const bytes = encode(this.#content, this.#charset);\n for (const byte of bytes) {\n bits.append(byte, 8);\n }\n return bits;\n }\n}\n\nexport { Byte };\n","import { sendHttpRequest } from \"../../utils/utils\";\n\n// 文件上传流水号SDK\nconst uploadNumberSDK = {\n number: '',\n isWorking: false,\n close: async function (params?: {\n onOk?: () => void;\n onError?: () => void;\n }) {\n const { onOk, onError } = params ?? {};\n const { number } = this;\n if (number) {\n const result = await sendHttpRequest({\n url: `/resource/update_id/${number}`,\n method: 'delete',\n });\n if (result.success) {\n this.number = '';\n onOk?.();\n } else {\n onError?.();\n }\n }\n }\n}\n\nexport default uploadNumberSDK;",".mobile-upload {\n display: flex;\n justify-content: flex-end;\n margin-bottom: 4px;\n}\n\n.btn {\n position: relative;\n padding: 4px 8px;\n border-radius: 4px;\n cursor: pointer;\n overflow: hidden;\n display: flex;\n justify-content: center;\n align-items: center;\n white-space: nowrap;\n}\n\n.btn::after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n.btn:hover::after {\n background-color: rgba(0,0,0,0.04);\n}\n\n.btn-link {\n color: #0D75FB;\n}\n\n.btn-default {\n background-color: #ffffff;\n color: #0D75FB;\n border: 1px solid #0D75FB;\n}\n\n.btn-primary {\n background-color: #0D75FB;\n color: #ffffff;\n}\n\n\n.loading {\n font-size: 12px;\n color: #999999;\n}\n\n.mask {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0,0,0,0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 10000;\n}\n\n.mask .upload-wrapper {\n width: 540px;\n max-width: 80%;\n max-height: 80%;\n background-color: #ffffff;\n padding: 32px 24px;\n border-radius: 16px;\n overflow-y: auto;\n}\n\n.mask .upload-wrapper .upload-box {\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.time-expire {\n margin: 8px 0;\n text-align: center;\n font-size: 12px;\n color: #555555;\n}\n\n.time-count-down {\n margin-left: 8px;\n color: #0D75FB;\n}\n\n.alert-tip {\n margin-top: 8px;\n text-align: center;\n font-size: 12px;\n color: #999999;\n}\n\n.qrcode-wrapper {\n width: 160px;\n height: 160px;\n display: flex;\n justify-content: center;\n align-items: center;\n border: 1px solid #e5e5e5;\n border-radius: 4px;\n padding: 1px;\n}\n\n.qrcode-wrapper .qrcode {\n width: 100%;\n height: 100%;\n}\n\n.modal-footer {\n margin-top: 32px;\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 8px;\n}\n\n.modal-footer .btn {\n min-width: 100px;\n}\n\n.qrcode-textarea {\n width: calc(100% - 16px);\n min-height: 120px;\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}",":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, State, Event, h, EventEmitter } from \"@stencil/core\";\nimport { Byte, Encoder } from '@nuintun/qrcode'\nimport { isMobile, sendHttpRequest, PCM_DOMAIN } from \"../../utils/utils\";\nimport { Message } from \"../../services/message.service\";\nimport uploadNumberSDK from \"./uploadNumberSDK\";\n\n@Component({\n tag: 'pcm-mobile-input-btn',\n styleUrls: ['pcm-mobile-input-btn.css', '../../global/global.css'],\n shadow: true,\n})\nexport class MobileUploadBtn {\n // 标题\n @Prop() name: string = '';\n /**\n * 最大文件数\n */\n @Prop() rows: number = 8;\n /**\n * 最大文件大小\n */\n @Prop() maxLength: number = undefined;\n /**\n * 填写请求头\n */\n @Prop() uploadHeaders?: Record<string, any>;\n /**\n * 填写请求参数\n */\n @Prop() uploadParams?: Record<string, any>;\n\n @State() QR_CODE_VALID_TIME: number = 0;\n @State() open: boolean = false;\n @State() mobileUrl: string = '';\n @State() setStartMobileUpload: boolean = false;\n @State() startMobileUploadLoading: boolean = false;\n @State() qrcodeStatus: 'active' | 'expired' | 'loading' | undefined = 'loading';\n @State() value: string = '';\n\n @Event() ok: EventEmitter<string>;\n\n private setStartMobileUploadWrapper = (e: boolean) => {\n uploadNumberSDK.isWorking = e;\n this.setStartMobileUpload = e;\n }\n\n @State() qrcodeUrl: string = '';\n private setMobileUrlWrapper = (e: string) => {\n this.mobileUrl = e;\n if (e) {\n const encoder = new Encoder();\n const qrcode = encoder.encode(new Byte(e));\n this.qrcodeUrl = qrcode.toDataURL();\n } else {\n this.qrcodeUrl = '';\n }\n }\n\n // 轮询流水号数据\n private pollingQueryNumberInfo = async (num: any) => {\n const res = await sendHttpRequest({\n url: `/sdk/v1/update_id/${num}/status`,\n method: 'get',\n });\n if (res?.success) {\n const resData: {\n update_id?: any;\n tags?: any;\n status?: any;\n file_list?: any;\n user_id?: any;\n cfg?: any;\n iat?: any;\n exp?: any;\n custom_data?: any;\n } = res.data ?? {};\n const { custom_data } = resData;\n this.value = custom_data ?? '';\n }\n if (uploadNumberSDK.isWorking) {\n setTimeout(() => {\n this.pollingQueryNumberInfo(num);\n }, 3000);\n }\n }\n\n private handleStartMobileUpload = async () => {\n const that = this;\n this.qrcodeStatus = 'loading';\n this.startMobileUploadLoading = true;\n const params = this.uploadParams ?? {};\n const reqData: {\n cfg?: Record<string, any>;\n } = {\n cfg: {\n fromUserName: '',\n fromUserId: '',\n upload: that.uploadParams,\n name: that.name,\n rows: that.rows,\n maxLength: that.maxLength,\n params,\n },\n }\n const res = await sendHttpRequest({\n url: `/sdk/v1/update_id`,\n method: 'post',\n data: reqData,\n });\n if (res?.success) {\n const resData: {\n update_id?: any;\n tags?: any;\n status?: any;\n file_list?: any;\n user_id?: any;\n cfg?: any;\n iat?: any;\n exp?: any;\n now?: any;\n } = res.data ?? {};\n uploadNumberSDK.number = resData.update_id;\n this.QR_CODE_VALID_TIME = Number(resData.exp) - Number(resData.now);\n const theMobileUrl = `${PCM_DOMAIN}/agents/inputByCode?num=${uploadNumberSDK.number}`;\n this.setMobileUrlWrapper(theMobileUrl)\n this.setStartMobileUploadWrapper(true);\n this.qrcodeStatus = 'active';\n // 开启轮询\n this.pollingQueryNumberInfo(uploadNumberSDK.number);\n }\n this.startMobileUploadLoading = false;\n }\n\n // 取消手机填写\n @State() cancelLoading = false;\n private cancelMobileUpload = async () => {\n this.cancelLoading = true;\n await uploadNumberSDK.close({\n onError() {\n Message.info('取消失败');\n }\n })\n this.cancelLoading = false;\n this.QR_CODE_VALID_TIME = 0;\n this.setStartMobileUploadWrapper(false);\n this.setMobileUrlWrapper('');\n this.qrcodeStatus = 'expired';\n this.value = '';\n this.open = false;\n }\n\n\n render() {\n const mobile = isMobile();\n if (mobile) {\n return null\n } else {\n return (\n <div>\n <div class=\"mobile-upload\">\n <div\n class=\"btn btn-link\"\n onClick={() => {\n this.open = true;\n this.handleStartMobileUpload();\n }}\n >扫码填写</div>\n </div>\n {\n this.open && <div class=\"mask\">\n <div class=\"upload-wrapper\">\n {\n this.setStartMobileUpload ? <div class=\"upload-box\">\n <div class=\"qrcode-wrapper\">\n {\n this.qrcodeStatus === 'active' && <img class=\"qrcode\" src={this.qrcodeUrl} />\n }\n {\n this.qrcodeStatus === 'loading' && <span class=\"loading\">加载中...</span>\n }\n {\n this.qrcodeStatus === 'expired' && <div\n class=\"btn btn-link\"\n onClick={this.handleStartMobileUpload}\n >重新获取</div>\n }\n </div>\n <div class=\"time-expire\">\n 二维码有效期\n <span class=\"time-count-down\">\n {\n !!this.QR_CODE_VALID_TIME && <pcm-time-count-down\n time={this.QR_CODE_VALID_TIME}\n onFinished={() => {\n this.qrcodeStatus = 'expired';\n }}\n />\n }\n </span>\n </div>\n <div class=\"alert-tip\">\n 填写过程中请不要关闭此弹窗\n </div>\n {\n this.qrcodeStatus === 'active' && <div\n style={{ marginTop: '12px', fontSize: '12px' }}\n class=\"btn btn-link\"\n onClick={() => {\n navigator.clipboard\n .writeText(this.mobileUrl)\n .then(() => {\n Message.success(\"已复制到剪贴板\");\n })\n .catch(() => {\n Message.error(\"复制失败\");\n });\n }}\n >复制二维码地址</div>\n }\n </div> : (this.startMobileUploadLoading && <span class=\"loading\">加载中...</span>)\n }\n {/* 填写文件列表 */}\n <div style={{ marginTop: '12px' }}>\n {\n !!this.value?.length && <textarea\n readOnly\n class=\"qrcode-textarea\"\n value={this.value}\n onChange={(e: any) => {\n this.value = e.target.value;\n }}\n />\n }\n </div>\n <div class=\"modal-footer\">\n <div class=\"btn btn-default\" onClick={this.cancelMobileUpload}>取消</div>\n <div class=\"btn btn-primary\" onClick={() => {\n if (!this.value) {\n Message.info(`请输入内容`);\n return;\n }\n if (this.value.length > this.maxLength) {\n Message.info(`输入内容不能超过${this.maxLength}个字符`);\n return;\n }\n this.ok.emit(this.value);\n this.cancelMobileUpload();\n }}>完成</div>\n </div>\n </div>\n </div>\n }\n </div>\n )\n }\n }\n}","import { sendHttpRequest } from \"../../utils/utils\";\n\n// 文件上传流水号SDK\nconst uploadNumberSDK = {\n number: '',\n isWorking: false,\n close: async function (params?: {\n onOk?: () => void;\n onError?: () => void;\n }) {\n const { onOk, onError } = params ?? {};\n const { number } = this;\n if (number) {\n const result = await sendHttpRequest({\n url: `/resource/update_id/${number}`,\n method: 'delete',\n });\n if (result.success) {\n this.number = '';\n onOk?.();\n } else {\n onError?.();\n }\n }\n }\n}\n\nexport default uploadNumberSDK;",".mobile-upload {\n display: flex;\n justify-content: flex-end;\n margin-bottom: 4px;\n}\n\n.btn {\n position: relative;\n padding: 4px 8px;\n border-radius: 4px;\n cursor: pointer;\n overflow: hidden;\n display: flex;\n justify-content: center;\n align-items: center;\n white-space: nowrap;\n}\n\n.btn::after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n.btn:hover::after {\n background-color: rgba(0,0,0,0.04);\n}\n\n.btn-link {\n color: #0D75FB;\n}\n\n.btn-default {\n background-color: #ffffff;\n color: #0D75FB;\n border: 1px solid #0D75FB;\n}\n\n.btn-primary {\n background-color: #0D75FB;\n color: #ffffff;\n}\n\n\n.loading {\n font-size: 12px;\n color: #999999;\n}\n\n.mask {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0,0,0,0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 10000;\n}\n\n.mask .upload-wrapper {\n width: 540px;\n max-width: 80%;\n max-height: 80%;\n background-color: #ffffff;\n padding: 32px 24px;\n border-radius: 16px;\n overflow-y: auto;\n}\n\n.mask .upload-wrapper .upload-box {\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.time-expire {\n margin: 8px 0;\n text-align: center;\n font-size: 12px;\n color: #555555;\n}\n\n.time-count-down {\n margin-left: 8px;\n color: #0D75FB;\n}\n\n.alert-tip {\n margin-top: 8px;\n text-align: center;\n font-size: 12px;\n color: #999999;\n}\n\n.qrcode-wrapper {\n width: 160px;\n height: 160px;\n display: flex;\n justify-content: center;\n align-items: center;\n border: 1px solid #e5e5e5;\n border-radius: 4px;\n padding: 1px;\n}\n\n.qrcode-wrapper .qrcode {\n width: 100%;\n height: 100%;\n}\n\n.modal-footer {\n margin-top: 32px;\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 8px;\n}\n\n.modal-footer .btn {\n min-width: 100px;\n}",":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, State, Event, h, EventEmitter } from \"@stencil/core\";\nimport { isMobile, sendHttpRequest, PCM_DOMAIN } from \"../../utils/utils\";\nimport uploadNumberSDK from \"./uploadNumberSDK\";\nimport { Message } from \"../../services/message.service\";\nimport { Byte, Encoder } from '@nuintun/qrcode'\n\n@Component({\n tag: 'pcm-mobile-upload-btn',\n styleUrls: ['pcm-mobile-upload-btn.css', '../../global/global.css'],\n shadow: true,\n})\nexport class MobileUploadBtn {\n /**\n * 是否支持多文件上传\n */\n @Prop() multiple: boolean = false;\n /**\n * 支持的文件后缀列表(需要带上小数点.)\n */\n @Prop() acceptFileSuffixList: string[] = [];\n /**\n * 最大文件数\n */\n @Prop() maxFileCount: number = Infinity;\n /**\n * 最大文件大小\n */\n @Prop() maxFileSize: number = Infinity;\n /**\n * 上传请求头\n */\n @Prop() uploadHeaders?: Record<string, any>;\n /**\n * 上传请求参数\n */\n @Prop() uploadParams?: Record<string, any>;\n @State() QR_CODE_VALID_TIME: number = 0;\n @State() open: boolean = false;\n @State() mobileUrl: string = '';\n @State() setStartMobileUpload: boolean = false;\n @State() startMobileUploadLoading: boolean = false;\n @State() qrcodeStatus: 'active' | 'expired' | 'loading' | undefined = 'loading';\n @State() value: any[] = [];\n\n @Event() ok: EventEmitter<any[]>;\n\n private setStartMobileUploadWrapper = (e: boolean) => {\n uploadNumberSDK.isWorking = e;\n this.setStartMobileUpload = e;\n }\n\n @State() qrcodeUrl: string = '';\n private setMobileUrlWrapper = (e: string) => {\n this.mobileUrl = e;\n if (e) {\n const encoder = new Encoder();\n const qrcode = encoder.encode(new Byte(e));\n this.qrcodeUrl = qrcode.toDataURL();\n } else {\n this.qrcodeUrl = '';\n }\n }\n\n // 轮询流水号数据\n private pollingQueryNumberInfo = async (num: any) => {\n const res = await sendHttpRequest({\n url: `/sdk/v1/update_id/${num}/status`,\n method: 'get',\n });\n if (res?.success) {\n const resData: {\n update_id?: any;\n tags?: any;\n status?: any;\n file_list?: any;\n user_id?: any;\n cfg?: any;\n iat?: any;\n exp?: any;\n } = res.data ?? {};\n const { file_list } = resData;\n this.value = file_list ?? [];\n }\n if (uploadNumberSDK.isWorking) {\n setTimeout(() => {\n this.pollingQueryNumberInfo(num);\n }, 3000);\n }\n }\n\n private handleStartMobileUpload = async () => {\n const that = this;\n this.qrcodeStatus = 'loading';\n this.startMobileUploadLoading = true;\n const params = this.uploadParams ?? {};\n const reqData: {\n tags?: string[];\n cfg?: Record<string, any>;\n is_knowledge_doc?: boolean,\n } = {\n is_knowledge_doc: false,\n tags: params.tags,\n cfg: {\n maxSize: that.maxFileSize,\n maxCount: that.multiple ? that.maxFileCount : 1,\n fromUserName: '',\n fromUserId: '',\n customAccept: that.acceptFileSuffixList.join(','),\n upload: that.uploadParams,\n },\n }\n const res = await sendHttpRequest({\n url: `/sdk/v1/update_id`,\n method: 'post',\n data: reqData,\n });\n if (res?.success) {\n const resData: {\n update_id?: any;\n tags?: any;\n status?: any;\n file_list?: any;\n user_id?: any;\n cfg?: any;\n iat?: any;\n exp?: any;\n now?: any;\n custom_data?: any;\n } = res.data ?? {};\n uploadNumberSDK.number = resData.update_id;\n this.QR_CODE_VALID_TIME = Number(resData.exp) - Number(resData.now);\n const theMobileUrl = `${PCM_DOMAIN}/agents/uploadFileByCode?num=${uploadNumberSDK.number}`;\n this.setMobileUrlWrapper(theMobileUrl)\n this.setStartMobileUploadWrapper(true);\n this.qrcodeStatus = 'active';\n // 开启轮询\n this.pollingQueryNumberInfo(uploadNumberSDK.number);\n }\n this.startMobileUploadLoading = false;\n }\n\n // 取消手机上传\n @State() cancelLoading = false;\n private cancelMobileUpload = async () => {\n this.cancelLoading = true;\n await uploadNumberSDK.close({\n onError() {\n Message.info('取消失败');\n }\n })\n this.cancelLoading = false;\n this.QR_CODE_VALID_TIME = 0;\n this.setStartMobileUploadWrapper(false);\n this.setMobileUrlWrapper('');\n this.qrcodeStatus = 'expired';\n this.value = [];\n this.open = false;\n }\n\n // 删除文件\n private handleDelete = async (cos_key: any) => {\n const res = await sendHttpRequest({\n url: `/sdk/v1/update_id/${uploadNumberSDK.number}/file`,\n method: 'delete',\n params: {\n update_id: uploadNumberSDK.number,\n cos_key,\n }\n });\n if (res?.success) {\n this.value = this.value.filter(it => it.cos_key !== cos_key);\n }\n }\n\n\n render() {\n const mobile = isMobile();\n if (mobile) {\n return null\n } else {\n return (\n <div>\n <div class=\"mobile-upload\">\n <div\n class=\"btn btn-link\"\n onClick={() => {\n if (this.maxFileCount < 1) {\n Message.info('文件数量已达到上限!');\n return;\n }\n this.open = true;\n this.handleStartMobileUpload();\n }}\n >扫码上传</div>\n </div>\n {\n this.open && <div class=\"mask\">\n <div class=\"upload-wrapper\">\n {\n this.setStartMobileUpload ? <div class=\"upload-box\">\n <div class=\"qrcode-wrapper\">\n {\n this.qrcodeStatus === 'active' && <img class=\"qrcode\" src={this.qrcodeUrl} />\n }\n {\n this.qrcodeStatus === 'loading' && <span class=\"loading\">加载中...</span>\n }\n {\n this.qrcodeStatus === 'expired' && <div\n class=\"btn btn-link\"\n onClick={this.handleStartMobileUpload}\n >重新获取</div>\n }\n </div>\n <div class=\"time-expire\">\n 二维码有效期\n <span class=\"time-count-down\">\n {\n !!this.QR_CODE_VALID_TIME && <pcm-time-count-down\n time={this.QR_CODE_VALID_TIME}\n onFinished={() => {\n this.qrcodeStatus = 'expired';\n }}\n />\n }\n </span>\n </div>\n <div class=\"alert-tip\">\n 上传过程中请不要关闭此弹窗\n </div>\n {\n this.qrcodeStatus === 'active' && <div\n style={{ marginTop: '12px', fontSize: '12px' }}\n class=\"btn btn-link\"\n onClick={() => {\n navigator.clipboard\n .writeText(this.mobileUrl)\n .then(() => {\n Message.success(\"已复制到剪贴板\");\n })\n .catch(() => {\n Message.error(\"复制失败\");\n });\n }}\n >复制二维码地址</div>\n }\n </div> : (this.startMobileUploadLoading && <span class=\"loading\">加载中...</span>)\n }\n {/* 上传文件列表 */}\n <div style={{ marginTop: '12px' }}>\n {\n this.value?.map?.((item, index) => {\n return <div class=\"file-item\" key={index}>\n <div class=\"file-item-content\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">{item?.file_name}</span>\n </div>\n <button class=\"remove-file\" onClick={(e) => {\n e.stopPropagation();\n this.handleDelete(item.cos_key)\n }}>×</button>\n </div>\n })\n }\n </div>\n <div class=\"modal-footer\">\n <div class=\"btn btn-default\" onClick={this.cancelMobileUpload}>取消</div>\n <div class=\"btn btn-primary\" onClick={() => {\n if (this.value.length > this.maxFileCount) {\n Message.info(`最多只能选择${this.maxFileCount}个文件,请删除多余文件!`);\n return;\n }\n this.ok.emit(this.value);\n this.cancelMobileUpload();\n }}>完成</div>\n </div>\n </div>\n </div>\n }\n </div>\n )\n }\n }\n}",null,":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { uploadFileToBackend, FileUploadResponse, verifyApiKey } from '../../utils/utils';\nimport { ConversationStartEventData, ErrorEventDetail, InterviewCompleteEventData, StreamCompleteEventData } from '../../components';\nimport { ErrorEventBus } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store';\nimport { configStore } from '../../../store/config.store';\nimport { SentryReporter } from '../../utils/sentry-reporter';\n\n/**\n * 面试报告\n */\n\n@Component({\n tag: 'pcm-msbg-modal',\n styleUrls: ['pcm-msbg-modal.css', '../../global/global.css'],\n shadow: true,\n})\nexport class MsbgModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '面试报告';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请开始分析';\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n /**\n * 自定义输入参数,传入customInputs.job_info时,会隐藏JD输入区域<br>\n * 传入customInputs.file_urls时,会隐藏简历上传区域。<br>\n * 传入customInputs.file_urls和customInputs.job_info时,会直接开始聊天。<br>\n */\n @Prop() customInputs: Record<string, string>= {};\n\n /**\n * 是否显示工作区历史会话按钮\n */\n @Prop() showWorkspaceHistory: boolean = false;\n\n /**\n * 上传成功事件\n */\n @Event() uploadSuccess: EventEmitter<FileUploadResponse>;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() interviewComplete: EventEmitter<InterviewCompleteEventData>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 附件预览模式\n * 'drawer': 在右侧抽屉中预览\n * 'window': 在新窗口中打开\n */\n @Prop() filePreviewMode: 'drawer' | 'window' = 'window';\n\n @State() selectedFile: File | null = null;\n @State() isUploading: boolean = false;\n @State() uploadedFileInfo: FileUploadResponse | null = null;\n @State() showChatModal: boolean = false;\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n @State() jobDescription: string = '';\n @State() isSubmitting: boolean = false;\n\n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n\n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.clearSelectedFile();\n this.showChatModal = false;\n this.jobDescription = '';\n } else {\n if (this.customInputs && this.customInputs.job_info) {\n this.jobDescription = this.customInputs.job_info;\n }\n\n await verifyApiKey(this.token);\n\n // 如果有会话ID或者同时有file_urls和job_info,直接显示聊天模态框\n if (this.conversationId || (this.customInputs?.file_urls && this.customInputs?.job_info)) {\n this.showChatModal = true;\n }\n }\n }\n\n\n componentWillLoad() {\n \n \n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n if (this.token) {\n authStore.setToken(this.token);\n }\n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n private handleFileChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length > 0) {\n this.selectedFile = input.files[0];\n }\n };\n\n private handleUploadClick = () => {\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n fileInput?.click();\n };\n\n private clearSelectedFile = () => {\n this.selectedFile = null;\n this.uploadedFileInfo = null;\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n if (fileInput) {\n fileInput.value = '';\n }\n };\n\n private async uploadFile() {\n if (!this.selectedFile) return;\n\n this.isUploading = true;\n\n try {\n // 使用 uploadFileToBackend 工具函数上传文件\n const result = await uploadFileToBackend(this.selectedFile, {\n }, {\n 'tags': ['other']\n });\n\n this.uploadedFileInfo = result;\n this.uploadSuccess.emit(result);\n } catch (error) {\n console.error('文件上传错误:', error);\n this.clearSelectedFile();\n SentryReporter.captureError(error, {\n action: 'uploadFile',\n component: 'pcm-msbg-modal',\n title: '文件上传失败'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '文件上传失败,请重试'\n });\n } finally {\n this.isUploading = false;\n }\n }\n\n private handleJobDescriptionChange = (event: Event) => {\n const textarea = event.target as HTMLTextAreaElement;\n this.jobDescription = textarea.value;\n };\n\n private handleStartInterview = async () => {\n if (!this.selectedFile) {\n alert('请上传面试内容');\n return;\n }\n\n // 如果没有预设的job_info,则需要检查用户输入\n if (!this.customInputs?.job_info && !this.jobDescription.trim()) {\n alert('请输入职位描述');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n // 如果还没上传,先上传文件\n if (!this.uploadedFileInfo) {\n await this.uploadFile();\n if (!this.uploadedFileInfo) {\n this.isSubmitting = false;\n return; // 上传失败\n }\n }\n\n // 直接显示聊天模态框\n this.showChatModal = true;\n } catch (error) {\n console.error('开始面试时出错:', error);\n SentryReporter.captureError(error, {\n action: 'handleStartInterview',\n component: 'pcm-msbg-modal',\n title: '开始面试时出错'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '开始面试时出错,请重试'\n });\n } finally {\n this.isSubmitting = false;\n }\n };\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n // 确保当 customInputs.job_info 存在时,hideJdInput 为 true\n const hideJdInput = Boolean(this.customInputs && this.customInputs.job_info);\n \n // 判断是否隐藏面试内容上传区域\n const hideFileUpload = Boolean(this.customInputs && this.customInputs.file_urls);\n \n // 判断是否同时提供了file_urls和job_info\n const hasFileAndJob = Boolean(this.customInputs?.file_urls && this.customInputs?.job_info);\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n {/* 上传界面 - 仅在不显示聊天模态框且没有会话ID且没有同时提供file_urls和job_info时显示 */}\n {!this.showChatModal && !this.conversationId && !hasFileAndJob && (\n <div class=\"input-container\">\n {/* JD输入区域 - 仅在没有parsedCustomInputs.job_info时显示 */}\n {!hideJdInput && (\n <div class=\"jd-input-section\">\n <label htmlFor=\"job-description\">请输入职位描述 (JD)</label>\n <textarea\n id=\"job-description\"\n class=\"job-description-textarea\"\n placeholder=\"请输入职位描述,包括职责、要求等信息...\"\n rows={6}\n value={this.jobDescription}\n onInput={this.handleJobDescriptionChange}\n ></textarea>\n </div>\n )}\n\n {/* 上传面试内容上传区域 - 仅在没有customInputs.file_urls时显示 */}\n {!hideFileUpload && (\n <div class=\"resume-upload-section\">\n <label>上传面试内容</label>\n <div class=\"upload-area\" onClick={this.handleUploadClick}>\n {this.selectedFile ? (\n <div class=\"file-item\">\n <div class=\"file-item-content\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">{this.selectedFile.name}</span>\n </div>\n <button class=\"remove-file\" onClick={(e) => {\n e.stopPropagation();\n this.clearSelectedFile();\n }}>×</button>\n </div>\n ) : (\n <div class=\"upload-placeholder\">\n <img src='https://pub.pincaimao.com/static/web/images/home/i_upload.png'></img>\n <p class='upload-text'>点击上传面试内容</p>\n <p class=\"upload-hint\">支持 mp3、markdown、pdf、docx、doc、md 格式</p>\n </div>\n )}\n </div>\n </div>\n )}\n\n <button\n class=\"submit-button\"\n disabled={(!hideFileUpload && !this.selectedFile) || (!hideJdInput && !this.jobDescription.trim()) || this.isUploading || this.isSubmitting}\n onClick={this.handleStartInterview}\n >\n {this.isUploading ? '上传中...' : this.isSubmitting ? '处理中...' : '开始分析'}\n </button>\n\n <div class=\"ai-disclaimer\">\n <p>所有内容均由AI生成仅供参考</p>\n <p class=\"beian-info\">\n <span>中央网信办生成式人工智能服务备案号</span>:\n <a href=\"https://www.pincaimao.com\" target=\"_blank\" rel=\"noopener noreferrer\">Hunan-PinCaiMao-202412310003</a>\n </p>\n </div>\n\n <input\n type=\"file\"\n class=\"file-input\"\n onChange={this.handleFileChange}\n />\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div >\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n fullscreen={this.fullscreen}\n showWorkspaceHistory={this.showWorkspaceHistory}\n botId=\"3022316191018877\"\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n filePreviewMode={this.filePreviewMode}\n enableVoice={false}\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n file_urls: this.customInputs?.file_urls || this.uploadedFileInfo?.cos_key,\n file_names: this.customInputs?.file_names || this.uploadedFileInfo?.file_name,\n job_info: this.customInputs?.job_info || this.jobDescription\n }}\n interviewMode=\"text\"\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} ","\n",":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { uploadFileToBackend, FileUploadResponse, verifyApiKey } from '../../utils/utils';\nimport { ConversationStartEventData, InterviewCompleteEventData, StreamCompleteEventData } from '../../components';\nimport { ErrorEventBus, ErrorEventDetail } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store';\nimport { configStore } from '../../../store/config.store';\nimport { SentryReporter } from '../../utils/sentry-reporter';\n\n/**\n * 千岗千简历\n */\n\n@Component({\n tag: 'pcm-qgqjl-modal',\n styleUrls: ['pcm-qgqjl-modal.css', '../../global/global.css'],\n shadow: true,\n})\nexport class QgqjlModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '千岗千简历';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请开始出题';\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n /**\n * 自定义输入参数,传入customInputs.job_info时,会隐藏JD输入区域<br>\n * 传入customInputs.file_url时,会隐藏简历上传区域。<br>\n * 传入customInputs.file_url和customInputs.job_info时,会直接开始聊天。<br>\n */\n @Prop() customInputs: Record<string, string> = {};\n\n /**\n * 是否显示工作区历史会话按钮\n */\n @Prop() showWorkspaceHistory: boolean = false;\n\n /**\n * 上传成功事件\n */\n @Event() uploadSuccess: EventEmitter<FileUploadResponse>;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() interviewComplete: EventEmitter<InterviewCompleteEventData>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 附件预览模式\n * 'drawer': 在右侧抽屉中预览\n * 'window': 在新窗口中打开\n */\n @Prop() filePreviewMode: 'drawer' | 'window' = 'window';\n\n @State() selectedFile: File | null = null;\n @State() isUploading: boolean = false;\n @State() uploadedFileInfo: FileUploadResponse | null = null;\n @State() showChatModal: boolean = false;\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n @State() jobDescription: string = '';\n @State() isSubmitting: boolean = false;\n\n\n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n\n\n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.clearSelectedFile();\n this.showChatModal = false;\n this.jobDescription = '';\n } else {\n if (this.customInputs && this.customInputs.job_info) {\n this.jobDescription = this.customInputs.job_info;\n }\n\n await verifyApiKey(this.token);\n\n // 如果有会话ID或者同时有file_url和job_info,直接显示聊天模态框\n if (this.conversationId || (this.customInputs?.file_url && this.customInputs?.job_info)) {\n this.showChatModal = true;\n }\n }\n }\n\n \n\n componentWillLoad() {\n \n\n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n if (this.token) {\n authStore.setToken(this.token);\n }\n\n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n private handleFileChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length > 0) {\n this.selectedFile = input.files[0];\n }\n };\n\n private handleUploadClick = () => {\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n fileInput?.click();\n };\n\n private clearSelectedFile = () => {\n this.selectedFile = null;\n this.uploadedFileInfo = null;\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n if (fileInput) {\n fileInput.value = '';\n }\n };\n\n private async uploadFile() {\n if (!this.selectedFile) return;\n\n this.isUploading = true;\n\n try {\n // 使用 uploadFileToBackend 工具函数上传文件\n const result = await uploadFileToBackend(this.selectedFile, {\n }, {\n 'tags': ['resume']\n });\n\n this.uploadedFileInfo = result;\n this.uploadSuccess.emit(result);\n } catch (error) {\n console.error('文件上传错误:', error);\n this.clearSelectedFile();\n SentryReporter.captureError(error, {\n action: 'uploadFile',\n component: 'pcm-qgqjl-modal',\n title: '文件上传失败'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '文件上传失败,请重试'\n });\n } finally {\n this.isUploading = false;\n }\n }\n\n private handleJobDescriptionChange = (event: Event) => {\n const textarea = event.target as HTMLTextAreaElement;\n this.jobDescription = textarea.value;\n };\n\n private handleStartInterview = async () => {\n if (!this.selectedFile) {\n alert('请上传简历');\n return;\n }\n\n // 如果没有预设的job_info,则需要检查用户输入\n if (!this.customInputs?.job_info && !this.jobDescription.trim()) {\n alert('请输入职位描述');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n // 如果还没上传,先上传文件\n if (!this.uploadedFileInfo) {\n await this.uploadFile();\n if (!this.uploadedFileInfo) {\n this.isSubmitting = false;\n return; // 上传失败\n }\n }\n\n // 直接显示聊天模态框\n this.showChatModal = true;\n } catch (error) {\n console.error('开始面试时出错:', error);\n SentryReporter.captureError(error, {\n action: 'handleStartInterview',\n component: 'pcm-qgqjl-modal',\n title: '开始面试时出错'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '开始面试时出错,请重试'\n });\n } finally {\n this.isSubmitting = false;\n }\n };\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n // 修正这里的逻辑,确保当 customInputs.job_info 存在时,hideJdInput 为 true\n const hideJdInput = Boolean(this.customInputs && this.customInputs.job_info);\n \n // 判断是否隐藏简历上传区域\n const hideResumeUpload = Boolean(this.customInputs && this.customInputs.file_url);\n \n // 判断是否同时提供了file_url和job_info\n const hasFileAndJob = Boolean(this.customInputs?.file_url && this.customInputs?.job_info);\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n {/* 上传界面 - 仅在不显示聊天模态框且没有会话ID且没有同时提供file_url和job_info时显示 */}\n {!this.showChatModal && !this.conversationId && !hasFileAndJob && (\n <div class=\"input-container\">\n {/* JD输入区域 - 仅在没有customInputs.job_info时显示 */}\n {!hideJdInput && (\n <div class=\"jd-input-section\">\n <label htmlFor=\"job-description\">请输入职位描述 (JD)</label>\n <textarea\n id=\"job-description\"\n class=\"job-description-textarea\"\n placeholder=\"请输入职位描述,包括职责、要求等信息...\"\n rows={6}\n value={this.jobDescription}\n onInput={this.handleJobDescriptionChange}\n ></textarea>\n </div>\n )}\n\n {/* 简历上传区域 - 仅在没有customInputs.file_url时显示 */}\n {!hideResumeUpload && (\n <div class=\"resume-upload-section\">\n <label>上传简历</label>\n <div class=\"upload-area\" onClick={this.handleUploadClick}>\n {this.selectedFile ? (\n <div class=\"file-item\">\n <div class=\"file-item-content\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">{this.selectedFile.name}</span>\n </div>\n <button class=\"remove-file\" onClick={(e) => {\n e.stopPropagation();\n this.clearSelectedFile();\n }}>×</button>\n </div>\n ) : (\n <div class=\"upload-placeholder\">\n <img src='https://pub.pincaimao.com/static/web/images/home/i_upload.png'></img>\n <p class='upload-text'>点击上传简历</p>\n <p class=\"upload-hint\">支持 txt、markdown、pdf、docx、doc、md 格式</p>\n </div>\n )}\n </div>\n </div>\n )}\n\n <button\n class=\"submit-button\"\n disabled={(!hideResumeUpload && !this.selectedFile) || (!hideJdInput && !this.jobDescription.trim()) || this.isUploading || this.isSubmitting}\n onClick={this.handleStartInterview}\n >\n {this.isUploading ? '上传中...' : this.isSubmitting ? '处理中...' : '开始分析'}\n </button>\n\n <div class=\"ai-disclaimer\">\n <p>所有内容均由AI生成仅供参考</p>\n <p class=\"beian-info\">\n <span>中央网信办生成式人工智能服务备案号</span>:\n <a href=\"https://www.pincaimao.com\" target=\"_blank\" rel=\"noopener noreferrer\">Hunan-PinCaiMao-202412310003</a>\n </p>\n </div>\n\n <input\n type=\"file\"\n class=\"file-input\"\n onChange={this.handleFileChange}\n />\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div>\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n fullscreen={this.fullscreen}\n showWorkspaceHistory={this.showWorkspaceHistory}\n botId=\"45444431062634496\"\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n filePreviewMode={this.filePreviewMode}\n enableVoice={false}\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n file_url: this.customInputs?.file_url || this.uploadedFileInfo?.cos_key,\n file_name: this.customInputs?.file_name || this.uploadedFileInfo?.file_name,\n job_info: this.customInputs?.job_info || this.jobDescription\n }}\n interviewMode=\"text\"\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} ",null,":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, EventEmitter, Prop, Event, h, State, Watch } from \"@stencil/core\";\n\nconst formatNumber = (n: number) => {\n const str = n.toString();\n return str[1] ? str : `0${str}`;\n}\n\n// 时间转时分秒\nconst timeToHMS = (time: number) => {\n const hour = Math.floor(time / 3600);\n const minute = Math.floor((time - hour * 3600) / 60);\n const second = time - hour * 3600 - minute * 60;\n return `${formatNumber(hour)}:${formatNumber(minute)}:${formatNumber(second)}`;\n}\n\n@Component({\n tag: 'pcm-time-count-down',\n styleUrls: ['pcm-time-count-down.css', '../../global/global.css'],\n shadow: true,\n})\nexport class TimeCountDown {\n /**\n * 倒计时总秒数\n */\n @Prop() time: number;\n /**\n * 倒计时结束事件\n */\n @Event() finished: EventEmitter;\n\n @State() currentTime: number;\n\n componentWillLoad() {\n this.currentTime = this.time;\n }\n\n @Watch('currentTime')\n watchStateHandler(currentTime) {\n let timer;\n if (currentTime > 0) {\n timer = setTimeout(() => {\n this.currentTime = currentTime - 1;\n clearTimeout(timer);\n }, 1000);\n } else {\n this.finished.emit();\n }\n }\n\n render() {\n return <span>{timeToHMS(this.currentTime)}</span>\n }\n}\n",null,":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ","import { Component, h, State, Element, Prop, Event, EventEmitter, Method } from \"@stencil/core\";\nimport { FileUploadResponse, FileUploadResponseWithState, FileUploadState, formatFileSize, uploadFileToBackend } from \"../../utils/utils\";\nimport { Message } from \"../../services/message.service\";\nimport { SentryReporter } from \"../../utils/sentry-reporter\";\n\n\n@Component({\n tag: 'pcm-upload',\n styleUrls: ['pcm-upload.css', '../../global/global.css'],\n shadow: true,\n})\nexport class PcmUpload {\n /**\n * 是否支持多文件上传\n */\n @Prop() multiple: boolean = false;\n /**\n * 是否开启移动端上传(仅PC端生效)\n */\n @Prop() mobileUploadAble: boolean = false;\n /**\n * label内容\n */\n @Prop() labelText: string = '上传文件'\n /**\n * 支持的文件后缀列表(需要带上小数点.)\n */\n @Prop() acceptFileSuffixList: string[] = [];\n /**\n * 最大文件数\n */\n @Prop() maxFileCount: number = Infinity;\n /**\n * 最大文件大小\n */\n @Prop() maxFileSize: number = Infinity;\n /**\n * 上传请求头\n */\n @Prop() uploadHeaders?: Record<string, any>;\n /**\n * 上传请求参数\n */\n @Prop() uploadParams?: Record<string, any>;\n /**\n * 上传失败监听\n */\n @Event() uploadFailed: EventEmitter<UploadFailedEvent>;\n /**\n * 上传文件变化监听\n */\n @Event() uploadChange: EventEmitter<FileUploadResponse[]>;\n\n\n @Element() hostElement: HTMLElement;\n @State() selectedFiles: FileUploadResponseWithState[] | null = null;\n\n @Method()\n async getIsUploading() {\n return !!this.selectedFiles?.some(item => item.state === FileUploadState.Uploading);\n }\n\n private handleUploadClick = () => {\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n fileInput?.click();\n };\n\n private clearSelectedFile = () => {\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n if (fileInput) {\n fileInput.value = '';\n }\n };\n\n private async uploadFile(file: File): Promise<FileUploadResponseWithState> {\n try {\n const result = await uploadFileToBackend(file, this.uploadHeaders || {}, this.uploadParams || {});\n return {\n ...result,\n file,\n file_name: file.name,\n file_size: file.size,\n state: FileUploadState.Success,\n }\n } catch (error) {\n this.clearSelectedFile();\n SentryReporter.captureError(error, {\n action: 'uploadFile',\n component: 'pcm-mnms-modal',\n title: '文件上传失败'\n });\n this.uploadFailed.emit({\n error: error,\n message: '文件上传失败,请重试'\n });\n return {\n file,\n error,\n state: FileUploadState.Failed,\n }\n }\n }\n\n private handleFileChange = async (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n if (this.multiple) {\n // 多选\n } else {\n // 单选\n const file = input.files?.[0];\n if (!file) return;\n // 检测文件是否符合后缀名\n if (this.acceptFileSuffixList?.length) {\n const suffix = '.' + file.name.split('.').pop()?.toLowerCase();\n if (!this.acceptFileSuffixList.includes(suffix)) {\n Message.info(`请上传 ${this.acceptFileSuffixList.join('、')} 格式的文件`);\n return;\n }\n }\n // 检测文件大小是否超出限制\n if (this.maxFileSize < file.size) {\n Message.info(`文件大小不能超过 ${formatFileSize(this.maxFileSize) ?? '-'}`);\n return;\n }\n this.selectedFiles = [{\n file,\n file_name: file.name,\n file_size: file.size,\n state: FileUploadState.Uploading,\n cos_key: '',\n error: undefined,\n }];\n const uploadResult = await this.uploadFile(file);\n this.selectedFiles = [uploadResult];\n this.clearSelectedFile();\n this.emitUploadChange();\n }\n };\n\n private emitUploadChange = () => {\n this.uploadChange.emit(this.selectedFiles?.map?.(item => ({\n cos_key: item.cos_key,\n file_name: item.file_name,\n file_size: item.file_size,\n ext: item.ext,\n })));\n }\n\n private uploadBtn() {\n return <div>\n {\n !!this.mobileUploadAble && <pcm-mobile-upload-btn\n multiple={this.multiple}\n acceptFileSuffixList={this.acceptFileSuffixList}\n maxFileCount={this.maxFileCount}\n maxFileSize={this.maxFileSize}\n uploadHeaders={this.uploadHeaders}\n uploadParams={this.uploadParams}\n onOk={e => {\n this.selectedFiles = [\n ...(this.selectedFiles ?? []),\n ...(e.detail ?? []).map(item => ({\n ...item,\n state: FileUploadState.Success,\n }))\n ]\n this.emitUploadChange();\n }}\n />\n }\n <div class=\"upload-placeholder\" onClick={this.handleUploadClick}>\n <img src='https://pub.pincaimao.com/static/web/images/home/i_upload.png'></img>\n <p class='upload-text'>点击上传简历</p>\n <p class=\"upload-hint\">\n {\n !!this.acceptFileSuffixList?.length && <p>支持 {this.acceptFileSuffixList.join('、')} 格式。</p>\n }\n {\n !!this.maxFileSize && this.maxFileSize !== Infinity && <p>文件大小不能超过 {formatFileSize(this.maxFileSize) ?? ''}。</p>\n }\n {\n !!this.maxFileCount && this.maxFileCount !== Infinity && <p>最多上传 {this.maxFileCount} 个文件。</p>\n }\n </p>\n </div>\n </div>\n }\n\n render() {\n return (\n <div>\n <div class=\"resume-upload-section\">\n <label >{this.labelText}</label>\n <div class=\"upload-area\">\n <div>\n {\n this.selectedFiles?.map?.((item, index) => {\n return <div class=\"file-item\">\n <div class=\"file-item-content\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\" style={item.state === FileUploadState.Failed ? { color: 'red', textDecoration: 'line-through' } : undefined}>{item?.file_name}</span>\n {\n item.state === FileUploadState.Failed && <span style={{ color: 'red', marginLeft: '4px' }}>({item.error?.message ?? '上传失败'})</span>\n }\n </div>\n <button class=\"remove-file\" onClick={(e) => {\n e.stopPropagation();\n this.selectedFiles = this.selectedFiles?.filter((_, itemIndex) => index !== itemIndex);\n }}>×</button>\n </div>\n })\n }\n </div>\n {\n this.multiple ? <div>\n {\n (this.selectedFiles?.length ?? 0) < this.maxFileCount && this.uploadBtn()\n }\n </div> : <div>\n {\n !this.selectedFiles?.length && this.uploadBtn()\n }\n </div>\n }\n </div>\n </div>\n <input\n type=\"file\"\n class=\"file-input\"\n onChange={this.handleFileChange}\n />\n </div>\n )\n }\n}",":host {\n display: block;\n font-size: 16px;\n}\n\n \n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n overflow-y: auto;\n padding: 20px;\n z-index: 1000;\n -webkit-overflow-scrolling: touch; /* 增强iOS滚动体验 */\n}\n\n/* 全屏模式下的overlay样式 */\n.fullscreen-overlay {\n padding: 0;\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n\n.modal-container {\n background: white;\n border-radius: 8px;\n width: 100%;\n max-width: 900px;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* 确保内容区域也使用 flex 布局并占满剩余空间 */\n.modal-container.fullscreen > div:not(.modal-header):not(.initial-upload) {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden; /* 防止内容溢出 */\n height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 800px;\n /* height: 80vh; */\n /* max-height: 700px; */\n min-width: 320px;\n min-height: 400px;\n}\n\n\n\n.video-preview.placeholder {\n display: flex;\n justify-content: center;\n align-items: center;\n background: #EAEAEA;\n}\n\n.placeholder-status {\n color: #00000066;\n}\n\n.waiting-message p {\n margin: 0;\n font-size: 16px;\n color: white;\n font-weight: 500;\n}\n\n.recording-container {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n\n\n.video-area {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.stop-recording-button {\n width: 100%;\n height: 100%;\n font-size: 16px;\n background: #f44336;\n border-radius: 6px;\n color: white;\n border: none;\n cursor: pointer;\n}\n\n.stop-recording-button:hover {\n background: #d32f2f;\n}\n\n.play-audio-container {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0; /* 防止头部被压缩 */\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n.chat-container{\n background-image: url(https://pub.pincaimao.com/static/web/images/login/bg_login_m.png);\n background-size: 100%;\n height: 100%;\n border-radius:0px 0px 8px 8px;\n}\n\n.chat-history {\n position: relative;\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n height: 400px;\n}\n\n/* 添加全屏模式下的样式 */\n.fullscreen .chat-history {\n height: auto;\n flex: 1 1 auto;\n}\n\n\n.message-input {\n padding: 16px;\n border-top: 1px solid #eee;\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.message-input input {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #ddd;\n border-radius: 4px;\n outline: none;\n transition: border-color 0.2s ease;\n}\n\n.message-input input:focus {\n border-color: #bbb;\n}\n\n/* 消息样式 */\n.message {\n margin-bottom: 16px;\n opacity: 1;\n transition: opacity 0.3s ease;\n}\n\n.message-content {\n max-width: 70%;\n padding: 8px 12px;\n border-radius: 8px;\n word-break: break-word;\n}\n\n.message-content p {\n margin: 0;\n word-break: break-word;\n}\n\n.user-message {\n display: flex;\n justify-content: flex-end;\n}\n\n.agent-message {\n display: flex;\n justify-content: flex-start;\n}\n\n.user-message .message-content {\n background-color: #007bff;\n color: white;\n}\n\n.agent-message .message-content {\n background-color: #f1f1f1;\n}\n\n.message-time {\n font-size: 12px;\n color: #999;\n margin-top: 4px;\n display: block;\n}\n\n/* 发送按钮样式 */\n.send-button {\n width: 38px;\n height: 38px;\n border-radius: 16px;\n background: #0d75fb;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: background-color 0.2s ease;\n}\n\n.send-button img {\n width: 24px;\n height: 24px;\n}\n\n.send-button:hover {\n background: #0a62d6;\n}\n\n.send-button.disabled {\n background: #d9d9d9;\n cursor: not-allowed;\n}\n\n.empty-state {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n color: #999;\n text-align: center;\n}\n\n.loading-container {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n background-color: rgba(255, 255, 255, 0.98);\n z-index: 1;\n opacity: 1;\n transition: opacity 0.3s ease;\n}\n\n.loading-container p {\n margin-top: 16px;\n color: #666;\n font-size: 14px;\n}\n\n.loading-spinner {\n width: 40px;\n height: 40px;\n border: 3px solid #f3f3f3;\n border-top: 3px solid #1890ff;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n}\n\n/* 修改 messages-wrapper 的样式 */\n.messages-wrapper {\n width: 100%;\n min-height: 100%;\n display: flex;\n flex-direction: column;\n /* 当内容少时,将内容放在底部 */\n justify-content: flex-end;\n}\n\n/* 当有很多消息时,取消固定在底部 */\n.messages-wrapper.has-overflow {\n justify-content: flex-start;\n}\n\n.suggested-questions {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 16px;\n}\n\n.suggested-question {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n background-color: #f3f4f6;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n color: #374151;\n transition: background-color 0.2s;\n}\n\n.suggested-question:hover {\n background-color: #e5e7eb;\n}\n\n.arrow-right {\n margin-left: 8px;\n}\n\n.loading-suggestions {\n display: flex;\n justify-content: center;\n padding: 16px;\n}\n\n.loading-spinner-small {\n width: 20px;\n height: 20px;\n border: 2px solid #e5e7eb;\n border-top-color: #6b7280;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n/* 添加上传按钮样式 */\n.upload-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n border-radius: 4px;\n transition: background-color 0.2s;\n}\n\n.upload-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.upload-button svg {\n width: 20px;\n height: 20px;\n}\n\n/* 隐藏原生文件输入框 */\n.file-input {\n display: none;\n}\n\n/* 添加文件名显示区域样式 */\n.selected-file {\n font-size: 12px;\n color: #666;\n margin-left: 8px;\n max-width: 150px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.input-wrapper {\n flex: 1;\n display: flex;\n align-items: center;\n border: 1px solid #ddd;\n border-radius: 4px;\n padding: 0 4px;\n background: white;\n}\n\n.input-wrapper input {\n border: none;\n flex: 1;\n padding: 8px;\n outline: none;\n}\n\n.input-wrapper:focus-within {\n border-color: #bbb;\n}\n\n/* 文件预览区域样式 */\n.file-preview {\n padding: 8px 16px;\n border-top: 1px solid #eee;\n background-color: #f9f9f9;\n}\n\n\n.recording-section {\n border-top: 1px solid #eee;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 10px 20px 0px 20px;\n border-radius: 14px 14px 0 0;\n flex: 0 0 auto;\n}\n\n.recording-section .video-preview {\n width: 100%;\n height: 200px;\n max-width: 400px;\n position: relative;\n margin-bottom: 10px;\n border: 1px solid #ddd;\n border-radius: 12px;\n overflow: hidden;\n}\n\n.recording-section video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n/* 修改 recording-status 样式 */\n.recording-status {\n position: absolute;\n top: 10px;\n left: 10px;\n background-color: rgba(0, 0, 0, 0.6);\n color: white;\n padding: 4px 8px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 14px;\n z-index: 2;\n}\n\n.recording-status .recording-dot {\n display: inline-block;\n width: 10px;\n height: 10px;\n background-color: red;\n border-radius: 50%;\n margin-right: 5px;\n animation: blink 1s infinite;\n}\n\n.recording-status.warning {\n color: #ff4d4f;\n animation: blink 1s infinite;\n}\n\n@keyframes blink {\n 0% {\n opacity: 1;\n }\n\n 50% {\n opacity: 0.5;\n }\n\n 100% {\n opacity: 1;\n }\n}\n\n.recording-section .stop-recording-button {\n background-color: #f44336;\n color: white;\n border: none;\n cursor: pointer;\n font-weight: bold;\n}\n\n.recording-section .stop-recording-button:hover {\n background-color: #d32f2f;\n}\n\n.fullscreen {\n width: 100vw;\n border-radius: 0;\n height: 100vh;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n}\n\n.recording-controls {\n margin-top: 10px;\n height: 53px;\n width: 100%;\n max-width: 400px;\n display: flex;\n justify-content: center;\n}\n\n.recording-controls .waiting-message {\n text-align: center;\n color: white;\n font-size: 16px;\n background-image: linear-gradient(100deg, #4A9FFF 0%, #1058FF 100%);\n border-radius: 6px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n width: 95%;\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n}\n\n.recording-controls .waiting-message.loading {\n background: #faad14;\n}\n\n.recording-controls .waiting-message p {\n margin: 0;\n font-size: 16px;\n color: white;\n font-weight: 500;\n}\n\n.recording-controls .stop-recording-button {\n background-color: #dc3545;\n color: white;\n border: none;\n cursor: pointer;\n font-size: 16px;\n}\n\n.recording-controls .stop-recording-button:hover {\n background-color: #c82333;\n}\n\n/* 添加禁用状态的样式 */\n.recording-controls .stop-recording-button.disabled {\n background: #ccc;\n cursor: not-allowed;\n}\n\n.recording-controls .stop-recording-button.disabled:hover {\n background: #ccc;\n}\n\n/* 添加进度条和数字进度的样式 */\n.progress-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n max-width: 400px;\n margin-top: 10px;\n padding: 0 5px;\n}\n\n.progress-bar-container {\n height: 4px;\n background-color: #E5E5E5;\n border-radius: 2px;\n overflow: hidden;\n margin-right: 10px;\n width: 75px;\n}\n\n.progress-bar {\n height: 100%;\n background-image: linear-gradient(111deg, #4A9FFF 0%, #1058FF 100%);\n border-radius: 2px;\n transition: width 0.3s ease;\n}\n\n.progress-text {\n font-size: 14px;\n color: #666;\n white-space: nowrap;\n}\n\n/* 重新设计文本输入区域样式 */\n.text-input-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n padding: 0px 16px 16px 16px;\n border-radius: 8px;\n border: none; /* 确保容器本身没有边框 */\n}\n\n/* 修改文本输入框样式 */\n.text-answer-input {\n flex: 1;\n min-height: 80px;\n padding: 12px 12px 0px 12px;\n border: 1px solid #ddd;\n border-radius: 8px 8px 0 0;\n resize: none;\n font-size: 16px;\n background-color: #fff;\n border-bottom: none;\n outline: none; /* 移除默认的焦点轮廓 */\n}\n\n/* 修改工具栏样式 */\n.input-toolbar {\n display: flex;\n justify-content: end;\n align-items: center;\n padding: 8px 12px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-top: none;\n border-radius: 0 0 8px 8px;\n}\n\n/* 当输入框获得焦点时,修改边框颜色 */\n.text-answer-input:focus {\n border-color: rgb(74, 144, 226);\n border-bottom: none;\n}\n\n.text-answer-input:focus+.input-toolbar {\n border-color: rgb(74, 144, 226);\n border-top: none;\n}\n\n/* 左侧工具按钮区域 */\n.toolbar-actions {\n width: 32px;\n height: 32px;\n display: flex;\n justify-content: center;\n align-items: center;\n margin-right: 10px;\n border: 1px solid #d9d9d9;\n border-radius: 6px;\n}\n\n.toolbar-actions:hover {\n background-color: #f0f0f0;\n}\n\n\n.toolbar-button {\n background: transparent;\n border: none;\n color: #666;\n cursor: pointer;\n padding: 0;\n margin: 0;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* 确保按钮内部的内容也居中 */\n.toolbar-button > div,\n.toolbar-button > svg {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.toolbar-button img {\n width: 16px;\n height: 16px;\n}\n\n/* 发送按钮样式 */\n.submit-text-button {\n padding: 6px 16px;\n background-color: #4a90e2;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background-color 0.2s;\n}\n\n.submit-text-button:hover:not(.disabled) {\n background-color: #3a7bc8;\n}\n\n.submit-text-button.disabled {\n background-color: #b3b3b3;\n cursor: not-allowed;\n}\n\n\n/* 语音输入按钮样式 */\n.toolbar-button.recording {\n background-color: rgba(255, 0, 0, 0.1);\n color: #ff3b30;\n animation: pulse 1.5s infinite;\n}\n\n.toolbar-button.converting {\n background-color: rgba(0, 122, 255, 0.1);\n color: #007aff;\n}\n\n.toolbar-button .recording-time {\n font-size: 12px;\n margin-left: 4px;\n}\n\n.converting-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.converting-indicator svg {\n animation: spin 1.5s linear infinite;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes pulse {\n 0% {\n box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.4);\n }\n 70% {\n box-shadow: 0 0 0 6px rgba(255, 0, 0, 0);\n }\n 100% {\n box-shadow: 0 0 0 0 rgba(255, 0, 0, 0);\n }\n}\n\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n\n\n}\n\n/* 修改引用文档样式 */\n.references-section {\n margin-top: 30px;\n padding: 12px;\n background-color: #f9f9f9;\n border-radius: 8px;\n border: 1px solid #e8e8e8;\n}\n\n.references-title {\n font-size: 14px;\n color: #666;\n margin: 0 0 8px 0;\n font-weight: 500;\n}\n\n.references-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.reference-item {\n background-color: #fff;\n border: 1px solid #e8e8e8;\n border-radius: 6px;\n padding: 10px;\n cursor: pointer;\n transition: background-color 0.2s, box-shadow 0.2s;\n}\n\n.reference-item:hover {\n background-color: #f5f5f5;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.reference-header {\n display: flex;\n align-items: center;\n gap: 6px;\n position: relative;\n}\n\n.reference-icon {\n color: #1890ff;\n display: flex;\n align-items: center;\n}\n\n.reference-name {\n font-size: 13px;\n font-weight: 500;\n color: #333;\n flex: 1;\n}\n\n.download-icon {\n color: #1890ff;\n display: flex;\n align-items: center;\n}\n\n/* 移除不再需要的引用内容样式 */\n.reference-content {\n display: none;\n}\n\n/* 推荐问题样式 */\n.suggested-questions {\n margin-top: 20px;\n padding: 12px;\n background-color: #f0f7ff;\n border-radius: 8px;\n border: 1px solid #d6e8ff;\n}\n\n.suggested-title {\n font-size: 14px;\n color: #1890ff;\n margin: 0 0 8px 0;\n font-weight: 500;\n}\n\n.suggested-question {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n background-color: #fff;\n border: 1px solid #e6f7ff;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n color: #1890ff;\n transition: all 0.3s;\n margin-bottom: 8px;\n}\n\n.suggested-question:last-child {\n margin-bottom: 0;\n}\n\n.suggested-question:hover {\n background-color: #e6f7ff;\n border-color: #91d5ff;\n}\n\n.arrow-right {\n color: #1890ff;\n display: flex;\n align-items: center;\n}\n\n.loading-suggestions {\n display: flex;\n justify-content: center;\n padding: 16px;\n}\n\n.loading-spinner-small {\n width: 20px;\n height: 20px;\n border: 2px solid #e6f7ff;\n border-top-color: #1890ff;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n",":host {\n font-size: 16px;\n}\n\n/* 模态框基础样式 */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* 全屏模式下的overlay样式 - 改为基于父组件 */\n.fullscreen-overlay {\n padding: 0;\n background-color: rgba(0, 0, 0, 0.7);\n /* 改为基于父组件的全屏 */\n position: absolute;\n width: 100%;\n height: calc(100% - 10px);\n}\n\n.modal-container {\n background-color: #fff;\n border-radius: 8px;\n width: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n margin: auto;\n transition: all 0.3s ease-out;\n overflow: hidden;\n}\n\n/* 全屏模式样式 - 改为基于父组件 */\n.modal-container.fullscreen {\n width: 100%;\n max-width: none;\n height: 100%;\n border-radius: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n}\n\n/* PC端布局 */\n.pc-layout {\n width: 80%;\n max-width: 600px;\n min-width: 320px;\n}\n\n/* 响应式布局 */\n@media screen and (max-width: 768px) {\n .pc-layout {\n width: 95%;\n }\n\n .modal-overlay {\n padding: 10px 0px 0px 0px;\n }\n\n .modal-container.fullscreen {\n /* 移动端也基于父组件尺寸 */\n width: 100%;\n height: 100%;\n max-height: 100%;\n border-radius: 16px 16px 0 0;\n /* 保留安全区域支持 */\n padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);\n }\n}\n\n/* 模态框头部样式 */\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 4px 16px;\n height: 50px;\n border-bottom: 1px solid #e8e8e8;\n flex-shrink: 0;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-icon {\n width: 24px;\n height: 24px;\n}\n\n.close-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 4px;\n}\n\n.close-button:hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n\n.close-button span {\n font-size: 24px;\n line-height: 1;\n color: #999;\n}\n\n.close-button:hover span {\n color: #666;\n}\n\n\n/* 文件上传区域通用样式 */\n.upload-area {\n cursor: pointer;\n width: 100%;\n}\n\n\n.upload-placeholder {\n transition: all 0.3s ease;\n display: flex;\n flex-direction: column;\n align-items: center;\n background: rgba(0, 0, 0, 0.02);\n border: 1px dashed #d9d9d9;\n border-radius: 8px;\n}\n\n.upload-placeholder:hover {\n border: 1px dashed #1890ff;\n}\n\n.upload-placeholder img {\n margin-top: 8px;\n width: 50px;\n height: 50px;\n}\n\n.upload-placeholder .upload-text {\n margin: 4px 0;\n color: #332F39;\n font-size: 14px;\n}\n\n.upload-placeholder .upload-hint {\n font-size: 14px;\n color: #949AA5;\n margin-top: 8px;\n padding: 0px 10px;\n text-align: center;\n}\n\n\n/* 文件项样式 */\n.file-item {\n position: relative;\n padding: 16px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n transition: border-color 0.3s;\n cursor: pointer;\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.file-item:hover {\n border-color: #0D75FB;\n}\n\n.file-item-content {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.file-icon {\n color: #0D75FB;\n flex-shrink: 0;\n}\n\n.file-name {\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 50px);\n}\n\n.remove-file {\n background: transparent;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px;\n margin-left: 8px;\n border-radius: 4px;\n transition: all 0.2s;\n min-width: 30px;\n min-height: 30px;\n}\n\n.remove-file:hover {\n background-color: #f1f5f9;\n color: #475569;\n}\n\n.file-input {\n display: none;\n}\n\n\n\n/* 输入容器样式 */\n.input-container {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: calc(100% - 50px);\n background: linear-gradient(150deg, #2a6ee933, #0000 50%) 0 0 / 400px 200px no-repeat, #fff;\n /* 减去header高度 */\n overflow-y: auto;\n}\n\n.input-container h3 {\n margin-top: 0;\n margin-bottom: 20px;\n font-size: 18px;\n color: #333;\n text-align: center;\n}\n\n/* JD输入区域样式 */\n.jd-input-section {\n margin-bottom: 20px;\n}\n\n.jd-input-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n}\n\n.job-description-textarea {\n width: calc(100% - 16px);\n border: 1px solid #ddd;\n border-radius: 4px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n transition: border-color 0.3s;\n padding: 8px;\n}\n\n.job-description-textarea:focus {\n outline: none;\n border-color: #1890ff;\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n}\n\n/* 简历上传区域样式 */\n.resume-upload-section {\n margin-bottom: 20px;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.resume-upload-section label {\n display: block;\n margin-bottom: 8px;\n font-weight: 500;\n color: #333;\n align-self: flex-start;\n}\n\n\n/* 提交按钮通用样式 */\n.submit-button {\n margin-top: 10px;\n padding: 10px 30px;\n background: #0D75FB;\n color: white;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n cursor: pointer;\n transition: all 0.3s ease;\n width: 100%;\n max-width: 400px;\n align-self: center;\n}\n\n.submit-button:hover {\n background-color: #40a9ff;\n}\n\n.submit-button:disabled {\n background-color: rgba(0,0,0,0.04);\n color: rgba(0,0,0,0.25);\n cursor: not-allowed;\n}\n\n\n\n/* AI免责声明和备案信息样式 */\n.ai-disclaimer {\n margin-top: 16px;\n text-align: center;\n font-size: 12px;\n color: #999;\n line-height: 1.5;\n}\n\n.ai-disclaimer p {\n margin: 4px 0;\n}\n\n.beian-info {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.ai-disclaimer a {\n color: #666;\n text-decoration: none;\n transition: color 0.2s ease;\n}\n\n.ai-disclaimer a:hover {\n color: #1890ff;\n text-decoration: underline;\n}\n\n/* 添加加载状态的样式 */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 24px;\n }\n \n .loading-spinner {\n width: 40px;\n height: 40px;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--pcm-primary-color, #1890ff);\n animation: spin 1s linear infinite;\n margin-bottom: 16px;\n }\n \n .loading-text {\n font-size: 16px;\n color: var(--pcm-text-color, #333);\n }\n \n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n \n ",".plan-type-section {\n display: flex;\n flex-direction: column;\n gap: 10px;\n margin-bottom: 20px;\n}\n\n.plan-type-section label {\n font-weight: 600;\n color: #333;\n margin-bottom: 8px;\n}\n\n.plan-type-options {\n display: flex;\n gap: 15px;\n flex-wrap: wrap;\n}\n\n.plan-type-option {\n flex: 1;\n min-width: 120px;\n border: 1px solid #e8e8e8;\n border-radius: 8px;\n padding: 15px;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n align-items: center;\n transition: all 0.3s;\n}\n\n.plan-type-option:hover {\n border-color: #1890ff;\n background-color: #f0f7ff;\n}\n\n.plan-type-option.selected {\n border-color: #1890ff;\n background-color: #e6f7ff;\n box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);\n}\n\n.option-icon {\n font-size: 24px;\n margin-bottom: 8px;\n}\n\n.option-label {\n font-size: 14px;\n font-weight: 500;\n color: #333;\n}\n\n.resume-upload-section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.resume-upload-section label {\n font-weight: 600;\n color: #333;\n margin-bottom: 8px;\n}\n\n\n\n","import { Component, Prop, h, State, Element, Event, EventEmitter, Watch } from '@stencil/core';\nimport { uploadFileToBackend, FileUploadResponse, verifyApiKey } from '../../utils/utils';\nimport { ConversationStartEventData, StreamCompleteEventData } from '../../components';\nimport { ErrorEventBus, ErrorEventDetail } from '../../utils/error-event';\nimport { authStore } from '../../../store/auth.store'; // 导入 authStore\nimport { configStore } from '../../../store/config.store';\nimport { SentryReporter } from '../../utils/sentry-reporter';\n\n/**\n * 职业规划助手\n */\n\nexport type CareerPlanType = '长期规划' | '转行建议' | '晋升路径';\n\n@Component({\n tag: 'pcm-zygh-modal',\n styleUrls: ['../../global/global.css', 'pcm-zygh-modal.css'],\n shadow: true,\n})\nexport class ZyghModal {\n /**\n * 模态框标题\n */\n @Prop() modalTitle: string = '职业规划助手';\n\n /**\n * SDK鉴权密钥\n */\n @Prop({ attribute: 'token' }) token!: string;\n\n /**\n * 是否显示聊天模态框\n */\n @Prop({ mutable: true }) isOpen: boolean = false;\n\n /**\n * 当点击模态框关闭时触发\n */\n @Event() modalClosed: EventEmitter<void>;\n\n /**\n * 应用图标URL\n */\n @Prop() icon?: string;\n\n /**\n * 聊天框的页面层级\n */\n @Prop() zIndex?: number = 1000;\n\n /**\n * 是否展示顶部标题栏\n */\n @Prop() isShowHeader: boolean = true;\n\n /**\n * 是否展示右上角的关闭按钮\n */\n @Prop() isNeedClose: boolean = true;\n\n /**\n * 会话ID,传入继续对话,否则创建新会话\n */\n @Prop({ mutable: true }) conversationId?: string;\n\n /**\n * 默认查询文本\n */\n @Prop() defaultQuery: string = '请开始规划';\n\n /**\n * 是否以全屏模式打开,移动端建议设置为true\n */\n @Prop() fullscreen: boolean = false;\n\n\n /**\n * 自定义输入参数,传入customInputs.type则可以指定规划类型,可传入\"长期规划\"、\"转行建议\"、\"晋升路径\"<br>\n * 传入customInputs.file_url时,会隐藏简历上传区域。<br>\n * 传入customInputs.file_url和customInputs.job_info时,会直接开始聊天。<br>\n */\n @Prop() customInputs: Record<string, string> = {};\n\n /**\n * 是否显示工作区历史会话按钮\n */\n @Prop() showWorkspaceHistory: boolean = false;\n\n\n /**\n * 上传成功事件\n */\n @Event() uploadSuccess: EventEmitter<FileUploadResponse>;\n\n /**\n * 流式输出完成事件\n */\n @Event() streamComplete: EventEmitter<StreamCompleteEventData>;\n\n /**\n * 新会话开始的回调,只会在一轮对话开始时触发一次\n */\n @Event() conversationStart: EventEmitter<ConversationStartEventData>;\n\n /**\n * 当聊天完成时触发\n */\n @Event() planningComplete: EventEmitter<{\n conversation_id: string;\n type: CareerPlanType;\n }>;\n\n /**\n * SDK密钥验证失败事件\n */\n @Event() tokenInvalid: EventEmitter<void>;\n\n /**\n * 错误事件\n */\n @Event() someErrorEvent: EventEmitter<ErrorEventDetail>;\n\n /**\n * 附件预览模式\n * 'drawer': 在右侧抽屉中预览\n * 'window': 在新窗口中打开\n */\n @Prop() filePreviewMode: 'drawer' | 'window' = 'window';\n\n @State() selectedFile: File | null = null;\n @State() isUploading: boolean = false;\n @State() uploadedFileInfo: FileUploadResponse | null = null;\n @State() showChatModal: boolean = false;\n @State() isSubmitting: boolean = false;\n @State() selectedPlanType: CareerPlanType = '长期规划';\n\n // 使用 @Element 装饰器获取组件的 host 元素\n @Element() hostElement: HTMLElement;\n\n private tokenInvalidListener: () => void;\n private removeErrorListener: () => void;\n\n @Watch('token')\n handleTokenChange(newToken: string) {\n // 当传入的 token 变化时,更新 authStore 中的 token\n if (newToken && newToken !== authStore.getToken()) {\n authStore.setToken(newToken);\n }\n }\n\n \n @Watch('isOpen')\n async handleIsOpenChange(newValue: boolean) {\n if (!newValue) {\n // 重置状态\n this.clearSelectedFile();\n this.showChatModal = false;\n\n } else {\n if (this.customInputs && this.customInputs.type) {\n // 检查是否是有效的 CareerPlanType 值\n const type = this.customInputs.type;\n if (type === '长期规划' || type === '转行建议' || type === '晋升路径') {\n this.selectedPlanType = type;\n }\n }\n\n await verifyApiKey(this.token);\n\n // 如果有会话ID或者有file_url参数,直接显示聊天模态框\n if (this.conversationId || this.customInputs?.file_url) {\n this.showChatModal = true;\n }\n }\n }\n\n \n\n componentWillLoad() {\n \n\n // 将 zIndex 存入配置缓存\n if (this.zIndex) {\n configStore.setItem('modal-zIndex', this.zIndex);\n }\n if (this.token) {\n authStore.setToken(this.token);\n }\n\n // 添加全局token无效事件监听器\n this.tokenInvalidListener = () => {\n this.tokenInvalid.emit();\n };\n // 添加全局错误监听\n this.removeErrorListener = ErrorEventBus.addErrorListener((errorDetail) => {\n this.someErrorEvent.emit(errorDetail);\n });\n document.addEventListener('pcm-token-invalid', this.tokenInvalidListener);\n }\n\n disconnectedCallback() {\n // 组件销毁时移除事件监听器\n document.removeEventListener('pcm-token-invalid', this.tokenInvalidListener);\n // 移除错误监听器\n if (this.removeErrorListener) {\n this.removeErrorListener();\n }\n }\n\n private handleClose = () => {\n this.modalClosed.emit();\n };\n\n private handleFileChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n if (input.files && input.files.length > 0) {\n this.selectedFile = input.files[0];\n }\n };\n\n private handleUploadClick = () => {\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n fileInput?.click();\n };\n\n private clearSelectedFile = () => {\n this.selectedFile = null;\n this.uploadedFileInfo = null;\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\n if (fileInput) {\n fileInput.value = '';\n }\n };\n\n private handlePlanTypeChange = (type: CareerPlanType) => {\n this.selectedPlanType = type;\n };\n\n private async uploadFile() {\n if (!this.selectedFile) return;\n\n this.isUploading = true;\n\n try {\n const result = await uploadFileToBackend(this.selectedFile, {\n }, {\n 'tags': ['resume']\n });\n\n this.uploadedFileInfo = result;\n this.uploadSuccess.emit(result);\n } catch (error) {\n console.error('文件上传错误:', error);\n this.clearSelectedFile();\n SentryReporter.captureError(error, {\n action: 'uploadFile',\n component: 'pcm-zygh-modal',\n title: '文件上传失败'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '文件上传失败,请重试'\n });\n } finally {\n this.isUploading = false;\n }\n }\n\n private handleStartPlanning = async () => {\n if (!this.selectedFile) {\n alert('请上传简历');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n // 如果还没上传,先上传文件\n if (!this.uploadedFileInfo) {\n await this.uploadFile();\n if (!this.uploadedFileInfo) {\n this.isSubmitting = false;\n return; // 上传失败\n }\n }\n\n // 直接显示聊天模态框\n this.showChatModal = true;\n } catch (error) {\n console.error('开始规划时出错:', error);\n SentryReporter.captureError(error, {\n action: 'handleStartPlanning',\n component: 'pcm-zygh-modal',\n title: '开始规划时出错'\n });\n ErrorEventBus.emitError({\n error: error,\n message: '开始规划时出错,请重试'\n });\n } finally {\n this.isSubmitting = false;\n }\n };\n\n\n // 处理规划完成事件\n private handlePlanningComplete = (event: CustomEvent) => {\n this.planningComplete.emit({\n ...event.detail,\n type: this.selectedPlanType\n });\n };\n\n\n render() {\n if (!this.isOpen) return null;\n\n const modalStyle = {\n zIndex: String(this.zIndex)\n };\n\n const containerClass = {\n 'modal-container': true,\n 'fullscreen': this.fullscreen,\n 'pc-layout': true,\n };\n\n const overlayClass = {\n 'modal-overlay': true,\n 'fullscreen-overlay': this.fullscreen\n };\n\n // 显示加载状态\n const isLoading = this.conversationId && !this.showChatModal;\n\n // 判断是否隐藏简历上传区域\n const hideResumeUpload = Boolean(this.customInputs && this.customInputs.file_url);\n\n return (\n <div class={overlayClass} style={modalStyle}>\n <div class={containerClass}>\n {this.isShowHeader && (\n <div class=\"modal-header\">\n <div class=\"header-left\">\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\n <div>{this.modalTitle}</div>\n </div>\n {this.isNeedClose && (\n <button class=\"close-button\" onClick={this.handleClose}>\n <span>×</span>\n </button>\n )}\n </div>\n )}\n\n\n {/* 输入界面 - 仅在不显示聊天模态框且没有会话ID且没有file_url时显示 */}\n {!this.showChatModal && !this.conversationId && !hideResumeUpload && (\n <div class=\"input-container\">\n\n {/* 规划类型选择 */}\n <div class=\"plan-type-section\">\n <label>选择规划类型</label>\n <div class=\"plan-type-options\">\n <div\n class={`plan-type-option ${this.selectedPlanType === '长期规划' ? 'selected' : ''}`}\n onClick={() => this.handlePlanTypeChange('长期规划')}\n >\n <div class=\"option-icon\">📈</div>\n <div class=\"option-label\">长期规划</div>\n </div>\n <div\n class={`plan-type-option ${this.selectedPlanType === '转行建议' ? 'selected' : ''}`}\n onClick={() => this.handlePlanTypeChange('转行建议')}\n >\n <div class=\"option-icon\">🔄</div>\n <div class=\"option-label\">转行建议</div>\n </div>\n <div\n class={`plan-type-option ${this.selectedPlanType === '晋升路径' ? 'selected' : ''}`}\n onClick={() => this.handlePlanTypeChange('晋升路径')}\n >\n <div class=\"option-icon\">🚀</div>\n <div class=\"option-label\">晋升路径</div>\n </div>\n </div>\n </div>\n\n {/* 简历上传区域 */}\n <div class=\"resume-upload-section\">\n <label>上传简历</label>\n <div class=\"upload-area\" onClick={this.handleUploadClick}>\n {this.selectedFile ? (\n <div class=\"file-item\">\n <div class=\"file-item-content\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">{this.selectedFile.name}</span>\n </div>\n <button class=\"remove-file\" onClick={(e) => {\n e.stopPropagation();\n this.clearSelectedFile();\n }}>×</button>\n </div>\n ) : (\n <div class=\"upload-placeholder\">\n <img src='https://pub.pincaimao.com/static/web/images/home/i_upload.png'></img>\n <p class='upload-text'>点击上传简历</p>\n <p class=\"upload-hint\">支持 txt、markdown、pdf、docx、doc、md 格式</p>\n </div>\n )}\n </div>\n </div>\n\n <button\n class=\"submit-button\"\n disabled={!this.selectedFile || this.isUploading || this.isSubmitting}\n onClick={this.handleStartPlanning}\n >\n {this.isUploading ? '上传中...' : this.isSubmitting ? '处理中...' : '开始规划'}\n </button>\n\n <div class=\"ai-disclaimer\">\n <p>所有内容均由AI生成仅供参考</p>\n <p class=\"beian-info\">\n <span>中央网信办生成式人工智能服务备案号</span>:\n <a href=\"https://www.pincaimao.com\" target=\"_blank\" rel=\"noopener noreferrer\">Hunan-PinCaiMao-202412310003</a>\n </p>\n </div>\n\n <input\n type=\"file\"\n class=\"file-input\"\n onChange={this.handleFileChange}\n />\n </div>\n )}\n\n {/* 加载状态 - 在有会话ID但聊天模态框尚未显示时展示 */}\n {isLoading && (\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">正在加载对话...</p>\n </div>\n )}\n\n {/* 聊天界面 - 在显示聊天模态框时显示 */}\n {this.showChatModal && (\n <div>\n <pcm-app-chat-modal\n isOpen={true}\n modalTitle={this.modalTitle}\n icon={this.icon}\n isShowHeader={this.isShowHeader}\n isNeedClose={this.isShowHeader}\n showWorkspaceHistory={this.showWorkspaceHistory}\n botId=\"3022316191018898\"\n fullscreen={this.fullscreen}\n conversationId={this.conversationId}\n defaultQuery={this.defaultQuery}\n enableVoice={false}\n filePreviewMode={this.filePreviewMode}\n customInputs={this.conversationId ? {} : {\n ...this.customInputs,\n file_url: this.customInputs?.file_url || this.uploadedFileInfo?.cos_key,\n file_name: this.customInputs?.file_name || this.uploadedFileInfo?.file_name,\n type: this.selectedPlanType\n }}\n interviewMode=\"text\"\n onInterviewComplete={this.handlePlanningComplete}\n ></pcm-app-chat-modal>\n </div>\n )}\n </div>\n </div>\n );\n }\n} "],"mappings":"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","ignoreList":[]}
|