| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007 | 
							- <!DOCTYPE html>
 
- <html lang="en">
 
- {{template "head" .}}
 
- <style>
 
-     @media (min-width: 769px) {
 
-         .ant-layout-content {
 
-             margin: 24px 16px;
 
-         }
 
-     }
 
-     .ant-col-sm-24 {
 
-         margin-top: 10px;
 
-     }
 
- </style>
 
- <body>
 
- <a-layout id="app" v-cloak>
 
-     {{ template "commonSider" . }}
 
-     <a-layout id="content-layout" :style="themeSwitcher.bgStyle">
 
-         <a-layout-content>
 
-             <a-spin :spinning="spinning" :delay="500" tip="loading">
 
-                 <transition name="list" appear>
 
-                     <a-tag v-if="false" color="red" style="margin-bottom: 10px">
 
-                         Please go to the panel settings as soon as possible to modify the username and password, otherwise there may be a risk of leaking account information
 
-                     </a-tag>
 
-                 </transition>
 
-                 <transition name="list" appear>
 
-                     <a-card hoverable style="margin-bottom: 20px;" :class="themeSwitcher.darkCardClass">
 
-                         <a-row>
 
-                             <a-col :xs="24" :sm="24" :lg="12">
 
-                                 {{ i18n "pages.inbounds.totalDownUp" }}:
 
-                                 <a-tag color="green">[[ sizeFormat(total.up) ]] / [[ sizeFormat(total.down) ]]</a-tag>
 
-                             </a-col>
 
-                             <a-col :xs="24" :sm="24" :lg="12">
 
-                                 {{ i18n "pages.inbounds.totalUsage" }}:
 
-                                 <a-tag color="green">[[ sizeFormat(total.up + total.down) ]]</a-tag>
 
-                             </a-col>
 
-                             <a-col :xs="24" :sm="24" :lg="12">
 
-                                 {{ i18n "pages.inbounds.inboundCount" }}:
 
-                                 <a-tag color="green">[[ dbInbounds.length ]]</a-tag>
 
-                             </a-col>
 
-                             <a-col :xs="24" :sm="24" :lg="12">
 
-                                 {{ i18n "clients" }}:
 
-                                 <a-tag color="green">[[ total.clients ]]</a-tag>
 
-                                 <a-popover title='{{ i18n "disabled" }}' :overlay-class-name="themeSwitcher.darkClass">
 
-                                     <template slot="content">
 
-                                         <p v-for="clientEmail in total.deactive">[[ clientEmail ]]</p>
 
-                                     </template>
 
-                                     <a-tag v-if="total.deactive.length">[[ total.deactive.length ]]</a-tag>
 
-                                 </a-popover>
 
-                                 <a-popover title='{{ i18n "depleted" }}' :overlay-class-name="themeSwitcher.darkClass">
 
-                                     <template slot="content">
 
-                                         <p v-for="clientEmail in total.depleted">[[ clientEmail ]]</p>
 
-                                     </template>
 
-                                     <a-tag color="red" v-if="total.depleted.length">[[ total.depleted.length ]]</a-tag>
 
-                                 </a-popover>
 
-                                 <a-popover title='{{ i18n "depletingSoon" }}' :overlay-class-name="themeSwitcher.darkClass">
 
-                                     <template slot="content">
 
-                                         <p v-for="clientEmail in total.expiring">[[ clientEmail ]]</p>
 
-                                     </template>
 
-                                     <a-tag color="orange" v-if="total.expiring.length">[[ total.expiring.length ]]</a-tag>
 
-                                 </a-popover>
 
-                             </a-col>
 
-                         </a-row>
 
-                     </a-card>
 
-                 </transition>
 
-                 <transition name="list" appear>
 
-                     <a-card hoverable :class="themeSwitcher.darkCardClass">
 
-                         <div slot="title">
 
-                             <a-row>
 
-                                 <a-col :xs="24" :sm="24" :lg="12">
 
-                                     <a-button type="primary" icon="plus" @click="openAddInbound">{{ i18n "pages.inbounds.addInbound" }}</a-button>
 
-                                     <a-dropdown :trigger="['click']">
 
-                                         <a-button type="primary" icon="menu">{{ i18n "pages.inbounds.generalActions" }}</a-button>
 
-                                         <a-menu slot="overlay" @click="a => generalActions(a)" :theme="themeSwitcher.currentTheme">
 
-                                             <a-menu-item key="export">
 
-                                                 <a-icon type="export"></a-icon>
 
-                                                 {{ i18n "pages.inbounds.export" }}
 
-                                             </a-menu-item>
 
-                                             <a-menu-item key="resetInbounds">
 
-                                                 <a-icon type="reload"></a-icon>
 
-                                                 {{ i18n "pages.inbounds.resetAllTraffic" }}
 
-                                             </a-menu-item>
 
-                                             <a-menu-item key="resetClients">
 
-                                                 <a-icon type="file-done"></a-icon>
 
-                                                 {{ i18n "pages.inbounds.resetAllClientTraffics" }}
 
-                                             </a-menu-item>
 
-                                             <a-menu-item key="delDepletedClients">
 
-                                                 <a-icon type="rest"></a-icon>
 
-                                                 {{ i18n "pages.inbounds.delDepletedClients" }}
 
-                                             </a-menu-item>
 
-                                         </a-menu>
 
-                                     </a-dropdown>
 
-                                 </a-col>
 
-                                 <a-col :xs="24" :sm="24" :lg="12" style="text-align: right;">
 
-                                     <a-select v-model="refreshInterval"
 
-                                               style="width: 65px;"
 
-                                               v-if="isRefreshEnabled"
 
-                                               @change="changeRefreshInterval"
 
-                                               :dropdown-class-name="themeSwitcher.darkCardClass">
 
-                                         <a-select-option v-for="key in [5,10,30,60]" :value="key*1000">[[ key ]]s</a-select-option>
 
-                                     </a-select>
 
-                                     <a-icon type="sync" :spin="refreshing" @click="manualRefresh" style="margin: 0 5px;"></a-icon>
 
-                                     <a-switch v-model="isRefreshEnabled" @change="toggleRefresh"></a-switch>
 
-                                 </a-col>
 
-                             </a-row>
 
-                         </div>
 
-                         <a-switch v-model="enableFilter"
 
-                             checked-children='{{ i18n "search" }}' un-checked-children='{{ i18n "filter" }}'
 
-                             @change="toggleFilter" style="margin-right: 10px;">
 
-                         </a-switch>
 
-                         <a-input v-if="!enableFilter" v-model.lazy="searchKey" placeholder='{{ i18n "search" }}' autofocus style="max-width: 300px"></a-input>
 
-                         <a-radio-group v-if="enableFilter" v-model="filterBy" @change="filterInbounds" button-style="solid">
 
-                             <a-radio-button value="">{{ i18n "none" }}</a-radio-button>
 
-                             <a-radio-button value="deactive">{{ i18n "disabled" }}</a-radio-button>
 
-                             <a-radio-button value="depleted">{{ i18n "depleted" }}</a-radio-button>
 
-                             <a-radio-button value="expiring">{{ i18n "depletingSoon" }}</a-radio-button>
 
-                         </a-radio-group>
 
-                         <a-table :columns="columns" :row-key="dbInbound => dbInbound.id"
 
-                                  :data-source="searchedInbounds"
 
-                                  :loading="spinning" :scroll="{ x: 1300 }"
 
-                                  :pagination="false"
 
-                                  style="margin-top: 20px"
 
-                                  @change="() => getDBInbounds()">
 
-                             <template slot="action" slot-scope="text, dbInbound">
 
-                                 <a-icon type="edit" style="font-size: 22px" @click="openEditInbound(dbInbound.id);"></a-icon>
 
-                                 <a-dropdown :trigger="['click']">
 
-                                     <a @click="e => e.preventDefault()">{{ i18n "pages.inbounds.operate" }}</a>
 
-                                     <a-menu slot="overlay" @click="a => clickAction(a, dbInbound)" :theme="themeSwitcher.currentTheme">
 
-                                         <a-menu-item key="edit">
 
-                                             <a-icon type="edit"></a-icon>
 
-                                             {{ i18n "edit" }}
 
-                                         </a-menu-item>
 
-                                         <a-menu-item key="qrcode" v-if="dbInbound.isSS && !dbInbound.toInbound().isSSMultiUser">
 
-                                             <a-icon type="qrcode"></a-icon>
 
-                                             {{ i18n "qrCode" }}
 
-                                         </a-menu-item>
 
-                                         <template v-if="dbInbound.isTrojan || dbInbound.isVLess || dbInbound.isVMess || dbInbound.toInbound().isSSMultiUser">
 
-                                             <a-menu-item key="addClient">
 
-                                                 <a-icon type="user-add"></a-icon>
 
-                                                 {{ i18n "pages.client.add"}}
 
-                                             </a-menu-item>
 
-                                             <a-menu-item key="addBulkClient">
 
-                                                 <a-icon type="usergroup-add"></a-icon>
 
-                                                 {{ i18n "pages.client.bulk"}}
 
-                                             </a-menu-item>
 
-                                             <a-menu-item key="resetClients">
 
-                                                 <a-icon type="file-done"></a-icon>
 
-                                                 {{ i18n "pages.inbounds.resetInboundClientTraffics"}}
 
-                                             </a-menu-item>
 
-                                             <a-menu-item key="export">
 
-                                                 <a-icon type="export"></a-icon>
 
-                                                 {{ i18n "pages.inbounds.export"}}
 
-                                             </a-menu-item>
 
-                                             <a-menu-item key="delDepletedClients">
 
-                                                 <a-icon type="rest"></a-icon>
 
-                                                 {{ i18n "pages.inbounds.delDepletedClients" }}
 
-                                             </a-menu-item>
 
-                                         </template>
 
-                                         <template v-else>
 
-                                             <a-menu-item key="showInfo">
 
-                                                 <a-icon type="info-circle"></a-icon>
 
-                                                 {{ i18n "info"}}
 
-                                             </a-menu-item>
 
-                                         </template>
 
-                                         <a-menu-item key="resetTraffic">
 
-                                             <a-icon type="retweet"></a-icon> {{ i18n "pages.inbounds.resetTraffic" }}
 
-                                         </a-menu-item>
 
-                                         <a-menu-item key="clone">
 
-                                             <a-icon type="block"></a-icon> {{ i18n "pages.inbounds.clone"}}
 
-                                         </a-menu-item>
 
-                                         <a-menu-item key="delete">
 
-                                             <span style="color: #FF4D4F">
 
-                                                 <a-icon type="delete"></a-icon> {{ i18n "delete"}}
 
-                                             </span>
 
-                                         </a-menu-item>
 
-                                     </a-menu>
 
-                                 </a-dropdown>
 
-                             </template>
 
-                             <template slot="protocol" slot-scope="text, dbInbound">
 
-                                 <a-tag style="margin:0;" color="blue">[[ dbInbound.protocol ]]</a-tag>
 
-                                 <template v-if="dbInbound.isVMess || dbInbound.isVLess || dbInbound.isTrojan || dbInbound.isSS">
 
-                                     <a-tag style="margin:0;" color="green">[[ dbInbound.toInbound().stream.network ]]</a-tag>
 
-                                     <a-tag style="margin:0;" v-if="dbInbound.toInbound().stream.isTls" color="cyan">TLS</a-tag>
 
-                                     <a-tag style="margin:0;" v-if="dbInbound.toInbound().stream.isXtls" color="cyan">XTLS</a-tag>
 
-                                     <a-tag style="margin:0;" v-if="dbInbound.toInbound().stream.isReality" color="cyan">Reality</a-tag>
 
-                                 </template>
 
-                             </template>
 
-                             <template slot="clients" slot-scope="text, dbInbound">
 
-                                 <template v-if="clientCount[dbInbound.id]">
 
-                                     <a-tag style="margin:0;" color="green">[[ clientCount[dbInbound.id].clients ]]</a-tag>
 
-                                     <a-popover title='{{ i18n "disabled" }}' :overlay-class-name="themeSwitcher.darkClass">
 
-                                         <template slot="content">
 
-                                             <p v-for="clientEmail in clientCount[dbInbound.id].deactive">[[ clientEmail ]]</p>
 
-                                         </template>
 
-                                         <a-tag style="margin:0; padding: 0 2px;" v-if="clientCount[dbInbound.id].deactive.length">[[ clientCount[dbInbound.id].deactive.length ]]</a-tag>
 
-                                     </a-popover>
 
-                                     <a-popover title='{{ i18n "depleted" }}' :overlay-class-name="themeSwitcher.darkClass">
 
-                                         <template slot="content">
 
-                                             <p v-for="clientEmail in clientCount[dbInbound.id].depleted">[[ clientEmail ]]</p>
 
-                                         </template>
 
-                                         <a-tag style="margin:0; padding: 0 2px;" color="red" v-if="clientCount[dbInbound.id].depleted.length">[[ clientCount[dbInbound.id].depleted.length ]]</a-tag>
 
-                                     </a-popover>
 
-                                     <a-popover title='{{ i18n "depletingSoon" }}' :overlay-class-name="themeSwitcher.darkClass">
 
-                                         <template slot="content">
 
-                                             <p v-for="clientEmail in clientCount[dbInbound.id].expiring">[[ clientEmail ]]</p>
 
-                                         </template>
 
-                                         <a-tag style="margin:0; padding: 0 2px;" color="orange" v-if="clientCount[dbInbound.id].expiring.length">[[ clientCount[dbInbound.id].expiring.length ]]</a-tag>
 
-                                     </a-popover>
 
-                                 </template>
 
-                             </template>
 
-                             <template slot="traffic" slot-scope="text, dbInbound">
 
-                                 <a-popover :overlay-class-name="themeSwitcher.darkClass">
 
-                                     <template slot="content">
 
-                                         <table cellpadding="2" width="100%">
 
-                                             <tr>
 
-                                                 <td>↑[[ sizeFormat(dbInbound.up) ]]</td>
 
-                                                 <td>↓[[ sizeFormat(dbInbound.down) ]]</td>
 
-                                             </tr>
 
-                                             <tr v-if="dbInbound.total > 0 &&  dbInbound.up + dbInbound.down < dbInbound.total">
 
-                                                 <td>{{ i18n "remained" }}</td>
 
-                                                 <td>[[ sizeFormat(dbInbound.total - dbInbound.up - dbInbound.down) ]]</td>
 
-                                             </tr>
 
-                                         </table>
 
-                                     </template>
 
-                                     <a-tag :color="dbInbound.total == 0 ? 'green' : dbInbound.up + dbInbound.down < dbInbound.total ? 'cyan' : 'red'">
 
-                                         [[ sizeFormat(dbInbound.up + dbInbound.down) ]] /
 
-                                         <template v-if="dbInbound.total > 0">
 
-                                             [[ sizeFormat(dbInbound.total) ]]
 
-                                         </template>
 
-                                         <template v-else>
 
-                                             <svg style="fill: currentColor; height: 10px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M484.4 96C407 96 349.2 164.1 320 208.5C290.8 164.1 233 96 155.6 96C69.75 96 0 167.8 0 256s69.75 160 155.6 160C233.1 416 290.8 347.9 320 303.5C349.2 347.9 407 416 484.4 416C570.3 416 640 344.2 640 256S570.3 96 484.4 96zM155.6 368C96.25 368 48 317.8 48 256s48.25-112 107.6-112c67.75 0 120.5 82.25 137.1 112C276 285.8 223.4 368 155.6 368zM484.4 368c-67.75 0-120.5-82.25-137.1-112C364 226.2 416.6 144 484.4 144C543.8 144 592 194.2 592 256S543.8 368 484.4 368z"/></svg>
 
-                                         </template>
 
-                                     </a-tag>
 
-                                 </a-popover>
 
-                             </template>
 
-                             <template slot="enable" slot-scope="text, dbInbound">
 
-                                 <a-switch v-model="dbInbound.enable" @change="switchEnable(dbInbound.id)"></a-switch>
 
-                             </template>
 
-                             <template slot="expiryTime" slot-scope="text, dbInbound">
 
-                                 <template v-if="dbInbound.expiryTime > 0">
 
-                                     <a-tag v-if="dbInbound.isExpiry" color="red">
 
-                                         [[ DateUtil.formatMillis(dbInbound.expiryTime) ]]
 
-                                     </a-tag>
 
-                                     <a-tag v-else color="blue">
 
-                                         [[ DateUtil.formatMillis(dbInbound.expiryTime) ]]
 
-                                     </a-tag>
 
-                                 </template>
 
-                                 <a-tag v-else color="green">{{ i18n "indefinite" }}</a-tag>
 
-                             </template>
 
-                             <template slot="expandedRowRender" slot-scope="record">
 
-                                 <a-table
 
-                                 v-if="(record.protocol === Protocols.VLESS) || (record.protocol === Protocols.VMESS)"
 
-                                 :row-key="client => client.id"
 
-                                 :columns="innerColumns"
 
-                                 :data-source="getInboundClients(record)"
 
-                                 :pagination="false"
 
-                                 >
 
-                                     {{template "client_table"}}
 
-                                 </a-table>
 
-                                 <a-table
 
-                                 v-else-if="record.protocol === Protocols.TROJAN || record.toInbound().isSSMultiUser"
 
-                                 :row-key="client => client.id"
 
-                                 :columns="innerTrojanColumns"
 
-                                 :data-source="getInboundClients(record)"
 
-                                 :pagination="false"
 
-                                 >
 
-                                     {{template "client_table"}}
 
-                                 </a-table>
 
-                             </template>
 
-                         </a-table>
 
-                     </a-card>
 
-                 </transition>
 
-             </a-spin>
 
-         </a-layout-content>
 
-     </a-layout>
 
- </a-layout>
 
- {{template "js" .}}
 
- {{template "component/themeSwitcher" .}}
 
- <script>
 
-     const columns = [{
 
-         title: '{{ i18n "pages.inbounds.operate" }}',
 
-         align: 'center',
 
-         width: 60,
 
-         scopedSlots: { customRender: 'action' },
 
-     }, {
 
-         title: '{{ i18n "pages.inbounds.enable" }}',
 
-         align: 'center',
 
-         width: 40,
 
-         scopedSlots: { customRender: 'enable' },
 
-     }, {
 
-         title: "ID",
 
-         align: 'center',
 
-         dataIndex: "id",
 
-         width: 40,
 
-     }, {
 
-         title: '{{ i18n "pages.inbounds.remark" }}',
 
-         align: 'center',
 
-         width: 80,
 
-         dataIndex: "remark",
 
-     }, {
 
-         title: '{{ i18n "pages.inbounds.port" }}',
 
-         align: 'center',
 
-         dataIndex: "port",
 
-         width: 40,
 
-     }, {
 
-         title: '{{ i18n "pages.inbounds.protocol" }}',
 
-         align: 'left',
 
-         width: 90,
 
-         scopedSlots: { customRender: 'protocol' },
 
-     }, {
 
-         title: '{{ i18n "clients" }}',
 
-         align: 'left',
 
-         width: 40,
 
-         scopedSlots: { customRender: 'clients' },
 
-     }, {
 
-         title: '{{ i18n "pages.inbounds.traffic" }}',
 
-         align: 'center',
 
-         width: 60,
 
-         scopedSlots: { customRender: 'traffic' },
 
-     }, {
 
-         title: '{{ i18n "pages.inbounds.expireDate" }}',
 
-         align: 'center',
 
-         width: 80,
 
-         scopedSlots: { customRender: 'expiryTime' },
 
-     }];
 
-     const innerColumns = [
 
-         { title: '{{ i18n "pages.inbounds.operate" }}', width: 70, scopedSlots: { customRender: 'actions' } },
 
-         { title: '{{ i18n "pages.inbounds.enable" }}', width: 40, scopedSlots: { customRender: 'enable' } },
 
-         { title: '{{ i18n "pages.inbounds.client" }}', width: 80, scopedSlots: { customRender: 'client' } },
 
-         { title: '{{ i18n "pages.inbounds.traffic" }}', width: 50, scopedSlots: { customRender: 'traffic' } },
 
-         { title: '{{ i18n "pages.inbounds.expireDate" }}', width: 50, scopedSlots: { customRender: 'expiryTime' } },
 
-         { title: 'UUID', width: 120, dataIndex: "id" },
 
-     ];
 
-     const innerTrojanColumns = [
 
-         { title: '{{ i18n "pages.inbounds.operate" }}', width: 70, scopedSlots: { customRender: 'actions' } },
 
-         { title: '{{ i18n "pages.inbounds.enable" }}', width: 40, scopedSlots: { customRender: 'enable' } },
 
-         { title: '{{ i18n "pages.inbounds.client" }}', width: 80, scopedSlots: { customRender: 'client' } },
 
-         { title: '{{ i18n "pages.inbounds.traffic" }}', width: 50, scopedSlots: { customRender: 'traffic' } },
 
-         { title: '{{ i18n "pages.inbounds.expireDate" }}', width: 50, scopedSlots: { customRender: 'expiryTime' } },
 
-         { title: 'Password', width: 170, dataIndex: "password" },
 
-     ];
 
-     const app = new Vue({
 
-         delimiters: ['[[', ']]'],
 
-         el: '#app',
 
-         data: {
 
-             siderDrawer,
 
-             themeSwitcher,
 
-             spinning: false,
 
-             inbounds: [],
 
-             dbInbounds: [],
 
-             searchKey: '',
 
-             enableFilter: false,
 
-             filterBy: '',
 
-             searchedInbounds: [],
 
-             expireDiff: 0,
 
-             trafficDiff: 0,
 
-             defaultCert: '',
 
-             defaultKey: '',
 
-             clientCount: [],
 
-             isRefreshEnabled: localStorage.getItem("isRefreshEnabled") === "true" ? true : false,
 
-             refreshing: false,
 
-             refreshInterval: Number(localStorage.getItem("refreshInterval")) || 5000,
 
-             subSettings: {
 
-                 enable : false,
 
-                 port: 0,
 
-                 path: '',
 
-                 domain: '',
 
-                 tls: false
 
-             },
 
-             tgBotEnable: false
 
-         },
 
-         methods: {
 
-             loading(spinning = true) {
 
-                 this.spinning = spinning;
 
-             },
 
-             async getDBInbounds() {
 
-                 this.refreshing = true;
 
-                 const msg = await HttpUtil.post('/panel/inbound/list');
 
-                 if (!msg.success) {
 
-                     this.refreshing = false;
 
-                     return;
 
-                 }
 
-                 this.setInbounds(msg.obj);
 
-                 setTimeout(() => {
 
-                     this.refreshing = false;
 
-                 }, 500);
 
-             },
 
-             async getDefaultSettings() {
 
-                 const msg = await HttpUtil.post('/panel/setting/defaultSettings');
 
-                 if (!msg.success) {
 
-                     return;
 
-                 }
 
-                 with(msg.obj){
 
-                     this.expireDiff = expireDiff * 86400000;
 
-                     this.trafficDiff = trafficDiff * 1073741824;
 
-                     this.defaultCert = defaultCert;
 
-                     this.defaultKey = defaultKey;
 
-                     this.tgBotEnable = tgBotEnable;
 
-                     this.subSettings = {
 
-                         enable : subEnable,
 
-                         port: subPort,
 
-                         path: subPath,
 
-                         domain: subDomain,
 
-                         tls: subTLS
 
-                     };
 
-                 }
 
-             },
 
-             setInbounds(dbInbounds) {
 
-                 this.inbounds.splice(0);
 
-                 this.dbInbounds.splice(0);
 
-                 this.clientCount.splice(0);
 
-                 for (const inbound of dbInbounds) {
 
-                     const dbInbound = new DBInbound(inbound);
 
-                     to_inbound = dbInbound.toInbound()
 
-                     this.inbounds.push(to_inbound);
 
-                     this.dbInbounds.push(dbInbound);
 
-                     if ([Protocols.VMESS, Protocols.VLESS, Protocols.TROJAN, Protocols.SHADOWSOCKS].includes(inbound.protocol)) {
 
-                         if (inbound.protocol === Protocols.SHADOWSOCKS && (!to_inbound.isSSMultiUser)) {
 
-                             continue;
 
-                         }
 
-                         this.clientCount[inbound.id] = this.getClientCounts(inbound, to_inbound);
 
-                     }
 
-                 }
 
-                 if(this.enableFilter){
 
-                     this.filterInbounds();
 
-                 } else {
 
-                     this.searchInbounds(this.searchKey);
 
-                 }
 
-             },
 
-             getClientCounts(dbInbound, inbound) {
 
-                 let clientCount = 0, active = [], deactive = [], depleted = [], expiring = [];
 
-                 clients = this.getClients(dbInbound.protocol, inbound.settings);
 
-                 clientStats = dbInbound.clientStats
 
-                 now = new Date().getTime()
 
-                 if (clients) {
 
-                     clientCount = clients.length;
 
-                     if (dbInbound.enable) {
 
-                         clients.forEach(client => {
 
-                             client.enable ? active.push(client.email) : deactive.push(client.email);
 
-                         });
 
-                         clientStats.forEach(client => {
 
-                             if (!client.enable) {
 
-                                 depleted.push(client.email);
 
-                             } else {
 
-                                 if ((client.expiryTime > 0 && (client.expiryTime - now < this.expireDiff)) ||
 
-                                     (client.total > 0 && (client.total - (client.up + client.down) < this.trafficDiff))) expiring.push(client.email);
 
-                             }
 
-                         });
 
-                     } else {
 
-                         clients.forEach(client => {
 
-                             deactive.push(client.email);
 
-                         });
 
-                     }
 
-                 }
 
-                 return {
 
-                     clients: clientCount,
 
-                     active: active,
 
-                     deactive: deactive,
 
-                     depleted: depleted,
 
-                     expiring: expiring,
 
-                 };
 
-             },
 
-             searchInbounds(key) {
 
-                 if (ObjectUtil.isEmpty(key)) {
 
-                     this.searchedInbounds = this.dbInbounds.slice();
 
-                 } else {
 
-                     this.searchedInbounds.splice(0, this.searchedInbounds.length);
 
-                     this.dbInbounds.forEach(inbound => {
 
-                         if (ObjectUtil.deepSearch(inbound, key)) {
 
-                             const newInbound = new DBInbound(inbound);
 
-                             const inboundSettings = JSON.parse(inbound.settings);
 
-                             if (inboundSettings.hasOwnProperty('clients')) {
 
-                                 const searchedSettings = { "clients": [] };
 
-                                 inboundSettings.clients.forEach(client => {
 
-                                     if (ObjectUtil.deepSearch(client, key)) {
 
-                                         searchedSettings.clients.push(client);
 
-                                     }
 
-                                 });
 
-                                 newInbound.settings = Inbound.Settings.fromJson(inbound.protocol, searchedSettings);
 
-                             }
 
-                             this.searchedInbounds.push(newInbound);
 
-                         }
 
-                     });
 
-                 }
 
-             },
 
-             filterInbounds() {
 
-                 if (ObjectUtil.isEmpty(this.filterBy)) {
 
-                     this.searchedInbounds = this.dbInbounds.slice();
 
-                 } else {
 
-                     this.searchedInbounds.splice(0, this.searchedInbounds.length);
 
-                     this.dbInbounds.forEach(inbound => {
 
-                         const newInbound = new DBInbound(inbound);
 
-                         const inboundSettings = JSON.parse(inbound.settings);
 
-                         if (this.clientCount[inbound.id] && this.clientCount[inbound.id].hasOwnProperty(this.filterBy)){
 
-                             const list = this.clientCount[inbound.id][this.filterBy];
 
-                             if (list.length > 0) {
 
-                                 const filteredSettings = { "clients": [] };
 
-                                 inboundSettings.clients.forEach(client => {
 
-                                     if (list.includes(client.email)) {
 
-                                         filteredSettings.clients.push(client);
 
-                                     }
 
-                                 });
 
-                                 newInbound.settings = Inbound.Settings.fromJson(inbound.protocol, filteredSettings);
 
-                                 this.searchedInbounds.push(newInbound);
 
-                             }
 
-                         }
 
-                     });
 
-                 }
 
-             },
 
-             toggleFilter(){
 
-                 if(this.enableFilter) {
 
-                     this.searchKey = '';
 
-                 } else {
 
-                     this.filterBy = '';
 
-                     this.searchedInbounds = this.dbInbounds.slice();
 
-                 }
 
-             },
 
-             generalActions(action) {
 
-                 switch (action.key) {
 
-                     case "export":
 
-                         this.exportAllLinks();
 
-                         break;
 
-                     case "resetInbounds":
 
-                         this.resetAllTraffic();
 
-                         break;
 
-                     case "resetClients":
 
-                         this.resetAllClientTraffics(-1);
 
-                         break;
 
-                     case "delDepletedClients":
 
-                         this.delDepletedClients(-1)
 
-                         break;
 
-                 }
 
-             },
 
-             clickAction(action, dbInbound) {
 
-                 switch (action.key) {
 
-                     case "qrcode":
 
-                         this.showQrcode(dbInbound);
 
-                         break;
 
-                     case "showInfo":
 
-                         this.showInfo(dbInbound);
 
-                         break;
 
-                     case "edit":
 
-                         this.openEditInbound(dbInbound.id);
 
-                         break;
 
-                     case "addClient":
 
-                         this.openAddClient(dbInbound.id)
 
-                         break;
 
-                     case "addBulkClient":
 
-                         this.openAddBulkClient(dbInbound.id)
 
-                         break;
 
-                     case "export":
 
-                         this.inboundLinks(dbInbound.id);
 
-                         break;
 
-                     case "resetTraffic":
 
-                         this.resetTraffic(dbInbound.id);
 
-                         break;
 
-                     case "resetClients":
 
-                         this.resetAllClientTraffics(dbInbound.id);
 
-                         break;
 
-                     case "clone":
 
-                         this.openCloneInbound(dbInbound);
 
-                         break;
 
-                     case "delete":
 
-                         this.delInbound(dbInbound.id);
 
-                         break;
 
-                     case "delDepletedClients":
 
-                         this.delDepletedClients(dbInbound.id)
 
-                         break;
 
-                 }
 
-             },
 
-             openCloneInbound(dbInbound) {
 
-                 this.$confirm({
 
-                     title: '{{ i18n "pages.inbounds.cloneInbound"}} \"' + dbInbound.remark + '\"',
 
-                     content: '{{ i18n "pages.inbounds.cloneInboundContent"}}',
 
-                     okText: '{{ i18n "pages.inbounds.cloneInboundOk"}}',
 
-                     cancelText: '{{ i18n "cancel" }}',
 
-                     onOk: () => {
 
-                         const baseInbound = dbInbound.toInbound();
 
-                         dbInbound.up = 0;
 
-                         dbInbound.down = 0;
 
-                         this.cloneInbound(baseInbound, dbInbound);
 
-                     },
 
-                 });
 
-             },
 
-             async cloneInbound(baseInbound, dbInbound) {
 
-                 const data = {
 
-                     up: dbInbound.up,
 
-                     down: dbInbound.down,
 
-                     total: dbInbound.total,
 
-                     remark: dbInbound.remark + " - Cloned",
 
-                     enable: dbInbound.enable,
 
-                     expiryTime: dbInbound.expiryTime,
 
-                     listen: '',
 
-                     port: RandomUtil.randomIntRange(10000, 60000),
 
-                     protocol: baseInbound.protocol,
 
-                     settings: Inbound.Settings.getSettings(baseInbound.protocol).toString(),
 
-                     streamSettings: baseInbound.stream.toString(),
 
-                     sniffing: baseInbound.canSniffing() ? baseInbound.sniffing.toString() : '{}',
 
-                 };
 
-                 await this.submit('/panel/inbound/add', data, inModal);
 
-             },
 
-             openAddInbound() {
 
-                 inModal.show({
 
-                     title: '{{ i18n "pages.inbounds.addInbound"}}',
 
-                     okText: '{{ i18n "pages.inbounds.create"}}',
 
-                     cancelText: '{{ i18n "close" }}',
 
-                     confirm: async (inbound, dbInbound) => {
 
-                         inModal.loading();
 
-                         await this.addInbound(inbound, dbInbound);
 
-                         inModal.close();
 
-                     },
 
-                     isEdit: false
 
-                 });
 
-             },
 
-             openEditInbound(dbInboundId) {
 
-                 dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
 
-                 const inbound = dbInbound.toInbound();
 
-                 inModal.show({
 
-                     title: '{{ i18n "pages.inbounds.modifyInbound"}}',
 
-                     okText: '{{ i18n "pages.inbounds.update"}}',
 
-                     cancelText: '{{ i18n "close" }}',
 
-                     inbound: inbound,
 
-                     dbInbound: dbInbound,
 
-                     confirm: async (inbound, dbInbound) => {
 
-                         inModal.loading();
 
-                         await this.updateInbound(inbound, dbInbound);
 
-                         inModal.close();
 
-                     },
 
-                     isEdit: true
 
-                 });
 
-             },
 
-             async addInbound(inbound, dbInbound) {
 
-                 const data = {
 
-                     up: dbInbound.up,
 
-                     down: dbInbound.down,
 
-                     total: dbInbound.total,
 
-                     remark: dbInbound.remark,
 
-                     enable: dbInbound.enable,
 
-                     expiryTime: dbInbound.expiryTime,
 
-                     listen: inbound.listen,
 
-                     port: inbound.port,
 
-                     protocol: inbound.protocol,
 
-                     settings: inbound.settings.toString(),
 
-                 };
 
-                 if (inbound.canEnableStream()) data.streamSettings = inbound.stream.toString();
 
-                 if (inbound.canSniffing()) data.sniffing = inbound.sniffing.toString();
 
-                 await this.submit('/panel/inbound/add', data, inModal);
 
-             },
 
-             async updateInbound(inbound, dbInbound) {
 
-                 const data = {
 
-                     up: dbInbound.up,
 
-                     down: dbInbound.down,
 
-                     total: dbInbound.total,
 
-                     remark: dbInbound.remark,
 
-                     enable: dbInbound.enable,
 
-                     expiryTime: dbInbound.expiryTime,
 
-                     listen: inbound.listen,
 
-                     port: inbound.port,
 
-                     protocol: inbound.protocol,
 
-                     settings: inbound.settings.toString(),
 
-                 };
 
-                 if (inbound.canEnableStream()) data.streamSettings = inbound.stream.toString();
 
-                 if (inbound.canSniffing()) data.sniffing = inbound.sniffing.toString();
 
-                 await this.submit(`/panel/inbound/update/${dbInbound.id}`, data, inModal);
 
-             },
 
-             openAddClient(dbInboundId) {
 
-                 dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
 
-                 clientModal.show({
 
-                     title: '{{ i18n "pages.client.add"}}',
 
-                     okText: '{{ i18n "pages.client.submitAdd"}}',
 
-                     dbInbound: dbInbound,
 
-                     confirm: async (clients, dbInboundId) => {
 
-                         clientModal.loading();
 
-                         await this.addClient(clients, dbInboundId);
 
-                         clientModal.close();
 
-                     },
 
-                     isEdit: false
 
-                 });
 
-             },
 
-             openAddBulkClient(dbInboundId) {
 
-                 dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
 
-                 clientsBulkModal.show({
 
-                     title: '{{ i18n "pages.client.bulk"}} ' + dbInbound.remark,
 
-                     okText: '{{ i18n "pages.client.bulk"}}',
 
-                     dbInbound: dbInbound,
 
-                     confirm: async (clients, dbInboundId) => {
 
-                         clientsBulkModal.loading();
 
-                         await this.addClient(clients, dbInboundId);
 
-                         clientsBulkModal.close();
 
-                     },
 
-                 });
 
-             },
 
-             openEditClient(dbInboundId, client) {
 
-                 dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
 
-                 clients = this.getInboundClients(dbInbound);
 
-                 index = this.findIndexOfClient(clients, client);
 
-                 clientModal.show({
 
-                     title: '{{ i18n "pages.client.edit"}}',
 
-                     okText: '{{ i18n "pages.client.submitEdit"}}',
 
-                     dbInbound: dbInbound,
 
-                     index: index,
 
-                     confirm: async (client, dbInboundId, clientId) => {
 
-                         clientModal.loading();
 
-                         await this.updateClient(client, dbInboundId, clientId);
 
-                         clientModal.close();
 
-                     },
 
-                     isEdit: true
 
-                 });
 
-             },
 
-             findIndexOfClient(clients, client) {
 
-                 firstKey = Object.keys(client)[0];
 
-                 return clients.findIndex(c => c[firstKey] === client[firstKey]);
 
-             },
 
-             async addClient(clients, dbInboundId) {
 
-                 const data = {
 
-                     id: dbInboundId,
 
-                     settings: '{"clients": [' + clients.toString() + ']}',
 
-                 };
 
-                 await this.submit(`/panel/inbound/addClient`, data);
 
-             },
 
-             async updateClient(client, dbInboundId, clientId) {
 
-                 const data = {
 
-                     id: dbInboundId,
 
-                     settings: '{"clients": [' + client.toString() + ']}',
 
-                 };
 
-                 await this.submit(`/panel/inbound/updateClient/${clientId}`, data);
 
-             },
 
-             resetTraffic(dbInboundId) {
 
-                 dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
 
-                 this.$confirm({
 
-                     title: '{{ i18n "pages.inbounds.resetTraffic"}}',
 
-                     content: '{{ i18n "pages.inbounds.resetTrafficContent"}}',
 
-                     class: themeSwitcher.darkCardClass,
 
-                     okText: '{{ i18n "reset"}}',
 
-                     cancelText: '{{ i18n "cancel"}}',
 
-                     onOk: () => {
 
-                         const inbound = dbInbound.toInbound();
 
-                         dbInbound.up = 0;
 
-                         dbInbound.down = 0;
 
-                         this.updateInbound(inbound, dbInbound);
 
-                     },
 
-                 });
 
-             },
 
-             delInbound(dbInboundId) {
 
-                 this.$confirm({
 
-                     title: '{{ i18n "pages.inbounds.deleteInbound"}}',
 
-                     content: '{{ i18n "pages.inbounds.deleteInboundContent"}}',
 
-                     class: themeSwitcher.darkCardClass,
 
-                     okText: '{{ i18n "delete"}}',
 
-                     cancelText: '{{ i18n "cancel"}}',
 
-                     onOk: () => this.submit('/panel/inbound/del/' + dbInboundId),
 
-                 });
 
-             },
 
-             delClient(dbInboundId, client) {
 
-                 dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
 
-                 clientId = this.getClientId(dbInbound.protocol, client);
 
-                 this.$confirm({
 
-                     title: '{{ i18n "pages.inbounds.deleteInbound"}}',
 
-                     content: '{{ i18n "pages.inbounds.deleteInboundContent"}}',
 
-                     class: themeSwitcher.darkCardClass,
 
-                     okText: '{{ i18n "delete"}}',
 
-                     cancelText: '{{ i18n "cancel"}}',
 
-                     onOk: () => this.submit(`/panel/inbound/${dbInboundId}/delClient/${clientId}`),
 
-                 });
 
-             },
 
-             getClients(protocol, clientSettings) {
 
-                 switch (protocol) {
 
-                     case Protocols.VMESS: return clientSettings.vmesses;
 
-                     case Protocols.VLESS: return clientSettings.vlesses;
 
-                     case Protocols.TROJAN: return clientSettings.trojans;
 
-                     case Protocols.SHADOWSOCKS: return clientSettings.shadowsockses;
 
-                     default: return null;
 
-                 }
 
-             },
 
-             getClientId(protocol, client) {
 
-                 switch (protocol) {
 
-                     case Protocols.TROJAN: return client.password;
 
-                     case Protocols.SHADOWSOCKS: return client.email;
 
-                     default: return client.id;
 
-                 }
 
-             },
 
-             checkFallback(dbInbound) {
 
-                 newDbInbound = new DBInbound(dbInbound);
 
-                 if (dbInbound.listen.startsWith("@")){
 
-                     rootInbound = this.inbounds.find((i) => 
 
-                         i.tls && 
 
-                         ['trojan','vless'].includes(i.protocol) &&
 
-                         i.settings.fallbacks.find(f => f.dest === dbInbound.listen)
 
-                     );
 
-                     if (rootInbound) {
 
-                         newDbInbound.listen = rootInbound.listen;
 
-                         newDbInbound.port = rootInbound.port;
 
-                         newInbound = newDbInbound.toInbound();
 
-                         newInbound.stream.security = 'tls';
 
-                         newInbound.stream.tls = rootInbound.stream.tls;
 
-                         newDbInbound.streamSettings = newInbound.stream.toString();
 
-                     }
 
-                 }
 
-                 return newDbInbound;
 
-             },
 
-             showQrcode(dbInbound, clientIndex) {
 
-                 newDbInbound = this.checkFallback(dbInbound);
 
-                 qrModal.show('{{ i18n "qrCode"}}', newDbInbound, clientIndex);
 
-             },
 
-             showInfo(dbInbound, index) {
 
-                 newDbInbound = this.checkFallback(dbInbound);
 
-                 infoModal.show(newDbInbound, index);
 
-             },
 
-             switchEnable(dbInboundId) {
 
-                 dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
 
-                 this.submit(`/panel/inbound/update/${dbInboundId}`, dbInbound);
 
-             },
 
-             async switchEnableClient(dbInboundId, client) {
 
-                 this.loading()
 
-                 dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
 
-                 inbound = dbInbound.toInbound();
 
-                 clients = this.getClients(dbInbound.protocol, inbound.settings);
 
-                 index = this.findIndexOfClient(clients, client);
 
-                 clients[index].enable = !clients[index].enable;
 
-                 clientId = this.getClientId(dbInbound.protocol, clients[index]);
 
-                 await this.updateClient(clients[index], dbInboundId, clientId);
 
-                 this.loading(false);
 
-             },
 
-             async submit(url, data) {
 
-                 const msg = await HttpUtil.postWithModal(url, data);
 
-                 if (msg.success) {
 
-                     await this.getDBInbounds();
 
-                 }
 
-             },
 
-             getInboundClients(dbInbound) {
 
-                 if (dbInbound.protocol == Protocols.VLESS) {
 
-                     return dbInbound.toInbound().settings.vlesses;
 
-                 } else if (dbInbound.protocol == Protocols.VMESS) {
 
-                     return dbInbound.toInbound().settings.vmesses;
 
-                 } else if (dbInbound.protocol == Protocols.TROJAN) {
 
-                     return dbInbound.toInbound().settings.trojans;
 
-                 } else if (dbInbound.protocol == Protocols.SHADOWSOCKS) {
 
-                     return dbInbound.toInbound().settings.shadowsockses;
 
-                 }
 
-             },
 
-             resetClientTraffic(client, dbInboundId) {
 
-                 this.$confirm({
 
-                     title: '{{ i18n "pages.inbounds.resetTraffic"}}',
 
-                     content: '{{ i18n "pages.inbounds.resetTrafficContent"}}',
 
-                     class: themeSwitcher.darkCardClass,
 
-                     okText: '{{ i18n "reset"}}',
 
-                     cancelText: '{{ i18n "cancel"}}',
 
-                     onOk: () => this.submit('/panel/inbound/' + dbInboundId + '/resetClientTraffic/' + client.email),
 
-                 })
 
-             },
 
-             resetAllTraffic() {
 
-                 this.$confirm({
 
-                     title: '{{ i18n "pages.inbounds.resetAllTrafficTitle"}}',
 
-                     content: '{{ i18n "pages.inbounds.resetAllTrafficContent"}}',
 
-                     class: themeSwitcher.darkCardClass,
 
-                     okText: '{{ i18n "reset"}}',
 
-                     cancelText: '{{ i18n "cancel"}}',
 
-                     onOk: () => this.submit('/panel/inbound/resetAllTraffics'),
 
-                 });
 
-             },
 
-             resetAllClientTraffics(dbInboundId) {
 
-                 this.$confirm({
 
-                     title: dbInboundId > 0 ? '{{ i18n "pages.inbounds.resetInboundClientTrafficTitle"}}' : '{{ i18n "pages.inbounds.resetAllClientTrafficTitle"}}',
 
-                     content: dbInboundId > 0 ? '{{ i18n "pages.inbounds.resetInboundClientTrafficContent"}}' : '{{ i18n "pages.inbounds.resetAllClientTrafficContent"}}',
 
-                     class: themeSwitcher.darkCardClass,
 
-                     okText: '{{ i18n "reset"}}',
 
-                     cancelText: '{{ i18n "cancel"}}',
 
-                     onOk: () => this.submit('/panel/inbound/resetAllClientTraffics/' + dbInboundId),
 
-                 })
 
-             },
 
-             delDepletedClients(dbInboundId) {
 
-                 this.$confirm({
 
-                     title: '{{ i18n "pages.inbounds.delDepletedClientsTitle"}}',
 
-                     content: '{{ i18n "pages.inbounds.delDepletedClientsContent"}}',
 
-                     class: themeSwitcher.darkCardClass,
 
-                     okText: '{{ i18n "reset"}}',
 
-                     cancelText: '{{ i18n "cancel"}}',
 
-                     onOk: () => this.submit('/panel/inbound/delDepletedClients/' + dbInboundId),
 
-                 })
 
-             },
 
-             isExpiry(dbInbound, index) {
 
-                 return dbInbound.toInbound().isExpiry(index)
 
-             },
 
-             getUpStats(dbInbound, email) {
 
-                 if (email.length == 0) return 0
 
-                 clientStats = dbInbound.clientStats.find(stats => stats.email === email)
 
-                 return clientStats ? clientStats.up : 0
 
-             },
 
-             getDownStats(dbInbound, email) {
 
-                 if (email.length == 0) return 0
 
-                 clientStats = dbInbound.clientStats.find(stats => stats.email === email)
 
-                 return clientStats ? clientStats.down : 0
 
-             },
 
-             statsColor(dbInbound, email) {
 
-                 if(email.length == 0) return 'blue';
 
-                 clientStats = dbInbound.clientStats.find(stats => stats.email === email);
 
-                 return usageColor(clientStats.down + clientStats.up, this.trafficDiff, clientStats.total);
 
-             },
 
-             isClientEnabled(dbInbound, email) {
 
-                 clientStats = dbInbound.clientStats ? dbInbound.clientStats.find(stats => stats.email === email) : null
 
-                 return clientStats ? clientStats['enable'] : true
 
-             },
 
-             isRemovable(dbInbound_id) {
 
-                 return this.getInboundClients(this.dbInbounds.find(row => row.id === dbInbound_id)).length > 1
 
-             },
 
-             inboundLinks(dbInboundId) {
 
-                 dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
 
-                 newDbInbound = this.checkFallback(dbInbound);
 
-                 txtModal.show('{{ i18n "pages.inbounds.export"}}', newDbInbound.genInboundLinks, newDbInbound.remark);
 
-             },
 
-             exportAllLinks() {
 
-                 let copyText = '';
 
-                 for (const dbInbound of this.dbInbounds) {
 
-                     copyText += dbInbound.genInboundLinks
 
-                 }
 
-                 txtModal.show('{{ i18n "pages.inbounds.export"}}', copyText, 'All-Inbounds');
 
-             },
 
-             async startDataRefreshLoop() {
 
-                 while (this.isRefreshEnabled) {
 
-                     try {
 
-                         await this.getDBInbounds();
 
-                     } catch (e) {
 
-                         console.error(e);
 
-                     }
 
-                     await PromiseUtil.sleep(this.refreshInterval);
 
-                 }
 
-             },
 
-             toggleRefresh() {
 
-                 localStorage.setItem("isRefreshEnabled", this.isRefreshEnabled);
 
-                 if (this.isRefreshEnabled) {
 
-                     this.startDataRefreshLoop();
 
-                 }
 
-             },
 
-             changeRefreshInterval() {
 
-                 localStorage.setItem("refreshInterval", this.refreshInterval);
 
-             },
 
-             async manualRefresh() {
 
-                 if (!this.refreshing) {
 
-                     this.spinning = true;
 
-                     await this.getDBInbounds();
 
-                     this.spinning = false;
 
-                 }
 
-             },
 
-         },
 
-         watch: {
 
-             searchKey: debounce(function (newVal) {
 
-                 this.searchInbounds(newVal);
 
-             }, 500)
 
-         },
 
-         mounted() {
 
-             this.loading();
 
-             this.getDefaultSettings();
 
-             if (this.isRefreshEnabled) {
 
-                 this.startDataRefreshLoop();
 
-             }
 
-             else {
 
-                 this.getDBInbounds();
 
-             }
 
-             this.loading(false);
 
-         },
 
-         computed: {
 
-             total() {
 
-                 let down = 0, up = 0;
 
-                 let clients = 0, deactive = [], depleted = [], expiring = [];
 
-                 this.dbInbounds.forEach(dbInbound => {
 
-                     down += dbInbound.down;
 
-                     up += dbInbound.up;
 
-                     if (this.clientCount[dbInbound.id]) {
 
-                         clients += this.clientCount[dbInbound.id].clients;
 
-                         deactive = deactive.concat(this.clientCount[dbInbound.id].deactive);
 
-                         depleted = depleted.concat(this.clientCount[dbInbound.id].depleted);
 
-                         expiring = expiring.concat(this.clientCount[dbInbound.id].expiring);
 
-                     }
 
-                 });
 
-                 return {
 
-                     down: down,
 
-                     up: up,
 
-                     clients: clients,
 
-                     deactive: deactive,
 
-                     depleted: depleted,
 
-                     expiring: expiring,
 
-                 };
 
-             }
 
-         },
 
-     });
 
- </script>
 
- {{template "inboundModal"}}
 
- {{template "promptModal"}}
 
- {{template "qrcodeModal"}}
 
- {{template "textModal"}}
 
- {{template "inboundInfoModal"}}
 
- {{template "clientsModal"}}
 
- {{template "clientsBulkModal"}}
 
- </body>
 
- </html>
 
 
  |