diff --git a/bootstrap_btn.ts b/bootstrap_btn.ts new file mode 100644 index 0000000..02a5394 --- /dev/null +++ b/bootstrap_btn.ts @@ -0,0 +1,199 @@ +import { type Preset, symbols } from 'unocss'; +function compressCSS(css: string, isDev = false) { + if (isDev) + return css.trim(); + return css.trim().replace(/\s+/g, " ").replace(/\/\*[\s\S]*?\*\//g, ""); +} +function get(obj: Record | undefined = {}, key: string): T { + // key = "key" or "key.subkey" + const keys = key.split('.'); + let result: any = obj; + + for (const k of keys) { + if (result == null || typeof result !== 'object') return undefined as any; + result = result[k]; + } + + return result; +} +type ColorRecordType = string | Record; +class ColorRecord { + // [key: string]: string | ColorRecord; + _colors: Record = {}; + constructor(obj?: Record>) { + if (obj) { + this._add(obj); + } + } + _add(obj: Record>) { + this._colors = { ...this._colors, ...obj }; + } + get colors() { + return this._colors; + } + get(key: string): ColorRecord | string | undefined { + const color = get(this._colors, key); + if (color !== undefined) { + return typeof color === 'string' ? color : new ColorRecord(color); + } + return undefined; + } +} +function extractColors(theme: {colors: Record>}): ColorRecord { + const colors: any = {}; + Object.entries(theme.colors).forEach(([key, value]) => { + if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + colors[key] = value as any + } + }); + return new ColorRecord(colors); +} + +const colorsMap = new Map>(); +export const presetBootstrapBtn = (): Preset => ({ + name: 'preset-bootstrap-btn', + preflights: [ + { + layer: 'base', + getCSS: (ctx) => { + const colors = (ctx.generator.config.theme as { colors: Record> }).colors || {} + Object.entries(colors).forEach(([key, value]) => { + colorsMap.set(key, value) + }) + return "" + } + } + ], + rules: [ + // Base .btn style + [ + /^btn$/, + () => ({ + 'display': 'inline-flex', + 'font-weight': '500', + 'line-height': '1.5', + 'text-align': 'center', + 'text-decoration': 'none', + 'vertical-align': 'middle', + 'user-select': 'none', + 'align-items': 'center', + 'border': '1px solid transparent', + 'padding': '0.375rem 0.75rem', + 'font-size': '1rem', + 'border-radius': '0.375rem', + 'transition': 'color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out', + 'cursor': 'pointer', + 'gap': '.375rem', + // "cursor": "pointer", + // "border": "1px solid #0000", + // "border-radius": ".375rem", + // "outline": "none", + // "align-items": "center", + // "gap": ".375rem", + // "height": "2.5rem", + // "padding-inline": "1rem", + // "font-size": ".8125rem", + // "font-weight": 500, + // "line-height": 1, + // "display": "inline-flex" + }), + ], + + // Variants + [/^btn-(primary|secondary|success|danger|warning|info|light|dark)$/, ([, c], {theme}) => { + const color = extractColors(theme as any).get(`${c}.DEFAULT`) + const colorLight = extractColors(theme as any).get(`${c}.light`) ?? `color-mix(in srgb, ${color} 85%, black)`; + const text = ['light', 'warning'].includes(c) ? '#000' : '#fff' + + return [{ + 'color': text, + 'background-color': color, + 'border-color': color, + 'transition': 'all 0.15s ease-in-out', + }, + { + [symbols.selector]: selector => `${selector}:hover`, + // background: `color-mix(in srgb, ${color} 90%, black)`, + // "border-color": `color-mix(in srgb, ${color} 85%, black)`, + "box-shadow": `.25rem .25rem 0 ${colorLight}`, + 'transform': 'translate(-0.125rem, -0.125rem)', + }, + { + [symbols.selector]: selector => `${selector}:focus`, + outline: `0`, + }, + { + [symbols.selector]: selector => `${selector}:disabled`, + opacity: `.65`, + "pointer-events": `none`, + }, + // Active + { + [symbols.selector]: selector => `${selector}.active`, + background: `color-mix(in srgb, ${color} 80%, black)`, + "border-color": `color-mix(in srgb, ${color} 75%, black)`, + "box-shadow": `inset 0 .15rem .3rem rgba(0,0,0,.15)`, + } + ] + }], + + // Outline variants + [/^btn-outline-(primary|secondary|success|danger|warning|info|light|dark)$/, ([, c], {theme}) => { + const color = extractColors(theme as any).get(`${c}.DEFAULT`) + const colorLight = extractColors(theme as any).get(`${c}.light`) + + return [{ + 'color': color, + 'border-color': color, + 'background-color': 'transparent', + 'transition': 'all 0.15s ease-in-out', + }, + { + [symbols.selector]: selector => `${selector}:hover`, + // color: '#fff', + // "background-color": color, + // "border-color": color, + 'box-shadow': `0.25rem .25rem 0 ${colorLight}`, + 'transform': 'translate(-0.125rem, -0.125rem)', + }, + ] + }], + // Size variants + [/^btn-(lg|sm)$/, ([, size], {theme}) => { + const padding = size === 'lg' ? '0.5rem 1rem' : '0.25rem 0.5rem'; + const fontSize = size === 'lg' ? '1.125rem' : '0.875rem'; + const borderRadius = size === 'lg' ? '0.5rem' : '0.25rem'; + return [{ + 'padding': padding, + 'font-size': fontSize, + 'border-radius': borderRadius, + }, + ] + }], + // Button group + ], + shortcuts: [ + // ==== Button Group ==== + [ + 'btn-group', + [ + 'inline-flex items-stretch align-middle', + '[&>.btn]:rounded-none', + '[&>.btn:first-child]:rounded-l-md', + '[&>.btn:last-child]:rounded-r-md', + '[&>.btn:not(:last-child)]:border-r-0', + ].join(' '), + ], + + [ + 'btn-group-vertical', + [ + 'inline-flex flex-col items-stretch align-middle', + '[&>.btn]:rounded-none', + '[&>.btn:first-child]:rounded-t-md', + '[&>.btn:last-child]:rounded-b-md', + '[&>.btn:not(:last-child)]:border-b-0', + ].join(' '), + ], + ] +}) diff --git a/bun.lock b/bun.lock index bd63acb..1193c20 100644 --- a/bun.lock +++ b/bun.lock @@ -4,22 +4,33 @@ "": { "name": "holistream", "dependencies": { + "@aws-sdk/client-s3": "^3.946.0", + "@aws-sdk/s3-presigned-post": "^3.946.0", + "@aws-sdk/s3-request-presigner": "^3.946.0", + "@hiogawa/tiny-rpc": "^0.2.3-pre.18", "@hiogawa/utils": "^1.7.0", "@primeuix/themes": "^2.0.2", "@primevue/forms": "^4.5.4", "@unhead/vue": "^2.1.1", + "@vueuse/core": "^14.1.0", "clsx": "^2.1.1", "hono": "^4.11.3", + "is-mobile": "^5.0.0", "pinia": "^3.0.4", + "primevue": "^4.5.4", + "tailwind-merge": "^3.4.0", "vue": "^3.5.26", "vue-router": "^4.6.4", + "zod": "^4.3.2", }, "devDependencies": { "@cloudflare/vite-plugin": "^1.17.1", + "@primevue/auto-import-resolver": "^4.5.4", "@types/node": "^25.0.3", "@vitejs/plugin-vue": "^6.0.3", "@vitejs/plugin-vue-jsx": "^5.1.3", "unocss": "^66.5.12", + "unplugin-vue-components": "^30.0.0", "vite": "^7.3.0", "vite-ssr-components": "^0.5.2", "wrangler": "^4.54.0", @@ -29,6 +40,94 @@ "packages": { "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], + "@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="], + + "@aws-crypto/crc32c": ["@aws-crypto/crc32c@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag=="], + + "@aws-crypto/sha1-browser": ["@aws-crypto/sha1-browser@5.2.0", "", { "dependencies": { "@aws-crypto/supports-web-crypto": "^5.2.0", "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg=="], + + "@aws-crypto/sha256-browser": ["@aws-crypto/sha256-browser@5.2.0", "", { "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw=="], + + "@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], + + "@aws-crypto/supports-web-crypto": ["@aws-crypto/supports-web-crypto@5.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg=="], + + "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], + + "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.958.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.957.0", "@aws-sdk/credential-provider-node": "3.958.0", "@aws-sdk/middleware-bucket-endpoint": "3.957.0", "@aws-sdk/middleware-expect-continue": "3.957.0", "@aws-sdk/middleware-flexible-checksums": "3.957.0", "@aws-sdk/middleware-host-header": "3.957.0", "@aws-sdk/middleware-location-constraint": "3.957.0", "@aws-sdk/middleware-logger": "3.957.0", "@aws-sdk/middleware-recursion-detection": "3.957.0", "@aws-sdk/middleware-sdk-s3": "3.957.0", "@aws-sdk/middleware-ssec": "3.957.0", "@aws-sdk/middleware-user-agent": "3.957.0", "@aws-sdk/region-config-resolver": "3.957.0", "@aws-sdk/signature-v4-multi-region": "3.957.0", "@aws-sdk/types": "3.957.0", "@aws-sdk/util-endpoints": "3.957.0", "@aws-sdk/util-user-agent-browser": "3.957.0", "@aws-sdk/util-user-agent-node": "3.957.0", "@smithy/config-resolver": "^4.4.5", "@smithy/core": "^3.20.0", "@smithy/eventstream-serde-browser": "^4.2.7", "@smithy/eventstream-serde-config-resolver": "^4.3.7", "@smithy/eventstream-serde-node": "^4.2.7", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/hash-blob-browser": "^4.2.8", "@smithy/hash-node": "^4.2.7", "@smithy/hash-stream-node": "^4.2.7", "@smithy/invalid-dependency": "^4.2.7", "@smithy/md5-js": "^4.2.7", "@smithy/middleware-content-length": "^4.2.7", "@smithy/middleware-endpoint": "^4.4.1", "@smithy/middleware-retry": "^4.4.17", "@smithy/middleware-serde": "^4.2.8", "@smithy/middleware-stack": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/node-http-handler": "^4.4.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.16", "@smithy/util-defaults-mode-node": "^4.2.19", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/util-stream": "^4.5.8", "@smithy/util-utf8": "^4.2.0", "@smithy/util-waiter": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-ol8Sw37AToBWb6PjRuT/Wu40SrrZSA0N4F7U3yTkjUNX0lirfO1VFLZ0hZtZplVJv8GNPITbiczxQ8VjxESXxg=="], + + "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.958.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.957.0", "@aws-sdk/middleware-host-header": "3.957.0", "@aws-sdk/middleware-logger": "3.957.0", "@aws-sdk/middleware-recursion-detection": "3.957.0", "@aws-sdk/middleware-user-agent": "3.957.0", "@aws-sdk/region-config-resolver": "3.957.0", "@aws-sdk/types": "3.957.0", "@aws-sdk/util-endpoints": "3.957.0", "@aws-sdk/util-user-agent-browser": "3.957.0", "@aws-sdk/util-user-agent-node": "3.957.0", "@smithy/config-resolver": "^4.4.5", "@smithy/core": "^3.20.0", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/hash-node": "^4.2.7", "@smithy/invalid-dependency": "^4.2.7", "@smithy/middleware-content-length": "^4.2.7", "@smithy/middleware-endpoint": "^4.4.1", "@smithy/middleware-retry": "^4.4.17", "@smithy/middleware-serde": "^4.2.8", "@smithy/middleware-stack": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/node-http-handler": "^4.4.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.16", "@smithy/util-defaults-mode-node": "^4.2.19", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6qNCIeaMzKzfqasy2nNRuYnMuaMebCcCPP4J2CVGkA8QYMbIVKPlkn9bpB20Vxe6H/r3jtCCLQaOJjVTx/6dXg=="], + + "@aws-sdk/core": ["@aws-sdk/core@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@aws-sdk/xml-builder": "3.957.0", "@smithy/core": "^3.20.0", "@smithy/node-config-provider": "^4.3.7", "@smithy/property-provider": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/signature-v4": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-DrZgDnF1lQZv75a52nFWs6MExihJF2GZB6ETZRqr6jMwhrk2kbJPUtvgbifwcL7AYmVqHQDJBrR/MqkwwFCpiw=="], + + "@aws-sdk/crc64-nvme": ["@aws-sdk/crc64-nvme@3.957.0", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-qSwSfI+qBU9HDsd6/4fM9faCxYJx2yDuHtj+NVOQ6XYDWQzFab/hUdwuKZ77Pi6goLF1pBZhJ2azaC2w7LbnTA=="], + + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.957.0", "", { "dependencies": { "@aws-sdk/core": "3.957.0", "@aws-sdk/types": "3.957.0", "@smithy/property-provider": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-475mkhGaWCr+Z52fOOVb/q2VHuNvqEDixlYIkeaO6xJ6t9qR0wpLt4hOQaR6zR1wfZV0SlE7d8RErdYq/PByog=="], + + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.957.0", "", { "dependencies": { "@aws-sdk/core": "3.957.0", "@aws-sdk/types": "3.957.0", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/node-http-handler": "^4.4.7", "@smithy/property-provider": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/util-stream": "^4.5.8", "tslib": "^2.6.2" } }, "sha512-8dS55QHRxXgJlHkEYaCGZIhieCs9NU1HU1BcqQ4RfUdSsfRdxxktqUKgCnBnOOn0oD3PPA8cQOCAVgIyRb3Rfw=="], + + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.958.0", "", { "dependencies": { "@aws-sdk/core": "3.957.0", "@aws-sdk/credential-provider-env": "3.957.0", "@aws-sdk/credential-provider-http": "3.957.0", "@aws-sdk/credential-provider-login": "3.958.0", "@aws-sdk/credential-provider-process": "3.957.0", "@aws-sdk/credential-provider-sso": "3.958.0", "@aws-sdk/credential-provider-web-identity": "3.958.0", "@aws-sdk/nested-clients": "3.958.0", "@aws-sdk/types": "3.957.0", "@smithy/credential-provider-imds": "^4.2.7", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-u7twvZa1/6GWmPBZs6DbjlegCoNzNjBsMS/6fvh5quByYrcJr/uLd8YEr7S3UIq4kR/gSnHqcae7y2nL2bqZdg=="], + + "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.958.0", "", { "dependencies": { "@aws-sdk/core": "3.957.0", "@aws-sdk/nested-clients": "3.958.0", "@aws-sdk/types": "3.957.0", "@smithy/property-provider": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-sDwtDnBSszUIbzbOORGh5gmXGl9aK25+BHb4gb1aVlqB+nNL2+IUEJA62+CE55lXSH8qXF90paivjK8tOHTwPA=="], + + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.958.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.957.0", "@aws-sdk/credential-provider-http": "3.957.0", "@aws-sdk/credential-provider-ini": "3.958.0", "@aws-sdk/credential-provider-process": "3.957.0", "@aws-sdk/credential-provider-sso": "3.958.0", "@aws-sdk/credential-provider-web-identity": "3.958.0", "@aws-sdk/types": "3.957.0", "@smithy/credential-provider-imds": "^4.2.7", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-vdoZbNG2dt66I7EpN3fKCzi6fp9xjIiwEA/vVVgqO4wXCGw8rKPIdDUus4e13VvTr330uQs2W0UNg/7AgtquEQ=="], + + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.957.0", "", { "dependencies": { "@aws-sdk/core": "3.957.0", "@aws-sdk/types": "3.957.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-/KIz9kadwbeLy6SKvT79W81Y+hb/8LMDyeloA2zhouE28hmne+hLn0wNCQXAAupFFlYOAtZR2NTBs7HBAReJlg=="], + + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.958.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.958.0", "@aws-sdk/core": "3.957.0", "@aws-sdk/token-providers": "3.958.0", "@aws-sdk/types": "3.957.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-CBYHJ5ufp8HC4q+o7IJejCUctJXWaksgpmoFpXerbjAso7/Fg7LLUu9inXVOxlHKLlvYekDXjIUBXDJS2WYdgg=="], + + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.958.0", "", { "dependencies": { "@aws-sdk/core": "3.957.0", "@aws-sdk/nested-clients": "3.958.0", "@aws-sdk/types": "3.957.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-dgnvwjMq5Y66WozzUzxNkCFap+umHUtqMMKlr8z/vl9NYMLem/WUbWNpFFOVFWquXikc+ewtpBMR4KEDXfZ+KA=="], + + "@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@aws-sdk/util-arn-parser": "3.957.0", "@smithy/node-config-provider": "^4.3.7", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-config-provider": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-iczcn/QRIBSpvsdAS/rbzmoBpleX1JBjXvCynMbDceVLBIcVrwT1hXECrhtIC2cjh4HaLo9ClAbiOiWuqt+6MA=="], + + "@aws-sdk/middleware-expect-continue": ["@aws-sdk/middleware-expect-continue@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-AlbK3OeVNwZZil0wlClgeI/ISlOt/SPUxBsIns876IFaVu/Pj3DgImnYhpcJuFRek4r4XM51xzIaGQXM6GDHGg=="], + + "@aws-sdk/middleware-flexible-checksums": ["@aws-sdk/middleware-flexible-checksums@3.957.0", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/core": "3.957.0", "@aws-sdk/crc64-nvme": "3.957.0", "@aws-sdk/types": "3.957.0", "@smithy/is-array-buffer": "^4.2.0", "@smithy/node-config-provider": "^4.3.7", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-stream": "^4.5.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-iJpeVR5V8se1hl2pt+k8bF/e9JO4KWgPCMjg8BtRspNtKIUGy7j6msYvbDixaKZaF2Veg9+HoYcOhwnZumjXSA=="], + + "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-BBgKawVyfQZglEkNTuBBdC3azlyqNXsvvN4jPkWAiNYcY0x1BasaJFl+7u/HisfULstryweJq/dAvIZIxzlZaA=="], + + "@aws-sdk/middleware-location-constraint": ["@aws-sdk/middleware-location-constraint@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-y8/W7TOQpmDJg/fPYlqAhwA4+I15LrS7TwgUEoxogtkD8gfur9wFMRLT8LCyc9o4NMEcAnK50hSb4+wB0qv6tQ=="], + + "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-w1qfKrSKHf9b5a8O76yQ1t69u6NWuBjr5kBX+jRWFx/5mu6RLpqERXRpVJxfosbep7k3B+DSB5tZMZ82GKcJtQ=="], + + "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-D2H/WoxhAZNYX+IjkKTdOhOkWQaK0jjJrDBj56hKjU5c9ltQiaX/1PqJ4dfjHntEshJfu0w+E6XJ+/6A6ILBBA=="], + + "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.957.0", "", { "dependencies": { "@aws-sdk/core": "3.957.0", "@aws-sdk/types": "3.957.0", "@aws-sdk/util-arn-parser": "3.957.0", "@smithy/core": "^3.20.0", "@smithy/node-config-provider": "^4.3.7", "@smithy/protocol-http": "^5.3.7", "@smithy/signature-v4": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-stream": "^4.5.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-5B2qY2nR2LYpxoQP0xUum5A1UNvH2JQpLHDH1nWFNF/XetV7ipFHksMxPNhtJJ6ARaWhQIDXfOUj0jcnkJxXUg=="], + + "@aws-sdk/middleware-ssec": ["@aws-sdk/middleware-ssec@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-qwkmrK0lizdjNt5qxl4tHYfASh8DFpHXM1iDVo+qHe+zuslfMqQEGRkzxS8tJq/I+8F0c6v3IKOveKJAfIvfqQ=="], + + "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.957.0", "", { "dependencies": { "@aws-sdk/core": "3.957.0", "@aws-sdk/types": "3.957.0", "@aws-sdk/util-endpoints": "3.957.0", "@smithy/core": "^3.20.0", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-50vcHu96XakQnIvlKJ1UoltrFODjsq2KvtTgHiPFteUS884lQnK5VC/8xd1Msz/1ONpLMzdCVproCQqhDTtMPQ=="], + + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.958.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.957.0", "@aws-sdk/middleware-host-header": "3.957.0", "@aws-sdk/middleware-logger": "3.957.0", "@aws-sdk/middleware-recursion-detection": "3.957.0", "@aws-sdk/middleware-user-agent": "3.957.0", "@aws-sdk/region-config-resolver": "3.957.0", "@aws-sdk/types": "3.957.0", "@aws-sdk/util-endpoints": "3.957.0", "@aws-sdk/util-user-agent-browser": "3.957.0", "@aws-sdk/util-user-agent-node": "3.957.0", "@smithy/config-resolver": "^4.4.5", "@smithy/core": "^3.20.0", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/hash-node": "^4.2.7", "@smithy/invalid-dependency": "^4.2.7", "@smithy/middleware-content-length": "^4.2.7", "@smithy/middleware-endpoint": "^4.4.1", "@smithy/middleware-retry": "^4.4.17", "@smithy/middleware-serde": "^4.2.8", "@smithy/middleware-stack": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/node-http-handler": "^4.4.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.16", "@smithy/util-defaults-mode-node": "^4.2.19", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-/KuCcS8b5TpQXkYOrPLYytrgxBhv81+5pChkOlhegbeHttjM69pyUpQVJqyfDM/A7wPLnDrzCAnk4zaAOkY0Nw=="], + + "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@smithy/config-resolver": "^4.4.5", "@smithy/node-config-provider": "^4.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-V8iY3blh8l2iaOqXWW88HbkY5jDoWjH56jonprG/cpyqqCnprvpMUZWPWYJoI8rHRf2bqzZeql1slxG6EnKI7A=="], + + "@aws-sdk/s3-presigned-post": ["@aws-sdk/s3-presigned-post@3.958.0", "", { "dependencies": { "@aws-sdk/client-s3": "3.958.0", "@aws-sdk/types": "3.957.0", "@aws-sdk/util-format-url": "3.957.0", "@smithy/middleware-endpoint": "^4.4.1", "@smithy/signature-v4": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-/ZIXeezt9QSkruWlk9yj4XkA2hQyKcYyykOWZtphqcZZXBL5Y1NcF/bjzPohbzOYTYxV1ddWZGzodiSdnBeXPw=="], + + "@aws-sdk/s3-request-presigner": ["@aws-sdk/s3-request-presigner@3.958.0", "", { "dependencies": { "@aws-sdk/signature-v4-multi-region": "3.957.0", "@aws-sdk/types": "3.957.0", "@aws-sdk/util-format-url": "3.957.0", "@smithy/middleware-endpoint": "^4.4.1", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-bFKsofead/fl3lyhdES+aNo+MZ+qv1ixSPSsF8O1oj6/KgGE0t1UH9AHw2vPq6iSQMTeEuyV0F5pC+Ns40kBgA=="], + + "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.957.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.957.0", "@aws-sdk/types": "3.957.0", "@smithy/protocol-http": "^5.3.7", "@smithy/signature-v4": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-t6UfP1xMUigMMzHcb7vaZcjv7dA2DQkk9C/OAP1dKyrE0vb4lFGDaTApi17GN6Km9zFxJthEMUbBc7DL0hq1Bg=="], + + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.958.0", "", { "dependencies": { "@aws-sdk/core": "3.957.0", "@aws-sdk/nested-clients": "3.958.0", "@aws-sdk/types": "3.957.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-UCj7lQXODduD1myNJQkV+LYcGYJ9iiMggR8ow8Hva1g3A/Na5imNXzz6O67k7DAee0TYpy+gkNw+SizC6min8Q=="], + + "@aws-sdk/types": ["@aws-sdk/types@3.957.0", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-wzWC2Nrt859ABk6UCAVY/WYEbAd7FjkdrQL6m24+tfmWYDNRByTJ9uOgU/kw9zqLCAwb//CPvrJdhqjTznWXAg=="], + + "@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.957.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Aj6m+AyrhWyg8YQ4LDPg2/gIfGHCEcoQdBt5DeSFogN5k9mmJPOJ+IAmNSWmWRjpOxEy6eY813RNDI6qS97M0g=="], + + "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-endpoints": "^3.2.7", "tslib": "^2.6.2" } }, "sha512-xwF9K24mZSxcxKS3UKQFeX/dPYkEps9wF1b+MGON7EvnbcucrJGyQyK1v1xFPn1aqXkBTFi+SZaMRx5E5YCVFw=="], + + "@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@smithy/querystring-builder": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-Yyo/tlc0iGFGTPPkuxub1uRAv6XrnVnvSNjslZh5jIYA8GZoeEFPgJa3Qdu0GUS/YwoK8GOLnnaL9h/eH5LDJQ=="], + + "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.957.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-nhmgKHnNV9K+i9daumaIz8JTLsIIML9PE/HUks5liyrjUzenjW/aHoc7WJ9/Td/gPZtayxFnXQSJRb/fDlBuJw=="], + + "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.957.0", "", { "dependencies": { "@aws-sdk/types": "3.957.0", "@smithy/types": "^4.11.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-exueuwxef0lUJRnGaVkNSC674eAiWU07ORhxBnevFFZEKisln+09Qrtw823iyv5I1N8T+wKfh95xvtWQrNKNQw=="], + + "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.957.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.957.0", "@aws-sdk/types": "3.957.0", "@smithy/node-config-provider": "^4.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-ycbYCwqXk4gJGp0Oxkzf2KBeeGBdTxz559D41NJP8FlzSej1Gh7Rk40Zo6AyTfsNWkrl/kVi1t937OIzC5t+9Q=="], + + "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.957.0", "", { "dependencies": { "@smithy/types": "^4.11.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-Ai5iiQqS8kJ5PjzMhWcLKN0G2yasAkvpnPlq2EnqlIMdB48HsizElt62qcktdxp4neRMyGkFq4NzgmDbXnhRiA=="], + + "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.2", "", {}, "sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg=="], + "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], "@babel/compat-data": ["@babel/compat-data@7.28.5", "", {}, "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="], @@ -153,6 +252,8 @@ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.0", "", { "os": "win32", "cpu": "x64" }, "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg=="], + "@hiogawa/tiny-rpc": ["@hiogawa/tiny-rpc@0.2.3-pre.18", "", {}, "sha512-BiNHrutG9G9yV622QvkxZxF+PhkaH2Aspp4/X1KYTfnaQTcg4fFUTBWf5Kf533swon2SuVJwi6U6H1LQbhVOQQ=="], + "@hiogawa/utils": ["@hiogawa/utils@1.7.0", "", {}, "sha512-ghiEFWBR1NENoHn+lSuW7liicTIzVPN+8Srm5UedCTw43gus0mlse6Wp2lz6GmbOXJ/CalMPp/0Tz2X8tajkAg=="], "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], @@ -219,14 +320,22 @@ "@primeuix/styled": ["@primeuix/styled@0.7.4", "", { "dependencies": { "@primeuix/utils": "^0.6.1" } }, "sha512-QSO/NpOQg8e9BONWRBx9y8VGMCMYz0J/uKfNJEya/RGEu7ARx0oYW0ugI1N3/KB1AAvyGxzKBzGImbwg0KUiOQ=="], + "@primeuix/styles": ["@primeuix/styles@2.0.2", "", { "dependencies": { "@primeuix/styled": "^0.7.4" } }, "sha512-LNtkJsTonNHF5ag+9s3+zQzm00+LRmffw68QRIHy6S/dam1JpdrrAnUzNYlWbaY7aE2EkZvQmx7Np7+PyHn+ow=="], + "@primeuix/themes": ["@primeuix/themes@2.0.2", "", { "dependencies": { "@primeuix/styled": "^0.7.4" } }, "sha512-prwQvA3tDGBz8yWSUenaJUttEMCEvPvxwOfFhDPmSe1vwsfVKL2Nmh5eZvtPFQnxmIOPsHZS7zc0/L3CzJ83Eg=="], "@primeuix/utils": ["@primeuix/utils@0.6.3", "", {}, "sha512-/SLNQSKQ73WbBIsflKVqbpVjCfFYvQO3Sf1LMheXyxh8JqxO4M63dzP56wwm9OPGuCQ6MYOd2AHgZXz+g7PZcg=="], + "@primevue/auto-import-resolver": ["@primevue/auto-import-resolver@4.5.4", "", { "dependencies": { "@primevue/metadata": "4.5.4" } }, "sha512-YQHrZ9PQSG/4K2BwthA2Xuna4WyS0JMHajiHD9PljaDyQtBVwCadX5ZpKcrAUWR8E/1gjva8x/si0RYxxYrRJw=="], + "@primevue/core": ["@primevue/core@4.5.4", "", { "dependencies": { "@primeuix/styled": "^0.7.4", "@primeuix/utils": "^0.6.2" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-lYJJB3wTrDJ8MkLctzHfrPZAqXVxoatjIsswSJzupatf6ZogJHVYADUKcn1JAkLLk8dtV1FA2AxDek663fHO5Q=="], "@primevue/forms": ["@primevue/forms@4.5.4", "", { "dependencies": { "@primeuix/forms": "^0.1.0", "@primeuix/utils": "^0.6.2", "@primevue/core": "4.5.4" } }, "sha512-2TlD8oJEtb8vuKzY3jY0W+7NVBC/Qj0m57iWzpMUmGnEKg9sbQ2/ZiU1sTof710/liYgm4FneRTOYHIpVkiJNA=="], + "@primevue/icons": ["@primevue/icons@4.5.4", "", { "dependencies": { "@primeuix/utils": "^0.6.2", "@primevue/core": "4.5.4" } }, "sha512-DxgryEc7ZmUqcEhYMcxGBRyFzdtLIoy3jLtlH1zsVSRZaG+iSAcjQ88nvfkZxGUZtZBFL7sRjF6KLq3bJZJwUw=="], + + "@primevue/metadata": ["@primevue/metadata@4.5.4", "", {}, "sha512-jJFD0KYm8bPYgFo0JP3Dc2RkyXzrMI1XHQGsEKTysx9Jx2d1XdxtFji/ZsQeoo/RmwUNof5ciZ72URq37rnK+g=="], + "@quansync/fs": ["@quansync/fs@1.0.0", "", { "dependencies": { "quansync": "^1.0.0" } }, "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ=="], "@remix-run/node-fetch-server": ["@remix-run/node-fetch-server@0.8.1", "", {}, "sha512-J1dev372wtJqmqn9U/qbpbZxbJSQrogNN2+Qv1lKlpATpe/WQ9aCZfl/xSb9d2Rgh1IyLSvNxZAXPZxruO6Xig=="], @@ -279,12 +388,116 @@ "@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], + "@smithy/abort-controller": ["@smithy/abort-controller@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-rzMY6CaKx2qxrbYbqjXWS0plqEy7LOdKHS0bg4ixJ6aoGDPNUcLWk/FRNuCILh7GKLG9TFUXYYeQQldMBBwuyw=="], + + "@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA=="], + + "@smithy/chunked-blob-reader-native": ["@smithy/chunked-blob-reader-native@4.2.1", "", { "dependencies": { "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ=="], + + "@smithy/config-resolver": ["@smithy/config-resolver@4.4.5", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.7", "@smithy/types": "^4.11.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-HAGoUAFYsUkoSckuKbCPayECeMim8pOu+yLy1zOxt1sifzEbrsRpYa+mKcMdiHKMeiqOibyPG0sFJnmaV/OGEg=="], + + "@smithy/core": ["@smithy/core@3.20.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.8", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-stream": "^4.5.8", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-WsSHCPq/neD5G/MkK4csLI5Y5Pkd9c1NMfpYEKeghSGaD4Ja1qLIohRQf2D5c1Uy5aXp76DeKHkzWZ9KAlHroQ=="], + + "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.7", "@smithy/property-provider": "^4.2.7", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-CmduWdCiILCRNbQWFR0OcZlUPVtyE49Sr8yYL0rZQ4D/wKxiNzBNS/YHemvnbkIWj623fplgkexUd/c9CAKdoA=="], + + "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.7", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.11.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-DrpkEoM3j9cBBWhufqBwnbbn+3nf1N9FP6xuVJ+e220jbactKuQgaZwjwP5CP1t+O94brm2JgVMD2atMGX3xIQ=="], + + "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.7", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-ujzPk8seYoDBmABDE5YqlhQZAXLOrtxtJLrbhHMKjBoG5b4dK4i6/mEU+6/7yXIAkqOO8sJ6YxZl+h0QQ1IJ7g=="], + + "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-x7BtAiIPSaNaWuzm24Q/mtSkv+BrISO/fmheiJ39PKRNH3RmH2Hph/bUKSOBOBC9unqfIYDhKTHwpyZycLGPVQ=="], + + "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.7", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-roySCtHC5+pQq5lK4be1fZ/WR6s/AxnPaLfCODIPArtN2du8s5Ot4mKVK3pPtijL/L654ws592JHJ1PbZFF6+A=="], + + "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.7", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-QVD+g3+icFkThoy4r8wVFZMsIP08taHVKjE6Jpmz8h5CgX/kk6pTODq5cht0OMtcapUx+xrPzUTQdA+TmO0m1g=="], + + "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.8", "", { "dependencies": { "@smithy/protocol-http": "^5.3.7", "@smithy/querystring-builder": "^4.2.7", "@smithy/types": "^4.11.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-h/Fi+o7mti4n8wx1SR6UHWLaakwHRx29sizvp8OOm7iqwKGFneT06GCSFhml6Bha5BT6ot5pj3CYZnCHhGC2Rg=="], + + "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.2.8", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.2.0", "@smithy/chunked-blob-reader-native": "^4.2.1", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-07InZontqsM1ggTCPSRgI7d8DirqRrnpL7nIACT4PW0AWrgDiHhjGZzbAE5UtRSiU0NISGUYe7/rri9ZeWyDpw=="], + + "@smithy/hash-node": ["@smithy/hash-node@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-PU/JWLTBCV1c8FtB8tEFnY4eV1tSfBc7bDBADHfn1K+uRbPgSJ9jnJp0hyjiFN2PMdPzxsf1Fdu0eo9fJ760Xw=="], + + "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ZQVoAwNYnFMIbd4DUc517HuwNelJUY6YOzwqrbcAgCnVn+79/OK7UjwA93SPpdTOpKDVkLIzavWm/Ck7SmnDPQ=="], + + "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-ncvgCr9a15nPlkhIUx3CU4d7E7WEuVJOV7fS7nnK2hLtPK9tYRBkMHQbhXU1VvvKeBm/O0x26OEoBq+ngFpOEQ=="], + + "@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="], + + "@smithy/md5-js": ["@smithy/md5-js@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Wv6JcUxtOLTnxvNjDnAiATUsk8gvA6EeS8zzHig07dotpByYsLot+m0AaQEniUBjx97AC41MQR4hW0baraD1Xw=="], + + "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-GszfBfCcvt7kIbJ41LuNa5f0wvQCHhnGx/aDaZJCCT05Ld6x6U2s0xsc/0mBFONBZjQJp2U/0uSJ178OXOwbhg=="], + + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.1", "", { "dependencies": { "@smithy/core": "^3.20.0", "@smithy/middleware-serde": "^4.2.8", "@smithy/node-config-provider": "^4.3.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-middleware": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-gpLspUAoe6f1M6H0u4cVuFzxZBrsGZmjx2O9SigurTx4PbntYa4AJ+o0G0oGm1L2oSX6oBhcGHwrfJHup2JnJg=="], + + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.17", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.7", "@smithy/protocol-http": "^5.3.7", "@smithy/service-error-classification": "^4.2.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-MqbXK6Y9uq17h+4r0ogu/sBT6V/rdV+5NvYL7ZV444BKfQygYe8wAhDrVXagVebN6w2RE0Fm245l69mOsPGZzg=="], + + "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.8", "", { "dependencies": { "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-8rDGYen5m5+NV9eHv9ry0sqm2gI6W7mc1VSFMtn6Igo25S507/HaOX9LTHAS2/J32VXD0xSzrY0H5FJtOMS4/w=="], + + "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-bsOT0rJ+HHlZd9crHoS37mt8qRRN/h9jRve1SXUhVbkRzu0QaNYZp1i1jha4n098tsvROjcwfLlfvcFuJSXEsw=="], + + "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.7", "", { "dependencies": { "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-7r58wq8sdOcrwWe+klL9y3bc4GW1gnlfnFOuL7CXa7UzfhzhxKuzNdtqgzmTV+53lEp9NXh5hY/S4UgjLOzPfw=="], + + "@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.7", "", { "dependencies": { "@smithy/abort-controller": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/querystring-builder": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-NELpdmBOO6EpZtWgQiHjoShs1kmweaiNuETUpuup+cmm/xJYjT4eUjfhrXRP4jCOaAsS3c3yPsP3B+K+/fyPCQ=="], + + "@smithy/property-provider": ["@smithy/property-provider@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-jmNYKe9MGGPoSl/D7JDDs1C8b3dC8f/w78LbaVfoTtWy4xAd5dfjaFG9c9PWPihY4ggMQNQSMtzU77CNgAJwmA=="], + + "@smithy/protocol-http": ["@smithy/protocol-http@5.3.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-1r07pb994I20dD/c2seaZhoCuNYm0rWrvBxhCQ70brNh11M5Ml2ew6qJVo0lclB3jMIXirD4s2XRXRe7QEi0xA=="], + + "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-eKONSywHZxK4tBxe2lXEysh8wbBdvDWiA+RIuaxZSgCMmA0zMgoDpGLJhnyj+c0leOQprVnXOmcB4m+W9Rw7sg=="], + + "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-3X5ZvzUHmlSTHAXFlswrS6EGt8fMSIxX/c3Rm1Pni3+wYWB6cjGocmRIoqcQF9nU5OgGmL0u7l9m44tSUpfj9w=="], + + "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0" } }, "sha512-YB7oCbukqEb2Dlh3340/8g8vNGbs/QsNNRms+gv3N2AtZz9/1vSBx6/6tpwQpZMEJFs7Uq8h4mmOn48ZZ72MkA=="], + + "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.2", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-M7iUUff/KwfNunmrgtqBfvZSzh3bmFgv/j/t1Y1dQ+8dNo34br1cqVEqy6v0mYEgi0DkGO7Xig0AnuOaEGVlcg=="], + + "@smithy/signature-v4": ["@smithy/signature-v4@5.3.7", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-9oNUlqBlFZFOSdxgImA6X5GFuzE7V2H7VG/7E70cdLhidFbdtvxxt81EHgykGK5vq5D3FafH//X+Oy31j3CKOg=="], + + "@smithy/smithy-client": ["@smithy/smithy-client@4.10.2", "", { "dependencies": { "@smithy/core": "^3.20.0", "@smithy/middleware-endpoint": "^4.4.1", "@smithy/middleware-stack": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-stream": "^4.5.8", "tslib": "^2.6.2" } }, "sha512-D5z79xQWpgrGpAHb054Fn2CCTQZpog7JELbVQ6XAvXs5MNKWf28U9gzSBlJkOyMl9LA1TZEjRtwvGXfP0Sl90g=="], + + "@smithy/types": ["@smithy/types@4.11.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-mlrmL0DRDVe3mNrjTcVcZEgkFmufITfUAPBEA+AHYiIeYyJebso/He1qLbP3PssRe22KUzLRpQSdBPbXdgZ2VA=="], + + "@smithy/url-parser": ["@smithy/url-parser@4.2.7", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-/RLtVsRV4uY3qPWhBDsjwahAtt3x2IsMGnP5W1b2VZIe+qgCqkLxI1UOHDZp1Q1QSOrdOR32MF3Ph2JfWT1VHg=="], + + "@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="], + + "@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="], + + "@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.2.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA=="], + + "@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="], + + "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="], + + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.16", "", { "dependencies": { "@smithy/property-provider": "^4.2.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-/eiSP3mzY3TsvUOYMeL4EqUX6fgUOj2eUOU4rMMgVbq67TiRLyxT7Xsjxq0bW3OwuzK009qOwF0L2OgJqperAQ=="], + + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.19", "", { "dependencies": { "@smithy/config-resolver": "^4.4.5", "@smithy/credential-provider-imds": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/property-provider": "^4.2.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-3a4+4mhf6VycEJyHIQLypRbiwG6aJvbQAeRAVXydMmfweEPnLLabRbdyo/Pjw8Rew9vjsh5WCdhmDaHkQnhhhA=="], + + "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-s4ILhyAvVqhMDYREeTS68R43B1V5aenV5q/V1QpRQJkCXib5BPRo4s7uNdzGtIKxaPHCfU/8YkvPAEvTpxgspg=="], + + "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="], + + "@smithy/util-middleware": ["@smithy/util-middleware@4.2.7", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-i1IkpbOae6NvIKsEeLLM9/2q4X+M90KV3oCFgWQI4q0Qz+yUZvsr+gZPdAEAtFhWQhAHpTsJO8DRJPuwVyln+w=="], + + "@smithy/util-retry": ["@smithy/util-retry@4.2.7", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-SvDdsQyF5CIASa4EYVT02LukPHVzAgUA4kMAuZ97QJc2BpAqZfA4PINB8/KOoCXEw9tsuv/jQjMeaHFvxdLNGg=="], + + "@smithy/util-stream": ["@smithy/util-stream@4.5.8", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.8", "@smithy/node-http-handler": "^4.4.7", "@smithy/types": "^4.11.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ZnnBhTapjM0YPGUSmOs0Mcg/Gg87k503qG4zU2v/+Js2Gu+daKOJMeqcQns8ajepY8tgzzfYxl6kQyZKml6O2w=="], + + "@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="], + + "@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="], + + "@smithy/util-waiter": ["@smithy/util-waiter@4.2.7", "", { "dependencies": { "@smithy/abort-controller": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-vHJFXi9b7kUEpHWUCY3Twl+9NPOZvQ0SAi+Ewtn48mbiJk4JY9MZmKQjGB4SCvVb9WPiSphZJYY6RIbs+grrzw=="], + + "@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="], + "@speed-highlight/core": ["@speed-highlight/core@1.2.14", "", {}, "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/node": ["@types/node@25.0.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA=="], + "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], + "@unhead/vue": ["@unhead/vue@2.1.1", "", { "dependencies": { "hookable": "^5.5.3", "unhead": "2.1.1" }, "peerDependencies": { "vue": ">=3.5.18" } }, "sha512-WYa8ORhfv7lWDSoNpkMKhbW1Dbsux/3HqMcVkZS3xZ2/c/VrcChLj+IMadpCd1WNR0srITfRJhBYZ1i9hON5Qw=="], "@unocss/astro": ["@unocss/astro@66.5.12", "", { "dependencies": { "@unocss/core": "66.5.12", "@unocss/reset": "66.5.12", "@unocss/vite": "66.5.12" }, "peerDependencies": { "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0" }, "optionalPeers": ["vite"] }, "sha512-ynhlljsTGTHAcQHbpqxe3IXEDXjPm9IdeDWAhPet7UiGXhW230vEZ+1/OoARqLysVSVz4pPb81MDgS167Oo4Nw=="], @@ -369,6 +582,12 @@ "@vue/shared": ["@vue/shared@3.5.26", "", {}, "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A=="], + "@vueuse/core": ["@vueuse/core@14.1.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "14.1.0", "@vueuse/shared": "14.1.0" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw=="], + + "@vueuse/metadata": ["@vueuse/metadata@14.1.0", "", {}, "sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA=="], + + "@vueuse/shared": ["@vueuse/shared@14.1.0", "", { "peerDependencies": { "vue": "^3.5.0" } }, "sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw=="], + "acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="], "acorn-walk": ["acorn-walk@8.3.2", "", {}, "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A=="], @@ -379,13 +598,15 @@ "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], + "bowser": ["bowser@2.13.1", "", {}, "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw=="], + "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="], "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], "caniuse-lite": ["caniuse-lite@1.0.30001762", "", {}, "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw=="], - "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], @@ -399,7 +620,7 @@ "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="], - "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + "confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="], "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], @@ -437,6 +658,10 @@ "exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="], + "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], + + "fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -457,6 +682,8 @@ "is-arrayish": ["is-arrayish@0.3.4", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="], + "is-mobile": ["is-mobile@5.0.0", "", {}, "sha512-Tz/yndySvLAEXh+Uk8liFCxOwVH6YutuR74utvOcu7I9Di+DwM0mtdPVZNaVvvBUM2OXxne/NhOs1zAO7riusQ=="], + "is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="], "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], @@ -469,6 +696,8 @@ "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], + "local-pkg": ["local-pkg@1.1.2", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.3.0", "quansync": "^0.2.11" } }, "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A=="], + "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], @@ -509,13 +738,15 @@ "pinia": ["pinia@3.0.4", "", { "dependencies": { "@vue/devtools-api": "^7.7.7" }, "peerDependencies": { "typescript": ">=4.5.0", "vue": "^3.5.11" }, "optionalPeers": ["typescript"] }, "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw=="], - "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + "pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], - "quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], + "primevue": ["primevue@4.5.4", "", { "dependencies": { "@primeuix/styled": "^0.7.4", "@primeuix/styles": "^2.0.2", "@primeuix/utils": "^0.6.2", "@primevue/core": "4.5.4", "@primevue/icons": "4.5.4" } }, "sha512-nTyEohZABFJhVIpeUxgP0EJ8vKcJAhD+Z7DYj95e7ie/MNUCjRNcGjqmE1cXtXi4z54qDfTSI9h2uJ51qz2DIw=="], - "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], + "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], + + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], @@ -535,10 +766,14 @@ "stoppable": ["stoppable@1.1.0", "", {}, "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw=="], + "strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="], + "superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="], "supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + "tailwind-merge": ["tailwind-merge@3.4.0", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="], + "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], @@ -563,8 +798,12 @@ "unocss": ["unocss@66.5.12", "", { "dependencies": { "@unocss/astro": "66.5.12", "@unocss/cli": "66.5.12", "@unocss/core": "66.5.12", "@unocss/postcss": "66.5.12", "@unocss/preset-attributify": "66.5.12", "@unocss/preset-icons": "66.5.12", "@unocss/preset-mini": "66.5.12", "@unocss/preset-tagify": "66.5.12", "@unocss/preset-typography": "66.5.12", "@unocss/preset-uno": "66.5.12", "@unocss/preset-web-fonts": "66.5.12", "@unocss/preset-wind": "66.5.12", "@unocss/preset-wind3": "66.5.12", "@unocss/preset-wind4": "66.5.12", "@unocss/transformer-attributify-jsx": "66.5.12", "@unocss/transformer-compile-class": "66.5.12", "@unocss/transformer-directives": "66.5.12", "@unocss/transformer-variant-group": "66.5.12", "@unocss/vite": "66.5.12" }, "peerDependencies": { "@unocss/webpack": "66.5.12", "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0" }, "optionalPeers": ["@unocss/webpack", "vite"] }, "sha512-3WdSuM+SOjVpXDtffTuSvYTMuufpFzBehu2b4Tr7DcoIUxGouZn3mdxCLx3PiEuK0ih40Fo7Sjm+J4mccHfwLg=="], + "unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="], + "unplugin-utils": ["unplugin-utils@0.3.1", "", { "dependencies": { "pathe": "^2.0.3", "picomatch": "^4.0.3" } }, "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog=="], + "unplugin-vue-components": ["unplugin-vue-components@30.0.0", "", { "dependencies": { "chokidar": "^4.0.3", "debug": "^4.4.3", "local-pkg": "^1.1.2", "magic-string": "^0.30.19", "mlly": "^1.8.0", "tinyglobby": "^0.2.15", "unplugin": "^2.3.10", "unplugin-utils": "^0.3.1" }, "peerDependencies": { "@babel/parser": "^7.15.8", "@nuxt/kit": "^3.2.2 || ^4.0.0", "vue": "2 || 3" }, "optionalPeers": ["@babel/parser", "@nuxt/kit"] }, "sha512-4qVE/lwCgmdPTp6h0qsRN2u642tt4boBQtcpn4wQcWZAsr8TQwq+SPT3NDu/6kBFxzo/sSEK4ioXhOOBrXc3iw=="], + "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], "vite": ["vite@7.3.0", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg=="], @@ -577,6 +816,8 @@ "vue-router": ["vue-router@4.6.4", "", { "dependencies": { "@vue/devtools-api": "^6.6.4" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg=="], + "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], + "workerd": ["workerd@1.20251210.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20251210.0", "@cloudflare/workerd-darwin-arm64": "1.20251210.0", "@cloudflare/workerd-linux-64": "1.20251210.0", "@cloudflare/workerd-linux-arm64": "1.20251210.0", "@cloudflare/workerd-windows-64": "1.20251210.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-9MUUneP1BnRE9XAYi94FXxHmiLGbO75EHQZsgWqSiOXjoXSqJCw8aQbIEPxCy19TclEl/kHUFYce8ST2W+Qpjw=="], "wrangler": ["wrangler@4.54.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.1", "@cloudflare/unenv-preset": "2.7.13", "blake3-wasm": "2.1.5", "esbuild": "0.27.0", "miniflare": "4.20251210.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20251210.0" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20251210.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-bANFsjDwJLbprYoBK+hUDZsVbUv2SqJd8QvArLIcZk+fPq4h/Ohtj5vkKXD3k0s2bD1DXLk08D+hYmeNH+xC6A=="], @@ -589,7 +830,13 @@ "youch-core": ["youch-core@0.3.3", "", { "dependencies": { "@poppinss/exception": "^1.2.2", "error-stack-parser-es": "^1.0.5" } }, "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA=="], - "zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], + "zod": ["zod@4.3.2", "", {}, "sha512-b8L8yn4rIVfiXyHAmnr52/ZEpDumlT0bmxiq3Ws1ybrinhflGpt12Hvv54kYnEsGPRs6o/Ka3/ppA2OWY21IVg=="], + + "@aws-crypto/sha1-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], + + "@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], + + "@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], "@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], @@ -597,20 +844,54 @@ "@jridgewell/remapping/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + "@quansync/fs/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], + + "@unocss/cli/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + "@unocss/transformer-attributify-jsx/@babel/parser": ["@babel/parser@7.27.7", "", { "dependencies": { "@babel/types": "^7.27.7" }, "bin": "./bin/babel-parser.js" }, "sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q=="], "@unocss/transformer-attributify-jsx/@babel/traverse": ["@babel/traverse@7.27.7", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.27.5", "@babel/parser": "^7.27.7", "@babel/template": "^7.27.2", "@babel/types": "^7.27.7", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-X6ZlfR/O/s5EQ/SnUSLzr+6kGnkg8HXGMzpgsMsrJVcfDtH1vIp6ctCN4eZ1LS5c0+te5Cb6Y514fASjMRJ1nw=="], + "@unocss/vite/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + "@vitejs/plugin-vue-jsx/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.9-commit.d91dfb5", "", {}, "sha512-8sExkWRK+zVybw3+2/kBkYBFeLnEUWz1fT7BLHplpzmtqkOfTbAQ9gkt4pzwGIIZmg4Qn5US5ACjUBenrhezwQ=="], "@vue/devtools-kit/perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], + "miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], + "mlly/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + "sharp/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + "unconfig/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], + + "unconfig-core/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], + + "unplugin/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "vue-router/@vue/devtools-api": ["@vue/devtools-api@6.6.4", "", {}, "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="], + "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], + + "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], + + "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], + + "@unocss/cli/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], + "@unocss/transformer-attributify-jsx/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": "./bin/babel-parser.js" }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + + "@unocss/vite/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], + + "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + + "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], + + "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], + + "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], } } diff --git a/package.json b/package.json index d585c83..bdd16b4 100644 --- a/package.json +++ b/package.json @@ -4,27 +4,38 @@ "scripts": { "dev": "vite", "build": "vite build", - "preview": "$npm_execpath run build && vite preview", - "deploy": "$npm_execpath run build && wrangler deploy", + "preview": "vite preview", + "deploy": "wrangler deploy", "cf-typegen": "wrangler types --env-interface CloudflareBindings" }, "dependencies": { + "@aws-sdk/client-s3": "^3.946.0", + "@aws-sdk/s3-presigned-post": "^3.946.0", + "@aws-sdk/s3-request-presigner": "^3.946.0", + "@hiogawa/tiny-rpc": "^0.2.3-pre.18", "@hiogawa/utils": "^1.7.0", "@primeuix/themes": "^2.0.2", "@primevue/forms": "^4.5.4", "@unhead/vue": "^2.1.1", + "is-mobile": "^5.0.0", + "@vueuse/core": "^14.1.0", "clsx": "^2.1.1", "hono": "^4.11.3", "pinia": "^3.0.4", + "primevue": "^4.5.4", "vue": "^3.5.26", - "vue-router": "^4.6.4" + "vue-router": "^4.6.4", + "tailwind-merge": "^3.4.0", + "zod": "^4.3.2" }, "devDependencies": { "@cloudflare/vite-plugin": "^1.17.1", + "@primevue/auto-import-resolver": "^4.5.4", "@types/node": "^25.0.3", "@vitejs/plugin-vue": "^6.0.3", "@vitejs/plugin-vue-jsx": "^5.1.3", "unocss": "^66.5.12", + "unplugin-vue-components": "^30.0.0", "vite": "^7.3.0", "vite-ssr-components": "^0.5.2", "wrangler": "^4.54.0" diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000..c9e056f Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000..a41198f Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..ed343ee Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..90bf4cf Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..711a7f8 Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/favicon.ico b/public/favicon.ico index 5431643..b8908b5 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/index.m3u8 b/public/index.m3u8 new file mode 100644 index 0000000..071ef9b --- /dev/null +++ b/public/index.m3u8 @@ -0,0 +1,1549 @@ +#EXTM3U +#EXT-X-VERSION:3 +#EXT-X-TARGETDURATION:5 +#EXT-X-MEDIA-SEQUENCE:0 +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4d7ea3939ee2484fa8fd~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765707&x-signature=HScqa5R%2FyC%2BmAEL4aDs6pkWwvAw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dae671241b16444899271~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765709&x-signature=3%2BkZ2qz%2FJD2mlDwiHRZYnB5IRfc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d28bd8505592c45cbb0fb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765712&x-signature=CkeEMRiv2GxpmTt%2BhsWM5ovPdsA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbb83578b5d424439b0e9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765714&x-signature=xumS9dU%2F2zASLv0rdaAlolHbaGs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4cbb77f488504a6296c0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765717&x-signature=mM%2FeXBRkLDarXsNhznH6xisw4g8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d669b1dd09d4d427d8f15~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765719&x-signature=HNel9Gh3V9ddwYJZexL3eSYqc1U%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1930cd6338eb4c298d63~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765722&x-signature=es2g5LLFc9tIutdvYb5bxsGtaWs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da5b66caa1132459da446~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765724&x-signature=JZXcLcLckUMHxeHKV2yS7HU%2B%2Fuw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0daaecd930a24a45a7ab5c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765726&x-signature=rN26o6qALKTwlgu2AxQpnijl3is%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d85326a87bd5b480ab283~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765729&x-signature=kg6sa7QJUFMSKTAbGjJ68Hbu6K4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d71d54b95f9a7452b9d9e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765731&x-signature=p%2B9o%2Bgbqa5Z%2FnT43X49pj6V%2BTqA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0b183dfe20724d209cf6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765734&x-signature=v3MR%2B7kVEbdFhULByyoesrgzkMc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8f02f471e6574925be9a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765737&x-signature=6IGUNHBKT1M5NoU3%2FWHPFZL9zJA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df51e044728c14fc79e21~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765738&x-signature=rgHAUk3s3UkA4WiLlyzRhND6Uoc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db048ad7d6a6d4c6e99d5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765740&x-signature=sBMaOveFVc4%2BXmZTfc%2BsTP8pHno%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d99b569f5ed574cf6b243~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765742&x-signature=e4VsfRnUFY4KFJbBEkRGF8x%2BN40%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d44753227715949e5a690~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765743&x-signature=P2YXFkxoKMTTqYQI1mEaTXjqOLU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dab8047723f93437c87d4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765745&x-signature=98F1Uo%2B3vPWbGg7XCt6ZCUkHpx0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc2f37fe35c1d48a28f1d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765747&x-signature=nM8SqkyMTlrT10vVJr%2BR%2Bj5%2BYfk%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d04433e6c3bc74107a2c9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765750&x-signature=Ch2COwcZZKJi7ozee9tWW1%2Be61k%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db0ca4285d13f44408ebc~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765751&x-signature=C%2F9jFwBytgghH9Owjdkn489Tnko%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d21034578d2f945ddae48~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765754&x-signature=XFy9RmUTAINgYORiT0W98y9cVt0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d464f28800c154955a573~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765756&x-signature=e6IUvdFv%2FamSuk3M6ivWfBRL57w%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8b3b29c58a79461e9752~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765758&x-signature=n7QLDI%2B6mkUeAf9B0%2BVkLlDjPiw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d54cd0ade18c24a03a33f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765760&x-signature=UIz0%2FTCjovQtinzyyoxGiSxvxIU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6b19c6dee35c48618f8e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765762&x-signature=9p0%2Fmlqb4iU615k6Omkmd0S2TE4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db85f80c68e274646b726~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765764&x-signature=HkLybum4ZkrkPB9SDuhOun3p%2BWE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2f90697530e8445aa2ab~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765767&x-signature=LrGBq2WQqdfB7VTdaEp9d%2Bl3jO8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6be4f8b327b140519e64~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765773&x-signature=O%2F6ITuiAR8gRmR5C4cZx00VJzbU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4af4166f9dc347eda44d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765775&x-signature=%2By1QxK21X7PGIJKwct6ruAomMCw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d864eebaa042a4ee59722~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765778&x-signature=HZz1vTO7NWKxZlta8Ju3R6xxHjU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da3f079eaa85a4f52afeb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765781&x-signature=%2BhecGI5R9p1x4ZwYKGApkqK1w9g%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4a0e57ee21fb47e99883~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765783&x-signature=IzQhSj596vuHYZeZ5bLvC3x%2FU5c%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db8eeac45cf094255b919~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765787&x-signature=MH4iD%2BEat%2FmDD2KmvS0N39Me548%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d57c4f73ff07943509102~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765790&x-signature=JmyS75HZF%2F6EiutGhOSwKYSpvp4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de12aff0063ce4b249aaa~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765793&x-signature=QTipE30as3uSc1hd5YSuLQm%2FgIk%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d842e2ac7d67146088786~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765795&x-signature=s24kZjHI%2B47ftTglB2zK4jpwQPM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbb388c22b50b44308d69~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765799&x-signature=Av4qAlXiyvZSUPeCb2rIPLaKi3w%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d55d28f62f7bc4f129b8b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765802&x-signature=45kyQjh91R6Ip0pFlnZhkvXbrG0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d29dd5be6bf604a1c81aa~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765804&x-signature=%2FXs3Pjcr%2F%2Fb3EK0fjsbTNKdaE1w%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d48671587662d40c4a34b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765805&x-signature=u8cMLMKPZcXU33SvOXsheZrRj34%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddfa9206570d742fbb170~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765807&x-signature=%2BSUlNBDWPwyxx0LoW1FgHwwuris%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd8fb1e8ba3534ada9b74~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765809&x-signature=31FqWKKFNKDwPQ0gBzGRB4w8ONo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc472e89f2a5441dbb99d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765811&x-signature=Q4DDsKE%2B0JwUBH6XW7fVqPRXhek%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d267b689e51c24e84924e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765813&x-signature=QfhUf7eLUYDlmHtp4E5WNRgWq2k%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d186af3f5d90f437ebe83~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765815&x-signature=GZHzOc4s3HC1t4jDPE09dojNp8o%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5a7cbdda811448beb585~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765817&x-signature=gaPltvwe%2B58uhnGZlLpKQxxIWic%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4bbcb84464824ede83b1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765819&x-signature=GUjMFzUHciQZH0kxzVQtFMrH5mE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddf36f4a4fb7b46d489cc~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765822&x-signature=4dWVebzyxnArom8mjGI06Xy%2BCJo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4afaf9697ef8403a8fd8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765824&x-signature=fQMabIbVlHPz9zpp9hiaGAmXdig%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd46cf38ece964f0a8d18~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765826&x-signature=YrbYruRNfwZYY5euIocuSeoTIkA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d58927d208cc74a8eb99c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765828&x-signature=jg5vovq11gHmUHU63nTUVzOd3gs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d90cd1c64a4e74a669990~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765829&x-signature=sawymrKHXeaKCxYZ1sDqFj4Ze0E%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da71f6fac92eb4f249875~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765832&x-signature=MMZNea6Lom3K3V85DEcQqAjjwlk%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5123bf12717e48818ade~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765834&x-signature=ORJsDuayNsX6l43DQ%2BXRl2y0wrE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0deb1db8d220e740bfafea~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765836&x-signature=Eht3kmU5w3SGAkoqMaAleWbSU24%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0b0ed4a1d12e483fb0df~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765838&x-signature=TT4R41MtqNzrIhG3pOgkFw9gYJA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db15d3b1b5b1140ee9a4f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765840&x-signature=NNuiDhxGhlv6IPPsTi%2FwvaTHXuw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da8b850d9753b46e99041~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765845&x-signature=cuRSr7SCrw6VRvJMI0psEMo4nbU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d10741acbf6404d398341~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765847&x-signature=%2BwnWuD6rzP1TWB2CJmCIOE3Ll24%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d36527b878808484b87bb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765849&x-signature=SvLuQHTd8RuHTRovPLDeWJ1Sjkg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d99492200fcc840eca65d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765851&x-signature=DS0j5ET%2F3274uThOK5jZCOmQUnM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d12f5b59db7914cd3a261~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765854&x-signature=McDQS6gvf4m30i5hA2%2FjDlOH7mQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4ff57836327d46009616~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765855&x-signature=bR8frGksdo7LPLOVm0DMJ1p48EI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0698d95a2dc34d9b8518~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765857&x-signature=M%2FAq1uycXx8ut0yxBErRGzk7nX4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da3482deb671f46d9b92a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765865&x-signature=JSDCQPAVC2vZ%2BgBo7cT1MOU%2B6uY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8a14caab12ec40ae9c57~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765867&x-signature=8e4%2FXPKEMJeqr0SV4Lb1BrZoJFE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0b0db2b0cba54fedbfa5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765869&x-signature=Zx925PFi9px%2BRavXZXJdM2fVoZg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d30d9e86da4714084a2cb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765872&x-signature=Wx8tKCEWTCcC94KXeprXvNSrdGw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df51b2e4f84374786a89c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765874&x-signature=cSKviOmZdy8hg0mqFmsBeSSOkRg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0deba0ebbdcdc4470783b3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765877&x-signature=BAgz%2FpuT1eskBdIvEk%2BQvq2rwWQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db38d0ea25a56487c9ad3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765878&x-signature=qWsZSsvDgD%2BcjrIXJkkwjFoPp1s%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc5b950771194475c8180~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765880&x-signature=BVbxOiHCngraKwdAOkmzkEnHWW4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd5c4553be6744f49bebb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765882&x-signature=V0ggHky%2F0fizuU4WG1AlQIm60W0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d559b029a64eb4f639e78~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765884&x-signature=QycSY8SOYoQFkjT9ntP2RqRZDd8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd8d273580b69426d948e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765887&x-signature=aAiIjcU5Zm9wXTJrfJfKFFbeWAo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbb8bb3b5979c4d4da327~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765889&x-signature=KXsWVoEV6N0NS14OZItSeYDIWwA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2cf251b134e24f2bac8c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765892&x-signature=%2B6a7ozD22pP4l3JIkSZXmq8YXyM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d407dca861acf4824b6c9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765893&x-signature=vl96r2kzg8moPPzvN4K6pORlzPY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3b84f32523fa4145a19a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765895&x-signature=ZmGUixzgq0FQMJ6GgDI9oh6tHws%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddca38e0f8e3d435495b2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765897&x-signature=sLY3fmgOzNWY1Lkxhg7Jd0tmk%2Bw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7fc1576e9e5a4f36a58f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765899&x-signature=hraiMVkz88yNjDFtFac8bM%2FPZuE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd56a1f6222fe4c5b88b2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765902&x-signature=s5BzTklCgEDAQyzyJ2qmBpnUq%2Bc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8efe86f518ff49fdb347~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765905&x-signature=rQ9Z7yMyrQ0DhzZvnSZZkUYmx%2BQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5be98e8c17884f2e8fc5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765906&x-signature=tcarw3Ind3VPt2OlDDWdlk3xlVQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dcaabb9436b6b40edad69~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765914&x-signature=gG8GRia%2FxycEBsTATim8WoHCZUo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dca2e6f6bf2434bf2a688~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765918&x-signature=jchhp1Z254U4HQitoPijMqjW59I%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d140e481c3c9e449f96db~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765926&x-signature=U8VJFMbWVJS9Mu2jLuPWxBi%2FdD4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d40bf235a8e9443d4913e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765928&x-signature=8Ulu3clZawSlwqeAjkRI5XfzWw4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de5a01e8567ba4437b412~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765930&x-signature=jBtgE4%2BoRqGhWYPCvtTCk1tAQ70%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d150f6f639d1741549dfe~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765936&x-signature=TJ7K8o9pmzH1YSX%2FMNBj57IJFkw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d063c138854414a00a2ea~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765943&x-signature=LPJRg8RvSLJVumV1xWg58fXHhKA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0defbfdb82770d4dd2b816~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765948&x-signature=XhFtnGmyveuUYW27m1zk%2Bb2lu3Q%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7b3eecbd0a8b4d05a862~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765950&x-signature=OMgFNUom%2BT7M%2B3UAWrRupKk0qs8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0b78452af7524b42913b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765952&x-signature=BTmfROwaniz6Q0E46RmoOVsD4UU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df48ed909ca73456e8348~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765958&x-signature=mrSqeXlocyEqYBH8zZxxS0%2BEC4o%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df9a74af01d9947dea3df~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765961&x-signature=ErEQA7rJvS%2BN%2FlBd68IkPpAGgcI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d540394f39be24261aadd~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765963&x-signature=E9Xa6%2FrDBvN9Dq3v2xeRYzgFyhc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2da41c1198874ac8b033~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765965&x-signature=bZVSo%2BmpqIiKkhrpnrUpH9CG3yU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d47bb735caf5f44628e03~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765967&x-signature=jvDgXRpjZAwLkG2HHijNuswLtko%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0debf05b10d99549119fb9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765970&x-signature=kQcpTU2IIYymksQGF1RZ2mbBwWc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9858821c44c7412bbfd2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765972&x-signature=%2FE94URdaHCnmpgdh0zr4uMCSd%2F4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da7f0e1aed0b64a07b480~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765974&x-signature=m7286Gx9CZczBdUW9msSeFXbSxs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d70ef3d89212049c0af15~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765977&x-signature=P1QjrUj1Fgz1Y5d2UEAH30UeofE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d78fceafc217a4a95a3e5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765978&x-signature=JmUWIElxOE%2Bnd584rjRmbhc%2FlRg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc147a2e72ac84e63b267~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765980&x-signature=w0NbKcTb%2FbzXX%2Bk0rokh5saiunI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc6e94a7a2be14cc5b30c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765981&x-signature=Ehvu0LPVWO8cHWyLR8kBUwMANb4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d654b75f4c6fb4f9087a3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765984&x-signature=QJUPaJ2NBfX8BQBkqejjQWS2Z7k%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d266bc8895d634be5a057~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765985&x-signature=U6o4pPPTS75MdNkpKgUOoAPRvJc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1929723653664bebad7e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765986&x-signature=q2Zv0X6bzrrs4eJH%2BKPyj2%2Fpz3g%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d22c3df25485f4620b9ac~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765989&x-signature=R%2F3JQqAP55woaa6A0ZmMx%2B1c8p0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6f1fb5579ce3488eae59~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765991&x-signature=Y6wjpzuQxjEGY10EyBwD2CC6SFs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc4f57c641f254b0fb8b3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765993&x-signature=Zhncfab6Zkf2GHOu98un762LwF4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d72b9683413f34b88bc7f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765995&x-signature=VT1KqtkaUWJL4ilUk7u1jr4%2F5wo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d05378b047043491d8942~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765996&x-signature=axABkxVw7ylm3sWlwW81Ey%2BwH7E%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d747005b4b7504936a8a5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790765999&x-signature=tKKtV9bszOVsfLun8bfaa2Nx5p8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9c473f39038946e497f3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766001&x-signature=udgnVbnZWjkrrQfF4AOrGK3jYqs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d977ef72ebddb4f929397~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766002&x-signature=80YGMgwMS60MHcRW2sfExyBagk4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3802b2871f6e4d0388a0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766009&x-signature=0pl%2BBUhSrFi8orwJFj1M8ipcY6c%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d085cf3d90cbf406999f8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766011&x-signature=Lre5ZADgXydAvBY4x5bKg0ymeqE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db4acb15e54e846b0b884~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766015&x-signature=p5sr0KvFJ%2FV3kN406AqpCqnhPpo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd1ad934b703d439596ca~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766018&x-signature=aCvgUd3KIrPVcmUw7TX3KpK4UNE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dff18ab15304944c9a564~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766020&x-signature=DsqNgscRterMEYj%2FPBHoRsy%2B7JA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d35c083f3ed7544ab91a7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766023&x-signature=%2Bql5fRSq4ZMrAHDLkgkzhHurk4I%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d61c2d78a59c1494694c7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766024&x-signature=Oa3eNSyN4Dh8yuA2955PvKzKPTE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0044a4185ea944e8b495~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766026&x-signature=Gi%2FQrvHGnjwZcfziEEGdEn16U9c%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc47d27c1e2bc4f26bad7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766028&x-signature=G3jPsOtf1XrrynQ1CY5vtutkCQs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d18a23806006a414d9745~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766030&x-signature=WvVMOQ0xhNJKsvn8QqMHl%2FOpOf8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd704b5ab44d04f4a8d9f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766032&x-signature=rExaoCRaqMPExWxb1oFkxg9GXwI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dca1cbe0aa5f74582879e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766034&x-signature=Qkdx45zIXBvaOJS3xFJ6RH6wvKY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8664bee0f53446ffb9cc~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766036&x-signature=fplp8s2%2FWO1pgYZN6k46B0d9f%2BI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d427cd1a6b6554747b814~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766038&x-signature=4URpKxn0JbWd%2FbWlFKsH89yobjw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d26655e8b4c2643d89e80~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766040&x-signature=cMAXUWXP0PCHUA9cxTrudDQgo5Q%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dde3c1aa6d8a74d54be82~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766042&x-signature=jmRKWDjtBruuyW4Zo1zccYcsqiI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d24ad2bd4a6a24c7d8700~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766044&x-signature=XvYp7OTrz1%2Bi44DqvgoCEy1FtTM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d040015007e5845cf8ec8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766046&x-signature=pMCS0PrOEQAWSPWhKJqmo1FB5oQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7fb8f0522d894f53ae24~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766048&x-signature=O3yoQVJfhD3rZcNtG%2FIDmj0IDS0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4feb67566a8d4d03b4a8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766050&x-signature=Ju%2BQM6b7wh9uDQGN%2BmgJiOchVjo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0c35eaa05b0049529b5a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766053&x-signature=XCLN0pdRpKcQUY4JreCasJ14JWw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc90f6e3928cb492eaec7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766055&x-signature=oX3VT5gzswnN6bpggC7DsJl9C6c%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6ceac1fa659542ae9d0d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766056&x-signature=UdHveZvELa5CROhTXu%2BHSc76%2Fis%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3f4109157a75458f9b4c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766058&x-signature=eVyOAl%2BSpVhgXPh2wk%2BN5NIPMwo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc9bcb37a6a8b4c97a1c0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766060&x-signature=QkSCk%2B9LbxY6FnGv1GE5v7IiwhE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8d338b301cfb4478b651~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766062&x-signature=L7grPFfENuuqv8MFiyds5AIBdW4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6c193e6ad26f47fa8a51~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766064&x-signature=g8sRR3hxcWc3WJ35v1o5TkRoMIo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbe9860bd89db4cc5b9ad~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766066&x-signature=BVQ01HMpfF%2BTubzaSeVpN%2FnOyKY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0deca6be33a05945c28b37~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766069&x-signature=ZcoBlprUIgL8OBf2AphImrr5DsA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3050c2366fb34d47b5a9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766071&x-signature=Bal4O7s6wuBM3FtwA%2F98imPg2%2Bg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d108a81a04f1849118407~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766073&x-signature=5pFFTrpUo3ULuT%2FR4moYe1vBW8s%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d411a4ecbf0324841b05b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766075&x-signature=mcwr%2FI0ygz0Q193SuwAWkxZi7GE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d51e26dedfd2c45a8bcb0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766077&x-signature=YHdZOStCNSsPQsgo1cDCyqy4dFM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8cfec31007ad4a36a6ac~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766078&x-signature=V6BpVfNZmI6bwUd6ZBhskXEslqA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0ad04d81e8114d959773~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766081&x-signature=f7bi7pmm6kJBba%2BX%2Bc%2Fp96rbUjQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dacc384a54cad41e980e8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766089&x-signature=49zih4KmQ3FBpY0UuJRlwWgotlw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d94067421466b455ab4be~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766091&x-signature=QAX%2Bi7WnG0MhnoH4M4GKeLCesvw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2ffdd178d60543908d11~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766098&x-signature=GtYnV3rZjpzHiJK92l2ebt3voDI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d355e4176e5b44d97b197~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766104&x-signature=7sM9SQCsvv%2BFvmtf3lfAZ6T6jq0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de2cac5ce298246ed83d6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766106&x-signature=IqHI7tZOR27wHSx4xiiUJ%2FiZn%2BE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db414f333110a47fb9e22~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766112&x-signature=c7E1o%2F4cw1kjAfP80K%2ByXlCW%2F30%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dadf7078c922a40a882a4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766114&x-signature=FNXqwQybfPy6Co3R5PZ909AImJQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d99ebcc1c1702428d8a76~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766119&x-signature=LSCDY4%2F2aw3Uju69MhJvPBALkIw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dea6afc79c7c944d38a76~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766121&x-signature=deYaekc2QfqThvM2gT3KepmKo58%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da19fe2e5a5a345c1ad13~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766124&x-signature=FUXN00SXnDOOiqsjxCIvSjVJzNM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1e2f11f313434d4aa0a5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766126&x-signature=AseK4Epyq6QL3qA5IU5%2But0wsqI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df6bee50d2acc406d8652~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766128&x-signature=XUweoBXRNLf2XJpdlzIrWexNeXY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5e64ce047eb34a9dbd2b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766130&x-signature=kT097%2BJRrlQL67YeARqcuZvAo3g%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da4009585fa354752968f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766133&x-signature=UQipIUumjU%2BQX0smhYRBBMbgHH4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6a44dd6740ff406e9640~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766135&x-signature=qNndqkwL9mwyYN7sUmnsvBXXf5U%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d841e1f17e7f84ccc8b49~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766138&x-signature=eNMddOkKRzsBwyVxNCPdZyufjRw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8507263965f74738b81d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766143&x-signature=eRAWzcSf3CeXrZRA37V3eKRSbKA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4c118128e2764623ba48~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766147&x-signature=m7QlUVGAc2U6jyrmElVDUdjmCQk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd7bcd45e4b5247f091aa~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766148&x-signature=FK9Wa0yx6BI%2B6dl%2BiDrsy7Fqh1o%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0775d2cc0fe54828a217~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766150&x-signature=gLDwmgdMqsDhbeGSkZ69JtpxFHM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d85c39cd0f55d4118a40e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766153&x-signature=oTkvkSuJlYZZqzp9L0MLz8%2BRRiA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ded1a87c6465c44e19277~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766155&x-signature=DCJ1Ibn%2BsvNDn66eZ%2BMe3KuTTKI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8b1e1ed35e994056b42f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766158&x-signature=0bb4qaHIL1oPYsHmdVMcyOYcQtg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3ced2a9f31d74af38465~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766159&x-signature=8clf%2BJZiIo8zh47s5Er418pLBwM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3cf10b06f7ee420e837e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766162&x-signature=ZDER%2FWe3Sqg9Hm6XKodw5gBCsag%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3efc451b6a974157aae4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766164&x-signature=0vOZBrhpCWiIoFCiXrMt48u5eLg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d873a98ad653c4a7e8309~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766166&x-signature=gGMF2%2FNLTBROdyKhJ9KWmXjaYtk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df0a0ce05348745d997c5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766173&x-signature=RqCaC7ztrfZszfpRU4aBj380gcY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d55320353b691444aa174~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766173&x-signature=eQksfy4a%2B1uwrfAm2ubD51b09D0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d914ee075a95d48fb9c3f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766175&x-signature=dLwY%2FIPVFuM%2F%2FhjuykbxI4BWheo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd78a1af70d45409ab7a3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766178&x-signature=Gkex3I0Y4L2xVBIlLneHVh5nzzs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da33a24faf2a945e5912b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766180&x-signature=UqjQviLh3In48U6UQ6nemhmRJMA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3a4664e7a5b94cd7ab68~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766182&x-signature=XKUa5jwNl7ysQxKy43nCEGaRATU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d47d435b108df4e73be0b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766184&x-signature=1VtM8zR930%2B3riKrYt8dGILdbUk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d959ebd72f1874c74b216~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766186&x-signature=5VtCrgypfhBWWvWk%2Fqs2DX2oQww%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d18bb98917f0049e0b70a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766188&x-signature=UqVCq5lCurOPmS%2FmM9FZu17FaRg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd78b8857bb544c0a8580~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766190&x-signature=iZXEQ2n4Pu5rsHp8L8oo3XGd2vQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd38e9fcd0a884d369783~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766193&x-signature=h4fxz2wev5fiQ%2FtX%2FL1%2BqydsnJQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbfa7101634d240e3a094~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766194&x-signature=JNIEh8M1do%2FHp1IFZ29TFejRPKs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df4bed5b456784c409232~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766197&x-signature=S6pg8L2Eliqh%2BA5IAp0hp97BlUA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfa999018f4d24b71bfa2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766198&x-signature=ip2zGEjSiaRo1dWc91OG8dLSi8M%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc117455d61af42fdb912~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766200&x-signature=%2FmasRu%2FeAchI5eei9Z5FppG%2BF64%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7532e7e9624c46559097~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766202&x-signature=meRpr9p8K%2BUlHR4UTcaExzr%2FCFI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dcfde0adbec6c4ac8a67d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766203&x-signature=totRcfyLVzo3h4eyH5mSo3MDKXM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc637854d01564dfeaacc~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766206&x-signature=9HoLxkTbJNT9X75VSEKLtXHkyo0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df67961afcc3246a8b0ee~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766209&x-signature=s0ZzUssNpfOpYYxa5tXEbwFzohY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d22e7433a033a43848f5e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766211&x-signature=S%2BwIbjAJmuxX45mWxZ%2By3yusH1s%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da70ae2ae22594dedb64b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766213&x-signature=A7hfgS9B2Wu8r%2BWXKyXHVJKSoA0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d77ffb85e871d40fda33b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766214&x-signature=67RIXpRSJ7x8AdhLo%2F1XpRb0vBA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4f4373d8150e4e6a8224~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766216&x-signature=6ujW5XeZNZ7zdI0RSLq9ti6HVuU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d85514e87dcab4fb28b7c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766218&x-signature=HEHkp10%2FkA1ytnCjhxJl6FiL79c%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0b29c501d0874ff39b89~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766221&x-signature=emv7gZwBTOAkCcypltRzFUkkH3c%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db0fd762d69cb4700ab09~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766222&x-signature=aVHj74GTUIB1%2F4STpeOvqu33X7k%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d59fe50ea2fe3482689a7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766225&x-signature=4iQuNkQZVi2jTz%2BHG1YhAy8iUEQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d99993e4ee7f844999227~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766227&x-signature=%2Fh%2FhZb2ULE%2BLCVYPibhTT0FoVLA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df5f5d8b9b39449c7b078~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766228&x-signature=WdXEfUYRqEmUiSV%2FXpq5D%2BrPaZo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d10752c618b45484eafb7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766230&x-signature=b9fdoOP7kvkUUFtl5xZhmmF1dMg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d84f0d33b32474e298589~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766232&x-signature=TzUTSCLWx5nmXuFDZvJB8Ig9lPo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da5ab34bc30cc489e9902~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766235&x-signature=%2FeMeZZR7%2BsXOvLOpFxXTHK9HUak%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d14e358182ad945259533~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766237&x-signature=AHdlvQF80mtG%2BPRhACa%2F1kegR4w%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0daa034cd590bb4e34a760~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766239&x-signature=X8Pc5jriwkiXC6pLEg4f9PMa%2B8g%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8984566888fe467daa48~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766241&x-signature=4SUDellCY1HNjqER0dS0mQ%2Bz5KU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc1dba4edcae44d4293f7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766243&x-signature=qhRS3lNfiurc55XIYWnEsiPstoo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbe288627bc564faf839c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766246&x-signature=5JpNiF7BWE2wPOpI9TwEE75PO7Y%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de5fc73add47046d88a19~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766247&x-signature=EcMa5qIE8uw6yzF%2Bx5sAZbaXxi8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d82e7cc543b1c4a7abd54~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766251&x-signature=1a026NrVnIhQdnV24Ncli%2BBEb0o%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc756817df1bd40ab89b7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766253&x-signature=dTTemsS7fsTtWqllsoy3V9Sw7Fs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9766255f58014fea8ee5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766255&x-signature=uDuD2gQ4iC12ZPjYmqXJ%2Bn6jrTk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6d678160439c4bcba56e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766258&x-signature=DvHMOYDoHdpu8lXhkTISV6Va6Zo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc39ff6d6da684bf99a1f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766261&x-signature=c2Ez9rTJgawFG%2FJtHbS1EjJU1CI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d40c5ab28f32649ccadea~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766263&x-signature=8CO9BQ%2FvcMfYZjUI06%2F4Uu6jCFY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4ed3b645a5bb49ffb63e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766266&x-signature=uG2fHq93rU0QLgEPQjfUMZD2SHY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8323b2c9dff042e59c65~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766268&x-signature=oC4wmF2w0E4zlSsNWB2bA8npwhs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dec33b24b28914c30aefb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766269&x-signature=KBelBka0f2CCw9Ey80Sr5JZLgHQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd59cea61753d4434a86a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766271&x-signature=exf5ddavBsQCOouR1%2FON6QIsyv0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4815f695f36a48adaf2f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766273&x-signature=4tvhu67nJeBMTCdTZDCl2RL9v1g%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0debf1d48804174245b7e1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766275&x-signature=NY0Xzzj7eDonTNR9Wy1zpLwLFFQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d001c2c89caa348a2b5d4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766278&x-signature=bS87l%2BQxZKqmpOS8Uk9Vq7E0oXU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd2b45646223544cba953~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766279&x-signature=G5jPi6xZBGJZj5U%2FLS8wdpFZ2no%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dafc1ff2863d844139660~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766283&x-signature=bogOPjK2FVeUpZ8ECsv%2BkkY7L%2FE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0bace9fcc2bf4c7ca310~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766286&x-signature=4wLBaGB%2FELTGkQg57Uo2xiRjBd8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d30f8a1c6084c46aca3ac~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766289&x-signature=QC%2B7yDBpjjavIbOFtvh95z2nYME%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5c8959488a9645559b85~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766292&x-signature=Eb67uZX8zn7GY58oll8wJ4NN584%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4c5095ccff3d4ab08319~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766293&x-signature=rryty70ghJPX%2BcrDOQ0fqQ%2F2JME%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dec2c74f398294b6295bb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766294&x-signature=KnJ9Mgg3SjZi%2BCuuk8DDXkAP3%2B0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1eb4df72a63748489a1e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766298&x-signature=HO5MBaq1t2gPcHk2E6WzRDuo2YA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d34ffd18cc92d45a6bec2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766301&x-signature=ShKieXb6cnZ8XqEPCsz1vS2hhzk%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d84c86903c83c4e08841c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766303&x-signature=Hz2CrYDqz1meZ222U0SRvNHWW08%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df5ffba8c1de34852b7c2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766307&x-signature=dpqvCHi2mh6tcB3TY2jD45elHhw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfb1a47c11a754b898fe2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766314&x-signature=0GMycBowphutsyq85T0qhk%2B2SF0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9fb5c78c2f274e63ae0b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766319&x-signature=cpAqqK8OBn9GxV9pKX5%2BACex0do%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0c34adf944fb4a9c8005~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766321&x-signature=soWFHE%2Ba90CmBLsEI%2F%2B6OAnO34U%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df159fd160b9343acb8e5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766323&x-signature=7X%2F9DigOKq8PJxe%2FdSFjuKASqO4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d70c3745ff54a4dc9b832~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766328&x-signature=xkiJj6hsdW2qQjsecOUZjWqQoAI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5232ee10da3541aab7c5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766333&x-signature=Xm9Wj6qOW0PPyCriXY561b281%2B4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de79f8e26de1247e688c9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766341&x-signature=MUXO8EL0PHjnNz7KEd9lSh%2FF%2BvU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0d75a380ea7842518313~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766342&x-signature=7%2F4qvbyWHPf6Rbmzh8my8nDmPC0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df8f2df1cb4574c2dac61~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766344&x-signature=V6th%2BC7AH6C%2BNBC7flfdWoB%2BykE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6a52e8a890e24ecc8245~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766346&x-signature=7bzEAWm8LVExelRLGnCXW0wxNCQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d762d1565c8ea42eab514~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766348&x-signature=%2F%2FCbz5X%2BdJnDsGm%2FFY%2FZyv9pesM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8ff26801b76745ce9c17~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766351&x-signature=oNQ3E6rjwAO622fznoy5i1qQmng%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9e79f0a08c814abcb554~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766352&x-signature=KFgFKc1w9aZ1tkqsWWqU91Z4VDQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df70f68f6fa4e44a3aa8b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766355&x-signature=aKIHVrqaIcOYdhcqWeGtr0X0czw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d48e02185a4334effb376~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766356&x-signature=0ZykO4%2Ft17%2FxFYL0gqTLWJKkk%2BU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d96395646005a426fa3ee~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766359&x-signature=X14N9yT7nCFxSPtUa5XQaE9HcAk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0f8be9bde711427fa727~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766360&x-signature=%2FZPvsIQ5yUD%2FhzGBihTMaWyq%2BN0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d181083f539064102b9bd~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766362&x-signature=nh0SZC023IjpagN9Ix92lZPuD5o%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d104a835d6269443fafa4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766366&x-signature=L7JKSU5Vfye63mLDdhmD%2BJ9jIXc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d02b19298e2064935a3ae~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766368&x-signature=JLxXJw6PK0Tck6bd8LHcosXoKpQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3350b14fb9344bdfa82c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766372&x-signature=%2FxkXfQ4YGo89dH83zuofa7qlpcc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df422d2981d4e447fbc87~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766374&x-signature=VOteNqp1F5EMIS%2BlMKGTwPq7o58%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc8d6bdab4b7c4ca7b6ac~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766377&x-signature=VxmZJzcZ%2Bsa0x1JcvqDeMyIp9fk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d364e9dd1be3747dba6fa~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766378&x-signature=J865B114YYfLsAX3uBC2IbRhfZc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4e7eac3d7b0b460d8b56~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766380&x-signature=oEYV9uP5dMJj3BLpniqW28kOPsg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1f1ffecfcd974ada8222~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766382&x-signature=%2BwoVR8vFuoEOzyeulzj6mnP%2F6jo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9c35ebed41b9438a9e00~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766384&x-signature=aDtltq21FwFkrCP0h7BIzTQvodA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6425409a6a734c4eb6db~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766386&x-signature=iEBTVUPJADGGvKcEKEKHuXqT9Ks%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbc360bc3bf9444ea80a8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766388&x-signature=3hh1IyC4j3%2FdNlpCTVopEUX06JM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5f6d8c02479149c8a837~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766390&x-signature=OanrbCwK3pNZ%2BqZ98Nv6Rj6pmPs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da5d706b9c5084466a64d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766392&x-signature=pXZWSQq8ShEwmddNZuVzatI3%2F6M%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3acd7dbe5b1f4d86a005~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766394&x-signature=2xZN58z%2F%2BTZLl%2F1GebL4Wc1XXek%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db49fb3ba301542c8b3a8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766395&x-signature=MFjWeqw5xQLKpvSHvaF7Vxz3coc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6e0bf983b4d14cfe8f5e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766397&x-signature=kbH1eR%2F9w%2B21K3x0EDPYleTzisQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d41dd9414e0594c6e8eff~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766399&x-signature=qGs7W9s773QUAJpvkjYIGxnCvqA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7ac9f3cfb0ef4c4aae05~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766401&x-signature=5%2FVcFa8%2FGwATtsBk2krK%2BaiTLZ0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbbbc34426d6f4f6aacde~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766403&x-signature=ukPBYwrrHUlkfhFrxbDdaJvh1Qg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dda6f8fb808a74f639a4b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766407&x-signature=h%2Bbo09O8mM2nZyj8RJ6505sq35Q%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db5065a6ca4a546799af8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766409&x-signature=pWxaypRMQYW%2BetNYPHkYUWseTu8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9ab2513390ce4b0f9b9a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766411&x-signature=l56%2F6BYDMfP70pM979DEx87vQFo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3bde21a4ca8f4b529c36~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766412&x-signature=tsIeLGNeO%2B6osDJGg1ib31gjnaY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1d972d53bab14fe78b76~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766414&x-signature=3JpyVrzuhQURZhxY4kuy%2BGVNmuM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbfa3c527627b467480bc~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766416&x-signature=B5lEoEQmATD0%2FLkzumzEUMEBK7M%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d36300dec4d7149269f5f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766417&x-signature=cpA04BP3jA3BIfYigiSmCeHaOJM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dac13cf4f89d046e7bbf3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766422&x-signature=dgAWhKi%2FvM9z98prAMrjfS1pgG8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da467a805b89540b2a19f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766426&x-signature=gZdhSZ08YCCl0YfrieQU8QP5qN0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dcd33deaf95ea442ea595~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766428&x-signature=ulmQh2Quk0TicdLMOnVXgx8%2BRdA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d59a728b34b424a7ab7c5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766429&x-signature=y6C5LpvVAojHyhFHVwZr10hUdws%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5667fe27138e4630a862~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766431&x-signature=xK0ksgV5pQLJ35JIKD3VTsSiX00%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d78b98767586940f29f84~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766432&x-signature=HPQ9GSvXu8miRrZnE%2BvBM9tT8%2B8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db7a50f50220a4a42a1b7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766433&x-signature=HPn0yzhFnuP0exC2rsMmaKOd62k%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5cbdef9a82574457839e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766436&x-signature=EGwws946%2BEx9J1xG%2FYbf7dUx3%2Bs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4c4631de6dd24e73874c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766436&x-signature=O6xE%2FhBgo92r%2BlRSYEiB24Wg%2FSw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de370d575f44c4aeb9af3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766439&x-signature=c2kcACf6BNbGW%2ByRoimaGJEGdeo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dee2ed7b61d7348e49a35~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766440&x-signature=J4Rf4IkkO6oAugLNMVTlrJFygrg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbef1a9671f3b47a480c2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766442&x-signature=8nj%2F3naRqCo%2BfnME4qbFS9slDTM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dcd82e1ccf30c4050b168~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766444&x-signature=%2B7bSF%2BxgD2xuyF5oGZ1QO58YOXs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc15721d060144ba28ccf~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766445&x-signature=9TDCVf6StdYLaaaO3i8N3w04XHg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd0ba045f8cd34aacbd82~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766447&x-signature=%2Fa2ubogpKNZdIUksf7RlpndnS%2BI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df1c01a95d968408ab5c6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766449&x-signature=cDaj0G61X%2FLbg1SVkcvYPFp1wIY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbf9048a9c10148e9b40d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766451&x-signature=ah3JbDNOANJw4evq9T2aoWUrdOA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d215a897353564b6e976a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766452&x-signature=KnpnJgJZvz10idX2e5VJlKMpPeE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4c901bdc51dd4f40ab88~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766454&x-signature=d28%2BJAQ2Es%2FCS%2BLzzzHV2oS5%2Bps%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d39745e136c5e4f60985e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766456&x-signature=zcfAoXhTKwsLmPK1wrGmFO%2BVQp8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4a3c67a3fd69469982d2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766458&x-signature=7q9Jat2t1AWJiaWwTOWc%2BSUxbF0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6152dbf648f74810ae8a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766460&x-signature=l04ES9gVtcDTipUd4BmNdNcv%2BBo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da265a739eb694b28a866~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766461&x-signature=cXx7cOBnCYvSmvedMXeWbK%2FXWr4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df934f46ba2734e01abd0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766464&x-signature=vdk0gVux%2F9oSlLyoRm8eD7JU5Dg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc1ecdbb774374bc2bc23~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766465&x-signature=Qiytuy%2Fe2%2F%2FmHYeIS6T0m9VbkiU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd365875140cf4b348a6f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766467&x-signature=j8fXN1uS8g8p%2FDt8zKzdYVlUOIs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbc87a3602ea245c18a05~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766468&x-signature=puKEFtWq44NVZdAI87vs%2Bmo%2BxSI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df3799d0934b647f08d73~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766470&x-signature=gmmRJW1xu2Oi464D36iuC8JNHrU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d79a9d698dec84466a77d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766473&x-signature=lPndx2Oe4kUbkSbjhlbkCfyzH2E%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6dfa8910f0224bb9a43b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766474&x-signature=PcwNKOVyjROIqVur%2FjnheaOx7x8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db6ea7d193c234732a89d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766477&x-signature=Bp5nCutHyFwhhMzNI7BqBrwAUoY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db2eee804632642caab1d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766482&x-signature=%2FFb6%2B%2BUTXQ82ZB8QBzI6dl2j5pE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d44fb121fbdeb4a119a92~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766485&x-signature=sHqE0RimvDvp7GAwkfeUnIP%2BHqE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da4832855816e4433b6f8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766488&x-signature=GfN6nwa%2Bzlvfa4RmnyvJH%2FAglU0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0def0629490721476c800c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766490&x-signature=L%2Bp55Mw6EpSoG9r9GUBFMdlv3%2Fc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0155faae8333478995c2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766493&x-signature=2XEdrElqRjHJdO0ogs2E%2FqycOgA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd502514e7a66424293e3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766494&x-signature=WtsukjJR1wEr60TmP0ituRxpF6A%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4380314313484fe59f8c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766496&x-signature=Dife0zS4bHBJxT6qQcizyUCNzl4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1bc523393e734768b93f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766504&x-signature=iJ6oOwLHAJSDVWCZ7MICutohZkg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da477557affd941c08c33~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766509&x-signature=qzNCJvdeHOM9wiDAnKTSM15n3kw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6d38e7cfdc92470d9311~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766515&x-signature=osig8YuH%2FQB9yjLJ81WUYy4rgh8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dcbadefd9a4b44d649ffa~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766516&x-signature=JejyDxunPGThBYsLGfXR3YTZcFE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d48813b1bbdcf4ca8ad13~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766518&x-signature=hXtx3%2F3bsnfYjuLJSutNyIJ9Sm4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9d76ce58c7a045659b45~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766520&x-signature=Nr5%2FJa%2ByIot7szEHmHy1bMxL%2BcU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d593eb04ecffb49939667~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766523&x-signature=bkyyjWSsgRFr8ggK%2FrioHMc%2BOBc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2b3675f2d6ed419ea982~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766524&x-signature=Hif7Hy2b376ZHKJNmPC5V5Yo9gg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddc07e9f0b9aa436395b0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766528&x-signature=bGe%2FGxFay2k9UmUBdg85Pele6cY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d73cd338b8cae4d4d88c0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766533&x-signature=PSAiIyWI6oHcLbZlrmTw7P0xwT0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9f789b82826647c2b552~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766539&x-signature=MhZe1SczdgsNsruwIg5Q2I0zuME%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d55952f7b58c546b2b517~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766545&x-signature=n2ARpqgtE8m%2BpCQJiEhLQrwhWRw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d100dcbb362074567a881~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766546&x-signature=vEKeLVkN%2FYIn%2BbeuULVL99iYF20%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1b38f250e8fe4d598875~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766548&x-signature=oWhOeacly9PQj4HYqS39rEQrTPk%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc1ec4426a2f84e72ad89~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766550&x-signature=T7dUTFeYMfWSztJ4VqbXLJGHKks%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfef6714834ca4514a74e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766552&x-signature=F7XoXb7vK0HAQPnqmssCWMTqZcs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfc8655e0952f483f88f9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766553&x-signature=HIc4fLLfQnWWOxwSvlPgksci8lQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5b9b808fcdf444058a47~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766555&x-signature=Qn%2FHWgCwO21SQKe9rUpbYkFQ6iw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d76040f4b4dfe4eeeaf11~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766557&x-signature=2DT8oUaUf0LtUYF%2FoH%2BHjHn4O8o%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d18ce3b9e1f91476d9427~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766558&x-signature=%2FGclWXdw5FnWyLT3xqrE%2BICoO98%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d18bf84f73ddf4a82b830~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766563&x-signature=k1RJ9rZSiIacdUB9dYIAtyg5pws%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc0890888811a4459b0aa~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766566&x-signature=YF1cOg%2FTHjID7%2FhhJnTjBtuVluc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de6e6311877924a8399dd~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766567&x-signature=YdAF%2FQi8dXKlTFrfW4q%2Bd4%2FpYNw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8757d5de57b54e378a53~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766569&x-signature=rbCG5KhdgF1FuWONVbtTliCNF3M%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5b4c2c751e2d4fa0a75d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766571&x-signature=avp5woDg1ov4VK9H65tygu8tFAc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d42860ab357514654b6e0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766573&x-signature=e5rLlfp%2B3V3hXs5SHvcmQpFxiJ0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de170a7d92ffd49b2b4a0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766575&x-signature=gqzVBy9nA8ta2YDT8Zuk25QaKNg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc75df77f05214e6c87b7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766578&x-signature=9eyuyr%2BKRBtgesiGElT05mg%2BzE0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d40d0b5d20b074c42ad65~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766583&x-signature=C%2BN0OqOwPBU34RO7wD72yTC7s9w%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da5011c2cb7584191951f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766584&x-signature=HAMH0dIEW%2BEXcDdLRA%2Bs9TYB39Y%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfc732e98be6f485ca1b7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766586&x-signature=vySaIY4z5qkoqHbJQFlMqYMoPKM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d36b341ee4aed4def9237~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766588&x-signature=WW3ZMFKjdzZ97fIYXz7EVEZobdA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de9ef8b6d3faa438e8ff0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766590&x-signature=RAJshPyjaRv6mOYYuMTRhNoSNps%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddde7343f6b674b8b88c3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766592&x-signature=9Nn4ygbIg8IGnsJoH9jko6Sr694%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df34dd2ac42894dcfb7ed~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766595&x-signature=UyxSsZCXTBv%2F3S6nBoL2pzstpFk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d064a476d0318461293f4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766596&x-signature=CrzNDM27KZpet4Ba6z0mSPtCJjg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d060530e06af54c428a51~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766599&x-signature=ZFKjiEmH%2Bwql%2BNHK3eiLWGY2deg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ded53a4a8bfc24af7b7e7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766600&x-signature=7Qu84PIhSOdA3L1ue5H5G2rm0gU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d13976eee5bfd4bef8faf~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766602&x-signature=c%2BpCft7c92yA0RK0nFl9O5EBQoU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7cb851b8b069403fa838~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766603&x-signature=eaNCmXSTKB%2BIaodWWAmKHpri1gQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddbd6b0381d38413e8377~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766605&x-signature=V9tXfGawYaR6%2BiJpr83qo4hjbJM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de6a87b8fd157423aa41c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766607&x-signature=Y6FKwn8x8eZ9kqvBFJz9L1z3MDY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfa4149c50b864bd2b836~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766609&x-signature=LjuX11fdXk94j2ms4yPL8zupdRo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df8e88ff5d7e74e118817~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766611&x-signature=LB9kGikp7xZD%2FHp6vG%2BIKCfyk8o%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfd35f915d26c469f8c80~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766612&x-signature=p1%2B0ygVj9k40Sf9PP6zJOm5LNe4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7cc06023182549c68dd2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766615&x-signature=lCmFKkpC9DmoG%2FxdSQ39cd9GiXk%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9189a49238ba488fae8a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766617&x-signature=qVuCXRhlcVrGfTxYZ3E9xIEvyQw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2be963310c2c48a9983d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766618&x-signature=XsQr%2FPI9wlHGRvu1SX9%2FdZ4f7es%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d26f59028fde64aeb9de9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766632&x-signature=XSyRG37XZwFRZvPoSLjB1M1lDvY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfc21e63abc194c6e90bb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766635&x-signature=3iK60EB0vka5AmYPgqMOL9LOFoQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d69b74df7812a49cea0ab~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766640&x-signature=LNXSPetlM0rWWuPgQZVTfpQOiEw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d60b974351eb64ff589a4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766648&x-signature=8%2FXQY5LrbXg0if23KTUjZmoM7BI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d130af38e2e4b4a02b7f2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766657&x-signature=ULmwhPwKjjoaeWILus5QjyoZulY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9864020906234abc8cf7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766670&x-signature=ySL5IjsF8Vi4aZXGW3iOA%2FhYNd0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d943c2f1aab1c4b989e7d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766676&x-signature=WleUdwqL5Q%2B0EKjni9PvVRhMk38%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfc70435fc7e140ebb3ff~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766685&x-signature=mhk9EthS8jpQ%2F11TH9ikHqstiq0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dda0cb5ac178c444b8c36~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766687&x-signature=%2BUptUpBCWNDPtAlCX30a5psmVj0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d410b62b80b6b4a44856a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766688&x-signature=sC3Xrl9kmm003aohTpKyQwyu3pA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db27cc6c75fc64936bd3e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766691&x-signature=FU3PVD%2FhV6r67kUT%2By2yhegfJhs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de65197fbea204a1c9db2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766691&x-signature=G1SIEKuWf7VqGblIRlcPoEICCgg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de0d754bc70e145b49a77~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766693&x-signature=kmKYRAau2BSI8EL%2Ff3OCztVUY68%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbbc144081cec4016af6b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766695&x-signature=1gdzwxJBSTFYYAbAGRrcptYJNt0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc24416c177c94048a8ef~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766697&x-signature=MsxWpedER7t9kp0HBjZcBzqRV%2Fk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d32aa1d1f87894c93a096~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766704&x-signature=s8QSQi%2F6LvVxKHfV3gegmImA5ZQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d736fbdc8cb414020bc6b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766709&x-signature=2WUmZt53fmV5pXYtHgh5Vm%2FVovY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df34e6072c24846669552~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766712&x-signature=LLOtKTfwaPgkYiR3PszIsoOxIro%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1e649073f7bf4644a0e4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766714&x-signature=423m126XVCgc%2BrV%2FkRcmBSUEVJY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d156d4d295574449d9ec8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766716&x-signature=OGXO27WYXCwzRtFjrp0L%2B5tdw2s%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2f0cc69ed6944a7eb43b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766718&x-signature=5iJCO1WzQVAVLxWn%2B1gDWn%2B8hnY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d312ddf2883db402dbae1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766719&x-signature=SiahbRHRsc%2FG8ZEjYCnjcH%2BzziM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2078df1cd407432eb2ac~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766721&x-signature=scEZ9CkELYluf1VIv7U69hXQAzo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7d9bbf84fe1c4be0af33~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766722&x-signature=FsXe7ZaYvff5L%2BVkdB1Z30fNP2o%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2ec746e431434a2ea3d4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766724&x-signature=9dUnlp6LdPFKmB%2BpDDwbNqYU1yc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da42a777045934312a07c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766726&x-signature=xqWn56Joy%2FB7p90hcaXoVKBDDlw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbfe048de488742699c4b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766728&x-signature=SvYtmfB%2B8I3ku18ztQEn%2FWUz54s%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0f2a5c2a45834442a1b1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766730&x-signature=8mB7%2BtXTF2a2%2Bcrpi7j7ZVqVKkc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dee486822ca134c3b9a78~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766732&x-signature=rkBaKmg6PjepiXfgKDSWrUFJrAc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1951994fb5ad4f3e9a3f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766733&x-signature=u0yNM35ePyHR74suc6rs1BgRZ4A%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d32a50c1f5ea341cdb506~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766735&x-signature=s3Zle4fqJKsm4WrwAQWvn0aV8es%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d02dc417200c84542b2ae~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766737&x-signature=Qsa2PuqKCNNNGSr7thWlGLRXHYc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd9585da74a5e42cb8742~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766739&x-signature=VUIRy8j5Vs3AtTgtq01EwZpVbCs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d51620d4564aa4803baf0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766743&x-signature=OX7a5cq6LiutoC6rjvcGhiPYJvI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfaeeca4478844419a9d5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766744&x-signature=%2FQQJRlBgREGgrts8cr%2BNmrklNvI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd74e4217823148ec8649~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766747&x-signature=EjFsU9NH7jGvGGVvb2mFD5uD7yA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc4d4ec0115ac4077ba08~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766750&x-signature=tG9Ci9GDrXix83gnEay7LkQoLvY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6a5a78739b1a49f8b991~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766752&x-signature=i2qmiVW0%2BV7kYiuXZf9vpBim6rU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d97defa53cacf4e4d9e69~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766754&x-signature=ZmejXUTyqhWH%2BNP5qMULSCIVzSs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1765acbf3af1481e827c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766756&x-signature=VijZWMzFH6%2FRzUHzBn6vl37EgSA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4eaf6d0dfd66488680ac~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766757&x-signature=uLvb62gO4cW%2BimRoOCfsA29GLF8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d39663e1cf56a47469449~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766759&x-signature=4o85YyTSpiSue9q2AjH8AbQFOkY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8580a77e1f3b4622ba5d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766761&x-signature=1I%2B5z7PGAaZpgtCzXmwqJAUntek%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d413294b592344b8b913f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766762&x-signature=Pz%2B0rrMzNskBBule09gROn5A6EY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0081d3f9554747dbb228~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766765&x-signature=EHZDxMHM%2Fv5AyQH6ZlxhaCS9Ixg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d336639e5fb0849b89d41~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766767&x-signature=k%2BtxpyWDW0ff0VV1jeMvZOcsmnc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7f7c94852251463d8388~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766770&x-signature=2z6RvANK4dEFQ8l8ankvOFZmS3E%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dec31398388a4414cb520~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766774&x-signature=4ADZqwjVzqe4ND1Wt0Pv6Z40iko%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d83d14b7ace714e35b4c0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766780&x-signature=w9%2BDM%2Bfo2%2BYxtLGEAnks2WUZ2Is%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db314013e6a464562b88a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766792&x-signature=YZ5fZ%2FZKp%2BJyArEt3Td9YIp7eHw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddd6132a0a7904d07b4c0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766802&x-signature=SO8j0sOH9F5x31cB7Bk2xwAYOps%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d867e45ee5074413c9469~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766805&x-signature=7qIlz47d3rvZ%2B0mFwaHJfZh86zE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8a5affd14ac142228f39~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766807&x-signature=9RtmJX6KNWp%2FZNd9%2BTf5sv5mWW8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd2989f4810db4f1ab935~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766810&x-signature=2rwM8uuTCbblEDv1C2%2B12ex82E4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d61f7a3ee34bb442b9b5e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766812&x-signature=g1TiJphmrm8MZP4BfUHvURzg55s%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6e52bbec98b540919cc0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766814&x-signature=bMzlQPXuSLgXvvMyWEXrW0kic60%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d97ecb39755fe4633ab3a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766815&x-signature=wAXUp9tgqU9eECDGNzXPZXH67AU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd92d13e2edc741e08061~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766818&x-signature=TiehtahW%2F8jCq2rY0MgwJlxwCfc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1981a9a86ab545b494b4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766821&x-signature=DBbTTtn91tLmpHKagjGcwSFEMRs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7a33af88557949b5a412~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766823&x-signature=mqDG0ROXBIHaHZZSGCXnr42CtDE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de261ffd8554b4509b3b2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766825&x-signature=SK5JL5drVJ62A7pexx2by5%2FeHms%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddee5d838575e40029118~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766828&x-signature=5Vd1jkJDcC%2Bik9b498eouKK6Mtg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5cf0641aeeea44f6ab6f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766831&x-signature=xGPF%2FNUwFB5gG5or8iUC8KAhCMg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d69b6e434df4e4d82a79d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766834&x-signature=STFvBgh7xSO8bbDWbU%2FRj%2FPsoRw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de973ae2a0b0e4c878f72~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766836&x-signature=H3LjNcwMcIJ5m4wRk0R3e6W6DX0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfc30dd169cc848d38fcc~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766838&x-signature=WNYVv4TdqmdUANGOHOe%2FgOppvQk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9d5aa1f7cbe04a26a890~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766841&x-signature=thJ5s1EFWaCVv%2FH%2Fyq9GEhsplrU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d120d4f4b151943ebbda0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766842&x-signature=U0jlD9h0r0f2KBlfoiXoYFOTGvw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da1896d26a51d43688f2a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766844&x-signature=vglR%2BQAnBeiz5mLbPjRVOTAeIeU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8172010bcbc74396a5a6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766846&x-signature=oI9j5k6AJy2IeJvwxUzu6hF9mUc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de2c3ab6db6a54fe6bbcc~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766848&x-signature=01JTBMaTWl5CE7%2BcbBxPRhU0Wvg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d387b870f351d4a2b8d26~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766849&x-signature=XWc7Qf%2FmrrYnoo%2BppKXFruHgznY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dee0a5b7e31754b54922f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766851&x-signature=YJ6NOcu8qREBIq%2B1cOK6iB9kCpI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3b173269596d48e38aa6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766853&x-signature=om3i0fr9swU1apQGVk6Zd8bsUV0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d12c016f33b5947a48fcb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766856&x-signature=S6MzD7q%2FWe%2BnSrH6nebATHTU%2FnM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9bdd89054e27408092c1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766858&x-signature=D6eVCMJHVi1dJ%2F4VfNCKSognL1A%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dab5a437b37104abdb513~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766861&x-signature=dksIl3EZWM2rKhqV0N%2BsDDmaVtA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7cadcd6b79fa41fe8493~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766863&x-signature=4DaLonoD9Qxd4%2BfaK0cfv4IYUL0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df299ba176b6e4910af86~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766865&x-signature=0CBhwkItnB%2Fs4To0xubJK4ObnQ4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4519bdfeb0b64e3f9cb1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766866&x-signature=IpdKQlX5I5aG9%2Fu8Rir%2Bt%2FJ4Hpo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8daf2ae19060447d9206~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766868&x-signature=ZXjfmC8H82H38pMKnrlUxADzCC8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df252e159006a41f0bf4a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766870&x-signature=cswscSomsgrSac%2FM%2Fm4YH1XVXpc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dcf24794a50de42c299fc~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766871&x-signature=xN2sEO%2FDqzOT72Dd61OjP5RtSgE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8677f0fbcc374dac9587~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766873&x-signature=HGO7lwKXKeyicJhxdjozzPViBR8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da0ac0ead66ec4fde943e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766875&x-signature=bQjQbq0v7I4r1QBXrfPUzmAZMBc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d791e5d479eb94f78a267~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766876&x-signature=TgiasCnjK8RHtr1yzTvpdxBhJW8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6eb45d33b1e945a1a120~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766878&x-signature=hYTHRn%2FUvpgt4O3yCVqTl8ay4B8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6719831ac5504e6e8185~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766881&x-signature=kOvDI5D%2BwselTAvmUeU%2FlTBK7Hc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db84cd19fffb74c8d9ca3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766882&x-signature=A8%2Br8EeVvbzI8hyOBa6beeFWfeU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d027296d60e3c4b3e8e33~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766890&x-signature=ULJF%2BrT%2FsL44XKD%2BVuVoiPOQ%2FD8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd3e4a56a978c49ad9c05~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766893&x-signature=0Ge6f85HZXFiZdU5z%2BaA0CSOmh8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d309f8d0cb405431b9986~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766895&x-signature=bDsVW5R8O2Dpj8ASVQ6KVRYVZn8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4382f4f89b2843f2b5b2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766899&x-signature=vEIz9rBZANnaICGZuKLj4pm88Cs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4aceec163ac34ab3b921~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766901&x-signature=BBYQ7sxOdrj%2FsQ%2FHHuzgx%2Fwr918%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da7e0f4aa1f9640deb019~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766904&x-signature=R8EGE1Oa50%2B7iIqEQKuWUT8nTY8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d606285b92f92403b817d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766907&x-signature=RbMWr5SrCu4CRNMvCtTWwz7%2F9Oo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6c4acc628215406aa65d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766912&x-signature=FMDyOpNVZwS6zwmEzfgE0j%2FMlmg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc36b69d8e6e944478280~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766915&x-signature=FmFMO06Io8voazFw2ZeJ59aZRLA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d76cd9319a3a3498dbe33~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766921&x-signature=WwfRXrG1PjLAYNvz9WQxiq3WzeM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d909a5bff3f474dceadec~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766931&x-signature=x%2BZo5oKcJdsAWmPdufuMtjPkd7I%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbe5903c9c7b24e9d961b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766937&x-signature=%2FdQDO%2FdZBHIKuDWreD4TABpJwpM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d64d8a9dc49d14ee09aed~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766940&x-signature=GFStNsy97QpVHUig1VZrJkM%2Ba7w%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7aa050b0aaa34a8cae74~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766943&x-signature=XRNqkijee5VF6y2XYyE6D39h2w8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5d8177310f4249ae89a9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766945&x-signature=IsJx2BHs6Y3YgIetX4KCua4grMs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d04a3c6ea3e8d482f85b2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766948&x-signature=KI9%2BTmzIguI8UPWV63fsolg3X%2Bg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5c712316ffb0489ba2b0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766951&x-signature=FToTe1maMIAQIsn7kyFgIHVJ43M%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d122eece244e34c9fac7f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766954&x-signature=O5uiyp58jlmdCzJEtAdERBsm4pg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db80a50b3ecec47d08a82~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766956&x-signature=8jrCA3tWvCWd8gbLUkg3zJ4XbRo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1242d86aaed04f1ab5d3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766959&x-signature=lTtk07HXUjBuCkoI9DULNXnyjSc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d90232e878e52406a990c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766962&x-signature=uw4cpzkiIoDCeBEDtMsBJnD9ExY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dad759349b6df4a2aabf4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766965&x-signature=041ZminiouaX14o%2FkdrZjOO1%2Fk4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfbb756c14588447dae97~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766967&x-signature=BGLqwppVVoJrT8nZwxe%2BLzuuZb4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4f22888a027a4e3998c6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766969&x-signature=u5745xjXvNkCPQvWXjL5VQMN%2FdY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4fb3511c14d64c05bb82~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766972&x-signature=MVjS%2BMrR6WJEwyafdlLQwLidCtU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6b507012a25f46619737~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766975&x-signature=TfAZGz25eO%2BFMffnMva9qFNFPXg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0304655cbf2e4c6eab78~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766977&x-signature=JA4WQK7gdPTV5WO46opct2PfruE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da5f80f5b799b4abaaf39~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766979&x-signature=SrYTLEpVHyZgiOSw9xmXVXllBE4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da1ce4e94762b4fc9b5fd~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766981&x-signature=qW1U6hkAnWuzUf%2BMMydbcPVog%2BM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d64e17f3524054760a6a8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766983&x-signature=TpcFI5MNhJsWGCZVXcygXDzpVPA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5a78a40362c14b85b14c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766986&x-signature=P5BUMDCWI7drIJX8LjcOkysQ2Qs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dffa54d8fb0e14f90a82d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766988&x-signature=H0tgXnK1iG2YgL9ef%2F7CI8t69Is%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dad1c9002f05f42a0833f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766990&x-signature=ghdcD67NYKSifu0GAqFXuW7uIDM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de61af6ad2bb34c82a145~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766997&x-signature=P9fDsoZgDmX7dfYZk3PfhPVLeSw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d29641fd3fe584a86b7b3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766998&x-signature=Uc1p3NATS3dRtlQoHXZFXK%2Bt91c%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da7cfc6b9729b40448e13~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790766999&x-signature=nGtYkcTls%2BFBu87blBkeztbjR5Y%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfcd3a23a316b471e9eba~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767001&x-signature=hXojLGjPdrfB5uwkCXYmG9wTj3s%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7086275689f549ac8204~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767003&x-signature=%2FctAzR9LgkvmAH%2BKSfU2czJSvS4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de88c760a0f31481088b2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767003&x-signature=ohcOa7mqDWzUsAvklRi7OUWTnXY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6a6e81a64fc84479b36c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767005&x-signature=CEY6ZGo2csFRXlVhXOItYo%2BRm9M%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0981765b2d3c40f5b1be~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767006&x-signature=Em2YfardmLsp0oOIFhpMjOLYtFs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dcd76bfbf234d4d6383e7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767007&x-signature=K9GiybP%2FyQuQr8eHvOJmOPcYdbA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfa5852aadd4e4477ab38~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767009&x-signature=B5KmW4GRHmAfb9BVEOhEx2B7FVw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc60d446e3eee4713baff~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767015&x-signature=ZfX5zRUqskohIj%2F%2FcYRT4sSLV%2Bg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dad0399ec039a49d09ad8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767020&x-signature=AbAHchGNM46SW8G8IDmGWJY%2BUig%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da8688f29cd034ffe8dfc~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767028&x-signature=R4Hd9DWaB6vWiJZtNrTez8eexkU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd01f7f737ac648cca068~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767031&x-signature=cpnETemuuOs28kqVWyeKPWXpNDI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d72cdadd4dcd84ff38115~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767035&x-signature=DZ9hgwksZuh66jRpVm0VGnbawgo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d06ebb21f8a0d40a8b40c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767039&x-signature=IKlUTVSnQ4BeyJcPYeky0GdeL%2Bo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d03852394a8ac40bd9988~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767043&x-signature=8Lv9%2FZWcFeQcNfeUJPwiQCj6QLY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ded019af07a7e41f69935~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767045&x-signature=JYrQESQ0L2%2Fy6HFqww%2F4RmwLQGE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfbcd853847e2485990c4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767047&x-signature=FP754c78lIjqaW%2FRxb0U6CZmQDw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6cf144287fde484b96d8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767051&x-signature=%2B4Jy1wLhCArTKkjnR%2FBng3NPq6c%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de094bf5098b94bc1927f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767053&x-signature=hlL%2FfcXSFIwRPNBlA2wqelEYRqI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d18df545d0dc646d292b3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767056&x-signature=%2FXRvMEigaIVay2GWJOp10TTjQ78%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfbe8eded5d074c258fad~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767058&x-signature=2bu7b8797NbRSHHcZI5tp0xsX7M%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4adb2f9b34274153a92e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767061&x-signature=LmSX%2Bum3JTuUEy1YB92bJNOarTc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4f208289fd13488b87ce~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767063&x-signature=7OEXKv3sLwt3LfQ1NRwzeKrZNmg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d53f2fede59704abf92ce~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767067&x-signature=G4t4WcQVEGKOpkiZ8w9BXJ16pbE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1a30a09b2f654de7a3c1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767069&x-signature=eJlv2WYzVRBdtepv8rQ%2B%2ByzgbMI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da16fff0da74f4857912e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767072&x-signature=TXEucaG2vfzKK0TJrXFAwAsVm3s%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d93c42933186e4f208022~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767076&x-signature=%2Bgh7jzl5amn3tD6%2Fvr7MWuTztls%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d999a7ec762104fbda631~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767087&x-signature=ItPbPrIq4dHroocuI%2Buce5tKUXg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc43c009ccba549269a93~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767089&x-signature=CltzDkwzzQ9wjNxNqhE8J25IeHE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da6a920e6a8d1484782d5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767092&x-signature=jQXRhq%2B5i6sFvrZQS7KLFIPjiZ4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9995ad11b9494ee78358~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767093&x-signature=XGpp%2F%2B5bLz81SCsZwnR5Tvpt3IA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d413f884fc4824adb915c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767096&x-signature=BeX43g7yzIxqXVV2o1HpzYwXDJE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6d32cbc25d2346c4b820~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767097&x-signature=AhYUO%2FKF%2FFsCwFZVYbcR5GS3ICY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfd3472af68cd47a0ae80~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767100&x-signature=iPx7lQ8UOZFEK1RVAP4jdPEZ%2Bgk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db266362b251342d49919~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767102&x-signature=JpoBgdtoy8LZp343MFzKczZ5Qnc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d967a7bb8faa445f7bfa0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767104&x-signature=0ge0PLAGfCPk%2BRN83tQpIMR24DY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3dba8fc03a634b149450~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767106&x-signature=hQomXy2Mi7%2BkSs6Tx6MwAsQYvnA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d56b2ad429869476ebd1d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767108&x-signature=fx9bWuVjgRpkZP0009c1cEW2Dl4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0debee5be99bde4378914b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767110&x-signature=e7s0I%2FZwzJQum2w5Cv9rb31FxSE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3bba0f591d50436e943e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767112&x-signature=4Zs2PZSSrJwNL68OcD7d%2BSbQeGI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d650516886cb246549037~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767114&x-signature=QuC7Atg%2BdR%2FqufraWI4WuTyaqE8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4ff86c47195d4af4be5b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767116&x-signature=%2B3BHZlMNrST6kSq3HsIqFyJmL1s%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db83441472f5b40a3864f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767119&x-signature=qze4Zx3gF8p66m0vuBfJzV%2B07SY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ded33c586d860494b9878~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767121&x-signature=Qb9c5Gz3gqMYz7MdvQm0mCRTRW8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db543b8db004d48dc9811~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767122&x-signature=6hBXEhBA%2F%2BEyv72gDZJ3IIsb7dc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d300725709b874d109d58~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767125&x-signature=PGxPkPzRk0WLIZ2qKVhCn%2FOinOU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d782e371ada5643a5a098~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767128&x-signature=qxRxE1AIfxVgRWIruDIqaVe8CeI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da0edaccd6efd4ad7abc8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767131&x-signature=8eCT5NKU%2FqZh5Qr4a5YMHrFAh5M%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7579431f3f614bf2a7c4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767134&x-signature=0nQc1H4Jyiphaw2aLOQHbhu0wZ4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db21d4df75302405ea282~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767137&x-signature=kRY0Lm%2BFOyxaifh5tjK%2BemoeLJ4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7587ae2c46c545018ce6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767140&x-signature=Xghfavty%2BTGKnVHtSdABxeFbYhg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2c2e53ac49ae43c3a09d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767143&x-signature=Ol9Hg9j7VxV6ED%2FJS7TucYS6FaE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d94758f5fca004bac8b26~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767150&x-signature=I2S2eHMFPIrtyr2vB2PZ3ktOIE4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8ea455a5dd0343af9517~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767153&x-signature=npHfH7qEnW0KcAa3T1pZKIMoA8c%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0ea83c6332624b60bac7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767155&x-signature=BTFNw%2BKhmoA22DlOQd6SHa3GXoI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d01600efdf4dd4fe4bbd7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767158&x-signature=xBRWO5haE2%2FWgsM%2FQwmC5CllNzQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7bebaf47873448f1a94c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767160&x-signature=JAGhkBYIWxNFfhlJt%2FeXzKaYCjY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d53d0f4219b2a4a51b2e5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767163&x-signature=jEkSDj6usLUzBVoAjCsvpBjBhD4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db4625af3fd39452287ed~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767167&x-signature=d%2BAQBxpL8D743gHj10TiDNZ22Go%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d978964d08e8242829ca3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767170&x-signature=RrtZ%2BcdSg2qIyNFHfk6i2BQAq2k%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db99e7618966245b9b4b7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767171&x-signature=%2FM9T4pvuDS5fGUtK09dg%2Fe%2FRobA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0eed2aa9e328416fa2ef~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767175&x-signature=qLvoKgocLOjAGOE%2FY2ULXNS8BuA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbfec3148a3fb46e59eab~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767177&x-signature=MOkS6Tb%2BuCmRLpAtx9CyNdH1h6I%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2e533574a289455b9026~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767179&x-signature=GJDcyL4VWdiCmohMyDk1oUuRr%2BI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d67f61488a75244c9a3d8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767182&x-signature=%2F2DWD8QvMlMOFg5P8dpD%2BnyoAK0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d052fef6b56154ee28b2f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767185&x-signature=5Kxf0Feq5bnrZN9YZ%2FbJOM2egUE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d23ba218c5e734a8195b4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767187&x-signature=J3Ov%2F8syTPacEJ6NAE9ftVgFp30%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3ca058bb5cfe442082d1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767190&x-signature=MYrZp9j994Iu1oRnrP0eU8FRkEU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc4a75a1c1da64964af61~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767193&x-signature=3dCkIS5LONoaP4l4NM76nkXfbms%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dadb7a4d212b34b6daae0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767196&x-signature=Oz7Ga60MuwgdAbC02Phrt5gJw80%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d58c66450e58546a09359~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767197&x-signature=Bc7g2gBB0iSDob0AEpzZ0A7BcNU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3a4826d2543c48a385fb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767198&x-signature=AY0FyhE1NBUbe5%2BgEWXEYS8k3O0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8e15a6d4dd5b4817b7a9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767201&x-signature=uf45JT8scZ2jMXG%2Bm%2FWOoBeWKyE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd5330241d1ed4b2cb1df~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767202&x-signature=YXrhdYrp%2FUbcsw2AJKivPX2y5jE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da4ff6f2aff564db6a256~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767204&x-signature=ePpVzCFauFeZw%2FOxO%2BSEs4hrfhU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfdda58ebaec24a4487a1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767207&x-signature=tLKC9NFeBMYWHafDNoFe400%2Bd6Y%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da43335a1722f47f999fb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767208&x-signature=0HVXol%2BxRglq9XwMCHCmHVmBMcg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dcbc8c3fe5a2844689a06~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767210&x-signature=Xv5T9gWzkl29bBGLze%2B1TsqjCq0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1651793fc6d944bdb38a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767214&x-signature=4S4P9PElaSiKQpOA%2FXgIBeneOGE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2875fcdfd3744adfbc4f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767216&x-signature=atSsBHNbIgLMDYhak%2B3tIQIFc84%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d23599f80acf4479695bb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767217&x-signature=c5nv9FvTwOSVaVDHCxc3s4W2mwU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9e21bfbdc7af41109d27~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767219&x-signature=jYsXybyKMSQaTLec4GS7jbafyq0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d14820cca64344a93b4c7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767221&x-signature=o1ExH1Ia4xUhxS0%2FW%2Fwzf5s%2FZbM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de7093da1412c4c25a2d9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767224&x-signature=jNJn9W7%2Fs%2FJdJrwsPEX9zr1IZ3Y%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d13df67df4f0c4bfc9075~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767226&x-signature=jfLb%2BZaCqpkZFWslU99xE70JUnU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc0cd70e1a6924616965e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767227&x-signature=TFx7yKT3BAsV7dWuvwgd3dvZg4Q%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3bd17594af2f491d9ed4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767229&x-signature=9qdqV2wv3UJl9GBy8OprvyeOjkE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3fd104425c544577a4cf~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767231&x-signature=6KSjCO6YpiEZ%2Fm9w6I6c1BOW%2B0Q%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfe1a4340c9b14bfba8b7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767233&x-signature=JF0hfmU8UhomCyFp4zaA5R1Kbu8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df247b4b9ce8e47a3bacf~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767234&x-signature=q4OiQGWTvJth35E%2FuiME6CagVM0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db4a91cee53d844bb8408~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767237&x-signature=oIaJ%2By%2BMGtXLD7dmx5LnQgEhSOs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db51d729b36e84939a294~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767239&x-signature=ifPKWnNkz8eQpBr7RGPmirKvcrU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1fc1315891a448708a38~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767240&x-signature=QS%2F%2BguIXxr%2FPEWngAqo2YR8uVQE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d61d33e171b8f4c6d979d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767243&x-signature=wWshs140qVWPtC5AN3z1NUvAr6E%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d31a6d4b0c846438dbfdd~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767245&x-signature=E6DhoDzIG0N5jbLBFdW%2FnIl9tkA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2beb61f360164e0c90df~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767247&x-signature=KRYnDLRyWFTUJ2K69Ktp9mPtOPU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de1adb7daafc249fda9fa~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767249&x-signature=N%2BDEqWATUd1CWtdR5pbZNs2Ynic%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d503f1ce106d043d7ade9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767251&x-signature=x4WAU4Hz0ZN00l6Pwd07tk2ZZq4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3af4a21108024dff9cc6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767253&x-signature=B8kPBjXxpYo8%2B%2BtizQczZa1uCz8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc5be9958085a4933b716~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767255&x-signature=RcuvJafMJEPG%2FrElQhl9G%2F%2F8txM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dedfe142737fe4268b9c1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767258&x-signature=vhPiI6BFQXoX4jEs7zXbGEy3qvQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da97f1c04528240c2b9a3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767264&x-signature=mFaAFd0u1aHEkronwLtGOe7Gi9w%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2db3576742d640deb00c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767265&x-signature=mM5GTjt9IEsvGYlZ5qCrk1qTX4o%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6eb19322ba37450a9532~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767267&x-signature=YaviezOxx%2FDVIfoMqtEV461%2BLiA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2daf339a0bf642289428~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767269&x-signature=6B6%2BkEfNBluXj43uS4qvxY0V1cs%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddbd33ce52cab403b8ce2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767271&x-signature=RV%2FKlEIJkxQVY0053hZUzFiGM%2Fc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d39fea53f5cf44533a143~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767272&x-signature=tS1biz73AjEW%2B0Ks7byAvQ5tmMk%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd4aee492239a4b349122~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767274&x-signature=BV4TwN1UklI8e0QksTk%2BwzT0zKI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0736191534e64e0ab327~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767276&x-signature=tHuqknb%2FZpxkmSrPXR8opD1nifk%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5d35c8d333054b8b9338~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767278&x-signature=DpLCA1DWBx%2BP8kUqMYvuWgREVr4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9acd1541b5394a06b1c0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767279&x-signature=4HAkFt0M3vPYsD%2B5hsO0oRU7DQU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da9235fd93092445a9ae3~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767281&x-signature=cS0kZUQfqQtN5E9WfPDDV2bcq9Q%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddd7dab1c8b604a1d95e7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767283&x-signature=%2FZK5nswXX51fyf5ISTBtk%2BWAXSc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dacee6b38c26441d78c10~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767285&x-signature=dinlhYjccNTnjh3bBncFGpvF7rI%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d09467c54e7fd4137a82e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767286&x-signature=w0XS4vhjZJADr7G7nkE9G1tg8mg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da4e692376ecf4c3dabd7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767287&x-signature=ma72ZzoaT%2FljaMSxowwhZGXbCuY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d29762616208e46959cc5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767289&x-signature=MWghOMG7Ct8smMw2MwnZ%2BsVWK4w%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d872772900eda4a1aa115~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767295&x-signature=Qd48UK9O15Pz%2BsFYw%2BnvFBOxpX8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dddf687a8f8f84a0c972b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767298&x-signature=Ppdi75myFbfzhsAauBQWMbYt64A%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d46267e8e529f4adbb0e0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767303&x-signature=ZuLpbcDWwWodPBZslIEUPg29ghk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d28c9a3f75c5142118c06~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767304&x-signature=aKKGEXOxp0amyyQbMdfT9AnkmGQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da24829a9e68f436b82b8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767308&x-signature=Rfyh0ROxKusMiq467XjGjtVpy9c%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc91d228cf2794711b44e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767316&x-signature=KgNgpMtvirEFc9tLzaVLTXCPt9s%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d73b0512ba1444e7b9ed0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767317&x-signature=fmhlMEDdYUmBFhm%2FMAVAKN5Ci14%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da5347f8ad05549cfb950~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767322&x-signature=mNTxPhX7tmKAm82VYEsjOxvfT0U%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2acf0b01068c4ce59808~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767329&x-signature=sTbfkIbtFWExH7RMo6fti%2Bq58bE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d84371edd12974b888c44~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767330&x-signature=C2Zg5v1s0Cq4dtFr4oLc6b%2BFCew%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9fbcc065fc524a0cb897~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767332&x-signature=CRpeta9jmnoY%2BLgacskLM9trhJY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbd21d1246c594259b904~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767340&x-signature=U2oi6%2FwGyasAon1qZGpjrUT%2FwwM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d58b42c32f90e41468e64~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767349&x-signature=oCltSJqfNMGSosx0ocftQmym6lE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dcc9ba03f3efa4c4da248~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767349&x-signature=cjiJ7GDJrLk%2FsSiYqBLmh8aqqn4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8d75b8907faa47ffbf18~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767358&x-signature=IH042oTOLVSFYLDbUuhsG7V5GkE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc96ac853a20c4e0eacc6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767359&x-signature=gotuBaR9cafNgnz75lLkdM1OvTc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddec6c5b3ae1a4040b071~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767364&x-signature=1fPxCXNKe24jxdeFfMmklStiLME%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6a9e00dc7be44f75a824~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767366&x-signature=uFQkerIW6Kpr30iqEKZdYL4MbPw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de83a5d8bab544d31a599~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767367&x-signature=wpau%2BXCcjUvPVgUFY6EFeBbgNp0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbe22ee07155b477092c4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767369&x-signature=bXsIuwPnGiMEDkm%2F6vHOh3bVOp0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da1a83fc517fd4ce49e7d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767371&x-signature=zbeT5grBCmjsoUE3gqJ43uZILKQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d625899dee72243318fc9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767373&x-signature=5h8H4wUlD5ypjKBCRb8LCnS1Ur4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9ba2c703f235432e8e6e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767376&x-signature=5CSqZcENzPVQmYhhwjuBjmf%2FTXk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbf8f8ec114ca4b16b300~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767377&x-signature=yLRimcfB4T7WPJSAh9v8r2VmnPs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7cbd792924934ed9a43a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767389&x-signature=tuzyfX1E2YL%2F83swjR%2B2esh24Ws%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0eaa9f600ab340dea477~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767390&x-signature=OVt1PkNjYZqJYanwJw9FxfLOxxM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6e7a3a94feb9458296a9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767391&x-signature=OWWoecPayXM9DXzI7RKc6lKpwSQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d041168774f38439ea036~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767393&x-signature=1NlWgviBlJDmlGc2KcraLbvmklo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8d624be532b94d5299c4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767395&x-signature=7J65oS4uBO8M2T7JkS3iyt5qX1s%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8dae48ac0d0f4cde8f9c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767397&x-signature=CMWGOfESHjcEDFwsufdxk4k0gzg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc50abd467a2948429bf0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767399&x-signature=VxxWAV7UnYpkE6QVC7QU0%2BPwAnw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d21e63b49860a48fc983f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767401&x-signature=P%2B%2FdSBsOsDKCS30rXYugd2bhDm8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1818a7db01d84a738e8a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767402&x-signature=q%2BiYaCz23P3z9nJT1Fy8bm%2BbmzM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1de63e99ff23452e80ad~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767404&x-signature=LnBiOiRFTjpyl8kejlhfOgC0xpo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d87134140cb524fb485e5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767405&x-signature=yKFYYNdZcV0QiR3nFq3i%2BSVcjbQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfd43acfba6404640aa56~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767407&x-signature=SkPoU%2FaCeoyGHoVel1om29koRPU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3f51dab052f942cba729~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767408&x-signature=W6KENxzUESMGw4e4SEbMuhjK2YM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d5b49e915815d41c5911e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767410&x-signature=DiGw1qTbcdKP3A4eP5s6Z4QL220%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d00be4b04ebca4585abf8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767412&x-signature=KXxiCOd%2FAv6GKGZhNkJzYznIMgQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4a00aaed3e9c4cdc976a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767413&x-signature=Ei8Cn2%2F7EX%2BM1nrjFEv0H9BrZac%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da6c0f339e798481d99a9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767415&x-signature=IrqO%2B9Ay33dEK2wAik3PIsAWC%2FQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db5f97ff159dd4360a1b0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767417&x-signature=oAIN2SGj20Ntqem50OWj411S9Lw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de81635af6a4644f89121~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767418&x-signature=UxFeS1YUETyDdRb%2BajOMCz2%2BMjE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d13e7467ace824753b314~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767421&x-signature=r0ayzvx5BS2k3uvsmZUJ8%2FSmhi8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dab17e539f0304330a8f6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767422&x-signature=N4rDZ5C7fQjuipacjFR%2FGO0pS1k%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d551fb0713c5641d980e2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767424&x-signature=DsPAma%2FmhaGaQ2Nvhsuqasry6vM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dfba3084057c74a259ad7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767426&x-signature=UygI5lKozEiq0E7BCVpzQd9wi2E%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db1e8feb9518b4ea59ad4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767428&x-signature=j1jjC7yRJP6kkwHLD%2Fol2i6fDhY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbabc8dd54e834a9fbd00~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767429&x-signature=cCXzutvSNIYCkJOFSAflO6h8I9c%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9d82208f6bb44780bdf6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767431&x-signature=ggsekkj6eOLImjTA9cON5%2BRHFWU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d95b174c5b4f943d3bef0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767444&x-signature=sPik1968jbHZectBp%2FU%2FMIaqV4M%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d01822d3d59544897ae2d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767449&x-signature=D524dwyjVNRYk1D91oSXTqXmfY0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dac257b3398e647498f73~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767451&x-signature=nkkZvaK7mWUHzF4QKne52PeilNY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0fed4a71aa1d40a39ef5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767461&x-signature=B1EORpUfUT6uDEC3Op4ZTk0qq2E%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd26bf7f7896d45318409~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767463&x-signature=1PJ7emElos0fqeeVilEObcJW3Ok%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d001bc3fd78de41d6aaad~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767465&x-signature=Cb%2Fy7%2BIbl8I5WKGoXi%2Fh1TJQHss%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6f0d920a63c343aaa0d0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767467&x-signature=27eIWXW3ZE%2FX3Q64OQtmw179GSA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2254f3d43d644ff39686~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767468&x-signature=7YAsb1MRXAoo%2FolcNGKg%2B%2FQl3hQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6151a3030a8b4ca29a30~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767470&x-signature=H8g7XE6vnDa8yp3mM1Y3owiiGko%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc3335963fdfe4082a3aa~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767472&x-signature=PwKpgWQON34rAW8vEQ3TTcEE%2FOE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3f4dcc6eb98a49d283b6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767474&x-signature=yzTiy1KZop1cJZmXWTORcd5aZmg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d163df787733c49d880b8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767476&x-signature=LtBWY6SidVe5JcI8RFMRaVMpEeA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d6fa22ef94d494af4ae96~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767477&x-signature=Fsef4Gd8gItXzkKcv7TRCundQMA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df39d2cfbd99744cdae1f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767480&x-signature=jpv%2BYR6ncYp%2FTqjRyi5DHWhIYTM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3354e69e640c4d27b929~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767481&x-signature=y2%2BLA8B4MIyfOWsb4o42r4V695g%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9d6cf731f5854f0ba76d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767483&x-signature=2Q%2F5YsWFTXCMNRqx8feF29QAaiU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd3cdd2a9ffa14ce0978a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767484&x-signature=yoKJH7os5zcozEA4B%2BqN1s5dgN8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d309a65bf38fb46f78844~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767486&x-signature=%2F2ge5yHTLUWb3N6InuJEZIqehNY%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db4b99b0c09fb42c7a8e4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767488&x-signature=DrChtkAFpSEb4CjV%2Bbs0fVFyjqE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1a7202786510486083e2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767489&x-signature=6VOTcL%2FB2tzvo5SvxgfIacmSa54%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d217430d475f54840af5e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767492&x-signature=EviNb%2FjzfHxPAQuzmjcsREODmSQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d46bfa48921d34a15a390~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767499&x-signature=5Wce5Mv7UXUIUlSfw7bM3%2Btx5Zw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9cb8fec0d5534a2a9cd0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767501&x-signature=r7tfeFgrZLKXpSdjrxlM%2BAtSNBo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d50a882276fcd4c848304~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767504&x-signature=8%2Fi6zpsXlxTtec3HaMDeR%2F%2FFVaU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0a91e86833e24155856f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767507&x-signature=uP%2FEgAhiid1HsSfuqi%2FMOmXIrb8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da8a39d7b5c4d4762998c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767509&x-signature=PjuHyUnm%2BVapKCodCYK0v00Clvw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de016739d4120441987d6~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767512&x-signature=cPo5Lv0j3o1Yc8hUwj7TgV04QIA%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d87fe52bc480049b58bde~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767513&x-signature=GACfvAX03JSBNfGnIoqfu8%2B9%2BU8%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de9f8d51318ca407aab94~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767514&x-signature=v59Pw8prlKF8h0FWoUqcOJkiSsA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d18627cd7257540cba3e1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767516&x-signature=3XmM6xUkItEKnXBxN2%2B1WcSYFAo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1831032a2c6943dfb33c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767520&x-signature=EkTa3avGwsgtMWXb%2BZVp05yEL6Y%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db65129b606fb42668768~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767522&x-signature=wNdntTq8Mp841nEJ3%2B1Ho4KexLE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ddf0e3183dadc4f8bbaee~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767523&x-signature=6u%2FuKaYgSaeTaGOS%2F4%2Fo2mjvyZ4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8406a41c94df4837aa50~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767524&x-signature=VwcULChpHindYzCGp46oyeWA17s%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d46053c838e224a6eb984~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767527&x-signature=j1gD20HIHVJQXdfBh1NEIghLm3o%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df40981205201423791a8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767528&x-signature=3IQdrhwSy2F9%2BO82N8rJgsX94x0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1f7556a363bc48a7ba1c~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767530&x-signature=4Rn%2FrgT4z6hBYaU4toHVtWkihOQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d24209c074d284b2b8202~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767532&x-signature=6U29IoNGt%2FecIKzW3xaJVe3nTwg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d133e6ad3b40a492c8b1a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767535&x-signature=g0wRK7SF49lcNBeO%2FjVHzAiLbDM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d588ecdb1f91a4f679849~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767536&x-signature=ntJ774AxC7Bt%2FqOB2LORJ5%2FgNs8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de4c0e705c00f422b8b99~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767537&x-signature=8TgI6IPvKE%2Fc02pc81vlurgWDQg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d93e8505ca7004c6ba0aa~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767540&x-signature=U7LjI24v5mJp6pUEunpMFH%2BxfoU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4c5d6ca7d2ba428dadde~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767542&x-signature=oCdExEuH3HOO13gqg4HobWzNekw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2c1d48cdc5704a4db597~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767544&x-signature=S8Zpys3fuPFvxVDPqqrYjDoiQS0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0daa783a5c472548f59be2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767546&x-signature=bmNJAu5%2BfC%2B0b0WnOiNNiTBZaEw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d412715376bcb4c148841~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767548&x-signature=3UiAC27m8KJq1FN062PDsufzi2Q%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d71e718cce6e5488b9826~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767549&x-signature=%2Fy3MP5pc27cJBVApUzDego2IB04%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1fdc011f8b994b559a44~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767551&x-signature=TTWFAuUSS0JdzrTfRa5jfvIZHgo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2e5d7c2a97d94f6cb176~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767554&x-signature=QfYu3v4Kw%2BanzdrxHH31xJhVSaE%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d208b74ce49bf4b3db8fe~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767556&x-signature=uOj28kvQRcoihaN8sGTX7iE1DG0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0ded96da6bc99840d7bf91~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767557&x-signature=yrF3CbDdnO9RYRMy8iQ834tcnBU%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbfff158ecf3b4d41a0cf~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767559&x-signature=y2Re%2FjLJmyWzvF7K7i0tE2MRlYw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3942e54f951b42a2b5bf~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767562&x-signature=kzXWuJNXWKwms3fB6SE42fmd2JM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d7e6c576e37e24492a9d7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767563&x-signature=prXB64FXcwvId%2Bg2mglm%2Byj2CjI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2bf1b730ac80421c8f89~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767565&x-signature=t3MC4jaC2g%2BJm8ssyXwzf2PPwf8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d058b1b1653e845638612~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767567&x-signature=dG7ECe%2F6BkRwTbDM97Wayk9sbvE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dce09c71ae1244590bdc0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767570&x-signature=IrbR8jkqpdJg4UwoUdA75hrrpmw%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d69db304b818a41c2b6fb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767572&x-signature=fyEBjXRJyyLmlnk0%2B6EyPw%2Biq18%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d512ed05d21df467a9e74~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767575&x-signature=F5TW1zizRs%2BK5qW%2Bo6c9LDyUmhs%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d40d09160f6654e0c9704~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767577&x-signature=SD6JKK26MnvfsG96PYf11iik2jA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d62425725357044ea8991~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767580&x-signature=fpYe2WQh6EPSLUtr7QkwZTHN4VY%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9490ddd3c94d4d1e9cad~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767584&x-signature=vI28ftPAeaEzG9cOZekLwV8DTP0%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d998b7bac12f14db5b041~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767585&x-signature=Ig95D2IzDm5hDDhlhVaxRqEdN5o%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc69bdd27d00645fe9809~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767587&x-signature=vy7gKMZcGtgM7buujyud14zTmpI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df45cf28471b04bf5a81f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767592&x-signature=hFNVF7C7eLU2o7I86Wi2VBzwbzg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d29fd4f276c6845198222~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767593&x-signature=c%2B9UTWEwXqBwPUxiyjfNo5WEMms%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0daec644b7da6a4dd9a0ee~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767595&x-signature=BvfYAXQpDHEYxygL3Ba3i%2BrnXAI%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3da11876e48c4255bb77~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767599&x-signature=Stf4%2B0dbCJnJEvEm12y%2FrxJt%2Bgw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0bc6ef7ac0d442afa164~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767603&x-signature=cASi80DLFPuecArystrVyWbVGc0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d613307efe9564367ad7e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767607&x-signature=%2FdwjO7D2CeMalTvlmRyobjS30Bk%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9cadb8f756074c5e8cf1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767612&x-signature=qtal78LfGCT4FT4AYI%2FO3VpEaZQ%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dedebe68f8341443786bf~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767615&x-signature=n4DGdEwf%2BzvJ8gQGGvEk9M6QB2Q%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9cf13b4e73144c21b7eb~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767618&x-signature=NkLdFoIyYP4wRHsCihvrHxTKYVw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d74ef15ac687248d28928~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767626&x-signature=D9OL5bBp64db2tIGAQrMIrTUpm8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d458cded9d05648ffa4a4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767628&x-signature=LpZRRJK0HcUL2vq8gYVvxnfQ2sU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dc929802993ef46728773~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767631&x-signature=ncYHPSnYcpMS8zzCwtwMYP9qeu4%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de5f0f2f74294417bb226~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767633&x-signature=Dk9V4pzqZfZXIVDuOVNtVkzZOOk%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d654b7ecc60214cef97f9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767636&x-signature=YbOOMjCWegtPDGVIjCuAW34okcw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dbedb60aa9b2943cabc81~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767637&x-signature=oLZTD3lTc21AnM1Az9IBAWNnGDA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4dbee8b953b5411b83c8~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767639&x-signature=pmCWbMjHHgjPetugitrSSFEYAyg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d17a71dbb2a7640098426~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767641&x-signature=ANnoM1jyGb3ZDM57Tlf8DDWeWIc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d1cfb3a27733b489cb350~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767643&x-signature=qYKo3DpzT4SZ%2FmkgsRHtJmVTyUw%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d190928a9e41947809f8e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767644&x-signature=COpWFJtMTowVW4f1CoaQv29nccA%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d3b87f4c111f0462f8ed9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767646&x-signature=Qt6Mwu76q2T38v9k3MAkNpoAP2g%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d247f5f1db5de401082a1~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767647&x-signature=0Ubr7zo6hH8T44tii0JUW%2B14PT4%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df39be4b8b6a744c18c9d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767649&x-signature=p%2F%2B0xby1YEyeFzfEQw0rzcQssBQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0df2aa4a002c7a499890a4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767651&x-signature=UbgPHtdU9utVQpPlcogH1pgH6Yg%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dee500182e282477cb781~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767652&x-signature=0d%2F9zqv58T51J1VQiH%2BT54tA1zU%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0da3faa67256314f84ac67~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767655&x-signature=fQp9SnozearSWeA%2B3Kpc4K3y4ds%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0db17dc5e9364e49099da0~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767661&x-signature=jPhHHvBEs9mV8YWd9LVwCz6mzBc%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd4d2382106d44c22b3fe~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767663&x-signature=J1hcJlZx3Bfr%2FOl4S4H1xH8bTXM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d2435a92ba5e04c93aac9~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767665&x-signature=Js9rivRW%2BkenvpI6%2FX0DPMY3uf8%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d8748f7ee5095420a8fa4~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767667&x-signature=xl7A60g3CP%2BjOEqqtE2nVaCIg10%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de1735d10ea2a4a63ad35~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767669&x-signature=7iHTQj0%2BSUjXBQgBiKPz7vzfEG0%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0b2f583d58ea4e1fb73e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767671&x-signature=J%2FkHz%2BJD5oAettyHAUrMLhS2Vik%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d043e6656ae27482eb94a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767673&x-signature=Xy4uOsmu5JOM2%2BHxS10YjuXMoeE%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d498cf77a6c5043459ed5~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767674&x-signature=WjDrLWtOb5VzCqr4jkJgtoopivM%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0de4a93cd176ab4415a96f~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767677&x-signature=XroqUqHBS94x7L91CEsVFJHS1qo%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d15a836bd39a44e7c8800~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767679&x-signature=N3PP1ePwy3iqxhOy34DmoosDenM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dad477bc22f4b4b119c7e~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767680&x-signature=vem4QHkzvGUlfO2qlB8PhLIpdBo%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0b0861b9602e43358bad~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767683&x-signature=L8LP6h6Su%2BIlgSu89GAGb9Ii5SM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d9e0661a996d24922b988~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767685&x-signature=MdGQ84cvkNkWSnhR71AAiym4TmM%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d248322ea591e4ba3a05a~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767687&x-signature=A%2FRdQJkg7%2B1KGTf4lAMjMlj1wgc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d192c8225a9e54d06a076~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767690&x-signature=7vp7TnV8ie%2Fr5b0WXA2LzWKABhg%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d0e6b628c047e4e03b1c7~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767693&x-signature=sqSeruQAEC%2FeCm0YzrPYv0pcTNc%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0dd7cf07c0286a4ffb89d2~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767695&x-signature=%2BGKI2TpBzP75ALEJGxNXty4U5PQ%3D +#EXTINF:5.066667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d4de2607460984a1b860d~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767698&x-signature=K0wRKL1ppuCfMQTpYqcSA6o7j1g%3D +#EXTINF:5.066667, +https://p19-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d890a700484784264aa22~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767704&x-signature=pO%2BvhAnpZzRBMGYnqj7keBkKUVk%3D +#EXTINF:2.966667, +https://p16-ad-site-sign-sg.tiktokcdn.com/ad-site-i18n-sg/202509305d0d727cd8cc062e4285ad1b~tplv-d5opwmad15-ttam-origin.image?lk3s=6d71dd51&x-expires=1790767705&x-signature=fNJ%2Btx3sSUyZK6tEl7Y9cnunj4o%3D +#EXT-X-ENDLIST diff --git a/public/logomin.jpg b/public/logomin.jpg new file mode 100644 index 0000000..9b573fa Binary files /dev/null and b/public/logomin.jpg differ diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..45dc8a2 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/api/rpc/auth.ts b/src/api/rpc/auth.ts new file mode 100644 index 0000000..748204c --- /dev/null +++ b/src/api/rpc/auth.ts @@ -0,0 +1,242 @@ +import { getContext } from "hono/context-storage"; +import { setCookie, deleteCookie, getCookie } from 'hono/cookie'; +import { HonoVarTypes } from "types"; +import { sign, verify } from "hono/jwt"; + +interface RegisterModel { + username: string; + password: string; + email: string; +} + +interface User { + id: string; + username: string; + email: string; + name: string; +} + +// Mock user database (in-memory) +const mockUsers: Map = new Map([ + ['admin', { + password: 'admin123', + user: { + id: '1', + username: 'admin', + email: 'admin@example.com', + name: 'Admin User' + } + }], + ['user@example.com', { + password: 'password', + user: { + id: '2', + username: 'user', + email: 'user@example.com', + name: 'Test User' + } + }] +]); + +// CSRF token storage (in-memory, in production use Redis or similar) +const csrfTokens = new Map(); + +// Secret for JWT signing +const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production'; + +function generateCSRFToken(): string { + return crypto.randomUUID(); +} + +function validateCSRFToken(sessionId: string, token: string): boolean { + const stored = csrfTokens.get(sessionId); + if (!stored) return false; + if (stored.expires < Date.now()) { + csrfTokens.delete(sessionId); + return false; + } + return stored.token === token; +} + +const register = async (registerModel: RegisterModel) => { + // Check if user already exists + if (mockUsers.has(registerModel.username) || mockUsers.has(registerModel.email)) { + throw new Error('User already exists'); + } + + const newUser: User = { + id: crypto.randomUUID(), + username: registerModel.username, + email: registerModel.email, + name: registerModel.username + }; + + mockUsers.set(registerModel.username, { + password: registerModel.password, + user: newUser + }); + + mockUsers.set(registerModel.email, { + password: registerModel.password, + user: newUser + }); + + const context = getContext(); + const sessionId = crypto.randomUUID(); + const csrfToken = generateCSRFToken(); + + // Store CSRF token (expires in 1 hour) + csrfTokens.set(sessionId, { + token: csrfToken, + expires: Date.now() + 60 * 60 * 1000 + }); + + // Create JWT token with user info + const token = await sign({ + sub: newUser.id, + username: newUser.username, + email: newUser.email, + sessionId, + exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 // 24 hours + }, JWT_SECRET); + + // Set HTTP-only cookie + setCookie(context, 'auth_token', token, { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + sameSite: 'Lax', + path: '/', + maxAge: 60 * 60 * 24 // 24 hours + }); + + return { + success: true, + user: newUser, + csrfToken // Return CSRF token to client for subsequent requests + }; +}; + +const login = async (username: string, password: string) => { + // Try to find user by username or email + const userRecord = mockUsers.get(username); + + if (!userRecord) { + throw new Error('Invalid credentials'); + } + + if (userRecord.password !== password) { + throw new Error('Invalid credentials'); + } + + const context = getContext(); + const sessionId = crypto.randomUUID(); + const csrfToken = generateCSRFToken(); + + // Store CSRF token (expires in 1 hour) + csrfTokens.set(sessionId, { + token: csrfToken, + expires: Date.now() + 60 * 60 * 1000 + }); + + // Create JWT token with user info + const token = await sign({ + sub: userRecord.user.id, + username: userRecord.user.username, + email: userRecord.user.email, + sessionId, + exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 // 24 hours + }, JWT_SECRET); + + // Set HTTP-only cookie + setCookie(context, 'auth_token', token, { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + sameSite: 'Lax', + path: '/', + maxAge: 60 * 60 * 24 // 24 hours + }); + + return { + success: true, + user: userRecord.user, + csrfToken // Return CSRF token to client for subsequent requests + }; +}; + +async function checkAuth() { + const context = getContext(); + const token = getCookie(context, 'auth_token'); + + if (!token) { + return { authenticated: false, user: null }; + } + + try { + const payload = await verify(token, JWT_SECRET) as any; + + // Find user + const userRecord = Array.from(mockUsers.values()).find( + record => record.user.id === payload.sub + ); + + if (!userRecord) { + return { authenticated: false, user: null }; + } + + return { + authenticated: true, + user: userRecord.user + }; + } catch (error) { + return { authenticated: false, user: null }; + } +} + +async function logout() { + const context = getContext(); + const token = getCookie(context, 'auth_token'); + + if (token) { + try { + const payload = await verify(token, JWT_SECRET) as any; + // Remove CSRF token + if (payload.sessionId) { + csrfTokens.delete(payload.sessionId); + } + } catch (error) { + // Token invalid, just delete cookie + } + } + + deleteCookie(context, 'auth_token', { path: '/' }); + + return { success: true }; +} + +async function getCSRFToken() { + const context = getContext(); + const token = getCookie(context, 'auth_token'); + + if (!token) { + throw new Error('Not authenticated'); + } + + const payload = await verify(token, JWT_SECRET) as any; + const stored = csrfTokens.get(payload.sessionId); + + if (!stored) { + throw new Error('CSRF token not found'); + } + + return { csrfToken: stored.token }; +} + +export const authMethods = { + register, + login, + checkAuth, + logout, + getCSRFToken, +}; + +export { validateCSRFToken }; \ No newline at end of file diff --git a/src/api/rpc/commom.ts b/src/api/rpc/commom.ts new file mode 100644 index 0000000..5e1a417 --- /dev/null +++ b/src/api/rpc/commom.ts @@ -0,0 +1 @@ +export const secret = "123_it-is-very-secret_123"; \ No newline at end of file diff --git a/src/api/rpc/index.ts b/src/api/rpc/index.ts new file mode 100644 index 0000000..af46bff --- /dev/null +++ b/src/api/rpc/index.ts @@ -0,0 +1,333 @@ +import { + exposeTinyRpc, + httpServerAdapter, + validateFn, +} from "@hiogawa/tiny-rpc"; +import { tinyassert } from "@hiogawa/utils"; +import { MiddlewareHandler, type Context, type Next } from "hono"; +import { getContext } from "hono/context-storage"; +import { register } from "module"; +import { z } from "zod"; +import { authMethods } from "./auth"; +import { jwt } from "hono/jwt"; +import { secret } from "./commom"; +import { abortChunk, chunkedUpload, completeChunk, createPresignedUrls, imageContentTypes, nanoid, presignedPut, videoContentTypes } from "./s3_handle"; +// import { createElement } from "react"; + +let counter = 0; +const listCourses = [ + { + id: 1, + title: "Lập trình Web Fullstack", + description: + "Học cách xây dựng ứng dụng web hoàn chỉnh từ frontend đến backend. Khóa học bao gồm HTML, CSS, JavaScript, React, Node.js và MongoDB.", + category: "Lập trình", + rating: 4.9, + price: "1.200.000 VNĐ", + icon: "fas fa-code", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Web%20Fullstack", + slug: "lap-trinh-web-fullstack", + }, + { + id: 2, + title: "Phân tích dữ liệu với Python", + description: + "Khám phá sức mạnh của Python trong việc phân tích và trực quan hóa dữ liệu. Sử dụng Pandas, NumPy, Matplotlib và Seaborn.", + category: "Phân tích dữ liệu", + rating: 4.8, + price: "900.000 VNĐ", + icon: "fas fa-chart-bar", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Data%20Analysis", + slug: "phan-tich-du-lieu-voi-python", + }, + { + id: 3, + title: "Thiết kế UI/UX chuyên nghiệp", + description: + "Học các nguyên tắc thiết kế giao diện và trải nghiệm người dùng hiện đại. Sử dụng Figma và Adobe XD.", + category: "Thiết kế", + rating: 4.7, + price: "800.000 VNĐ", + icon: "fas fa-paint-brush", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=UI/UX%20Design", + slug: "thiet-ke-ui-ux-chuyen-nghiep", + }, + { + id: 4, + title: "Machine Learning cơ bản", + description: + "Nhập môn Machine Learning với Python. Tìm hiểu về các thuật toán học máy cơ bản như Linear Regression, Logistic Regression, Decision Trees.", + category: "AI/ML", + rating: 4.6, + price: "1.500.000 VNĐ", + icon: "fas fa-brain", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Machine%20Learning", + slug: "machine-learning-co-ban", + }, + { + id: 5, + title: "Digital Marketing toàn diện", + description: + "Chiến lược Marketing trên các nền tảng số. SEO, Google Ads, Facebook Ads và Content Marketing.", + category: "Marketing", + rating: 4.5, + price: "700.000 VNĐ", + icon: "fas fa-bullhorn", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Digital%20Marketing", + slug: "digital-marketing-toan-dien", + }, + { + id: 6, + title: "Lập trình Mobile với Flutter", + description: + "Xây dựng ứng dụng di động đa nền tảng (iOS & Android) với Flutter và Dart.", + category: "Lập trình", + rating: 4.8, + price: "1.100.000 VNĐ", + icon: "fas fa-mobile-alt", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Flutter%20Mobile", + slug: "lap-trinh-mobile-voi-flutter", + }, + { + id: 7, + title: "Tiếng Anh giao tiếp công sở", + description: + "Cải thiện kỹ năng giao tiếp tiếng Anh trong môi trường làm việc chuyên nghiệp.", + category: "Ngoại ngữ", + rating: 4.4, + price: "600.000 VNĐ", + icon: "fas fa-language", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Business%20English", + slug: "tieng-anh-giao-tiep-cong-so", + }, + { + id: 8, + title: "Quản trị dự án Agile/Scrum", + description: + "Phương pháp quản lý dự án linh hoạt Agile và khung làm việc Scrum.", + category: "Kỹ năng mềm", + rating: 4.7, + price: "950.000 VNĐ", + icon: "fas fa-tasks", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Agile%20Scrum", + slug: "quan-tri-du-an-agile-scrum", + }, + { + id: 9, + title: "Nhiếp ảnh cơ bản", + description: + "Làm chủ máy ảnh và nghệ thuật nhiếp ảnh. Bố cục, ánh sáng và chỉnh sửa ảnh.", + category: "Nghệ thuật", + rating: 4.9, + price: "500.000 VNĐ", + icon: "fas fa-camera", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Photography", + slug: "nhiep-anh-co-ban", + }, + { + id: 10, + title: "Blockchain 101", + description: + "Hiểu về công nghệ Blockchain, Bitcoin, Ethereum và Smart Contracts.", + category: "Công nghệ", + rating: 4.6, + price: "1.300.000 VNĐ", + icon: "fas fa-link", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Blockchain", + slug: "blockchain-101", + }, + { + id: 11, + title: "ReactJS Nâng cao", + description: + "Các kỹ thuật nâng cao trong React: Hooks, Context, Redux, Performance Optimization.", + category: "Lập trình", + rating: 4.9, + price: "1.000.000 VNĐ", + icon: "fas fa-code", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Advanced%20React", + slug: "reactjs-nang-cao", + }, + { + id: 12, + title: "Viết Content Marketing thu hút", + description: + "Kỹ thuật viết bài chuẩn SEO, thu hút người đọc và tăng tỷ lệ chuyển đổi.", + category: "Marketing", + rating: 4.5, + price: "550.000 VNĐ", + icon: "fas fa-pen-nib", + bgImg: "https://placehold.co/600x400/EEE/31343C?font=playfair-display&text=Content%20Marketing", + slug: "viet-content-marketing", + } +]; + +const courseContent = [ + { + id: 1, + title: "Giới thiệu khóa học", + type: "video", + duration: "5:00", + completed: true, + }, + { + id: 2, + title: "Cài đặt môi trường", + type: "video", + duration: "15:00", + completed: false, + }, + { + id: 3, + title: "Kiến thức cơ bản", + type: "video", + duration: "25:00", + completed: false, + }, + { + id: 4, + title: "Bài tập thực hành 1", + type: "quiz", + duration: "10:00", + completed: false, + }, +]; + +const routes = { + // define as a bare function + checkId: (id: string) => { + const context = getContext(); + console.log(context.req.raw.headers); + return id === "good"; + }, + + checkIdThrow: (id: string) => { + tinyassert(id === "good", "Invalid ID"); + return null; + }, + + getCounter: () => { + const context = getContext(); + console.log(context.get("jwtPayload")); + return counter; + }, + + // define with zod validation + input type inference + incrementCounter: validateFn(z.object({ delta: z.number().default(1) }))( + (input) => { + // expectTypeOf(input).toEqualTypeOf<{ delta: number }>(); + counter += input.delta; + return counter; + } + ), + + // access context + components: async () => {}, + getHomeCourses: async () => { + return listCourses.slice(0, 3); + }, + getCourses: validateFn( + z.object({ + page: z.number().default(1), + limit: z.number().default(6), + search: z.string().optional(), + category: z.string().optional(), + }) + )(async ({ page, limit, search, category }) => { + let filtered = listCourses; + + if (search) { + const lowerSearch = search.toLowerCase(); + filtered = filtered.filter( + (c) => + c.title.toLowerCase().includes(lowerSearch) || + c.description.toLowerCase().includes(lowerSearch) + ); + } + + if (category && category !== "All") { + filtered = filtered.filter((c) => c.category === category); + } + + const start = (page - 1) * limit; + const end = start + limit; + const paginated = filtered.slice(start, end); + + return { + data: paginated, + total: filtered.length, + page, + totalPages: Math.ceil(filtered.length / limit), + }; + }), + getCourseBySlug: validateFn(z.object({ slug: z.string() }))(async ({ slug }) => { + const course = listCourses.find((c) => c.slug === slug); + if (!course) { + throw new Error("Course not found"); + } + return course; + }), + getCourseContent: validateFn(z.object({ slug: z.string() }))(async ({ slug }) => { + // In a real app, we would fetch content specific to the course + return courseContent; + }), + presignedPut: validateFn(z.object({ fileName: z.string(), contentType: z.string().refine((val) => imageContentTypes.includes(val), { message: "Invalid content type" }) }))(async ({ fileName, contentType }) => { + return await presignedPut(fileName, contentType); + }), + chunkedUpload: validateFn(z.object({ fileName: z.string(), contentType: z.string().refine((val) => videoContentTypes.includes(val), { message: "Invalid content type" }), fileSize: z.number().min(1024 * 10).max(3 * 1024 * 1024 * 1024).default(1024 * 256) }))(async ({ fileName, contentType, fileSize }) => { + const key = nanoid() + "_" + fileName; + const { UploadId } = await chunkedUpload(key, contentType, fileSize); + const chunkSize = 1024 * 1024 * 20; // 20MB + const presignedUrls = await createPresignedUrls({ + key, + uploadId: UploadId!, + totalParts: Math.ceil(fileSize / chunkSize), + }); + return { uploadId: UploadId!, presignedUrls, chunkSize, key, totalParts: presignedUrls.length }; + }), + completeChunk: validateFn(z.object({ key: z.string(), uploadId: z.string(), parts: z.array(z.object({ PartNumber: z.number(), ETag: z.string() })) }))(async ({ key, uploadId, parts }) => { + await completeChunk(key, uploadId, parts); + return { success: true }; + }), + abortChunk: validateFn(z.object({ key: z.string(), uploadId: z.string() }))(async ({ key, uploadId }) => { + await abortChunk(key, uploadId); + return { success: true }; + }), + ...authMethods +}; +export type RpcRoutes = typeof routes; +export const endpoint = "/rpc"; +export const pathsForGET: (keyof typeof routes)[] = ["getCounter"]; +export const jwtRpc: MiddlewareHandler = async (c, next) => { + const publicPaths: (keyof typeof routes)[] = ["getHomeCourses", "getCourses", "getCourseBySlug", "getCourseContent", "login", "register"]; + const isPublic = publicPaths.some((path) => c.req.path.split("/").includes(path)); + c.set("isPublic", isPublic); + // return await next(); + if (c.req.path !== endpoint && !c.req.path.startsWith(endpoint + "/") || isPublic) { + return await next(); + } + console.log("JWT RPC Middleware:", c.req.path); + const jwtMiddleware = jwt({ + secret, + cookie: 'auth_token', + verification: { + aud: "ez.lms_users", + } + }) + return jwtMiddleware(c, next) +} +export const rpcServer = async (c: Context, next: Next) => { + if (c.req.path !== endpoint && !c.req.path.startsWith(endpoint + "/")) { + return await next(); + } + // c.get("redis").has(`auth_token:${}`) + const handler = exposeTinyRpc({ + routes, + adapter: httpServerAdapter({ endpoint }), + }); + const res = await handler({ request: c.req.raw }); + if (res) { + return res; + } + return await next(); +}; diff --git a/src/api/rpc/s3_handle.ts b/src/api/rpc/s3_handle.ts new file mode 100644 index 0000000..ede32c3 --- /dev/null +++ b/src/api/rpc/s3_handle.ts @@ -0,0 +1,198 @@ +import { + S3Client, + ListBucketsCommand, + ListObjectsV2Command, + GetObjectCommand, + PutObjectCommand, + DeleteObjectCommand, + CreateMultipartUploadCommand, + UploadPartCommand, + AbortMultipartUploadCommand, + CompleteMultipartUploadCommand, + ListPartsCommand, +} from "@aws-sdk/client-s3"; +import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; + import { createPresignedPost } from "@aws-sdk/s3-presigned-post"; +import { randomBytes } from "crypto"; + const urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + +export function nanoid(size = 21) { + let id = ''; + const bytes = randomBytes(size); // Node.js specific method + + for (let i = 0; i < size; i++) { + id += urlAlphabet[bytes[i] & 63]; + } + + return id; +} +// createPresignedPost +const S3 = new S3Client({ + region: "auto", // Required by SDK but not used by R2 + endpoint: `https://s3.cloudfly.vn`, + credentials: { + // accessKeyId: "Q3AM3UQ867SPQQA43P2F", + // secretAccessKey: "Ik7nlCaUUCFOKDJAeSgFcbF5MEBGh9sVGBUrsUOp", + accessKeyId: "BD707P5W8J5DHFPUKYZ6", + secretAccessKey: "LTX7IizSDn28XGeQaHNID2fOtagfLc6L2henrP6P", + }, + forcePathStyle: true, +}); +// const S3 = new S3Client({ +// region: "auto", // Required by SDK but not used by R2 +// endpoint: `https://u.pipic.fun`, +// credentials: { +// // accessKeyId: "Q3AM3UQ867SPQQA43P2F", +// // secretAccessKey: "Ik7nlCaUUCFOKDJAeSgFcbF5MEBGh9sVGBUrsUOp", +// accessKeyId: "cdnadmin", +// secretAccessKey: "D@tkhong9", +// }, +// forcePathStyle: true, +// }); +export const imageContentTypes = ["image/png", "image/jpg", "image/jpeg", "image/webp"]; +export const videoContentTypes = ["video/mp4", "video/webm", "video/ogg", "video/*"]; +const nanoId = () => { + // return crypto.randomUUID().replace(/-/g, "").slice(0, 10); + return "" +} +export async function presignedPut(fileName: string, contentType: string){ + if (!imageContentTypes.includes(contentType)) { + throw new Error("Invalid content type"); + } + const key = nanoId()+"_"+fileName; + const url = await getSignedUrl( + S3, + new PutObjectCommand({ + Bucket: "tmp", + Key: key, + ContentType: contentType, + CacheControl: "public, max-age=31536000, immutable", + // ContentLength: 31457280, // Max 30MB + // ACL: "public-read", // Uncomment if you want the object to be publicly readable + }), + { expiresIn: 600 } // URL valid for 10 minutes + ); + return { url, key }; +} +export async function createPresignedUrls({ + key, + uploadId, + totalParts, + expiresIn = 60 * 15, // 15 phút +}: { + key: string; + uploadId: string; + totalParts: number; + expiresIn?: number; +}) { + const urls = []; + + for (let partNumber = 1; partNumber <= totalParts; partNumber++) { + const command = new UploadPartCommand({ + Bucket: "tmp", + Key: key, + UploadId: uploadId, + PartNumber: partNumber, + }); + + const url = await getSignedUrl(S3, command, { + expiresIn, + }); + + urls.push({ + partNumber, + url, + }); + } + + return urls; +} +export async function chunkedUpload(Key: string, contentType: string, fileSize: number) { + // lớn hơn 3gb thì cút + if (fileSize > 3 * 1024 * 1024 * 1024) { + throw new Error("File size exceeds 3GB"); + } + // CreateMultipartUploadCommand + const uploadParams = { + Bucket: "tmp", + Key, + ContentType: contentType, + CacheControl: "public, max-age=31536000, immutable", + }; + let data = await S3.send(new CreateMultipartUploadCommand(uploadParams)); + return data; +} +export async function abortChunk(key: string, uploadId: string) { + await S3.send( + new AbortMultipartUploadCommand({ + Bucket: "tmp", + Key: key, + UploadId: uploadId, + }) + ); +} +export async function completeChunk(key: string, uploadId: string, parts: { ETag: string; PartNumber: number }[]) { + const listed = await S3.send( + new ListPartsCommand({ + Bucket: "tmp", + Key: key, + UploadId: uploadId, + }) + ); + if (!listed.Parts || listed.Parts.length !== parts.length) { + throw new Error("Not all parts have been uploaded"); + } + await S3.send( + new CompleteMultipartUploadCommand({ + Bucket: "tmp", + Key: key, + UploadId: uploadId, + MultipartUpload: { + Parts: parts.sort((a, b) => a.PartNumber - b.PartNumber), + }, + }) + ); +} +export async function deleteObject(bucketName: string, objectKey: string) { + await S3.send( + new DeleteObjectCommand({ + Bucket: bucketName, + Key: objectKey, + }) + ); +} +export async function listBuckets() { + const data = await S3.send(new ListBucketsCommand({})); + return data.Buckets; +} +export async function listObjects(bucketName: string) { + const data = await S3.send( + new ListObjectsV2Command({ + Bucket: bucketName, + }) + ); + return data.Contents; +} +export async function generateUploadForm(fileName: string, contentType: string) { + if (!imageContentTypes.includes(contentType)) { + throw new Error("Invalid content type"); + } + return await createPresignedPost(S3, { + Bucket: "tmp", + Key: nanoId()+"_"+fileName, + Expires: 10 * 60, // URL valid for 10 minutes + Conditions: [ + ["starts-with", "$Content-Type", contentType], + ["content-length-range", 0, 31457280], // Max 30MB + ], + }); + } +// generateUploadUrl("tmp", "cat.png", "image/png").then(console.log); +export async function createDownloadUrl(key: string): Promise { + const url = await getSignedUrl( + S3, + new GetObjectCommand({ Bucket: "tmp", Key: key }), + { expiresIn: 600 } // 600 giây = 10 phút + ); + return url; +} \ No newline at end of file diff --git a/src/api/rpcclient.ts b/src/api/rpcclient.ts new file mode 100644 index 0000000..9d2757b --- /dev/null +++ b/src/api/rpcclient.ts @@ -0,0 +1,79 @@ +import { + proxyTinyRpc, + TinyRpcClientAdapter, + TinyRpcError, +} from "@hiogawa/tiny-rpc"; +import type { RpcRoutes } from "./rpc"; +import { Result } from "@hiogawa/utils"; +declare let __host__: string; +const endpoint = "/rpc"; +const url = import.meta.env.SSR ? "http://localhost" : ""; +const headers: Record = {}; // inject headers to demonstrate context +export const client = proxyTinyRpc({ + adapter: httpClientAdapter({ + url: url + endpoint, + pathsForGET: [], + }), +}); +const GET_PAYLOAD_PARAM = "payload"; +function httpClientAdapter(opts: { + url: string; + pathsForGET?: string[]; +}): TinyRpcClientAdapter { + return { + send: async (data) => { + const url = [opts.url, data.path].join("/"); + const payload = JSON.stringify(data.args); + const method = opts.pathsForGET?.includes(data.path) + ? "GET" + : "POST"; + let req: Request; + if (method === "GET") { + req = new Request( + url + + "?" + + new URLSearchParams({ [GET_PAYLOAD_PARAM]: payload }) + ); + } else { + req = new Request(url, { + method: "POST", + body: payload, + headers: { + "content-type": "application/json; charset=utf-8", + }, + credentials: "include", + }); + } + let res: Response; + if (import.meta.env.SSR) { + const { getContext } = await import("hono/context-storage"); + const c = getContext(); + Object.entries(c.req.header()).forEach(([k, v]) => { + req.headers.append(k, v); + }); + res = await c.get("fetch")(req); + } else { + res = await fetch(req); + } + if (!res.ok) { + // throw new Error(`HTTP error: ${res.status}`); + throw new Error( + JSON.stringify({ + status: res.status, + statusText: res.statusText, + data: { message: await res.text() }, + internal: true, + }) + ); + // throw TinyRpcError.deserialize(res.status); + } + const result: Result = JSON.parse( + await res.text() + ); + if (!result.ok) { + throw TinyRpcError.deserialize(result.value); + } + return result.value; + }, + }; +} diff --git a/src/client.ts b/src/client.ts new file mode 100644 index 0000000..35ba2ae --- /dev/null +++ b/src/client.ts @@ -0,0 +1,11 @@ +import { createApp } from './main'; +import 'uno.css'; +async function render() { + const { app, router } = createApp(); + router.isReady().then(() => { + app.mount('body', true) + }) +} +render().catch((error) => { + console.error('Error during app initialization:', error) +}) diff --git a/src/components/DashboardLayout.vue b/src/components/DashboardLayout.vue new file mode 100644 index 0000000..19258df --- /dev/null +++ b/src/components/DashboardLayout.vue @@ -0,0 +1,59 @@ + + diff --git a/src/components/RootLayout.vue b/src/components/RootLayout.vue new file mode 100644 index 0000000..01a0b42 --- /dev/null +++ b/src/components/RootLayout.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/components/icons/Add.vue b/src/components/icons/Add.vue new file mode 100644 index 0000000..811011d --- /dev/null +++ b/src/components/icons/Add.vue @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/src/components/icons/AddFilled.vue b/src/components/icons/AddFilled.vue new file mode 100644 index 0000000..d7b3c5b --- /dev/null +++ b/src/components/icons/AddFilled.vue @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/src/components/icons/Bell.vue b/src/components/icons/Bell.vue new file mode 100644 index 0000000..1c1623a --- /dev/null +++ b/src/components/icons/Bell.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/components/icons/BellFilled.vue b/src/components/icons/BellFilled.vue new file mode 100644 index 0000000..ed02e02 --- /dev/null +++ b/src/components/icons/BellFilled.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/components/icons/Home.vue b/src/components/icons/Home.vue new file mode 100644 index 0000000..37eee92 --- /dev/null +++ b/src/components/icons/Home.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/components/icons/HomeFilled.vue b/src/components/icons/HomeFilled.vue new file mode 100644 index 0000000..48c4b57 --- /dev/null +++ b/src/components/icons/HomeFilled.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/components/icons/Layout.vue b/src/components/icons/Layout.vue new file mode 100644 index 0000000..b66a45b --- /dev/null +++ b/src/components/icons/Layout.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/components/icons/LayoutFilled.vue b/src/components/icons/LayoutFilled.vue new file mode 100644 index 0000000..ee44361 --- /dev/null +++ b/src/components/icons/LayoutFilled.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/components/icons/TestIcon.vue b/src/components/icons/TestIcon.vue new file mode 100644 index 0000000..72f775b --- /dev/null +++ b/src/components/icons/TestIcon.vue @@ -0,0 +1,7 @@ + diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts new file mode 100644 index 0000000..8c80a1b --- /dev/null +++ b/src/components/icons/index.ts @@ -0,0 +1,46 @@ +import { createStaticVNode } from "vue"; + +export const Home = createStaticVNode(``, 1); +export const HomeFilled = createStaticVNode(``, 1); +export const Dashboard = createStaticVNode(``, 1); +export const DashboardFilled = createStaticVNode(``, 1); +export const Add = createStaticVNode(``, 1); +export const AddFilled = createStaticVNode(``, 1); +export const Bell = createStaticVNode(``, 1); +export const BellFilled = createStaticVNode(``, 1); +export const Search = createStaticVNode(``, 1); \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 97db3eb..629d6d3 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,18 +1,30 @@ import { Hono } from 'hono' -import { renderer } from './renderer' import { createApp } from './main'; import { renderToWebStream } from 'vue/server-renderer'; import { streamText } from 'hono/streaming'; import { renderSSRHead } from '@unhead/vue/server'; +import { buildBootstrapScript, getHrefFromManifest } from './lib/manifest'; +import { contextStorage } from 'hono/context-storage'; +import { cors } from "hono/cors"; +import { jwtRpc, rpcServer } from './api/rpc'; +import isMobile from 'is-mobile'; const app = new Hono() // app.use(renderer) -// app.get('/', (c) => { -// return c.text('Hello World!') -// // return c.render(

Hello!

) -// }) +app.use(cors(), async (c, next) => { + c.set("fetch", app.request.bind(app)); + const ua = c.req.header("User-Agent") + if (!ua) { + return c.json({ error: "User-Agent header is missing" }, 400); + }; + c.set("isMobile", isMobile({ ua })); + await next(); +}, contextStorage(), rpcServer); +app.get("/.well-known/*", (c) => { + return c.json({ ok: true }); +}); app.get("*", async (c) => { const url = new URL(c.req.url); const { app, router, head } = createApp(); @@ -26,27 +38,28 @@ app.get("*", async (c) => { await stream.write(""); await stream.write(""); await renderSSRHead(head).then((headString) => stream.write(headString.headTags.replace(/\n/g, ""))); - await stream.write(``); - await stream.write(""); - await stream.pipe(appStream); - let json = htmlEscape(JSON.stringify(JSON.stringify(ctx))); - await stream.write(``); - await stream.write(""); + await stream.write(``); + await stream.write(''); + await stream.write(buildBootstrapScript()); + await stream.write(""); + await stream.pipe(appStream); + let json = htmlEscape(JSON.stringify(JSON.stringify(ctx))); + await stream.write(``); + await stream.write(""); }); // return c.body(renderToWebStream(app, {})); }) const ESCAPE_LOOKUP: { [match: string]: string } = { - "&": "\\u0026", - ">": "\\u003e", - "<": "\\u003c", - "\u2028": "\\u2028", - "\u2029": "\\u2029", + "&": "\\u0026", + ">": "\\u003e", + "<": "\\u003c", + "\u2028": "\\u2028", + "\u2029": "\\u2029", }; const ESCAPE_REGEX = /[&><\u2028\u2029]/g; function htmlEscape(str: string): string { - return str.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]); + return str.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]); } export default app diff --git a/src/lib/constants.ts b/src/lib/constants.ts new file mode 100644 index 0000000..8177e7f --- /dev/null +++ b/src/lib/constants.ts @@ -0,0 +1,3 @@ +export const requestCtxKey = Symbol("requestCtx"); +export const isRouteLoading = Symbol("isRouteLoading"); +export const routerKey = Symbol("routerKey"); diff --git a/src/lib/manifest.ts b/src/lib/manifest.ts new file mode 100644 index 0000000..a7439cb --- /dev/null +++ b/src/lib/manifest.ts @@ -0,0 +1,94 @@ +import type { Manifest } from "vite"; +export interface GetHrefOptions { + href: string; + manifest?: Manifest; + prod?: boolean; + baseUrl?: string; +} +// Use Vite's import.meta.glob to dynamically search for manifest.json +export const loadManifest = (): Manifest | undefined => { + // Check if manifest content is provided via plugin + const manifestContent = import.meta.env.VITE_MANIFEST_CONTENT as + | string + | undefined; + if (manifestContent) { + try { + return JSON.parse(manifestContent) as Manifest; + } catch { + // Fall through to auto-detection if parsing fails + } + } + + // Placeholder replaced by inject-manifest plugin during SSR build + const MANIFEST = "__VITE_MANIFEST_CONTENT__" as unknown as Record< + string, + { default: Manifest } + >; + + let manifestData = {}; + for (const [, manifestFile] of Object.entries(MANIFEST)) { + manifestData = { ...manifestData, ...manifestFile.default }; + } + // Return merged values + return manifestData; +}; +const ensureTrailingSlash = (path: string) => { + return path.endsWith("/") ? path : path + "/"; +}; +export const getHrefFromManifest = ({ + href, + manifest, + prod, + baseUrl = "/", +}: GetHrefOptions) => { + if (!href) return undefined; + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain, @typescript-eslint/no-unnecessary-condition + if (prod ?? (import.meta.env && import.meta.env.PROD)) { + manifest ??= loadManifest(); + + if (manifest) { + const assetInManifest = manifest[href.replace(/^\//, "")]; + return href.startsWith("/") + ? `${ensureTrailingSlash(baseUrl)}${assetInManifest.file}` + : assetInManifest.file; + } + return undefined; + } else { + return href; + } +}; +export function buildBootstrapScript() { + let script = ""; + let styles = ""; + let manifest: Manifest = import.meta.env.PROD + ? loadManifest() ?? {} + : { + "0": { + file: "@vite/client", + isEntry: true, + css: [], + imports: [], + dynamicImports: [], + assets: [], + }, + "1": { + file: "src/client.ts", + isEntry: true, + css: [], + }, + }; + Object.values(manifest).forEach((chunk) => { + if (chunk.isEntry) { + script += ``; + (chunk.css || []).forEach((cssFile) => { + styles += ``; + }); + } else { + script += ``; + (chunk.css || []).forEach((cssFile) => { + styles += ``; + }); + } + }); + return styles + script; +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts index c0e4458..6e987f9 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -4,4 +4,47 @@ import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); +} +export function debounce any>(func: Func, wait: number): Func { + let timeout: ReturnType | null; + return function(this: any, ...args: any[]) { + if (timeout) clearTimeout(timeout); + timeout = setTimeout(() => { + func.apply(this, args); + }, wait); + } as Func; +} +type AspectInfo = { + width: number; + height: number; + ratio: string; // ví dụ: "16:9" + float: number; // ví dụ: 1.777... +}; + +function gcd(a: number, b: number): number { + return b === 0 ? a : gcd(b, a % b); +} + +export function getImageAspectRatio(url: string): Promise { + return new Promise((resolve, reject) => { + const img = new Image(); + + img.onload = () => { + const w = img.naturalWidth; + const h = img.naturalHeight; + + const g = gcd(w, h); + + resolve({ + width: w, + height: h, + ratio: `${w / g}:${h / g}`, + float: w / h + }); + }; + + img.onerror = () => reject(new Error("Cannot load image")); + + img.src = url; + }); } \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 78dfc04..472e8bf 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,13 +5,42 @@ import { RouterView } from 'vue-router'; import { withErrorBoundary } from './lib/hoc/withErrorBoundary'; import { vueSWR } from './lib/swr/use-swrv'; import router from './routes'; -// import { appComponents } from './components' +import PrimeVue from 'primevue/config'; +import Aura from '@primeuix/themes/aura'; +import { createPinia } from "pinia"; +import { useAuthStore } from './stores/auth'; + +const pinia = createPinia(); + export function createApp() { + const app = createSSRApp(withErrorBoundary(RouterView)); + const head = import.meta.env.SSR ? SSRHead() : CSRHead(); - const app = createSSRApp(withErrorBoundary(RouterView)) - const head = import.meta.env.SSR ? SSRHead() : CSRHead() - app.use(head) - app.use(vueSWR({revalidateOnFocus: false})) - app.use(router) - return { app, router, head } + app.use(head); + app.use(PrimeVue, { + theme: { + preset: Aura, + options: { + darkModeSelector: '.my-app-dark', + } + } + }); + app.directive('no-hydrate', { + created(el) { + el.__v_skip = true; + } + }); + app.use(vueSWR({revalidateOnFocus: false})); + app.use(router); + app.use(pinia); + + // Initialize auth store on client side + if (!import.meta.env.SSR) { + router.isReady().then(() => { + const auth = useAuthStore(); + auth.init(); + }); + } + + return { app, router, head }; } \ No newline at end of file diff --git a/src/renderer.tsx b/src/renderer.tsx deleted file mode 100644 index ddcc21f..0000000 --- a/src/renderer.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { jsxRenderer } from 'hono/jsx-renderer' -import { Link, ViteClient } from 'vite-ssr-components/hono' - -export const renderer = jsxRenderer(({ children }) => { - return ( - - - - - - {children} - - ) -}) diff --git a/src/routes/add/Add.vue b/src/routes/add/Add.vue new file mode 100644 index 0000000..9a96ec9 --- /dev/null +++ b/src/routes/add/Add.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/routes/auth/forgot.vue b/src/routes/auth/forgot.vue new file mode 100644 index 0000000..dc559dd --- /dev/null +++ b/src/routes/auth/forgot.vue @@ -0,0 +1,56 @@ + + + \ No newline at end of file diff --git a/src/routes/auth/layout.vue b/src/routes/auth/layout.vue new file mode 100644 index 0000000..e506efe --- /dev/null +++ b/src/routes/auth/layout.vue @@ -0,0 +1,35 @@ + + \ No newline at end of file diff --git a/src/routes/auth/login.vue b/src/routes/auth/login.vue new file mode 100644 index 0000000..926bc5b --- /dev/null +++ b/src/routes/auth/login.vue @@ -0,0 +1,114 @@ + + + \ No newline at end of file diff --git a/src/routes/auth/signup.vue b/src/routes/auth/signup.vue new file mode 100644 index 0000000..849e69e --- /dev/null +++ b/src/routes/auth/signup.vue @@ -0,0 +1,67 @@ + + + \ No newline at end of file diff --git a/src/routes/home/Home.vue b/src/routes/home/Home.vue index 1fd4cb8..d5a8417 100644 --- a/src/routes/home/Home.vue +++ b/src/routes/home/Home.vue @@ -1,7 +1,231 @@ - - \ No newline at end of file + diff --git a/src/routes/index.ts b/src/routes/index.ts index 5167434..21ff529 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -5,15 +5,78 @@ import { createWebHistory, type RouteRecordRaw, } from "vue-router"; +import { useAuthStore } from "@/stores/auth"; type RouteData = RouteRecordRaw & { - meta?: ResolvableValue; + meta?: ResolvableValue & { requiresAuth?: boolean }; children?: RouteData[]; }; const routes: RouteData[] = [ { path: "/", - component: () => import("./home/Home.vue") + component: () => import("@/components/RootLayout.vue"), + children: [ + { + path: "", + component: () => import("./home/Home.vue"), + beforeEnter: (to, from, next) => { + const auth = useAuthStore(); + if (auth.user) { + next({ name: "overview" }); + } else { + next(); + } + }, + }, + { + path: "", + component: () => import("./auth/layout.vue"), + children: [ + { + path: "login", + name: "login", + component: () => import("./auth/login.vue"), + }, + { + path: "signup", + name: "signup", + component: () => import("./auth/signup.vue"), + }, + { + path: "forgot", + name: "forgot", + component: () => import("./auth/forgot.vue"), + }, + ], + }, + { + path: "", + component: () => import("@/components/DashboardLayout.vue"), + meta: { requiresAuth: true }, + children: [ + { + path: "", + name: "overview", + component: () => import("./add/Add.vue"), + }, + { + path: "video", + name: "video", + component: () => import("./add/Add.vue"), + }, + { + path: "add", + name: "add", + component: () => import("./add/Add.vue"), + }, + { + path: "notification", + name: "notification", + component: () => import("./add/Add.vue"), + }, + ], + } + ], }, ]; const router = createRouter({ @@ -22,4 +85,18 @@ const router = createRouter({ : createWebHistory(), // client routes, }); + +router.beforeEach((to, from, next) => { + const auth = useAuthStore(); + if (to.matched.some((record) => record.meta.requiresAuth)) { + if (!auth.user) { + next({ name: "login" }); + } else { + next(); + } + } else { + next(); + } +}); + export default router; diff --git a/src/stores/auth.ts b/src/stores/auth.ts new file mode 100644 index 0000000..6cb9684 --- /dev/null +++ b/src/stores/auth.ts @@ -0,0 +1,88 @@ +import { defineStore } from 'pinia'; +import { useRouter } from 'vue-router'; +import { client } from '@/api/rpcclient'; +import { ref } from 'vue'; + +interface User { + id: string; + username: string; + email: string; + name: string; +} + +export const useAuthStore = defineStore('auth', () => { + const user = ref(null); + const router = useRouter(); + const loading = ref(false); + const error = ref(null); + const csrfToken = ref(null); + const initialized = ref(false); + + // Check auth status on init (reads from cookie) + async function init() { + if (initialized.value) return; + + try { + const response = await client.checkAuth(); + if (response.authenticated && response.user) { + user.value = response.user; + // Get CSRF token if authenticated + try { + const csrfResponse = await client.getCSRFToken(); + csrfToken.value = csrfResponse.csrfToken; + } catch (e) { + // CSRF token might not be available yet + } + } + } catch (e) { + // Not authenticated, that's fine + } finally { + initialized.value = true; + } + } + + async function login(username: string, password: string) { + loading.value = true; + error.value = null; + try { + const response = await client.login(username, password); + user.value = response.user; + csrfToken.value = response.csrfToken; + router.push('/'); + } catch (e: any) { + error.value = e.message || 'Login failed'; + throw e; + } finally { + loading.value = false; + } + } + + async function register(username: string, email: string, password: string) { + loading.value = true; + error.value = null; + try { + const response = await client.register({ username, email, password }); + user.value = response.user; + csrfToken.value = response.csrfToken; + router.push('/'); + } catch (e: any) { + error.value = e.message || 'Registration failed'; + throw e; + } finally { + loading.value = false; + } + } + + async function logout() { + try { + await client.logout(); + } catch (e) { + // Ignore errors on logout + } + user.value = null; + csrfToken.value = null; + router.push('/'); + } + + return { user, loading, error, csrfToken, initialized, init, login, register, logout }; +}); diff --git a/src/style.css b/src/style.css deleted file mode 100644 index 50969c8..0000000 --- a/src/style.css +++ /dev/null @@ -1,3 +0,0 @@ -h1 { - font-family: Arial, Helvetica, sans-serif; -} diff --git a/src/worker/html.ts b/src/worker/html.ts new file mode 100644 index 0000000..3283b89 --- /dev/null +++ b/src/worker/html.ts @@ -0,0 +1,56 @@ +/** + * @module + * html Helper for Hono. + */ + +import { escapeToBuffer, raw, resolveCallbackSync, stringBufferToString } from 'hono/utils/html' +import type { HtmlEscaped, HtmlEscapedString, StringBufferWithCallbacks } from 'hono/utils/html' + + +export const html = ( + strings: TemplateStringsArray, + ...values: unknown[] +): HtmlEscapedString | Promise => { + const buffer: StringBufferWithCallbacks = [''] as StringBufferWithCallbacks + + for (let i = 0, len = strings.length - 1; i < len; i++) { + buffer[0] += strings[i] + + const children = Array.isArray(values[i]) + ? (values[i] as Array).flat(Infinity) + : [values[i]] + for (let i = 0, len = children.length; i < len; i++) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const child = children[i] as any + if (typeof child === 'string') { + escapeToBuffer(child, buffer) + } else if (typeof child === 'number') { + ;(buffer[0] as string) += child + } else if (typeof child === 'boolean' || child === null || child === undefined) { + continue + } else if (typeof child === 'object' && (child as HtmlEscaped).isEscaped) { + if ((child as HtmlEscapedString).callbacks) { + buffer.unshift('', child) + } else { + const tmp = child.toString() + if (tmp instanceof Promise) { + buffer.unshift('', tmp) + } else { + buffer[0] += tmp + } + } + } else if (child instanceof Promise) { + buffer.unshift('', child) + } else { + escapeToBuffer(child.toString(), buffer) + } + } + } + buffer[0] += strings.at(-1) as string + + return buffer.length === 1 + ? 'callbacks' in buffer + ? raw(resolveCallbackSync(raw(buffer[0], buffer.callbacks))) + : raw(buffer[0]) + : stringBufferToString(buffer, buffer.callbacks) +} diff --git a/src/worker/ssrLayout.ts b/src/worker/ssrLayout.ts new file mode 100644 index 0000000..647447a --- /dev/null +++ b/src/worker/ssrLayout.ts @@ -0,0 +1,65 @@ +import { createContext, jsx, Suspense } from "hono/jsx"; +import { renderToReadableStream, StreamingContext } from "hono/jsx/streaming"; +import { HtmlEscapedCallback, HtmlEscapedString, raw } from "hono/utils/html"; +// import { jsxs } from "hono/jsx-renderer"; +import { Context } from "hono"; +import type { + FC, + Context as JSXContext, + JSXNode +} from "hono/jsx"; +import { jsxTemplate } from "hono/jsx/jsx-runtime"; +export const RequestContext: JSXContext | null> = + createContext(null); +export function renderSSRLayout(c: Context, appStream: ReadableStream) { + const body = jsxTemplate`${raw("")}${_c( + RequestContext.Provider, + { value: c }, + // currentLayout as any + _c( + "html", + { lang: "en" }, + _c( + "head", + null, + raw(''), + raw( + '' + ), + raw(''), + raw(``) + ), + _c( + "body", + { + class: + "font-sans bg-[#f9fafd] text-gray-800 antialiased flex flex-col", + }, + _c( + StreamingContext, + { value: { scriptNonce: "random-nonce-value" } }, + _c( + Suspense, + { fallback: _c("div", { class: "loading" }, raw("Loading...")) }, + raw(appStream.getReader()) + ) + ), + _c("script", { + dangerouslySetInnerHTML: { + __html: `window.__SSR_STATE__ = ${JSON.stringify( + JSON.stringify(c.get("ssrContext") || {}) + )};`, + }, + }) + ) + ) + )}`; + return renderToReadableStream(body); +} +function _c( + tag: string | FC, + props: any, + ...children: (JSXNode | HtmlEscapedCallback | HtmlEscapedString | null)[] +): JSXNode { + return jsx(tag, props, ...(children as any)); +} diff --git a/ssrPlugin.ts b/ssrPlugin.ts new file mode 100644 index 0000000..265e67d --- /dev/null +++ b/ssrPlugin.ts @@ -0,0 +1,142 @@ +import { readFileSync } from "node:fs"; +import path from "node:path"; +import type { Plugin } from "vite"; +export function createVirtualPlugin(name: string, load: Plugin["load"]) { + name = "virtual:" + name; + return { + name, + resolveId(source, _importer, _options) { + if (source === name || source.startsWith(`${name}?`)) { + return `\0${source}`; + } + return; + }, + load(id, options) { + if (id === `\0${name}` || id.startsWith(`\0${name}?`)) { + return (load as any).apply(this, [id, options]); + } + }, + } satisfies Plugin; +} +export function clientFirstBuild(): Plugin { + return { + name: "client-first-build", + config(config) { + config.builder ??= {}; + config.builder.buildApp = async (builder) => { + const clientEnvironment = builder.environments.client; + const workerEnvironments = Object.keys(builder.environments) + .filter((name) => name !== "client" && name !== "ssr") + .map((name) => builder.environments[name]); + // console.log('Client First Build Plugin: Starting builds...', workerEnvironments) + // Client build first + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (clientEnvironment) { + await builder.build(clientEnvironment); + } + + // Then worker builds + for (const workerEnv of workerEnvironments) { + await builder.build(workerEnv); + } + }; + }, + }; +} +export function injectManifest(): Plugin { + let clientOutDir = "dist/client"; + + return { + name: "inject-manifest", + config(config) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const viteConfig = config as any; + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + clientOutDir = + viteConfig.environments?.client?.build?.outDir ?? "dist/client"; + }, + async transform(code, id, options) { + // Only transform in SSR environment (non-client) + if (!options?.ssr) { + return; + } + + // Only transform files that contain the placeholder + if (!code.includes("__VITE_MANIFEST_CONTENT__")) { + return; + } + + // Read manifest from client build output + const manifestPath = path.resolve( + process.cwd(), + clientOutDir, + ".vite/manifest.json" + ); + let manifestContent: string | undefined; + try { + manifestContent = await this.fs + .readFile(manifestPath) + .then((data) => data.toString()); + } catch { + // Manifest not found + } + + if (!manifestContent) return; + + // Replace placeholder string with actual manifest data + // Format: { "__manifest__": { default: } } to match the Object.entries loop + const newCode = code.replace( + /"__VITE_MANIFEST_CONTENT__"/g, + `{ "__manifest__": { default: ${manifestContent} } }` + ); + + if (newCode !== code) { + return { code: newCode, map: null }; + } + }, + }; +} +export default function ssrPlugin(): Plugin[] { + // const { hotReload: hotReloadOption = true, entry: entryOption = {} } = options + + const plugins: Plugin[] = []; + + plugins.push(clientFirstBuild()); + plugins.push({ + name: "ssr-auto-entry", + config(config) { + config.define = config.define || {}; + }, + async configResolved(config) { + const viteConfig = config as any; + + if (!viteConfig.environments) { + viteConfig.environments = {}; + } + if (!viteConfig.environments.client) { + viteConfig.environments.client = {}; + } + if (!viteConfig.environments.client.build) { + viteConfig.environments.client.build = {}; + } + + const clientBuild = viteConfig.environments.client.build; + clientBuild.manifest = true; + clientBuild.rollupOptions = clientBuild.rollupOptions || {}; + clientBuild.rollupOptions.input = "src/client.ts"; + if (!viteConfig.environments.ssr) { + const manifestPath = path.join(clientBuild.outDir as string, '.vite/manifest.json') + try { + const resolvedPath = path.resolve(process.cwd(), manifestPath) + const manifestContent = readFileSync(resolvedPath, 'utf-8') + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + config.define['import.meta.env.VITE_MANIFEST_CONTENT'] = JSON.stringify(manifestContent) + } catch {} + } + }, + }); + plugins.push(injectManifest()); + + return plugins; +} diff --git a/tsconfig.json b/tsconfig.json index e39c806..f3df554 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,10 @@ ], "types": ["vite/client"], "jsx": "preserve", - "jsxImportSource": "vue" + "jsxImportSource": "vue", + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } }, } \ No newline at end of file diff --git a/uno.config.ts b/uno.config.ts index c8a1158..4a49946 100644 --- a/uno.config.ts +++ b/uno.config.ts @@ -1,18 +1,12 @@ -// unocss.config.ts -import { - defineConfig, - presetWind4, - presetIcons, - transformerVariantGroup, - transformerCompileClass, -} from "unocss"; +import { defineConfig, presetAttributify, presetTypography, presetWind4, transformerCompileClass, transformerVariantGroup } from 'unocss' +import { presetBootstrapBtn } from "./bootstrap_btn"; export default defineConfig({ presets: [ presetWind4() as any, - presetIcons({ - extraProperties: { display: "block" }, - }), + presetTypography(), + presetBootstrapBtn(), + presetAttributify(), ], // By default, `.ts` and `.js` files are NOT extracted. // If you want to extract them, use the following configuration. diff --git a/vite.config.ts b/vite.config.ts index a500bae..aab9251 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,14 +1,30 @@ -import { cloudflare } from '@cloudflare/vite-plugin' -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import vueJsx from '@vitejs/plugin-vue-jsx' +import { cloudflare } from "@cloudflare/vite-plugin"; +import { defineConfig, Manifest, Plugin } from "vite"; +import vue from "@vitejs/plugin-vue"; +import vueJsx from "@vitejs/plugin-vue-jsx"; import unocss from "unocss/vite"; import path from "node:path"; -export default defineConfig({ - plugins: [unocss(), cloudflare(), vue(), vueJsx()], - resolve: { - alias: { - "@": path.resolve(__dirname, "./src"), +import ssrPlugin from "./ssrPlugin"; +import Components from 'unplugin-vue-components/vite'; +import {PrimeVueResolver} from '@primevue/auto-import-resolver'; +export default defineConfig((env) => { + return { + plugins: [ + unocss(), + vue(), + vueJsx(), + ssrPlugin(), + cloudflare(), + Components({ + resolvers: [ + PrimeVueResolver() + ] + }), + ], + resolve: { + alias: { + "@": path.resolve(__dirname, "./src"), + }, }, - } -}) + }; +}); diff --git a/wrangler.jsonc b/wrangler.jsonc index 4e303b9..39fdfba 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -2,5 +2,8 @@ "$schema": "node_modules/wrangler/config-schema.json", "name": "holistream", "compatibility_date": "2025-08-03", - "main": "./src/index.tsx" + "main": "./src/index.tsx", + "compatibility_flags": [ + "nodejs_compat" + ] } \ No newline at end of file