@alibarbar/common 1.0.0
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/README.md +338 -0
- package/dist/algorithm.d.mts +66 -0
- package/dist/algorithm.d.ts +66 -0
- package/dist/algorithm.js +44 -0
- package/dist/algorithm.js.map +1 -0
- package/dist/algorithm.mjs +3 -0
- package/dist/algorithm.mjs.map +1 -0
- package/dist/array.d.mts +139 -0
- package/dist/array.d.ts +139 -0
- package/dist/array.js +84 -0
- package/dist/array.js.map +1 -0
- package/dist/array.mjs +3 -0
- package/dist/array.mjs.map +1 -0
- package/dist/chunk-27UDDVLZ.js +259 -0
- package/dist/chunk-27UDDVLZ.js.map +1 -0
- package/dist/chunk-2FFSQ573.mjs +138 -0
- package/dist/chunk-2FFSQ573.mjs.map +1 -0
- package/dist/chunk-4RGXV4SJ.js +106 -0
- package/dist/chunk-4RGXV4SJ.js.map +1 -0
- package/dist/chunk-56W6YECK.js +374 -0
- package/dist/chunk-56W6YECK.js.map +1 -0
- package/dist/chunk-5BGSUGTI.mjs +128 -0
- package/dist/chunk-5BGSUGTI.mjs.map +1 -0
- package/dist/chunk-7E6GELHJ.mjs +302 -0
- package/dist/chunk-7E6GELHJ.mjs.map +1 -0
- package/dist/chunk-7V5UQXIO.js +89 -0
- package/dist/chunk-7V5UQXIO.js.map +1 -0
- package/dist/chunk-A4SWQXX7.mjs +484 -0
- package/dist/chunk-A4SWQXX7.mjs.map +1 -0
- package/dist/chunk-ALDC6LRJ.mjs +85 -0
- package/dist/chunk-ALDC6LRJ.mjs.map +1 -0
- package/dist/chunk-BHCRFURU.js +491 -0
- package/dist/chunk-BHCRFURU.js.map +1 -0
- package/dist/chunk-D7CS5EKF.js +110 -0
- package/dist/chunk-D7CS5EKF.js.map +1 -0
- package/dist/chunk-DYBSRI7V.js +189 -0
- package/dist/chunk-DYBSRI7V.js.map +1 -0
- package/dist/chunk-F3LAGHPG.js +332 -0
- package/dist/chunk-F3LAGHPG.js.map +1 -0
- package/dist/chunk-HLDFI7R2.mjs +175 -0
- package/dist/chunk-HLDFI7R2.mjs.map +1 -0
- package/dist/chunk-HME2N3VY.mjs +354 -0
- package/dist/chunk-HME2N3VY.mjs.map +1 -0
- package/dist/chunk-I3L42475.js +145 -0
- package/dist/chunk-I3L42475.js.map +1 -0
- package/dist/chunk-JBLX27WD.mjs +240 -0
- package/dist/chunk-JBLX27WD.mjs.map +1 -0
- package/dist/chunk-JHZ7M2MR.mjs +133 -0
- package/dist/chunk-JHZ7M2MR.mjs.map +1 -0
- package/dist/chunk-JK2SE3I2.js +100 -0
- package/dist/chunk-JK2SE3I2.js.map +1 -0
- package/dist/chunk-JQZBPAPO.js +157 -0
- package/dist/chunk-JQZBPAPO.js.map +1 -0
- package/dist/chunk-JXYGC2C5.mjs +100 -0
- package/dist/chunk-JXYGC2C5.mjs.map +1 -0
- package/dist/chunk-KGFTD255.js +104 -0
- package/dist/chunk-KGFTD255.js.map +1 -0
- package/dist/chunk-LBHBNPNJ.mjs +148 -0
- package/dist/chunk-LBHBNPNJ.mjs.map +1 -0
- package/dist/chunk-LCXGZISK.js +158 -0
- package/dist/chunk-LCXGZISK.js.map +1 -0
- package/dist/chunk-LF4CILQS.mjs +87 -0
- package/dist/chunk-LF4CILQS.mjs.map +1 -0
- package/dist/chunk-MMR6XQNX.js +98 -0
- package/dist/chunk-MMR6XQNX.js.map +1 -0
- package/dist/chunk-NSSDYX2U.mjs +80 -0
- package/dist/chunk-NSSDYX2U.mjs.map +1 -0
- package/dist/chunk-O3O67R4I.js +143 -0
- package/dist/chunk-O3O67R4I.js.map +1 -0
- package/dist/chunk-OX5PLOWB.js +90 -0
- package/dist/chunk-OX5PLOWB.js.map +1 -0
- package/dist/chunk-PJ7UCTX4.mjs +362 -0
- package/dist/chunk-PJ7UCTX4.mjs.map +1 -0
- package/dist/chunk-QIBE7GVN.mjs +81 -0
- package/dist/chunk-QIBE7GVN.mjs.map +1 -0
- package/dist/chunk-QIOC54LQ.mjs +130 -0
- package/dist/chunk-QIOC54LQ.mjs.map +1 -0
- package/dist/chunk-QV6MIQ7H.mjs +328 -0
- package/dist/chunk-QV6MIQ7H.mjs.map +1 -0
- package/dist/chunk-TQN37HIN.js +94 -0
- package/dist/chunk-TQN37HIN.js.map +1 -0
- package/dist/chunk-XJTZDXSR.mjs +94 -0
- package/dist/chunk-XJTZDXSR.mjs.map +1 -0
- package/dist/chunk-XVUE53T3.js +361 -0
- package/dist/chunk-XVUE53T3.js.map +1 -0
- package/dist/chunk-Y364QIQH.js +139 -0
- package/dist/chunk-Y364QIQH.js.map +1 -0
- package/dist/chunk-YXM6Q4JS.mjs +94 -0
- package/dist/chunk-YXM6Q4JS.mjs.map +1 -0
- package/dist/chunk-ZDMFMUDR.js +309 -0
- package/dist/chunk-ZDMFMUDR.js.map +1 -0
- package/dist/chunk-ZVJ6NQUM.mjs +82 -0
- package/dist/chunk-ZVJ6NQUM.mjs.map +1 -0
- package/dist/color.d.mts +74 -0
- package/dist/color.d.ts +74 -0
- package/dist/color.js +40 -0
- package/dist/color.js.map +1 -0
- package/dist/color.mjs +3 -0
- package/dist/color.mjs.map +1 -0
- package/dist/crypto.d.mts +92 -0
- package/dist/crypto.d.ts +92 -0
- package/dist/crypto.js +60 -0
- package/dist/crypto.js.map +1 -0
- package/dist/crypto.mjs +3 -0
- package/dist/crypto.mjs.map +1 -0
- package/dist/data-structure.d.mts +213 -0
- package/dist/data-structure.d.ts +213 -0
- package/dist/data-structure.js +32 -0
- package/dist/data-structure.js.map +1 -0
- package/dist/data-structure.mjs +3 -0
- package/dist/data-structure.mjs.map +1 -0
- package/dist/date.d.mts +108 -0
- package/dist/date.d.ts +108 -0
- package/dist/date.js +72 -0
- package/dist/date.js.map +1 -0
- package/dist/date.mjs +3 -0
- package/dist/date.mjs.map +1 -0
- package/dist/dom.d.mts +92 -0
- package/dist/dom.d.ts +92 -0
- package/dist/dom.js +56 -0
- package/dist/dom.js.map +1 -0
- package/dist/dom.mjs +3 -0
- package/dist/dom.mjs.map +1 -0
- package/dist/file.d.mts +44 -0
- package/dist/file.d.ts +44 -0
- package/dist/file.js +32 -0
- package/dist/file.js.map +1 -0
- package/dist/file.mjs +3 -0
- package/dist/file.mjs.map +1 -0
- package/dist/i18n.d.mts +77 -0
- package/dist/i18n.d.ts +77 -0
- package/dist/i18n.js +40 -0
- package/dist/i18n.js.map +1 -0
- package/dist/i18n.mjs +3 -0
- package/dist/i18n.mjs.map +1 -0
- package/dist/index.d.mts +155 -0
- package/dist/index.d.ts +155 -0
- package/dist/index.js +839 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +22 -0
- package/dist/index.mjs.map +1 -0
- package/dist/network.d.mts +47 -0
- package/dist/network.d.ts +47 -0
- package/dist/network.js +28 -0
- package/dist/network.js.map +1 -0
- package/dist/network.mjs +3 -0
- package/dist/network.mjs.map +1 -0
- package/dist/number.d.mts +100 -0
- package/dist/number.d.ts +100 -0
- package/dist/number.js +56 -0
- package/dist/number.js.map +1 -0
- package/dist/number.mjs +3 -0
- package/dist/number.mjs.map +1 -0
- package/dist/object.d.mts +132 -0
- package/dist/object.d.ts +132 -0
- package/dist/object.js +80 -0
- package/dist/object.js.map +1 -0
- package/dist/object.mjs +3 -0
- package/dist/object.mjs.map +1 -0
- package/dist/performance.d.mts +85 -0
- package/dist/performance.d.ts +85 -0
- package/dist/performance.js +40 -0
- package/dist/performance.js.map +1 -0
- package/dist/performance.mjs +3 -0
- package/dist/performance.mjs.map +1 -0
- package/dist/storage.d.mts +176 -0
- package/dist/storage.d.ts +176 -0
- package/dist/storage.js +33 -0
- package/dist/storage.js.map +1 -0
- package/dist/storage.mjs +4 -0
- package/dist/storage.mjs.map +1 -0
- package/dist/string.d.mts +105 -0
- package/dist/string.d.ts +105 -0
- package/dist/string.js +68 -0
- package/dist/string.js.map +1 -0
- package/dist/string.mjs +3 -0
- package/dist/string.mjs.map +1 -0
- package/dist/tracking.d.mts +182 -0
- package/dist/tracking.d.ts +182 -0
- package/dist/tracking.js +52 -0
- package/dist/tracking.js.map +1 -0
- package/dist/tracking.mjs +3 -0
- package/dist/tracking.mjs.map +1 -0
- package/dist/transform.d.mts +53 -0
- package/dist/transform.d.ts +53 -0
- package/dist/transform.js +32 -0
- package/dist/transform.js.map +1 -0
- package/dist/transform.mjs +3 -0
- package/dist/transform.mjs.map +1 -0
- package/dist/upload-DzlQtUBc.d.mts +202 -0
- package/dist/upload-DzlQtUBc.d.ts +202 -0
- package/dist/upload.d.mts +1 -0
- package/dist/upload.d.ts +1 -0
- package/dist/upload.js +17 -0
- package/dist/upload.js.map +1 -0
- package/dist/upload.mjs +4 -0
- package/dist/upload.mjs.map +1 -0
- package/dist/url.d.mts +82 -0
- package/dist/url.d.ts +82 -0
- package/dist/url.js +44 -0
- package/dist/url.js.map +1 -0
- package/dist/url.mjs +3 -0
- package/dist/url.mjs.map +1 -0
- package/dist/validation.d.mts +83 -0
- package/dist/validation.d.ts +83 -0
- package/dist/validation.js +60 -0
- package/dist/validation.js.map +1 -0
- package/dist/validation.mjs +3 -0
- package/dist/validation.mjs.map +1 -0
- package/package.json +170 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/helper/tracking.ts"],"names":[],"mappings":";AAsEO,IAAM,UAAN,MAAc;AAAA,EAgBnB,YAAY,OAAA,EAAyB;AARrC,IAAA,IAAA,CAAQ,aAA8B,EAAC;AACvC,IAAA,IAAA,CAAQ,UAAA,GAAmD,IAAA;AAC3D,IAAA,IAAA,CAAQ,WAAoC,EAAC;AAE7C,IAAA,IAAA,CAAQ,iBAAA,uBAA2D,GAAA,EAAI;AACvE,IAAA,IAAA,CAAQ,cAAA,uBAAiE,GAAA,EAAI;AAC7E,IAAA,IAAA,CAAQ,eAAA,uBAAoC,GAAA,EAAI;AAG9C,IAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,IAAY,CAAC,QAAQ,UAAA,EAAY;AAC5C,MAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,IAClE;AAEA,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,QAAA,EAAU,QAAQ,QAAA,IAAY,EAAA;AAAA,MAC9B,SAAA,EAAW,QAAQ,SAAA,IAAa,EAAA;AAAA,MAChC,UAAA,EAAY,QAAQ,UAAA,IAAc,GAAA;AAAA,MAClC,iBAAA,EAAmB,QAAQ,iBAAA,IAAqB,IAAA;AAAA,MAChD,cAAA,EAAgB,QAAQ,cAAA,IAAkB,KAAA;AAAA,MAC1C,YAAA,EAAc,OAAA,CAAQ,YAAA,IAAgB,EAAC;AAAA,MACvC,YAAY,OAAA,CAAQ,UAAA;AAAA,MACpB,KAAA,EAAO,QAAQ,KAAA,IAAS;AAAA,KAC1B;AAGA,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,iBAAA,EAAkB;AAGxC,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,iBAAA,IAAqB,OAAO,WAAW,WAAA,EAAa;AACnE,MAAA,IAAA,CAAK,aAAA,EAAc;AAEnB,MAAA,IAAA,CAAK,qBAAA,EAAsB;AAAA,IAC7B;AAGA,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,cAAA,IAAkB,OAAO,WAAW,WAAA,EAAa;AAChE,MAAA,IAAA,CAAK,kBAAA,EAAmB;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAA,GAA4B;AAClC,IAAA,OAAO,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,IAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAA,GACkD;AACxD,IAAA,MAAM,IAAA,GACsD;AAAA,MAC1D,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,GAAG,KAAK,OAAA,CAAQ,YAAA;AAAA,MAChB,GAAG,IAAA,CAAK;AAAA,KACV;AAEA,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,IAAA,CAAK,GAAA,GAAM,OAAO,QAAA,CAAS,IAAA;AAC3B,MAAA,IAAA,CAAK,YAAY,SAAA,CAAU,SAAA;AAAA,IAC7B;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,QAAQ,KAAA,EAA4B;AAC1C,IAAA,IAAA,CAAK,UAAA,CAAW,KAAK,KAAK,CAAA;AAE1B,IAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,GAAA,CAAI,6BAA6B,KAAK,CAAA;AAAA,IAChD;AAGA,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,IAAU,IAAA,CAAK,QAAQ,SAAA,EAAW;AACpD,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb,CAAA,MAAO;AAEL,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAA,GAAsB;AAC5B,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,YAAA,CAAa,KAAK,UAAU,CAAA;AAAA,IAC9B;AAEA,IAAA,IAAA,CAAK,UAAA,GAAa,WAAW,MAAM;AACjC,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb,CAAA,EAAG,IAAA,CAAK,OAAA,CAAQ,UAAU,CAAA;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,WAAW,MAAA,EAAwC;AAC/D,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AAEzB,IAAA,IAAI;AACF,MAAA,IAAI,IAAA,CAAK,QAAQ,UAAA,EAAY;AAC3B,QAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,UAAA,CAAW,MAAM,CAAA;AAAA,MACtC,CAAA,MAAA,IAAW,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU;AAChC,QAAA,MAAM,IAAA,CAAK,eAAe,MAAM,CAAA;AAAA,MAClC;AAEA,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,GAAA,CAAI,0BAA0B,MAAM,CAAA;AAAA,MAC9C;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,oCAAoC,KAAK,CAAA;AAEvD,MAAA,IAAA,CAAK,UAAA,CAAW,OAAA,CAAQ,GAAG,MAAM,CAAA;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAe,MAAA,EAAwC;AACnE,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,IAAA,CAAK,QAAQ,QAAA,EAAU;AAAA,MAClD,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB;AAAA,OAClB;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,QAAQ;AAAA,KAChC,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuB,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,YAAA,CAAa,KAAK,UAAU,CAAA;AAC5B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AAEA,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAElC,IAAA,MAAM,MAAA,GAAS,CAAC,GAAG,IAAA,CAAK,UAAU,CAAA;AAClC,IAAA,IAAA,CAAK,aAAa,EAAC;AAEnB,IAAA,MAAM,IAAA,CAAK,WAAW,MAAM,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,CAAW,MAAc,MAAA,EAAwC;AAC/D,IAAA,MAAM,KAAA,GAAuB;AAAA,MAC3B,IAAA,EAAM,OAAA;AAAA,MACN,IAAA;AAAA,MACA,MAAA;AAAA,MACA,GAAG,KAAK,aAAA;AAAc,KACxB;AAEA,IAAA,IAAA,CAAK,QAAQ,KAAK,CAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,MAAA,EAAwC;AACpD,IAAA,MAAM,KAAA,GAAuB;AAAA,MAC3B,IAAA,EAAM,UAAA;AAAA,MACN,IAAA,EAAM,UAAA;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,MAAM,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,QAAA,GAAW,MAAA;AAAA,QACjE,QAAQ,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,MAAA;AAAA,QACjE,MAAM,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,IAAA,GAAO,MAAA;AAAA,QAC7D,GAAG;AAAA,OACL;AAAA,MACA,GAAG,KAAK,aAAA;AAAc,KACxB;AAEA,IAAA,IAAA,CAAK,QAAQ,KAAK,CAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,CAAW,SAA2B,MAAA,EAAwC;AAC5E,IAAA,MAAM,KAAK,OAAO,OAAA,KAAY,WAAW,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,GAAI,OAAA;AAC3E,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,IAAA,CAAK,gCAAgC,OAAO,CAAA;AAAA,MACtD;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAuB;AAAA,MAC3B,IAAA,EAAM,OAAA;AAAA,MACN,IAAA,EAAM,OAAA;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,OAAA,EAAS,EAAA,CAAG,OAAA,CAAQ,WAAA,EAAY;AAAA,QAChC,EAAA,EAAI,GAAG,EAAA,IAAM,MAAA;AAAA,QACb,SAAA,EAAW,GAAG,SAAA,IAAa,MAAA;AAAA,QAC3B,IAAA,EAAM,GAAG,WAAA,EAAa,IAAA,GAAO,SAAA,CAAU,CAAA,EAAG,GAAG,CAAA,IAAK,MAAA;AAAA,QAClD,GAAG;AAAA,OACL;AAAA,MACA,GAAG,KAAK,aAAA;AAAc,KACxB;AAEA,IAAA,IAAA,CAAK,QAAQ,KAAK,CAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,CACE,OAAA,EACA,OAAA,EACA,MAAA,EACM;AACN,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,CAAC,OAAO,oBAAA,EAAsB;AACjE,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,KAAK,iDAAiD,CAAA;AAAA,MAChE;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAK,OAAO,OAAA,KAAY,WAAW,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,GAAI,OAAA;AAC3E,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,QAAA,OAAA,CAAQ,IAAA,CAAK,gCAAgC,OAAO,CAAA;AAAA,MACtD;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,EAAE,YAAY,GAAA,EAAK,QAAA,GAAW,KAAM,IAAA,GAAO,IAAA,EAAK,GAAI,OAAA,IAAW,EAAC;AAEtE,IAAA,MAAM,SAAA,GAAY,GAAG,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,QAAQ,CAAA,CAAA;AAGhD,IAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,EAAE,CAAA,EAAG;AACxC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,aAAA,GAAsD,IAAA;AAC1D,IAAA,IAAI,SAAA,GAA2B,IAAA;AAE/B,IAAA,MAAM,WAAW,IAAI,oBAAA;AAAA,MACnB,CAAA,OAAA,KAAW;AACT,QAAA,OAAA,CAAQ,QAAQ,CAAA,KAAA,KAAS;AACvB,UAAA,IAAI,KAAA,CAAM,cAAA,IAAkB,KAAA,CAAM,iBAAA,IAAqB,SAAA,EAAW;AAEhE,YAAA,IAAI,CAAC,SAAA,EAAW;AACd,cAAA,SAAA,GAAY,KAAK,GAAA,EAAI;AACrB,cAAA,MAAM,gBAAA,GAAmB,SAAA;AACzB,cAAA,aAAA,GAAgB,WAAW,MAAM;AAE/B,gBAAA,MAAM,KAAA,GAAuB;AAAA,kBAC3B,IAAA,EAAM,UAAA;AAAA,kBACN,IAAA,EAAM,UAAA;AAAA,kBACN,MAAA,EAAQ;AAAA,oBACN,OAAA,EAAS,EAAA,CAAG,OAAA,CAAQ,WAAA,EAAY;AAAA,oBAChC,EAAA,EAAI,GAAG,EAAA,IAAM,MAAA;AAAA,oBACb,SAAA,EAAW,GAAG,SAAA,IAAa,MAAA;AAAA,oBAC3B,QAAA,EAAU,gBAAA,GAAmB,IAAA,CAAK,GAAA,KAAQ,gBAAA,GAAmB,QAAA;AAAA,oBAC7D,GAAG;AAAA,mBACL;AAAA,kBACA,GAAG,KAAK,aAAA;AAAc,iBACxB;AAEA,gBAAA,IAAA,CAAK,QAAQ,KAAK,CAAA;AAClB,gBAAA,IAAA,CAAK,eAAA,CAAgB,IAAI,EAAE,CAAA;AAG3B,gBAAA,QAAA,CAAS,UAAA,EAAW;AACpB,gBAAA,IAAA,CAAK,iBAAA,CAAkB,OAAO,SAAS,CAAA;AACvC,gBAAA,IAAI,aAAA,EAAe;AACjB,kBAAA,YAAA,CAAa,aAAa,CAAA;AAC1B,kBAAA,IAAA,CAAK,cAAA,CAAe,OAAO,SAAS,CAAA;AAAA,gBACtC;AAAA,cACF,GAAG,QAAQ,CAAA;AACX,cAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,SAAA,EAAW,aAAa,CAAA;AAAA,YAClD;AAAA,UACF,CAAA,MAAO;AAEL,YAAA,IAAI,aAAA,EAAe;AACjB,cAAA,YAAA,CAAa,aAAa,CAAA;AAC1B,cAAA,IAAA,CAAK,cAAA,CAAe,OAAO,SAAS,CAAA;AAAA,YACtC;AACA,YAAA,SAAA,GAAY,IAAA;AAAA,UACd;AAAA,QACF,CAAC,CAAA;AAAA,MACH,CAAA;AAAA,MACA;AAAA,QACE,SAAA,EAAW,CAAC,SAAS;AAAA;AACvB,KACF;AAEA,IAAA,QAAA,CAAS,QAAQ,EAAE,CAAA;AACnB,IAAA,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,SAAA,EAAW,QAAQ,CAAA;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,QAAA,EAAyC;AACnD,IAAA,IAAA,CAAK,WAAW,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,QAAA,EAAS;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,MAAA,EAAuC;AACrD,IAAA,IAAA,CAAK,OAAA,CAAQ,eAAe,EAAE,GAAG,KAAK,OAAA,CAAQ,YAAA,EAAc,GAAG,MAAA,EAAO;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAA,GAA8B;AACpC,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAGnC,IAAA,MAAA,CAAO,gBAAA,CAAiB,YAAY,MAAM;AACxC,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB,CAAC,CAAA;AAGD,IAAA,MAAM,oBAAoB,OAAA,CAAQ,SAAA;AAClC,IAAA,MAAM,uBAAuB,OAAA,CAAQ,YAAA;AAErC,IAAA,OAAA,CAAQ,SAAA,GAAY,YAAa,IAAA,EAAM;AACrC,MAAA,iBAAA,CAAkB,KAAA,CAAM,SAAS,IAAI,CAAA;AACrC,MAAA,MAAA,CAAO,aAAA,CAAc,IAAI,KAAA,CAAM,WAAW,CAAC,CAAA;AAAA,IAC7C,CAAA;AAEA,IAAA,OAAA,CAAQ,YAAA,GAAe,YAAa,IAAA,EAAM;AACxC,MAAA,oBAAA,CAAqB,KAAA,CAAM,SAAS,IAAI,CAAA;AACxC,MAAA,MAAA,CAAO,aAAA,CAAc,IAAI,KAAA,CAAM,cAAc,CAAC,CAAA;AAAA,IAChD,CAAA;AAEA,IAAA,MAAA,CAAO,gBAAA,CAAiB,aAAa,MAAM;AACzC,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,gBAAA,CAAiB,gBAAgB,MAAM;AAC5C,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAA,GAA2B;AACjC,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,aAAa,WAAA,EAAa;AAEtE,IAAA,QAAA,CAAS,gBAAA;AAAA,MACP,OAAA;AAAA,MACA,CAAA,KAAA,KAAS;AACP,QAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,QAAA,IAAI,MAAA,EAAQ;AACV,UAAA,IAAA,CAAK,WAAW,MAAM,CAAA;AAAA,QACxB;AAAA,MACF,CAAA;AAAA,MACA;AAAA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AAEd,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,YAAA,CAAa,KAAK,UAAU,CAAA;AAC5B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AAGA,IAAA,IAAA,CAAK,iBAAA,CAAkB,OAAA,CAAQ,CAAA,QAAA,KAAY,QAAA,CAAS,YAAY,CAAA;AAChE,IAAA,IAAA,CAAK,kBAAkB,KAAA,EAAM;AAG7B,IAAA,IAAA,CAAK,cAAA,CAAe,OAAA,CAAQ,CAAA,KAAA,KAAS,YAAA,CAAa,KAAK,CAAC,CAAA;AACxD,IAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAG1B,IAAA,IAAA,CAAK,KAAA,EAAM,CAAE,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,EAClC;AACF;AAKO,SAAS,cAAc,OAAA,EAAkC;AAC9D,EAAA,OAAO,IAAI,QAAQ,OAAO,CAAA;AAC5B;AAKA,IAAI,cAAA,GAAiC,IAAA;AAK9B,SAAS,YAAY,OAAA,EAAkC;AAC5D,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,OAAA,CAAQ,KAAK,+CAA+C,CAAA;AAC5D,IAAA,OAAO,cAAA;AAAA,EACT;AACA,EAAA,cAAA,GAAiB,IAAI,QAAQ,OAAO,CAAA;AACpC,EAAA,OAAO,cAAA;AACT;AAKO,SAAS,UAAA,GAAsB;AACpC,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,MAAM,IAAI,MAAM,oDAAoD,CAAA;AAAA,EACtE;AACA,EAAA,OAAO,cAAA;AACT;AAKO,SAAS,UAAA,CAAW,MAAc,MAAA,EAAwC;AAC/E,EAAA,UAAA,EAAW,CAAE,UAAA,CAAW,IAAA,EAAM,MAAM,CAAA;AACtC;AAKO,SAAS,cAAc,MAAA,EAAwC;AACpE,EAAA,UAAA,EAAW,CAAE,cAAc,MAAM,CAAA;AACnC;AAKO,SAAS,UAAA,CAAW,SAA2B,MAAA,EAAwC;AAC5F,EAAA,UAAA,EAAW,CAAE,UAAA,CAAW,OAAA,EAAS,MAAM,CAAA;AACzC;AAKO,SAAS,aAAA,CACd,OAAA,EACA,OAAA,EACA,MAAA,EACM;AACN,EAAA,UAAA,EAAW,CAAE,aAAA,CAAc,OAAA,EAAS,OAAA,EAAS,MAAM,CAAA;AACrD;AAKO,SAAS,YAAY,QAAA,EAAyC;AACnE,EAAA,UAAA,EAAW,CAAE,YAAY,QAAQ,CAAA;AACnC;AAKO,SAAS,gBAAgB,MAAA,EAAuC;AACrE,EAAA,UAAA,EAAW,CAAE,gBAAgB,MAAM,CAAA;AACrC;AAKA,eAAsB,KAAA,GAAuB;AAC3C,EAAA,MAAM,UAAA,GAAa,KAAA,EAAM;AAC3B","file":"chunk-PJ7UCTX4.mjs","sourcesContent":["/**\n * 埋点追踪工具\n */\n\n/**\n * 埋点事件类型\n */\nexport type TrackingEventType = 'event' | 'pageview' | 'click' | 'exposure' | 'custom';\n\n/**\n * 埋点事件数据\n */\nexport interface TrackingEvent {\n /** 事件类型 */\n type: TrackingEventType;\n /** 事件名称 */\n name: string;\n /** 事件参数 */\n params?: Record<string, unknown>;\n /** 时间戳 */\n timestamp: number;\n /** 页面URL */\n url?: string;\n /** 用户代理 */\n userAgent?: string;\n /** 用户ID */\n userId?: string;\n /** 会话ID */\n sessionId?: string;\n /** 其他自定义字段 */\n [key: string]: unknown;\n}\n\n/**\n * 埋点配置选项\n */\nexport interface TrackerOptions {\n /** 上报接口URL */\n endpoint: string;\n /** 批量上报大小,默认10 */\n batchSize?: number;\n /** 批量上报延迟(毫秒),默认3000 */\n batchDelay?: number;\n /** 是否自动追踪页面浏览,默认true */\n autoTrackPageView?: boolean;\n /** 是否自动追踪点击事件,默认false */\n autoTrackClick?: boolean;\n /** 公共参数 */\n commonParams?: Record<string, unknown>;\n /** 自定义上报函数 */\n customSend?: (events: TrackingEvent[]) => Promise<void>;\n /** 是否启用调试模式,默认false */\n debug?: boolean;\n}\n\n/**\n * 曝光追踪选项\n */\nexport interface ExposureOptions {\n /** 曝光阈值(0-1),元素可见比例达到此值才触发,默认0.5 */\n threshold?: number;\n /** 曝光时长(毫秒),元素可见时长达到此值才触发,默认1000 */\n duration?: number;\n /** 是否只触发一次,默认true */\n once?: boolean;\n}\n\n/**\n * 埋点追踪器类\n */\nexport class Tracker {\n private options: Required<\n Pick<\n TrackerOptions,\n 'batchSize' | 'batchDelay' | 'autoTrackPageView' | 'autoTrackClick' | 'debug'\n >\n > &\n Pick<TrackerOptions, 'endpoint' | 'commonParams' | 'customSend'>;\n private eventQueue: TrackingEvent[] = [];\n private batchTimer: ReturnType<typeof setTimeout> | null = null;\n private userInfo: Record<string, unknown> = {};\n private sessionId: string;\n private exposureObservers: Map<string, IntersectionObserver> = new Map();\n private exposureTimers: Map<string, ReturnType<typeof setTimeout>> = new Map();\n private exposedElements: Set<Element> = new Set();\n\n constructor(options: TrackerOptions) {\n if (!options.endpoint && !options.customSend) {\n throw new Error('Either endpoint or customSend must be provided');\n }\n\n this.options = {\n endpoint: options.endpoint || '',\n batchSize: options.batchSize ?? 10,\n batchDelay: options.batchDelay ?? 3000,\n autoTrackPageView: options.autoTrackPageView ?? true,\n autoTrackClick: options.autoTrackClick ?? false,\n commonParams: options.commonParams || {},\n customSend: options.customSend,\n debug: options.debug ?? false,\n };\n\n // 生成会话ID\n this.sessionId = this.generateSessionId();\n\n // 自动追踪页面浏览\n if (this.options.autoTrackPageView && typeof window !== 'undefined') {\n this.trackPageView();\n // 监听路由变化(SPA应用)\n this.setupPageViewListener();\n }\n\n // 自动追踪点击事件\n if (this.options.autoTrackClick && typeof window !== 'undefined') {\n this.setupClickListener();\n }\n }\n\n /**\n * 生成会话ID\n */\n private generateSessionId(): string {\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n }\n\n /**\n * 获取公共数据\n */\n private getCommonData(): Pick<TrackingEvent, 'timestamp' | 'sessionId'> &\n Partial<Omit<TrackingEvent, 'timestamp' | 'sessionId'>> {\n const data: Pick<TrackingEvent, 'timestamp' | 'sessionId'> &\n Partial<Omit<TrackingEvent, 'timestamp' | 'sessionId'>> = {\n timestamp: Date.now(),\n sessionId: this.sessionId,\n ...this.options.commonParams,\n ...this.userInfo,\n };\n\n if (typeof window !== 'undefined') {\n data.url = window.location.href;\n data.userAgent = navigator.userAgent;\n }\n\n return data;\n }\n\n /**\n * 添加事件到队列\n */\n private enqueue(event: TrackingEvent): void {\n this.eventQueue.push(event);\n\n if (this.options.debug) {\n console.log('[Tracker] Event enqueued:', event);\n }\n\n // 如果队列达到批量大小,立即上报\n if (this.eventQueue.length >= this.options.batchSize) {\n this.flush();\n } else {\n // 否则设置延迟上报\n this.scheduleBatch();\n }\n }\n\n /**\n * 安排批量上报\n */\n private scheduleBatch(): void {\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n }\n\n this.batchTimer = setTimeout(() => {\n this.flush();\n }, this.options.batchDelay);\n }\n\n /**\n * 上报事件\n */\n private async sendEvents(events: TrackingEvent[]): Promise<void> {\n if (events.length === 0) return;\n\n try {\n if (this.options.customSend) {\n await this.options.customSend(events);\n } else if (this.options.endpoint) {\n await this.sendToEndpoint(events);\n }\n\n if (this.options.debug) {\n console.log('[Tracker] Events sent:', events);\n }\n } catch (error) {\n console.error('[Tracker] Failed to send events:', error);\n // 失败后重新加入队列(可选:限制重试次数)\n this.eventQueue.unshift(...events);\n }\n }\n\n /**\n * 发送到上报接口\n */\n private async sendToEndpoint(events: TrackingEvent[]): Promise<void> {\n const response = await fetch(this.options.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ events }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n }\n\n /**\n * 立即上报所有待上报事件\n */\n async flush(): Promise<void> {\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n if (this.eventQueue.length === 0) return;\n\n const events = [...this.eventQueue];\n this.eventQueue = [];\n\n await this.sendEvents(events);\n }\n\n /**\n * 追踪事件\n */\n trackEvent(name: string, params?: Record<string, unknown>): void {\n const event: TrackingEvent = {\n type: 'event',\n name,\n params,\n ...this.getCommonData(),\n };\n\n this.enqueue(event);\n }\n\n /**\n * 追踪页面浏览\n */\n trackPageView(params?: Record<string, unknown>): void {\n const event: TrackingEvent = {\n type: 'pageview',\n name: 'pageview',\n params: {\n path: typeof window !== 'undefined' ? window.location.pathname : undefined,\n search: typeof window !== 'undefined' ? window.location.search : undefined,\n hash: typeof window !== 'undefined' ? window.location.hash : undefined,\n ...params,\n },\n ...this.getCommonData(),\n };\n\n this.enqueue(event);\n }\n\n /**\n * 追踪点击事件\n */\n trackClick(element: Element | string, params?: Record<string, unknown>): void {\n const el = typeof element === 'string' ? document.querySelector(element) : element;\n if (!el) {\n if (this.options.debug) {\n console.warn('[Tracker] Element not found:', element);\n }\n return;\n }\n\n const event: TrackingEvent = {\n type: 'click',\n name: 'click',\n params: {\n element: el.tagName.toLowerCase(),\n id: el.id || undefined,\n className: el.className || undefined,\n text: el.textContent?.trim().substring(0, 100) || undefined,\n ...params,\n },\n ...this.getCommonData(),\n };\n\n this.enqueue(event);\n }\n\n /**\n * 追踪曝光事件\n */\n trackExposure(\n element: Element | string,\n options?: ExposureOptions,\n params?: Record<string, unknown>\n ): void {\n if (typeof window === 'undefined' || !window.IntersectionObserver) {\n if (this.options.debug) {\n console.warn('[Tracker] IntersectionObserver is not supported');\n }\n return;\n }\n\n const el = typeof element === 'string' ? document.querySelector(element) : element;\n if (!el) {\n if (this.options.debug) {\n console.warn('[Tracker] Element not found:', element);\n }\n return;\n }\n\n const { threshold = 0.5, duration = 1000, once = true } = options || {};\n\n const elementId = `${Date.now()}-${Math.random()}`;\n\n // 如果已经曝光过且只触发一次,直接返回\n if (once && this.exposedElements.has(el)) {\n return;\n }\n\n let exposureTimer: ReturnType<typeof setTimeout> | null = null;\n let startTime: number | null = null;\n\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.intersectionRatio >= threshold) {\n // 开始计时\n if (!startTime) {\n startTime = Date.now();\n const currentStartTime = startTime;\n exposureTimer = setTimeout(() => {\n // 触发曝光事件\n const event: TrackingEvent = {\n type: 'exposure',\n name: 'exposure',\n params: {\n element: el.tagName.toLowerCase(),\n id: el.id || undefined,\n className: el.className || undefined,\n duration: currentStartTime ? Date.now() - currentStartTime : duration,\n ...params,\n },\n ...this.getCommonData(),\n };\n\n this.enqueue(event);\n this.exposedElements.add(el);\n\n // 清理\n observer.disconnect();\n this.exposureObservers.delete(elementId);\n if (exposureTimer) {\n clearTimeout(exposureTimer);\n this.exposureTimers.delete(elementId);\n }\n }, duration);\n this.exposureTimers.set(elementId, exposureTimer);\n }\n } else {\n // 不可见,重置计时\n if (exposureTimer) {\n clearTimeout(exposureTimer);\n this.exposureTimers.delete(elementId);\n }\n startTime = null;\n }\n });\n },\n {\n threshold: [threshold],\n }\n );\n\n observer.observe(el);\n this.exposureObservers.set(elementId, observer);\n }\n\n /**\n * 设置用户信息\n */\n setUserInfo(userInfo: Record<string, unknown>): void {\n this.userInfo = { ...this.userInfo, ...userInfo };\n }\n\n /**\n * 设置公共参数\n */\n setCommonParams(params: Record<string, unknown>): void {\n this.options.commonParams = { ...this.options.commonParams, ...params };\n }\n\n /**\n * 设置页面浏览监听器(SPA应用)\n */\n private setupPageViewListener(): void {\n if (typeof window === 'undefined') return;\n\n // 监听popstate事件(浏览器前进后退)\n window.addEventListener('popstate', () => {\n this.trackPageView();\n });\n\n // 监听pushState和replaceState(需要重写history方法)\n const originalPushState = history.pushState;\n const originalReplaceState = history.replaceState;\n\n history.pushState = function (...args) {\n originalPushState.apply(history, args);\n window.dispatchEvent(new Event('pushstate'));\n };\n\n history.replaceState = function (...args) {\n originalReplaceState.apply(history, args);\n window.dispatchEvent(new Event('replacestate'));\n };\n\n window.addEventListener('pushstate', () => {\n this.trackPageView();\n });\n\n window.addEventListener('replacestate', () => {\n this.trackPageView();\n });\n }\n\n /**\n * 设置点击事件监听器\n */\n private setupClickListener(): void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\n\n document.addEventListener(\n 'click',\n event => {\n const target = event.target as Element;\n if (target) {\n this.trackClick(target);\n }\n },\n true // 使用捕获阶段\n );\n }\n\n /**\n * 清理资源\n */\n destroy(): void {\n // 清理定时器\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n // 清理曝光观察器\n this.exposureObservers.forEach(observer => observer.disconnect());\n this.exposureObservers.clear();\n\n // 清理曝光定时器\n this.exposureTimers.forEach(timer => clearTimeout(timer));\n this.exposureTimers.clear();\n\n // 上报剩余事件\n this.flush().catch(console.error);\n }\n}\n\n/**\n * 创建埋点追踪器实例\n */\nexport function createTracker(options: TrackerOptions): Tracker {\n return new Tracker(options);\n}\n\n/**\n * 默认追踪器实例(单例模式)\n */\nlet defaultTracker: Tracker | null = null;\n\n/**\n * 初始化默认追踪器\n */\nexport function initTracker(options: TrackerOptions): Tracker {\n if (defaultTracker) {\n console.warn('[Tracker] Default tracker already initialized');\n return defaultTracker;\n }\n defaultTracker = new Tracker(options);\n return defaultTracker;\n}\n\n/**\n * 获取默认追踪器\n */\nexport function getTracker(): Tracker {\n if (!defaultTracker) {\n throw new Error('Tracker not initialized. Call initTracker() first.');\n }\n return defaultTracker;\n}\n\n/**\n * 追踪事件(使用默认追踪器)\n */\nexport function trackEvent(name: string, params?: Record<string, unknown>): void {\n getTracker().trackEvent(name, params);\n}\n\n/**\n * 追踪页面浏览(使用默认追踪器)\n */\nexport function trackPageView(params?: Record<string, unknown>): void {\n getTracker().trackPageView(params);\n}\n\n/**\n * 追踪点击事件(使用默认追踪器)\n */\nexport function trackClick(element: Element | string, params?: Record<string, unknown>): void {\n getTracker().trackClick(element, params);\n}\n\n/**\n * 追踪曝光事件(使用默认追踪器)\n */\nexport function trackExposure(\n element: Element | string,\n options?: ExposureOptions,\n params?: Record<string, unknown>\n): void {\n getTracker().trackExposure(element, options, params);\n}\n\n/**\n * 设置用户信息(使用默认追踪器)\n */\nexport function setUserInfo(userInfo: Record<string, unknown>): void {\n getTracker().setUserInfo(userInfo);\n}\n\n/**\n * 设置公共参数(使用默认追踪器)\n */\nexport function setCommonParams(params: Record<string, unknown>): void {\n getTracker().setCommonParams(params);\n}\n\n/**\n * 立即上报(使用默认追踪器)\n */\nexport async function flush(): Promise<void> {\n await getTracker().flush();\n}\n"]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// src/format/i18n.ts
|
|
2
|
+
function getLocale() {
|
|
3
|
+
if (typeof navigator !== "undefined" && navigator.language) {
|
|
4
|
+
return navigator.language;
|
|
5
|
+
}
|
|
6
|
+
return "en-US";
|
|
7
|
+
}
|
|
8
|
+
function formatNumberI18n(value, locale, options) {
|
|
9
|
+
const loc = locale || getLocale();
|
|
10
|
+
return new Intl.NumberFormat(loc, options).format(value);
|
|
11
|
+
}
|
|
12
|
+
function formatDateI18n(date, locale, options) {
|
|
13
|
+
const loc = locale || getLocale();
|
|
14
|
+
const dateObj = typeof date === "number" ? new Date(date) : date;
|
|
15
|
+
return new Intl.DateTimeFormat(loc, options).format(dateObj);
|
|
16
|
+
}
|
|
17
|
+
function formatCurrencyI18n(value, currency, locale, options) {
|
|
18
|
+
const loc = locale || getLocale();
|
|
19
|
+
return new Intl.NumberFormat(loc, {
|
|
20
|
+
style: "currency",
|
|
21
|
+
currency,
|
|
22
|
+
...options
|
|
23
|
+
}).format(value);
|
|
24
|
+
}
|
|
25
|
+
function translate(key, dictionary, defaultValue) {
|
|
26
|
+
const keys = key.split(".");
|
|
27
|
+
let current = dictionary;
|
|
28
|
+
for (const k of keys) {
|
|
29
|
+
if (typeof current === "object" && current !== null && k in current) {
|
|
30
|
+
current = current[k];
|
|
31
|
+
} else {
|
|
32
|
+
return defaultValue || key;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (typeof current === "string") {
|
|
36
|
+
return current;
|
|
37
|
+
}
|
|
38
|
+
return defaultValue || key;
|
|
39
|
+
}
|
|
40
|
+
function createTranslator(dictionary) {
|
|
41
|
+
return (key, defaultValue) => {
|
|
42
|
+
return translate(key, dictionary, defaultValue);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function formatRelativeTime(date, locale) {
|
|
46
|
+
const loc = locale || getLocale();
|
|
47
|
+
const dateObj = typeof date === "number" ? new Date(date) : date;
|
|
48
|
+
const now = /* @__PURE__ */ new Date();
|
|
49
|
+
const diffInSeconds = Math.floor((now.getTime() - dateObj.getTime()) / 1e3);
|
|
50
|
+
const rtf = new Intl.RelativeTimeFormat(loc, { numeric: "auto" });
|
|
51
|
+
const intervals = [
|
|
52
|
+
{ unit: "year", seconds: 31536e3 },
|
|
53
|
+
{ unit: "month", seconds: 2592e3 },
|
|
54
|
+
{ unit: "week", seconds: 604800 },
|
|
55
|
+
{ unit: "day", seconds: 86400 },
|
|
56
|
+
{ unit: "hour", seconds: 3600 },
|
|
57
|
+
{ unit: "minute", seconds: 60 },
|
|
58
|
+
{ unit: "second", seconds: 1 }
|
|
59
|
+
];
|
|
60
|
+
for (const interval of intervals) {
|
|
61
|
+
const count = Math.floor(Math.abs(diffInSeconds) / interval.seconds);
|
|
62
|
+
if (count >= 1) {
|
|
63
|
+
return rtf.format(diffInSeconds < 0 ? count : -count, interval.unit);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return rtf.format(0, "second");
|
|
67
|
+
}
|
|
68
|
+
function pluralize(count, singular, plural, locale) {
|
|
69
|
+
const loc = locale || getLocale();
|
|
70
|
+
const pluralForm = plural || `${singular}s`;
|
|
71
|
+
const pluralRules = new Intl.PluralRules(loc);
|
|
72
|
+
const rule = pluralRules.select(count);
|
|
73
|
+
if (rule === "one" || count === 1) {
|
|
74
|
+
return `${count} ${singular}`;
|
|
75
|
+
}
|
|
76
|
+
return `${count} ${pluralForm}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { createTranslator, formatCurrencyI18n, formatDateI18n, formatNumberI18n, formatRelativeTime, getLocale, pluralize, translate };
|
|
80
|
+
//# sourceMappingURL=chunk-QIBE7GVN.mjs.map
|
|
81
|
+
//# sourceMappingURL=chunk-QIBE7GVN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/format/i18n.ts"],"names":[],"mappings":"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","file":"chunk-QIBE7GVN.mjs","sourcesContent":["/**\n * 国际化工具函数\n */\n\n/**\n * 语言环境类型\n */\nexport type Locale = string;\n\n/**\n * 货币代码类型(ISO 4217)\n */\nexport type CurrencyCode = string;\n\n/**\n * 获取当前语言环境\n * @returns 语言环境字符串(如 'zh-CN', 'en-US')\n */\nexport function getLocale(): Locale {\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language;\n }\n return 'en-US';\n}\n\n/**\n * 数字本地化格式化\n * @param value - 数字值\n * @param locale - 语言环境,默认为当前环境\n * @param options - Intl.NumberFormat选项\n * @returns 格式化后的字符串\n */\nexport function formatNumberI18n(\n value: number,\n locale?: Locale,\n options?: Intl.NumberFormatOptions\n): string {\n const loc = locale || getLocale();\n return new Intl.NumberFormat(loc, options).format(value);\n}\n\n/**\n * 日期本地化格式化\n * @param date - 日期对象或时间戳\n * @param locale - 语言环境,默认为当前环境\n * @param options - Intl.DateTimeFormat选项\n * @returns 格式化后的字符串\n */\nexport function formatDateI18n(\n date: Date | number,\n locale?: Locale,\n options?: Intl.DateTimeFormatOptions\n): string {\n const loc = locale || getLocale();\n const dateObj = typeof date === 'number' ? new Date(date) : date;\n return new Intl.DateTimeFormat(loc, options).format(dateObj);\n}\n\n/**\n * 货币本地化格式化\n * @param value - 金额\n * @param currency - 货币代码(ISO 4217),如 'USD', 'CNY', 'EUR'\n * @param locale - 语言环境,默认为当前环境\n * @param options - Intl.NumberFormat选项\n * @returns 格式化后的货币字符串\n */\nexport function formatCurrencyI18n(\n value: number,\n currency: CurrencyCode,\n locale?: Locale,\n options?: Intl.NumberFormatOptions\n): string {\n const loc = locale || getLocale();\n return new Intl.NumberFormat(loc, {\n style: 'currency',\n currency,\n ...options,\n }).format(value);\n}\n\n/**\n * 翻译字典类型\n */\nexport type TranslationDictionary = Record<string, string | Record<string, unknown>>;\n\n/**\n * 翻译函数\n * @param key - 翻译键(支持点号分隔的嵌套键,如 'user.name')\n * @param dictionary - 翻译字典\n * @param defaultValue - 默认值(如果找不到翻译)\n * @returns 翻译后的字符串\n */\nexport function translate(\n key: string,\n dictionary: TranslationDictionary,\n defaultValue?: string\n): string {\n const keys = key.split('.');\n let current: unknown = dictionary;\n\n for (const k of keys) {\n if (typeof current === 'object' && current !== null && k in current) {\n current = (current as TranslationDictionary)[k];\n } else {\n return defaultValue || key;\n }\n }\n\n if (typeof current === 'string') {\n return current;\n }\n\n return defaultValue || key;\n}\n\n/**\n * 创建翻译函数(带预设字典)\n * @param dictionary - 翻译字典\n * @returns 翻译函数\n */\nexport function createTranslator(dictionary: TranslationDictionary) {\n return (key: string, defaultValue?: string): string => {\n return translate(key, dictionary, defaultValue);\n };\n}\n\n/**\n * 获取相对时间格式化(本地化)\n * @param date - 日期对象或时间戳\n * @param locale - 语言环境,默认为当前环境\n * @returns 格式化后的相对时间字符串\n */\nexport function formatRelativeTime(date: Date | number, locale?: Locale): string {\n const loc = locale || getLocale();\n const dateObj = typeof date === 'number' ? new Date(date) : date;\n const now = new Date();\n const diffInSeconds = Math.floor((now.getTime() - dateObj.getTime()) / 1000);\n\n const rtf = new Intl.RelativeTimeFormat(loc, { numeric: 'auto' });\n\n const intervals: Array<{ unit: Intl.RelativeTimeFormatUnit; seconds: number }> = [\n { unit: 'year', seconds: 31536000 },\n { unit: 'month', seconds: 2592000 },\n { unit: 'week', seconds: 604800 },\n { unit: 'day', seconds: 86400 },\n { unit: 'hour', seconds: 3600 },\n { unit: 'minute', seconds: 60 },\n { unit: 'second', seconds: 1 },\n ];\n\n for (const interval of intervals) {\n const count = Math.floor(Math.abs(diffInSeconds) / interval.seconds);\n if (count >= 1) {\n return rtf.format(diffInSeconds < 0 ? count : -count, interval.unit);\n }\n }\n\n return rtf.format(0, 'second');\n}\n\n/**\n * 获取复数形式(简单实现)\n * @param count - 数量\n * @param singular - 单数形式\n * @param plural - 复数形式(可选,默认为 singular + 's')\n * @param locale - 语言环境,默认为当前环境\n * @returns 格式化后的字符串\n */\nexport function pluralize(\n count: number,\n singular: string,\n plural?: string,\n locale?: Locale\n): string {\n const loc = locale || getLocale();\n const pluralForm = plural || `${singular}s`;\n\n // 使用 Intl.PluralRules 获取正确的复数形式\n const pluralRules = new Intl.PluralRules(loc);\n const rule = pluralRules.select(count);\n\n // 简单实现:大多数语言中,1 使用单数,其他使用复数\n if (rule === 'one' || count === 1) {\n return `${count} ${singular}`;\n }\n\n return `${count} ${pluralForm}`;\n}\n"]}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// src/format/color.ts
|
|
2
|
+
function hexToRgb(hex) {
|
|
3
|
+
const cleanHex = hex.replace("#", "");
|
|
4
|
+
if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex)) {
|
|
5
|
+
throw new Error("Invalid hex color format");
|
|
6
|
+
}
|
|
7
|
+
return {
|
|
8
|
+
r: parseInt(cleanHex.substring(0, 2), 16),
|
|
9
|
+
g: parseInt(cleanHex.substring(2, 4), 16),
|
|
10
|
+
b: parseInt(cleanHex.substring(4, 6), 16)
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function rgbToHex(rgb) {
|
|
14
|
+
let r;
|
|
15
|
+
let g;
|
|
16
|
+
let b;
|
|
17
|
+
if (typeof rgb === "string") {
|
|
18
|
+
const match = rgb.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
19
|
+
if (!match) {
|
|
20
|
+
throw new Error("Invalid RGB string format");
|
|
21
|
+
}
|
|
22
|
+
r = parseInt(match[1], 10);
|
|
23
|
+
g = parseInt(match[2], 10);
|
|
24
|
+
b = parseInt(match[3], 10);
|
|
25
|
+
} else {
|
|
26
|
+
r = rgb.r;
|
|
27
|
+
g = rgb.g;
|
|
28
|
+
b = rgb.b;
|
|
29
|
+
}
|
|
30
|
+
r = Math.max(0, Math.min(255, Math.round(r)));
|
|
31
|
+
g = Math.max(0, Math.min(255, Math.round(g)));
|
|
32
|
+
b = Math.max(0, Math.min(255, Math.round(b)));
|
|
33
|
+
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`.toUpperCase();
|
|
34
|
+
}
|
|
35
|
+
function rgbToHsl(rgb) {
|
|
36
|
+
const r = rgb.r / 255;
|
|
37
|
+
const g = rgb.g / 255;
|
|
38
|
+
const b = rgb.b / 255;
|
|
39
|
+
const max = Math.max(r, g, b);
|
|
40
|
+
const min = Math.min(r, g, b);
|
|
41
|
+
const delta = max - min;
|
|
42
|
+
let h = 0;
|
|
43
|
+
let s = 0;
|
|
44
|
+
const l = (max + min) / 2;
|
|
45
|
+
if (delta !== 0) {
|
|
46
|
+
s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
|
|
47
|
+
if (max === r) {
|
|
48
|
+
h = ((g - b) / delta + (g < b ? 6 : 0)) / 6;
|
|
49
|
+
} else if (max === g) {
|
|
50
|
+
h = ((b - r) / delta + 2) / 6;
|
|
51
|
+
} else {
|
|
52
|
+
h = ((r - g) / delta + 4) / 6;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
h: Math.round(h * 360),
|
|
57
|
+
s: Math.round(s * 100),
|
|
58
|
+
l: Math.round(l * 100)
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function hslToRgb(hsl) {
|
|
62
|
+
const h = hsl.h / 360;
|
|
63
|
+
const s = hsl.s / 100;
|
|
64
|
+
const l = hsl.l / 100;
|
|
65
|
+
let r;
|
|
66
|
+
let g;
|
|
67
|
+
let b;
|
|
68
|
+
if (s === 0) {
|
|
69
|
+
r = g = b = l;
|
|
70
|
+
} else {
|
|
71
|
+
const hue2rgb = (p2, q2, t) => {
|
|
72
|
+
if (t < 0) t += 1;
|
|
73
|
+
if (t > 1) t -= 1;
|
|
74
|
+
if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
|
|
75
|
+
if (t < 1 / 2) return q2;
|
|
76
|
+
if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
|
|
77
|
+
return p2;
|
|
78
|
+
};
|
|
79
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
80
|
+
const p = 2 * l - q;
|
|
81
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
82
|
+
g = hue2rgb(p, q, h);
|
|
83
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
r: Math.round(r * 255),
|
|
87
|
+
g: Math.round(g * 255),
|
|
88
|
+
b: Math.round(b * 255)
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function lighten(color, amount) {
|
|
92
|
+
const rgb = typeof color === "string" ? hexToRgb(color) : color;
|
|
93
|
+
const hsl = rgbToHsl(rgb);
|
|
94
|
+
hsl.l = Math.min(100, hsl.l + amount);
|
|
95
|
+
return rgbToHex(hslToRgb(hsl));
|
|
96
|
+
}
|
|
97
|
+
function darken(color, amount) {
|
|
98
|
+
const rgb = typeof color === "string" ? hexToRgb(color) : color;
|
|
99
|
+
const hsl = rgbToHsl(rgb);
|
|
100
|
+
hsl.l = Math.max(0, hsl.l - amount);
|
|
101
|
+
return rgbToHex(hslToRgb(hsl));
|
|
102
|
+
}
|
|
103
|
+
function mix(color1, color2, ratio) {
|
|
104
|
+
const rgb1 = hexToRgb(color1);
|
|
105
|
+
const rgb2 = hexToRgb(color2);
|
|
106
|
+
const r = Math.round(rgb1.r * (1 - ratio) + rgb2.r * ratio);
|
|
107
|
+
const g = Math.round(rgb1.g * (1 - ratio) + rgb2.g * ratio);
|
|
108
|
+
const b = Math.round(rgb1.b * (1 - ratio) + rgb2.b * ratio);
|
|
109
|
+
return rgbToHex({ r, g, b });
|
|
110
|
+
}
|
|
111
|
+
function contrast(color1, color2) {
|
|
112
|
+
const rgb1 = hexToRgb(color1);
|
|
113
|
+
const rgb2 = hexToRgb(color2);
|
|
114
|
+
const getLuminance = (rgb) => {
|
|
115
|
+
const normalize = (value) => {
|
|
116
|
+
value = value / 255;
|
|
117
|
+
return value <= 0.03928 ? value / 12.92 : Math.pow((value + 0.055) / 1.055, 2.4);
|
|
118
|
+
};
|
|
119
|
+
return 0.2126 * normalize(rgb.r) + 0.7152 * normalize(rgb.g) + 0.0722 * normalize(rgb.b);
|
|
120
|
+
};
|
|
121
|
+
const lum1 = getLuminance(rgb1);
|
|
122
|
+
const lum2 = getLuminance(rgb2);
|
|
123
|
+
const lighter = Math.max(lum1, lum2);
|
|
124
|
+
const darker = Math.min(lum1, lum2);
|
|
125
|
+
return (lighter + 0.05) / (darker + 0.05);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { contrast, darken, hexToRgb, hslToRgb, lighten, mix, rgbToHex, rgbToHsl };
|
|
129
|
+
//# sourceMappingURL=chunk-QIOC54LQ.mjs.map
|
|
130
|
+
//# sourceMappingURL=chunk-QIOC54LQ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/format/color.ts"],"names":["p","q"],"mappings":"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","file":"chunk-QIOC54LQ.mjs","sourcesContent":["/**\n * 颜色工具函数\n */\n\n/**\n * RGB颜色类型\n */\nexport interface RGB {\n r: number;\n g: number;\n b: number;\n}\n\n/**\n * HSL颜色类型\n */\nexport interface HSL {\n h: number; // 色相 (0-360)\n s: number; // 饱和度 (0-100)\n l: number; // 亮度 (0-100)\n}\n\n/**\n * 十六进制转RGB\n * @param hex - 十六进制颜色值(如 '#FF0000' 或 'FF0000')\n * @returns RGB对象\n */\nexport function hexToRgb(hex: string): RGB {\n // 移除 # 号\n const cleanHex = hex.replace('#', '');\n\n // 验证格式\n if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex)) {\n throw new Error('Invalid hex color format');\n }\n\n return {\n r: parseInt(cleanHex.substring(0, 2), 16),\n g: parseInt(cleanHex.substring(2, 4), 16),\n b: parseInt(cleanHex.substring(4, 6), 16),\n };\n}\n\n/**\n * RGB转十六进制\n * @param rgb - RGB对象或字符串(如 'rgb(255, 0, 0)')\n * @returns 十六进制颜色值(如 '#FF0000')\n */\nexport function rgbToHex(rgb: RGB | string): string {\n let r: number;\n let g: number;\n let b: number;\n\n if (typeof rgb === 'string') {\n const match = rgb.match(/rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)/);\n if (!match) {\n throw new Error('Invalid RGB string format');\n }\n r = parseInt(match[1], 10);\n g = parseInt(match[2], 10);\n b = parseInt(match[3], 10);\n } else {\n r = rgb.r;\n g = rgb.g;\n b = rgb.b;\n }\n\n // 确保值在有效范围内\n r = Math.max(0, Math.min(255, Math.round(r)));\n g = Math.max(0, Math.min(255, Math.round(g)));\n b = Math.max(0, Math.min(255, Math.round(b)));\n\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`.toUpperCase();\n}\n\n/**\n * RGB转HSL\n * @param rgb - RGB对象\n * @returns HSL对象\n */\nexport function rgbToHsl(rgb: RGB): HSL {\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const delta = max - min;\n\n let h = 0;\n let s = 0;\n const l = (max + min) / 2;\n\n if (delta !== 0) {\n s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);\n\n if (max === r) {\n h = ((g - b) / delta + (g < b ? 6 : 0)) / 6;\n } else if (max === g) {\n h = ((b - r) / delta + 2) / 6;\n } else {\n h = ((r - g) / delta + 4) / 6;\n }\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\n/**\n * HSL转RGB\n * @param hsl - HSL对象\n * @returns RGB对象\n */\nexport function hslToRgb(hsl: HSL): RGB {\n const h = hsl.h / 360;\n const s = hsl.s / 100;\n const l = hsl.l / 100;\n\n let r: number;\n let g: number;\n let b: number;\n\n if (s === 0) {\n r = g = b = l; // 无色彩\n } else {\n const hue2rgb = (p: number, q: number, t: number): number => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n };\n}\n\n/**\n * 颜色变亮\n * @param color - 十六进制颜色值或RGB对象\n * @param amount - 变亮程度(0-100)\n * @returns 新的十六进制颜色值\n */\nexport function lighten(color: string | RGB, amount: number): string {\n const rgb = typeof color === 'string' ? hexToRgb(color) : color;\n const hsl = rgbToHsl(rgb);\n\n hsl.l = Math.min(100, hsl.l + amount);\n\n return rgbToHex(hslToRgb(hsl));\n}\n\n/**\n * 颜色变暗\n * @param color - 十六进制颜色值或RGB对象\n * @param amount - 变暗程度(0-100)\n * @returns 新的十六进制颜色值\n */\nexport function darken(color: string | RGB, amount: number): string {\n const rgb = typeof color === 'string' ? hexToRgb(color) : color;\n const hsl = rgbToHsl(rgb);\n\n hsl.l = Math.max(0, hsl.l - amount);\n\n return rgbToHex(hslToRgb(hsl));\n}\n\n/**\n * 颜色混合\n * @param color1 - 第一个颜色(十六进制)\n * @param color2 - 第二个颜色(十六进制)\n * @param ratio - 混合比例(0-1),0表示完全使用color1,1表示完全使用color2\n * @returns 混合后的十六进制颜色值\n */\nexport function mix(color1: string, color2: string, ratio: number): string {\n const rgb1 = hexToRgb(color1);\n const rgb2 = hexToRgb(color2);\n\n const r = Math.round(rgb1.r * (1 - ratio) + rgb2.r * ratio);\n const g = Math.round(rgb1.g * (1 - ratio) + rgb2.g * ratio);\n const b = Math.round(rgb1.b * (1 - ratio) + rgb2.b * ratio);\n\n return rgbToHex({ r, g, b });\n}\n\n/**\n * 计算颜色对比度(WCAG标准)\n * @param color1 - 第一个颜色(十六进制)\n * @param color2 - 第二个颜色(十六进制)\n * @returns 对比度比值(1-21,4.5以上为可接受对比度)\n */\nexport function contrast(color1: string, color2: string): number {\n const rgb1 = hexToRgb(color1);\n const rgb2 = hexToRgb(color2);\n\n // 计算相对亮度\n const getLuminance = (rgb: RGB): number => {\n const normalize = (value: number): number => {\n value = value / 255;\n return value <= 0.03928 ? value / 12.92 : Math.pow((value + 0.055) / 1.055, 2.4);\n };\n\n return 0.2126 * normalize(rgb.r) + 0.7152 * normalize(rgb.g) + 0.0722 * normalize(rgb.b);\n };\n\n const lum1 = getLuminance(rgb1);\n const lum2 = getLuminance(rgb2);\n\n const lighter = Math.max(lum1, lum2);\n const darker = Math.min(lum1, lum2);\n\n return (lighter + 0.05) / (darker + 0.05);\n}\n"]}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { splitFileIntoChunks, calculateBlobMD5 } from './chunk-ZVJ6NQUM.mjs';
|
|
2
|
+
|
|
3
|
+
// src/types/upload.ts
|
|
4
|
+
var UploadStatus = /* @__PURE__ */ ((UploadStatus2) => {
|
|
5
|
+
UploadStatus2["PENDING"] = "pending";
|
|
6
|
+
UploadStatus2["UPLOADING"] = "uploading";
|
|
7
|
+
UploadStatus2["PAUSED"] = "paused";
|
|
8
|
+
UploadStatus2["COMPLETED"] = "completed";
|
|
9
|
+
UploadStatus2["FAILED"] = "failed";
|
|
10
|
+
UploadStatus2["CANCELLED"] = "cancelled";
|
|
11
|
+
return UploadStatus2;
|
|
12
|
+
})(UploadStatus || {});
|
|
13
|
+
|
|
14
|
+
// src/browser/upload.ts
|
|
15
|
+
var ChunkUploader = class {
|
|
16
|
+
constructor(file, options = {}) {
|
|
17
|
+
this.taskId = null;
|
|
18
|
+
this.chunks = [];
|
|
19
|
+
this.uploadedChunks = /* @__PURE__ */ new Set();
|
|
20
|
+
this.status = "pending" /* PENDING */;
|
|
21
|
+
this.abortController = null;
|
|
22
|
+
this.file = file;
|
|
23
|
+
this.options = {
|
|
24
|
+
chunkSize: options.chunkSize || 2 * 1024 * 1024,
|
|
25
|
+
// 默认2MB
|
|
26
|
+
concurrency: options.concurrency || 3,
|
|
27
|
+
retryCount: options.retryCount || 3,
|
|
28
|
+
retryDelay: options.retryDelay || 1e3,
|
|
29
|
+
baseURL: options.baseURL || "",
|
|
30
|
+
headers: options.headers || {},
|
|
31
|
+
onProgress: options.onProgress || (() => {
|
|
32
|
+
}),
|
|
33
|
+
onComplete: options.onComplete || (() => {
|
|
34
|
+
}),
|
|
35
|
+
onError: options.onError || (() => {
|
|
36
|
+
})
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 初始化上传
|
|
41
|
+
*/
|
|
42
|
+
async initUpload() {
|
|
43
|
+
const fileMd5 = await this.calculateFileMD5();
|
|
44
|
+
const request = {
|
|
45
|
+
fileName: this.file.name,
|
|
46
|
+
fileSize: this.file.size,
|
|
47
|
+
fileMd5,
|
|
48
|
+
chunkSize: this.options.chunkSize
|
|
49
|
+
};
|
|
50
|
+
const response = await this.request("/api/files/common/init", {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
...this.options.headers
|
|
55
|
+
},
|
|
56
|
+
body: JSON.stringify(request)
|
|
57
|
+
});
|
|
58
|
+
if (response.code !== 200) {
|
|
59
|
+
throw new Error(response.message || "\u521D\u59CB\u5316\u4E0A\u4F20\u5931\u8D25");
|
|
60
|
+
}
|
|
61
|
+
return response.data;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 计算文件MD5(简化版,实际应该使用spark-md5等库)
|
|
65
|
+
*/
|
|
66
|
+
async calculateFileMD5() {
|
|
67
|
+
const chunks = splitFileIntoChunks(this.file, this.options.chunkSize);
|
|
68
|
+
const md5Promises = chunks.map(
|
|
69
|
+
(chunk, index) => calculateBlobMD5(chunk).then((md5) => ({ index, md5 }))
|
|
70
|
+
);
|
|
71
|
+
const md5Results = await Promise.all(md5Promises);
|
|
72
|
+
return md5Results.map((r) => r.md5).join("");
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 准备分片
|
|
76
|
+
*/
|
|
77
|
+
prepareChunks() {
|
|
78
|
+
const blobChunks = splitFileIntoChunks(this.file, this.options.chunkSize);
|
|
79
|
+
this.chunks = blobChunks.map((blob, index) => ({
|
|
80
|
+
index,
|
|
81
|
+
start: index * this.options.chunkSize,
|
|
82
|
+
end: Math.min((index + 1) * this.options.chunkSize, this.file.size),
|
|
83
|
+
blob
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 获取已上传的分片列表
|
|
88
|
+
*/
|
|
89
|
+
async getUploadedChunks() {
|
|
90
|
+
if (!this.taskId) return [];
|
|
91
|
+
try {
|
|
92
|
+
const response = await this.request(
|
|
93
|
+
`/api/files/common/chunks/${this.taskId}`,
|
|
94
|
+
{
|
|
95
|
+
method: "GET",
|
|
96
|
+
headers: this.options.headers
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
if (response.code === 200) {
|
|
100
|
+
return response.data || [];
|
|
101
|
+
}
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.warn("\u83B7\u53D6\u5DF2\u4E0A\u4F20\u5206\u7247\u5931\u8D25:", error);
|
|
104
|
+
}
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 上传单个分片
|
|
109
|
+
*/
|
|
110
|
+
async uploadChunk(chunkInfo, retryCount = 0) {
|
|
111
|
+
if (!this.taskId) {
|
|
112
|
+
throw new Error("\u4EFB\u52A1ID\u4E0D\u5B58\u5728");
|
|
113
|
+
}
|
|
114
|
+
if (this.uploadedChunks.has(chunkInfo.index)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
const chunkMd5 = await calculateBlobMD5(chunkInfo.blob);
|
|
119
|
+
const formData = new FormData();
|
|
120
|
+
formData.append("file", chunkInfo.blob, this.file.name);
|
|
121
|
+
const url = `/api/files/common/chunk?taskId=${this.taskId}&chunkIndex=${chunkInfo.index}&chunkMd5=${chunkMd5}`;
|
|
122
|
+
const response = await this.request(url, {
|
|
123
|
+
method: "POST",
|
|
124
|
+
headers: this.options.headers,
|
|
125
|
+
body: formData
|
|
126
|
+
});
|
|
127
|
+
if (response.code === 200 && response.data.success) {
|
|
128
|
+
this.uploadedChunks.add(chunkInfo.index);
|
|
129
|
+
this.updateProgress();
|
|
130
|
+
} else {
|
|
131
|
+
throw new Error(response.message || "\u5206\u7247\u4E0A\u4F20\u5931\u8D25");
|
|
132
|
+
}
|
|
133
|
+
} catch (error) {
|
|
134
|
+
if (retryCount < this.options.retryCount) {
|
|
135
|
+
await this.delay(this.options.retryDelay);
|
|
136
|
+
return this.uploadChunk(chunkInfo, retryCount + 1);
|
|
137
|
+
}
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 并发上传分片
|
|
143
|
+
*/
|
|
144
|
+
async uploadChunksConcurrently() {
|
|
145
|
+
const chunksToUpload = this.chunks.filter((chunk) => !this.uploadedChunks.has(chunk.index));
|
|
146
|
+
const uploadPromises = [];
|
|
147
|
+
let currentIndex = 0;
|
|
148
|
+
const uploadNext = async () => {
|
|
149
|
+
while (currentIndex < chunksToUpload.length && this.status === "uploading" /* UPLOADING */) {
|
|
150
|
+
const chunk = chunksToUpload[currentIndex++];
|
|
151
|
+
const promise = this.uploadChunk(chunk).then(() => {
|
|
152
|
+
if (currentIndex < chunksToUpload.length) {
|
|
153
|
+
return uploadNext();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
uploadPromises.push(promise);
|
|
157
|
+
if (uploadPromises.length >= this.options.concurrency) {
|
|
158
|
+
await Promise.race(uploadPromises);
|
|
159
|
+
uploadPromises.splice(
|
|
160
|
+
uploadPromises.findIndex((p) => p === promise),
|
|
161
|
+
1
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const concurrencyPromises = [];
|
|
167
|
+
for (let i = 0; i < this.options.concurrency; i++) {
|
|
168
|
+
concurrencyPromises.push(uploadNext());
|
|
169
|
+
}
|
|
170
|
+
await Promise.all(concurrencyPromises);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 完成上传
|
|
174
|
+
*/
|
|
175
|
+
async completeUpload() {
|
|
176
|
+
if (!this.taskId) {
|
|
177
|
+
throw new Error("\u4EFB\u52A1ID\u4E0D\u5B58\u5728");
|
|
178
|
+
}
|
|
179
|
+
const response = await this.request(
|
|
180
|
+
`/api/files/common/complete/${this.taskId}`,
|
|
181
|
+
{
|
|
182
|
+
method: "POST",
|
|
183
|
+
headers: this.options.headers
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
if (response.code !== 200) {
|
|
187
|
+
throw new Error(response.message || "\u5B8C\u6210\u4E0A\u4F20\u5931\u8D25");
|
|
188
|
+
}
|
|
189
|
+
return response.data;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* 更新上传进度
|
|
193
|
+
*/
|
|
194
|
+
async updateProgress() {
|
|
195
|
+
if (!this.taskId) return;
|
|
196
|
+
try {
|
|
197
|
+
const response = await this.request(
|
|
198
|
+
`/api/files/common/progress/${this.taskId}`,
|
|
199
|
+
{
|
|
200
|
+
method: "GET",
|
|
201
|
+
headers: this.options.headers
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
if (response.code === 200 && this.options.onProgress) {
|
|
205
|
+
this.options.onProgress(response.data);
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.warn("\u83B7\u53D6\u4E0A\u4F20\u8FDB\u5EA6\u5931\u8D25:", error);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* 开始上传
|
|
213
|
+
*/
|
|
214
|
+
async upload() {
|
|
215
|
+
try {
|
|
216
|
+
this.status = "uploading" /* UPLOADING */;
|
|
217
|
+
this.abortController = new AbortController();
|
|
218
|
+
const initResponse = await this.initUpload();
|
|
219
|
+
this.taskId = initResponse.taskId;
|
|
220
|
+
if (initResponse.instantUpload && initResponse.fileUrl) {
|
|
221
|
+
this.status = "completed" /* COMPLETED */;
|
|
222
|
+
const result2 = {
|
|
223
|
+
taskId: this.taskId,
|
|
224
|
+
fileUrl: initResponse.fileUrl,
|
|
225
|
+
fileName: this.file.name,
|
|
226
|
+
fileSize: this.file.size,
|
|
227
|
+
fileMd5: "",
|
|
228
|
+
success: true,
|
|
229
|
+
message: "\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u79D2\u4F20\u6210\u529F"
|
|
230
|
+
};
|
|
231
|
+
this.options.onComplete(result2);
|
|
232
|
+
return result2;
|
|
233
|
+
}
|
|
234
|
+
this.prepareChunks();
|
|
235
|
+
const existingChunks = await this.getUploadedChunks();
|
|
236
|
+
existingChunks.forEach((index) => this.uploadedChunks.add(index));
|
|
237
|
+
await this.uploadChunksConcurrently();
|
|
238
|
+
const result = await this.completeUpload();
|
|
239
|
+
this.status = "completed" /* COMPLETED */;
|
|
240
|
+
this.options.onComplete(result);
|
|
241
|
+
return result;
|
|
242
|
+
} catch (error) {
|
|
243
|
+
this.status = "failed" /* FAILED */;
|
|
244
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
245
|
+
this.options.onError(err);
|
|
246
|
+
throw err;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* 暂停上传
|
|
251
|
+
*/
|
|
252
|
+
pause() {
|
|
253
|
+
if (this.status === "uploading" /* UPLOADING */) {
|
|
254
|
+
this.status = "paused" /* PAUSED */;
|
|
255
|
+
if (this.abortController) {
|
|
256
|
+
this.abortController.abort();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* 恢复上传
|
|
262
|
+
*/
|
|
263
|
+
async resume() {
|
|
264
|
+
if (this.status === "paused" /* PAUSED */) {
|
|
265
|
+
return this.upload();
|
|
266
|
+
}
|
|
267
|
+
throw new Error("\u5F53\u524D\u72B6\u6001\u65E0\u6CD5\u6062\u590D\u4E0A\u4F20");
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* 取消上传
|
|
271
|
+
*/
|
|
272
|
+
async cancel() {
|
|
273
|
+
if (this.taskId && this.status === "uploading" /* UPLOADING */) {
|
|
274
|
+
try {
|
|
275
|
+
await this.request(`/api/files/common/cancel/${this.taskId}`, {
|
|
276
|
+
method: "POST",
|
|
277
|
+
headers: this.options.headers
|
|
278
|
+
});
|
|
279
|
+
} catch (error) {
|
|
280
|
+
console.warn("\u53D6\u6D88\u4E0A\u4F20\u5931\u8D25:", error);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
this.status = "cancelled" /* CANCELLED */;
|
|
284
|
+
if (this.abortController) {
|
|
285
|
+
this.abortController.abort();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* 获取当前状态
|
|
290
|
+
*/
|
|
291
|
+
getStatus() {
|
|
292
|
+
return this.status;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* 获取任务ID
|
|
296
|
+
*/
|
|
297
|
+
getTaskId() {
|
|
298
|
+
return this.taskId;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* HTTP请求封装
|
|
302
|
+
*/
|
|
303
|
+
async request(url, options = {}) {
|
|
304
|
+
const fullUrl = `${this.options.baseURL}${url}`;
|
|
305
|
+
const signal = this.abortController?.signal;
|
|
306
|
+
const response = await fetch(fullUrl, {
|
|
307
|
+
...options,
|
|
308
|
+
signal
|
|
309
|
+
});
|
|
310
|
+
if (!response.ok) {
|
|
311
|
+
throw new Error(`HTTP\u9519\u8BEF: ${response.status} ${response.statusText}`);
|
|
312
|
+
}
|
|
313
|
+
return response.json();
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* 延迟函数
|
|
317
|
+
*/
|
|
318
|
+
delay(ms) {
|
|
319
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
function createUploader(file, options) {
|
|
323
|
+
return new ChunkUploader(file, options);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export { ChunkUploader, UploadStatus, createUploader };
|
|
327
|
+
//# sourceMappingURL=chunk-QV6MIQ7H.mjs.map
|
|
328
|
+
//# sourceMappingURL=chunk-QV6MIQ7H.mjs.map
|