From e2e9b125a3a6dcecef0604d5c2367c8de1a62d8b Mon Sep 17 00:00:00 2001 From: LiRuoChen <571244399@qq.com> Date: Thu, 27 Aug 2026 13:54:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=B8=AA=E6=A1=A5?= =?UTF-8?q?=E6=8E=A5=E6=9C=8D=E5=8A=A1=EF=BC=8C=E7=9B=B4=E6=8E=A5=E5=B0=86?= =?UTF-8?q?ai=E7=94=A8=E9=87=8F=E7=AD=89=E7=BA=A7=E5=88=B0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + ExtendWebAITokenChart.js | 858 +-- __old_extend.js | Bin 0 -> 76722 bytes __review_diff.txt | Bin 0 -> 84078 bytes .../dashboard-full-screenshot.png | Bin 0 -> 26382 bytes .../dashboard-screenshot.png | Bin 0 -> 26382 bytes ai-usage-mysql-bridge/dashboard-sidebar.png | Bin 0 -> 8069 bytes ai-usage-mysql-bridge/dashboard.html | 536 ++ .../node_modules/.package-lock.json | 128 + .../node_modules/@types/node/LICENSE | 21 + .../node_modules/@types/node/README.md | 15 + .../node_modules/@types/node/assert.d.ts | 1077 ++++ .../@types/node/assert/strict.d.ts | 68 + .../node_modules/@types/node/async_hooks.d.ts | 711 +++ .../@types/node/buffer.buffer.d.ts | 466 ++ .../node_modules/@types/node/buffer.d.ts | 1799 +++++++ .../@types/node/child_process.d.ts | 1361 +++++ .../node_modules/@types/node/cluster.d.ts | 432 ++ .../node_modules/@types/node/console.d.ts | 93 + .../node_modules/@types/node/constants.d.ts | 14 + .../node_modules/@types/node/crypto.d.ts | 3954 ++++++++++++++ .../node_modules/@types/node/dgram.d.ts | 537 ++ .../@types/node/diagnostics_channel.d.ts | 794 +++ .../node_modules/@types/node/dns.d.ts | 876 +++ .../@types/node/dns/promises.d.ts | 497 ++ .../node_modules/@types/node/domain.d.ts | 150 + .../node_modules/@types/node/events.d.ts | 1008 ++++ .../node_modules/@types/node/ffi.d.ts | 486 ++ .../node_modules/@types/node/fs.d.ts | 4793 +++++++++++++++++ .../node_modules/@types/node/fs/promises.d.ts | 1481 +++++ .../node_modules/@types/node/globals.d.ts | 150 + .../@types/node/globals.typedarray.d.ts | 101 + .../node_modules/@types/node/http.d.ts | 2218 ++++++++ .../node_modules/@types/node/http2.d.ts | 2497 +++++++++ .../node_modules/@types/node/https.d.ts | 400 ++ .../node_modules/@types/node/index.d.ts | 115 + .../node_modules/@types/node/inspector.d.ts | 264 + .../@types/node/inspector.generated.d.ts | 4406 +++++++++++++++ .../@types/node/inspector/promises.d.ts | 35 + .../node_modules/@types/node/module.d.ts | 726 +++ .../node_modules/@types/node/net.d.ts | 970 ++++ .../node_modules/@types/node/os.d.ts | 498 ++ .../node_modules/@types/node/package.json | 155 + .../node_modules/@types/node/path.d.ts | 178 + .../node_modules/@types/node/path/posix.d.ts | 8 + .../node_modules/@types/node/path/win32.d.ts | 8 + .../node_modules/@types/node/perf_hooks.d.ts | 605 +++ .../node_modules/@types/node/process.d.ts | 2268 ++++++++ .../node_modules/@types/node/punycode.d.ts | 89 + .../node_modules/@types/node/querystring.d.ts | 139 + .../node_modules/@types/node/quic.d.ts | 2125 ++++++++ .../node_modules/@types/node/readline.d.ts | 508 ++ .../@types/node/readline/promises.d.ts | 158 + .../node_modules/@types/node/repl.d.ts | 420 ++ .../node_modules/@types/node/sea.d.ts | 47 + .../node_modules/@types/node/sqlite.d.ts | 1140 ++++ .../node_modules/@types/node/stream.d.ts | 1806 +++++++ .../@types/node/stream/consumers.d.ts | 114 + .../node_modules/@types/node/stream/iter.d.ts | 452 ++ .../@types/node/stream/promises.d.ts | 211 + .../node_modules/@types/node/stream/web.d.ts | 300 ++ .../@types/node/string_decoder.d.ts | 27 + .../node_modules/@types/node/test.d.ts | 2486 +++++++++ .../@types/node/test/reporters.d.ts | 59 + .../node_modules/@types/node/timers.d.ts | 149 + .../@types/node/timers/promises.d.ts | 93 + .../node_modules/@types/node/tls.d.ts | 1193 ++++ .../@types/node/trace_events.d.ts | 103 + .../@types/node/ts5.6/buffer.buffer.d.ts | 462 ++ .../ts5.6/compatibility/float16array.d.ts | 71 + .../@types/node/ts5.6/globals.typedarray.d.ts | 36 + .../node_modules/@types/node/ts5.6/index.d.ts | 117 + .../ts5.7/compatibility/float16array.d.ts | 72 + .../node_modules/@types/node/ts5.7/index.d.ts | 117 + .../node_modules/@types/node/tty.d.ts | 225 + .../node_modules/@types/node/url.d.ts | 556 ++ .../node_modules/@types/node/util.d.ts | 1677 ++++++ .../node_modules/@types/node/util/types.d.ts | 558 ++ .../node_modules/@types/node/v8.d.ts | 1059 ++++ .../node_modules/@types/node/vm.d.ts | 1136 ++++ .../node_modules/@types/node/wasi.d.ts | 131 + .../node/web-globals/abortcontroller.d.ts | 59 + .../@types/node/web-globals/blob.d.ts | 23 + .../@types/node/web-globals/console.d.ts | 9 + .../@types/node/web-globals/crypto.d.ts | 39 + .../@types/node/web-globals/domexception.d.ts | 83 + .../@types/node/web-globals/encoding.d.ts | 11 + .../@types/node/web-globals/events.d.ts | 106 + .../@types/node/web-globals/fetch.d.ts | 69 + .../@types/node/web-globals/importmeta.d.ts | 13 + .../@types/node/web-globals/messaging.d.ts | 23 + .../@types/node/web-globals/navigator.d.ts | 25 + .../@types/node/web-globals/performance.d.ts | 45 + .../@types/node/web-globals/storage.d.ts | 24 + .../@types/node/web-globals/streams.d.ts | 115 + .../@types/node/web-globals/timers.d.ts | 44 + .../@types/node/web-globals/url.d.ts | 24 + .../@types/node/worker_threads.d.ts | 669 +++ .../node_modules/@types/node/zlib.d.ts | 589 ++ .../node_modules/@types/node/zlib/iter.d.ts | 131 + .../node_modules/aws-ssl-profiles/LICENSE | 19 + .../node_modules/aws-ssl-profiles/README.md | 146 + .../aws-ssl-profiles/lib/@types/profiles.d.ts | 4 + .../aws-ssl-profiles/lib/@types/profiles.js | 2 + .../aws-ssl-profiles/lib/index.d.ts | 8 + .../aws-ssl-profiles/lib/index.js | 13 + .../lib/profiles/ca/defaults.d.ts | 9 + .../lib/profiles/ca/defaults.js | 2888 ++++++++++ .../lib/profiles/ca/proxies.d.ts | 8 + .../lib/profiles/ca/proxies.js | 111 + .../aws-ssl-profiles/package.json | 52 + .../generate-function/.travis.yml | 3 + .../node_modules/generate-function/LICENSE | 21 + .../node_modules/generate-function/README.md | 89 + .../node_modules/generate-function/example.js | 27 + .../node_modules/generate-function/index.js | 181 + .../generate-function/package.json | 32 + .../node_modules/generate-function/test.js | 49 + .../node_modules/iconv-lite/LICENSE | 21 + .../node_modules/iconv-lite/README.md | 138 + .../iconv-lite/encodings/dbcs-codec.js | 532 ++ .../iconv-lite/encodings/dbcs-data.js | 185 + .../iconv-lite/encodings/index.js | 23 + .../iconv-lite/encodings/internal.js | 218 + .../iconv-lite/encodings/sbcs-codec.js | 75 + .../encodings/sbcs-data-generated.js | 451 ++ .../iconv-lite/encodings/sbcs-data.js | 180 + .../encodings/tables/big5-added.json | 122 + .../iconv-lite/encodings/tables/cp936.json | 264 + .../iconv-lite/encodings/tables/cp949.json | 273 + .../iconv-lite/encodings/tables/cp950.json | 177 + .../iconv-lite/encodings/tables/eucjp.json | 182 + .../encodings/tables/gb18030-ranges.json | 1 + .../encodings/tables/gbk-added.json | 56 + .../iconv-lite/encodings/tables/shiftjis.json | 125 + .../iconv-lite/encodings/utf16.js | 187 + .../iconv-lite/encodings/utf32.js | 314 ++ .../node_modules/iconv-lite/encodings/utf7.js | 283 + .../iconv-lite/lib/bom-handling.js | 48 + .../iconv-lite/lib/helpers/merge-exports.js | 13 + .../node_modules/iconv-lite/lib/index.d.ts | 129 + .../node_modules/iconv-lite/lib/index.js | 182 + .../node_modules/iconv-lite/lib/streams.js | 105 + .../node_modules/iconv-lite/package.json | 70 + .../iconv-lite/types/encodings.d.ts | 425 ++ .../node_modules/is-property/.npmignore | 17 + .../node_modules/is-property/LICENSE | 22 + .../node_modules/is-property/README.md | 28 + .../node_modules/is-property/is-property.js | 5 + .../node_modules/is-property/package.json | 36 + .../node_modules/long/LICENSE | 202 + .../node_modules/long/README.md | 286 + .../node_modules/long/index.d.ts | 2 + .../node_modules/long/index.js | 1581 ++++++ .../node_modules/long/package.json | 58 + .../node_modules/long/types.d.ts | 474 ++ .../node_modules/long/umd/index.d.ts | 3 + .../node_modules/long/umd/index.js | 1622 ++++++ .../node_modules/long/umd/package.json | 3 + .../node_modules/long/umd/types.d.ts | 474 ++ .../node_modules/lru.min/LICENSE | 21 + .../node_modules/lru.min/README.md | 392 ++ .../node_modules/lru.min/browser/lru.min.js | 1 + .../node_modules/lru.min/lib/index.d.ts | 38 + .../node_modules/lru.min/lib/index.js | 248 + .../node_modules/lru.min/lib/index.mjs | 227 + .../node_modules/lru.min/package.json | 87 + .../node_modules/mysql2/License | 19 + .../node_modules/mysql2/README.md | 114 + .../node_modules/mysql2/index.d.ts | 1 + .../node_modules/mysql2/index.js | 82 + .../node_modules/mysql2/lib/auth_41.js | 95 + .../lib/auth_plugins/caching_sha2_password.js | 115 + .../lib/auth_plugins/caching_sha2_password.md | 18 + .../mysql2/lib/auth_plugins/index.js | 8 + .../lib/auth_plugins/mysql_clear_password.js | 17 + .../lib/auth_plugins/mysql_native_password.js | 34 + .../lib/auth_plugins/sha256_password.js | 74 + .../mysql2/lib/base/connection.js | 1149 ++++ .../node_modules/mysql2/lib/base/pool.js | 368 ++ .../mysql2/lib/commands/auth_switch.js | 151 + .../mysql2/lib/commands/binlog_dump.js | 110 + .../mysql2/lib/commands/change_user.js | 68 + .../mysql2/lib/commands/client_handshake.js | 410 ++ .../mysql2/lib/commands/close_statement.js | 18 + .../mysql2/lib/commands/command.js | 54 + .../mysql2/lib/commands/execute.js | 132 + .../node_modules/mysql2/lib/commands/index.js | 29 + .../node_modules/mysql2/lib/commands/ping.js | 36 + .../mysql2/lib/commands/prepare.js | 151 + .../node_modules/mysql2/lib/commands/query.js | 370 ++ .../node_modules/mysql2/lib/commands/quit.js | 29 + .../mysql2/lib/commands/register_slave.js | 27 + .../mysql2/lib/commands/reset_connection.js | 29 + .../mysql2/lib/commands/server_handshake.js | 205 + .../mysql2/lib/compressed_protocol.js | 153 + .../node_modules/mysql2/lib/connection.js | 12 + .../mysql2/lib/connection_config.js | 300 ++ .../mysql2/lib/constants/charset_encodings.js | 341 ++ .../mysql2/lib/constants/charsets.js | 317 ++ .../mysql2/lib/constants/client.js | 39 + .../mysql2/lib/constants/commands.js | 37 + .../mysql2/lib/constants/cursor.js | 9 + .../mysql2/lib/constants/encoding_charset.js | 50 + .../mysql2/lib/constants/errors.js | 3973 ++++++++++++++ .../mysql2/lib/constants/field_flags.js | 20 + .../mysql2/lib/constants/mariadb_client.js | 19 + .../mysql2/lib/constants/server_status.js | 44 + .../mysql2/lib/constants/session_track.js | 11 + .../mysql2/lib/constants/ssl_profiles.js | 11 + .../mysql2/lib/constants/types.js | 65 + .../mysql2/lib/create_connection.js | 10 + .../node_modules/mysql2/lib/create_pool.js | 10 + .../mysql2/lib/create_pool_cluster.js | 9 + .../node_modules/mysql2/lib/helpers.js | 83 + .../node_modules/mysql2/lib/packet_parser.js | 199 + .../mysql2/lib/packets/auth_next_factor.js | 35 + .../mysql2/lib/packets/auth_switch_request.js | 38 + .../packets/auth_switch_request_more_data.js | 33 + .../lib/packets/auth_switch_response.js | 30 + .../mysql2/lib/packets/binary_row.js | 95 + .../mysql2/lib/packets/binlog_dump.js | 33 + .../lib/packets/binlog_query_statusvars.js | 115 + .../mysql2/lib/packets/change_user.js | 97 + .../mysql2/lib/packets/close_statement.js | 21 + .../mysql2/lib/packets/column_definition.js | 326 ++ .../mysql2/lib/packets/encode_parameter.js | 121 + .../mysql2/lib/packets/execute.js | 223 + .../mysql2/lib/packets/handshake.js | 124 + .../mysql2/lib/packets/handshake_response.js | 177 + .../node_modules/mysql2/lib/packets/index.js | 154 + .../node_modules/mysql2/lib/packets/packet.js | 1165 ++++ .../mysql2/lib/packets/prepare_statement.js | 39 + .../lib/packets/prepared_statement_header.js | 16 + .../node_modules/mysql2/lib/packets/query.js | 149 + .../mysql2/lib/packets/register_slave.js | 46 + .../mysql2/lib/packets/reset_connection.js | 17 + .../mysql2/lib/packets/resultset_header.js | 123 + .../mysql2/lib/packets/ssl_request.js | 30 + .../mysql2/lib/packets/text_row.js | 47 + .../mysql2/lib/packets/typed_parameter.js | 391 ++ .../mysql2/lib/parsers/binary_parser.js | 274 + .../mysql2/lib/parsers/parser_cache.js | 77 + .../lib/parsers/static_binary_parser.js | 248 + .../mysql2/lib/parsers/static_text_parser.js | 171 + .../node_modules/mysql2/lib/parsers/string.js | 95 + .../mysql2/lib/parsers/text_parser.js | 220 + .../node_modules/mysql2/lib/pool.js | 12 + .../node_modules/mysql2/lib/pool_cluster.js | 386 ++ .../node_modules/mysql2/lib/pool_config.js | 34 + .../mysql2/lib/pool_connection.js | 81 + .../mysql2/lib/promise/capture_local_err.js | 25 + .../mysql2/lib/promise/connection.js | 251 + .../mysql2/lib/promise/inherit_events.js | 27 + .../mysql2/lib/promise/make_done_cb.js | 16 + .../node_modules/mysql2/lib/promise/pool.js | 124 + .../mysql2/lib/promise/pool_cluster.js | 59 + .../mysql2/lib/promise/pool_connection.js | 19 + .../lib/promise/prepared_statement_info.js | 35 + .../node_modules/mysql2/lib/results_stream.js | 38 + .../node_modules/mysql2/lib/ring_queue.js | 353 ++ .../node_modules/mysql2/lib/server.js | 37 + .../node_modules/mysql2/lib/tracing.js | 81 + .../node_modules/mysql2/package.json | 86 + .../node_modules/mysql2/promise.d.ts | 141 + .../node_modules/mysql2/promise.js | 214 + .../mysql2/typings/mysql/LICENSE.txt | 15 + .../mysql2/typings/mysql/index.d.ts | 94 + .../mysql2/typings/mysql/info.txt | 1 + .../mysql2/typings/mysql/lib/Auth.d.ts | 30 + .../mysql2/typings/mysql/lib/Connection.d.ts | 462 ++ .../mysql2/typings/mysql/lib/Pool.d.ts | 88 + .../mysql2/typings/mysql/lib/PoolCluster.d.ts | 92 + .../typings/mysql/lib/PoolConnection.d.ts | 16 + .../mysql2/typings/mysql/lib/Server.d.ts | 11 + .../mysql2/typings/mysql/lib/Tracing.d.ts | 67 + .../typings/mysql/lib/TypedParameter.d.ts | 84 + .../lib/constants/CharsetToEncoding.d.ts | 8 + .../typings/mysql/lib/constants/Charsets.d.ts | 326 ++ .../typings/mysql/lib/constants/Types.d.ts | 70 + .../typings/mysql/lib/constants/index.d.ts | 5 + .../mysql/lib/parsers/ParserCache.d.ts | 4 + .../typings/mysql/lib/parsers/index.d.ts | 18 + .../typings/mysql/lib/parsers/typeCast.d.ts | 65 + .../mysql/lib/protocol/packets/Field.d.ts | 10 + .../lib/protocol/packets/FieldPacket.d.ts | 38 + .../mysql/lib/protocol/packets/OkPacket.d.ts | 23 + .../lib/protocol/packets/ProcedurePacket.d.ts | 13 + .../lib/protocol/packets/ResultSetHeader.d.ts | 18 + .../lib/protocol/packets/RowDataPacket.d.ts | 9 + .../mysql/lib/protocol/packets/index.d.ts | 28 + .../packets/params/ErrorPacketParams.d.ts | 6 + .../packets/params/OkPacketParams.d.ts | 9 + .../protocol/sequences/ExecutableBase.d.ts | 41 + .../mysql/lib/protocol/sequences/Prepare.d.ts | 65 + .../mysql/lib/protocol/sequences/Query.d.ts | 243 + .../lib/protocol/sequences/QueryableBase.d.ts | 41 + .../lib/protocol/sequences/Sequence.d.ts | 5 + .../sequences/promise/ExecutableBase.d.ts | 17 + .../sequences/promise/QueryableBase.d.ts | 18 + .../node_modules/named-placeholders/LICENSE | 21 + .../node_modules/named-placeholders/README.md | 27 + .../node_modules/named-placeholders/index.js | 179 + .../named-placeholders/package.json | 36 + .../node_modules/safer-buffer/LICENSE | 21 + .../safer-buffer/Porting-Buffer.md | 268 + .../node_modules/safer-buffer/Readme.md | 156 + .../node_modules/safer-buffer/dangerous.js | 58 + .../node_modules/safer-buffer/package.json | 34 + .../node_modules/safer-buffer/safer.js | 77 + .../node_modules/safer-buffer/tests.js | 406 ++ .../node_modules/sql-escaper/LICENSE | 21 + .../node_modules/sql-escaper/README.md | 516 ++ .../node_modules/sql-escaper/lib/index.d.ts | 16 + .../node_modules/sql-escaper/lib/index.js | 566 ++ .../node_modules/sql-escaper/lib/index.mjs | 467 ++ .../node_modules/sql-escaper/lib/types.d.ts | 11 + .../node_modules/sql-escaper/lib/types.js | 2 + .../node_modules/sql-escaper/package.json | 81 + .../node_modules/undici-types/LICENSE | 21 + .../node_modules/undici-types/README.md | 6 + .../node_modules/undici-types/agent.d.ts | 30 + .../node_modules/undici-types/api.d.ts | 43 + .../undici-types/balanced-pool.d.ts | 30 + .../undici-types/cache-interceptor.d.ts | 179 + .../node_modules/undici-types/cache.d.ts | 36 + .../undici-types/client-stats.d.ts | 15 + .../node_modules/undici-types/client.d.ts | 129 + .../node_modules/undici-types/connector.d.ts | 36 + .../undici-types/content-type.d.ts | 21 + .../node_modules/undici-types/cookies.d.ts | 30 + .../undici-types/diagnostics-channel.d.ts | 74 + .../node_modules/undici-types/dispatcher.d.ts | 253 + .../undici-types/dispatcher1-wrapper.d.ts | 7 + .../undici-types/env-http-proxy-agent.d.ts | 22 + .../node_modules/undici-types/errors.d.ts | 177 + .../undici-types/eventsource.d.ts | 66 + .../node_modules/undici-types/fetch.d.ts | 231 + .../node_modules/undici-types/formdata.d.ts | 108 + .../undici-types/global-dispatcher.d.ts | 9 + .../undici-types/global-origin.d.ts | 7 + .../node_modules/undici-types/h2c-client.d.ts | 73 + .../node_modules/undici-types/handlers.d.ts | 14 + .../node_modules/undici-types/header.d.ts | 165 + .../node_modules/undici-types/index.d.ts | 93 + .../undici-types/interceptors.d.ts | 80 + .../node_modules/undici-types/mock-agent.d.ts | 68 + .../undici-types/mock-call-history.d.ts | 111 + .../undici-types/mock-client.d.ts | 27 + .../undici-types/mock-errors.d.ts | 12 + .../undici-types/mock-interceptor.d.ts | 94 + .../node_modules/undici-types/mock-pool.d.ts | 27 + .../node_modules/undici-types/package.json | 55 + .../node_modules/undici-types/patch.d.ts | 29 + .../node_modules/undici-types/pool-stats.d.ts | 19 + .../node_modules/undici-types/pool.d.ts | 39 + .../undici-types/proxy-agent.d.ts | 29 + .../node_modules/undici-types/readable.d.ts | 68 + .../undici-types/retry-agent.d.ts | 8 + .../undici-types/retry-handler.d.ts | 125 + .../undici-types/round-robin-pool.d.ts | 39 + .../undici-types/snapshot-agent.d.ts | 113 + .../undici-types/socks5-proxy-agent.d.ts | 25 + .../node_modules/undici-types/util.d.ts | 18 + .../node_modules/undici-types/utility.d.ts | 7 + .../node_modules/undici-types/webidl.d.ts | 346 ++ .../node_modules/undici-types/websocket.d.ts | 188 + ai-usage-mysql-bridge/package-lock.json | 135 + ai-usage-mysql-bridge/package.json | 13 + ai-usage-mysql-bridge/server.js | 724 +++ .../停止AI用量MySQL桥接服务.bat | 20 + .../启动AI用量MySQL桥接服务.bat | 57 + 372 files changed, 97030 insertions(+), 661 deletions(-) create mode 100644 __old_extend.js create mode 100644 __review_diff.txt create mode 100644 ai-usage-mysql-bridge/dashboard-full-screenshot.png create mode 100644 ai-usage-mysql-bridge/dashboard-screenshot.png create mode 100644 ai-usage-mysql-bridge/dashboard-sidebar.png create mode 100644 ai-usage-mysql-bridge/dashboard.html create mode 100644 ai-usage-mysql-bridge/node_modules/.package-lock.json create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/assert.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/assert/strict.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/async_hooks.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/buffer.buffer.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/buffer.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/child_process.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/cluster.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/console.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/constants.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/crypto.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/dgram.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/diagnostics_channel.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/dns.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/dns/promises.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/domain.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/events.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/ffi.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/fs.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/fs/promises.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/globals.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/globals.typedarray.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/http.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/http2.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/https.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/inspector.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/inspector.generated.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/inspector/promises.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/module.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/net.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/os.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/path.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/path/posix.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/path/win32.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/perf_hooks.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/process.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/punycode.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/querystring.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/quic.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/readline.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/readline/promises.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/repl.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/sea.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/sqlite.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/stream.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/stream/consumers.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/stream/iter.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/stream/promises.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/stream/web.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/string_decoder.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/test.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/test/reporters.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/timers.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/timers/promises.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/tls.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/trace_events.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/ts5.6/buffer.buffer.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/ts5.6/globals.typedarray.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/ts5.6/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/ts5.7/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/tty.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/url.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/util.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/util/types.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/v8.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/vm.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/wasi.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/abortcontroller.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/blob.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/console.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/crypto.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/domexception.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/encoding.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/events.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/fetch.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/importmeta.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/messaging.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/navigator.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/performance.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/storage.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/streams.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/timers.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/web-globals/url.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/worker_threads.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/zlib.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/@types/node/zlib/iter.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/lib/@types/profiles.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/lib/@types/profiles.js create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/lib/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/lib/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/lib/profiles/ca/defaults.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/lib/profiles/ca/defaults.js create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/lib/profiles/ca/proxies.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/lib/profiles/ca/proxies.js create mode 100644 ai-usage-mysql-bridge/node_modules/aws-ssl-profiles/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/generate-function/.travis.yml create mode 100644 ai-usage-mysql-bridge/node_modules/generate-function/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/generate-function/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/generate-function/example.js create mode 100644 ai-usage-mysql-bridge/node_modules/generate-function/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/generate-function/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/generate-function/test.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/dbcs-codec.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/dbcs-data.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/internal.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/sbcs-codec.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/sbcs-data-generated.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/sbcs-data.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/tables/big5-added.json create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/tables/cp936.json create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/tables/cp949.json create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/tables/cp950.json create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/tables/eucjp.json create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/tables/gbk-added.json create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/tables/shiftjis.json create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/utf16.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/utf32.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/encodings/utf7.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/lib/bom-handling.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/lib/helpers/merge-exports.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/lib/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/lib/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/lib/streams.js create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/iconv-lite/types/encodings.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/is-property/.npmignore create mode 100644 ai-usage-mysql-bridge/node_modules/is-property/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/is-property/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/is-property/is-property.js create mode 100644 ai-usage-mysql-bridge/node_modules/is-property/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/long/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/long/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/long/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/long/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/long/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/long/types.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/long/umd/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/long/umd/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/long/umd/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/long/umd/types.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/lru.min/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/lru.min/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/lru.min/browser/lru.min.js create mode 100644 ai-usage-mysql-bridge/node_modules/lru.min/lib/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/lru.min/lib/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/lru.min/lib/index.mjs create mode 100644 ai-usage-mysql-bridge/node_modules/lru.min/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/License create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/auth_41.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/auth_plugins/caching_sha2_password.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/auth_plugins/caching_sha2_password.md create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/auth_plugins/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/auth_plugins/mysql_clear_password.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/auth_plugins/mysql_native_password.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/auth_plugins/sha256_password.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/base/connection.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/base/pool.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/auth_switch.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/binlog_dump.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/change_user.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/client_handshake.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/close_statement.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/command.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/execute.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/ping.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/prepare.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/query.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/quit.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/register_slave.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/reset_connection.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/commands/server_handshake.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/compressed_protocol.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/connection.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/connection_config.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/charset_encodings.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/charsets.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/client.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/commands.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/cursor.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/encoding_charset.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/errors.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/field_flags.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/mariadb_client.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/server_status.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/session_track.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/ssl_profiles.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/constants/types.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/create_connection.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/create_pool.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/create_pool_cluster.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/helpers.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packet_parser.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/auth_next_factor.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/auth_switch_request.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/auth_switch_request_more_data.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/auth_switch_response.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/binary_row.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/binlog_dump.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/binlog_query_statusvars.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/change_user.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/close_statement.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/column_definition.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/encode_parameter.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/execute.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/handshake.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/handshake_response.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/packet.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/prepare_statement.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/prepared_statement_header.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/query.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/register_slave.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/reset_connection.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/resultset_header.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/ssl_request.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/text_row.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/packets/typed_parameter.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/parsers/binary_parser.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/parsers/parser_cache.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/parsers/static_binary_parser.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/parsers/static_text_parser.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/parsers/string.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/parsers/text_parser.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/pool.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/pool_cluster.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/pool_config.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/pool_connection.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/promise/capture_local_err.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/promise/connection.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/promise/inherit_events.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/promise/make_done_cb.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/promise/pool.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/promise/pool_cluster.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/promise/pool_connection.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/promise/prepared_statement_info.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/results_stream.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/ring_queue.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/server.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/lib/tracing.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/promise.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/promise.js create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/LICENSE.txt create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/info.txt create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/Auth.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/Connection.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/Pool.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/PoolCluster.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/PoolConnection.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/Server.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/Tracing.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/TypedParameter.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/constants/CharsetToEncoding.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/constants/Charsets.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/constants/Types.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/constants/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/parsers/ParserCache.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/parsers/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/parsers/typeCast.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/packets/Field.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/packets/FieldPacket.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/packets/OkPacket.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/packets/ProcedurePacket.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/packets/ResultSetHeader.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/packets/RowDataPacket.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/packets/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/packets/params/ErrorPacketParams.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/packets/params/OkPacketParams.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/sequences/ExecutableBase.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/sequences/Prepare.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/sequences/Query.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/sequences/QueryableBase.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/sequences/Sequence.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/sequences/promise/ExecutableBase.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/mysql2/typings/mysql/lib/protocol/sequences/promise/QueryableBase.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/named-placeholders/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/named-placeholders/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/named-placeholders/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/named-placeholders/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/safer-buffer/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/safer-buffer/Porting-Buffer.md create mode 100644 ai-usage-mysql-bridge/node_modules/safer-buffer/Readme.md create mode 100644 ai-usage-mysql-bridge/node_modules/safer-buffer/dangerous.js create mode 100644 ai-usage-mysql-bridge/node_modules/safer-buffer/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/safer-buffer/safer.js create mode 100644 ai-usage-mysql-bridge/node_modules/safer-buffer/tests.js create mode 100644 ai-usage-mysql-bridge/node_modules/sql-escaper/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/sql-escaper/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/sql-escaper/lib/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/sql-escaper/lib/index.js create mode 100644 ai-usage-mysql-bridge/node_modules/sql-escaper/lib/index.mjs create mode 100644 ai-usage-mysql-bridge/node_modules/sql-escaper/lib/types.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/sql-escaper/lib/types.js create mode 100644 ai-usage-mysql-bridge/node_modules/sql-escaper/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/LICENSE create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/README.md create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/agent.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/api.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/balanced-pool.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/cache-interceptor.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/cache.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/client-stats.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/client.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/connector.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/content-type.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/cookies.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/diagnostics-channel.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/dispatcher.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/dispatcher1-wrapper.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/env-http-proxy-agent.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/errors.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/eventsource.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/fetch.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/formdata.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/global-dispatcher.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/global-origin.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/h2c-client.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/handlers.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/header.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/index.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/interceptors.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/mock-agent.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/mock-call-history.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/mock-client.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/mock-errors.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/mock-interceptor.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/mock-pool.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/package.json create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/patch.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/pool-stats.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/pool.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/proxy-agent.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/readable.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/retry-agent.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/retry-handler.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/round-robin-pool.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/snapshot-agent.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/socks5-proxy-agent.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/util.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/utility.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/webidl.d.ts create mode 100644 ai-usage-mysql-bridge/node_modules/undici-types/websocket.d.ts create mode 100644 ai-usage-mysql-bridge/package-lock.json create mode 100644 ai-usage-mysql-bridge/package.json create mode 100644 ai-usage-mysql-bridge/server.js create mode 100644 ai-usage-mysql-bridge/停止AI用量MySQL桥接服务.bat create mode 100644 ai-usage-mysql-bridge/启动AI用量MySQL桥接服务.bat diff --git a/.gitignore b/.gitignore index 8fbabf6..beeea82 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ 外部参考/ +.trae/ diff --git a/ExtendWebAITokenChart.js b/ExtendWebAITokenChart.js index 8575a79..4f9dae9 100644 --- a/ExtendWebAITokenChart.js +++ b/ExtendWebAITokenChart.js @@ -1,53 +1,39 @@ // ==UserScript== -// @name AI 用量监控与历史图表 +// @name AI 用量监控 // @namespace http://tampermonkey.net/ -// @version 5.1 -// @description 记录额度历史、展示总用量和区间增量,并支持剪贴板导入导出合并。 +// @version 7.3 +// @description 拦截页面 API 用量数据并推送到后端采集服务。 // @author AI Assistant // @match http://192.168.0.87:8787/* -// @grant GM_getValue -// @grant GM_setValue -// @grant GM_setClipboard +// @connect 127.0.0.1 // @grant unsafeWindow -// @require https://cdn.jsdelivr.net/npm/chart.js +// @grant GM_xmlhttpRequest // ==/UserScript== (function () { 'use strict'; - const POLLING_INTERVAL = 300000; - const REQUEST_TIMEOUT = 30000; - const PANEL_MIN_WIDTH = 340; - const PANEL_MIN_HEIGHT = 240; - const STORAGE_KEY = 'aiUsageHistoryV1'; - const PANEL_LAYOUT_STORAGE_KEY = 'aiUsagePanelLayoutV1'; - const EXPORT_PREFIX = 'AI_USAGE_HISTORY_V1:'; - const pageWindow = typeof unsafeWindow === 'undefined' || typeof unsafeWindow.fetch !== 'function' ? window : unsafeWindow; + // ── 配置 ── + const POLLING_INTERVAL = 300000; // 轮询间隔 5 分钟 + const REQUEST_TIMEOUT = 30000; // 刷新请求超时 + const BACKEND_URL = 'http://127.0.0.1:8788'; + const CHANNEL_ID = 1; // 默认渠道:内网平台 - // 兼容 ExtendWebUIDark.js:该脚本会全局反色,并单独还原 canvas。 - const usesInversionDarkMode = () => Boolean(document.getElementById('tm-dark-filter')); + const pageWindow = typeof unsafeWindow === 'undefined' || typeof unsafeWindow.fetch !== 'function' + ? window : unsafeWindow; + // ── 状态 ── let historyByAssignment = {}; let assignmentNames = {}; - let currentQuotaByAssignment = {}; - let selectedAssignmentId = ''; - let selectedRange = 'today'; - let myChart = null; let timerId = null; let isProcessing = false; - let isClipboardBusy = false; - let refreshAnimationId = null; - let refreshAnimationStartedAt = 0; - const REFRESH_ANIMATION_DURATION = 1200; - const pendingRefreshes = new Map(); - function setStatus(message, color = '#6c757d') { - const status = document.getElementById('monitor-status'); - if (status) { - status.textContent = message; - status.style.color = color; - } - } + const pendingRefreshes = new Map(); + let lastSyncSummary = '尚未同步'; + let lastPushError = null; + let panelSyncBtn = null; + + // ── 工具函数 ── function numberOrNull(value) { const parsed = Number(value); @@ -61,10 +47,6 @@ return [Number(timestamp), Number(used)]; } - function toChartPoint(point) { - return { timestamp: point[0], used: point[1] }; - } - function aggregatePoints(points, intervalMs) { const buckets = new Map(); points.forEach(point => { @@ -75,471 +57,111 @@ return Array.from(buckets.values()).sort((a, b) => a[0] - b[0]); } + /** 按 2 天分界:近期全量 + 更早按天聚合,防止内存无限增长 */ function compactPoints(points) { const cutoff = Date.now() - 2 * 86400000; - const unique = new Map(points.map(normalizePoint).filter(Boolean).map(point => [point[0], point])); + const unique = new Map( + points.map(normalizePoint).filter(Boolean).map(p => [p[0], p]) + ); const all = Array.from(unique.values()).sort((a, b) => a[0] - b[0]); return { - recent: all.filter(point => point[0] >= cutoff), - archived: aggregatePoints(all.filter(point => point[0] < cutoff), 86400000) + recent: all.filter(p => p[0] >= cutoff), + archived: aggregatePoints(all.filter(p => p[0] < cutoff), 86400000) }; } - function extractStoredPoints(stored) { - if (Array.isArray(stored)) return stored; - if (!stored || typeof stored !== 'object') return []; - if (Array.isArray(stored.recent) || Array.isArray(stored.archived)) return [...(stored.recent || []), ...(stored.archived || [])]; - return Object.values(stored).flatMap(points => Array.isArray(points) ? points : []); + // ── 数据格式转换 ── + + function rawToPayload(raw) { + const assignments = Object.entries(raw || {}).map(([id, history]) => [ + id, + assignmentNames[id] || '', + [...(history?.archived || []), ...(history?.recent || [])] + ]); + return { v: 3, a: assignments }; } - function normalizeHistory(raw) { - const normalized = {}; - if (!raw || typeof raw !== 'object') return normalized; - Object.entries(raw).forEach(([assignmentId, stored]) => { - const compact = compactPoints(extractStoredPoints(stored)); - if (compact.recent.length || compact.archived.length) normalized[assignmentId] = compact; - }); - return normalized; - } + // ── 后端推送 ── - function getAssignmentPoints(assignmentId) { - const history = historyByAssignment[assignmentId] || { recent: [], archived: [] }; - return [...history.archived, ...history.recent].sort((a, b) => a[0] - b[0]).map(toChartPoint); - } - - async function loadHistory() { - historyByAssignment = normalizeHistory(await GM_getValue(STORAGE_KEY, {})); - } - - async function saveHistory() { - historyByAssignment = normalizeHistory(historyByAssignment); - await GM_setValue(STORAGE_KEY, historyByAssignment); - } - - function constrainPanel(container, layout = {}) { - const viewportWidth = Math.max(1, window.innerWidth); - const viewportHeight = Math.max(1, window.innerHeight); - const minWidth = Math.min(PANEL_MIN_WIDTH, viewportWidth); - const minHeight = Math.min(PANEL_MIN_HEIGHT, viewportHeight); - const width = Math.min(Math.max(minWidth, Number(layout.width) || container.getBoundingClientRect().width), viewportWidth); - const height = Math.min(Math.max(minHeight, Number(layout.height) || container.getBoundingClientRect().height), viewportHeight); - const fallbackLeft = Math.max(0, viewportWidth - width - 20); - const left = Math.min(Math.max(0, Number.isFinite(Number(layout.left)) ? Number(layout.left) : fallbackLeft), viewportWidth - width); - const top = Math.min(Math.max(0, Number.isFinite(Number(layout.top)) ? Number(layout.top) : 20), viewportHeight - height); - Object.assign(container.style, { left: `${left}px`, top: `${top}px`, width: `${width}px`, height: `${height}px`, right: 'auto', bottom: 'auto' }); - } - - async function restorePanelLayout(container) { - const layout = await GM_getValue(PANEL_LAYOUT_STORAGE_KEY, {}); - constrainPanel(container, layout); - myChart?.resize(); - myChart?.update('none'); - } - - function savePanelLayout(container) { - const rect = container.getBoundingClientRect(); - GM_setValue(PANEL_LAYOUT_STORAGE_KEY, { left: rect.left, top: rect.top, width: rect.width, height: rect.height }); - } - - function getRefreshButtons() { - return Array.from(document.querySelectorAll('button[data-action="refresh"][data-assignment-id]')); - } - - function refreshAssignments() { - getRefreshButtons().forEach(button => { - const id = button.dataset.assignmentId; - if (!id) return; - const card = button.closest('article, section, div'); - const text = card ? card.innerText.split('\n')[0].trim() : ''; - assignmentNames[id] = text || assignmentNames[id] || id; - }); - Object.keys(historyByAssignment).forEach(id => { assignmentNames[id] = assignmentNames[id] || id; }); - const ids = Object.keys(assignmentNames); - if (!selectedAssignmentId || !ids.includes(selectedAssignmentId)) selectedAssignmentId = ids[0] || ''; - - const select = document.getElementById('assignment-selector'); - if (!select) return; - select.replaceChildren(); - ids.forEach(id => { - const option = document.createElement('option'); - option.value = id; - option.textContent = assignmentNames[id] || id; - select.appendChild(option); - }); - select.value = selectedAssignmentId; - } - - function setPanelMinimized(container, minimized) { - const restoreButton = document.getElementById('usage-monitor-restore-button'); - container.dataset.minimized = minimized ? 'true' : ''; - container.style.display = minimized ? 'none' : 'flex'; - if (restoreButton) restoreButton.style.display = minimized ? 'block' : 'none'; - if (!minimized) { - myChart?.resize(); - myChart?.update('none'); - } - } - - function createUI() { - const inverted = usesInversionDarkMode(); - // 反色模式下,面板本身会被 html 滤镜反转,因此改用对应的浅色原始值。 - const palette = inverted - ? { surface: '#efe7d8', text: '#071012', border: '#cbd5e1', control: '#e2e8f0', muted: '#475569', shadow: '0 12px 32px rgba(255,255,255,.28)' } - : { surface: '#101827', text: '#f8fafc', border: '#334155', control: '#1e293b', muted: '#94a3b8', shadow: '0 12px 32px rgba(15,23,42,.48)' }; - const container = document.createElement('div'); - container.id = 'usage-monitor-container'; - Object.assign(container.style, { - position: 'fixed', top: '20px', right: '20px', width: '460px', height: '330px', - backgroundColor: palette.surface, color: palette.text, padding: '15px', borderRadius: '10px', - boxShadow: palette.shadow, zIndex: '9999', - fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', - fontSize: '14px', border: `1px solid ${palette.border}`, boxSizing: 'border-box', display: 'flex', flexDirection: 'column', overflow: 'hidden' - }); - const header = document.createElement('div'); - header.style.cssText = `display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-shrink:0;color:${palette.text}`; - header.innerHTML = `用量监控`; - const createHeaderButton = (id, label, title, handler, accent = false) => { - const button = document.createElement('button'); - button.id = id; - button.type = 'button'; - button.textContent = label; - button.title = title; - button.style.cssText = `background:${accent ? '#0ea5e9' : palette.control};color:${palette.text};border:1px solid ${accent ? '#7dd3fc' : palette.border};border-radius:5px;padding:4px 8px;font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap`; - button.addEventListener('click', handler); - header.appendChild(button); - return button; - }; - const manualRefreshButton = createHeaderButton('manual-refresh-button', '刷新', '立即刷新全部凭据用量', () => triggerPageRefresh(), true); - createHeaderButton('export-history-button', '导出', '将全部历史复制到剪贴板', () => runClipboardAction('export')); - createHeaderButton('import-history-button', '导入', '从剪贴板读取历史并合并', () => runClipboardAction('import')); - const minimizeButton = document.createElement('button'); - minimizeButton.type = 'button'; - minimizeButton.textContent = '−'; - minimizeButton.title = '最小化图表'; - minimizeButton.setAttribute('aria-label', '最小化图表'); - minimizeButton.style.cssText = `background:${palette.control};color:${palette.text};border:1px solid ${palette.border};border-radius:5px;padding:2px 8px;font-size:16px;line-height:18px;cursor:pointer;font-weight:700`; - minimizeButton.addEventListener('click', () => setPanelMinimized(container, true)); - header.appendChild(minimizeButton); - container.appendChild(header); - - const rangeBar = document.createElement('div'); - rangeBar.id = 'chart-range-selector'; - rangeBar.style.cssText = 'display:flex;gap:6px;margin-bottom:7px;flex-shrink:0'; - [['today', '今天'], ['7d', '最近 7 天'], ['30d', '最近 30 天']].forEach(([value, label]) => { - const button = document.createElement('button'); - button.type = 'button'; - button.dataset.range = value; - button.textContent = label; - button.style.cssText = `background:${palette.control};color:${palette.text};border:1px solid ${palette.border};border-radius:5px;padding:3px 7px;font-size:12px;cursor:pointer`; - button.addEventListener('click', () => { - selectedRange = value; - updateRangeButtons(); - updateChart(); - }); - rangeBar.appendChild(button); - }); - container.appendChild(rangeBar); - - const status = document.createElement('div'); - status.id = 'monitor-status'; - status.textContent = '初始化...'; - status.style.cssText = `font-size:12px;color:${palette.muted};margin-bottom:4px;flex-shrink:0`; - container.appendChild(status); - const hint = document.createElement('div'); - hint.textContent = '使用“导出”复制全部历史;使用“导入”从剪贴板合并历史'; - hint.style.cssText = `font-size:11px;color:${palette.muted};margin-bottom:8px;flex-shrink:0`; - container.appendChild(hint); - - const chartBox = document.createElement('div'); - chartBox.style.cssText = 'position:relative;flex:1;min-height:0'; - const canvas = document.createElement('canvas'); - canvas.id = 'usageChart'; - chartBox.appendChild(canvas); - container.appendChild(chartBox); - const resizer = document.createElement('div'); - Object.assign(resizer.style, { width: '15px', height: '15px', position: 'absolute', right: '1px', bottom: '1px', cursor: 'se-resize', background: 'linear-gradient(135deg, transparent 50%, #38bdf8 50%)' }); - container.appendChild(resizer); - document.body.appendChild(container); - const restoreButton = document.createElement('button'); - restoreButton.id = 'usage-monitor-restore-button'; - restoreButton.type = 'button'; - restoreButton.textContent = '用量监控'; - restoreButton.title = '恢复用量监控图表'; - restoreButton.style.cssText = `position:fixed;top:12px;right:12px;z-index:9999;display:none;background:${palette.control};color:${palette.text};border:1px solid ${palette.border};border-radius:6px;padding:6px 10px;font-size:12px;font-weight:700;box-shadow:${palette.shadow};cursor:pointer`; - restoreButton.addEventListener('click', () => setPanelMinimized(container, false)); - document.body.appendChild(restoreButton); - makeDraggable(container, header); - makeResizable(container, resizer); - document.getElementById('assignment-selector').addEventListener('change', event => { - selectedAssignmentId = event.target.value; - updateChart(); - }); - refreshAssignments(); - initChart(); - updateRangeButtons(); - restorePanelLayout(container); - } - - function makeDraggable(container, handle) { - let dragOffsetX = 0; - let dragOffsetY = 0; - let dragging = false; - - handle.style.cursor = 'move'; - handle.addEventListener('mousedown', event => { - if (event.target.closest('button, select')) return; - const rect = container.getBoundingClientRect(); - dragOffsetX = event.clientX - rect.left; - dragOffsetY = event.clientY - rect.top; - dragging = true; - event.preventDefault(); - }); - window.addEventListener('mousemove', event => { - if (!dragging) return; - const rect = container.getBoundingClientRect(); - const maxLeft = Math.max(0, window.innerWidth - rect.width); - const maxTop = Math.max(0, window.innerHeight - rect.height); - container.style.left = `${Math.min(Math.max(0, event.clientX - dragOffsetX), maxLeft)}px`; - container.style.top = `${Math.min(Math.max(0, event.clientY - dragOffsetY), maxTop)}px`; - container.style.right = 'auto'; - container.style.bottom = 'auto'; - }); - window.addEventListener('mouseup', () => { - if (!dragging) return; - dragging = false; - savePanelLayout(container); - }); - } - - function makeResizable(container, resizer) { - let resizing = false; - let startX = 0; - let startY = 0; - let startWidth = 0; - let startHeight = 0; - - resizer.addEventListener('mousedown', event => { - const rect = container.getBoundingClientRect(); - resizing = true; - startX = event.clientX; - startY = event.clientY; - startWidth = rect.width; - startHeight = rect.height; - event.preventDefault(); - event.stopPropagation(); - }); - window.addEventListener('mousemove', event => { - if (!resizing) return; - const rect = container.getBoundingClientRect(); - const minWidth = Math.min(PANEL_MIN_WIDTH, window.innerWidth); - const minHeight = Math.min(PANEL_MIN_HEIGHT, window.innerHeight); - const maxWidth = Math.max(minWidth, window.innerWidth - rect.left); - const maxHeight = Math.max(minHeight, window.innerHeight - rect.top); - const width = Math.min(Math.max(minWidth, startWidth + event.clientX - startX), maxWidth); - const height = Math.min(Math.max(minHeight, startHeight + event.clientY - startY), maxHeight); - container.style.width = `${width}px`; - container.style.height = `${height}px`; - myChart?.resize(); - }); - window.addEventListener('mouseup', () => { - if (!resizing) return; - resizing = false; - savePanelLayout(container); - myChart?.resize(); - myChart?.update('none'); - }); - } - - function getRefreshAnimationProgress() { - if (!refreshAnimationStartedAt) return 1; - return Math.min(1, (performance.now() - refreshAnimationStartedAt) / REFRESH_ANIMATION_DURATION); - } - - function playRefreshAnimation() { - refreshAnimationStartedAt = performance.now(); - cancelAnimationFrame(refreshAnimationId); - const render = () => { - const progress = getRefreshAnimationProgress(); - myChart?.draw(); - if (progress < 1) refreshAnimationId = requestAnimationFrame(render); - else refreshAnimationStartedAt = 0; - }; - refreshAnimationId = requestAnimationFrame(render); - } - - function getAverageDailyUsage(points) { - if (points.length < 2) return 0; - const first = points[0]; - const last = points[points.length - 1]; - const elapsedDays = (last.timestamp - first.timestamp) / 86400000; - return elapsedDays > 0 ? Math.max(0, (last.used - first.used) / elapsedDays) : 0; - } - - function getTodayUsage(points) { - const todayPoints = points.filter(point => point.timestamp >= startOfToday()); - if (todayPoints.length < 2) return 0; - return Math.max(0, todayPoints[todayPoints.length - 1].used - todayPoints[0].used); - } - - const currentUsageLinePlugin = { - id: 'currentUsageLine', - afterDraw(chart) { - const points = getAssignmentPoints(selectedAssignmentId); - const currentPoint = points[points.length - 1]; - const quota = currentQuotaByAssignment[selectedAssignmentId]; - const yScale = chart.scales.yUsed; - if (!currentPoint || !yScale) return; - - const y = yScale.getPixelForValue(currentPoint.used); - const { left, right, top, bottom } = chart.chartArea; - if (y < top || y > bottom) return; - - const remaining = numberOrNull(quota?.remaining); - const todayUsage = getTodayUsage(points); - const dailyUsage = getAverageDailyUsage(points); - const estimatedDays = remaining !== null && dailyUsage > 0 ? remaining / dailyUsage : null; - const estimateText = remaining !== null && remaining <= 0 - ? ' [已用完]' - : estimatedDays === null - ? '' - : estimatedDays < 1 - ? ' [预计今天全部使用完毕]' - : ` [预计 ${Math.ceil(estimatedDays)} 天使用完毕]`; - const text = remaining === null - ? `当前 ${currentPoint.used.toFixed(6)} CNY / 今日用量 ${todayUsage.toFixed(6)} CNY` - : `当前 ${currentPoint.used.toFixed(6)} CNY / 剩余 ${remaining.toFixed(6)} CNY / 今日用量 ${todayUsage.toFixed(6)} CNY${estimateText}`; - - const context = chart.ctx; - context.save(); - context.setLineDash([7, 5]); - context.strokeStyle = '#facc15'; - context.lineWidth = 2; - context.beginPath(); - context.moveTo(left, y); - context.lineTo(right, y); - context.stroke(); - context.setLineDash([]); - context.font = 'bold 16px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'; - context.textAlign = 'right'; - context.textBaseline = 'bottom'; - context.fillStyle = '#fef08a'; - context.fillText(text, right - 6, y - 5); - context.restore(); - } - }; - - const refreshSweepPlugin = { - id: 'refreshSweep', - afterDatasetsDraw(chart) { - if (!refreshAnimationStartedAt) return; - const dataset = chart.getDatasetMeta(0); - const points = dataset.data; - if (points.length < 2) return; - - const progress = getRefreshAnimationProgress(); - const { left, right, bottom } = chart.chartArea; - const sweepX = left + (right - left) * progress; - const context = chart.ctx; - const glow = context.createLinearGradient(sweepX - 90, 0, sweepX + 90, 0); - glow.addColorStop(0, 'rgba(125,211,252,0)'); - glow.addColorStop(.5, 'rgba(224,242,254,.48)'); - glow.addColorStop(1, 'rgba(125,211,252,0)'); - - // 用总用量折线与基线构成裁剪区域,扫光只会出现在该折线的填充范围内。 - context.save(); - context.beginPath(); - context.moveTo(points[0].x, bottom); - points.forEach(point => context.lineTo(point.x, point.y)); - context.lineTo(points[points.length - 1].x, bottom); - context.closePath(); - context.clip(); - context.fillStyle = glow; - context.fillRect(sweepX - 90, chart.chartArea.top, 180, bottom - chart.chartArea.top); - context.restore(); - } - }; - - function initChart() { - const ctx = document.getElementById('usageChart').getContext('2d'); - myChart = new Chart(ctx, { - type: 'line', - plugins: [refreshSweepPlugin, currentUsageLinePlugin], - data: { datasets: [ - { label: '总已用额度 (CNY)', data: [], yAxisID: 'yUsed', borderColor: '#0ea5e9', backgroundColor: 'rgba(14,165,233,.18)', pointBackgroundColor: '#e0f2fe', pointBorderColor: '#38bdf8', fill: true, borderWidth: 2.5, tension: .25 }, - { label: '区间新增用量 (CNY)', data: [], yAxisID: 'yDelta', borderColor: '#f97316', backgroundColor: 'rgba(249,115,22,.15)', pointBackgroundColor: '#ffedd5', pointBorderColor: '#fb923c', borderWidth: 2.5, borderDash: [5, 4], tension: .25 } - ] }, - options: { - responsive: true, maintainAspectRatio: false, animation: { duration: 0 }, - scales: { - // 使用毫秒时间戳作为 x 值,点距会按真实经过时间而非样本数量绘制。 - x: { - type: 'linear', grid: { color: '#334155' }, - ticks: { color: '#cbd5e1', maxTicksLimit: 6, callback: value => formatAxisTime(value) } + /** 通过篡改猴后台通道发 POST:不受页面 CSP、CORS、扩展沙箱限制 */ + function gmPost(url, body) { + return new Promise((resolve, reject) => { + if (typeof GM_xmlhttpRequest === 'function') { + GM_xmlhttpRequest({ + method: 'POST', + url, + headers: { 'Content-Type': 'application/json' }, + data: body, + timeout: 15000, + onload: (res) => { + if (res.status >= 200 && res.status < 300) resolve(res); + else reject(new Error('HTTP ' + res.status + ' ' + res.statusText)); }, - yUsed: { position: 'left', grid: { color: '#334155' }, ticks: { color: '#7dd3fc', callback: value => `${Number(value).toFixed(2)} CNY` } }, - yDelta: { position: 'right', grid: { drawOnChartArea: false }, ticks: { color: '#fdba74', callback: value => `${Number(value).toFixed(2)} CNY` }, suggestedMin: 0 } - }, - plugins: { - legend: { labels: { color: '#e2e8f0', boxWidth: 14 } }, - tooltip: { - callbacks: { - title: items => items[0] ? formatTime(items[0].parsed.x) : '', - label: item => `${item.dataset.label}: ${Number(item.parsed.y).toFixed(5)} CNY` - } - } - } + onerror: (err) => reject(new Error('网络错误(' + (err && err.error ? err.error : '未知') + ')')), + ontimeout: () => reject(new Error('请求超时(15s)')) + }); + } else { + // 回退:普通 fetch(受同源策略约束,仅作忽略) + fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body }) + .then((r) => (r.ok ? resolve(r) : reject(new Error('HTTP ' + r.status)))) + .catch(reject); } }); } - function formatTime(timestamp) { - return new Date(Number(timestamp)).toLocaleString('zh-CN', { hour12: false }); - } - - function formatAxisTime(timestamp) { - return new Date(Number(timestamp)).toLocaleString('zh-CN', { - month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false - }); - } - - function startOfToday() { - const date = new Date(); - date.setHours(0, 0, 0, 0); - return date.getTime(); - } - - function getDisplayedPoints(assignmentId) { - const allPoints = getAssignmentPoints(assignmentId); - const now = Date.now(); - if (selectedRange === 'today') return allPoints.filter(point => point.timestamp >= startOfToday()); - // 超过两天的采样在存储阶段已按天归档;近期数据在视图中再按范围聚合。 - if (selectedRange === '7d') { - return aggregatePoints(allPoints.filter(point => point.timestamp >= now - 7 * 86400000).map(point => [point.timestamp, point.used]), 3600000).map(toChartPoint); + async function sendPointToBackend(assignmentId, point) { + try { + await gmPost(`${BACKEND_URL}/api/usage-data`, JSON.stringify({ + assignmentId, + assignmentName: assignmentNames[assignmentId] || assignmentId, + channel_id: CHANNEL_ID, + timestamp: point.timestamp, + used: point.used, + remaining: point.remaining + })); + } catch (error) { + console.warn('[用量监控] 推送到后端失败', error); + lastPushError = '推送后端失败:' + (error && error.message ? error.message : error); + setLastSyncSummary(lastPushError, '#e74c3c'); } - return allPoints.filter(point => point.timestamp >= now - 30 * 86400000); } - function getPointsWithDelta(assignmentId) { - const points = getDisplayedPoints(assignmentId); - return points.map((point, index) => ({ ...point, delta: index ? point.used - points[index - 1].used : 0 })); + async function saveHistoryToBackend() { + const payload = rawToPayload(historyByAssignment); + if (!payload.a.length) return; + try { + await gmPost(`${BACKEND_URL}/api/history/sync`, JSON.stringify({ ...payload, channel_id: CHANNEL_ID })); + } catch (error) { + console.warn('[用量监控] 同步历史到后端失败', error); + lastPushError = '历史同步失败:' + (error && error.message ? error.message : error); + setLastSyncSummary(lastPushError, '#e74c3c'); + } } - function updateRangeButtons() { - document.querySelectorAll('#chart-range-selector button').forEach(button => { - const active = button.dataset.range === selectedRange; - button.style.background = active ? '#0ea5e9' : ''; - button.style.borderColor = active ? '#7dd3fc' : ''; - button.style.fontWeight = active ? '700' : '400'; - }); + // ── 数据采集核心 ── + + async function addQuotaPoint(assignmentId, quota) { + const used = numberOrNull(quota && quota.used); + if (!assignmentId || used === null) return false; + const now = Date.now(); + const remaining = numberOrNull(quota.remaining); + const point = [now, used]; + + historyByAssignment[assignmentId] = historyByAssignment[assignmentId] || { recent: [], archived: [] }; + historyByAssignment[assignmentId].recent.push(point); + historyByAssignment[assignmentId] = compactPoints([ + ...historyByAssignment[assignmentId].archived, + ...historyByAssignment[assignmentId].recent + ]); + assignmentNames[assignmentId] = assignmentNames[assignmentId] || assignmentId; + + // 推送到后端 + await sendPointToBackend(assignmentId, { timestamp: now, used, remaining }); + + return true; } - function updateChart() { - if (!myChart) return; - const points = getPointsWithDelta(selectedAssignmentId); - myChart.data.datasets[0].data = points.map(point => ({ x: point.timestamp, y: point.used })); - myChart.data.datasets[1].data = points.map(point => ({ x: point.timestamp, y: point.delta })); - myChart.update(); - } + // ── Fetch 拦截 ── function getRequestUrl(input) { if (typeof input === 'string') return input; @@ -555,25 +177,6 @@ try { return JSON.parse(body).assignmentId || ''; } catch (_) { return ''; } } - function addQuotaPoint(assignmentId, quota) { - const used = numberOrNull(quota && quota.used); - if (!assignmentId || used === null) return false; - const point = [Date.now(), used]; - currentQuotaByAssignment[assignmentId] = { remaining: numberOrNull(quota.remaining) }; - historyByAssignment[assignmentId] = historyByAssignment[assignmentId] || { recent: [], archived: [] }; - historyByAssignment[assignmentId].recent.push(point); - historyByAssignment[assignmentId] = compactPoints([ - ...historyByAssignment[assignmentId].archived, - ...historyByAssignment[assignmentId].recent - ]); - assignmentNames[assignmentId] = assignmentNames[assignmentId] || assignmentId; - if (!selectedAssignmentId) selectedAssignmentId = assignmentId; - refreshAssignments(); - updateChart(); - playRefreshAnimation(); - return true; - } - function hookFetch() { const originalFetch = pageWindow.fetch; pageWindow.fetch = async function (...args) { @@ -590,7 +193,7 @@ try { if (!response.ok) throw new Error(`请求失败 (${response.status})`); const quota = await response.clone().json(); - if (!addQuotaPoint(assignmentId, quota)) throw new Error('响应中缺少有效用量'); + if (!(await addQuotaPoint(assignmentId, quota))) throw new Error('响应中缺少有效用量'); finishRefresh(assignmentId); } catch (error) { finishRefresh(assignmentId, error); @@ -600,6 +203,68 @@ }; } + // ── 页面诊断面板 ── + + function updatePanel() { + const info = document.getElementById('aIoMonInfo'); + const last = document.getElementById('aIoMonLast'); + if (info) { + const count = getRefreshButtons().length; + info.textContent = count ? `检测到 ${count} 个凭据卡片` : '未找到刷新额度按钮(页面结构可能有变)'; + info.style.color = count ? '#2ecc71' : '#f39c12'; + } + if (last) last.textContent = '上次同步:' + lastSyncSummary; + } + + function setLastSyncSummary(text, color) { + lastSyncSummary = text; + const last = document.getElementById('aIoMonLast'); + if (last) { + last.textContent = '上次同步:' + text; + last.style.color = color || '#e0e0e0'; + } + } + + function injectPanel() { + if (document.getElementById('aIoMonPanel')) return; + const panel = document.createElement('div'); + panel.id = 'aIoMonPanel'; + panel.innerHTML = ` +
nf+`Hx^V%nMX1XgO?V;rRt0TemsrxY13fcY#morAMBgdA#_a}=I8lR9A
z=1|e7p)NoRL47#ZDgh0fCdtLmqDM`gm}1X7k1*G&+LE}p&Uw@A#;)SR5GPt~sgVy{
z3STovVD Tj>zE}j~BShBo-J(@o$Qcs#R>gh^<+Up@JquxYymOkWDs~xG&
zqv6`^e(@>X3OJnht^8!9l#H*8&FIbYt^fV#Nb9SwzkN}6-Tc+*zSF<|iteN+O8Z8U
zs7 wOstb7-IbLX(aK$pw{OS`-@s*$vz1WcQ~r=$p7NU4^5--
zcpdS0@v6j+7E8(8APZ4a2RKFXbx~f;PF;KfN9|{f_K}Je<a1k!?@u6LXh;
z;h{%nztVc!mARSEwblwFRE4g=BM%utLVhM
zXcOKYfFGb4n(guwz4YZ;z}I*mmkN0v;~o19?SgW@%D>7*IA)xKb9ia3zH{2YR$9b9
zi9wPd3%zM?4K1r5Q26o?>ps0=1%hWRuLS~VfUTJqkIO0^s$j^kuB-$MP#c|nP@wP%
zVeCU07B*!*W3SxR9EqM*lHNU$&VR)6uJOiaTenDk=Y^p!A3WUpt%s*xDc2jEu)u0D
zSq^vu`|SF4MCN1_9C|P9-C*spU$F