├── .env.example ├── .eslintrc.json ├── .gitignore ├── LICENSE ├── README.md ├── config ├── admin.default.js ├── chronoScroll.default.js ├── gameEvents.default.js ├── geoip.default.js ├── ipBlock.default.js ├── launcher.default.js ├── localization.default.js ├── promoCode.default.js ├── rateLimits.default.js ├── shop.default.js └── slsOverride.default.js ├── data ├── captcha-images │ ├── 001_fc1bff.jpg │ ├── 002_c0ff2a.jpg │ ├── 003_c045ff.jpg │ ├── 004_ff3655.jpg │ ├── 005_ff9a24.jpg │ ├── 006_00eaff.jpg │ ├── 007_e43100.jpg │ ├── 008_e9e500.jpg │ ├── 009_90d409.jpg │ ├── 010_66a3ff.jpg │ ├── 011_1fffed.jpg │ ├── 012_2563ff.jpg │ ├── 013_3c6eff.jpg │ ├── 014_ffbd28.jpg │ ├── 015_7539ff.jpg │ ├── 016_b2ff44.jpg │ ├── 017_5be9dd.jpg │ ├── 018_75e3ff.jpg │ ├── 019_f7de39.jpg │ ├── 020_a2e066.jpg │ ├── 021_a767f7.jpg │ └── 022_64d6be.jpg ├── datasheets │ └── !Place datacenter files here.txt ├── geoip │ └── !Place mmdb file here.txt ├── shop-slides-bg │ └── !Unpack shop-slides-bg here.txt └── tera-icons │ └── !Unpack tera-icons here.txt ├── install.bat ├── package.json ├── public ├── captcha │ ├── css │ │ └── slidercaptcha.css │ └── js │ │ ├── .eslintrc.json │ │ └── slidercaptcha.js ├── email │ └── images │ │ └── logo.png ├── fontawesome │ ├── LICENSE.txt │ ├── css │ │ └── all.min.css │ └── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ └── fa-solid-900.woff2 ├── launcher │ ├── css │ │ ├── core.css │ │ └── login.css │ ├── images │ │ ├── bg.jpg │ │ ├── bg.png │ │ ├── btn-close.png │ │ ├── btn-close1.png │ │ ├── btn-gs-blue.png │ │ ├── btn-gs-green.png │ │ ├── btn-gs-orange.png │ │ ├── btn-gs-red.png │ │ ├── btn-logout.png │ │ ├── btn.png │ │ ├── flags │ │ │ ├── cn.png │ │ │ ├── de.png │ │ │ ├── en.png │ │ │ ├── fr.png │ │ │ ├── jp.png │ │ │ ├── kr.png │ │ │ ├── ru.png │ │ │ ├── se.png │ │ │ ├── th.png │ │ │ ├── tw.png │ │ │ └── us.png │ │ ├── form.png │ │ ├── ico.png │ │ ├── launcher_mask.png │ │ ├── loader.gif │ │ ├── logo.png │ │ └── repair-btn.png │ └── js │ │ ├── .eslintrc.json │ │ ├── jquery-1.11.1.min.js │ │ ├── launcher-errors.js │ │ ├── launcher-util.js │ │ └── launcher.js ├── patch │ └── .gitkeep └── shop │ ├── css │ ├── bootstrap.min.css │ ├── core.css │ ├── customselect.css │ └── numberinput.css │ ├── images │ └── icons │ │ ├── icon_grade_0.png │ │ ├── icon_grade_1.png │ │ ├── icon_grade_2.png │ │ ├── icon_grade_3.png │ │ ├── icon_grade_4.png │ │ ├── icon_grade_5.png │ │ ├── icon_grade_6.png │ │ ├── icon_tag_0.png │ │ ├── icon_tag_1.png │ │ ├── icon_tag_2.png │ │ └── icon_tag_3.png │ └── js │ ├── .eslintrc.json │ ├── bootstrap.min.js │ ├── coherent.js │ ├── imagesloaded.min.js │ ├── jquery-3.2.1.min.js │ ├── jquery.customselect.js │ ├── jquery.customselect.min.js │ ├── jquery.lazy.min.js │ ├── jquery.numberinput.js │ ├── jquery.numberinput.min.js │ ├── screen.js │ └── shop.js ├── share ├── data │ ├── shop-slides-bg.zip │ └── tera-icons.zip ├── db │ ├── 01_db_data.sql │ └── 03_db_shop_data.sql └── steer │ └── ExportSteerData_steeradmin_API.sef ├── src ├── actions │ ├── chronoScroll.actions.js │ ├── gameEvents.actions.js │ ├── handlers │ │ ├── benefit.js │ │ ├── custom.js │ │ ├── itemClaim.js │ │ └── shop.js │ ├── promoCode.actions.js │ ├── serverCheck.actions.js │ └── tasks.actions.js ├── app.js ├── controllers │ ├── admin.controller.js │ ├── adminAccounts.controller.js │ ├── adminApi.controller.js │ ├── adminBans.controller.js │ ├── adminBenefits.controller.js │ ├── adminBoxes.controller.js │ ├── adminCoupons.controller.js │ ├── adminCouponsActivated.controller.js │ ├── adminGatewayReport.controller.js │ ├── adminLauncherLogs.controller.js │ ├── adminMaintenance.controller.js │ ├── adminOnline.controller.js │ ├── adminOperationsReport.controller.js │ ├── adminPromocodes.controller.js │ ├── adminPromocodesActivated.controller.js │ ├── adminReport.controller.js │ ├── adminServerStrings.controller.js │ ├── adminServers.controller.js │ ├── adminShopAccounts.controller.js │ ├── adminShopCategories.controller.js │ ├── adminShopLogs.controller.js │ ├── adminShopProducts.controller.js │ ├── adminShopSlides.controller.js │ ├── adminTasks.controller.js │ ├── adminTasksLogs.controller.js │ ├── arbiterApi.controller.js │ ├── arbiterAuth.controller.js │ ├── gatewayAccount.controller.js │ ├── gatewayBox.controller.js │ ├── gatewayServer.controller.js │ ├── gatewayShop.controller.js │ ├── portalLauncher.controller.js │ ├── portalShop.controller.js │ └── portalSls.controller.js ├── lib │ ├── apiError.js │ ├── backgroundQueue.js │ ├── configManager.js │ ├── databaseMigration.js │ ├── datacenter │ │ ├── datacenter.js │ │ ├── packer.js │ │ └── reader.js │ ├── datasheetLoader.js │ ├── expressServer.js │ ├── hubConnection.js │ ├── hubError.js │ ├── hubFunctions.js │ ├── ipApiClient.js │ ├── ipApiClientResponse.d.ts │ ├── localizationManager.js │ ├── pluginsLoader.js │ ├── protobuf │ │ ├── hub.d.ts │ │ ├── hub.js │ │ ├── opArb.d.ts │ │ ├── opArb.js │ │ ├── opMsg.d.ts │ │ ├── opMsg.js │ │ ├── opUent.d.ts │ │ └── opUent.js │ ├── rateLimitter.js │ ├── scheduler.js │ ├── steerConnection.js │ ├── steerError.js │ ├── steerFunctions.js │ └── teraPlatformGuid.js ├── locales │ ├── admin │ │ ├── en.json │ │ └── ru.json │ ├── launcher │ │ ├── en.json │ │ └── ru.json │ └── shop │ │ ├── en.json │ │ └── ru.json ├── middlewares │ ├── admin.middlewares.js │ ├── arbiterApi.middlewares.js │ ├── arbiterAuth.middlewares.js │ ├── gateway.middlewares.js │ ├── portalLauncher.middlewares.js │ └── portalShop.middlewares.js ├── migrations │ └── update_000003.js ├── models │ ├── account.model.js │ ├── account │ │ ├── accountBans.model.js │ │ ├── accountBenefits.model.js │ │ ├── accountCharacters.model.js │ │ ├── accountInfo.model.js │ │ └── accountOnline.model.js │ ├── box.model.js │ ├── box │ │ ├── boxInfo.model.js │ │ └── boxItems.model.js │ ├── datasheet │ │ ├── itemConversion.model.js │ │ ├── itemData.model.js │ │ ├── skillIconData.model.js │ │ ├── strSheetAccountBenefit.model.js │ │ ├── strSheetCreature.model.js │ │ ├── strSheetDungeon.model.js │ │ └── strSheetItem.model.js │ ├── planetDb.model.js │ ├── planetDb │ │ └── planetDbUsers.model.js │ ├── queue.model.js │ ├── queue │ │ └── queueTasks.model.js │ ├── report.model.js │ ├── report │ │ ├── reportActivity.model.js │ │ ├── reportAdminOp.model.js │ │ ├── reportBoxes.model.js │ │ ├── reportCharacters.model.js │ │ ├── reportCheats.model.js │ │ ├── reportChronoScrolls.model.js │ │ ├── reportGateway.model.js │ │ ├── reportLauncher.model.js │ │ ├── reportQueueTasks.model.js │ │ ├── reportShopFund.model.js │ │ └── reportShopPay.model.js │ ├── server.model.js │ ├── server │ │ ├── serverInfo.model.js │ │ ├── serverMaintenance.model.js │ │ └── serverStrings.model.js │ ├── shop.model.js │ └── shop │ │ ├── shopAccounts.model.js │ │ ├── shopCategories.model.js │ │ ├── shopCategoryStrings.model.js │ │ ├── shopCouponActivated.model.js │ │ ├── shopCoupons.model.js │ │ ├── shopProductItems.model.js │ │ ├── shopProductStrings.model.js │ │ ├── shopProducts.model.js │ │ ├── shopPromoCodeActivated.model.js │ │ ├── shopPromoCodeStrings.model.js │ │ ├── shopPromoCodes.model.js │ │ └── shopSlides.model.js ├── modules │ ├── datasheetModel.module.js │ ├── geoip.module.js │ ├── hub.module.js │ ├── ipapi.module.js │ ├── mailer.module.js │ ├── planetDbs.module.js │ ├── sequelize.module.js │ └── steer.module.js ├── routes │ ├── admin.index.js │ ├── admin │ │ └── admin.routes.js │ ├── arbiter.index.js │ ├── arbiter │ │ ├── api.routes.js │ │ ├── authApi.routes.js │ │ └── systemApi.routes.js │ ├── gateway.index.js │ ├── gateway │ │ ├── accountApi.routes.js │ │ ├── boxApi.routes.js │ │ ├── serverApi.routes.js │ │ └── shopApi.routes.js │ ├── portal.index.js │ └── portal │ │ ├── launcher.routes.js │ │ ├── shop.routes.js │ │ └── tera.routes.js ├── servers │ ├── adminPanel.server.js │ ├── arbiterApi.server.js │ ├── gatewayApi.server.js │ └── portalApi.server.js ├── static │ └── admin │ │ ├── css │ │ ├── app.css │ │ └── vendor.css │ │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ │ ├── images │ │ ├── favicon.ico │ │ ├── icons │ │ │ ├── giftbox01.bmp.png │ │ │ ├── giftbox02.bmp.png │ │ │ ├── icon_grade_0.png │ │ │ ├── icon_grade_1.png │ │ │ ├── icon_grade_2.png │ │ │ ├── icon_grade_3.png │ │ │ ├── icon_grade_4.png │ │ │ ├── icon_grade_5.png │ │ │ ├── icon_grade_6.png │ │ │ ├── icon_tag_0.png │ │ │ ├── icon_tag_1.png │ │ │ ├── icon_tag_2.png │ │ │ └── icon_tag_3.png │ │ ├── sort_asc.png │ │ ├── sort_asc_disabled.png │ │ ├── sort_both.png │ │ ├── sort_desc.png │ │ └── sort_desc_disabled.png │ │ └── js │ │ ├── .eslintrc.json │ │ ├── app.js │ │ ├── vendor.js │ │ └── vendor │ │ └── jquery-validation │ │ └── localization │ │ ├── messages_ar.min.js │ │ ├── messages_az.min.js │ │ ├── messages_bg.min.js │ │ ├── messages_bn_BD.min.js │ │ ├── messages_ca.min.js │ │ ├── messages_cs.min.js │ │ ├── messages_da.min.js │ │ ├── messages_de.min.js │ │ ├── messages_el.min.js │ │ ├── messages_es.min.js │ │ ├── messages_es_AR.min.js │ │ ├── messages_es_PE.min.js │ │ ├── messages_et.min.js │ │ ├── messages_eu.min.js │ │ ├── messages_fa.min.js │ │ ├── messages_fi.min.js │ │ ├── messages_fr.min.js │ │ ├── messages_ge.min.js │ │ ├── messages_gl.min.js │ │ ├── messages_he.min.js │ │ ├── messages_hr.min.js │ │ ├── messages_hu.min.js │ │ ├── messages_hy_AM.min.js │ │ ├── messages_id.min.js │ │ ├── messages_is.min.js │ │ ├── messages_it.min.js │ │ ├── messages_ja.min.js │ │ ├── messages_ka.min.js │ │ ├── messages_kk.min.js │ │ ├── messages_ko.min.js │ │ ├── messages_lt.min.js │ │ ├── messages_lv.min.js │ │ ├── messages_mk.min.js │ │ ├── messages_my.min.js │ │ ├── messages_nl.min.js │ │ ├── messages_no.min.js │ │ ├── messages_pl.min.js │ │ ├── messages_pt_BR.min.js │ │ ├── messages_pt_PT.min.js │ │ ├── messages_ro.min.js │ │ ├── messages_ru.min.js │ │ ├── messages_sd.min.js │ │ ├── messages_si.min.js │ │ ├── messages_sk.min.js │ │ ├── messages_sl.min.js │ │ ├── messages_sr.min.js │ │ ├── messages_sr_lat.min.js │ │ ├── messages_sv.min.js │ │ ├── messages_th.min.js │ │ ├── messages_tj.min.js │ │ ├── messages_tr.min.js │ │ ├── messages_uk.min.js │ │ ├── messages_ur.min.js │ │ ├── messages_vi.min.js │ │ ├── messages_zh.min.js │ │ └── messages_zh_TW.min.js ├── utils │ ├── boxHelper.js │ ├── cacheManager.js │ ├── cliHelper.js │ ├── downloadFile.js │ ├── env.js │ ├── helpers.js │ ├── ipBlockHandler.js │ ├── isPortReachable.js │ ├── logger.js │ ├── migrationManager.js │ ├── sliderCaptcha.js │ ├── slsBuilder.js │ └── slsOverrideHandler.js └── views │ ├── adminAccounts.ejs │ ├── adminAccountsAdd.ejs │ ├── adminAccountsCharacters.ejs │ ├── adminAccountsEdit.ejs │ ├── adminBans.ejs │ ├── adminBansAdd.ejs │ ├── adminBansEdit.ejs │ ├── adminBenefits.ejs │ ├── adminBenefitsAdd.ejs │ ├── adminBenefitsEdit.ejs │ ├── adminBoxes.ejs │ ├── adminBoxesAdd.ejs │ ├── adminBoxesEdit.ejs │ ├── adminBoxesLogs.ejs │ ├── adminBoxesSend.ejs │ ├── adminBoxesSendAll.ejs │ ├── adminBoxesSendResult.ejs │ ├── adminCoupons.ejs │ ├── adminCouponsActivated.ejs │ ├── adminCouponsAdd.ejs │ ├── adminCouponsEdit.ejs │ ├── adminError.ejs │ ├── adminGatewayReport.ejs │ ├── adminGatewayReportView.ejs │ ├── adminHome.ejs │ ├── adminLauncherLogs.ejs │ ├── adminLayout.ejs │ ├── adminLogin.ejs │ ├── adminMaintenance.ejs │ ├── adminMaintenanceAdd.ejs │ ├── adminMaintenanceEdit.ejs │ ├── adminOnline.ejs │ ├── adminOperationsReport.ejs │ ├── adminOperationsReportView.ejs │ ├── adminProfile.ejs │ ├── adminPromocodes.ejs │ ├── adminPromocodesActivated.ejs │ ├── adminPromocodesActivatedAdd.ejs │ ├── adminPromocodesAdd.ejs │ ├── adminPromocodesEdit.ejs │ ├── adminReportActivity.ejs │ ├── adminReportCharacters.ejs │ ├── adminReportCheats.ejs │ ├── adminReportChronoScrolls.ejs │ ├── adminServerStrings.ejs │ ├── adminServerStringsAdd.ejs │ ├── adminServerStringsEdit.ejs │ ├── adminServers.ejs │ ├── adminServersAdd.ejs │ ├── adminServersEdit.ejs │ ├── adminSettings.ejs │ ├── adminShopAccounts.ejs │ ├── adminShopAccountsAdd.ejs │ ├── adminShopAccountsEdit.ejs │ ├── adminShopCategories.ejs │ ├── adminShopCategoriesAdd.ejs │ ├── adminShopCategoriesEdit.ejs │ ├── adminShopFundLogs.ejs │ ├── adminShopPayLogs.ejs │ ├── adminShopProducts.ejs │ ├── adminShopProductsAdd.ejs │ ├── adminShopProductsEdit.ejs │ ├── adminShopProductsEditAll.ejs │ ├── adminShopSlides.ejs │ ├── adminShopSlidesAdd.ejs │ ├── adminShopSlidesEdit.ejs │ ├── adminTasks.ejs │ ├── adminTasksLogs.ejs │ ├── email │ ├── emailVerify.ejs │ └── resetPasswordVerify.ejs │ ├── launcherErrorForm.ejs │ ├── launcherLoginForm.ejs │ ├── launcherMain.ejs │ ├── launcherResetPasswordForm.ejs │ ├── launcherResetPasswordVerifyForm.ejs │ ├── launcherSignupForm.ejs │ ├── launcherSignupVerifyForm.ejs │ ├── partials │ ├── adminFooter.ejs │ ├── adminFormErrors.ejs │ ├── adminHead.ejs │ ├── adminHeader.ejs │ ├── adminReportForm.ejs │ ├── adminScripts.ejs │ ├── adminSidebar.ejs │ ├── shopCoupons.ejs │ ├── shopError.ejs │ ├── shopProduct.ejs │ ├── shopPromoCode.ejs │ └── shopWelcome.ejs │ ├── shopDisabled.ejs │ └── shopMain.ejs ├── start__all.bat ├── start_admin_panel.bat ├── start_arbiter_api.bat ├── start_gateway_api.bat ├── start_portal_api.bat └── tera-api.code-workspace /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | config/*.js 3 | !config/*.default.js 4 | data/* 5 | !data/captcha-images/*.jpg 6 | !data/datasheets/*.txt 7 | !data/geoip/*.txt 8 | !data/shop-slides-bg/*.txt 9 | !data/tera-icons/*.txt 10 | logs/* 11 | sessions/* 12 | src/plugins/* 13 | public/updates/* 14 | public/patch/* 15 | !public/patch/.gitkeep 16 | share/dataitems/* 17 | config/slsOverride.js 18 | package-lock.json 19 | .env 20 | Thumbs.db 21 | *.tmp -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022-2025 Non-commercial Project "HSDN" 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /config/admin.default.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // THE CHANGES MADE ARE APPLIED WITHOUT RESTARTING THE PROCESS. 4 | 5 | module.exports = { 6 | // List of Admin Panel Quick Menu Links 7 | quickMenu: [ 8 | { name: "WebApp Panel", url: "http://localhost:88/" }, 9 | { name: "Box System Panel", url: "http://localhost:8070/" }, 10 | { name: "Steer Server Panel", url: "http://localhost:8060/" } 11 | ] 12 | }; -------------------------------------------------------------------------------- /config/geoip.default.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // CHANGES MADE ARE APPLIED ONLY AFTER THE PROCESS IS RESTARTED. 4 | 5 | const { expr } = require("../src/lib/scheduler"); 6 | 7 | module.exports = { 8 | // Automatic download settings. 9 | autoDownload: { 10 | // Enables or disables automatic downloading. 11 | enabled: false, 12 | 13 | // The URL from which the GeoIP database should be downloaded. 14 | url: "https://git.io/GeoLite2-City.mmdb", 15 | 16 | // Connection timeout in milliseconds. 17 | connectTimeout: 5000, 18 | 19 | // Response timeout in milliseconds (max interval between data chunks). 20 | responseTimeout: 10000, 21 | 22 | // Optional authentication string in the format "username:password". 23 | auth: null, 24 | 25 | // Enables or disables automatic updating. 26 | autoUpdateEnabled: true, 27 | 28 | // Schedule for automatic updates (see src/lib/scheduler.js). 29 | autoUpdateSchedule: expr.EVERY_WEDNESDAY_AND_SATURDAY 30 | } 31 | }; -------------------------------------------------------------------------------- /config/launcher.default.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // THE CHANGES MADE ARE APPLIED WITHOUT RESTARTING THE PROCESS. 4 | 5 | module.exports = { 6 | // Pages URLs for in-game actions (e.g. opening a page when entering the game). 7 | // You can specify the "%s" tag, which will include the user's current AuthKey. 8 | actsMap: { 9 | // On auth the game 10 | 210: "/tera/ShopAuth?authKey=%s", // opens TERA Shop 11 | 12 | // On enter the game 13 | 230: "/tera/ShopAuth?authKey=%s" // opens TERA Shop 14 | }, 15 | 16 | // Pages URLs used to open pop-up windows from the game interface. 17 | // You can specify the "%s" tag, which will include the user's current AuthKey. 18 | pagesMap: { 19 | // Homepage 20 | // 0: "http://example.com", 21 | 22 | // League 23 | // 1: "http://example.com/league", 24 | 25 | // Support 26 | // 11: "http://example.com/support", 27 | 28 | // Homepage 29 | // 13: "http://example.com", 30 | 31 | // Facebook 32 | // 30: "http://facebook.com", 33 | 34 | // VK 35 | // 32: "http://vk.com", 36 | 37 | // Youtube 38 | // 33: "http://youtube.com", 39 | 40 | // Donation 41 | // 201501: "http://example.com/donation", 42 | 43 | // Inventory 44 | // 2017041901: "http://example.com/inventory", 45 | 46 | // Collection 47 | // 2017041902: "http://example.com/collection" 48 | } 49 | }; -------------------------------------------------------------------------------- /config/shop.default.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // THE CHANGES MADE ARE APPLIED WITHOUT RESTARTING THE PROCESS. 4 | 5 | module.exports = { 6 | // List of Founder Benefit IDs to display on the shop welcome page 7 | founderBenefits: [ 8 | "334", 9 | "434", 10 | "534" 11 | ], 12 | 13 | // List of VIP/Premium/TERA Club Benefit IDs to display on the shop welcome page 14 | premiumBenefits: [ 15 | "333", 16 | "433", 17 | "533", 18 | "500", 19 | "520", 20 | "701" 21 | ], 22 | 23 | // List of PC Cafe/PC Club Benefit IDs to display on the shop welcome page 24 | pcCafeBenefits: [ 25 | "800", 26 | "801", 27 | "802", 28 | "803", 29 | "1000" 30 | ] 31 | }; -------------------------------------------------------------------------------- /data/captcha-images/001_fc1bff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/001_fc1bff.jpg -------------------------------------------------------------------------------- /data/captcha-images/002_c0ff2a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/002_c0ff2a.jpg -------------------------------------------------------------------------------- /data/captcha-images/003_c045ff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/003_c045ff.jpg -------------------------------------------------------------------------------- /data/captcha-images/004_ff3655.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/004_ff3655.jpg -------------------------------------------------------------------------------- /data/captcha-images/005_ff9a24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/005_ff9a24.jpg -------------------------------------------------------------------------------- /data/captcha-images/006_00eaff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/006_00eaff.jpg -------------------------------------------------------------------------------- /data/captcha-images/007_e43100.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/007_e43100.jpg -------------------------------------------------------------------------------- /data/captcha-images/008_e9e500.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/008_e9e500.jpg -------------------------------------------------------------------------------- /data/captcha-images/009_90d409.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/009_90d409.jpg -------------------------------------------------------------------------------- /data/captcha-images/010_66a3ff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/010_66a3ff.jpg -------------------------------------------------------------------------------- /data/captcha-images/011_1fffed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/011_1fffed.jpg -------------------------------------------------------------------------------- /data/captcha-images/012_2563ff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/012_2563ff.jpg -------------------------------------------------------------------------------- /data/captcha-images/013_3c6eff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/013_3c6eff.jpg -------------------------------------------------------------------------------- /data/captcha-images/014_ffbd28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/014_ffbd28.jpg -------------------------------------------------------------------------------- /data/captcha-images/015_7539ff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/015_7539ff.jpg -------------------------------------------------------------------------------- /data/captcha-images/016_b2ff44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/016_b2ff44.jpg -------------------------------------------------------------------------------- /data/captcha-images/017_5be9dd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/017_5be9dd.jpg -------------------------------------------------------------------------------- /data/captcha-images/018_75e3ff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/018_75e3ff.jpg -------------------------------------------------------------------------------- /data/captcha-images/019_f7de39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/019_f7de39.jpg -------------------------------------------------------------------------------- /data/captcha-images/020_a2e066.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/020_a2e066.jpg -------------------------------------------------------------------------------- /data/captcha-images/021_a767f7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/021_a767f7.jpg -------------------------------------------------------------------------------- /data/captcha-images/022_64d6be.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/captcha-images/022_64d6be.jpg -------------------------------------------------------------------------------- /data/datasheets/!Place datacenter files here.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/datasheets/!Place datacenter files here.txt -------------------------------------------------------------------------------- /data/geoip/!Place mmdb file here.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/geoip/!Place mmdb file here.txt -------------------------------------------------------------------------------- /data/shop-slides-bg/!Unpack shop-slides-bg here.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/shop-slides-bg/!Unpack shop-slides-bg here.txt -------------------------------------------------------------------------------- /data/tera-icons/!Unpack tera-icons here.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/data/tera-icons/!Unpack tera-icons here.txt -------------------------------------------------------------------------------- /install.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cd . 3 | npm install 4 | pause -------------------------------------------------------------------------------- /public/email/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/email/images/logo.png -------------------------------------------------------------------------------- /public/fontawesome/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Font Awesome Free License 2 | ------------------------- 3 | 4 | Font Awesome Free is free, open source, and GPL friendly. You can use it for 5 | commercial projects, open source projects, or really almost whatever you want. 6 | Full Font Awesome Free license: https://fontawesome.com/license/free. 7 | 8 | # Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) 9 | In the Font Awesome Free download, the CC BY 4.0 license applies to all icons 10 | packaged as SVG and JS file types. 11 | 12 | # Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) 13 | In the Font Awesome Free download, the SIL OFL license applies to all icons 14 | packaged as web and desktop font files. 15 | 16 | # Code: MIT License (https://opensource.org/licenses/MIT) 17 | In the Font Awesome Free download, the MIT license applies to all non-font and 18 | non-icon files. 19 | 20 | # Attribution 21 | Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font 22 | Awesome Free files already contain embedded comments with sufficient 23 | attribution, so you shouldn't need to do anything additional when using these 24 | files normally. 25 | 26 | We've kept attribution comments terse, so we ask that you do not actively work 27 | to remove them from files, especially code. They're a great way for folks to 28 | learn about Font Awesome. 29 | 30 | # Brand Icons 31 | All brand icons are trademarks of their respective owners. The use of these 32 | trademarks does not indicate endorsement of the trademark holder by Font 33 | Awesome, nor vice versa. **Please do not use brand logos for any purpose except 34 | to represent the company, product, or service to which they refer.** 35 | -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /public/fontawesome/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/fontawesome/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /public/launcher/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/bg.jpg -------------------------------------------------------------------------------- /public/launcher/images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/bg.png -------------------------------------------------------------------------------- /public/launcher/images/btn-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/btn-close.png -------------------------------------------------------------------------------- /public/launcher/images/btn-close1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/btn-close1.png -------------------------------------------------------------------------------- /public/launcher/images/btn-gs-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/btn-gs-blue.png -------------------------------------------------------------------------------- /public/launcher/images/btn-gs-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/btn-gs-green.png -------------------------------------------------------------------------------- /public/launcher/images/btn-gs-orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/btn-gs-orange.png -------------------------------------------------------------------------------- /public/launcher/images/btn-gs-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/btn-gs-red.png -------------------------------------------------------------------------------- /public/launcher/images/btn-logout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/btn-logout.png -------------------------------------------------------------------------------- /public/launcher/images/btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/btn.png -------------------------------------------------------------------------------- /public/launcher/images/flags/cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/cn.png -------------------------------------------------------------------------------- /public/launcher/images/flags/de.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/de.png -------------------------------------------------------------------------------- /public/launcher/images/flags/en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/en.png -------------------------------------------------------------------------------- /public/launcher/images/flags/fr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/fr.png -------------------------------------------------------------------------------- /public/launcher/images/flags/jp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/jp.png -------------------------------------------------------------------------------- /public/launcher/images/flags/kr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/kr.png -------------------------------------------------------------------------------- /public/launcher/images/flags/ru.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/ru.png -------------------------------------------------------------------------------- /public/launcher/images/flags/se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/se.png -------------------------------------------------------------------------------- /public/launcher/images/flags/th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/th.png -------------------------------------------------------------------------------- /public/launcher/images/flags/tw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/tw.png -------------------------------------------------------------------------------- /public/launcher/images/flags/us.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/flags/us.png -------------------------------------------------------------------------------- /public/launcher/images/form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/form.png -------------------------------------------------------------------------------- /public/launcher/images/ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/ico.png -------------------------------------------------------------------------------- /public/launcher/images/launcher_mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/launcher_mask.png -------------------------------------------------------------------------------- /public/launcher/images/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/loader.gif -------------------------------------------------------------------------------- /public/launcher/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/logo.png -------------------------------------------------------------------------------- /public/launcher/images/repair-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/launcher/images/repair-btn.png -------------------------------------------------------------------------------- /public/patch/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/patch/.gitkeep -------------------------------------------------------------------------------- /public/shop/css/customselect.css: -------------------------------------------------------------------------------- 1 | .custom-select { 2 | position: relative; 3 | display: inline-block; 4 | vertical-align: middle; 5 | width: auto; 6 | min-width: 220px; 7 | font-family: Verdana, Geneva, Tahoma, sans-serif; 8 | font-size: 12px; 9 | font-weight: bold; 10 | color: #fff; 11 | margin: 10px 0; 12 | } 13 | 14 | .custom-select-selected { 15 | background-color: #051423; 16 | color: white; 17 | padding: 0 30px 0 6px; 18 | line-height: 28px; 19 | height: 28px !important; 20 | border: 1px solid #13426D; 21 | white-space: nowrap; 22 | overflow: hidden; 23 | cursor: pointer; 24 | border-radius: 4px; 25 | } 26 | 27 | .custom-select-arrow { 28 | margin: 0; 29 | position: absolute; 30 | right: 6px; 31 | top: 50%; 32 | bottom: 0; 33 | margin-top: -1.1em; 34 | height: 26px; 35 | line-height: 26px; 36 | color: white; 37 | display: block; 38 | } 39 | 40 | .custom-select-options { 41 | display: none; 42 | position: absolute; 43 | top: 100%; 44 | left: 0; 45 | right: 0; 46 | background: #fff; 47 | border: 1px solid #767676; 48 | z-index: 1000; 49 | max-height: 200px; 50 | white-space: nowrap; 51 | overflow-x: hidden; 52 | overflow-y: auto; 53 | z-index: 1000; 54 | } 55 | 56 | .custom-select-option { 57 | padding: 5px; 58 | cursor: pointer; 59 | background-color: black; 60 | color: white; 61 | font-weight: normal; 62 | } 63 | 64 | .custom-select-option:hover { 65 | display: block; 66 | padding: 4px; 67 | border: 1px solid #767676; 68 | } 69 | 70 | .custom-select-disabled { 71 | opacity: 0.5; 72 | pointer-events: none; 73 | } -------------------------------------------------------------------------------- /public/shop/css/numberinput.css: -------------------------------------------------------------------------------- 1 | .number-input { 2 | position: relative; 3 | display: inline-block; 4 | } 5 | 6 | input[type="number"] { 7 | -moz-appearance: textfield; 8 | -webkit-appearance: none; 9 | appearance: textfield; 10 | } 11 | 12 | input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { 13 | -webkit-appearance: none; 14 | margin: 0; 15 | } 16 | 17 | .custom-arrows { 18 | position: absolute; 19 | right: 11px; 20 | top: 50%; 21 | bottom: 0; 22 | margin-top: -1.25em; 23 | } 24 | 25 | .custom-arrows .disabled { 26 | cursor: not-allowed; 27 | color: #55556d; 28 | background-color: #eeeeee; 29 | } 30 | 31 | .arrow-up, .arrow-down { 32 | cursor: pointer; 33 | color: black; 34 | background-color: white; 35 | font-size: 14px; 36 | padding: 3px; 37 | line-height: 1; 38 | user-select: none; 39 | -webkit-user-select: none; 40 | -ms-user-select: none; 41 | -moz-user-select: none; 42 | -webkit-touch-callout: none; 43 | -webkit-tap-highlight-color: transparent; 44 | } 45 | 46 | .arrow-up { 47 | margin-bottom: -5px; 48 | } 49 | 50 | .arrow-up:active, .arrow-down:active { 51 | outline: none; 52 | } 53 | -------------------------------------------------------------------------------- /public/shop/images/icons/icon_grade_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_grade_0.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_grade_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_grade_1.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_grade_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_grade_2.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_grade_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_grade_3.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_grade_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_grade_4.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_grade_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_grade_5.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_grade_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_grade_6.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_tag_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_tag_0.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_tag_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_tag_1.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_tag_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_tag_2.png -------------------------------------------------------------------------------- /public/shop/images/icons/icon_tag_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/public/shop/images/icons/icon_tag_3.png -------------------------------------------------------------------------------- /public/shop/js/jquery.customselect.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Custom Select v1.0.1 | MIT License | (c) 2025 Non-commercial Project "HSDN" */ 2 | !function(t){var e=t.fn.prop;t.fn.prop=function(n,o){return"selectedIndex"===n&&void 0!==o?(this.each(function(){var c=t(this),i=c.prop(n);e.call(c,n,o),i!==o&&c.trigger("change")}),this):e.apply(this,arguments)}}(window.jQuery),function(t){t.fn.customSelect=function(){return this.each(function(){var e=t(this),n=t('
'),o=t('
'),c=t('
'),i=t('
');function s(){o.off("click"),e.prop("disabled")?n.addClass("custom-select-disabled"):(n.removeClass("custom-select-disabled"),o.on("click",function(t){t.stopPropagation(),i.toggle()}))}o.text(e.find("option:selected").text()),n.append(o),o.append(c),e.find("option").each(function(n){var s=t(this),d=t('
');d.text(s.text()),d.attr("data-value",s.val()),d.on("click",function(){e.prop("disabled")||(e.prop("selectedIndex",n).trigger("change"),o.text(s.text()),o.append(c),i.hide())}),i.append(d)}),n.append(i),e.css({position:"absolute",left:"-9999px",top:"-9999px"}),e.after(n),"none"===e.css("display")&&n.hide(),s(),e.on("showCustomSelect",function(){n.show()}),e.on("hideCustomSelect",function(){n.hide()}),e.on("updateDisabledState",function(){s()}),t(document).on("click",function(e){t(e.target).closest(n).length||i.hide()}),e.on("change",function(){var t=e.prop("selectedIndex"),n=e.find("option").eq(t).text();o.text(n),o.append(c)})})}}(window.jQuery); -------------------------------------------------------------------------------- /public/shop/js/jquery.numberinput.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Number Input v1.1.2 | MIT License | (c) 2024 Non-commercial Project "HSDN" */ 2 | !(function($) { 3 | $.fn.numberInput = function() { 4 | return this.each(function() { 5 | var $input = $(this); 6 | var step = parseFloat($input.attr("step")) || 1; 7 | var min = parseFloat($input.attr("min")); 8 | var max = parseFloat($input.attr("max")); 9 | var $container = $("
"); 10 | 11 | $input.wrap($container); 12 | 13 | var $arrows = $("
" + 14 | "
" + 15 | "
" + 16 | "
"); 17 | 18 | $input.after($arrows); 19 | 20 | var updateArrowsState = function() { 21 | var isDisabled = $input.prop("disabled"); 22 | $arrows.find(".arrow-up, .arrow-down").toggleClass("disabled", isDisabled); 23 | }; 24 | 25 | $arrows.find(".arrow-up").click(function() { 26 | if ($input.prop("disabled")) return; 27 | $input.val(function(i, val) { 28 | var newValue = +val + step; 29 | if (max !== undefined && newValue > max) { 30 | newValue = max; 31 | } 32 | return newValue; 33 | }).trigger("change"); 34 | }); 35 | 36 | $arrows.find(".arrow-down").click(function() { 37 | if ($input.prop("disabled")) return; 38 | $input.val(function(i, val) { 39 | var newValue = +val - step; 40 | if (min !== undefined && newValue < min) { 41 | newValue = min; 42 | } 43 | return newValue; 44 | }).trigger("change"); 45 | }); 46 | 47 | updateArrowsState(); 48 | 49 | $input.on("change disabledChange", updateArrowsState); 50 | }); 51 | }; 52 | }(window.jQuery)); -------------------------------------------------------------------------------- /public/shop/js/jquery.numberinput.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Number Input v1.1.2 | MIT License | (c) 2024 Non-commercial Project "HSDN" */ 2 | !function(r){r.fn.numberInput=function(){return this.each(function(){var a=r(this),n=parseFloat(a.attr("step"))||1,i=parseFloat(a.attr("min")),t=parseFloat(a.attr("max")),d=r('
');a.wrap(d);var o=r('
');a.after(o);var c=function(){var r=a.prop("disabled");o.find(".arrow-up, .arrow-down").toggleClass("disabled",r)};o.find(".arrow-up").click(function(){a.prop("disabled")||a.val(function(r,a){var i=+a+n;return void 0!==t&&i>t&&(i=t),i}).trigger("change")}),o.find(".arrow-down").click(function(){a.prop("disabled")||a.val(function(r,a){var t=+a-n;return void 0!==i&&t { 34 | this.controller[event] = (...args) => 35 | modules.sequelize.transaction(() => { 36 | const methods = []; 37 | 38 | config[event].forEach(controller => { 39 | const instance = new controller[0](...args); 40 | 41 | Object.keys(controller[1]).forEach(method => { 42 | methods.push(instance[method].bind(instance, ...controller[1][method])); 43 | }); 44 | }); 45 | 46 | return chainPromise(methods); 47 | }) 48 | ; 49 | }); 50 | } 51 | 52 | async execute(event, params) { 53 | if (this.controller[event] === undefined) { 54 | this.modules.logger.debug(`GameEventsActions: Invalid event: ${event}`); 55 | 56 | return Promise.resolve(); 57 | } 58 | 59 | return await this.controller[event](this.modules, this.userId, this.serverId, params); 60 | } 61 | } 62 | 63 | module.exports = GameEventsActions; -------------------------------------------------------------------------------- /src/actions/handlers/custom.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../../app").modules} modules 5 | */ 6 | 7 | class Custom { 8 | /** 9 | * @param {modules} modules 10 | */ 11 | constructor(modules, userId, serverId, params = {}) { 12 | this.modules = modules; 13 | this.userId = userId; 14 | this.serverId = serverId; 15 | this.params = params; 16 | } 17 | 18 | /** 19 | * @param {function} callback 20 | */ 21 | async invoke(callback, ...args) { 22 | if (typeof callback !== "function") { 23 | throw Error("Callback is not a function"); 24 | } 25 | 26 | await callback.call(null, 27 | this.modules, 28 | this.userId, 29 | this.serverId, 30 | this.params, 31 | ...args 32 | ); 33 | } 34 | } 35 | 36 | module.exports = Custom; -------------------------------------------------------------------------------- /src/controllers/adminTasksLogs.controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").modules} modules 5 | * @typedef {import("express").RequestHandler} RequestHandler 6 | */ 7 | 8 | const expressLayouts = require("express-ejs-layouts"); 9 | const query = require("express-validator").query; 10 | const moment = require("moment-timezone"); 11 | const validator = require("validator"); 12 | const Op = require("sequelize").Op; 13 | 14 | const { validationHandler, accessFunctionHandler } = require("../middlewares/admin.middlewares"); 15 | 16 | /** 17 | * @param {modules} modules 18 | */ 19 | module.exports.index = ({ reportModel }) => [ 20 | accessFunctionHandler, 21 | expressLayouts, 22 | /** 23 | * @type {RequestHandler} 24 | */ 25 | async (req, res, next) => { 26 | const { taskId, handler, tag } = req.query; 27 | const from = req.query.from ? moment.tz(req.query.from, req.user.tz) : moment().subtract(30, "days"); 28 | const to = req.query.to ? moment.tz(req.query.to, req.user.tz) : moment().add(30, "days"); 29 | 30 | const reports = await reportModel.queueTasks.findAll({ 31 | where: { 32 | ...taskId ? { taskId } : {}, 33 | ...handler ? { handler } : {}, 34 | ...tag ? { tag } : {}, 35 | reportTime: { 36 | [Op.gt]: from.toDate(), 37 | [Op.lt]: to.toDate() 38 | } 39 | }, 40 | order: [ 41 | ["reportTime", "DESC"] 42 | ] 43 | }); 44 | 45 | res.render("adminTasksLogs", { 46 | layout: "adminLayout", 47 | moment, 48 | reports, 49 | from, 50 | to, 51 | taskId, 52 | tag, 53 | handler 54 | }); 55 | } 56 | ]; -------------------------------------------------------------------------------- /src/lib/apiError.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class ApiError extends Error { 4 | constructor(message, code) { 5 | super(message); 6 | 7 | this.name = this.constructor.name; 8 | this.code = code; 9 | } 10 | 11 | resultCode() { 12 | return this.code; 13 | } 14 | } 15 | 16 | module.exports = ApiError; -------------------------------------------------------------------------------- /src/lib/configManager.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const fs = require("fs"); 4 | const path = require("path"); 5 | 6 | function requireConfig(withReload, filePath) { 7 | if (withReload) { 8 | delete require.cache[require.resolve(filePath)]; 9 | } 10 | return require(filePath); 11 | } 12 | 13 | class ConfigManager { 14 | constructor(configPath, logger = null) { 15 | this.configPath = configPath; 16 | this.logger = logger; 17 | } 18 | 19 | get(name, withReload = true) { 20 | const filePath = path.join(this.configPath, `${name}.js`); 21 | const defaultFilePath = path.join(this.configPath, `${name}.default.js`); 22 | 23 | if (fs.existsSync(filePath)) { 24 | return requireConfig(withReload, filePath); 25 | } 26 | 27 | if (fs.existsSync(defaultFilePath)) { 28 | return requireConfig(withReload, defaultFilePath); 29 | } 30 | 31 | if (this.logger) { 32 | this.logger.debug(`Cannot find config file: ${name}.js`); 33 | } 34 | 35 | return null; 36 | } 37 | } 38 | 39 | module.exports = ConfigManager; -------------------------------------------------------------------------------- /src/lib/databaseMigration.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("sequelize").Sequelize} sequelize 5 | * @typedef {import("../utils/logger")} logger 6 | */ 7 | 8 | const MigrationManager = require("../utils/migrationManager"); 9 | 10 | /** 11 | * @param {sequelize} sequelize 12 | * @param {logger} migrationLogger 13 | * @param {string} migrationsDir 14 | * @param {string} fieldName 15 | * @param {number} dbVersion 16 | */ 17 | async function databaseMigrationProcedure(sequelize, migrationLogger, migrationsDir, fieldName, dbVersion) { 18 | const migrationManager = new MigrationManager(sequelize, migrationLogger, migrationsDir, fieldName); 19 | await migrationManager.init(); 20 | 21 | const currentDbVersion = await migrationManager.getCurrentVersion(); 22 | let passed = false; 23 | 24 | if (currentDbVersion === 0) { 25 | migrationLogger.info("DB version is not found."); 26 | 27 | passed = true; 28 | const isDbNotClean = await migrationManager.queryInterface.showAllTables() 29 | .then(tables => tables.includes("server_info")); 30 | 31 | if (!isDbNotClean) { 32 | migrationLogger.debug(`Database is clean, set DB version: ${dbVersion}`); 33 | await migrationManager.setVersion(dbVersion); 34 | } else { 35 | await migrationManager.runMigrations(); 36 | } 37 | } else if (currentDbVersion !== dbVersion) { 38 | passed = true; 39 | await migrationManager.runMigrations(); 40 | } 41 | 42 | migrationLogger.info(`DB version: ${dbVersion}`); 43 | 44 | return passed; 45 | } 46 | 47 | module.exports = { MigrationManager, databaseMigrationProcedure }; -------------------------------------------------------------------------------- /src/lib/datacenter/packer.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const crypto = require("crypto"); 3 | const zlib = require("zlib"); 4 | 5 | class Packer { 6 | constructor(key, iv, filePath, isCompressed = true, logger = null) { 7 | this.key = key; 8 | this.iv = iv; 9 | this.filePath = filePath; 10 | this.isCompressed = isCompressed; 11 | this.logger = logger; 12 | } 13 | 14 | unpack() { 15 | const data = this.read(); 16 | 17 | if (this.logger) { 18 | this.logger.debug(`Packer: Original size: ${data.length}`); 19 | } 20 | 21 | const decrypted = this.key && this.iv ? this.decrypt(data) : data; 22 | 23 | if (this.isCompressed) { 24 | const uncompressed = this.inflate(decrypted); 25 | 26 | if (this.logger) { 27 | this.logger.debug(`Packer: Uncompressed size: ${uncompressed.length}`); 28 | } 29 | 30 | return uncompressed; 31 | } 32 | 33 | return decrypted; 34 | } 35 | 36 | read() { 37 | return fs.readFileSync(this.filePath); 38 | } 39 | 40 | decrypt(data) { 41 | const decipher = crypto.createDecipheriv("aes-128-cfb", Buffer.from(this.key, "hex"), Buffer.from(this.iv, "hex")); 42 | decipher.setAutoPadding(false); 43 | 44 | const decrypted = Buffer.concat([decipher.update(data), decipher.final()]); 45 | 46 | if (decrypted[4] !== 0x78 || decrypted[5] !== 0x9c) { 47 | throw "Packer: Invalid Key/IV"; 48 | } 49 | 50 | return decrypted; 51 | } 52 | 53 | inflate(data) { 54 | return zlib.inflateSync(data.slice(4)); 55 | } 56 | } 57 | 58 | module.exports = Packer; -------------------------------------------------------------------------------- /src/lib/hubError.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class HubError extends Error { 4 | constructor(message, code) { 5 | super(message); 6 | 7 | this.name = this.constructor.name; 8 | this.code = code; 9 | } 10 | 11 | resultCode() { 12 | return this.code; 13 | } 14 | } 15 | 16 | module.exports = HubError; -------------------------------------------------------------------------------- /src/lib/steerError.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class SteerError extends Error { 4 | constructor(message, code) { 5 | super(message); 6 | 7 | this.name = this.constructor.name; 8 | this.code = code; 9 | } 10 | 11 | resultCode() { 12 | return this.code; 13 | } 14 | } 15 | 16 | module.exports = SteerError; -------------------------------------------------------------------------------- /src/lib/teraPlatformGuid.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.makeGuid = (category, number) => 4 | (parseInt(category) & 0x000000FF) << 24 | (parseInt(number) & 0x00FFFFFF) 5 | ; 6 | 7 | module.exports.readGuid = guid => 8 | ({ category: parseInt(guid) >> 24, number: parseInt(guid) & 0x00FFFFFF }) 9 | ; 10 | 11 | module.exports.gusid = { 12 | userentity: 4278190080, 13 | boxapi: 268435457, // (16 << 24) + 1 14 | steersession: 167772160, // (10 << 24) + 0 15 | steermind: 67108864 // (4 << 24) + 0 16 | }; 17 | 18 | module.exports.serverCategory = { 19 | unknown: 254, 20 | all: 255, 21 | arbitergw: 0, 22 | steerweb: 1, 23 | steergw: 2, 24 | steerhub: 3, 25 | steermind: 4, 26 | steerdb: 5, 27 | gas: 6, 28 | glogdb: 7, 29 | steerclient: 8, 30 | steercast: 9, 31 | steersession: 10, 32 | gameadmintool: 11, 33 | steerbridge: 12, 34 | hubgw: 13, 35 | cardmaker: 14, 36 | carddealer: 15, 37 | boxapi: 16, 38 | boxdm: 17, 39 | dbgw: 18, 40 | webcstool: 19, 41 | cardsteerbridge: 20, 42 | cardweb: 21, 43 | carddb: 22, 44 | boxdb: 23, 45 | boxbridgedorian: 24, 46 | scstool: 25, 47 | boxweb: 26, 48 | cardbridgenetmoderator: 27, 49 | dicedb: 31, 50 | dice: 32, 51 | diceweb: 33, 52 | steereye: 35 53 | }; -------------------------------------------------------------------------------- /src/middlewares/arbiterApi.middlewares.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("express").RequestHandler} RequestHandler 5 | */ 6 | 7 | const ApiError = require("../lib/apiError"); 8 | const helpers = require("../utils/helpers"); 9 | 10 | module.exports.validationHandler = logger => 11 | /** 12 | * @type {RequestHandler} 13 | */ 14 | (req, res, next) => { 15 | const result = helpers.validationResultLog(req, logger); 16 | 17 | if (!result.isEmpty()) { 18 | throw new ApiError("invalid parameter: ".concat(result.array() 19 | .map(e => `${e.location}:${e.param}=${e.msg}`).join(", ") 20 | ), 2); 21 | } 22 | 23 | next(); 24 | } 25 | ; -------------------------------------------------------------------------------- /src/middlewares/arbiterAuth.middlewares.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("express").RequestHandler} RequestHandler 5 | */ 6 | 7 | const ApiError = require("../lib/apiError"); 8 | const helpers = require("../utils/helpers"); 9 | 10 | module.exports.validationHandler = logger => 11 | /** 12 | * @type {RequestHandler} 13 | */ 14 | (req, res, next) => { 15 | const result = helpers.validationResultLog(req, logger); 16 | 17 | if (!result.isEmpty()) { 18 | throw new ApiError("invalid parameter: ".concat(result.array() 19 | .map(e => `${e.location}:${e.param}=${e.msg}`).join(", ") 20 | ), 2); 21 | } 22 | 23 | next(); 24 | } 25 | ; -------------------------------------------------------------------------------- /src/middlewares/gateway.middlewares.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("express").RequestHandler} RequestHandler 5 | */ 6 | 7 | const ApiError = require("../lib/apiError"); 8 | const helpers = require("../utils/helpers"); 9 | const databaseLogger = require("../utils/logger").createLogger("Database"); 10 | 11 | module.exports.validationHandler = logger => 12 | /** 13 | * @type {RequestHandler} 14 | */ 15 | (req, res, next) => { 16 | const result = helpers.validationResultLog(req, logger); 17 | 18 | if (!result.isEmpty()) { 19 | throw new ApiError("Invalid parameter: ".concat(result.array() 20 | .map(e => `${e.location}:${e.param}=${e.msg}`).join(", ") 21 | ), 2); 22 | } 23 | 24 | next(); 25 | } 26 | ; 27 | 28 | /** 29 | * @param {reportModel} reportModel 30 | */ 31 | module.exports.writeOperationReport = (reportModel, params = {}) => 32 | /** 33 | * @type {RequestHandler} 34 | */ 35 | (req, res, next) => { 36 | const query = { ...req.query || {} }; 37 | const body = { ...req.body || {} }; 38 | 39 | ["passWord", "password"].forEach(key => { 40 | if (query[key] !== undefined) { 41 | query[key] = "[removed]"; 42 | } 43 | 44 | if (body[key] !== undefined) { 45 | body[key] = "[removed]"; 46 | } 47 | }); 48 | 49 | reportModel.gateway.create({ 50 | ip: req.ip, 51 | endpoint: res.locals.__endpoint, 52 | payload: JSON.stringify([query, body]), 53 | reportType: params.reportType || 1 54 | }).catch(err => { 55 | databaseLogger.error(err); 56 | }); 57 | 58 | next(); 59 | } 60 | ; -------------------------------------------------------------------------------- /src/middlewares/portalLauncher.middlewares.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../lib/rateLimitter")} rateLimitter 5 | * @typedef {import("express").RequestHandler} RequestHandler 6 | */ 7 | 8 | const ApiError = require("../lib/apiError"); 9 | const helpers = require("../utils/helpers"); 10 | 11 | module.exports.validationHandler = logger => 12 | /** 13 | * @type {RequestHandler} 14 | */ 15 | (req, res, next) => { 16 | const result = helpers.validationResultLog(req, logger); 17 | 18 | if (!result.isEmpty()) { 19 | throw new ApiError("Invalid parameter: ".concat(result.array() 20 | .map(e => `${e.location}:${e.param}=${e.msg}`).join(", ") 21 | ), 2); 22 | } 23 | 24 | next(); 25 | } 26 | ; 27 | 28 | module.exports.authSessionHandler = () => 29 | /** 30 | * @type {RequestHandler} 31 | */ 32 | (req, res, next) => { 33 | if (!req.isAuthenticated()) { 34 | return res.redirect("/launcher/LoginForm"); 35 | } 36 | 37 | next(); 38 | } 39 | ; 40 | 41 | module.exports.apiAuthSessionHandler = () => 42 | /** 43 | * @type {RequestHandler} 44 | */ 45 | (req, res, next) => { 46 | if (!req.isAuthenticated()) { 47 | throw new ApiError("Access denied", 3); 48 | } 49 | 50 | next(); 51 | } 52 | ; 53 | 54 | /** 55 | * @param {rateLimitter} rateLimitter 56 | */ 57 | module.exports.rateLimitterHandler = (rateLimitter, endpoint, points = 1) => 58 | /** 59 | * @type {RequestHandler} 60 | */ 61 | async (req, res, next) => { 62 | const result = await rateLimitter.consume(endpoint, req.ip, points); 63 | 64 | if (!result) { 65 | throw new ApiError("Too many requests", 9); 66 | } 67 | 68 | next(); 69 | } 70 | ; -------------------------------------------------------------------------------- /src/middlewares/portalShop.middlewares.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../lib/rateLimitter")} rateLimitter 5 | * @typedef {import("express").RequestHandler} RequestHandler 6 | */ 7 | 8 | const ApiError = require("../lib/apiError"); 9 | const env = require("../utils/env"); 10 | const helpers = require("../utils/helpers"); 11 | 12 | module.exports.validationHandler = logger => 13 | /** 14 | * @type {RequestHandler} 15 | */ 16 | (req, res, next) => { 17 | const result = helpers.validationResultLog(req, logger); 18 | 19 | if (!result.isEmpty()) { 20 | throw new ApiError("Invalid parameter: ".concat(result.array() 21 | .map(e => `${e.location}:${e.param}=${e.msg}`).join(", ") 22 | ), 2); 23 | } 24 | 25 | next(); 26 | } 27 | ; 28 | 29 | module.exports.authSessionHandler = () => 30 | /** 31 | * @type {RequestHandler} 32 | */ 33 | (req, res, next) => { 34 | if (req.isAuthenticated()) { 35 | next(); 36 | } else { 37 | res.status(401).send(); 38 | } 39 | } 40 | ; 41 | 42 | /** 43 | * @type {RequestHandler} 44 | */ 45 | module.exports.shopStatusHandler = (req, res, next) => { 46 | if (!env.bool("API_PORTAL_SHOP_ENABLE")) { 47 | return res.redirect("ShopDisabled"); 48 | } 49 | 50 | next(); 51 | }; 52 | 53 | /** 54 | * @param {rateLimitter} rateLimitter 55 | */ 56 | module.exports.rateLimitterHandler = (rateLimitter, endpoint, points = 1) => 57 | /** 58 | * @type {RequestHandler} 59 | */ 60 | async (req, res, next) => { 61 | const result = await rateLimitter.consume(endpoint, req.ip, points); 62 | 63 | if (!result) { 64 | throw new ApiError("Too many requests", 9); 65 | } 66 | 67 | next(); 68 | } 69 | ; -------------------------------------------------------------------------------- /src/models/account/accountBans.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../account.model").Sequelize} Sequelize 5 | * @typedef {import("../account.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("account_bans", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | accountDBID: { 21 | type: DataTypes.BIGINT(20), 22 | allowNull: false 23 | }, 24 | startTime: { 25 | type: DataTypes.DATE, 26 | allowNull: false 27 | }, 28 | endTime: { 29 | type: DataTypes.DATE, 30 | allowNull: false 31 | }, 32 | ip: { 33 | type: DataTypes.TEXT 34 | }, 35 | description: { 36 | type: DataTypes.TEXT 37 | }, 38 | active: { 39 | type: DataTypes.BOOLEAN, 40 | allowNull: false, 41 | defaultValue: true 42 | } 43 | }, { 44 | indexes: [ 45 | { 46 | name: "accountDBID", 47 | unique: false, 48 | fields: ["accountDBID"] 49 | }, 50 | { 51 | name: "startTime", 52 | unique: false, 53 | fields: ["startTime"] 54 | }, 55 | { 56 | name: "endTime", 57 | unique: false, 58 | fields: ["endTime"] 59 | }, 60 | { 61 | name: "ip", 62 | unique: false, 63 | fields: ["ip"], 64 | type: "FULLTEXT" 65 | }, 66 | { 67 | name: "active", 68 | unique: false, 69 | fields: ["active"] 70 | } 71 | ] 72 | }) 73 | ; -------------------------------------------------------------------------------- /src/models/account/accountBenefits.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../account.model").Sequelize} Sequelize 5 | * @typedef {import("../account.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("account_benefits", { 14 | accountDBID: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | allowNull: false, 18 | references: { 19 | model: "account_info", 20 | key: "accountDBID" 21 | } 22 | }, 23 | benefitId: { 24 | type: DataTypes.INTEGER(11), 25 | primaryKey: true, 26 | allowNull: false 27 | }, 28 | availableUntil: { 29 | type: DataTypes.DATE, 30 | allowNull: false 31 | } 32 | }, { 33 | indexes: [ 34 | { 35 | name: "availableUntil", 36 | unique: false, 37 | fields: ["availableUntil"] 38 | } 39 | ] 40 | }) 41 | ; -------------------------------------------------------------------------------- /src/models/account/accountCharacters.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../account.model").Sequelize} Sequelize 5 | * @typedef {import("../account.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("account_characters", { 14 | characterId: { 15 | type: DataTypes.INTEGER(11), 16 | primaryKey: true, 17 | allowNull: false 18 | }, 19 | serverId: { 20 | type: DataTypes.INTEGER(11), 21 | primaryKey: true, 22 | allowNull: false 23 | }, 24 | accountDBID: { 25 | type: DataTypes.BIGINT(20), 26 | primaryKey: true, 27 | allowNull: false 28 | }, 29 | name: { 30 | type: DataTypes.STRING(64) 31 | }, 32 | classId: { 33 | type: DataTypes.INTEGER(11) 34 | }, 35 | genderId: { 36 | type: DataTypes.INTEGER(11) 37 | }, 38 | raceId: { 39 | type: DataTypes.INTEGER(11) 40 | }, 41 | level: { 42 | type: DataTypes.INTEGER(11) 43 | } 44 | }, { 45 | indexes: [ 46 | { 47 | name: "name", 48 | unique: false, 49 | fields: ["name"] 50 | } 51 | ] 52 | }) 53 | ; -------------------------------------------------------------------------------- /src/models/account/accountOnline.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../account.model").Sequelize} Sequelize 5 | * @typedef {import("../account.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("account_online", { 14 | accountDBID: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | allowNull: false 18 | }, 19 | serverId: { 20 | type: DataTypes.INTEGER(11), 21 | primaryKey: true, 22 | allowNull: false 23 | } 24 | }, { 25 | timestamps: true, 26 | updatedAt: false 27 | }) 28 | ; -------------------------------------------------------------------------------- /src/models/box.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").Sequelize} Sequelize 5 | * @typedef {import("../app").DataTypes} DataTypes 6 | * @typedef {import("../app").modules} modules 7 | * 8 | * @typedef {object} boxModel 9 | * @property {import("sequelize").ModelCtor>} info 10 | * @property {import("sequelize").ModelCtor>} items 11 | */ 12 | 13 | /** 14 | * @param {Sequelize} sequelize 15 | * @param {modules} modules 16 | */ 17 | module.exports = async (sequelize, DataTypes, syncTables, modules) => { 18 | const model = { 19 | info: require("./box/boxInfo.model")(sequelize, DataTypes), 20 | items: require("./box/boxItems.model")(sequelize, DataTypes) 21 | }; 22 | 23 | if (syncTables) { 24 | await model.info.sync(); 25 | await model.items.sync(); 26 | } 27 | 28 | // info 29 | model.info.hasMany(model.items, { 30 | foreignKey: "boxId", 31 | sourceKey: "id", 32 | as: "item" 33 | }); 34 | 35 | return model; 36 | }; -------------------------------------------------------------------------------- /src/models/box/boxInfo.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../box.model").Sequelize} Sequelize 5 | * @typedef {import("../box.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("box_info", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | icon: { 21 | type: DataTypes.STRING(255), 22 | allowNull: false 23 | }, 24 | title: { 25 | type: DataTypes.STRING(1024), 26 | allowNull: false 27 | }, 28 | content: { 29 | type: DataTypes.STRING(2048), 30 | allowNull: false 31 | }, 32 | days: { 33 | type: DataTypes.INTEGER(11), 34 | allowNull: false 35 | } 36 | }, { 37 | timestamps: true 38 | }) 39 | ; -------------------------------------------------------------------------------- /src/models/box/boxItems.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../box.model").Sequelize} Sequelize 5 | * @typedef {import("../box.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("box_items", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | boxId: { 21 | type: DataTypes.BIGINT(20), 22 | unique: "UNIQUE", 23 | allowNull: false 24 | }, 25 | itemTemplateId: { 26 | type: DataTypes.BIGINT(20), 27 | unique: "UNIQUE", 28 | allowNull: false 29 | }, 30 | boxItemId: { 31 | type: DataTypes.INTEGER(11) 32 | }, 33 | boxItemCount: { 34 | type: DataTypes.INTEGER(11), 35 | allowNull: false, 36 | defaultValue: 1 37 | } 38 | }, { 39 | indexes: [ 40 | { 41 | name: "UNIQUE", 42 | unique: true, 43 | fields: ["boxId", "itemTemplateId"] 44 | } 45 | ], 46 | timestamps: true 47 | }) 48 | ; -------------------------------------------------------------------------------- /src/models/datasheet/itemConversion.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class ItemConversionModel { 4 | constructor() { 5 | this.data = new Map(); 6 | } 7 | 8 | get section() { 9 | return "ItemConversion"; 10 | } 11 | 12 | get bindings() { 13 | return { 14 | "/ItemConversion/SeedItem": ({ attributes, elements }) => { 15 | const conversions = []; 16 | 17 | elements.forEach(element => { 18 | if (element.attributes?.templateId) { 19 | conversions.push({ 20 | itemTemplateId: element.attributes.templateId, 21 | class: element.attributes?.class || null, 22 | gender: element.attributes?.gender || null, 23 | race: element.attributes?.race || null 24 | }); 25 | } 26 | }); 27 | 28 | if (conversions.length) { 29 | this.data.set(attributes.itemTemplateId, conversions); 30 | } 31 | } 32 | }; 33 | } 34 | 35 | export() { 36 | return this.data; 37 | } 38 | 39 | import(data) { 40 | this.data = data; 41 | } 42 | 43 | getOne(itemTemplateId) { 44 | return this.data.get(Number(itemTemplateId)); 45 | } 46 | 47 | getAll() { 48 | return this.data.values(); 49 | } 50 | } 51 | 52 | module.exports = ItemConversionModel; -------------------------------------------------------------------------------- /src/models/datasheet/itemData.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class ItemDataModel { 4 | constructor() { 5 | this.data = new Map(); 6 | } 7 | 8 | get section() { 9 | return "ItemData"; 10 | } 11 | 12 | get bindings() { 13 | return { 14 | "/ItemData/Item": ({ attributes }) => { 15 | this.data.set(attributes.id, { 16 | itemTemplateId: attributes.id, 17 | name: attributes.name || null, 18 | category: attributes.category || null, 19 | linkSkillId: attributes.linkSkillId || null, 20 | linkSkillPeriodDay: attributes.linkSkillPeriodDay || null, 21 | icon: attributes.icon.split(".").at(-1).toLowerCase(), 22 | maxStack: attributes.maxStack, 23 | rareGrade: attributes.rareGrade, 24 | requiredLevel: attributes.requiredLevel || null, 25 | requiredClass: attributes.requiredClass?.toLowerCase() || null, 26 | requiredGender: attributes.requiredGender?.toLowerCase() || null, 27 | requiredRace: attributes.requiredRace?.toLowerCase() || null, 28 | boundType: attributes.boundType?.toLowerCase() || null, 29 | tradable: attributes.tradable, 30 | periodByWebAdmin: attributes.periodByWebAdmin || null, 31 | periodInMinute: attributes.periodInMinute || null, 32 | warehouseStorable: attributes.warehouseStorable 33 | }); 34 | } 35 | }; 36 | } 37 | 38 | export() { 39 | return this.data; 40 | } 41 | 42 | import(data) { 43 | this.data = data; 44 | } 45 | 46 | getOne(itemTemplateId) { 47 | return this.data.get(Number(itemTemplateId)); 48 | } 49 | 50 | getAll() { 51 | return this.data.values(); 52 | } 53 | } 54 | 55 | module.exports = ItemDataModel; -------------------------------------------------------------------------------- /src/models/datasheet/skillIconData.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class SkillIconDataModel { 4 | constructor() { 5 | this.data = new Map(); 6 | } 7 | 8 | get section() { 9 | return "SkillIconData"; 10 | } 11 | 12 | get bindings() { 13 | return { 14 | "/SkillIconData/Icon": ({ attributes }) => { 15 | if (attributes.iconName !== undefined) { 16 | const id = [attributes.skillId, attributes.class, attributes.race, attributes.gender].join("-"); 17 | 18 | this.data.set(id, { 19 | skillId: attributes.skillId, 20 | class: attributes.class.toLowerCase(), 21 | race: attributes.race.toLowerCase(), 22 | gender: attributes.gender.toLowerCase(), 23 | icon: attributes.iconName.split(".").at(-1).toLowerCase() 24 | }); 25 | } 26 | } 27 | }; 28 | } 29 | 30 | export() { 31 | return this.data; 32 | } 33 | 34 | import(data) { 35 | this.data = data; 36 | } 37 | 38 | getOne(skillId, class_, race, gender) { 39 | return this.data.get([skillId, class_, race, gender].join("-")); 40 | } 41 | 42 | getAll() { 43 | return this.data.values(); 44 | } 45 | } 46 | 47 | module.exports = SkillIconDataModel; -------------------------------------------------------------------------------- /src/models/datasheet/strSheetAccountBenefit.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class StrSheetAccountBenefitModel { 4 | constructor() { 5 | this.data = new Map(); 6 | } 7 | 8 | get section() { 9 | return "StrSheet_AccountBenefit"; 10 | } 11 | 12 | get bindings() { 13 | return { 14 | "/StrSheet_AccountBenefit/String": ({ attributes }) => { 15 | if (attributes.id < 1999) { 16 | this.data.set(attributes.id, { 17 | id: attributes.id, 18 | string: attributes.string 19 | }); 20 | } 21 | } 22 | }; 23 | } 24 | 25 | export() { 26 | return this.data; 27 | } 28 | 29 | import(data) { 30 | this.data = data; 31 | } 32 | 33 | getOne(id) { 34 | return this.data.get(Number(id)); 35 | } 36 | 37 | getAll() { 38 | return this.data.values(); 39 | } 40 | } 41 | 42 | module.exports = StrSheetAccountBenefitModel; -------------------------------------------------------------------------------- /src/models/datasheet/strSheetCreature.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class StrSheetCreatureModel { 4 | constructor() { 5 | this.data = new Map(); 6 | } 7 | 8 | get section() { 9 | return "StrSheet_Creature"; 10 | } 11 | 12 | get bindings() { 13 | return { 14 | "/StrSheet_Creature/HuntingZone": ({ attributes, elements }) => { 15 | elements.forEach(element => { 16 | this.data.set(`${attributes.id},${element.attributes.templateId}`, { 17 | zoneId: attributes.id, 18 | templateId: element.attributes.templateId, 19 | name: element.attributes.name 20 | }); 21 | }); 22 | } 23 | }; 24 | } 25 | 26 | export() { 27 | return this.data; 28 | } 29 | 30 | import(data) { 31 | this.data = data; 32 | } 33 | 34 | getOne(huntingZoneId, templateId) { 35 | return this.data.get(`${huntingZoneId},${templateId}`); 36 | } 37 | 38 | getAll() { 39 | return this.data.values(); 40 | } 41 | } 42 | 43 | module.exports = StrSheetCreatureModel; -------------------------------------------------------------------------------- /src/models/datasheet/strSheetDungeon.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | class StrSheetDungeonModel { 4 | constructor() { 5 | this.data = new Map(); 6 | } 7 | 8 | get section() { 9 | return "StrSheet_Dungeon"; 10 | } 11 | 12 | get bindings() { 13 | return { 14 | "/StrSheet_Dungeon/String": ({ attributes }) => { 15 | this.data.set(attributes.id, { 16 | id: attributes.id, 17 | string: attributes.string 18 | }); 19 | } 20 | }; 21 | } 22 | 23 | export() { 24 | return this.data; 25 | } 26 | 27 | import(data) { 28 | this.data = data; 29 | } 30 | 31 | getOne(id) { 32 | return this.data.get(Number(id)); 33 | } 34 | 35 | getAll() { 36 | return this.data.values(); 37 | } 38 | } 39 | 40 | module.exports = StrSheetDungeonModel; -------------------------------------------------------------------------------- /src/models/datasheet/strSheetItem.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { Index } = require("flexsearch"); 4 | 5 | class StrSheetItemModel { 6 | constructor() { 7 | this.data = new Map(); 8 | this.stringIndex = new Index({ 9 | preset: "memory", 10 | tokenize: "forward", 11 | threshold: 0, 12 | resolution: 3, 13 | cache: true 14 | }); 15 | } 16 | 17 | get section() { 18 | return "StrSheet_Item"; 19 | } 20 | 21 | get bindings() { 22 | return { 23 | "/StrSheet_Item/String": ({ attributes }) => { 24 | this.stringIndex.add(attributes.id, attributes.string); 25 | 26 | this.data.set(attributes.id, { 27 | itemTemplateId: attributes.id, 28 | string: attributes.string, 29 | toolTip: attributes.toolTip 30 | }); 31 | } 32 | }; 33 | } 34 | 35 | export() { 36 | return this.data; 37 | } 38 | 39 | import(data) { 40 | this.data = data; 41 | 42 | this.data.forEach(({ itemTemplateId, string }) => 43 | this.stringIndex.add(itemTemplateId, string) 44 | ); 45 | } 46 | 47 | getOne(itemTemplateId) { 48 | return this.data.get(Number(itemTemplateId)); 49 | } 50 | 51 | getAll() { 52 | return this.data.values(); 53 | } 54 | 55 | findAll(string, options = {}) { 56 | return this.stringIndex.search(string, options).map( 57 | itemTemplateId => this.data.get(itemTemplateId) 58 | ); 59 | } 60 | } 61 | 62 | module.exports = StrSheetItemModel; -------------------------------------------------------------------------------- /src/models/planetDb.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").Sequelize} Sequelize 5 | * @typedef {import("../app").DataTypes} DataTypes 6 | * 7 | * @typedef {object} planetDbModel 8 | * @property {import("sequelize").ModelCtor>} users 9 | */ 10 | 11 | module.exports = async (sequelize, DataTypes) => { 12 | const models = { 13 | users: require("./planetDb/planetDbUsers.model.js")(sequelize, DataTypes) 14 | }; 15 | 16 | return models; 17 | }; -------------------------------------------------------------------------------- /src/models/queue.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").Sequelize} Sequelize 5 | * @typedef {import("../app").DataTypes} DataTypes 6 | * 7 | * @typedef {object} queueModel 8 | * @property {import("sequelize").ModelCtor>} tasks 9 | */ 10 | 11 | /** 12 | * @param {Sequelize} sequelize 13 | * @param {DataTypes} DataTypes 14 | * @param {modules} modules 15 | */ 16 | module.exports = async (sequelize, DataTypes, syncTables, modules) => { 17 | const model = { 18 | tasks: require("./queue/queueTasks.model")(sequelize, DataTypes) 19 | }; 20 | 21 | if (syncTables) { 22 | await model.tasks.sync(); 23 | } 24 | 25 | return model; 26 | }; -------------------------------------------------------------------------------- /src/models/queue/queueTasks.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../queue.model").Sequelize} Sequelize 5 | * @typedef {import("../queue.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("queue_tasks", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | tag: { 21 | type: DataTypes.STRING(256) 22 | }, 23 | handler: { 24 | type: DataTypes.STRING(256), 25 | allowNull: false 26 | }, 27 | arguments: { 28 | type: DataTypes.TEXT, 29 | allowNull: false 30 | }, 31 | status: { 32 | type: DataTypes.INTEGER(11), 33 | allowNull: false 34 | }, 35 | message: { 36 | type: DataTypes.TEXT 37 | } 38 | }, { 39 | indexes: [ 40 | { 41 | name: "tag", 42 | unique: false, 43 | fields: ["tag"] 44 | }, 45 | { 46 | name: "handler", 47 | unique: false, 48 | fields: ["handler"] 49 | }, 50 | { 51 | name: "status", 52 | unique: false, 53 | fields: ["status"] 54 | } 55 | ], 56 | timestamps: true 57 | }) 58 | ; -------------------------------------------------------------------------------- /src/models/report/reportActivity.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../report.model").Sequelize} Sequelize 5 | * @typedef {import("../report.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_activity", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | accountDBID: { 21 | type: DataTypes.BIGINT(20) 22 | }, 23 | serverId: { 24 | type: DataTypes.INTEGER(11) 25 | }, 26 | ip: { 27 | type: DataTypes.STRING(64) 28 | }, 29 | playTime: { 30 | type: DataTypes.INTEGER(11) 31 | }, 32 | reportType: { 33 | type: DataTypes.INTEGER(11) 34 | }, 35 | reportTime: { 36 | type: DataTypes.DATE, 37 | defaultValue: DataTypes.NOW 38 | } 39 | }, { 40 | indexes: [ 41 | { 42 | name: "accountDBID", 43 | unique: false, 44 | fields: ["accountDBID"] 45 | }, 46 | { 47 | name: "serverId", 48 | unique: false, 49 | fields: ["serverId"] 50 | }, 51 | { 52 | name: "reportType", 53 | unique: false, 54 | fields: ["reportType"] 55 | }, 56 | { 57 | name: "reportTime", 58 | unique: false, 59 | fields: ["reportTime"] 60 | } 61 | ] 62 | }) 63 | ; -------------------------------------------------------------------------------- /src/models/report/reportAdminOp.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../report.model").Sequelize} Sequelize 5 | * @typedef {import("../report.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_admin_op", { 14 | id: { 15 | type: DataTypes.BIGINT, 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | userId: { 21 | type: DataTypes.STRING(64) 22 | }, 23 | userType: { 24 | type: DataTypes.STRING(64) 25 | }, 26 | userSn: { 27 | type: DataTypes.BIGINT(20) 28 | }, 29 | userTz: { 30 | type: DataTypes.STRING(128) 31 | }, 32 | ip: { 33 | type: DataTypes.STRING(64) 34 | }, 35 | function: { 36 | type: DataTypes.STRING(256) 37 | }, 38 | payload: { 39 | type: DataTypes.TEXT 40 | }, 41 | reportType: { 42 | type: DataTypes.INTEGER(11) 43 | }, 44 | reportTime: { 45 | type: DataTypes.DATE, 46 | defaultValue: DataTypes.NOW 47 | } 48 | }, { 49 | indexes: [ 50 | { 51 | name: "userId", 52 | unique: false, 53 | fields: ["userId"] 54 | }, 55 | { 56 | name: "userType", 57 | unique: false, 58 | fields: ["userType"] 59 | }, 60 | { 61 | name: "userSn", 62 | unique: false, 63 | fields: ["userSn"] 64 | }, 65 | { 66 | name: "reportTime", 67 | unique: false, 68 | fields: ["reportTime"] 69 | } 70 | ] 71 | }) 72 | ; -------------------------------------------------------------------------------- /src/models/report/reportBoxes.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../report.model").Sequelize} Sequelize 5 | * @typedef {import("../report.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_boxes", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | boxId: { 21 | type: DataTypes.BIGINT(20) 22 | }, 23 | accountDBID: { 24 | type: DataTypes.BIGINT(20), 25 | allowNull: false 26 | }, 27 | serverId: { 28 | type: DataTypes.INTEGER(11) 29 | }, 30 | characterId: { 31 | type: DataTypes.INTEGER(11) 32 | }, 33 | logType: { 34 | type: DataTypes.INTEGER(11) 35 | }, 36 | logId: { 37 | type: DataTypes.BIGINT(20) 38 | }, 39 | context: { 40 | type: DataTypes.TEXT, 41 | allowNull: false 42 | }, 43 | createdAt: { 44 | type: DataTypes.DATE, 45 | defaultValue: DataTypes.NOW 46 | } 47 | }, { 48 | indexes: [ 49 | { 50 | name: "boxId", 51 | unique: false, 52 | fields: ["boxId"] 53 | }, 54 | { 55 | name: "accountDBID", 56 | unique: false, 57 | fields: ["accountDBID"] 58 | }, 59 | { 60 | name: "logType", 61 | unique: false, 62 | fields: ["logType"] 63 | }, 64 | { 65 | name: "logId", 66 | unique: false, 67 | fields: ["logId"] 68 | }, 69 | { 70 | name: "createdAt", 71 | unique: false, 72 | fields: ["createdAt"] 73 | } 74 | ] 75 | }) 76 | ; -------------------------------------------------------------------------------- /src/models/report/reportCheats.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../report.model").Sequelize} Sequelize 5 | * @typedef {import("../report.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_cheats", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | accountDBID: { 21 | type: DataTypes.BIGINT(20) 22 | }, 23 | serverId: { 24 | type: DataTypes.INTEGER(11) 25 | }, 26 | ip: { 27 | type: DataTypes.STRING(64) 28 | }, 29 | type: { 30 | type: DataTypes.INTEGER(11) 31 | }, 32 | cheatInfo: { 33 | type: DataTypes.STRING(1024) 34 | }, 35 | reportTime: { 36 | type: DataTypes.DATE, 37 | defaultValue: DataTypes.NOW 38 | } 39 | }, { 40 | indexes: [ 41 | { 42 | name: "accountDBID", 43 | unique: false, 44 | fields: ["accountDBID"] 45 | }, 46 | { 47 | name: "serverId", 48 | unique: false, 49 | fields: ["serverId"] 50 | }, 51 | { 52 | name: "reportTime", 53 | unique: false, 54 | fields: ["reportTime"] 55 | } 56 | ] 57 | }) 58 | ; -------------------------------------------------------------------------------- /src/models/report/reportChronoScrolls.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../report.model").Sequelize} Sequelize 5 | * @typedef {import("../report.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_chronoscrolls", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | accountDBID: { 21 | type: DataTypes.BIGINT(20) 22 | }, 23 | serverId: { 24 | type: DataTypes.INTEGER(11) 25 | }, 26 | chronoId: { 27 | type: DataTypes.INTEGER(11) 28 | }, 29 | reportTime: { 30 | type: DataTypes.DATE, 31 | defaultValue: DataTypes.NOW 32 | } 33 | }, { 34 | indexes: [ 35 | { 36 | name: "accountDBID", 37 | unique: false, 38 | fields: ["accountDBID"] 39 | }, 40 | { 41 | name: "serverId", 42 | unique: false, 43 | fields: ["serverId"] 44 | }, 45 | { 46 | name: "reportTime", 47 | unique: false, 48 | fields: ["reportTime"] 49 | } 50 | ] 51 | }) 52 | ; -------------------------------------------------------------------------------- /src/models/report/reportGateway.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../report.model").Sequelize} Sequelize 5 | * @typedef {import("../report.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_gateway", { 14 | id: { 15 | type: DataTypes.BIGINT, 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | ip: { 21 | type: DataTypes.STRING(64) 22 | }, 23 | endpoint: { 24 | type: DataTypes.STRING(256) 25 | }, 26 | payload: { 27 | type: DataTypes.TEXT 28 | }, 29 | reportType: { 30 | type: DataTypes.INTEGER(11) 31 | }, 32 | reportTime: { 33 | type: DataTypes.DATE, 34 | defaultValue: DataTypes.NOW 35 | } 36 | }, { 37 | indexes: [ 38 | { 39 | name: "endpoint", 40 | unique: false, 41 | fields: ["endpoint"] 42 | }, 43 | { 44 | name: "reportTime", 45 | unique: false, 46 | fields: ["reportTime"] 47 | } 48 | ] 49 | }) 50 | ; -------------------------------------------------------------------------------- /src/models/report/reportLauncher.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../report.model").Sequelize} Sequelize 5 | * @typedef {import("../report.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_launcher", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | accountDBID: { 21 | type: DataTypes.BIGINT(20) 22 | }, 23 | ip: { 24 | type: DataTypes.STRING(64) 25 | }, 26 | action: { 27 | type: DataTypes.STRING(64) 28 | }, 29 | label: { 30 | type: DataTypes.STRING(128) 31 | }, 32 | optLabel: { 33 | type: DataTypes.STRING(128) 34 | }, 35 | version: { 36 | type: DataTypes.STRING(128) 37 | }, 38 | reportTime: { 39 | type: DataTypes.DATE, 40 | defaultValue: DataTypes.NOW 41 | } 42 | }, { 43 | indexes: [ 44 | { 45 | name: "accountDBID", 46 | unique: false, 47 | fields: ["accountDBID"] 48 | }, 49 | { 50 | name: "action", 51 | unique: false, 52 | fields: ["action"] 53 | }, 54 | { 55 | name: "reportTime", 56 | unique: false, 57 | fields: ["reportTime"] 58 | } 59 | ] 60 | }) 61 | ; -------------------------------------------------------------------------------- /src/models/report/reportQueueTasks.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../queue.model").Sequelize} Sequelize 5 | * @typedef {import("../queue.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_queue_tasks", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | taskId: { 21 | type: DataTypes.BIGINT(20) 22 | }, 23 | tag: { 24 | type: DataTypes.STRING(256) 25 | }, 26 | handler: { 27 | type: DataTypes.STRING(256), 28 | allowNull: false 29 | }, 30 | arguments: { 31 | type: DataTypes.TEXT, 32 | allowNull: false 33 | }, 34 | status: { 35 | type: DataTypes.INTEGER(11), 36 | allowNull: false 37 | }, 38 | message: { 39 | type: DataTypes.TEXT 40 | }, 41 | reportTime: { 42 | type: DataTypes.DATE, 43 | defaultValue: DataTypes.NOW 44 | } 45 | }, { 46 | indexes: [ 47 | { 48 | name: "taskId", 49 | unique: false, 50 | fields: ["taskId"] 51 | }, 52 | { 53 | name: "tag", 54 | unique: false, 55 | fields: ["tag"] 56 | }, 57 | { 58 | name: "handler", 59 | unique: false, 60 | fields: ["handler"] 61 | }, 62 | { 63 | name: "status", 64 | unique: false, 65 | fields: ["status"] 66 | }, 67 | { 68 | name: "reportTime", 69 | unique: false, 70 | fields: ["reportTime"] 71 | } 72 | ] 73 | }) 74 | ; -------------------------------------------------------------------------------- /src/models/report/reportShopFund.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../report.model").Sequelize} Sequelize 5 | * @typedef {import("../report.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_shop_fund", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | accountDBID: { 21 | type: DataTypes.BIGINT(20), 22 | allowNull: false 23 | }, 24 | amount: { 25 | type: DataTypes.INTEGER(11), 26 | allowNull: false 27 | }, 28 | balance: { 29 | type: DataTypes.INTEGER(11), 30 | allowNull: false 31 | }, 32 | description: { 33 | type: DataTypes.STRING(255) 34 | } 35 | }, { 36 | indexes: [ 37 | { 38 | name: "accountDBID", 39 | unique: false, 40 | fields: ["accountDBID"] 41 | } 42 | ], 43 | timestamps: true, 44 | updatedAt: false 45 | }) 46 | ; -------------------------------------------------------------------------------- /src/models/report/reportShopPay.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../report.model").Sequelize} Sequelize 5 | * @typedef {import("../report.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("report_shop_pay", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | accountDBID: { 21 | type: DataTypes.BIGINT(20), 22 | allowNull: false 23 | }, 24 | serverId: { 25 | type: DataTypes.INTEGER(11), 26 | allowNull: false 27 | }, 28 | ip: { 29 | type: DataTypes.STRING(64), 30 | allowNull: false 31 | }, 32 | boxId: { 33 | type: DataTypes.INTEGER(11) 34 | }, 35 | productId: { 36 | type: DataTypes.STRING(255), 37 | allowNull: false 38 | }, 39 | price: { 40 | type: DataTypes.INTEGER(11), 41 | allowNull: false 42 | }, 43 | quantity: { 44 | type: DataTypes.INTEGER(11), 45 | allowNull: false, 46 | defaultValue: 1 47 | }, 48 | status: { 49 | type: DataTypes.STRING(16), 50 | allowNull: false 51 | } 52 | }, { 53 | indexes: [ 54 | { 55 | name: "accountDBID", 56 | unique: false, 57 | fields: ["accountDBID"] 58 | }, 59 | { 60 | name: "serverId", 61 | unique: false, 62 | fields: ["serverId"] 63 | }, 64 | { 65 | name: "status", 66 | unique: false, 67 | fields: ["status"] 68 | } 69 | ], 70 | timestamps: true 71 | }) 72 | ; -------------------------------------------------------------------------------- /src/models/server.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").Sequelize} Sequelize 5 | * @typedef {import("../app").DataTypes} DataTypes 6 | * 7 | * @typedef {object} serverModel 8 | * @property {import("sequelize").ModelCtor>} maintenance 9 | * @property {import("sequelize").ModelCtor>} info 10 | * @property {import("sequelize").ModelCtor>} strings 11 | */ 12 | 13 | /** 14 | * @param {Sequelize} sequelize 15 | * @param {DataTypes} DataTypes 16 | * @param {modules} modules 17 | */ 18 | module.exports = async (sequelize, DataTypes, syncTables, modules) => { 19 | const model = { 20 | maintenance: require("./server/serverMaintenance.model")(sequelize, DataTypes), 21 | info: require("./server/serverInfo.model")(sequelize, DataTypes), 22 | strings: require("./server/serverStrings.model")(sequelize, DataTypes) 23 | }; 24 | 25 | if (syncTables) { 26 | await model.maintenance.sync(); 27 | await model.info.sync(); 28 | await model.strings.sync(); 29 | } 30 | 31 | return model; 32 | }; -------------------------------------------------------------------------------- /src/models/server/serverInfo.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../server.model").Sequelize} Sequelize 5 | * @typedef {import("../server.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("server_info", { 14 | serverId: { 15 | type: DataTypes.INTEGER(11), 16 | primaryKey: true, 17 | allowNull: false 18 | }, 19 | loginIp: { 20 | type: DataTypes.STRING(64) 21 | }, 22 | loginPort: { 23 | type: DataTypes.INTEGER(11) 24 | }, 25 | language: { 26 | type: DataTypes.STRING(3) 27 | }, 28 | nameString: { 29 | type: DataTypes.STRING(256) 30 | }, 31 | descrString: { 32 | type: DataTypes.STRING(1024) 33 | }, 34 | permission: { 35 | type: DataTypes.INTEGER(11), 36 | defaultValue: 0 37 | }, 38 | thresholdLow: { 39 | type: DataTypes.INTEGER(11) 40 | }, 41 | thresholdMedium: { 42 | type: DataTypes.INTEGER(11) 43 | }, 44 | isPvE: { 45 | type: DataTypes.BOOLEAN, 46 | defaultValue: false 47 | }, 48 | isCrowdness: { 49 | type: DataTypes.BOOLEAN, 50 | defaultValue: false 51 | }, 52 | isAvailable: { 53 | type: DataTypes.BOOLEAN, 54 | defaultValue: false 55 | }, 56 | isEnabled: { 57 | type: DataTypes.BOOLEAN, 58 | defaultValue: true 59 | }, 60 | usersOnline: { 61 | type: DataTypes.INTEGER(11), 62 | defaultValue: 0 63 | }, 64 | usersTotal: { 65 | type: DataTypes.INTEGER(11), 66 | defaultValue: 0 67 | } 68 | }) 69 | ; -------------------------------------------------------------------------------- /src/models/server/serverMaintenance.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../server.model").Sequelize} Sequelize 5 | * @typedef {import("../server.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("server_maintenance", { 14 | id: { 15 | type: DataTypes.INTEGER(11), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | startTime: { 21 | type: DataTypes.DATE 22 | }, 23 | endTime: { 24 | type: DataTypes.DATE 25 | }, 26 | description: { 27 | type: DataTypes.STRING 28 | } 29 | }, { 30 | indexes: [ 31 | { 32 | name: "startTime", 33 | unique: false, 34 | fields: ["startTime"] 35 | }, 36 | { 37 | name: "endTime", 38 | unique: false, 39 | fields: ["endTime"] 40 | } 41 | ] 42 | }) 43 | ; -------------------------------------------------------------------------------- /src/models/server/serverStrings.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../server.model").Sequelize} Sequelize 5 | * @typedef {import("../server.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("server_strings", { 14 | language: { 15 | type: DataTypes.STRING(3), 16 | primaryKey: true, 17 | allowNull: false 18 | }, 19 | categoryPvE: { 20 | type: DataTypes.STRING(50) 21 | }, 22 | categoryPvP: { 23 | type: DataTypes.STRING(50) 24 | }, 25 | serverOffline: { 26 | type: DataTypes.STRING(50) 27 | }, 28 | serverLow: { 29 | type: DataTypes.STRING(50) 30 | }, 31 | serverMedium: { 32 | type: DataTypes.STRING(50) 33 | }, 34 | serverHigh: { 35 | type: DataTypes.STRING(50) 36 | }, 37 | crowdNo: { 38 | type: DataTypes.STRING(50) 39 | }, 40 | crowdYes: { 41 | type: DataTypes.STRING(50) 42 | }, 43 | popup: { 44 | type: DataTypes.STRING(2048) 45 | } 46 | }) 47 | ; -------------------------------------------------------------------------------- /src/models/shop/shopAccounts.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../shop.model").Sequelize} Sequelize 5 | * @typedef {import("../shop.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("shop_accounts", { 14 | accountDBID: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | allowNull: false 18 | }, 19 | balance: { 20 | type: DataTypes.INTEGER(11), 21 | allowNull: false, 22 | defaultValue: 0 23 | }, 24 | discount: { 25 | type: DataTypes.INTEGER(11), 26 | allowNull: false, 27 | defaultValue: 0 28 | }, 29 | active: { 30 | type: DataTypes.BOOLEAN, 31 | allowNull: false, 32 | defaultValue: true 33 | } 34 | }, { 35 | indexes: [ 36 | { 37 | name: "active", 38 | unique: false, 39 | fields: ["active"] 40 | } 41 | ], 42 | timestamps: true 43 | }) 44 | ; -------------------------------------------------------------------------------- /src/models/shop/shopCategories.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../shop.model").Sequelize} Sequelize 5 | * @typedef {import("../shop.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("shop_categories", { 14 | id: { 15 | type: DataTypes.INTEGER(11), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | sort: { 21 | type: DataTypes.INTEGER(11), 22 | allowNull: false, 23 | defaultValue: 0 24 | }, 25 | active: { 26 | type: DataTypes.BOOLEAN, 27 | allowNull: false, 28 | defaultValue: true 29 | } 30 | }, { 31 | indexes: [ 32 | { 33 | name: "active", 34 | unique: false, 35 | fields: ["active"] 36 | } 37 | ], 38 | timestamps: true 39 | }) 40 | ; -------------------------------------------------------------------------------- /src/models/shop/shopCategoryStrings.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../shop.model").Sequelize} Sequelize 5 | * @typedef {import("../shop.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("shop_category_strings", { 14 | id: { 15 | type: DataTypes.INTEGER(11), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | language: { 21 | type: DataTypes.STRING(3), 22 | unique: "unique", 23 | allowNull: false 24 | }, 25 | categoryId: { 26 | type: DataTypes.INTEGER(11), 27 | unique: "unique", 28 | allowNull: false 29 | }, 30 | title: { 31 | type: DataTypes.STRING(1024) 32 | }, 33 | description: { 34 | type: DataTypes.TEXT 35 | } 36 | }, { 37 | indexes: [ 38 | { 39 | name: "unique", 40 | unique: true, 41 | fields: ["language", "categoryId"] 42 | } 43 | ] 44 | }) 45 | ; -------------------------------------------------------------------------------- /src/models/shop/shopCouponActivated.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../shop.model").Sequelize} Sequelize 5 | * @typedef {import("../shop.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("shop_coupon_activated", { 14 | id: { 15 | type: DataTypes.INTEGER(11), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | couponId: { 21 | type: DataTypes.INTEGER(11), 22 | unique: "unique", 23 | allowNull: false 24 | }, 25 | accountDBID: { 26 | type: DataTypes.BIGINT(20), 27 | unique: "unique", 28 | allowNull: false 29 | }, 30 | logId: { 31 | type: DataTypes.BIGINT(20), 32 | allowNull: false 33 | } 34 | }, { 35 | indexes: [ 36 | { 37 | name: "unique", 38 | unique: true, 39 | fields: ["couponId", "accountDBID"] 40 | } 41 | ], 42 | timestamps: true, 43 | updatedAt: false 44 | }) 45 | ; -------------------------------------------------------------------------------- /src/models/shop/shopProductItems.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../shop.model").Sequelize} Sequelize 5 | * @typedef {import("../shop.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("shop_product_items", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | productId: { 21 | type: DataTypes.BIGINT(20), 22 | unique: "UNIQUE", 23 | allowNull: false 24 | }, 25 | itemTemplateId: { 26 | type: DataTypes.BIGINT(20), 27 | unique: "UNIQUE", 28 | allowNull: false 29 | }, 30 | boxItemId: { 31 | type: DataTypes.INTEGER(11) 32 | }, 33 | boxItemCount: { 34 | type: DataTypes.INTEGER(11), 35 | allowNull: false, 36 | defaultValue: 1 37 | } 38 | }, { 39 | indexes: [ 40 | { 41 | name: "UNIQUE", 42 | unique: true, 43 | fields: ["productId", "itemTemplateId"] 44 | } 45 | ], 46 | timestamps: true 47 | }) 48 | ; -------------------------------------------------------------------------------- /src/models/shop/shopProductStrings.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../shop.model").Sequelize} Sequelize 5 | * @typedef {import("../shop.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("shop_product_strings", { 14 | id: { 15 | type: DataTypes.BIGINT(20), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | language: { 21 | type: DataTypes.STRING(3), 22 | unique: "UNIQUE", 23 | allowNull: false 24 | }, 25 | productId: { 26 | type: DataTypes.BIGINT(20), 27 | unique: "UNIQUE", 28 | allowNull: false 29 | }, 30 | title: { 31 | type: DataTypes.STRING(2048) 32 | }, 33 | description: { 34 | type: DataTypes.TEXT 35 | } 36 | }, { 37 | indexes: [ 38 | { 39 | name: "UNIQUE", 40 | unique: true, 41 | fields: ["language", "productId"] 42 | }, 43 | { 44 | name: "title", 45 | unique: false, 46 | fields: ["title"], 47 | type: "FULLTEXT" 48 | }, 49 | { 50 | name: "description", 51 | unique: false, 52 | fields: ["description"], 53 | type: "FULLTEXT" 54 | } 55 | ] 56 | }) 57 | ; -------------------------------------------------------------------------------- /src/models/shop/shopPromoCodeActivated.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../shop.model").Sequelize} Sequelize 5 | * @typedef {import("../shop.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("shop_promocode_activated", { 14 | id: { 15 | type: DataTypes.INTEGER(11), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | promoCodeId: { 21 | type: DataTypes.INTEGER(11), 22 | unique: "unique", 23 | allowNull: false 24 | }, 25 | accountDBID: { 26 | type: DataTypes.BIGINT(20), 27 | unique: "unique", 28 | allowNull: false 29 | } 30 | }, { 31 | indexes: [ 32 | { 33 | name: "unique", 34 | unique: true, 35 | fields: ["promoCodeId", "accountDBID"] 36 | } 37 | ], 38 | timestamps: true, 39 | updatedAt: false 40 | }) 41 | ; -------------------------------------------------------------------------------- /src/models/shop/shopPromoCodeStrings.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../shop.model").Sequelize} Sequelize 5 | * @typedef {import("../shop.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("shop_promocode_strings", { 14 | id: { 15 | type: DataTypes.BIGINT, 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | language: { 21 | type: DataTypes.STRING(3), 22 | unique: "unique", 23 | allowNull: false 24 | }, 25 | promoCodeId: { 26 | type: DataTypes.INTEGER(11), 27 | unique: "unique", 28 | allowNull: false 29 | }, 30 | description: { 31 | type: DataTypes.STRING(2048) 32 | } 33 | }, { 34 | indexes: [ 35 | { 36 | name: "unique", 37 | unique: true, 38 | fields: ["language", "promoCodeId"] 39 | } 40 | ] 41 | }) 42 | ; -------------------------------------------------------------------------------- /src/models/shop/shopSlides.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../shop.model").Sequelize} Sequelize 5 | * @typedef {import("../shop.model").DataTypes} DataTypes 6 | */ 7 | 8 | /** 9 | * @param {Sequelize} sequelize 10 | * @param {DataTypes} DataTypes 11 | */ 12 | module.exports = (sequelize, DataTypes) => 13 | sequelize.define("shop_slides", { 14 | id: { 15 | type: DataTypes.INTEGER(11), 16 | primaryKey: true, 17 | autoIncrement: true, 18 | allowNull: false 19 | }, 20 | active: { 21 | type: DataTypes.BOOLEAN, 22 | allowNull: false, 23 | defaultValue: true 24 | }, 25 | priority: { 26 | type: DataTypes.INTEGER(11), 27 | allowNull: false, 28 | defaultValue: 0 29 | }, 30 | productId: { 31 | type: DataTypes.BIGINT(20), 32 | allowNull: false 33 | }, 34 | image: { 35 | type: DataTypes.STRING(2048), 36 | allowNull: false 37 | }, 38 | displayDateStart: { 39 | type: DataTypes.DATE 40 | }, 41 | displayDateEnd: { 42 | type: DataTypes.DATE 43 | } 44 | }, { 45 | indexes: [ 46 | { 47 | name: "active", 48 | unique: false, 49 | fields: ["active"] 50 | }, 51 | { 52 | name: "displayDateStart", 53 | unique: false, 54 | fields: ["displayDateStart"] 55 | }, 56 | { 57 | name: "displayDateEnd", 58 | unique: false, 59 | fields: ["displayDateEnd"] 60 | } 61 | ], 62 | timestamps: true 63 | }) 64 | ; -------------------------------------------------------------------------------- /src/modules/hub.module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {HubFunctions} hub 5 | * @typedef {import("../app").modules} modules 6 | */ 7 | 8 | const env = require("../utils/env"); 9 | const { createLogger } = require("../utils/logger"); 10 | const HubFunctions = require("../lib/hubFunctions"); 11 | const serverCategory = require("../lib/teraPlatformGuid").serverCategory; 12 | 13 | /** 14 | * @param {modules} modules 15 | */ 16 | module.exports = async () => { 17 | const hub = new HubFunctions( 18 | env.string("HUB_HOST"), 19 | env.number("HUB_PORT"), 20 | serverCategory.webcstool, { 21 | logger: createLogger("Hub", { colors: { debug: "magenta" } }) 22 | } 23 | ); 24 | 25 | await hub.connect(); 26 | 27 | return hub; 28 | }; -------------------------------------------------------------------------------- /src/modules/ipapi.module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {IpApiClient} ipapi 5 | * @typedef {import("../app").modules} modules 6 | */ 7 | 8 | const env = require("../utils/env"); 9 | const IpApiClient = require("../lib/ipApiClient"); 10 | 11 | /** 12 | * @param {modules} modules 13 | */ 14 | module.exports = async () => new IpApiClient( 15 | env.array("IPAPI_API_KEYS", []), 16 | env.number("IPAPI_CACHE_TTL", 86400), // 24 hours 17 | env.number("IPAPI_REQUEST_TIMEOUT", 3), 18 | env.number("IPAPI_REQUEST_MAX_RETRIES", 3) 19 | ); -------------------------------------------------------------------------------- /src/modules/mailer.module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {nodemailer.Transporter} modules 5 | * @typedef {import("../app").modules} modules 6 | */ 7 | 8 | const nodemailer = require("nodemailer"); 9 | 10 | const env = require("../utils/env"); 11 | 12 | /** 13 | * @param {modules} modules 14 | */ 15 | module.exports = async () => { 16 | const settings = { 17 | host: env.string("MAILER_SMTP_HOST"), 18 | port: env.number("MAILER_SMTP_PORT"), 19 | secure: env.bool("MAILER_SMTP_SECURE") 20 | }; 21 | 22 | if (env.string("MAILER_SMTP_AUTH_USER") && env.string("MAILER_SMTP_AUTH_PASSWORD")) { 23 | settings.auth = { 24 | user: env.string("MAILER_SMTP_AUTH_USER"), 25 | pass: env.string("MAILER_SMTP_AUTH_PASSWORD") 26 | }; 27 | } 28 | 29 | return nodemailer.createTransport(settings); 30 | }; -------------------------------------------------------------------------------- /src/modules/steer.module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {SteerFunctions} steer 5 | * @typedef {import("../app").modules} modules 6 | */ 7 | 8 | const env = require("../utils/env"); 9 | const { createLogger } = require("../utils/logger"); 10 | const SteerFunctions = require("../lib/steerFunctions"); 11 | const serverCategory = require("../lib/teraPlatformGuid").serverCategory; 12 | 13 | /** 14 | * @param {modules} modules 15 | */ 16 | module.exports = async ({ checkComponent }) => { 17 | const steer = new SteerFunctions( 18 | env.string("STEER_HOST"), 19 | env.number("STEER_PORT"), 20 | serverCategory.webcstool, "WebIMSTool", { 21 | logger: createLogger("Steer", { colors: { debug: "bold magenta" } }) 22 | } 23 | ); 24 | 25 | if (checkComponent("admin_panel")) { 26 | if (env.bool("STEER_ENABLE")) { 27 | await steer.connect(); 28 | } else { 29 | steer.params.logger.warn("Not configured or disabled. QA authorization for Admin Panel is used."); 30 | } 31 | } 32 | 33 | return steer; 34 | }; -------------------------------------------------------------------------------- /src/routes/admin.index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").modules} modules 5 | */ 6 | 7 | /** 8 | * @param {modules} modules 9 | */ 10 | module.exports = async modules => { 11 | modules.app.use("/", await require("./admin/admin.routes")(modules)); 12 | 13 | modules.app.use((req, res) => 14 | res.redirect("/") 15 | ); 16 | }; -------------------------------------------------------------------------------- /src/routes/arbiter.index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").modules} modules 5 | */ 6 | 7 | /** 8 | * @param {modules} modules 9 | */ 10 | module.exports = async modules => { 11 | modules.app.use("/systemApi", await require("./arbiter/systemApi.routes")(modules)); 12 | modules.app.use("/authApi", await require("./arbiter/authApi.routes")(modules)); 13 | modules.app.use("/api", await require("./arbiter/api.routes")(modules)); 14 | }; -------------------------------------------------------------------------------- /src/routes/arbiter/api.routes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("express").ErrorRequestHandler} ErrorRequestHandler 5 | * @typedef {import("../../app").modules} modules 6 | */ 7 | 8 | const express = require("express"); 9 | 10 | const ApiError = require("../../lib/apiError"); 11 | const arbiterApiController = require("../../controllers/arbiterApi.controller"); 12 | 13 | /** 14 | * @param {modules} modules 15 | */ 16 | module.exports = async modules => express.Router() 17 | .get("/ServiceTest", arbiterApiController.ServiceTest(modules)) 18 | .post("/GetServerPermission", arbiterApiController.GetServerPermission(modules)) 19 | .post("/ServerDown", arbiterApiController.ServerDown(modules)) 20 | .post("/GetUserInfo", arbiterApiController.GetUserInfo(modules)) 21 | .post("/EnterGame", arbiterApiController.EnterGame(modules)) 22 | .post("/LeaveGame", arbiterApiController.LeaveGame(modules)) 23 | .post("/CreateChar", arbiterApiController.CreateChar(modules)) 24 | .post("/ModifyChar", arbiterApiController.ModifyChar(modules)) 25 | .post("/DeleteChar", arbiterApiController.DeleteChar(modules)) 26 | .post("/UseChronoScroll", arbiterApiController.UseChronoScroll(modules)) 27 | .post("/report_cheater", arbiterApiController.ReportCheater(modules)) 28 | 29 | .use( 30 | /** 31 | * @type {ErrorRequestHandler} 32 | */ 33 | (err, req, res, next) => { 34 | if (err instanceof ApiError) { 35 | res.json({ Return: false, ReturnCode: err.code, Msg: err.message }); 36 | } else { 37 | modules.logger.error(err); 38 | res.status(500).json({ Return: false, ReturnCode: 1, Msg: "internal server error" }); 39 | } 40 | } 41 | ) 42 | ; -------------------------------------------------------------------------------- /src/routes/arbiter/authApi.routes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("express").ErrorRequestHandler} ErrorRequestHandler 5 | * @typedef {import("../../app").modules} modules 6 | */ 7 | 8 | const express = require("express"); 9 | 10 | const ApiError = require("../../lib/apiError"); 11 | const arbiterAuthController = require("../../controllers/arbiterAuth.controller"); 12 | 13 | /** 14 | * @param {modules} modules 15 | */ 16 | module.exports = async modules => express.Router() 17 | .post("/RequestAuthkey", arbiterAuthController.RequestAuthkey(modules)) 18 | .post("/GameAuthenticationLogin", arbiterAuthController.GameAuthenticationLogin(modules)) 19 | 20 | .use( 21 | /** 22 | * @type {ErrorRequestHandler} 23 | */ 24 | (err, req, res, next) => { 25 | if (err instanceof ApiError) { 26 | res.json({ Return: false, ReturnCode: err.code, Msg: err.message }); 27 | } else { 28 | modules.logger.error(err); 29 | res.status(500).json({ Return: false, ReturnCode: 1, Msg: "internal server error" }); 30 | } 31 | } 32 | ) 33 | ; -------------------------------------------------------------------------------- /src/routes/arbiter/systemApi.routes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("express").ErrorRequestHandler} ErrorRequestHandler 5 | * @typedef {import("../../app").modules} modules 6 | */ 7 | 8 | const express = require("express"); 9 | 10 | const ApiError = require("../../lib/apiError"); 11 | const arbiterAuthController = require("../../controllers/arbiterAuth.controller"); 12 | 13 | /** 14 | * @param {modules} modules 15 | */ 16 | module.exports = async modules => express.Router() 17 | .get("/RequestAPIServerStatusAvailable", arbiterAuthController.RequestAPIServerStatusAvailable(modules)) 18 | 19 | .use( 20 | /** 21 | * @type {ErrorRequestHandler} 22 | */ 23 | (err, req, res, next) => { 24 | if (err instanceof ApiError) { 25 | res.json({ Return: false, ReturnCode: err.code, Msg: err.message }); 26 | } else { 27 | modules.logger.error(err); 28 | res.status(500).json({ Return: false, ReturnCode: 1, Msg: "internal server error" }); 29 | } 30 | } 31 | ) 32 | ; -------------------------------------------------------------------------------- /src/routes/gateway.index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").modules} modules 5 | */ 6 | 7 | /** 8 | * @param {modules} modules 9 | */ 10 | module.exports = async modules => { 11 | modules.app.use("/serverApi", await require("./gateway/serverApi.routes")(modules)); 12 | modules.app.use("/accountApi", await require("./gateway/accountApi.routes")(modules)); 13 | modules.app.use("/shopApi", await require("./gateway/shopApi.routes")(modules)); 14 | modules.app.use("/boxApi", await require("./gateway/boxApi.routes")(modules)); 15 | }; -------------------------------------------------------------------------------- /src/routes/gateway/accountApi.routes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("express").ErrorRequestHandler} ErrorRequestHandler 5 | * @typedef {import("../../app").modules} modules 6 | */ 7 | 8 | const express = require("express"); 9 | 10 | const ApiError = require("../../lib/apiError"); 11 | const gatewayAccountController = require("../../controllers/gatewayAccount.controller"); 12 | 13 | /** 14 | * @param {modules} modules 15 | */ 16 | module.exports = async modules => express.Router() 17 | .get("/ListAccounts", gatewayAccountController.ListAccounts(modules)) 18 | .get("/ListCharactersByUserNo", gatewayAccountController.ListCharactersByUserNo(modules)) 19 | .get("/ListBenefitsByUserNo", gatewayAccountController.ListBenefitsByUserNo(modules)) 20 | .get("/GetAccountInfoByUserNo", gatewayAccountController.GetAccountInfoByUserNo(modules)) 21 | .get("/GetAccountBanByUserNo", gatewayAccountController.GetAccountBanByUserNo(modules)) 22 | .post("/RegisterNewAccount", gatewayAccountController.RegisterNewAccount(modules)) 23 | .post("/AddBenefitByUserNo", gatewayAccountController.AddBenefitByUserNo(modules)) 24 | .post("/RemoveBenefitByUserNo", gatewayAccountController.RemoveBenefitByUserNo(modules)) 25 | .post("/BanAccountByUserNo", gatewayAccountController.BanAccountByUserNo(modules)) 26 | 27 | .use( 28 | /** 29 | * @type {ErrorRequestHandler} 30 | */ 31 | (err, req, res, next) => { 32 | if (err instanceof ApiError) { 33 | res.json({ Return: false, ReturnCode: err.code, Msg: err.message }); 34 | } else { 35 | modules.logger.error(err); 36 | res.status(500).json({ Return: false, ReturnCode: 1, Msg: "Internal Server Error" }); 37 | } 38 | } 39 | ) 40 | ; -------------------------------------------------------------------------------- /src/routes/gateway/boxApi.routes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("express").ErrorRequestHandler} ErrorRequestHandler 5 | * @typedef {import("../../app").modules} modules 6 | */ 7 | 8 | const express = require("express"); 9 | 10 | const ApiError = require("../../lib/apiError"); 11 | const gatewayBoxController = require("../../controllers/gatewayBox.controller"); 12 | 13 | /** 14 | * @param {modules} modules 15 | */ 16 | module.exports = async modules => express.Router() 17 | .get("/ListBoxes", gatewayBoxController.ListBoxes(modules)) 18 | .post("/SendBoxToAccountByUserNo", gatewayBoxController.SendBoxToAccountByUserNo(modules)) 19 | .post("/SendBoxesToAllByServerId", gatewayBoxController.SendBoxesToAllByServerId(modules)) 20 | 21 | .use( 22 | /** 23 | * @type {ErrorRequestHandler} 24 | */ 25 | (err, req, res, next) => { 26 | if (err instanceof ApiError) { 27 | res.json({ Return: false, ReturnCode: err.code, Msg: err.message }); 28 | } else { 29 | modules.logger.error(err); 30 | res.status(500).json({ Return: false, ReturnCode: 1, Msg: "Internal Server Error" }); 31 | } 32 | } 33 | ) 34 | ; -------------------------------------------------------------------------------- /src/routes/gateway/serverApi.routes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("express").ErrorRequestHandler} ErrorRequestHandler 5 | * @typedef {import("../../app").modules} modules 6 | */ 7 | 8 | const express = require("express"); 9 | 10 | const ApiError = require("../../lib/apiError"); 11 | const gatewayServerController = require("../../controllers/gatewayServer.controller"); 12 | 13 | /** 14 | * @param {modules} modules 15 | */ 16 | module.exports = async modules => express.Router() 17 | .get("/ListServers", gatewayServerController.ListServers(modules)) 18 | .get("/ListOnlineAccountsByServerId", gatewayServerController.ListOnlineAccountsByServerId(modules)) 19 | .get("/GetServerInfoByServerId", gatewayServerController.GetServerInfoByServerId(modules)) 20 | .post("/KickAccountByUserNo", gatewayServerController.KickAccountByUserNo(modules)) 21 | .post("/KickAllAccountsByServerId", gatewayServerController.KickAllAccountsByServerId(modules)) 22 | 23 | .use( 24 | /** 25 | * @type {ErrorRequestHandler} 26 | */ 27 | (err, req, res, next) => { 28 | if (err instanceof ApiError) { 29 | res.json({ Return: false, ReturnCode: err.code, Msg: err.message }); 30 | } else { 31 | modules.logger.error(err); 32 | res.status(500).json({ Return: false, ReturnCode: 1, Msg: "Internal Server Error" }); 33 | } 34 | } 35 | ) 36 | ; -------------------------------------------------------------------------------- /src/routes/portal.index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").modules} modules 5 | */ 6 | 7 | const env = require("../utils/env"); 8 | 9 | /** 10 | * @param {modules} modules 11 | */ 12 | module.exports = async modules => { 13 | // Game API 14 | modules.app.use("/tera", await require("./portal/tera.routes")(modules)); 15 | 16 | // Shop 17 | modules.app.use("/shop", await require("./portal/shop.routes")(modules)); 18 | 19 | // Launcher 20 | if (!env.bool("API_PORTAL_LAUNCHER_DISABLE")) { 21 | modules.app.use("/launcher", await require("./portal/launcher.routes")(modules)); 22 | } 23 | }; -------------------------------------------------------------------------------- /src/servers/arbiterApi.server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").modules} modules 5 | */ 6 | 7 | const env = require("../utils/env"); 8 | const { createLogger } = require("../utils/logger"); 9 | const { expr } = require("../lib/scheduler"); 10 | const ExpressServer = require("../lib/expressServer"); 11 | const ServerCheckActions = require("../actions/serverCheck.actions"); 12 | 13 | /** 14 | * @param {modules} modules 15 | */ 16 | module.exports = async modules => { 17 | if (!modules.checkComponent("arbiter_api")) return; 18 | 19 | if (!env.number("API_ARBITER_LISTEN_PORT")) { 20 | throw "Invalid configuration parameter: API_ARBITER_LISTEN_PORT"; 21 | } 22 | 23 | const es = new ExpressServer(modules, { 24 | logger: createLogger("Arbiter API", { colors: { debug: "bold blue" } }), 25 | compressionEnabled: false, 26 | cacheEnabled: false, 27 | logLevel: env.string("LOG_LEVEL"), 28 | logRequestsEnabled: env.bool("LOG_API_REQUESTS"), 29 | logIpAddressesEnabled: env.bool("LOG_IP_ADDRESSES") 30 | }); 31 | 32 | es.setLogging(); 33 | 34 | await es.setRouter("../routes/arbiter.index"); 35 | 36 | await es.bind( 37 | env.string("API_ARBITER_LISTEN_HOST"), 38 | env.number("API_ARBITER_LISTEN_PORT") 39 | ); 40 | 41 | const allowPortCheck = env.bool("API_ARBITER_SERVER_PORT_CHECK"); 42 | const serverCheckActions = new ServerCheckActions(modules); 43 | 44 | modules.scheduler.start({ 45 | name: "serverCheckActions", 46 | schedule: expr.EVERY_TEN_SECONDS 47 | }, () => 48 | serverCheckActions.all(allowPortCheck) 49 | ); 50 | 51 | serverCheckActions.all(allowPortCheck); 52 | }; -------------------------------------------------------------------------------- /src/servers/gatewayApi.server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @typedef {import("../app").modules} modules 5 | */ 6 | 7 | const env = require("../utils/env"); 8 | const { createLogger } = require("../utils/logger"); 9 | const ExpressServer = require("../lib/expressServer"); 10 | const TasksActions = require("../actions/tasks.actions"); 11 | 12 | /** 13 | * @param {modules} modules 14 | */ 15 | module.exports = async modules => { 16 | if (!modules.checkComponent("gateway_api")) return; 17 | 18 | const tasksActions = new TasksActions(modules); 19 | 20 | if (!env.number("API_GATEWAY_LISTEN_PORT")) { 21 | throw "Invalid configuration parameter: API_GATEWAY_LISTEN_PORT"; 22 | } 23 | 24 | const es = new ExpressServer(modules, { 25 | logger: createLogger("Gateway API", { colors: { debug: "italic blue" } }), 26 | compressionEnabled: false, 27 | cacheEnabled: false, 28 | logLevel: env.string("LOG_LEVEL"), 29 | logRequestsEnabled: env.bool("LOG_API_REQUESTS"), 30 | logIpAddressesEnabled: env.bool("LOG_IP_ADDRESSES") 31 | }); 32 | 33 | es.setLogging(); 34 | 35 | await modules.pluginsLoader.loadComponent("routers.gatewayApi.before", es); 36 | await es.setRouter("../routes/gateway.index"); 37 | await modules.pluginsLoader.loadComponent("routers.gatewayApi.after", es); 38 | 39 | await es.bind( 40 | env.string("API_GATEWAY_LISTEN_HOST"), 41 | env.number("API_GATEWAY_LISTEN_PORT") 42 | ); 43 | 44 | modules.queue.setModel(modules.queueModel.tasks); 45 | modules.queue.setLogsModel(modules.reportModel.queueTasks); 46 | modules.queue.setHandlers(tasksActions); 47 | }; -------------------------------------------------------------------------------- /src/static/admin/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /src/static/admin/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /src/static/admin/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /src/static/admin/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/static/admin/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/static/admin/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/favicon.ico -------------------------------------------------------------------------------- /src/static/admin/images/icons/giftbox01.bmp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/giftbox01.bmp.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/giftbox02.bmp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/giftbox02.bmp.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_grade_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_grade_0.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_grade_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_grade_1.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_grade_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_grade_2.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_grade_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_grade_3.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_grade_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_grade_4.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_grade_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_grade_5.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_grade_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_grade_6.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_tag_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_tag_0.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_tag_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_tag_1.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_tag_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_tag_2.png -------------------------------------------------------------------------------- /src/static/admin/images/icons/icon_tag_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/icons/icon_tag_3.png -------------------------------------------------------------------------------- /src/static/admin/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/sort_asc.png -------------------------------------------------------------------------------- /src/static/admin/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /src/static/admin/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/sort_both.png -------------------------------------------------------------------------------- /src/static/admin/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/sort_desc.png -------------------------------------------------------------------------------- /src/static/admin/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justkeepquiet/tera-api/c1d81dec6af19de93dbbb6f8dcbfdc0790dddb41/src/static/admin/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_ar.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"هذا الحقل إلزامي",remote:"يرجى تصحيح هذا الحقل للمتابعة",email:"رجاء إدخال عنوان بريد إلكتروني صحيح",url:"رجاء إدخال عنوان موقع إلكتروني صحيح",date:"رجاء إدخال تاريخ صحيح",dateISO:"رجاء إدخال تاريخ صحيح (ISO)",number:"رجاء إدخال عدد بطريقة صحيحة",digits:"رجاء إدخال أرقام فقط",creditcard:"رجاء إدخال رقم بطاقة ائتمان صحيح",equalTo:"رجاء إدخال نفس القيمة",extension:"رجاء إدخال ملف بامتداد موافق عليه",maxlength:a.validator.format("الحد الأقصى لعدد الحروف هو {0}"),minlength:a.validator.format("الحد الأدنى لعدد الحروف هو {0}"),rangelength:a.validator.format("عدد الحروف يجب أن يكون بين {0} و {1}"),range:a.validator.format("رجاء إدخال عدد قيمته بين {0} و {1}"),max:a.validator.format("رجاء إدخال عدد أقل من أو يساوي {0}"),min:a.validator.format("رجاء إدخال عدد أكبر من أو يساوي {0}")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_az.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Bu xana mütləq doldurulmalıdır.",remote:"Zəhmət olmasa, düzgün məna daxil edin.",email:"Zəhmət olmasa, düzgün elektron poçt daxil edin.",url:"Zəhmət olmasa, düzgün URL daxil edin.",date:"Zəhmət olmasa, düzgün tarix daxil edin.",dateISO:"Zəhmət olmasa, düzgün ISO formatlı tarix daxil edin.",number:"Zəhmət olmasa, düzgün rəqəm daxil edin.",digits:"Zəhmət olmasa, yalnız rəqəm daxil edin.",creditcard:"Zəhmət olmasa, düzgün kredit kart nömrəsini daxil edin.",equalTo:"Zəhmət olmasa, eyni mənanı bir daha daxil edin.",extension:"Zəhmət olmasa, düzgün genişlənməyə malik faylı seçin.",maxlength:a.validator.format("Zəhmət olmasa, {0} simvoldan çox olmayaraq daxil edin."),minlength:a.validator.format("Zəhmət olmasa, {0} simvoldan az olmayaraq daxil edin."),rangelength:a.validator.format("Zəhmət olmasa, {0} - {1} aralığında uzunluğa malik simvol daxil edin."),range:a.validator.format("Zəhmət olmasa, {0} - {1} aralığında rəqəm daxil edin."),max:a.validator.format("Zəhmət olmasa, {0} və ondan kiçik rəqəm daxil edin."),min:a.validator.format("Zəhmət olmasa, {0} və ondan böyük rəqəm daxil edin")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_bg.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Полето е задължително.",remote:"Моля, въведете правилната стойност.",email:"Моля, въведете валиден email.",url:"Моля, въведете валидно URL.",date:"Моля, въведете валидна дата.",dateISO:"Моля, въведете валидна дата (ISO).",number:"Моля, въведете валиден номер.",digits:"Моля, въведете само цифри.",creditcard:"Моля, въведете валиден номер на кредитна карта.",equalTo:"Моля, въведете същата стойност отново.",extension:"Моля, въведете стойност с валидно разширение.",maxlength:a.validator.format("Моля, въведете повече от {0} символа."),minlength:a.validator.format("Моля, въведете поне {0} символа."),rangelength:a.validator.format("Моля, въведете стойност с дължина между {0} и {1} символа."),range:a.validator.format("Моля, въведете стойност между {0} и {1}."),max:a.validator.format("Моля, въведете стойност по-малка или равна на {0}."),min:a.validator.format("Моля, въведете стойност по-голяма или равна на {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_bn_BD.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"এই তথ্যটি আবশ্যক।",remote:"এই তথ্যটি ঠিক করুন।",email:"অনুগ্রহ করে একটি সঠিক মেইল ঠিকানা লিখুন।",url:"অনুগ্রহ করে একটি সঠিক লিঙ্ক দিন।",date:"তারিখ সঠিক নয়।",dateISO:"অনুগ্রহ করে একটি সঠিক (ISO) তারিখ লিখুন।",number:"অনুগ্রহ করে একটি সঠিক নম্বর লিখুন।",digits:"এখানে শুধু সংখ্যা ব্যবহার করা যাবে।",creditcard:"অনুগ্রহ করে একটি ক্রেডিট কার্ডের সঠিক নম্বর লিখুন।",equalTo:"একই মান আবার লিখুন।",extension:"সঠিক ধরনের ফাইল আপলোড করুন।",maxlength:a.validator.format("{0}টির বেশি অক্ষর লেখা যাবে না।"),minlength:a.validator.format("{0}টির কম অক্ষর লেখা যাবে না।"),rangelength:a.validator.format("{0} থেকে {1} টি অক্ষর সম্বলিত মান লিখুন।"),range:a.validator.format("{0} থেকে {1} এর মধ্যে একটি মান ব্যবহার করুন।"),max:a.validator.format("অনুগ্রহ করে {0} বা তার চাইতে কম মান ব্যবহার করুন।"),min:a.validator.format("অনুগ্রহ করে {0} বা তার চাইতে বেশি মান ব্যবহার করুন।")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_ca.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Aquest camp és obligatori.",remote:"Si us plau, omple aquest camp.",email:"Si us plau, escriu una adreça de correu-e vàlida",url:"Si us plau, escriu una URL vàlida.",date:"Si us plau, escriu una data vàlida.",dateISO:"Si us plau, escriu una data (ISO) vàlida.",number:"Si us plau, escriu un número enter vàlid.",digits:"Si us plau, escriu només dígits.",creditcard:"Si us plau, escriu un número de tarjeta vàlid.",equalTo:"Si us plau, escriu el mateix valor de nou.",extension:"Si us plau, escriu un valor amb una extensió acceptada.",maxlength:a.validator.format("Si us plau, no escriguis més de {0} caracters."),minlength:a.validator.format("Si us plau, no escriguis menys de {0} caracters."),rangelength:a.validator.format("Si us plau, escriu un valor entre {0} i {1} caracters."),range:a.validator.format("Si us plau, escriu un valor entre {0} i {1}."),max:a.validator.format("Si us plau, escriu un valor menor o igual a {0}."),min:a.validator.format("Si us plau, escriu un valor major o igual a {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_cs.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Tento údaj je povinný.",remote:"Prosím, opravte tento údaj.",email:"Prosím, zadejte platný e-mail.",url:"Prosím, zadejte platné URL.",date:"Prosím, zadejte platné datum.",dateISO:"Prosím, zadejte platné datum (ISO).",number:"Prosím, zadejte číslo.",digits:"Prosím, zadávejte pouze číslice.",creditcard:"Prosím, zadejte číslo kreditní karty.",equalTo:"Prosím, zadejte znovu stejnou hodnotu.",extension:"Prosím, zadejte soubor se správnou příponou.",maxlength:a.validator.format("Prosím, zadejte nejvíce {0} znaků."),minlength:a.validator.format("Prosím, zadejte nejméně {0} znaků."),rangelength:a.validator.format("Prosím, zadejte od {0} do {1} znaků."),range:a.validator.format("Prosím, zadejte hodnotu od {0} do {1}."),max:a.validator.format("Prosím, zadejte hodnotu menší nebo rovnu {0}."),min:a.validator.format("Prosím, zadejte hodnotu větší nebo rovnu {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_da.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Dette felt er påkrævet.",maxlength:a.validator.format("Indtast højst {0} tegn."),minlength:a.validator.format("Indtast mindst {0} tegn."),rangelength:a.validator.format("Indtast mindst {0} og højst {1} tegn."),email:"Indtast en gyldig email-adresse.",url:"Indtast en gyldig URL.",date:"Indtast en gyldig dato.",number:"Indtast et tal.",digits:"Indtast kun cifre.",equalTo:"Indtast den samme værdi igen.",range:a.validator.format("Angiv en værdi mellem {0} og {1}."),max:a.validator.format("Angiv en værdi der højst er {0}."),min:a.validator.format("Angiv en værdi der mindst er {0}."),creditcard:"Indtast et gyldigt kreditkortnummer."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_de.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Dieses Feld ist ein Pflichtfeld.",maxlength:a.validator.format("Geben Sie bitte maximal {0} Zeichen ein."),minlength:a.validator.format("Geben Sie bitte mindestens {0} Zeichen ein."),rangelength:a.validator.format("Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein."),email:"Geben Sie bitte eine gültige E-Mail Adresse ein.",url:"Geben Sie bitte eine gültige URL ein.",date:"Bitte geben Sie ein gültiges Datum ein.",number:"Geben Sie bitte eine Nummer ein.",digits:"Geben Sie bitte nur Ziffern ein.",equalTo:"Bitte denselben Wert wiederholen.",range:a.validator.format("Geben Sie bitte einen Wert zwischen {0} und {1} ein."),max:a.validator.format("Geben Sie bitte einen Wert kleiner oder gleich {0} ein."),min:a.validator.format("Geben Sie bitte einen Wert größer oder gleich {0} ein."),creditcard:"Geben Sie bitte eine gültige Kreditkarten-Nummer ein."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_el.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Αυτό το πεδίο είναι υποχρεωτικό.",remote:"Παρακαλώ διορθώστε αυτό το πεδίο.",email:"Παρακαλώ εισάγετε μια έγκυρη διεύθυνση email.",url:"Παρακαλώ εισάγετε ένα έγκυρο URL.",date:"Παρακαλώ εισάγετε μια έγκυρη ημερομηνία.",dateISO:"Παρακαλώ εισάγετε μια έγκυρη ημερομηνία (ISO).",number:"Παρακαλώ εισάγετε έναν έγκυρο αριθμό.",digits:"Παρακαλώ εισάγετε μόνο αριθμητικά ψηφία.",creditcard:"Παρακαλώ εισάγετε έναν έγκυρο αριθμό πιστωτικής κάρτας.",equalTo:"Παρακαλώ εισάγετε την ίδια τιμή ξανά.",extension:"Παρακαλώ εισάγετε μια τιμή με έγκυρη επέκταση αρχείου.",maxlength:a.validator.format("Παρακαλώ εισάγετε μέχρι και {0} χαρακτήρες."),minlength:a.validator.format("Παρακαλώ εισάγετε τουλάχιστον {0} χαρακτήρες."),rangelength:a.validator.format("Παρακαλώ εισάγετε μια τιμή με μήκος μεταξύ {0} και {1} χαρακτήρων."),range:a.validator.format("Παρακαλώ εισάγετε μια τιμή μεταξύ {0} και {1}."),max:a.validator.format("Παρακαλώ εισάγετε μια τιμή μικρότερη ή ίση του {0}."),min:a.validator.format("Παρακαλώ εισάγετε μια τιμή μεγαλύτερη ή ίση του {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_es.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo es obligatorio.",remote:"Por favor, rellena este campo.",email:"Por favor, escribe una dirección de correo válida.",url:"Por favor, escribe una URL válida.",date:"Por favor, escribe una fecha válida.",dateISO:"Por favor, escribe una fecha (ISO) válida.",number:"Por favor, escribe un número válido.",digits:"Por favor, escribe sólo dígitos.",creditcard:"Por favor, escribe un número de tarjeta válido.",equalTo:"Por favor, escribe el mismo valor de nuevo.",extension:"Por favor, escribe un valor con una extensión aceptada.",maxlength:a.validator.format("Por favor, no escribas más de {0} caracteres."),minlength:a.validator.format("Por favor, no escribas menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escribe un valor entre {0} y {1} caracteres."),range:a.validator.format("Por favor, escribe un valor entre {0} y {1}."),max:a.validator.format("Por favor, escribe un valor menor o igual a {0}."),min:a.validator.format("Por favor, escribe un valor mayor o igual a {0}."),nifES:"Por favor, escribe un NIF válido.",nieES:"Por favor, escribe un NIE válido.",cifES:"Por favor, escribe un CIF válido."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_es_AR.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo es obligatorio.",remote:"Por favor, completá este campo.",email:"Por favor, escribí una dirección de correo válida.",url:"Por favor, escribí una URL válida.",date:"Por favor, escribí una fecha válida.",dateISO:"Por favor, escribí una fecha (ISO) válida.",number:"Por favor, escribí un número entero válido.",digits:"Por favor, escribí sólo dígitos.",creditcard:"Por favor, escribí un número de tarjeta válido.",equalTo:"Por favor, escribí el mismo valor de nuevo.",extension:"Por favor, escribí un valor con una extensión aceptada.",maxlength:a.validator.format("Por favor, no escribas más de {0} caracteres."),minlength:a.validator.format("Por favor, no escribas menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escribí un valor entre {0} y {1} caracteres."),range:a.validator.format("Por favor, escribí un valor entre {0} y {1}."),max:a.validator.format("Por favor, escribí un valor menor o igual a {0}."),min:a.validator.format("Por favor, escribí un valor mayor o igual a {0}."),nifES:"Por favor, escribí un NIF válido.",nieES:"Por favor, escribí un NIE válido.",cifES:"Por favor, escribí un CIF válido."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_es_PE.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo es obligatorio.",remote:"Por favor, llene este campo.",email:"Por favor, escriba un correo electrónico válido.",url:"Por favor, escriba una URL válida.",date:"Por favor, escriba una fecha válida.",dateISO:"Por favor, escriba una fecha (ISO) válida.",number:"Por favor, escriba un número válido.",digits:"Por favor, escriba sólo dígitos.",creditcard:"Por favor, escriba un número de tarjeta válido.",equalTo:"Por favor, escriba el mismo valor de nuevo.",extension:"Por favor, escriba un valor con una extensión permitida.",maxlength:a.validator.format("Por favor, no escriba más de {0} caracteres."),minlength:a.validator.format("Por favor, no escriba menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escriba un valor entre {0} y {1} caracteres."),range:a.validator.format("Por favor, escriba un valor entre {0} y {1}."),max:a.validator.format("Por favor, escriba un valor menor o igual a {0}."),min:a.validator.format("Por favor, escriba un valor mayor o igual a {0}."),nifES:"Por favor, escriba un NIF válido.",nieES:"Por favor, escriba un NIE válido.",cifES:"Por favor, escriba un CIF válido."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_et.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"See väli peab olema täidetud.",maxlength:a.validator.format("Palun sisestage vähem kui {0} tähemärki."),minlength:a.validator.format("Palun sisestage vähemalt {0} tähemärki."),rangelength:a.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1} tähemärki."),email:"Palun sisestage korrektne e-maili aadress.",url:"Palun sisestage korrektne URL.",date:"Palun sisestage korrektne kuupäev.",dateISO:"Palun sisestage korrektne kuupäev (YYYY-MM-DD).",number:"Palun sisestage korrektne number.",digits:"Palun sisestage ainult numbreid.",equalTo:"Palun sisestage sama väärtus uuesti.",range:a.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1}."),max:a.validator.format("Palun sisestage väärtus, mis on väiksem või võrdne arvuga {0}."),min:a.validator.format("Palun sisestage väärtus, mis on suurem või võrdne arvuga {0}."),creditcard:"Palun sisestage korrektne krediitkaardi number."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_eu.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Eremu hau beharrezkoa da.",remote:"Mesedez, bete eremu hau.",email:"Mesedez, idatzi baliozko posta helbide bat.",url:"Mesedez, idatzi baliozko URL bat.",date:"Mesedez, idatzi baliozko data bat.",dateISO:"Mesedez, idatzi baliozko (ISO) data bat.",number:"Mesedez, idatzi baliozko zenbaki oso bat.",digits:"Mesedez, idatzi digituak soilik.",creditcard:"Mesedez, idatzi baliozko txartel zenbaki bat.",equalTo:"Mesedez, idatzi berdina berriro ere.",extension:"Mesedez, idatzi onartutako luzapena duen balio bat.",maxlength:a.validator.format("Mesedez, ez idatzi {0} karaktere baino gehiago."),minlength:a.validator.format("Mesedez, ez idatzi {0} karaktere baino gutxiago."),rangelength:a.validator.format("Mesedez, idatzi {0} eta {1} karaktere arteko balio bat."),range:a.validator.format("Mesedez, idatzi {0} eta {1} arteko balio bat."),max:a.validator.format("Mesedez, idatzi {0} edo txikiagoa den balio bat."),min:a.validator.format("Mesedez, idatzi {0} edo handiagoa den balio bat.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_fa.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"تکمیل این فیلد اجباری است.",remote:"لطفا این فیلد را تصحیح کنید.",email:".لطفا یک ایمیل صحیح وارد کنید",url:"لطفا آدرس صحیح وارد کنید.",date:"لطفا یک تاریخ صحیح وارد کنید",dateFA:"لطفا یک تاریخ صحیح وارد کنید",dateISO:"لطفا تاریخ صحیح وارد کنید (ISO).",number:"لطفا عدد صحیح وارد کنید.",digits:"لطفا تنها رقم وارد کنید",creditcard:"لطفا کریدیت کارت صحیح وارد کنید.",equalTo:"لطفا مقدار برابری وارد کنید",extension:"لطفا مقداری وارد کنید که ",maxlength:a.validator.format("لطفا بیشتر از {0} حرف وارد نکنید."),minlength:a.validator.format("لطفا کمتر از {0} حرف وارد نکنید."),rangelength:a.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."),range:a.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."),max:a.validator.format("لطفا مقداری کمتر از {0} وارد کنید."),min:a.validator.format("لطفا مقداری بیشتر از {0} وارد کنید."),minWords:a.validator.format("لطفا حداقل {0} کلمه وارد کنید."),maxWords:a.validator.format("لطفا حداکثر {0} کلمه وارد کنید.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_fi.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Tämä kenttä on pakollinen.",email:"Syötä oikea sähköpostiosoite.",url:"Syötä oikea URL-osoite.",date:"Syötä oikea päivämäärä.",dateISO:"Syötä oikea päivämäärä muodossa VVVV-KK-PP.",number:"Syötä luku.",creditcard:"Syötä voimassa oleva luottokorttinumero.",digits:"Syötä pelkästään numeroita.",equalTo:"Syötä sama arvo uudestaan.",maxlength:a.validator.format("Voit syöttää enintään {0} merkkiä."),minlength:a.validator.format("Vähintään {0} merkkiä."),rangelength:a.validator.format("Syötä vähintään {0} ja enintään {1} merkkiä."),range:a.validator.format("Syötä arvo väliltä {0}–{1}."),max:a.validator.format("Syötä arvo, joka on enintään {0}."),min:a.validator.format("Syötä arvo, joka on vähintään {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_ge.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"ეს ველი სავალდებულოა",remote:"გთხოვთ შეასწოროთ.",email:"გთხოვთ შეიყვანოთ სწორი ფორმატით.",url:"გთხოვთ შეიყვანოთ სწორი ფორმატით.",date:"გთხოვთ შეიყვანოთ სწორი თარიღი.",dateISO:"გთხოვთ შეიყვანოთ სწორი ფორმატით (ISO).",number:"გთხოვთ შეიყვანოთ რიცხვი.",digits:"დაშვებულია მხოლოდ ციფრები.",creditcard:"გთხოვთ შეიყვანოთ სწორი ფორმატის ბარათის კოდი.",equalTo:"გთხოვთ შეიყვანოთ იგივე მნიშვნელობა.",maxlength:a.validator.format("გთხოვთ შეიყვანოთ არა უმეტეს {0} სიმბოლოსი."),minlength:a.validator.format("შეიყვანეთ მინიმუმ {0} სიმბოლო."),rangelength:a.validator.format("გთხოვთ შეიყვანოთ {0} -დან {1} -მდე რაოდენობის სიმბოლოები."),range:a.validator.format("შეიყვანეთ {0} -სა {1} -ს შორის."),max:a.validator.format("გთხოვთ შეიყვანოთ მნიშვნელობა ნაკლები ან ტოლი {0} -ს."),min:a.validator.format("გთხოვთ შეიყვანოთ მნიშვნელობა მეტი ან ტოლი {0} -ს.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_gl.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return function(a){a.extend(a.validator.messages,{required:"Este campo é obrigatorio.",remote:"Por favor, cubre este campo.",email:"Por favor, escribe unha dirección de correo válida.",url:"Por favor, escribe unha URL válida.",date:"Por favor, escribe unha data válida.",dateISO:"Por favor, escribe unha data (ISO) válida.",number:"Por favor, escribe un número válido.",digits:"Por favor, escribe só díxitos.",creditcard:"Por favor, escribe un número de tarxeta válido.",equalTo:"Por favor, escribe o mesmo valor de novo.",extension:"Por favor, escribe un valor cunha extensión aceptada.",maxlength:a.validator.format("Por favor, non escribas máis de {0} caracteres."),minlength:a.validator.format("Por favor, non escribas menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escribe un valor entre {0} e {1} caracteres."),range:a.validator.format("Por favor, escribe un valor entre {0} e {1}."),max:a.validator.format("Por favor, escribe un valor menor ou igual a {0}."),min:a.validator.format("Por favor, escribe un valor maior ou igual a {0}."),nifES:"Por favor, escribe un NIF válido.",nieES:"Por favor, escribe un NIE válido.",cifES:"Por favor, escribe un CIF válido."})}(jQuery),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_he.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"השדה הזה הינו שדה חובה",remote:"נא לתקן שדה זה",email:'נא למלא כתובת דוא"ל חוקית',url:"נא למלא כתובת אינטרנט חוקית",date:"נא למלא תאריך חוקי",dateISO:"נא למלא תאריך חוקי (ISO)",number:"נא למלא מספר",digits:"נא למלא רק מספרים",creditcard:"נא למלא מספר כרטיס אשראי חוקי",equalTo:"נא למלא את אותו ערך שוב",extension:"נא למלא ערך עם סיומת חוקית",maxlength:a.validator.format(".נא לא למלא יותר מ- {0} תווים"),minlength:a.validator.format("נא למלא לפחות {0} תווים"),rangelength:a.validator.format("נא למלא ערך בין {0} ל- {1} תווים"),range:a.validator.format("נא למלא ערך בין {0} ל- {1}"),max:a.validator.format("נא למלא ערך קטן או שווה ל- {0}"),min:a.validator.format("נא למלא ערך גדול או שווה ל- {0}")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_hr.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Ovo polje je obavezno.",remote:"Ovo polje treba popraviti.",email:"Unesite ispravnu e-mail adresu.",url:"Unesite ispravan URL.",date:"Unesite ispravan datum.",dateISO:"Unesite ispravan datum (ISO).",number:"Unesite ispravan broj.",digits:"Unesite samo brojeve.",creditcard:"Unesite ispravan broj kreditne kartice.",equalTo:"Unesite ponovo istu vrijednost.",extension:"Unesite vrijednost sa ispravnom ekstenzijom.",maxlength:a.validator.format("Maksimalni broj znakova je {0} ."),minlength:a.validator.format("Minimalni broj znakova je {0} ."),rangelength:a.validator.format("Unesite vrijednost između {0} i {1} znakova."),range:a.validator.format("Unesite vrijednost između {0} i {1}."),max:a.validator.format("Unesite vrijednost manju ili jednaku {0}."),min:a.validator.format("Unesite vrijednost veću ili jednaku {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_hu.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Kötelező megadni.",maxlength:a.validator.format("Legfeljebb {0} karakter hosszú legyen."),minlength:a.validator.format("Legalább {0} karakter hosszú legyen."),rangelength:a.validator.format("Legalább {0} és legfeljebb {1} karakter hosszú legyen."),email:"Érvényes e-mail címnek kell lennie.",url:"Érvényes URL-nek kell lennie.",date:"Dátumnak kell lennie.",number:"Számnak kell lennie.",digits:"Csak számjegyek lehetnek.",equalTo:"Meg kell egyeznie a két értéknek.",range:a.validator.format("{0} és {1} közé kell esnie."),max:a.validator.format("Nem lehet nagyobb, mint {0}."),min:a.validator.format("Nem lehet kisebb, mint {0}."),creditcard:"Érvényes hitelkártyaszámnak kell lennie.",remote:"Kérem javítsa ki ezt a mezőt.",dateISO:"Kérem írjon be egy érvényes dátumot (ISO).",step:a.validator.format("A {0} egyik többszörösét adja meg.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_hy_AM.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Պարտադիր լրացման դաշտ",remote:"Ներմուծեք ճիշտ արժեքը",email:"Ներմուծեք վավեր էլեկտրոնային փոստի հասցե",url:"Ներմուծեք վավեր URL",date:"Ներմուծեք վավեր ամսաթիվ",dateISO:"Ներմուծեք ISO ֆորմատով վավեր ամսաթիվ։",number:"Ներմուծեք թիվ",digits:"Ներմուծեք միայն թվեր",creditcard:"Ներմուծեք ճիշտ բանկային քարտի համար",equalTo:"Ներմուծեք միևնուն արժեքը ևս մեկ անգամ",extension:"Ընտրեք ճիշտ ընդլանումով ֆայլ",maxlength:a.validator.format("Ներմուծեք ոչ ավել քան {0} նիշ"),minlength:a.validator.format("Ներմուծեք ոչ պակաս քան {0} նիշ"),rangelength:a.validator.format("Ներմուծեք {0}֊ից {1} երկարությամբ արժեք"),range:a.validator.format("Ներմուծեք թիվ {0}֊ից {1} միջակայքում"),max:a.validator.format("Ներմուծեք թիվ, որը փոքր կամ հավասար է {0}֊ին"),min:a.validator.format("Ներմուծեք թիվ, որը մեծ կամ հավասար է {0}֊ին")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_id.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Kolom ini diperlukan.",remote:"Harap benarkan kolom ini.",email:"Silakan masukkan format email yang benar.",url:"Silakan masukkan format URL yang benar.",date:"Silakan masukkan format tanggal yang benar.",dateISO:"Silakan masukkan format tanggal(ISO) yang benar.",number:"Silakan masukkan angka yang benar.",digits:"Harap masukan angka saja.",creditcard:"Harap masukkan format kartu kredit yang benar.",equalTo:"Harap masukkan nilai yg sama dengan sebelumnya.",maxlength:a.validator.format("Input dibatasi hanya {0} karakter."),minlength:a.validator.format("Input tidak kurang dari {0} karakter."),rangelength:a.validator.format("Panjang karakter yg diizinkan antara {0} dan {1} karakter."),range:a.validator.format("Harap masukkan nilai antara {0} dan {1}."),max:a.validator.format("Harap masukkan nilai lebih kecil atau sama dengan {0}."),min:a.validator.format("Harap masukkan nilai lebih besar atau sama dengan {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_is.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Þessi reitur er nauðsynlegur.",remote:"Lagaðu þennan reit.",maxlength:a.validator.format("Sláðu inn mest {0} stafi."),minlength:a.validator.format("Sláðu inn minnst {0} stafi."),rangelength:a.validator.format("Sláðu inn minnst {0} og mest {1} stafi."),email:"Sláðu inn gilt netfang.",url:"Sláðu inn gilda vefslóð.",date:"Sláðu inn gilda dagsetningu.",number:"Sláðu inn tölu.",digits:"Sláðu inn tölustafi eingöngu.",equalTo:"Sláðu sama gildi inn aftur.",range:a.validator.format("Sláðu inn gildi milli {0} og {1}."),max:a.validator.format("Sláðu inn gildi sem er minna en eða jafnt og {0}."),min:a.validator.format("Sláðu inn gildi sem er stærra en eða jafnt og {0}."),creditcard:"Sláðu inn gilt greiðslukortanúmer."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_it.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Campo obbligatorio",remote:"Controlla questo campo",email:"Inserisci un indirizzo email valido",url:"Inserisci un indirizzo web valido",date:"Inserisci una data valida",dateISO:"Inserisci una data valida (ISO)",number:"Inserisci un numero valido",digits:"Inserisci solo numeri",creditcard:"Inserisci un numero di carta di credito valido",equalTo:"Il valore non corrisponde",extension:"Inserisci un valore con un'estensione valida",maxlength:a.validator.format("Non inserire più di {0} caratteri"),minlength:a.validator.format("Inserisci almeno {0} caratteri"),rangelength:a.validator.format("Inserisci un valore compreso tra {0} e {1} caratteri"),range:a.validator.format("Inserisci un valore compreso tra {0} e {1}"),max:a.validator.format("Inserisci un valore minore o uguale a {0}"),min:a.validator.format("Inserisci un valore maggiore o uguale a {0}"),nifES:"Inserisci un NIF valido",nieES:"Inserisci un NIE valido",cifES:"Inserisci un CIF valido",currency:"Inserisci una valuta valida"}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_ja.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"このフィールドは必須です。",remote:"このフィールドを修正してください。",email:"有効なEメールアドレスを入力してください。",url:"有効なURLを入力してください。",date:"有効な日付を入力してください。",dateISO:"有効な日付(ISO)を入力してください。",number:"有効な数字を入力してください。",digits:"数字のみを入力してください。",creditcard:"有効なクレジットカード番号を入力してください。",equalTo:"同じ値をもう一度入力してください。",extension:"有効な拡張子を含む値を入力してください。",maxlength:a.validator.format("{0} 文字以内で入力してください。"),minlength:a.validator.format("{0} 文字以上で入力してください。"),rangelength:a.validator.format("{0} 文字から {1} 文字までの値を入力してください。"),range:a.validator.format("{0} から {1} までの値を入力してください。"),step:a.validator.format("{0} の倍数を入力してください。"),max:a.validator.format("{0} 以下の値を入力してください。"),min:a.validator.format("{0} 以上の値を入力してください。")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_ka.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"ამ ველის შევსება აუცილებელია.",remote:"გთხოვთ მიუთითოთ სწორი მნიშვნელობა.",email:"გთხოვთ მიუთითოთ ელ-ფოსტის კორექტული მისამართი.",url:"გთხოვთ მიუთითოთ კორექტული URL.",date:"გთხოვთ მიუთითოთ კორექტული თარიღი.",dateISO:"გთხოვთ მიუთითოთ კორექტული თარიღი ISO ფორმატში.",number:"გთხოვთ მიუთითოთ ციფრი.",digits:"გთხოვთ მიუთითოთ მხოლოდ ციფრები.",creditcard:"გთხოვთ მიუთითოთ საკრედიტო ბარათის კორექტული ნომერი.",equalTo:"გთხოვთ მიუთითოთ ასეთივე მნიშვნელობა კიდევ ერთხელ.",extension:"გთხოვთ აირჩიოთ ფაილი კორექტული გაფართოებით.",maxlength:a.validator.format("დასაშვებია არაუმეტეს {0} სიმბოლო."),minlength:a.validator.format("აუცილებელია შეიყვანოთ მინიმუმ {0} სიმბოლო."),rangelength:a.validator.format("ტექსტში სიმბოლოების რაოდენობა უნდა იყოს {0}-დან {1}-მდე."),range:a.validator.format("გთხოვთ შეიყვანოთ ციფრი {0}-დან {1}-მდე."),max:a.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც ნაკლებია ან უდრის {0}-ს."),min:a.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც მეტია ან უდრის {0}-ს.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_kk.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Бұл өрісті міндетті түрде толтырыңыз.",remote:"Дұрыс мағына енгізуіңізді сұраймыз.",email:"Нақты электронды поштаңызды енгізуіңізді сұраймыз.",url:"Нақты URL-ды енгізуіңізді сұраймыз.",date:"Нақты URL-ды енгізуіңізді сұраймыз.",dateISO:"Нақты ISO форматымен сәйкес датасын енгізуіңізді сұраймыз.",number:"Күнді енгізуіңізді сұраймыз.",digits:"Тек қана сандарды енгізуіңізді сұраймыз.",creditcard:"Несие картасының нөмірін дұрыс енгізуіңізді сұраймыз.",equalTo:"Осы мәнді қайта енгізуіңізді сұраймыз.",extension:"Файлдың кеңейтуін дұрыс таңдаңыз.",maxlength:a.validator.format("Ұзындығы {0} символдан көр болмасын."),minlength:a.validator.format("Ұзындығы {0} символдан аз болмасын."),rangelength:a.validator.format("Ұзындығы {0}-{1} дейін мән енгізуіңізді сұраймыз."),range:a.validator.format("Пожалуйста, введите число от {0} до {1}. - {0} - {1} санын енгізуіңізді сұраймыз."),max:a.validator.format("{0} аз немесе тең санын енгізуіңіді сұраймыз."),min:a.validator.format("{0} көп немесе тең санын енгізуіңізді сұраймыз.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_ko.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"필수 항목입니다.",remote:"항목을 수정하세요.",email:"유효하지 않은 E-Mail주소입니다.",url:"유효하지 않은 URL입니다.",date:"올바른 날짜를 입력하세요.",dateISO:"올바른 날짜(ISO)를 입력하세요.",number:"유효한 숫자가 아닙니다.",digits:"숫자만 입력 가능합니다.",creditcard:"신용카드 번호가 바르지 않습니다.",equalTo:"같은 값을 다시 입력하세요.",extension:"올바른 확장자가 아닙니다.",maxlength:a.validator.format("{0}자를 넘을 수 없습니다. "),minlength:a.validator.format("{0}자 이상 입력하세요."),rangelength:a.validator.format("문자 길이가 {0} 에서 {1} 사이의 값을 입력하세요."),range:a.validator.format("{0} 에서 {1} 사이의 값을 입력하세요."),max:a.validator.format("{0} 이하의 값을 입력하세요."),min:a.validator.format("{0} 이상의 값을 입력하세요.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_lt.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Šis laukas yra privalomas.",remote:"Prašau pataisyti šį lauką.",email:"Prašau įvesti teisingą elektroninio pašto adresą.",url:"Prašau įvesti teisingą URL.",date:"Prašau įvesti teisingą datą.",dateISO:"Prašau įvesti teisingą datą (ISO).",number:"Prašau įvesti teisingą skaičių.",digits:"Prašau naudoti tik skaitmenis.",creditcard:"Prašau įvesti teisingą kreditinės kortelės numerį.",equalTo:"Prašau įvestį tą pačią reikšmę dar kartą.",extension:"Prašau įvesti reikšmę su teisingu plėtiniu.",maxlength:a.validator.format("Prašau įvesti ne daugiau kaip {0} simbolių."),minlength:a.validator.format("Prašau įvesti bent {0} simbolius."),rangelength:a.validator.format("Prašau įvesti reikšmes, kurių ilgis nuo {0} iki {1} simbolių."),range:a.validator.format("Prašau įvesti reikšmę intervale nuo {0} iki {1}."),max:a.validator.format("Prašau įvesti reikšmę mažesnę arba lygią {0}."),min:a.validator.format("Prašau įvesti reikšmę didesnę arba lygią {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_lv.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Šis lauks ir obligāts.",remote:"Lūdzu, pārbaudiet šo lauku.",email:"Lūdzu, ievadiet derīgu e-pasta adresi.",url:"Lūdzu, ievadiet derīgu URL adresi.",date:"Lūdzu, ievadiet derīgu datumu.",dateISO:"Lūdzu, ievadiet derīgu datumu (ISO).",number:"Lūdzu, ievadiet derīgu numuru.",digits:"Lūdzu, ievadiet tikai ciparus.",creditcard:"Lūdzu, ievadiet derīgu kredītkartes numuru.",equalTo:"Lūdzu, ievadiet to pašu vēlreiz.",extension:"Lūdzu, ievadiet vērtību ar derīgu paplašinājumu.",maxlength:a.validator.format("Lūdzu, ievadiet ne vairāk kā {0} rakstzīmes."),minlength:a.validator.format("Lūdzu, ievadiet vismaz {0} rakstzīmes."),rangelength:a.validator.format("Lūdzu ievadiet {0} līdz {1} rakstzīmes."),range:a.validator.format("Lūdzu, ievadiet skaitli no {0} līdz {1}."),max:a.validator.format("Lūdzu, ievadiet skaitli, kurš ir mazāks vai vienāds ar {0}."),min:a.validator.format("Lūdzu, ievadiet skaitli, kurš ir lielāks vai vienāds ar {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_mk.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Полето е задолжително.",remote:"Поправете го ова поле",email:"Внесете правилна e-mail адреса",url:"Внесете правилен URL.",date:"Внесете правилен датум",dateISO:"Внесете правилен датум (ISO).",number:"Внесете правилен број.",digits:"Внесете само бројки.",creditcard:"Внесете правилен број на кредитната картичка.",equalTo:"Внесете ја истата вредност повторно.",extension:"Внесете вредност со соодветна екстензија.",maxlength:a.validator.format("Внесете максимално {0} знаци."),minlength:a.validator.format("Внесете барем {0} знаци."),rangelength:a.validator.format("Внесете вредност со должина помеѓу {0} и {1} знаци."),range:a.validator.format("Внесете вредност помеѓу {0} и {1}."),max:a.validator.format("Внесете вредност помала или еднаква на {0}."),min:a.validator.format("Внесете вредност поголема или еднаква на {0}")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_my.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Medan ini diperlukan.",remote:"Sila betulkan medan ini.",email:"Sila masukkan alamat emel yang betul.",url:"Sila masukkan URL yang betul.",date:"Sila masukkan tarikh yang betul.",dateISO:"Sila masukkan tarikh(ISO) yang betul.",number:"Sila masukkan nombor yang betul.",digits:"Sila masukkan nilai digit sahaja.",creditcard:"Sila masukkan nombor kredit kad yang betul.",equalTo:"Sila masukkan nilai yang sama semula.",extension:"Sila masukkan nilai yang telah diterima.",maxlength:a.validator.format("Sila masukkan tidak lebih dari {0} aksara."),minlength:a.validator.format("Sila masukkan sekurang-kurangnya {0} aksara."),rangelength:a.validator.format("Sila masukkan antara {0} dan {1} panjang aksara."),range:a.validator.format("Sila masukkan nilai antara {0} dan {1} aksara."),max:a.validator.format("Sila masukkan nilai yang kurang atau sama dengan {0}."),min:a.validator.format("Sila masukkan nilai yang lebih atau sama dengan {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_no.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Dette feltet er obligatorisk.",maxlength:a.validator.format("Maksimalt {0} tegn."),minlength:a.validator.format("Minimum {0} tegn."),rangelength:a.validator.format("Angi minimum {0} og maksimum {1} tegn."),email:"Oppgi en gyldig epostadresse.",url:"Angi en gyldig URL.",date:"Angi en gyldig dato.",dateISO:"Angi en gyldig dato (&ARING;&ARING;&ARING;&ARING;-MM-DD).",dateSE:"Angi en gyldig dato.",number:"Angi et gyldig nummer.",numberSE:"Angi et gyldig nummer.",digits:"Skriv kun tall.",equalTo:"Skriv samme verdi igjen.",range:a.validator.format("Angi en verdi mellom {0} og {1}."),max:a.validator.format("Angi en verdi som er mindre eller lik {0}."),min:a.validator.format("Angi en verdi som er større eller lik {0}."),step:a.validator.format("Angi en verdi ganger {0}."),creditcard:"Angi et gyldig kredittkortnummer."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_pl.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"To pole jest wymagane.",remote:"Proszę o wypełnienie tego pola.",email:"Proszę o podanie prawidłowego adresu email.",url:"Proszę o podanie prawidłowego URL.",date:"Proszę o podanie prawidłowej daty.",dateISO:"Proszę o podanie prawidłowej daty (ISO).",number:"Proszę o podanie prawidłowej liczby.",digits:"Proszę o podanie samych cyfr.",creditcard:"Proszę o podanie prawidłowej karty kredytowej.",equalTo:"Proszę o podanie tej samej wartości ponownie.",extension:"Proszę o podanie wartości z prawidłowym rozszerzeniem.",nipPL:"Proszę o podanie prawidłowego numeru NIP.",maxlength:a.validator.format("Proszę o podanie nie więcej niż {0} znaków."),minlength:a.validator.format("Proszę o podanie przynajmniej {0} znaków."),rangelength:a.validator.format("Proszę o podanie wartości o długości od {0} do {1} znaków."),range:a.validator.format("Proszę o podanie wartości z przedziału od {0} do {1}."),max:a.validator.format("Proszę o podanie wartości mniejszej bądź równej {0}."),min:a.validator.format("Proszę o podanie wartości większej bądź równej {0}."),pattern:a.validator.format("Pole zawiera niedozwolone znaki.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_pt_PT.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Campo de preenchimento obrigatório.",remote:"Por favor, corrija este campo.",email:"Por favor, introduza um endereço eletrónico válido.",url:"Por favor, introduza um URL válido.",date:"Por favor, introduza uma data válida.",dateISO:"Por favor, introduza uma data válida (ISO).",number:"Por favor, introduza um número válido.",digits:"Por favor, introduza apenas dígitos.",creditcard:"Por favor, introduza um número de cartão de crédito válido.",equalTo:"Por favor, introduza de novo o mesmo valor.",extension:"Por favor, introduza um ficheiro com uma extensão válida.",maxlength:a.validator.format("Por favor, não introduza mais do que {0} caracteres."),minlength:a.validator.format("Por favor, introduza pelo menos {0} caracteres."),rangelength:a.validator.format("Por favor, introduza entre {0} e {1} caracteres."),range:a.validator.format("Por favor, introduza um valor entre {0} e {1}."),max:a.validator.format("Por favor, introduza um valor menor ou igual a {0}."),min:a.validator.format("Por favor, introduza um valor maior ou igual a {0}."),nifES:"Por favor, introduza um NIF válido.",nieES:"Por favor, introduza um NIE válido.",cifES:"Por favor, introduza um CIF válido."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_ro.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Acest câmp este obligatoriu.",remote:"Te rugăm să completezi acest câmp.",email:"Te rugăm să introduci o adresă de email validă",url:"Te rugăm sa introduci o adresă URL validă.",date:"Te rugăm să introduci o dată corectă.",dateISO:"Te rugăm să introduci o dată (ISO) corectă.",number:"Te rugăm să introduci un număr întreg valid.",digits:"Te rugăm să introduci doar cifre.",creditcard:"Te rugăm să introduci un numar de carte de credit valid.",equalTo:"Te rugăm să reintroduci valoarea.",extension:"Te rugăm să introduci o valoare cu o extensie validă.",maxlength:a.validator.format("Te rugăm să nu introduci mai mult de {0} caractere."),minlength:a.validator.format("Te rugăm să introduci cel puțin {0} caractere."),rangelength:a.validator.format("Te rugăm să introduci o valoare între {0} și {1} caractere."),range:a.validator.format("Te rugăm să introduci o valoare între {0} și {1}."),max:a.validator.format("Te rugăm să introduci o valoare egal sau mai mică decât {0}."),min:a.validator.format("Te rugăm să introduci o valoare egal sau mai mare decât {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_ru.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Это поле необходимо заполнить.",remote:"Пожалуйста, введите правильное значение.",email:"Пожалуйста, введите корректный адрес электронной почты.",url:"Пожалуйста, введите корректный URL.",date:"Пожалуйста, введите корректную дату.",dateISO:"Пожалуйста, введите корректную дату в формате ISO.",number:"Пожалуйста, введите число.",digits:"Пожалуйста, вводите только цифры.",creditcard:"Пожалуйста, введите правильный номер кредитной карты.",equalTo:"Пожалуйста, введите такое же значение ещё раз.",extension:"Пожалуйста, выберите файл с правильным расширением.",maxlength:a.validator.format("Пожалуйста, введите не больше {0} символов."),minlength:a.validator.format("Пожалуйста, введите не меньше {0} символов."),rangelength:a.validator.format("Пожалуйста, введите значение длиной от {0} до {1} символов."),range:a.validator.format("Пожалуйста, введите число от {0} до {1}."),max:a.validator.format("Пожалуйста, введите число, меньшее или равное {0}."),min:a.validator.format("Пожалуйста, введите число, большее или равное {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_sd.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"هنن جاين جي ضرورت آهي",remote:"هنن جاين جي ضرورت آهي",email:"لکيل اي ميل غلط آهي",url:"لکيل ايڊريس غلط آهي",date:"لکيل تاريخ غلط آهي",dateISO:"جي معيار جي مطابق نه آهي (ISO) لکيل تاريخ",number:"لکيل انگ صحيح ناهي",digits:"رڳو انگ داخل ڪري سگهجي ٿو",creditcard:"لکيل ڪارڊ نمبر صحيح نه آهي",equalTo:"داخل ٿيل ڀيٽ صحيح نه آهي",extension:"لکيل غلط آهي",maxlength:a.validator.format("وڌ کان وڌ {0} جي داخلا ڪري سگهجي ٿي"),minlength:a.validator.format("گهٽ ۾ گهٽ {0} جي داخلا ڪرڻ ضروري آهي"),rangelength:a.validator.format("داخلا جو {0} ۽ {1}جي وچ ۾ هجڻ ضروري آهي"),range:a.validator.format("داخلا جو {0} ۽ {1}جي وچ ۾ هجڻ ضروري آهي"),max:a.validator.format("وڌ کان وڌ {0} جي داخلا ڪري سگهجي ٿي"),min:a.validator.format("گهٽ ۾ گهٽ {0} جي داخلا ڪرڻ ضروري آهي")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_si.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"To polje je obvezno.",remote:"Vpis v tem polju ni v pravi obliki.",email:"Prosimo, vnesite pravi email naslov.",url:"Prosimo, vnesite pravi URL.",date:"Prosimo, vnesite pravi datum.",dateISO:"Prosimo, vnesite pravi datum (ISO).",number:"Prosimo, vnesite pravo številko.",digits:"Prosimo, vnesite samo številke.",creditcard:"Prosimo, vnesite pravo številko kreditne kartice.",equalTo:"Prosimo, ponovno vnesite enako vsebino.",extension:"Prosimo, vnesite vsebino z pravo končnico.",maxlength:a.validator.format("Prosimo, da ne vnašate več kot {0} znakov."),minlength:a.validator.format("Prosimo, vnesite vsaj {0} znakov."),rangelength:a.validator.format("Prosimo, vnesite od {0} do {1} znakov."),range:a.validator.format("Prosimo, vnesite vrednost med {0} in {1}."),max:a.validator.format("Prosimo, vnesite vrednost manjšo ali enako {0}."),min:a.validator.format("Prosimo, vnesite vrednost večjo ali enako {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_sk.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Povinné zadať.",maxlength:a.validator.format("Maximálne {0} znakov."),minlength:a.validator.format("Minimálne {0} znakov."),rangelength:a.validator.format("Minimálne {0} a maximálne {1} znakov."),email:"E-mailová adresa musí byť platná.",url:"URL musí byť platná.",date:"Musí byť dátum.",number:"Musí byť číslo.",digits:"Môže obsahovať iba číslice.",equalTo:"Dve hodnoty sa musia rovnať.",range:a.validator.format("Musí byť medzi {0} a {1}."),max:a.validator.format("Nemôže byť viac ako {0}."),min:a.validator.format("Nemôže byť menej ako {0}."),creditcard:"Číslo platobnej karty musí byť platné."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_sl.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"To polje je obvezno.",remote:"Prosimo popravite to polje.",email:"Prosimo vnesite veljaven email naslov.",url:"Prosimo vnesite veljaven URL naslov.",date:"Prosimo vnesite veljaven datum.",dateISO:"Prosimo vnesite veljaven ISO datum.",number:"Prosimo vnesite veljavno število.",digits:"Prosimo vnesite samo števila.",creditcard:"Prosimo vnesite veljavno številko kreditne kartice.",equalTo:"Prosimo ponovno vnesite vrednost.",extension:"Prosimo vnesite vrednost z veljavno končnico.",maxlength:a.validator.format("Prosimo vnesite največ {0} znakov."),minlength:a.validator.format("Prosimo vnesite najmanj {0} znakov."),rangelength:a.validator.format("Prosimo vnesite najmanj {0} in največ {1} znakov."),range:a.validator.format("Prosimo vnesite vrednost med {0} in {1}."),max:a.validator.format("Prosimo vnesite vrednost manjše ali enako {0}."),min:a.validator.format("Prosimo vnesite vrednost večje ali enako {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_sr.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Поље је обавезно.",remote:"Средите ово поље.",email:"Унесите исправну и-мејл адресу.",url:"Унесите исправан URL.",date:"Унесите исправан датум.",dateISO:"Унесите исправан датум (ISO).",number:"Унесите исправан број.",digits:"Унесите само цифе.",creditcard:"Унесите исправан број кредитне картице.",equalTo:"Унесите исту вредност поново.",extension:"Унесите вредност са одговарајућом екстензијом.",maxlength:a.validator.format("Унесите мање од {0} карактера."),minlength:a.validator.format("Унесите барем {0} карактера."),rangelength:a.validator.format("Унесите вредност дугачку између {0} и {1} карактера."),range:a.validator.format("Унесите вредност између {0} и {1}."),max:a.validator.format("Унесите вредност мању или једнаку {0}."),min:a.validator.format("Унесите вредност већу или једнаку {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_sr_lat.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Polje je obavezno.",remote:"Sredite ovo polje.",email:"Unesite ispravnu e-mail adresu",url:"Unesite ispravan URL.",date:"Unesite ispravan datum.",dateISO:"Unesite ispravan datum (ISO).",number:"Unesite ispravan broj.",digits:"Unesite samo cifre.",creditcard:"Unesite ispravan broj kreditne kartice.",equalTo:"Unesite istu vrednost ponovo.",extension:"Unesite vrednost sa odgovarajućom ekstenzijom.",maxlength:a.validator.format("Unesite manje od {0} karaktera."),minlength:a.validator.format("Unesite barem {0} karaktera."),rangelength:a.validator.format("Unesite vrednost dugačku između {0} i {1} karaktera."),range:a.validator.format("Unesite vrednost između {0} i {1}."),max:a.validator.format("Unesite vrednost manju ili jednaku {0}."),min:a.validator.format("Unesite vrednost veću ili jednaku {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_sv.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Detta fält är obligatoriskt.",maxlength:a.validator.format("Du får ange högst {0} tecken."),minlength:a.validator.format("Du måste ange minst {0} tecken."),rangelength:a.validator.format("Ange minst {0} och max {1} tecken."),email:"Ange en korrekt e-postadress.",url:"Ange en korrekt URL.",date:"Ange ett korrekt datum.",dateISO:"Ange ett korrekt datum (ÅÅÅÅ-MM-DD).",number:"Ange ett korrekt nummer.",digits:"Ange endast siffror.",equalTo:"Ange samma värde igen.",range:a.validator.format("Ange ett värde mellan {0} och {1}."),max:a.validator.format("Ange ett värde som är mindre eller lika med {0}."),min:a.validator.format("Ange ett värde som är större eller lika med {0}."),creditcard:"Ange ett korrekt kreditkortsnummer."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_th.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"โปรดระบุ",remote:"โปรดแก้ไขให้ถูกต้อง",email:"โปรดระบุที่อยู่อีเมล์ที่ถูกต้อง",url:"โปรดระบุ URL ที่ถูกต้อง",date:"โปรดระบุวันที่ ที่ถูกต้อง",dateISO:"โปรดระบุวันที่ ที่ถูกต้อง (ระบบ ISO).",number:"โปรดระบุทศนิยมที่ถูกต้อง",digits:"โปรดระบุจำนวนเต็มที่ถูกต้อง",creditcard:"โปรดระบุรหัสบัตรเครดิตที่ถูกต้อง",equalTo:"โปรดระบุค่าเดิมอีกครั้ง",extension:"โปรดระบุค่าที่มีส่วนขยายที่ถูกต้อง",maxlength:a.validator.format("โปรดอย่าระบุค่าที่ยาวกว่า {0} อักขระ"),minlength:a.validator.format("โปรดอย่าระบุค่าที่สั้นกว่า {0} อักขระ"),rangelength:a.validator.format("โปรดอย่าระบุค่าความยาวระหว่าง {0} ถึง {1} อักขระ"),range:a.validator.format("โปรดระบุค่าระหว่าง {0} และ {1}"),max:a.validator.format("โปรดระบุค่าน้อยกว่าหรือเท่ากับ {0}"),min:a.validator.format("โปรดระบุค่ามากกว่าหรือเท่ากับ {0}")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_tj.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Ворид кардани ин филд маҷбури аст.",remote:"Илтимос, маълумоти саҳеҳ ворид кунед.",email:"Илтимос, почтаи электронии саҳеҳ ворид кунед.",url:"Илтимос, URL адреси саҳеҳ ворид кунед.",date:"Илтимос, таърихи саҳеҳ ворид кунед.",dateISO:"Илтимос, таърихи саҳеҳи (ISO)ӣ ворид кунед.",number:"Илтимос, рақамҳои саҳеҳ ворид кунед.",digits:"Илтимос, танҳо рақам ворид кунед.",creditcard:"Илтимос, кредит карди саҳеҳ ворид кунед.",equalTo:"Илтимос, миқдори баробар ворид кунед.",extension:"Илтимос, қофияи файлро дуруст интихоб кунед",maxlength:a.validator.format("Илтимос, бештар аз {0} рамз ворид накунед."),minlength:a.validator.format("Илтимос, камтар аз {0} рамз ворид накунед."),rangelength:a.validator.format("Илтимос, камтар аз {0} ва зиёда аз {1} рамз ворид кунед."),range:a.validator.format("Илтимос, аз {0} то {1} рақам зиёд ворид кунед."),max:a.validator.format("Илтимос, бештар аз {0} рақам ворид накунед."),min:a.validator.format("Илтимос, камтар аз {0} рақам ворид накунед.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_tr.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Bu alanın doldurulması zorunludur.",remote:"Lütfen bu alanı düzeltin.",email:"Lütfen geçerli bir e-posta adresi giriniz.",url:"Lütfen geçerli bir web adresi (URL) giriniz.",date:"Lütfen geçerli bir tarih giriniz.",dateISO:"Lütfen geçerli bir tarih giriniz(ISO formatında)",number:"Lütfen geçerli bir sayı giriniz.",digits:"Lütfen sadece sayısal karakterler giriniz.",creditcard:"Lütfen geçerli bir kredi kartı giriniz.",equalTo:"Lütfen aynı değeri tekrar giriniz.",extension:"Lütfen geçerli uzantıya sahip bir değer giriniz.",maxlength:a.validator.format("Lütfen en fazla {0} karakter uzunluğunda bir değer giriniz."),minlength:a.validator.format("Lütfen en az {0} karakter uzunluğunda bir değer giriniz."),rangelength:a.validator.format("Lütfen en az {0} ve en fazla {1} uzunluğunda bir değer giriniz."),range:a.validator.format("Lütfen {0} ile {1} arasında bir değer giriniz."),max:a.validator.format("Lütfen {0} değerine eşit ya da daha küçük bir değer giriniz."),min:a.validator.format("Lütfen {0} değerine eşit ya da daha büyük bir değer giriniz."),require_from_group:"Lütfen bu alanların en az {0} tanesini doldurunuz."}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_uk.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Це поле необхідно заповнити.",remote:"Будь ласка, введіть правильне значення.",email:"Будь ласка, введіть коректну адресу електронної пошти.",url:"Будь ласка, введіть коректний URL.",date:"Будь ласка, введіть коректну дату.",dateISO:"Будь ласка, введіть коректну дату у форматі ISO.",number:"Будь ласка, введіть число.",digits:"Вводите потрібно лише цифри.",creditcard:"Будь ласка, введіть правильний номер кредитної карти.",equalTo:"Будь ласка, введіть таке ж значення ще раз.",extension:"Будь ласка, виберіть файл з правильним розширенням.",maxlength:a.validator.format("Будь ласка, введіть не більше {0} символів."),minlength:a.validator.format("Будь ласка, введіть не менше {0} символів."),rangelength:a.validator.format("Будь ласка, введіть значення довжиною від {0} до {1} символів."),range:a.validator.format("Будь ласка, введіть число від {0} до {1}."),max:a.validator.format("Будь ласка, введіть число, менше або рівно {0}."),min:a.validator.format("Будь ласка, введіть число, більше або рівно {0}.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_ur.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"ان معلومات کا اندراج ضروری ہے",remote:"ان معلومات کا اندراج ضروری ہے",email:"درج کی ہوئی ای میل درست نہیں ہے",url:"درج کیا گیا پتہ درست نہیں ہے",date:"درج کی گئی تاریخ درست نہیں ہے",dateISO:"معیار کے مطابق نہیں ہے (ISO) درج کی گئی تاریخ",number:"درج کیےگئے ہندسے درست نہیں ہیں",digits:"صرف ہندسے اندراج کئے جاسکتے ہیں",creditcard:"درج کیا گیا کارڈ نمبر درست نہیں ہے",equalTo:"اندراج کا موازنہ درست نہیں ہے",extension:"اندراج درست نہیں ہے",maxlength:a.validator.format("زیادہ سے زیادہ {0} کا اندراج کر سکتے ہیں"),minlength:a.validator.format("کم سے کم {0} کا اندراج کرنا ضروری ہے"),rangelength:a.validator.format("اندراج کا {0} اور {1}کے درمیان ہونا ضروری ہے"),range:a.validator.format("اندراج کا {0} اور {1} کے درمیان ہونا ضروری ہے"),max:a.validator.format("زیادہ سے زیادہ {0} کا اندراج کر سکتے ہیں"),min:a.validator.format("کم سے کم {0} کا اندراج کرنا ضروری ہے")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_vi.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Hãy nhập.",remote:"Hãy sửa cho đúng.",email:"Hãy nhập email.",url:"Hãy nhập URL.",date:"Hãy nhập ngày.",dateISO:"Hãy nhập ngày (ISO).",number:"Hãy nhập số.",digits:"Hãy nhập chữ số.",creditcard:"Hãy nhập số thẻ tín dụng.",equalTo:"Hãy nhập thêm lần nữa.",extension:"Phần mở rộng không đúng.",maxlength:a.validator.format("Hãy nhập từ {0} kí tự trở xuống."),minlength:a.validator.format("Hãy nhập từ {0} kí tự trở lên."),rangelength:a.validator.format("Hãy nhập từ {0} đến {1} kí tự."),range:a.validator.format("Hãy nhập từ {0} đến {1}."),max:a.validator.format("Hãy nhập từ {0} trở xuống."),min:a.validator.format("Hãy nhập từ {1} trở lên.")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_zh.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"这是必填字段",remote:"请修正此字段",email:"请输入有效的电子邮件地址",url:"请输入有效的网址",date:"请输入有效的日期",dateISO:"请输入有效的日期 (YYYY-MM-DD)",number:"请输入有效的数字",digits:"只能输入数字",creditcard:"请输入有效的信用卡号码",equalTo:"你的输入不相同",extension:"请输入有效的后缀",maxlength:a.validator.format("最多可以输入 {0} 个字符"),minlength:a.validator.format("最少要输入 {0} 个字符"),rangelength:a.validator.format("请输入长度在 {0} 到 {1} 之间的字符串"),range:a.validator.format("请输入范围在 {0} 到 {1} 之间的数值"),max:a.validator.format("请输入不大于 {0} 的数值"),min:a.validator.format("请输入不小于 {0} 的数值")}),a}); -------------------------------------------------------------------------------- /src/static/admin/js/vendor/jquery-validation/localization/messages_zh_TW.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017 2 | * https://jqueryvalidation.org/ 3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"必須填寫",remote:"請修正此欄位",email:"請輸入有效的電子郵件",url:"請輸入有效的網址",date:"請輸入有效的日期",dateISO:"請輸入有效的日期 (YYYY-MM-DD)",number:"請輸入正確的數值",digits:"只可輸入數字",creditcard:"請輸入有效的信用卡號碼",equalTo:"請重複輸入一次",extension:"請輸入有效的後綴",maxlength:a.validator.format("最多 {0} 個字"),minlength:a.validator.format("最少 {0} 個字"),rangelength:a.validator.format("請輸入長度為 {0} 至 {1} 之間的字串"),range:a.validator.format("請輸入 {0} 至 {1} 之間的數值"),max:a.validator.format("請輸入不大於 {0} 的數值"),min:a.validator.format("請輸入不小於 {0} 的數值")}),a}); -------------------------------------------------------------------------------- /src/utils/cliHelper.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const moment = require("moment"); 4 | const { program } = require("commander"); 5 | 6 | module.exports = (logger, appVersion) => ({ 7 | printReady: () => { 8 | logger.info("$ Server ready $"); 9 | }, 10 | 11 | printEnded: () => { 12 | logger.info("Process closed."); 13 | }, 14 | 15 | printInfo: () => { 16 | logger.info(`TERA API Version: ${appVersion}`); 17 | logger.info(`Node.js Version: ${process.version}`); 18 | logger.info(`Server Timezone: ${moment().format("Z")} (${moment.tz.guess()})`); 19 | }, 20 | 21 | printMemoryUsage: () => { 22 | const used = process.memoryUsage(); 23 | 24 | const keys = { 25 | rss: "Resident set size", 26 | heapTotal: "Total heap size ", 27 | heapUsed: "Used heap ", 28 | external: "External ", 29 | arrayBuffers: "Array buffers " 30 | }; 31 | 32 | logger.info("-".repeat(30)); 33 | logger.info("Memory Usage:"); 34 | 35 | Object.keys(used).forEach(key => 36 | logger.info(` ${keys[key]}: ${Math.round(used[key] / 1024 / 1024 * 100) / 100} MB`) 37 | ); 38 | 39 | logger.info("-".repeat(30)); 40 | }, 41 | 42 | addOption: (flags, description, defaultValue) => { 43 | program.option(flags, description, defaultValue); 44 | }, 45 | 46 | getOptions: () => 47 | program.parse(process.argv).opts() 48 | }); -------------------------------------------------------------------------------- /src/utils/env.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports.bool = (parameter, def = undefined) => ( 4 | process.env[parameter] !== undefined ? /^true$/i.test(process.env[parameter]) : def 5 | ); 6 | 7 | module.exports.string = (parameter, def = undefined) => ( 8 | process.env[parameter] !== undefined ? process.env[parameter].toString() : def 9 | ); 10 | 11 | module.exports.number = (parameter, def = undefined) => ( 12 | process.env[parameter] !== undefined ? Number(process.env[parameter]) : def 13 | ); 14 | 15 | module.exports.array = (parameter, def = undefined, separator = ",") => ( 16 | process.env[parameter] !== undefined ? process.env[parameter].split(separator).map(el => el.trim()).filter(el => el.length > 0) : def 17 | ); -------------------------------------------------------------------------------- /src/views/adminError.ejs: -------------------------------------------------------------------------------- 1 | <%- contentFor("content") %> 2 |
3 |
4 | <%_ if (err.includes("\n")) { _%> 5 | <%= __("Operation failed") %>: 6 |
<%= err %>
7 | <%_ } else { _%> 8 | <%= __("Operation failed") %>: <%= err %> 9 | <%_ } _%> 10 |
11 |
-------------------------------------------------------------------------------- /src/views/adminLayout.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%- include("partials/adminHead") %> 5 | 6 |
7 | 13 |
14 | <%- include("partials/adminScripts") %> 15 | <%- typeof scripts !== "undefined" ? scripts : "" %> 16 | 17 | -------------------------------------------------------------------------------- /src/views/adminPromocodesActivatedAdd.ejs: -------------------------------------------------------------------------------- 1 | <%- contentFor("content") %> 2 |
3 |
4 |

<%= __("Activate Promo Code") %>

5 |
6 |
7 | <%= __("Back to list") %> 8 |
9 |
10 |
11 |
12 |
13 |
14 | 15 |
16 | 17 | 18 |
19 |
20 | 21 | 26 |
27 |
28 | 29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | <%- contentFor("scripts") %> 37 | -------------------------------------------------------------------------------- /src/views/adminShopAccountsEdit.ejs: -------------------------------------------------------------------------------- 1 | <%- contentFor("content") %> 2 |
3 |
4 |

<%= __("Edit Shop Account") %> ID <%= accountDBID %>

5 |
6 |
7 | <%= __("Back to list") %> 8 |
9 |
10 |
11 |
12 |
13 |
14 | 15 |
16 | 17 | 18 |
19 |
20 | 21 | 22 |
23 |
24 | 28 |
29 |
30 | 31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | <%- contentFor("scripts") %> 39 | -------------------------------------------------------------------------------- /src/views/launcherErrorForm.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Login 7 | 8 | 9 | 12 | 13 | 14 | 15 | 22 | 23 | 24 |
25 |
26 |

<%= __("Error") %>

27 |

Code <%= error.code %>: <%= error.message %>

28 |
29 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /src/views/partials/adminFooter.ejs: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /src/views/partials/adminFormErrors.ejs: -------------------------------------------------------------------------------- 1 | <%_ if (errors && errors.length > 0) { _%> 2 |
3 |
    4 | <%_ errors.forEach(error => { _%> 5 |
  • <%= error.msg %>
  • 6 | <%_ }) _%> 7 |
8 |
9 | <%_ } _%> -------------------------------------------------------------------------------- /src/views/partials/adminHead.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TERA API Admin Panel 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/views/partials/adminReportForm.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | "> 6 |
7 |
8 | 9 | "> 10 |
11 | <%_ if (accountDBID !== null) { _%> 12 |
13 | 14 | 15 |
16 | <%_ } _%> 17 | <%_ if (servers !== null) { _%> 18 |
19 | 20 | 26 |
27 | <%_ } _%> 28 | 29 |
30 |
-------------------------------------------------------------------------------- /src/views/partials/shopError.ejs: -------------------------------------------------------------------------------- 1 |
<%= __("An error occurred while running the store. Try closing the window and open again.") %>
-------------------------------------------------------------------------------- /src/views/shopDisabled.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%= __('TERA Shop') %> 7 | 8 | 9 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 | <%= __("Unfortunately, TERA Shop is currently closed.") %> 25 |
26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /start__all.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | title TeraAPI 3 | node --expose-gc --max_old_space_size=8192 src/app 4 | pause -------------------------------------------------------------------------------- /start_admin_panel.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | title TeraAPI - Admin Panel 3 | node --expose-gc --max_old_space_size=8192 src/app --component admin_panel 4 | pause -------------------------------------------------------------------------------- /start_arbiter_api.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | title TeraAPI - Arbiter API 3 | node --expose-gc --max_old_space_size=8192 src/app --component arbiter_api 4 | pause -------------------------------------------------------------------------------- /start_gateway_api.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | title TeraAPI - Gateway API 3 | node --expose-gc --max_old_space_size=8192 src/app --component gateway_api 4 | pause -------------------------------------------------------------------------------- /start_portal_api.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | title TeraAPI - Portal API 3 | node --expose-gc --max_old_space_size=8192 src/app --component portal_api 4 | pause -------------------------------------------------------------------------------- /tera-api.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": {} 8 | } --------------------------------------------------------------------------------