<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>ChatGPT账号OpenAI官方APIkey余额信息批量查询</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?70076cdc16b66ddca1afdb1e4b20d953";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<style>
.contents {
width: 100%;
max-width: 1600px;
margin: auto;
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
background-color: rgba(0, 0, 0, 0.63);
}
.custom-style {
font-family: "微软雅黑";
color: white;
}
.btn-plain{
background-color: transparent;
border: none; color: #333;
font-size: 16px; cursor: pointer;
}
.btn-plain:hover { color: #666; }
.footer {
color: pink; /* 将文本颜色设置为粉色 */
font-size: 20px; /* 文字大小 */
font-family: Arial, sans-serif; /* 字体 */
text-align: center; /* 文本居中对齐 */
padding: 10px; /* 内边距 */
}
.form-control {
font-family: inherit;
font-size: 15px;
display: block;
width: 100%;
height: calc(2.5rem + 80px);
padding: 0.375rem 0.75rem;
line-height: 1.5;
color: #495057;
background-color: #fff;
border: 1px solid #ced4da;
border-radius: 0.25rem;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.form-control:hover,
.form-control:active,
.form-control:focus {
border-color: #80bdff;
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
.form-control::-webkit-input-placeholder {
color: #999;
}
.form-control::-moz-placeholder {
color: #999;
}
.form-control:-ms-input-placeholder {
color: #999;
}
.form-control::-ms-input-placeholder {
color: #999;
}
.form-control::placeholder {
color: #999;
}
body {
background: url('https://images.unsplash.com/photo-1506408117482-b60ae52a2480?ixid=M3wxMTI1OHwwfDF8cmFuZG9tfHx8fHx8fHx8MTY5MDI2MjgyNHw&ixlib=rb-4.0.3&q=85&w=2640') no-repeat center center fixed;
background-size: cover;
background-color: #f5f5f5;
padding: 20px;
max-width: 1200px;
margin: auto;
//background: #FFF;
border-radius: 15px;
font-size: 16px;
font-family: Consolas, "Courier New", Courier, FreeMono, monospace;
}
h1 {
text-align: center;
font-size: 60px;
margin-bottom: 50px;
}
.text-gradient {
background-image: linear-gradient(to right, #4299e5, #00c458);
-webkit-background-clip: text;
color: transparent;
}
.text-gradient {
animation: gradient-animation 2s linear infinite;
-webkit-background-clip: text;
color: transparent;
}
@keyframes gradient-animation {
from {background-image: linear-gradient(to right, #4299e5, #00c458);}
to {background-image: linear-gradient(to right, #00c458, #4299e5);}
}
#langSwitch {
float: right;
}
textarea {
resize: none;
overflow-y: auto;
line-height: 22px;
min-height: 40px;
max-height: 300px;
padding: 6px 12px;
box-sizing: border-box;
border: 2px solid gray;
border-radius: 4px;
font-size: 16px;
}
.tool {
display: flex;
align-items: flex-end;
justify-content: space-between;
margin-bottom: 10px;
user-select: none;
}
.custom-switch {
display: flex;
align-items: center;
}
.tool input {
margin: 0 8px 0 0;
}
.tool label,
.tool input,
.custom-switch {
cursor: pointer;
}
.btn {
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
margin-top: 10px;
height: 40px;
min-width: 100px;
padding: 0 20px;
box-sizing: border-box;
}
.btn:hover {
opacity: .8;
}
.btn-primary {
background-color: #007bff;
color: white;
}
.btn-plain {
background-color: #FFF;
border: 1px solid transparent;
border-color: #dcdee2;
border-radius: 3px;
line-height: 1.5;
transition: color .2s linear, background-color .2s linear, border .2s linear, box-shadow .2s linear, -webkit-box-shadow .2s linear;
outline: 0;
color: #515a6e;
font-size: 14px;
font-weight: 400;
cursor: pointer;
}
.btn-plain:hover {
color: #57a3f3;
background-color: #fff;
border-color: #57a3f3;
}
.btn-secondary {
background-color: #6c757d;
color: white;
}
.btn-success {
background-color: #28a745;
color: white;
}
.table {
width: 100%;
border-collapse: collapse;
}
.table {
width: 100%;
border-collapse: collapse;
}
.table-responsive {
overflow: auto;
}
.table th,
.table td {
padding: 15px;
border: 1px solid black;
text-align: center;
}
.table th {
background-color: #710f94;
color: white;
font-weight: bold; /* 加粗表头字体 */
}
/* 奇数行淡紫色背景 */
.table-striped tbody tr:nth-of-type(odd) {
background-color: #00b894;
}
/* 偶数行淡粉色背景 */
.table-striped tbody tr:nth-of-type(even) {
background-color: #a45ae4de;
}
label[for="proxySwitch"] {
font-family: "微软雅黑", sans-serif;
color: white;
}
label[for="typeCheckSwitch"] {
font-family: "微软雅黑", sans-serif;
color: white;
}
label[for="totalCheckSwitch"] {
font-family: "微软雅黑", sans-serif;
color: white;
}
label[for="monthlyCheckSwitch"] {
font-family: "微软雅黑", sans-serif;
color: white;
}
label[for="typeCheckSwitch"] {
font-family: "微软雅黑", sans-serif;
color: white;
}
label[for="allCheckSwitch"] {
font-family: "微软雅黑", sans-serif;
color: white;
}
label[for="delinquentCheckSwitch"] {
font-family: "微软雅黑", sans-serif;
color: white;
}
label[for="otherCheckSwitch"] {
font-family: "微软雅黑", sans-serif;
color: white;
}
label[for="deactivatedCheckSwitch"] {
font-family: "微软雅黑", sans-serif;
color: white;
}
#resultTitle{
font-family:"微软雅黑",
sans-serif;color:white;
}
#process{
font-family:"微软雅黑",
sans-serif;color:white;
}
#langSwitch {
cursor: pointer;
}
#langSwitch:hover {
opacity: .6;
}
#purchase {
display: inline-block;
line-height: 40px;
text-decoration: none;
}
#result-tool {
display: flex;
justify-content: space-between;
align-items: center;
height: 40px;
margin-top: 40px;
}
#result-tool_rt {
display: flex;
align-items: center;
justify-content: flex-start;
}
#capture {
margin-left: 6px;
}
#resultTitle {
font-weight: bold;
}
#submit {
margin-right: 8px;
}
</style>
<script>
window.calc = function(els) {
return document.querySelectorAll(els).length;
};
</script></head>
<body>
<div class="contents">
<h1 id="title" class="text-3xl font-semibold text-center mb-8 text-gradient" style="font-size: 45px;text-align: center;">OpenAI API 密钥检查</h1>
<div class="footer">
<footer>
<br>
<p id="ipinfo"></p>
</footer>
</div>
<div class="tool">
<div class="custom-control custom-switch">
<input type="checkbox" id="proxySwitch" checked="checked">
<label for="proxySwitch">使用代理</label>
</div>
<svg t="1684909313939" id="langSwitch" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2392" width="24" height="24">
<path d="M446.857143 616q-0.571429 1.714286-7.142857 2.857143t-18-6.571429l-11.428571-5.142857q-25.142857-11.428571-49.714286-28-4-2.857143-23.428571-18t-21.714286-16.285714q-38.285714 58.857143-76.571429 103.428571-46.285714 54.285714-60 62.857143-2.285714 1.142857-11.142857 2.285714t-10.571429 0q3.428571-2.285714 46.857143-52.571429 12-13.714286 48.857143-65.714286t44.857143-67.428571q9.714286-17.142857 29.142857-56.285714t20.571429-44.285714q-4.571429-0.571429-62.857143 18.857143-4.571429 1.142857-15.714286 4.285714t-19.714286 5.428571-9.714286 2.857143q-1.142857 1.142857-1.142857 6t-0.571429 5.428571q-2.857143 5.714286-17.714286 8.571429-13.142857 4-26.857143 0-10.285714-2.285714-16-12-2.285714-3.428571-2.857143-13.142857 3.428571-1.142857 14-2.857143t16.857143-3.428571q33.142857-9.142857 60-18.285714 57.142857-20 58.285714-20 5.714286-1.142857 24.571429-11.142857t25.142857-12.285714q5.142857-1.714286 12.285714-4.571429t8.285714-3.142857 3.428571 2.857143q1.142857 6.857143-0.571429 18.857143 0 1.142857-7.142857 15.428571t-15.142857 30.571429-9.714286 19.142857q-14.285714 28.571429-44 74.857143l36.571429 16q6.857143 3.428571 42.571429 18.285714t38.571429 16q2.285714 0.571429 6 14.571429t2.571429 17.428571zm-117.142857-277.714286q1.714286 8.571429-2.285714 16-6.857143 13.142857-28.571429 21.714286-17.142857 6.857143-34.285714 6.857143-14.857143-1.714286-28-14.857143-8-8.571429-10.285714-23.428571l0.571429-1.714286q1.714286 1.714286 11.142857 2.857143t15.142857 0 33.142857-9.142857q20.571429-6.857143 31.428571-8 9.714286 0 12 9.714286zm398.857143 73.714286l36 129.714286-79.428571-24zm-633.142857 457.142857l396.571429-132.571429 0-589.714286-396.571429 133.142857 0 589.142857zm709.142857-181.142857l58.285714 17.714286-103.428571-375.428571-57.142857-17.714286-123.428571 306.285714 58.285714 17.714286 25.714286-62.857143 120.571429 37.142857zm-287.428571-549.714286l327.428571 105.142857 0-217.142857zm177.714286 756l90.285714 7.428571-30.857143 91.428571-22.857143-37.714286q-74.285714 47.428571-157.714286 61.714286-33.142857 6.857143-52 6.857143l-48 0q-45.142857 0-114-22.285714t-104.857143-48.571429q-4.571429-4-4.571429-9.142857 0-4.571429 2.857143-7.714286t7.428571-3.142857q2.285714 0 10.285714 4.285714t17.428571 9.428571 11.714286 6.285714q41.714286 21.142857 91.142857 35.142857t90 14q54.285714 0 95.428571-8.285714t89.714286-28.857143q8.571429-4 17.428571-8.857143t19.428571-10.857143 16.285714-9.428571zm256-616.571429l0 616.571429-442.285714-140.571429q-8 3.428571-214.285714 72.857143t-210.285714 69.428571q-7.428571 0-10.285714-7.428571 0-0.571429-0.571429-1.714286l0-616q1.714286-5.142857 2.285714-5.714286 2.857143-3.428571 11.428571-6.285714 60.571429-20 85.142857-28.571429l0-219.428571 318.857143 113.142857q1.142857 0 91.714286-31.428571t180.571429-62 92.285714-30.571429q11.428571 0 11.428571 12l0 238.857143z" p-id="2393"></path>
</svg>
</div>
<textarea id="keys" style="width:100%" rows="1" autocomplete="on" autofocus="" placeholder="每行一个(格式:账号----密码----密钥,支持分隔符:“----” “,” “;” “|”)"></textarea>
<br>
<button id="submit" class="btn btn-primary">检查</button>
<div id="result-tool">
<div class="result-tool_lt">
<span id="resultTitle">结果:</span>
<span id="process">0/0</span>
</div>
<div id="result-tool_rt">
<div class="check-box">
<input type="checkbox" id="allCheckSwitch" checked="checked">
<label for="allCheckSwitch">全部</label>
</div>
<div class="check-box">
<input type="checkbox" id="typeCheckSwitch" checked="checked">
<label for="typeCheckSwitch">类型</label>
</div>
<div class="check-box">
<input type="checkbox" id="totalCheckSwitch" checked="checked">
<label for="totalCheckSwitch">总使用量</label>
</div>
<div class="check-box">
<input type="checkbox" id="monthlyCheckSwitch" checked="checked">
<label for="monthlyCheckSwitch">当月用量</label>
</div>
<div class="check-box">
<input type="checkbox" id="delinquentCheckSwitch" checked="checked">
<label for="delinquentCheckSwitch">欠费</label>
</div>
<div class="check-box">
<input type="checkbox" id="deactivatedCheckSwitch" checked="checked">
<label for="deactivatedCheckSwitch">被封</label>
</div>
<div class="check-box">
<input type="checkbox" id="otherCheckSwitch" checked="checked">
<label for="otherCheckSwitch">其它</label>
</div>
<button id="download" class="btn-plain">下载</button>
<button id="capture" class="btn-plain">保存截图</button>
</div>
</div>
<div class="table-responsive">
<table id="result" class="table table-striped">
<thead>
<tr>
<th id="keyHeader">序号</th>
<th>Key</th>
<th id="typeHeader">类型</th>
<th id="totalHeader">总使用量</th>
<th id="usageHeader">当月用量</th>
<th id="balanceHeader">总额度</th>
<th id="delinquentHeader">欠费</th>
<th id="deactivatedHeader">被封</th>
<th id="expiresHeader">有效期</th>
</tr>
</thead>
<tbody id="resultBody">
</tbody>
</table>
</div>
</div>
<script src="OpenAI%20API%20Key%20Check2_files/html2canvas.min.js"></script>
<script>const CONCURRENT_LIMIT=3,KEY_REG=/sk-[a-zA-Z0-9]{48}/,SESS_REG=/sess-[a-zA-Z0-9]{40}/,$=e=>document.querySelector(e),_isEn=localStorage.getItem("isEn");let isEn=null===_isEn||JSON.parse(_isEn),results=[],keyCounter=0,validKeys=[],invalidKeys=[],keyQueue=[],activeRequests=0,total=0,count=0,checking=!1,controllers=[],cancel=!1,typeCheck=!0,totalCheck=!0,monthlyCheck=!0,allCheck=!0,otherCheck=!0,delinquentCheck=!0,deactivatedCheck=!0;function onCheckBoxChange(e){const t=this.querySelector("input");switch(t.id){case"allCheckSwitch":onAllCheckChange(t);break;case"typeCheckSwitch":onTypeCheckChange(t);break;case"totalCheckSwitch":onTotalCheckChange(t);break;case"monthlyCheckSwitch":onMonthCheckChange(t);break;case"delinquentCheckSwitch":onDelinquentCheckChange(t);break;case"deactivatedCheckSwitch":onDeactivatedCheckChange(t);break;case"otherCheckSwitch":onOtherCheckChange(t)}}function isAllCheck(){allCheck=typeCheck&&totalCheck&&monthlyCheck&&otherCheck&&deactivatedCheck&&delinquentCheck,$("#allCheckSwitch").checked=allCheck}function onAllCheckChange(e){allCheck=typeCheck=totalCheck=monthlyCheck=delinquentCheck=deactivatedCheck=otherCheck=e.checked,$("#typeCheckSwitch").checked=allCheck,$("#totalCheckSwitch").checked=allCheck,$("#monthlyCheckSwitch").checked=allCheck,$("#otherCheckSwitch").checked=allCheck,$("#delinquentCheckSwitch").checked=allCheck,$("#deactivatedCheckSwitch").checked=allCheck}function onTypeCheckChange(e){typeCheck=e.checked,isAllCheck()}function onTotalCheckChange(e){totalCheck=e.checked,isAllCheck()}function onMonthCheckChange(e){monthlyCheck=e.checked,isAllCheck()}function onDelinquentCheckChange(e){delinquentCheck=e.checked,isAllCheck()}function onDeactivatedCheckChange(e){deactivatedCheck=e.checked,isAllCheck()}function onOtherCheckChange(e){otherCheck=e.checked,isAllCheck()}function formatDate(e,t){const n={"Y+":e.getFullYear().toString(),"m+":(e.getMonth()+1).toString(),"d+":e.getDate().toString(),"H+":e.getHours().toString(),"M+":e.getMinutes().toString(),"S+":e.getSeconds().toString()};for(let e in n){const a=new RegExp("("+e+")").exec(t);a&&(t=t.replace(a[1],1==a[1].length?n[e]:n[e].padStart(a[1].length,"0")))}return t}async function startKeyCheck(){if(checking)return cancel=!0,void controllers.forEach((e=>e.abort()));const e=$("#keys").value.split("\n").filter((e=>""!==e.trim()&&(e.match(KEY_REG)||e.match(SESS_REG))));if(total=e.length,count=0,keyCounter=0,validKeys=[],invalidKeys=[],results=[],$("#resultBody").innerHTML="",!e[0])return $("#resultBody").innerHTML=`<tr><td colspan="9" class="text-center">${isEn?"No results":"暂无查询结果"}</td></tr>`,void alert(isEn?"Invalid Key":"无效 Key");checking=!0,$("#submit").innerHTML=isEn?"Cancel":"取消",keyQueue=[...e];let t=e.length>3?3:e.length;for(let e=0;e<t;e++)await processNextKey();checking=!1,cancel=!1,$("#submit").innerHTML=isEn?"Check":"检查"}async function processNextKey(){if(!cancel&&keyQueue.length){activeRequests++;let e=keyQueue.shift(),t=await fetchUsageAndBalance(e);count++,$("#process").innerHTML=`${count}/${total}`,results.push(t),addResultToTable(t),await processNextKey()}}async function fetchUsageAndBalance(e){let t="----",n=e.split(t);-1!==e.indexOf(",")&&(t=",",n=e.split(t)),-1!==e.indexOf(";")&&(t=";",n=e.split(t)),-1!==e.indexOf("|")&&(t="|",n=e.split(t));let a="",o="";const c=e.match(KEY_REG),l=e.match(SESS_REG);c&&(o=c[0]),l&&(a=l[0]);const i=$("#proxySwitch").checked?"https://api.unchatgp.com":"https://api.openai.com",s=`${i}/dashboard/billing/usage`,r=`${i}/dashboard/billing/subscription`,d=`${i}/dashboard/rate_limits`,h=`${i}/dashboard/billing/invoices?system=api`,u=`${i}/v1/images/generations`;let k=o.replace(/^(.{7}).*(.{4})$/,"$1********$2");a&&(k=a.replace(/^(.{7}).*(.{4})$/,"$1********$2"));try{let c=null,l=null,i=null,C=null,g=!1,y="--",$=!1;if(deactivatedCheck){const e={method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+(a||o)}},t=new AbortController;controllers.push(t);const n=await fetch(u,{signal:t.signal,...e}),{error:c}=await n.json();if($="account_deactivated"===c.code,activeRequests--,$)return{key:k,deactivated:$}}if(otherCheck||typeCheck||totalCheck||monthlyCheck||delinquentCheck){if(!a){const e=new AbortController;controllers.push(e);const t=await fetch(`https://vipapi.iuai.cc/get_session_key?email=${n[0]}&password=${n[1]}`,{signal:e.signal}),{session_key:o}=await t.json();a=o}const e={headers:{"Content-Type":"application/json",Authorization:"Bearer "+a}};if(delinquentCheck){const t=new AbortController;controllers.push(t);const n=await fetch(h,{signal:t.signal,...e}).catch((e=>console.log(e))),{data:a}=await n.json();if(a.length){const e=a.reduce(((e,t)=>"uncollectible"===t.status?e+t.total:0),0)/100;e>0&&(l=e.toFixed(2))}}const t=864e5,u=new Date,$=formatDate(new Date(Date.now()+t),"YYYY-mm-dd");if(otherCheck){const t=new AbortController;controllers.push(t);const n=await fetch(r,{signal:t.signal,...e}).catch((e=>console.log(e)));c=await n.json()}if(monthlyCheck){const t=new Date(u.getFullYear(),u.getMonth(),1),n=new AbortController;controllers.push(n);const a=formatDate(t,"YYYY-mm-dd"),o=await fetch(`${s}?start_date=${a}&end_date=${$}`,{signal:n.signal,...e});i=await o.json()}if(totalCheck){const n=formatDate(new Date(Date.now()-90*t),"YYYY-mm-dd"),a=new AbortController;controllers.push(a);const o=await fetch(`${s}?start_date=${n}&end_date=${$}`,{signal:a.signal,...e});C=await o.json()}if(typeCheck){const t=new AbortController;controllers.push(t);const n=await fetch(d,{signal:t.signal,...e}),a=await n.json();a.error||(g=a["gpt-4"]||a["gpt-4-32k"],y=g?"GPT-4":"GPT-3.5")}if(g&&console.log("GPT-4:",o),c&&c.error)return console.warn(c.error.message),activeRequests--,{key:k};activeRequests--}return{type:y,sign:t,sess_key:a,deactivated:$,origin:e,key:k,delinquentTotal:l,total:totalCheck&&!C.error?`$${(C.total_usage/100).toFixed(2)}`:"--",usage:monthlyCheck&&!i.error?`$${(i.total_usage/100).toFixed(2)}`:"--",balance:otherCheck&&!c.error?Math.round(c.hard_limit_usd):-1,delinquent:otherCheck?c.delinquent:"--",expires:otherCheck?formatDate(new Date(1e3*c.access_until),"YYYY/mm/dd"):"--"}}catch(e){return console.warn(`Failed to fetch data for key ${o}`,e),activeRequests--,{key:k}}}function addResultToTable(e){const t=({delinquent:e,delinquentTotal:t})=>delinquentCheck?t?`$${t}`:isEn?"No":"否":"--"===e?e:e?isEn?"Yes":"是":isEn?"No":"否",n=({deactivated:e})=>e?isEn?"Yes":"是":isEn?"No":"否";if(e.deactivated||otherCheck&&-1===e.balance||totalCheck&&"--"===e.total||monthlyCheck&&"--"===e.usage||typeCheck&&"--"===e.type||isNaN(e.balance)){keyCounter++;let t="";t=e.deactivated?`<tr style="background-color: #efbbbb;"><td>${keyCounter}</td><td>${e.key}</td><td>--</td><td>--</td><td>--</td><td>--</td><td>--</td><td>${n(e)}</td><td>--</td></tr>`:`<tr style="background-color:${cancel?"rgb(232 172 71 / 41%)":"#efbbbb"};"><td>${keyCounter}</td><td>${e.key}</td><td colspan="7">${cancel?isEn?"Query cancelled":"已取消查询":isEn?"Invalid Key":"无效 Key"}</td></tr>`,$("#resultBody").innerHTML+=t}else if(e.deactivated||otherCheck&&!(e.balance>0))invalidKeys.push(e);else{validKeys.push(e),keyCounter++;let a=`<tr style="${delinquentCheck&&null!==e.delinquentTotal&&e.delinquent?"background-color:rgb(239 216 187 / 43%)":""}"><td>${keyCounter}</td><td>${e.key}</td><td>${e.type}</td><td>${e.total}</td><td>${e.usage}</td><td>${otherCheck?"$"+e.balance:"--"}</td><td>${t(e)}</td><td>${n(e)}</td><td>${e.expires}</td></tr>`;$("#resultBody").innerHTML+=a}0===keyQueue.length&&0===activeRequests&&invalidKeys.forEach(((a,o)=>{keyCounter++;let c="";delinquentCheck&&null!==e.delinquentTotal&&e.delinquent&&(c="background-color:rgb(239 216 187 / 43%)"),e.deactivated&&(c="background-color:#efbbbb");let l=`<tr style="${c}"><td>${keyCounter}</td><td>${a.key}</td><td>${a.type}</td><td>${a.total}</td><td>${a.usage}</td><td>${otherCheck?"$"+a.balance:"--"}</td><td>${t(a)}</td><td>${n(e)}</td><td>${a.expires}</td></tr>`;$("#resultBody").innerHTML+=l}))}function switchLanguage(){isEn=!isEn,updateLanguageTexts(),localStorage.setItem("isEn",isEn)}function downloadKeys(){const e=({origin:e,sign:t,sess_key:n})=>-1!==e.indexOf("sess-")?e:e+t+n,t=validKeys.map(e).join("\n"),n=invalidKeys.map(e).join("\n");if(""===t.trim()&&""===n.trim())return void alert(isEn?"There is no downloadable content":"没有可下载内容");const a=formatDate(new Date,"YYYYmmdd");t&&downloadFile(`valid_${validKeys.length}_${a}.txt`,t),n&&downloadFile(`invalid_${invalidKeys.length}_${a}.txt`,n)}function downloadFile(e,t){let n=t.split("\n").map((e=>e.trim())).join("\n"),a=document.createElement("a");a.setAttribute("href","data:text/plain;charset=utf-8,"+encodeURIComponent(n)),a.setAttribute("download",e),a.style.display="none",document.body.appendChild(a),a.click(),document.body.removeChild(a)}function updateLanguageTexts(){$("#title").textContent=isEn?"OpenAI API Key Check":"OpenAI API 密钥检查",$("#keys").setAttribute("placeholder",isEn?'One per line(Format: Account----Password----Key, Support for separators: "----" "," ";" "|")':"每行一个(格式:账号----密码----密钥,支持分隔符:“----” “,” “;” “|”)"),$("#submit").textContent=isEn?"Check":"检查",$("#resultTitle").textContent=isEn?"Results:":"结果:",$("#keyHeader").textContent=isEn?"No.":"序号",$("#typeHeader").textContent=isEn?"Type":"类型",$("#totalHeader").textContent=isEn?"Total Usage":"总使用量",$("#usageHeader").textContent=isEn?" Monthly Usage":"当月用量",$("#balanceHeader").textContent=isEn?"Credit":"总额度",$("#delinquentHeader").textContent=isEn?"Delinquent":"欠费",$("#deactivatedHeader").textContent=isEn?"Blocked":"被封",$("#expiresHeader").textContent=isEn?"Expires":"有效期",$("#proxySwitch").nextElementSibling.textContent=isEn?"Use Proxy":"使用代理",$("#download").textContent=isEn?"Download":"下载",$("#capture").textContent=isEn?"Save Capture":"保存截图",$('label[for="allCheckSwitch"]').textContent=isEn?"All":"全部",$('label[for="typeCheckSwitch"]').textContent=isEn?"Type":"类型",$('label[for="totalCheckSwitch"]').textContent=isEn?"TotalUsage":"总使用量",$('label[for="monthlyCheckSwitch"]').textContent=isEn?"MonthlyUsage":"当月用量",$('label[for="delinquentCheckSwitch"]').textContent=isEn?"Delinquent":"欠费",$('label[for="deactivatedCheckSwitch"]').textContent=isEn?"Blocked":"被封",$('label[for="otherCheckSwitch"]').textContent=isEn?"Other":"其它"}function saveImage(){total<=0?alert(isEn?"No content to display in screenshot":"无查询内容可截图"):(document.documentElement.scrollTop=0,document.body.scrollTop=0,html2canvas($("#result")).then((e=>{let t=document.createElement("a");t.href=e.toDataURL("image/jpeg").replace("image/jpeg","image/octet-stream"),t.download=`openai_key_${total}_${formatDate(new Date,"YYYYmmdd")}.jpg`,t.click()})))}window.onload=function(){updateLanguageTexts(),$("#keys").addEventListener("input",(function(){this.style.height="auto",this.style.height=this.scrollHeight+"px"})),$("#keys").addEventListener("keydown",(function(e){const t=e.shiftKey,n="Enter"===e.key;if(t&&n){const t=this.value,n=this.selectionStart,a=t.substring(0,n)+"\n"+t.substring(n);return this.value=a,e.preventDefault(),this.style.height="auto",void(this.style.height=this.scrollHeight+"px")}"Enter"===e.key&&(e.preventDefault(),startKeyCheck())})),$("#submit").addEventListener("click",startKeyCheck),$("#langSwitch").addEventListener("click",switchLanguage),$("#download").addEventListener("click",downloadKeys),$("#capture").addEventListener("click",saveImage),document.querySelectorAll(".check-box").forEach((e=>{e.addEventListener("click",onCheckBoxChange)}))}</script>
<script>
function getIpInfo() {
fetch('https://forge.speedtest.cn/api/location/info')
.then(res => res.json())
.then(res => {
document.getElementById('ipinfo').textContent = `当前IP: ${res.ip} (${res.province} ${res.city} ${res.distinct} ${res.isp}) `;
})
.catch(err => {
console.log(err);
});
}
getIpInfo();
</script>
</body></html>