5.5.2290
This commit is contained in:
parent
bdc6b15792
commit
8bbe942cbd
|
@ -54,7 +54,7 @@ command:
|
|||
manage:
|
||||
confirm: "> §c添加 '-a' 参数来确认执行:${0}"
|
||||
confirmOverwrite: "数据库 ${0} 中的数据将被覆盖!"
|
||||
confirmPartialRemoval: "Join Address Data for Server ${0} in ${1} will be removed!"
|
||||
confirmPartialRemoval: "数据库 ${1} 中服务器 ${0} 的加入地址数据将被删除!"
|
||||
confirmRemoval: "数据库 ${0} 中的数据将被删除!"
|
||||
fail: "> §c发生了错误:${0}"
|
||||
failFileNotFound: "> §c没有在 ${0} 发现文件"
|
||||
|
@ -64,7 +64,7 @@ command:
|
|||
failSameServer: "不能将此服务器标记为已卸载(你在这个服务器上)。"
|
||||
hotswap: "§e请切换到新的数据库(/plan db hotswap ${0})并重新加载插件。"
|
||||
importers: "导入器:"
|
||||
preparing: "Preparing.."
|
||||
preparing: "准备中.."
|
||||
progress: "${0} / ${1} 处理中..."
|
||||
start: "> §2处理数据中..."
|
||||
success: "> §a成功!"
|
||||
|
@ -166,7 +166,7 @@ command:
|
|||
description: "将其他用户从面板上登出。"
|
||||
inDepth: "输入用户名作为参数可以注销 Plan 上的一个用户,输入 * 作为参数可以注销所有用户。"
|
||||
migrateToOnlineUuids:
|
||||
description: "Migrate offline uuid data to online uuids"
|
||||
description: "将离线uuid数据迁移到在线uuid"
|
||||
network:
|
||||
description: "查看群组网络页面"
|
||||
inDepth: "获得一个指向 /network page(群组网络) 的链接,只能在群组网络上这样做。"
|
||||
|
@ -183,7 +183,7 @@ command:
|
|||
description: "重启 Plan"
|
||||
inDepth: "禁用然后重新启用本插件,会重新加载配置中的设置。"
|
||||
removejoinaddresses:
|
||||
description: "Remove join addresses of a specified server"
|
||||
description: "移除指定服务器的加入地址"
|
||||
search:
|
||||
description: "搜索玩家"
|
||||
inDepth: "列出所有与给定名字部分相匹配的玩家名字。"
|
||||
|
@ -265,8 +265,8 @@ html:
|
|||
authFailedTips: "- 确保你已使用 <b>/plan register</b> 来注册用户<br>- 检查用户名与密码是否正确<br>- 用户名与密码区分大小写<br><br>若您忘记了密码,请让工作人员删除您的旧密码并重新注册。"
|
||||
noServersOnline: "无可执行此请求的在线服务器。"
|
||||
playerNotSeen: "Plan 没有找到此玩家。"
|
||||
serverNotExported: "Server doesn't exist, its data might not have been exported yet."
|
||||
serverNotSeen: "Server doesn't exist"
|
||||
serverNotExported: "服务器不存在,其数据可能尚未导出。"
|
||||
serverNotSeen: "服务器不存在"
|
||||
generic:
|
||||
none: "无"
|
||||
label:
|
||||
|
@ -277,26 +277,26 @@ html:
|
|||
afkTime: "挂机时间"
|
||||
all: "全部"
|
||||
allTime: "所有时间"
|
||||
alphabetical: "Alphabetical"
|
||||
apply: "Apply"
|
||||
alphabetical: "按字母顺序"
|
||||
apply: "应用"
|
||||
asNumbers: "数据"
|
||||
average: "平均"
|
||||
averageActivePlaytime: "平均活跃时间"
|
||||
averageAfkTime: "平均挂机时间"
|
||||
averageChunks: "平均区块数"
|
||||
averageCpuUsage: "Average CPU Usage"
|
||||
averageCpuUsage: "平均 CPU 使用率"
|
||||
averageEntities: "平均实体数"
|
||||
averageKdr: "平均 KDR"
|
||||
averageMobKdr: "平均生物 KDR"
|
||||
averagePing: "平均延迟"
|
||||
averagePlayers: "Average Players"
|
||||
averagePlayers: "平均在线玩家"
|
||||
averagePlaytime: "平均游玩时间"
|
||||
averageRamUsage: "Average RAM Usage"
|
||||
averageServerDowntime: "Average Downtime / Server"
|
||||
averageRamUsage: "平均内存使用量"
|
||||
averageServerDowntime: "平均停机时间/服务器"
|
||||
averageSessionLength: "平均会话时长"
|
||||
averageSessions: "平均会话"
|
||||
averageTps: "平均 TPS"
|
||||
averageTps7days: "Average TPS (7 days)"
|
||||
averageTps7days: "平均 TPS(7 天)"
|
||||
banned: "已被封禁"
|
||||
bestPeak: "所有时间峰值"
|
||||
bestPing: "最低延迟"
|
||||
|
@ -306,9 +306,9 @@ html:
|
|||
country: "国家和地区"
|
||||
cpu: "CPU"
|
||||
cpuRam: "CPU 和内存"
|
||||
cpuUsage: "CPU Usage"
|
||||
cpuUsage: "CPU 使用率"
|
||||
currentPlayerbase: "当前玩家数"
|
||||
currentUptime: "Current Uptime"
|
||||
currentUptime: "正常运行时间"
|
||||
dayByDay: "按天查看"
|
||||
dayOfweek: "星期"
|
||||
deadliestWeapon: "最致命的 PVP 武器"
|
||||
|
@ -318,32 +318,62 @@ html:
|
|||
downtime: "停机时间"
|
||||
duringLowTps: "持续低 TPS 时间"
|
||||
entities: "实体"
|
||||
exported: "Data export time"
|
||||
exported: "数据导出时间"
|
||||
favoriteServer: "最喜爱的服务器"
|
||||
firstSession: "第一此会话"
|
||||
firstSession: "第一次会话"
|
||||
firstSessionLength:
|
||||
average: "Average first session length"
|
||||
median: "Median first session length"
|
||||
average: "平均首次会话时间长度"
|
||||
median: "首次会话时间长度的中位数"
|
||||
geoProjection:
|
||||
dropdown: "Select projection"
|
||||
equalEarth: "Equal Earth"
|
||||
mercator: "Mercator"
|
||||
miller: "Miller"
|
||||
ortographic: "Ortographic"
|
||||
dropdown: "选择地图投影方式"
|
||||
equalEarth: "等面积投影"
|
||||
mercator: "墨卡托投影"
|
||||
miller: "米勒投影"
|
||||
ortographic: "正射投影"
|
||||
geolocations: "地理位置"
|
||||
help:
|
||||
activityIndexBasis: "Activity index is based on non-AFK playtime in the past 3 weeks (21 days). Each week is considered separately."
|
||||
activityIndexExample1: "If someone plays as much as threshold every week, they are given activity index ~3."
|
||||
activityIndexExample2: "Very active is ~2x the threshold (y ≥ 3.75)."
|
||||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
playtimeUnit: "hours"
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
activityIndexBasis: "活跃指数基于过去3周(21天)内的非AFK游戏时间。每周单独考虑。"
|
||||
activityIndexExample1: "如果有人每周玩的时间达到阈值,他们将获得活跃指数约为3。"
|
||||
activityIndexExample2: "非常活跃是阈值的约2倍(y ≥ 3.75)。"
|
||||
activityIndexExample3: "该指数无限趋近于5。"
|
||||
activityIndexVisual: "这里是y = 活跃指数,x = 每周游戏时间 / 阈值的曲线可视化。"
|
||||
activityIndexWeek: "第{}周"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "小时"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "新玩家留坑率根据会话数据计算。如果注册玩家在时间跨度的后半段内有游戏记录,则被视为已留坑。"
|
||||
testPrompt: "试一下:"
|
||||
testResult: "测试结果"
|
||||
threshold: "阈值"
|
||||
thresholdUnit: "小时/周"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "按小时查看"
|
||||
inactive: "不活跃"
|
||||
indexInactive: "不活跃"
|
||||
|
@ -352,7 +382,7 @@ html:
|
|||
insights: "Insights"
|
||||
insights30days: "30 天分析"
|
||||
irregular: "偶尔上线"
|
||||
joinAddress: "Join Address"
|
||||
joinAddress: "加入地址"
|
||||
joinAddresses: "加入地址"
|
||||
kdr: "KDR"
|
||||
killed: "被击杀数"
|
||||
|
@ -362,7 +392,7 @@ html:
|
|||
lastConnected: "最后连接时间"
|
||||
lastPeak: "上次在线峰值"
|
||||
lastSeen: "最后在线时间"
|
||||
latestJoinAddresses: "Latest Join Addresses"
|
||||
latestJoinAddresses: "上一次加入地址"
|
||||
length: " 游玩时长"
|
||||
links: "链接"
|
||||
loadedChunks: "已加载区块"
|
||||
|
@ -371,9 +401,9 @@ html:
|
|||
loneNewbieJoins: "单独新玩家加入"
|
||||
longestSession: "最长会话时间"
|
||||
lowTpsSpikes: "低 TPS 时间"
|
||||
lowTpsSpikes7days: "Low TPS Spikes (7 days)"
|
||||
lowTpsSpikes7days: "低 TPS 时间(7天)"
|
||||
maxFreeDisk: "最大可用硬盘空间"
|
||||
medianSessionLength: "Median Session Length"
|
||||
medianSessionLength: "会话长度中位数"
|
||||
minFreeDisk: "最小可用硬盘空间"
|
||||
mobDeaths: "被生物击杀数"
|
||||
mobKdr: "生物 KDR"
|
||||
|
@ -389,13 +419,13 @@ html:
|
|||
new: "新"
|
||||
newPlayerRetention: "新玩家留坑率"
|
||||
newPlayers: "新玩家"
|
||||
newPlayers7days: "New Players (7 days)"
|
||||
newPlayers7days: "新玩家(7天)"
|
||||
nickname: "昵称"
|
||||
noDataToDisplay: "No Data to Display"
|
||||
noDataToDisplay: "没有数据可以展示"
|
||||
now: "现在"
|
||||
onlineActivity: "在线活动"
|
||||
onlineActivityAsNumbers: "在线活动数据"
|
||||
onlineOnFirstJoin: "第一次进入服务器的在线玩家"
|
||||
onlineOnFirstJoin: "首次加入时的在线玩家数"
|
||||
operator: "管理员"
|
||||
overview: "总览"
|
||||
perDay: "/ 天"
|
||||
|
@ -407,29 +437,29 @@ html:
|
|||
player: "玩家"
|
||||
playerDeaths: "被玩家击杀次数"
|
||||
playerKills: "击杀玩家数"
|
||||
playerKillsVictimIndicator: "Player was killed within 24h of first time they were seen (Time since registered: <>)."
|
||||
playerKillsVictimIndicator: "玩家在首次出现后 24 小时内被杀(自注册以来的时间:<>)。"
|
||||
playerList: "玩家列表"
|
||||
playerOverview: "玩家总览"
|
||||
playerPage: "玩家页面"
|
||||
playerRetention: "Player Retention"
|
||||
playerRetention: "玩家留坑"
|
||||
playerbase: "玩家数据"
|
||||
playerbaseDevelopment: "玩家发展"
|
||||
playerbaseOverview: "Playerbase Overview"
|
||||
playerbaseOverview: "玩家总览"
|
||||
players: "玩家"
|
||||
playersOnline: "在线玩家"
|
||||
playersOnlineNow: "Players Online (Now)"
|
||||
playersOnlineNow: "在线玩家(当前)"
|
||||
playersOnlineOverview: "在线活动总览"
|
||||
playtime: "游玩时间"
|
||||
plugins: "插件"
|
||||
pluginsOverview: "Plugins Overview"
|
||||
pluginsOverview: "插件总览"
|
||||
punchcard: "打卡"
|
||||
punchcard30days: "30 天打卡"
|
||||
pvpPve: "PvP 和 PvE"
|
||||
pvpPveAsNumbers: "PvP 和 PvE 数据"
|
||||
query: "进行查询"
|
||||
quickView: "快速浏览"
|
||||
ram: "RAM"
|
||||
ramUsage: "RAM Usage"
|
||||
ram: "内存"
|
||||
ramUsage: "内存使用情况"
|
||||
recentKills: "最近击杀"
|
||||
recentPvpDeaths: "最近的 PVP 死亡"
|
||||
recentPvpKills: "最近的 PVP 击杀"
|
||||
|
@ -439,53 +469,82 @@ html:
|
|||
regular: "普通"
|
||||
regularPlayers: "普通玩家"
|
||||
relativeJoinActivity: "最近加入活动"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "第二致命的 PVP 武器"
|
||||
seenNicknames: "用过的昵称"
|
||||
server: "服务器"
|
||||
serverAnalysis: "服务器分析"
|
||||
serverAsNumberse: "服务器数据"
|
||||
serverCalendar: "Server Calendar"
|
||||
serverCalendar: "服务器日历"
|
||||
serverDowntime: "服务器停机时间"
|
||||
serverOccupied: "服务器在线时间"
|
||||
serverOverview: "服务器总览"
|
||||
serverPage: "服务器页面"
|
||||
serverPlaytime: "服务器游戏时间"
|
||||
serverPlaytime30days: "最近 30 天内的服务器游玩时间"
|
||||
serverSelector: "Server selector"
|
||||
serverSelector: "服务器选择器"
|
||||
servers: "服务器"
|
||||
serversTitle: "服务器"
|
||||
session: "会话次数"
|
||||
sessionCalendar: "Session Calendar"
|
||||
sessionCalendar: "会话日历"
|
||||
sessionEnded: " 会话结束"
|
||||
sessionMedian: "平均会话长度"
|
||||
sessionStart: "会话开始于"
|
||||
sessions: "会话"
|
||||
sortBy: "Sort By"
|
||||
stacked: "Stacked"
|
||||
sortBy: "排序方式"
|
||||
stacked: "堆叠"
|
||||
themeSelect: "主题选择"
|
||||
thirdDeadliestWeapon: "第三致命的 PVP 武器"
|
||||
thirtyDays: "30 天"
|
||||
thirtyDaysAgo: "30 天前"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "被踢出次数"
|
||||
toMainPage: "回到主页面"
|
||||
total: "Total"
|
||||
total: "总计"
|
||||
totalActive: "总活跃时长"
|
||||
totalAfk: "总挂机时长"
|
||||
totalPlayers: "总玩家数"
|
||||
totalPlayersOld: "总游玩时长"
|
||||
totalPlaytime: "总游玩时间"
|
||||
totalServerDowntime: "Total Server Downtime"
|
||||
totalServerDowntime: "服务器停机时间"
|
||||
tps: "TPS"
|
||||
trend: "趋势"
|
||||
trends30days: "30 天趋势"
|
||||
uniquePlayers: "独立玩家"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
uniquePlayers7days: "独立玩家(7天)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "非常活跃"
|
||||
weekComparison: "每周对比"
|
||||
weekdays: "'星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'"
|
||||
world: "世界加载"
|
||||
worldPlaytime: "世界游玩时间"
|
||||
worstPing: "最高延迟"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "登录失败:"
|
||||
forgotPassword: "忘记密码?"
|
||||
|
@ -528,17 +587,17 @@ html:
|
|||
name: "封禁状态"
|
||||
banned: "被封禁"
|
||||
country:
|
||||
text: "have joined from country"
|
||||
text: "加入的国家"
|
||||
generic:
|
||||
allPlayers: "全体玩家"
|
||||
and: "外加 "
|
||||
start: "查询玩家:"
|
||||
hasPlayedOnServers:
|
||||
name: "Has played on one of servers"
|
||||
text: "have played on at least one of"
|
||||
name: "在其中一个服务器上玩过"
|
||||
text: "至少在其中一个服务器上玩过"
|
||||
hasPluginBooleanValue:
|
||||
name: "Has plugin boolean value"
|
||||
text: "have Plugin boolean value"
|
||||
name: "插件布尔值"
|
||||
text: "插件布尔值"
|
||||
joinAddress:
|
||||
text: "加入地址"
|
||||
nonOperators: "非管理员"
|
||||
|
@ -553,7 +612,7 @@ html:
|
|||
text: "在 ${plugin} 插件的 ${group} 分组中"
|
||||
registeredBetween:
|
||||
text: "在此期间注册"
|
||||
skipped: "Skipped"
|
||||
skipped: "已跳过"
|
||||
title:
|
||||
activityGroup: "活跃度分组"
|
||||
view: " 日期范围:"
|
||||
|
@ -566,10 +625,10 @@ html:
|
|||
from: ">从 </label>"
|
||||
makeAnother: "进行另一个查询"
|
||||
servers:
|
||||
all: "using data of all servers"
|
||||
many: "using data of {number} servers"
|
||||
single: "using data of 1 server"
|
||||
two: "using data of 2 servers"
|
||||
all: "使用所有服务器的数据"
|
||||
many: "使用 {number} 台服务器的数据。"
|
||||
single: "使用 1 台服务器的数据"
|
||||
two: "使用 2 台服务器的数据"
|
||||
to: ">到 </label>"
|
||||
view: "日期范围"
|
||||
performQuery: "执行查询!"
|
||||
|
@ -598,7 +657,7 @@ html:
|
|||
login: "已经有帐号了? 登录!"
|
||||
passwordTip: "密码不能超过8个字符,没有其他限制。"
|
||||
register: "注册"
|
||||
success: "Registered a new user successfully! You can now login."
|
||||
success: "新用户注册成功!你现在可以登录了。"
|
||||
usernameTip: "用户名最多可以包含 50 个字符。"
|
||||
text:
|
||||
clickToExpand: "点击展开"
|
||||
|
@ -662,9 +721,9 @@ plugin:
|
|||
dbNotifySQLiteWAL: "此服务器版本不支持 SQLite WAL 模式,正使用默认模式。这可能会影响性能。"
|
||||
dbPatchesAlreadyApplied: "已应用所有数据库补丁。"
|
||||
dbPatchesApplied: "已成功应用所有数据库补丁。"
|
||||
dbSchemaPatch: "Database: Making sure schema is up to date.."
|
||||
loadedServerInfo: "Server identifier loaded: ${0}"
|
||||
loadingServerInfo: "Loading server identifying information"
|
||||
dbSchemaPatch: "数据库:确保表结构是最新的.."
|
||||
loadedServerInfo: "服务器标识已加载:${0}"
|
||||
loadingServerInfo: "正在加载服务器标识信息"
|
||||
no: "否"
|
||||
today: "'今天'"
|
||||
unavailable: "不可用"
|
||||
|
@ -687,10 +746,10 @@ plugin:
|
|||
notify:
|
||||
authDisabledConfig: "网页服务器: 用户登录已关闭! (已在配置文件中禁用)"
|
||||
authDisabledNoHTTPS: "网页服务器:已禁用用户登录!(HTTP 方式不安全)"
|
||||
certificateExpiresOn: "Webserver: Loaded certificate is valid until ${0}."
|
||||
certificateExpiresPassed: "Webserver: Certificate has expired, consider renewing the certificate."
|
||||
certificateExpiresSoon: "Webserver: Certificate expires in ${0}, consider renewing the certificate."
|
||||
certificateNoSuchAlias: "Webserver: Certificate with alias '${0}' was not found inside the keystore file '${1}'."
|
||||
certificateExpiresOn: "网页服务器:加载的证书有效期截止到 ${0}。"
|
||||
certificateExpiresPassed: "网页服务器:证书已过期,请考虑更新证书。"
|
||||
certificateExpiresSoon: "网页服务器:证书将在${0}到期,请考虑更新证书。"
|
||||
certificateNoSuchAlias: "网页服务器:密钥库文件'${1}'中未找到别名为'${0}'的证书。"
|
||||
http: "网页服务器:无证书 -> 正使用 HTTP 服务器提供可视化效果。"
|
||||
ipWhitelist: "网页服务器: IP 白名单已启用。"
|
||||
ipWhitelistBlock: "网页服务器:${0} 被拒绝访问 '${1}'. (不在白名单中)"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Hodina po hodině"
|
||||
inactive: "Neaktivní"
|
||||
indexInactive: "Neaktivní"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Pravidelný"
|
||||
regularPlayers: "Pravidelní hráči"
|
||||
relativeJoinActivity: "Relativní aktivita připojení"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2. PvP Zbraň"
|
||||
seenNicknames: "Viděné přezdívky"
|
||||
server: "Server"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3. PvP Zbraň"
|
||||
thirtyDays: "30 dní"
|
||||
thirtyDaysAgo: "před 30 dny"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Počet vykopnutí"
|
||||
toMainPage: "Zpět na hlavní stránku"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "Trendy za 30 dní"
|
||||
uniquePlayers: "Unikátní hráči"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Velmi aktivní"
|
||||
weekComparison: "Týdenní srovnání"
|
||||
weekdays: "'Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota', 'Neděle'"
|
||||
world: "Načtení světa"
|
||||
worldPlaytime: "Herní čas světa"
|
||||
worstPing: "Nejhorší ping"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Přihlašování selhalo: "
|
||||
forgotPassword: "Zapomněl jste heslo?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Hour by Hour"
|
||||
inactive: "Inaktiv"
|
||||
indexInactive: "Inaktiv"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Regulär"
|
||||
regularPlayers: "Reguläre Spieler"
|
||||
relativeJoinActivity: "Relative Join Activity"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2. PvP Waffe"
|
||||
seenNicknames: "Registrierte Nicknames"
|
||||
server: "Server"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3. PvP Waffe"
|
||||
thirtyDays: "30 Tage"
|
||||
thirtyDaysAgo: "30 Tage vorher"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Mal gekickt"
|
||||
toMainPage: "zur Hauptseite"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "Trends für 30 Tage"
|
||||
uniquePlayers: "Einzigartige Spieler"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Sehr aktiv"
|
||||
weekComparison: "Wochenvergleich"
|
||||
weekdays: "'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'"
|
||||
world: "World Load"
|
||||
worldPlaytime: "Spielzeit in der Welt"
|
||||
worstPing: "Schlechtester Ping"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Login failed: "
|
||||
forgotPassword: "Passwort vergessen?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Hour by Hour"
|
||||
inactive: "Inactive"
|
||||
indexInactive: "Inactive"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Regular"
|
||||
regularPlayers: "Regular Players"
|
||||
relativeJoinActivity: "Relative Join Activity"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2nd PvP Weapon"
|
||||
seenNicknames: "Seen Nicknames"
|
||||
server: "Server"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3rd PvP Weapon"
|
||||
thirtyDays: "30 days"
|
||||
thirtyDaysAgo: "30 days ago"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Times Kicked"
|
||||
toMainPage: "to main page"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "Trends for 30 days"
|
||||
uniquePlayers: "Unique Players"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Very Active"
|
||||
weekComparison: "Week Comparison"
|
||||
weekdays: "'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'"
|
||||
world: "World Load"
|
||||
worldPlaytime: "World Playtime"
|
||||
worstPing: "Worst Ping"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Login failed: "
|
||||
forgotPassword: "Forgot Password?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Hora a Hora"
|
||||
inactive: "Inactivo"
|
||||
indexInactive: "Inactivo"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Normal"
|
||||
regularPlayers: "Jugadores normal"
|
||||
relativeJoinActivity: "Actividad de unión relativa"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2ª arma PvP"
|
||||
seenNicknames: "Nombres de usuarios vistos"
|
||||
server: "Servidor"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3ª arma PvP"
|
||||
thirtyDays: "30 días"
|
||||
thirtyDaysAgo: "Hace 30 días"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Veces kickeado"
|
||||
toMainPage: "hasta la página principal"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "Tendencias de 30 días"
|
||||
uniquePlayers: "Jugadores únicos"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Muy activo"
|
||||
weekComparison: "Comparación semanal"
|
||||
weekdays: "'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo'"
|
||||
world: "Carga de mundo"
|
||||
worldPlaytime: "Jugabilidad de mundo"
|
||||
worstPing: "Peor ping"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Ingreso fallido: "
|
||||
forgotPassword: "Contraseña Olvidada?"
|
||||
|
|
|
@ -115,7 +115,7 @@ command:
|
|||
network: "> §2Verkoston Sivu"
|
||||
players: "> §2Pelaajat"
|
||||
search: "> §2${0} Tulosta haulle §f${1}§2:"
|
||||
serverList: "id::nimi::uuid::version"
|
||||
serverList: "id::nimi::uuid::versio"
|
||||
servers: "> §2Palvelimet"
|
||||
webUserList: "käyttäjänimi::linkitetty pelaajaan::lupa taso"
|
||||
webUsers: "> §2${0} Verkkokäyttäjät"
|
||||
|
@ -332,18 +332,48 @@ html:
|
|||
ortographic: "Ortografinen"
|
||||
geolocations: "Sijainnit"
|
||||
help:
|
||||
activityIndexBasis: "Activity index is based on non-AFK playtime in the past 3 weeks (21 days). Each week is considered separately."
|
||||
activityIndexExample1: "If someone plays as much as threshold every week, they are given activity index ~3."
|
||||
activityIndexExample2: "Very active is ~2x the threshold (y ≥ 3.75)."
|
||||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
playtimeUnit: "hours"
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
activityIndexBasis: "Aktiivisuus indeksi perustuu ei-AFK peliaikaan viimeiseltä kolmelta viikolta (21 päivää). Jokaista viikkoa katsotaan erikseen"
|
||||
activityIndexExample1: "Jos joku pelaa kynnyksen määrän joka viikko, on aktiivisuus indeksi noin ~3."
|
||||
activityIndexExample2: "Hyvin aktiivinen pelaa ~2x kynnysarvon verran (y ≥ 3.75)."
|
||||
activityIndexExample3: "Indeksi lähestyy arvoa 5 äärettömyyteen asti"
|
||||
activityIndexVisual: "Alapuolelta löytyy esimerkki käyrästä, missä y = aktiivisuus indeksi, and x = peliaika viikossa / kynnys."
|
||||
activityIndexWeek: "Viikko {}"
|
||||
examples: "Esimerkkejä"
|
||||
graph:
|
||||
labels: "Voit piilottaa/näyttää ryhmän klikkaamalla nimeä käyrän alapuolella"
|
||||
title: "Käyrä"
|
||||
zoom: "Voit katsoa tietoja tarkemmin klikkaamalla ja vetämällä käyrän päällä"
|
||||
playtimeUnit: "tuntia"
|
||||
retention:
|
||||
calculationStep1: "Ensin tiedot rajataan käyttämällä '<>' valintaa. Pelaajat joiden 'registerDate' osuu aikarajauksen ulkopuolelle eivät tule mukaan laskuihin"
|
||||
calculationStep2: "Tämän jälkeen tiedot ryhmitellään käyttämällä '<0>' valintaa, esim. '<1>' valittuna: Kaikki pelaajat jotka rekisteröityivät tammikuussa 2023, helmikuussa 2023, jne"
|
||||
calculationStep3: "Sitten '<0>' ja '<1>' valitsevat mitä esitystä näytetään."
|
||||
calculationStep4: "'<>' ohjaa montako pistettä käyrällä on, esim. 'Päivät' laittaa yhden pisteen per päivä."
|
||||
calculationStep5: "Jokaiselle lasketulle pisteelle tarkistetaan, vastaavatko pelaajat ehtoa."
|
||||
calculationStep6: "Valitse X Akseli alapuolella nähdäksesi ehdot."
|
||||
calculationStepDate: "Tämä esitysmuoto näyttää eri ryhmät jotka vielä pelaavat palvelimella. Esitys käyttää lastSeen päivämäärää. Jos x < lastSeenDate, pelaaja näkyy käyrällä."
|
||||
calculationStepDeltas: "Tämä esitysmuoto on tehokkaampi jos käytetään Pelaajamäärää Y akselina. Esitys näyttää pelaajien lisääntymisen kokonaismääärän (Montako pelaajaa rekisteröityi - pelaajat jotka lopettivat pelaamisen). Esitys käyttää registered ja lastSeen päiviä. Jos registerDate < x < lastSeenDate, pelaaja näkyy käyrällä."
|
||||
calculationStepPlaytime: "Tämä esitysmuoto kertoo miten pitkään pelisykli pitää pelaajat kiinnostuneita palvelimesta. Esitys käyttää peliaikaa. Jos x < playtime, pelaaja näkyy käyrällä."
|
||||
calculationStepTime: "Tämä esitysmuoto kertoo miten kauan pelaajat jatkavat palvelimelle takaisin liittymistä rekisteröitymisen jälkeen. Kuvaus käyttää aikojen erotusta. Jos x < timeDifference, pelaaja näkyy käyrällä."
|
||||
compareJoinAddress: "Liittymisosoitteen avulla ryhmittely mahdollistaa eri mainoskampanjoiden tehokkuuden tarkkailun."
|
||||
compareMonths: "Voit verrata eri kuukausia vaihtamalla '<0>' kohtaan '<1>'"
|
||||
examples:
|
||||
adCampaign: "Eri mainoskampanjoiden tehokkuuden mittaus eri liittymäosotteiden avulla (anonymisoitu)"
|
||||
deltas: "<> näyttää pelaajien lisääntymismäärän."
|
||||
pattern: "Käyrästä paljastuu yleisempi kuvio, kun kaikki pelaajat lopettavat palvelimella pelaamisen kokonaan samaan aikaan."
|
||||
plateau: "Tässä verrataan pelaajien lisääntymismäärää eri kuukausilta. Tasanteet viittaavat siihen, että on pelaajia joista Plan ei tiedä. Tässä esimerkissä Plan asennettiin tammikuussa 2022."
|
||||
playtime: "Peliaika kertoo kuinka kauan pelisykli pitää pelaajat kiinnostuneina palvelimesta."
|
||||
stack: "Kumulatiivisen pelaajien lisääntymismäärän voi tarkistaa päälekkäisillä pelaajamäärillä Y akselina"
|
||||
howIsItCalculated: "Miten se lasketaan"
|
||||
howIsItCalculatedData: "Käyrä generoidaan pelaajien tiedoista:"
|
||||
options: "Eri valinnoilla voi analysoida pelaajien pysyvyyden eri puolia."
|
||||
retentionBasis: "Uusien pelaajien pysyvyys perustuu istuntoihin. Jos rekisteröitynyt pelaaja on pelannut ajanjakson viimeisellä puoliskolla, ajatellaan heidän pysyneen palvelimella"
|
||||
testPrompt: "Kokeile käytännössä:"
|
||||
testResult: "Kokeilun tulos"
|
||||
threshold: "kynnys"
|
||||
thresholdUnit: "tuntia / viikko"
|
||||
tips: "Neuvoja"
|
||||
usingTheGraph: "Käyrän käyttö"
|
||||
hourByHour: "Tunnittainen katsaus"
|
||||
inactive: "Inaktiivinen"
|
||||
indexInactive: "Inaktiivinen"
|
||||
|
@ -411,7 +441,7 @@ html:
|
|||
playerList: "Pelaajalista"
|
||||
playerOverview: "Yhteenveto Pelaajasta"
|
||||
playerPage: "Pelaajan sivu"
|
||||
playerRetention: "Pelaajien säilyvyys"
|
||||
playerRetention: "Pelaajien pysyvyys"
|
||||
playerbase: "Pelaajakunta"
|
||||
playerbaseDevelopment: "Pelaajakunnan kehitys"
|
||||
playerbaseOverview: "Yhteenveto Pelaajakunnasta"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Kantapelaaja"
|
||||
regularPlayers: "Kantapelaajia"
|
||||
relativeJoinActivity: "Verrannollinen liittymis aktiivisuus"
|
||||
retention:
|
||||
groupByNone: "Ei ryhmittelyä"
|
||||
groupByTime: "Ryhmittele rekisteröityneet"
|
||||
inAnytime: "koska vain"
|
||||
inLast180d: "viimeisen 6 kuukauden aikana"
|
||||
inLast30d: "viimeisen 30 päivän aikana"
|
||||
inLast365d: "viimeisen 12 kuukauden aikana"
|
||||
inLast730d: "viimeisen 24 kuukauden aikana"
|
||||
inLast7d: "viimeisen 7 päivän aikana"
|
||||
inLast90d: "viimeisen 3 kuukauden aikana"
|
||||
playersRegisteredInTime: "Pelaajat jotka rekisteröityivät"
|
||||
retainedPlayersPercentage: "Pelaajien pysyvyys %"
|
||||
timeSinceRegistered: "Aika rekisteröitymispäivästä"
|
||||
timeStep: "Aika askel"
|
||||
secondDeadliestWeapon: "2. PvP Ase"
|
||||
seenNicknames: "Nähdyt Lempinimet"
|
||||
server: "Palvelin"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3. PvP Ase"
|
||||
thirtyDays: "30 päivää"
|
||||
thirtyDaysAgo: "30 päivää sitten"
|
||||
time:
|
||||
date: "Päivämäärä"
|
||||
day: "Päivä"
|
||||
days: "Päivää"
|
||||
hours: "Tuntia"
|
||||
month: "Kuukausi"
|
||||
months: "Kuukautta"
|
||||
week: "Viikko"
|
||||
weeks: "Viikkoa"
|
||||
year: "Vuosi"
|
||||
timesKicked: "Heitetty pihalle"
|
||||
toMainPage: "pääsivu"
|
||||
total: "Yhteensä"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "Suunnat 30 päivälle"
|
||||
uniquePlayers: "Uniikkeja pelaajia"
|
||||
uniquePlayers7days: "Uniikkeja pelaajia (7 päivää)"
|
||||
unit:
|
||||
percentage: "Prosentti"
|
||||
playerCount: "Pelaajamäärä"
|
||||
veryActive: "Todella Aktiivinen"
|
||||
weekComparison: "Viikkojen vertaus"
|
||||
weekdays: "'Maanantai', 'Tiistai', 'Keskiviikko', 'Torstai', 'Perjantai', 'Lauantai', 'Sunnuntai'"
|
||||
world: "Maailmojen Resurssit"
|
||||
worldPlaytime: "Maailmakohtainen Peliaika"
|
||||
worstPing: "Huonoin Vasteaika"
|
||||
xAxis: "X akseli"
|
||||
yAxis: "Y akseli"
|
||||
login:
|
||||
failed: "Kirjautuminen epäonnistui:"
|
||||
forgotPassword: "Unohtuiko salasana?"
|
||||
|
@ -504,7 +563,7 @@ html:
|
|||
contributors:
|
||||
bugreporters: "& Bugien ilmoittajat!"
|
||||
code: "koodin tuottaja"
|
||||
donate: "Suuret kiitokset rahallisesti tukeneille henkilöille."
|
||||
donate: "Suuret kiitokset projektia rahallisesti tukeneille henkilöille."
|
||||
text: 'Myös seuraavat <span class="col-plan">mahtavat ihmiset</span> ovat tukeneet kehitystä:'
|
||||
translator: "kääntäjä"
|
||||
developer: "on kehittänyt"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Heure par Heure"
|
||||
inactive: "Inactif(ve)"
|
||||
indexInactive: "Inactif"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Régulier(ère)"
|
||||
regularPlayers: "Joueurs Réguliers"
|
||||
relativeJoinActivity: "Activité de Connexion relative"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2ᵉ Arme de Combat"
|
||||
seenNicknames: "Surnoms vus"
|
||||
server: "Serveur"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3ᵉ Arme de Combat"
|
||||
thirtyDays: "30 jours"
|
||||
thirtyDaysAgo: "Il y a 30 jours"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Nombre d'Éjections"
|
||||
toMainPage: "Retour à la page principale"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "Tendances sur 30 Jours"
|
||||
uniquePlayers: "Joueurs Uniques"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Très Actif"
|
||||
weekComparison: "Comparaison Hebdomadaire"
|
||||
weekdays: "'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche'"
|
||||
world: "Charge du Monde"
|
||||
worldPlaytime: "Temps de Jeu par Monde"
|
||||
worstPing: "Pire Latence"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Connexion échouée : "
|
||||
forgotPassword: "Mot de Passe oublié ?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Hour by Hour"
|
||||
inactive: "Inattivo"
|
||||
indexInactive: "Inattivo"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Regolari"
|
||||
regularPlayers: "Giocatori Regolari"
|
||||
relativeJoinActivity: "Attività Entrate Relative"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2° Arma PvP Preferita"
|
||||
seenNicknames: "Nick Usati"
|
||||
server: "Server"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3° Arma PvP Preferita"
|
||||
thirtyDays: "30 giorni"
|
||||
thirtyDaysAgo: "30 giorni fa"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Cacciato"
|
||||
toMainPage: "Ritorna alla pagina principale"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "Tendenza per 30 giorni"
|
||||
uniquePlayers: "Giocatori unici"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Molto Attivo"
|
||||
weekComparison: "Confronto settimanale"
|
||||
weekdays: "'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato', 'Domenica'"
|
||||
world: "Caricamento Mondo"
|
||||
worldPlaytime: "Tempo di gioco Mondo"
|
||||
worstPing: "Ping Peggiore"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Login failed: "
|
||||
forgotPassword: "Forgot Password?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Hour by Hour"
|
||||
inactive: "休止中"
|
||||
indexInactive: "休止中"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "よくオンラインのプレイヤー"
|
||||
regularPlayers: "よくオンラインのプレイヤー"
|
||||
relativeJoinActivity: "オンラインと活動との関係性"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2番目にPvPで使用されている武器"
|
||||
seenNicknames: "ニックネーム一覧"
|
||||
server: "サーバー"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3番目にPvPで使用されている武器"
|
||||
thirtyDays: "1ヶ月"
|
||||
thirtyDaysAgo: "1ヶ月前"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "キック回数"
|
||||
toMainPage: "メインページに戻る"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "1ヶ月間の増減"
|
||||
uniquePlayers: "接続したプレイヤーの総数"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "とてもログインしている"
|
||||
weekComparison: "直近1周間での比較"
|
||||
weekdays: "'月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日', '日曜日'"
|
||||
world: "ワールドのロード数"
|
||||
worldPlaytime: "ワールドごとのプレイ時間"
|
||||
worstPing: "最低Ping値"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Login failed: "
|
||||
forgotPassword: "Forgot Password?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Hour by Hour"
|
||||
inactive: "비활성"
|
||||
indexInactive: "비활성"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "신규"
|
||||
regularPlayers: "신규 플레이어"
|
||||
relativeJoinActivity: "상대 조인 활동"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2nd PvP 무기"
|
||||
seenNicknames: "본 별명"
|
||||
server: "서버"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3rd PvP 무기"
|
||||
thirtyDays: "30일"
|
||||
thirtyDaysAgo: "30일 전"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "접속종료한 시간"
|
||||
toMainPage: "메인 페이지로"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "30일 동안의 트렌드"
|
||||
uniquePlayers: "기존 플레이어"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "매우 활성화된"
|
||||
weekComparison: "주 비교"
|
||||
weekdays: "'월요일', '화요일', '수요일', '목요일', '금요일', '토요일', '일요일'"
|
||||
world: "월드 로드"
|
||||
worldPlaytime: "맵 플레이 타임"
|
||||
worstPing: "Worst Ping"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Login failed: "
|
||||
forgotPassword: "Forgot Password?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Uur voor uur"
|
||||
inactive: "Inactief"
|
||||
indexInactive: "Inactief"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Regulier"
|
||||
regularPlayers: "Reguliere speler"
|
||||
relativeJoinActivity: "Relatieve deelname aan activiteit"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2e PvP-wapen"
|
||||
seenNicknames: "Bijnamen gezien"
|
||||
server: "Server"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3e PvP-wapen"
|
||||
thirtyDays: "30 dagen"
|
||||
thirtyDaysAgo: "30 dagen geleden"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Aantal keer afgetapt"
|
||||
toMainPage: "naar hoofdpagina"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "Trends voor 30 dagen"
|
||||
uniquePlayers: "Unieke spelers"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Heel Actief"
|
||||
weekComparison: "Weekvergelijking"
|
||||
weekdays: "'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag'"
|
||||
world: "Wereldbelasting"
|
||||
worldPlaytime: "Wereld speeltijd"
|
||||
worstPing: "Slechtste ping"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Login niet gelukt: "
|
||||
forgotPassword: "Wachtwoord Vergeten?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Hour by Hour"
|
||||
inactive: "Inactive"
|
||||
indexInactive: "Inativo"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Regular"
|
||||
regularPlayers: "Regular Players"
|
||||
relativeJoinActivity: "Relative Join Activity"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2nd PvP Weapon"
|
||||
seenNicknames: "Nicks Vistos"
|
||||
server: "Servidor"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3rd PvP Weapon"
|
||||
thirtyDays: "30 days"
|
||||
thirtyDaysAgo: "30 days ago"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Vezes Kickado"
|
||||
toMainPage: "to main page"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "Trends for 30 days"
|
||||
uniquePlayers: "Jogadores Únicos"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Muito Ativo"
|
||||
weekComparison: "Week Comparison"
|
||||
weekdays: "'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'"
|
||||
world: "World Load"
|
||||
worldPlaytime: "Tempo de Jogo por Mundo"
|
||||
worstPing: "Worst Ping"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Login failed: "
|
||||
forgotPassword: "Forgot Password?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Статистика по часам"
|
||||
inactive: "Неактивный"
|
||||
indexInactive: "Неактивный"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Постоянный"
|
||||
regularPlayers: "Постоянные игроки"
|
||||
relativeJoinActivity: "Сравнительная активность присоединения"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2-е PvP оружие"
|
||||
seenNicknames: "Увиденные никнеймы"
|
||||
server: "Сервер"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3-е PvP оружие"
|
||||
thirtyDays: "30 дней"
|
||||
thirtyDaysAgo: "30 дней назад"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Кол-во киков"
|
||||
toMainPage: "На главную страницу"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "тенденция за 30 дней"
|
||||
uniquePlayers: "Уникальные игроки"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Очень активный"
|
||||
weekComparison: "Сравнение за неделю"
|
||||
weekdays: "'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье'"
|
||||
world: "Загрузка мира"
|
||||
worldPlaytime: "Время игры в мире"
|
||||
worstPing: "Наихудший пинг"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Логин неудачен: "
|
||||
forgotPassword: "Забыли пароль?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "Saat saat"
|
||||
inactive: "Etkin değil"
|
||||
indexInactive: "Etkisiz"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "Düzenli"
|
||||
regularPlayers: "Normal Oyuncular"
|
||||
relativeJoinActivity: "Göreli Birleştirme Etkinliği"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "2. PvP Silahı"
|
||||
seenNicknames: "Görülen takma adlar"
|
||||
server: "Sunucu"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "3. PvP Silahı"
|
||||
thirtyDays: "30 gün"
|
||||
thirtyDaysAgo: "30 gün önce"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "Kere Atılmış"
|
||||
toMainPage: "Ana Sayfaya"
|
||||
total: "Total"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "30 günlük trendler"
|
||||
uniquePlayers: "Sunucuya İlk Defa Girenler"
|
||||
uniquePlayers7days: "Unique Players (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "Çok Aktif"
|
||||
weekComparison: "Hafta Karşılaştırması"
|
||||
weekdays: "'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi', 'Pazar'"
|
||||
world: "Dünya Yükle"
|
||||
worldPlaytime: "Dünya Oyun Süresi"
|
||||
worstPing: "En kötü Ping"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "Giriş başarısız:"
|
||||
forgotPassword: "Parolanızı mı unuttunuz?"
|
||||
|
|
|
@ -338,12 +338,42 @@ html:
|
|||
activityIndexExample3: "The index approaches 5 indefinitely."
|
||||
activityIndexVisual: "Here is a visualization of the curve where y = activity index, and x = playtime per week / threshold."
|
||||
activityIndexWeek: "Week {}"
|
||||
examples: "Examples"
|
||||
graph:
|
||||
labels: "You can hide/show a group by clicking on the label at the bottom."
|
||||
title: "Graph"
|
||||
zoom: "You can Zoom in by click + dragging on the graph."
|
||||
playtimeUnit: "hours"
|
||||
retention:
|
||||
calculationStep1: "First the data is filtered using '<>' option. Any players with 'registerDate' outside the time range are ignored."
|
||||
calculationStep2: "Then it is grouped into groups of players using '<0>' option, eg. With '<1>': All players who registered in January 2023, February 2023, etc"
|
||||
calculationStep3: "Then the '<0>' and '<1>' options select which visualization to render."
|
||||
calculationStep4: "'<>' controls how many points the graph has, eg. 'Days' has one point per day."
|
||||
calculationStep5: "On each calculated point all players are checked for the condition."
|
||||
calculationStep6: "Select X Axis below to see conditions."
|
||||
calculationStepDate: "This visualization shows the different groups of players that are still playing on your server. The visualization uses lastSeen date. If x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepDeltas: "This visualization is most effective using Player Count as the Y Axis. The visualization shows net gain of players (How many players joined minus players who stopped playing). The visualization uses both registered and lastSeen dates. If registerDate < x < lastSeenDate, the player is visible on the graph."
|
||||
calculationStepPlaytime: "This visualization tells how long the gameplay loop keeps players engaged on your server. The visualization uses playtime. If x < playtime, the player is visible on the graph."
|
||||
calculationStepTime: "This visualization tells how long people keep coming back to play on the server after they join the first time. The visualization uses timeDifference. If x < timeDifference, the player is visible on the graph."
|
||||
compareJoinAddress: "Grouping by join address allows measuring advertising campaigns on different sites."
|
||||
compareMonths: "You can compare different months by changing the '<0>' option to '<1>'"
|
||||
examples:
|
||||
adCampaign: "Comparing player gain of different ad campaigns using different Join Addresses (anonymized)"
|
||||
deltas: "<> shows net gain of players."
|
||||
pattern: "A general pattern emerges when all players start leaving the server at the same time"
|
||||
plateau: "Comparing player gain of different months. Plateaus suggest there were players Plan doesn't know about. In this example Plan was installed in January 2022."
|
||||
playtime: "Playtime tells how long the gameplay loop keeps players engaged on your server."
|
||||
stack: "Cumulative player gain can be checked with stacked player count as Y axis"
|
||||
howIsItCalculated: "How it is calculated"
|
||||
howIsItCalculatedData: "The graph is generated from player data:"
|
||||
options: "Select the options to analyze different aspects of Player Retention."
|
||||
retentionBasis: "New player retention is calculated based on session data. If a registered player has played within latter half of the timespan, they are considered retained."
|
||||
testPrompt: "Test it out:"
|
||||
testResult: "Test result"
|
||||
threshold: "Threshold"
|
||||
thresholdUnit: "hours / week"
|
||||
tips: "Tips"
|
||||
usingTheGraph: "Using the Graph"
|
||||
hourByHour: "按小時查看"
|
||||
inactive: "不活躍"
|
||||
indexInactive: "不活躍"
|
||||
|
@ -439,6 +469,20 @@ html:
|
|||
regular: "普通"
|
||||
regularPlayers: "普通玩家"
|
||||
relativeJoinActivity: "最近加入活動"
|
||||
retention:
|
||||
groupByNone: "No grouping"
|
||||
groupByTime: "Group registered by"
|
||||
inAnytime: "any time"
|
||||
inLast180d: "in the last 6 months"
|
||||
inLast30d: "in the last 30 days"
|
||||
inLast365d: "in the last 12 months"
|
||||
inLast730d: "in the last 24 months"
|
||||
inLast7d: "in the last 7 days"
|
||||
inLast90d: "in the last 3 months"
|
||||
playersRegisteredInTime: "Players who registered"
|
||||
retainedPlayersPercentage: "Retained Players %"
|
||||
timeSinceRegistered: "Time since register date"
|
||||
timeStep: "Time step"
|
||||
secondDeadliestWeapon: "第二致命的 PvP 武器"
|
||||
seenNicknames: "使用過的暱稱"
|
||||
server: "伺服器"
|
||||
|
@ -466,6 +510,16 @@ html:
|
|||
thirdDeadliestWeapon: "第三致命的 PvP 武器"
|
||||
thirtyDays: "30 天"
|
||||
thirtyDaysAgo: "30 天前"
|
||||
time:
|
||||
date: "Date"
|
||||
day: "Day"
|
||||
days: "Days"
|
||||
hours: "Hours"
|
||||
month: "Month"
|
||||
months: "Months"
|
||||
week: "Week"
|
||||
weeks: "Weeks"
|
||||
year: "Year"
|
||||
timesKicked: "被踢出次數"
|
||||
toMainPage: "回到主頁面"
|
||||
total: "總計"
|
||||
|
@ -480,12 +534,17 @@ html:
|
|||
trends30days: "30 天趨勢"
|
||||
uniquePlayers: "獨立玩家"
|
||||
uniquePlayers7days: "獨立玩家 (7 days)"
|
||||
unit:
|
||||
percentage: "Percentage"
|
||||
playerCount: "Player Count"
|
||||
veryActive: "非常活躍"
|
||||
weekComparison: "每週對比"
|
||||
weekdays: "'星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'"
|
||||
world: "世界載入"
|
||||
worldPlaytime: "世界遊玩時間"
|
||||
worstPing: "最高延遲"
|
||||
xAxis: "X Axis"
|
||||
yAxis: "Y Axis"
|
||||
login:
|
||||
failed: "登入失敗:"
|
||||
forgotPassword: "忘記密碼?"
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
"@testing-library/user-event": "^14.4.3",
|
||||
"axios": "^1.3.4",
|
||||
"bootstrap": "^5.2.3",
|
||||
"datatables.net": "^1.13.3",
|
||||
"datatables.net-bs5": "^1.13.3",
|
||||
"datatables.net-responsive-bs5": "^2.4.0",
|
||||
"datatables.net": "^1.13.4",
|
||||
"datatables.net-bs5": "^1.13.4",
|
||||
"datatables.net-responsive-bs5": "^2.4.1",
|
||||
"highcharts": "^10.3.3",
|
||||
"i18next": "^22.4.10",
|
||||
"i18next": "^22.4.11",
|
||||
"i18next-chained-backend": "^4.2.0",
|
||||
"i18next-http-backend": "^2.1.1",
|
||||
"i18next-http-backend": "^2.2.0",
|
||||
"i18next-localstorage-backend": "^4.1.0",
|
||||
"masonry-layout": "^4.2.2",
|
||||
"react": "^18.2.0",
|
||||
|
@ -37,9 +37,9 @@
|
|||
"react-mcjsonchat": "^1.0.0",
|
||||
"react-router-dom": "6",
|
||||
"react-scripts": "5.0.1",
|
||||
"sass": "^1.58.3",
|
||||
"sass": "^1.59.3",
|
||||
"source-map-explorer": "^2.5.2",
|
||||
"swagger-ui": "^4.17.0",
|
||||
"swagger-ui": "^4.18.1",
|
||||
"web-vitals": "^3.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
@ -37,12 +37,14 @@ const ServerPerformance = React.lazy(() => import("./views/server/ServerPerforma
|
|||
const ServerPluginData = React.lazy(() => import("./views/server/ServerPluginData"));
|
||||
const ServerWidePluginData = React.lazy(() => import("./views/server/ServerWidePluginData"));
|
||||
const ServerJoinAddresses = React.lazy(() => import("./views/server/ServerJoinAddresses"));
|
||||
const ServerPlayerRetention = React.lazy(() => import("./views/server/ServerPlayerRetention"));
|
||||
|
||||
const NetworkPage = React.lazy(() => import("./views/layout/NetworkPage"));
|
||||
const NetworkOverview = React.lazy(() => import("./views/network/NetworkOverview"));
|
||||
const NetworkServers = React.lazy(() => import("./views/network/NetworkServers"));
|
||||
const NetworkSessions = React.lazy(() => import("./views/network/NetworkSessions"));
|
||||
const NetworkJoinAddresses = React.lazy(() => import("./views/network/NetworkJoinAddresses"));
|
||||
const NetworkPlayerRetention = React.lazy(() => import("./views/network/NetworkPlayerRetention"));
|
||||
const NetworkGeolocations = React.lazy(() => import("./views/network/NetworkGeolocations"));
|
||||
const NetworkPlayerbaseOverview = React.lazy(() => import("./views/network/NetworkPlayerbaseOverview"));
|
||||
const NetworkPerformance = React.lazy(() => import("./views/network/NetworkPerformance"));
|
||||
|
@ -145,7 +147,7 @@ function App() {
|
|||
<Route path="pvppve" element={<Lazy><ServerPvpPve/></Lazy>}/>
|
||||
<Route path="playerbase" element={<Lazy><PlayerbaseOverview/></Lazy>}/>
|
||||
<Route path="join-addresses" element={<Lazy><ServerJoinAddresses/></Lazy>}/>
|
||||
<Route path="retention" element={<></>}/>
|
||||
<Route path="retention" element={<Lazy><ServerPlayerRetention/></Lazy>}/>
|
||||
<Route path="players" element={<Lazy><ServerPlayers/></Lazy>}/>
|
||||
<Route path="geolocations" element={<Lazy><ServerGeolocations/></Lazy>}/>
|
||||
<Route path="performance" element={<Lazy><ServerPerformance/></Lazy>}/>
|
||||
|
@ -165,6 +167,7 @@ function App() {
|
|||
{!staticSite &&
|
||||
<Route path="performance" element={<Lazy><NetworkPerformance/></Lazy>}/>}
|
||||
<Route path="playerbase" element={<Lazy><NetworkPlayerbaseOverview/></Lazy>}/>
|
||||
<Route path="retention" element={<Lazy><NetworkPlayerRetention/></Lazy>}/>
|
||||
<Route path="join-addresses" element={<Lazy><NetworkJoinAddresses/></Lazy>}/>
|
||||
<Route path="players" element={<Lazy><AllPlayers/></Lazy>}/>
|
||||
<Route path="geolocations" element={<Lazy><NetworkGeolocations/></Lazy>}/>
|
||||
|
|
|
@ -17,9 +17,9 @@ const TabButton = ({name, href, icon, color, active}) => {
|
|||
const TabButtons = ({tabs, selectedTab}) => {
|
||||
return (
|
||||
<ul className="nav nav-tabs" role="tablist">
|
||||
{tabs.map((tab, i) => (
|
||||
{tabs.map(tab => (
|
||||
<TabButton
|
||||
key={i}
|
||||
key={tab.href}
|
||||
name={tab.name}
|
||||
href={tab.href}
|
||||
icon={tab.icon}
|
||||
|
@ -37,10 +37,10 @@ const CardTabs = ({tabs}) => {
|
|||
const [selectedTab, setSelectedTab] = useState(firstTab);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedTab(hash && tabs ? tabs.find(t => t.href === hash.substring(1)).href : firstTab)
|
||||
setSelectedTab(hash && tabs ? tabs.find(t => t.href === hash.substring(1))?.href : firstTab)
|
||||
}, [hash, tabs, firstTab])
|
||||
|
||||
const tabContent = tabs.find(t => t.href === selectedTab).element;
|
||||
const tabContent = tabs.find(t => t.href === selectedTab)?.element;
|
||||
return (
|
||||
<>
|
||||
<TabButtons tabs={tabs} selectedTab={selectedTab}/>
|
||||
|
|
|
@ -3,13 +3,14 @@ import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
|||
import {Card} from "react-bootstrap";
|
||||
import {useTranslation} from "react-i18next";
|
||||
|
||||
const CardHeader = ({icon, color, label}) => {
|
||||
const CardHeader = ({icon, color, label, children}) => {
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<Card.Header>
|
||||
<h6 className="col-black">
|
||||
<h6 className="col-black" style={{width: "100%"}}>
|
||||
<Fa icon={icon} className={"col-" + color}/> {t(label)}
|
||||
{children}
|
||||
</h6>
|
||||
</Card.Header>
|
||||
)
|
||||
|
|
|
@ -0,0 +1,322 @@
|
|||
import React, {useCallback, useEffect, useMemo, useState} from 'react';
|
||||
import {Card, Col, Row} from "react-bootstrap";
|
||||
import CardHeader from "../CardHeader";
|
||||
import {faUsersViewfinder} from "@fortawesome/free-solid-svg-icons";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import ExtendableCardBody from "../../layout/extension/ExtendableCardBody";
|
||||
import {BasicDropdown} from "../../input/BasicDropdown";
|
||||
import {useDataRequest} from "../../../hooks/dataFetchHook";
|
||||
import {fetchPlayerJoinAddresses, fetchRetentionData} from "../../../service/serverService";
|
||||
import {ErrorViewCard} from "../../../views/ErrorView";
|
||||
import {CardLoader} from "../../navigation/Loader";
|
||||
import {tooltip} from "../../../util/graphs";
|
||||
import {hsvToRgb, randomHSVColor, rgbToHexString, withReducedSaturation} from "../../../util/colors";
|
||||
import LineGraph from "../../graphs/LineGraph";
|
||||
import FunctionPlotGraph from "../../graphs/FunctionPlotGraph";
|
||||
import {useTheme} from "../../../hooks/themeHook";
|
||||
import {useNavigation} from "../../../hooks/navigationHook";
|
||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||
import {faQuestionCircle} from "@fortawesome/free-regular-svg-icons";
|
||||
|
||||
const dayMs = 24 * 3600000;
|
||||
const getWeek = (date) => {
|
||||
const onejan = new Date(date.getFullYear(), 0, 1);
|
||||
const today = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||||
const dayOfYear = ((today - onejan + 86400000) / 86400000);
|
||||
return Math.ceil(dayOfYear / 7)
|
||||
};
|
||||
|
||||
const PlayerRetentionGraphCard = ({identifier}) => {
|
||||
const {t} = useTranslation();
|
||||
const {nightModeEnabled} = useTheme();
|
||||
const {setHelpModalTopic} = useNavigation();
|
||||
const openHelp = useCallback(() => setHelpModalTopic('player-retention-graph'), [setHelpModalTopic]);
|
||||
|
||||
const time = useMemo(() => new Date().getTime(), []);
|
||||
|
||||
const {data, loadingError} = useDataRequest(fetchRetentionData, [identifier]);
|
||||
const {
|
||||
data: joinAddressData,
|
||||
loadingError: joinAddressLoadingError
|
||||
} = useDataRequest(fetchPlayerJoinAddresses, [identifier]);
|
||||
|
||||
const [selectedWindow, setSelectedWindow] = useState('days');
|
||||
const windowOptions = useMemo(() => [
|
||||
{name: 'hours', displayName: t('html.label.time.hours'), increment: 3600000},
|
||||
{name: 'days', displayName: t('html.label.time.days'), increment: dayMs},
|
||||
{name: 'weeks', displayName: t('html.label.time.weeks'), increment: 7 * dayMs},
|
||||
{name: 'months', displayName: t('html.label.time.months'), increment: 30 * dayMs},
|
||||
], [t]);
|
||||
const [selectedGroup, setSelectedGroup] = useState('registered-7d');
|
||||
const groupOptions = useMemo(() => [
|
||||
{name: 'registered-7d', displayName: t('html.label.retention.inLast7d'), start: time - 7 * dayMs},
|
||||
{name: 'registered-30d', displayName: t('html.label.retention.inLast30d'), start: time - 30 * dayMs},
|
||||
{name: 'registered-3m', displayName: t('html.label.retention.inLast90d'), start: time - 3 * 30 * dayMs},
|
||||
{name: 'registered-6m', displayName: t('html.label.retention.inLast180d'), start: time - 6 * 30 * dayMs},
|
||||
{name: 'registered-1y', displayName: t('html.label.retention.inLast365d'), start: time - 365 * dayMs},
|
||||
{name: 'registered-2y', displayName: t('html.label.retention.inLast730d'), start: time - 2 * 365 * dayMs},
|
||||
{name: 'registered-ever', displayName: t('html.label.retention.inAnytime'), start: 0},
|
||||
], [t, time]);
|
||||
const [selectedGroupBy, setSelectedGroupBy] = useState('none');
|
||||
const groupByOptions = useMemo(() => [
|
||||
{name: 'none', displayName: t('html.label.retention.groupByNone')},
|
||||
{name: 'days', displayName: t('html.label.time.day')},
|
||||
{name: 'weeks', displayName: t('html.label.time.week')},
|
||||
{name: 'months', displayName: t('html.label.time.month')},
|
||||
{name: 'years', displayName: t('html.label.time.year')},
|
||||
{name: 'joinAddress', displayName: t('html.label.joinAddress')},
|
||||
], [t]);
|
||||
const [selectedYAxis, setSelectedYAxis] = useState('percentage');
|
||||
const yAxisOptions = useMemo(() => [
|
||||
{name: 'percentage', displayName: t('html.label.unit.percentage')},
|
||||
{name: 'count', displayName: t('html.label.unit.playerCount')},
|
||||
{name: 'count-stacked', displayName: t('html.label.unit.playerCount') + ' (' + t('html.label.stacked') + ')'},
|
||||
], [t]);
|
||||
const [selectedAxis, setSelectedAxis] = useState('time');
|
||||
const axisOptions = useMemo(() => [
|
||||
{name: 'time', displayName: t('html.label.retention.timeSinceRegistered')},
|
||||
{name: 'playtime', displayName: t('html.label.playtime')},
|
||||
{name: 'date', displayName: t('html.label.time.date')},
|
||||
{name: 'deltas', displayName: t('html.label.time.date') + ' > ' + t('html.label.registered')},
|
||||
], [t]);
|
||||
|
||||
const [series, setSeries] = useState([]);
|
||||
const [graphOptions, setGraphOptions] = useState({title: {text: ''},});
|
||||
|
||||
const mapToData = useCallback(async (dataToMap, start) => {
|
||||
const total = dataToMap.length;
|
||||
let seriesData;
|
||||
const increment = windowOptions.find(option => option.name === selectedWindow).increment;
|
||||
const xAxis = axisOptions.find(option => option.name === selectedAxis).name;
|
||||
switch (xAxis) {
|
||||
case 'deltas':
|
||||
const retainedBasedOnDeltas = [];
|
||||
const firstRegisterDeltasStart = dataToMap[0].registerDate - dataToMap[0].registerDate % increment;
|
||||
let previousRetained = -1;
|
||||
for (let date = firstRegisterDeltasStart; date < time; date += increment) {
|
||||
const filter = player => player.registerDate <= date && player.lastSeenDate >= date;
|
||||
const retainedSince = dataToMap.filter(filter).length;
|
||||
retainedBasedOnDeltas.push([date, selectedYAxis === 'percentage' ? retainedSince * 100.0 / total : retainedSince]);
|
||||
if (previousRetained === retainedSince && retainedSince <= 0.5) break;
|
||||
if (previousRetained !== -1 || retainedSince > 0) previousRetained = retainedSince;
|
||||
}
|
||||
seriesData = retainedBasedOnDeltas;
|
||||
break;
|
||||
case 'date':
|
||||
const retainedBasedOnDate = [];
|
||||
const firstRegisterDateStart = dataToMap[0].registerDate - dataToMap[0].registerDate % increment;
|
||||
for (let date = firstRegisterDateStart; date < time; date += increment) {
|
||||
const filter = player => player.lastSeenDate >= date;
|
||||
const retainedSince = dataToMap.filter(filter).length;
|
||||
retainedBasedOnDate.push([date, selectedYAxis === 'percentage' ? retainedSince * 100.0 / total : retainedSince]);
|
||||
if (retainedSince < 0.5) break;
|
||||
}
|
||||
seriesData = retainedBasedOnDate;
|
||||
break;
|
||||
case 'time':
|
||||
const retainedBasedOnTime = [];
|
||||
for (let i = 0; i < time; i += increment) {
|
||||
const retainedSince = dataToMap.filter(point => point.timeDifference > i).length;
|
||||
retainedBasedOnTime.push([(i) / increment, selectedYAxis === 'percentage' ? retainedSince * 100.0 / total : retainedSince]);
|
||||
if (retainedSince < 0.5) break;
|
||||
}
|
||||
seriesData = retainedBasedOnTime;
|
||||
break;
|
||||
case 'playtime':
|
||||
default:
|
||||
const retainedBasedOnPlaytime = [];
|
||||
for (let i = start; i < time; i += increment) {
|
||||
const retainedSince = dataToMap.filter(point => point.playtime > i - start).length;
|
||||
retainedBasedOnPlaytime.push([(i - start) / increment, selectedYAxis === 'percentage' ? retainedSince * 100.0 / total : retainedSince]);
|
||||
if (retainedSince < 0.5) break;
|
||||
}
|
||||
seriesData = retainedBasedOnPlaytime;
|
||||
break;
|
||||
}
|
||||
return seriesData;
|
||||
}, [selectedWindow, windowOptions, selectedAxis, axisOptions, selectedYAxis, time])
|
||||
|
||||
const group = useCallback(async (filtered, joinAddressData) => {
|
||||
const grouped = {};
|
||||
const groupBy = groupByOptions.find(option => option.name === selectedGroupBy).name;
|
||||
for (const point of filtered) {
|
||||
const date = new Date();
|
||||
date.setTime(point.registerDate);
|
||||
switch (groupBy) {
|
||||
case 'days':
|
||||
const day = date.toISOString().substring(0, 10);
|
||||
if (!grouped[day]) grouped[day] = [];
|
||||
grouped[day].push(point);
|
||||
break;
|
||||
case 'weeks':
|
||||
const week = date.getUTCFullYear() + '-week-' + getWeek(date);
|
||||
if (!grouped[week]) grouped[week] = [];
|
||||
grouped[week].push(point);
|
||||
break;
|
||||
case 'months':
|
||||
const month = date.toISOString().substring(0, 7);
|
||||
if (!grouped[month]) grouped[month] = [];
|
||||
grouped[month].push(point);
|
||||
break;
|
||||
case 'years':
|
||||
const year = date.getUTCFullYear();
|
||||
if (!grouped[year]) grouped[year] = [];
|
||||
grouped[year].push(point);
|
||||
break;
|
||||
case 'joinAddress':
|
||||
const joinAddress = joinAddressData[point.playerUUID];
|
||||
if (!grouped[joinAddress]) grouped[joinAddress] = [];
|
||||
grouped[joinAddress].push(point);
|
||||
break;
|
||||
case 'none':
|
||||
default:
|
||||
grouped['all'] = filtered;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return grouped;
|
||||
}, [groupByOptions, selectedGroupBy]);
|
||||
|
||||
const createSeries = useCallback(async (retentionData, joinAddressData) => {
|
||||
|
||||
const start = groupOptions.find(option => option.name === selectedGroup).start;
|
||||
const filtered = retentionData.filter(point => point.registerDate > start)
|
||||
.sort((a, b) => a.registerDate - b.registerDate);
|
||||
|
||||
const grouped = await group(filtered, joinAddressData);
|
||||
|
||||
let colorIndex = 1;
|
||||
return Promise.all(Object.entries(grouped).map(async group => {
|
||||
const name = group[0];
|
||||
const groupData = group[1];
|
||||
const color = rgbToHexString(hsvToRgb(randomHSVColor(colorIndex)));
|
||||
colorIndex++;
|
||||
const mapped = await mapToData(groupData, start);
|
||||
if (mapped.filter(point => point[1] === 0).length === mapped.length) {
|
||||
// Don't include all zeros series
|
||||
return [];
|
||||
}
|
||||
return [{
|
||||
name: name,
|
||||
type: selectedYAxis === 'count-stacked' ? 'areaspline' : 'spline',
|
||||
tooltip: tooltip.twoDecimals,
|
||||
data: mapped,
|
||||
color: nightModeEnabled ? withReducedSaturation(color) : color
|
||||
}];
|
||||
}));
|
||||
}, [nightModeEnabled, mapToData, groupOptions, selectedGroup, selectedYAxis, group]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!data || !joinAddressData) return;
|
||||
|
||||
createSeries(data.player_retention, joinAddressData.join_address_by_player).then(series => setSeries(series.flat()));
|
||||
}, [data, joinAddressData, createSeries, setSeries]);
|
||||
|
||||
useEffect(() => {
|
||||
const windowName = windowOptions.find(option => option.name === selectedWindow).displayName;
|
||||
const unitLabel = selectedYAxis === 'percentage' ? t('html.label.retention.retainedPlayersPercentage') : t('html.label.players');
|
||||
const axisName = axisOptions.find(option => option.name === selectedAxis).displayName;
|
||||
setGraphOptions({
|
||||
title: {text: ''},
|
||||
rangeSelector: selectedAxis === 'date' ? {
|
||||
selected: 2,
|
||||
buttons: [{
|
||||
type: 'day',
|
||||
count: 7,
|
||||
text: '7d'
|
||||
}, {
|
||||
type: 'month',
|
||||
count: 1,
|
||||
text: '30d'
|
||||
}, {
|
||||
type: 'all',
|
||||
text: 'All'
|
||||
}]
|
||||
} : undefined,
|
||||
chart: {
|
||||
zooming: {
|
||||
type: 'xy'
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
areaspline: {
|
||||
fillOpacity: nightModeEnabled ? 0.2 : 0.4,
|
||||
stacking: 'normal'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
enabled: selectedGroupBy !== 'none',
|
||||
},
|
||||
xAxis: {
|
||||
zoomEnabled: true,
|
||||
title: {
|
||||
text: selectedAxis === 'date' || selectedAxis === 'deltas' ? t('html.label.time.date') : axisName + ' (' + windowName + ')'
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
zoomEnabled: true,
|
||||
title: {text: unitLabel},
|
||||
max: selectedYAxis === 'percentage' ? 100 : undefined,
|
||||
min: 0
|
||||
},
|
||||
tooltip: selectedAxis === 'date' || selectedAxis === 'deltas' ? {
|
||||
enabled: true,
|
||||
valueDecimals: 2,
|
||||
pointFormat: (selectedGroupBy !== 'none' ? '{series.name} - ' : '') + '<b>{point.y} ' + (selectedYAxis === 'percentage' ? '%' : t('html.label.players')) + '</b>'
|
||||
} : {
|
||||
enabled: true,
|
||||
valueDecimals: 2,
|
||||
headerFormat: '{point.x} ' + windowName + '<br>',
|
||||
pointFormat: (selectedGroupBy !== 'none' ? '{series.name} - ' : '') + '<b>{point.y} ' + (selectedYAxis === 'percentage' ? '%' : t('html.label.players')) + '</b>'
|
||||
},
|
||||
series: series
|
||||
})
|
||||
}, [t, nightModeEnabled, series, selectedGroupBy, axisOptions, selectedAxis, windowOptions, selectedWindow, selectedYAxis]);
|
||||
|
||||
if (loadingError) return <ErrorViewCard error={loadingError}/>
|
||||
if (joinAddressLoadingError) return <ErrorViewCard error={joinAddressLoadingError}/>
|
||||
if (!data || !joinAddressData) return <CardLoader/>;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader icon={faUsersViewfinder} color={'indigo'} label={t('html.label.playerRetention')}>
|
||||
<button className={"float-end"} onClick={openHelp}>
|
||||
<Fa className={"col-blue"}
|
||||
icon={faQuestionCircle}/>
|
||||
</button>
|
||||
</CardHeader>
|
||||
<ExtendableCardBody id={'card-body-' + (identifier ? 'server-' : 'network-') + 'player-retention'}>
|
||||
<Row>
|
||||
<Col>
|
||||
<label>{t('html.label.retention.timeStep')}</label>
|
||||
<BasicDropdown selected={selectedWindow} options={windowOptions} onChange={setSelectedWindow}/>
|
||||
</Col>
|
||||
<Col>
|
||||
<label>{t('html.label.retention.playersRegisteredInTime')}</label>
|
||||
<BasicDropdown selected={selectedGroup} options={groupOptions} onChange={setSelectedGroup}/>
|
||||
</Col>
|
||||
<Col>
|
||||
<label>{t('html.label.retention.groupByTime')}</label>
|
||||
<BasicDropdown selected={selectedGroupBy} options={groupByOptions}
|
||||
onChange={setSelectedGroupBy}/>
|
||||
</Col>
|
||||
<Col>
|
||||
<label>{t('html.label.xAxis')}</label>
|
||||
<BasicDropdown selected={selectedAxis} options={axisOptions} onChange={setSelectedAxis}/>
|
||||
</Col>
|
||||
<Col>
|
||||
<label>{t('html.label.yAxis')}</label>
|
||||
<BasicDropdown selected={selectedYAxis} options={yAxisOptions} onChange={setSelectedYAxis}/>
|
||||
</Col>
|
||||
</Row>
|
||||
<hr/>
|
||||
{(selectedAxis !== 'date' && selectedAxis !== 'deltas') &&
|
||||
<FunctionPlotGraph id={'retention-graph'} options={graphOptions} tall/>}
|
||||
{(selectedAxis === 'date' || selectedAxis === 'deltas') &&
|
||||
<LineGraph id={'retention-graph'} options={graphOptions} tall/>}
|
||||
</ExtendableCardBody>
|
||||
</Card>
|
||||
)
|
||||
};
|
||||
|
||||
export default PlayerRetentionGraphCard
|
|
@ -11,7 +11,7 @@ const QuickViewGraphCard = ({server}) => {
|
|||
<Card>
|
||||
<CardHeader icon={faChartArea} color={'light-blue'}
|
||||
label={server.name + ' ' + t('html.label.onlineActivity') + ' (' + t('html.label.thirtyDays') + ')'}/>
|
||||
<PlayersOnlineGraph data={server.playersOnline}/>
|
||||
<PlayersOnlineGraph data={{playersOnline: server.playersOnline, color: server.playersOnlineColor}}/>
|
||||
</Card>
|
||||
)
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ const FunctionPlotGraph = ({
|
|||
yPlotBands,
|
||||
xPlotLines,
|
||||
xPlotBands,
|
||||
options
|
||||
}) => {
|
||||
const {t} = useTranslation()
|
||||
const {graphTheming, nightModeEnabled} = useTheme();
|
||||
|
@ -23,7 +24,7 @@ const FunctionPlotGraph = ({
|
|||
Accessibility(Highcharts);
|
||||
Highcharts.setOptions({lang: {noData: t('html.label.noDataToDisplay')}})
|
||||
Highcharts.setOptions(graphTheming);
|
||||
Highcharts.chart(id, {
|
||||
Highcharts.chart(id, options ? options : {
|
||||
yAxis: {
|
||||
plotLines: yPlotLines,
|
||||
plotBands: yPlotBands
|
||||
|
@ -44,7 +45,7 @@ const FunctionPlotGraph = ({
|
|||
},
|
||||
series: series
|
||||
});
|
||||
}, [series, id, t, graphTheming, nightModeEnabled, legendEnabled,
|
||||
}, [options, series, id, t, graphTheming, nightModeEnabled, legendEnabled,
|
||||
yPlotLines, yPlotBands, xPlotLines, xPlotBands]);
|
||||
|
||||
const style = tall ? {height: "450px"} : undefined;
|
||||
|
|
|
@ -16,7 +16,9 @@ const LineGraph = ({
|
|||
selectedRange,
|
||||
extremes,
|
||||
onSetExtremes,
|
||||
alreadyOffsetTimezone
|
||||
alreadyOffsetTimezone,
|
||||
options,
|
||||
extraModules
|
||||
}) => {
|
||||
const {t} = useTranslation()
|
||||
const {graphTheming, nightModeEnabled} = useTheme();
|
||||
|
@ -26,9 +28,14 @@ const LineGraph = ({
|
|||
useEffect(() => {
|
||||
NoDataDisplay(Highcharts);
|
||||
Accessibility(Highcharts);
|
||||
if (extraModules) {
|
||||
for (const extraModule of extraModules) {
|
||||
extraModule(Highcharts);
|
||||
}
|
||||
}
|
||||
Highcharts.setOptions({lang: {noData: t('html.label.noDataToDisplay')}})
|
||||
Highcharts.setOptions(graphTheming);
|
||||
setGraph(Highcharts.stockChart(id, {
|
||||
setGraph(Highcharts.stockChart(id, options ? options : {
|
||||
rangeSelector: {
|
||||
selected: selectedRange !== undefined ? selectedRange : 2,
|
||||
buttons: linegraphButtons
|
||||
|
@ -58,7 +65,7 @@ const LineGraph = ({
|
|||
},
|
||||
series: series
|
||||
}));
|
||||
}, [series, id, t,
|
||||
}, [options, extraModules, series, id, t,
|
||||
graphTheming, nightModeEnabled, alreadyOffsetTimezone, timeZoneOffsetMinutes,
|
||||
legendEnabled, yAxis,
|
||||
onSetExtremes, setGraph, selectedRange]);
|
||||
|
|
|
@ -1,28 +1,16 @@
|
|||
import React from 'react';
|
||||
import DropdownToggle from "react-bootstrap/lib/esm/DropdownToggle";
|
||||
import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome";
|
||||
import DropdownMenu from "react-bootstrap/lib/esm/DropdownMenu";
|
||||
import DropdownItem from "react-bootstrap/lib/esm/DropdownItem";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {Dropdown} from "react-bootstrap";
|
||||
import React, {useCallback} from 'react';
|
||||
|
||||
export const DropDownWithOptions = ({selected, optionList, onChange, optionLabelMapper, icon, title}) => {
|
||||
const {t} = useTranslation();
|
||||
export const BasicDropdown = ({selected, onChange, options}) => {
|
||||
const onSelect = useCallback(({target}) => {
|
||||
onChange(target.value);
|
||||
}, [onChange]);
|
||||
|
||||
return (
|
||||
<Dropdown className="float-end" style={{position: "absolute", right: "0.5rem"}} title={t(title)}>
|
||||
<DropdownToggle variant=''>
|
||||
<Fa icon={icon}/> {t(optionLabelMapper ? optionLabelMapper(selected) : selected)}
|
||||
</DropdownToggle>
|
||||
|
||||
<DropdownMenu>
|
||||
<h6 className="dropdown-header">{t(title)}</h6>
|
||||
{optionList.map((option, i) => (
|
||||
<DropdownItem key={i} onClick={() => onChange(option)}>
|
||||
{t(optionLabelMapper ? optionLabelMapper(option) : option)}
|
||||
</DropdownItem>
|
||||
))}
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
<select onChange={onSelect}
|
||||
className="form-select form-select-sm"
|
||||
defaultValue={selected}>
|
||||
{options.map((option, i) =>
|
||||
<option key={option.name} value={option.name} disabled={option.disabled}>{option.displayName}</option>)}
|
||||
</select>
|
||||
)
|
||||
};
|
|
@ -6,6 +6,7 @@ import {useTranslation} from "react-i18next";
|
|||
import ActivityIndexHelp from "./help/ActivityIndexHelp";
|
||||
import {faQuestionCircle} from "@fortawesome/free-regular-svg-icons";
|
||||
import NewPlayerRetentionHelp from "./help/NewPlayerRetentionHelp";
|
||||
import PlayerRetentionGraphHelp from "./help/PlayerRetentionGraphHelp";
|
||||
|
||||
const HelpModal = () => {
|
||||
const {t} = useTranslation();
|
||||
|
@ -20,6 +21,10 @@ const HelpModal = () => {
|
|||
"new-player-retention": {
|
||||
title: t('html.label.newPlayerRetention'),
|
||||
body: <NewPlayerRetentionHelp/>
|
||||
},
|
||||
"player-retention-graph": {
|
||||
title: t('html.label.playerRetention'),
|
||||
body: <PlayerRetentionGraphHelp/>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@ const inverseIndex = y => {
|
|||
return -2 * y / (Math.PI * (y - 5));
|
||||
}
|
||||
|
||||
const activityIndexPlot = () => {
|
||||
const activityIndexPlot = (maxValue) => {
|
||||
const data = []
|
||||
let x;
|
||||
|
||||
for (x = 0; x <= 3.5; x += 0.01) {
|
||||
for (x = 0; x <= Math.max(3.5, maxValue); x += 0.01) {
|
||||
data.push([x, indexValue(x)]);
|
||||
}
|
||||
return data;
|
||||
|
@ -67,7 +67,8 @@ const ActivityIndexHelp = () => {
|
|||
const [result, setResult] = useState(0);
|
||||
|
||||
const series = useMemo(() => {
|
||||
const data = activityIndexPlot();
|
||||
const inverse = inverseIndex(result);
|
||||
const data = activityIndexPlot(inverse);
|
||||
return [{
|
||||
name: t('html.label.activityIndex') + ' y=5-5/(πx/2)+1',
|
||||
data: data,
|
||||
|
@ -77,7 +78,7 @@ const ActivityIndexHelp = () => {
|
|||
}, {
|
||||
name: t('html.label.help.testResult'),
|
||||
type: 'scatter',
|
||||
data: [{x: inverseIndex(result), y: result, marker: {radius: 10}}],
|
||||
data: [{x: inverse, y: result, marker: {radius: 10}}],
|
||||
pointPlacement: 0,
|
||||
width: 5,
|
||||
tooltip: tooltip.twoDecimals,
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
import React, {useCallback, useEffect, useMemo, useState} from 'react';
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {faChartArea, faGears} from "@fortawesome/free-solid-svg-icons";
|
||||
import CardTabs from "../../CardTabs"
|
||||
import {BasicDropdown} from "../../input/BasicDropdown";
|
||||
import RangeSlider from "react-bootstrap-range-slider";
|
||||
import {tooltip} from "../../../util/graphs";
|
||||
import {hsvToRgb, randomHSVColor, rgbToHexString} from "../../../util/colors";
|
||||
import FunctionPlotGraph from "../../graphs/FunctionPlotGraph";
|
||||
import LineGraph from "../../graphs/LineGraph";
|
||||
|
||||
const PlayerRetentionGraphHelp = () => {
|
||||
const {t} = useTranslation();
|
||||
|
||||
const [selectedAxis, setSelectedAxis] = useState('time');
|
||||
const axisOptions = useMemo(() => [
|
||||
{name: 'time', displayName: t('html.label.retention.timeSinceRegistered')},
|
||||
{name: 'playtime', displayName: t('html.label.playtime')},
|
||||
{name: 'date', displayName: t('html.label.time.date')},
|
||||
{name: 'deltas', displayName: t('html.label.time.date') + ' > ' + t('html.label.registered')},
|
||||
], [t]);
|
||||
|
||||
const [x, setX] = useState(0);
|
||||
const updateX = useCallback(event => setX(event.target.value), [setX]);
|
||||
useEffect(() => {
|
||||
setX(0);
|
||||
}, [selectedAxis, setX]);
|
||||
|
||||
const data = useMemo(() => [
|
||||
{x: 1},
|
||||
{x: 2},
|
||||
{x: 9},
|
||||
{x: 24},
|
||||
], []);
|
||||
const [series, setSeries] = useState([]);
|
||||
const [graphOptions, setGraphOptions] = useState({title: {text: ''},});
|
||||
useEffect(() => {
|
||||
const d = []
|
||||
for (let i = 0; i < x; i++) {
|
||||
d.push([i, data.filter(item => item.x > i).length * 100.0 / data.length]);
|
||||
}
|
||||
for (let i = x; i < 30; i++) {
|
||||
d.push([i, null]);
|
||||
}
|
||||
const color = rgbToHexString(hsvToRgb(randomHSVColor(1)));
|
||||
setSeries([{
|
||||
name: 'name',
|
||||
type: 'spline',
|
||||
tooltip: tooltip.twoDecimals,
|
||||
data: d,
|
||||
color
|
||||
}]);
|
||||
}, [x, data, setSeries]);
|
||||
useEffect(() => {
|
||||
const unitLabel = t('html.label.retention.retainedPlayersPercentage');
|
||||
const windowName = t('html.label.time.hours');
|
||||
const axisName = axisOptions.find(option => option.name === selectedAxis).displayName;
|
||||
setGraphOptions({
|
||||
title: {text: ''},
|
||||
rangeSelector: selectedAxis === 'date' ? {
|
||||
selected: 2,
|
||||
buttons: [{
|
||||
type: 'day',
|
||||
count: 7,
|
||||
text: '7d'
|
||||
}, {
|
||||
type: 'month',
|
||||
count: 1,
|
||||
text: '30d'
|
||||
}, {
|
||||
type: 'all',
|
||||
text: 'All'
|
||||
}]
|
||||
} : undefined,
|
||||
legend: {
|
||||
enabled: false,
|
||||
},
|
||||
plotOptions: {
|
||||
series: {animation: false}
|
||||
},
|
||||
xAxis: {
|
||||
zoomEnabled: true,
|
||||
title: {
|
||||
text: selectedAxis === 'date' || selectedAxis === 'deltas' ? t('html.label.time.date') : axisName + ' (' + windowName + ')'
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
zoomEnabled: true,
|
||||
title: {text: unitLabel},
|
||||
max: 100,
|
||||
min: 0
|
||||
},
|
||||
tooltip: selectedAxis === 'date' || selectedAxis === 'deltas' ? {
|
||||
enabled: true,
|
||||
valueDecimals: 2,
|
||||
pointFormat: '<b>{point.y} %</b>'
|
||||
} : {
|
||||
enabled: true,
|
||||
valueDecimals: 2,
|
||||
headerFormat: '{point.x} ' + windowName + '<br>',
|
||||
pointFormat: '<b>{point.y} %</b>'
|
||||
},
|
||||
series: series
|
||||
})
|
||||
}, [t, series, axisOptions, selectedAxis]);
|
||||
|
||||
|
||||
const disabledColor = 'rgba(0, 0, 0, 0.05)';
|
||||
return (
|
||||
<>
|
||||
<CardTabs tabs={[
|
||||
{
|
||||
name: t('html.label.help.usingTheGraph'), icon: faGears, color: 'indigo', href: 'data-explanation',
|
||||
element: <div className={'mt-2'}>
|
||||
<p>{t('html.label.help.retention.options')}</p>
|
||||
<h4>{t('html.label.help.tips')}</h4>
|
||||
<ul>
|
||||
<li>{t('html.label.help.retention.compareMonths')
|
||||
.replace('<0>', t('html.label.retention.groupByTime'))
|
||||
.replace('<1>', t('html.label.time.month'))}
|
||||
</li>
|
||||
<li>{t('html.label.help.retention.compareJoinAddress')}</li>
|
||||
<li>{t('html.label.help.graph.zoom')}</li>
|
||||
<li>{t('html.label.help.graph.labels')}</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
<h3>{t('html.label.help.retention.howIsItCalculated')}</h3>
|
||||
<p>{t('html.label.help.retention.howIsItCalculatedData')}</p>
|
||||
<pre>
|
||||
{'{\n playerUUID,\n registerDate,\n lastSeenDate,\n timeDifference = lastSeenDate - registerDate,\n playtime\n joinAddress\n}'}
|
||||
</pre>
|
||||
<ol>
|
||||
<li>{t('html.label.help.retention.calculationStep1')
|
||||
.replace('<>', t('html.label.retention.timeSinceRegistered'))}
|
||||
</li>
|
||||
<li>{t('html.label.help.retention.calculationStep2')
|
||||
.replace('<0>', t('html.label.retention.groupByTime'))
|
||||
.replace('<1>', t('html.label.time.month'))}
|
||||
</li>
|
||||
<li>{t('html.label.help.retention.calculationStep3')
|
||||
.replace('<0>', t('html.label.xAxis'))
|
||||
.replace('<1>', t('html.label.yAxis'))}
|
||||
</li>
|
||||
<li>{t('html.label.help.retention.calculationStep4')
|
||||
.replace('<>', t('html.label.retention.timeStep'))}
|
||||
</li>
|
||||
<li>
|
||||
<p className={'m-0'}>{t('html.label.help.retention.calculationStep5')}
|
||||
{t('html.label.help.retention.calculationStep6')}</p>
|
||||
<label>{t('html.label.xAxis')}</label>
|
||||
<BasicDropdown selected={selectedAxis} options={axisOptions}
|
||||
onChange={setSelectedAxis}/>
|
||||
<div className={'mt-2'}>
|
||||
<p>
|
||||
{selectedAxis === 'time' && <>
|
||||
{t('html.label.help.retention.calculationStepTime')}
|
||||
</>}
|
||||
{selectedAxis === 'playtime' && <>
|
||||
{t('html.label.help.retention.calculationStepPlaytime')}
|
||||
</>}
|
||||
{selectedAxis === 'date' && <>
|
||||
{t('html.label.help.retention.calculationStepDate')}
|
||||
</>}
|
||||
{selectedAxis === 'deltas' && <>
|
||||
{t('html.label.help.retention.calculationStepDeltas')}
|
||||
</>}</p>
|
||||
{selectedAxis !== 'date' && selectedAxis !== 'deltas' && <>
|
||||
<h4>{t('html.label.help.testPrompt')}</h4>
|
||||
<table className={"table"}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{t('html.label.player')}</th>
|
||||
<th>{axisOptions.find(option => option.name === selectedAxis).displayName}</th>
|
||||
<th>{t('html.label.playerRetention')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr style={x <= 24 ? {} : {backgroundColor: disabledColor}}>
|
||||
<td>Pooh</td>
|
||||
<td>1d 53s</td>
|
||||
<th>{x <= 24 ? t('plugin.generic.yes') : t('plugin.generic.no')}</th>
|
||||
</tr>
|
||||
<tr style={x <= 9 ? {} : {backgroundColor: disabledColor}}>
|
||||
<td>Piglet</td>
|
||||
<td>9h 12min</td>
|
||||
<th>{x <= 9 ? t('plugin.generic.yes') : t('plugin.generic.no')}</th>
|
||||
</tr>
|
||||
<tr style={x <= 2 ? {} : {backgroundColor: disabledColor}}>
|
||||
<td>Rabbit</td>
|
||||
<td>2h</td>
|
||||
<th>{x <= 2 ? t('plugin.generic.yes') : t('plugin.generic.no')}</th>
|
||||
</tr>
|
||||
<tr style={x <= 1 ? {} : {backgroundColor: disabledColor}}>
|
||||
<td>Tigger</td>
|
||||
<td>1h 59min 59s</td>
|
||||
<th>{x <= 1 ? t('plugin.generic.yes') : t('plugin.generic.no')}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>Retention</th>
|
||||
<th></th>
|
||||
{x <= 1 && <td>100%</td>}
|
||||
{1 < x && x <= 2 && <td>75%</td>}
|
||||
{2 < x && x <= 9 && <td>50%</td>}
|
||||
{9 < x && x <= 24 && <td>25%</td>}
|
||||
{x > 24 && <td>0%</td>}
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<label>x = {x} {t('html.label.time.hours')}</label>
|
||||
<RangeSlider
|
||||
value={x}
|
||||
onChange={updateX}
|
||||
min={0}
|
||||
max={25}
|
||||
tooltip={'off'}/>
|
||||
{(selectedAxis !== 'date' && selectedAxis !== 'deltas') &&
|
||||
<FunctionPlotGraph id={'retention-help-graph'} options={graphOptions}/>}
|
||||
{(selectedAxis === 'date' || selectedAxis === 'deltas') &&
|
||||
<LineGraph id={'retention-help-graph'} options={graphOptions}/>}
|
||||
</>}
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
}, {
|
||||
name: t('html.label.help.examples'),
|
||||
icon: faChartArea,
|
||||
color: 'indigo',
|
||||
href: 'interesting-combinations',
|
||||
element: <div className={'mt-2'}>
|
||||
<label>{t('html.label.retention.timeSinceRegistered')}</label>
|
||||
<img className={'w-100'} alt={t('html.label.help.graph.title')} loading={'lazy'}
|
||||
src={'https://raw.githubusercontent.com/plan-player-analytics/drawio-diagrams-storage/master/image/screenshot/225086629-69e70c66-69d5-4a08-afbc-c63b218ec9bc.png'}/>
|
||||
<hr/>
|
||||
<label>{t('html.label.help.retention.examples.playtime')}</label>
|
||||
<img className={'w-100'} alt={t('html.label.help.graph.title')} loading={'lazy'}
|
||||
src={'https://raw.githubusercontent.com/plan-player-analytics/drawio-diagrams-storage/master/image/screenshot/225086773-ae5646e5-0d9e-4016-9f1d-c392d3d25c07.png'}/>
|
||||
<hr/>
|
||||
<label>{t('html.label.time.date')}</label>
|
||||
<img className={'w-100'} alt={t('html.label.help.graph.title')} loading={'lazy'}
|
||||
src={'https://raw.githubusercontent.com/plan-player-analytics/drawio-diagrams-storage/master/image/screenshot/225086880-c6e88e9a-125d-4513-b86a-ca61b4d752b2.png'}/>
|
||||
<hr/>
|
||||
<label>{t('html.label.help.retention.examples.deltas')
|
||||
.replace('<>', t('html.label.time.date') + ' > ' + t('html.label.registered'))}</label>
|
||||
<img className={'w-100'} alt={t('html.label.help.graph.title')} loading={'lazy'}
|
||||
src={'https://raw.githubusercontent.com/plan-player-analytics/drawio-diagrams-storage/master/image/screenshot/225087066-0cacc7e4-aacc-48ff-97d7-ba2cf6a368ff.png'}/>
|
||||
<hr/>
|
||||
<label>{t('html.label.help.retention.examples.pattern')}</label>
|
||||
<img className={'w-100'} alt={t('html.label.help.graph.title')} loading={'lazy'}
|
||||
src={'https://raw.githubusercontent.com/plan-player-analytics/drawio-diagrams-storage/master/image/screenshot/225087273-04331324-6bc3-4efb-8864-166b5b3d4a89.png'}/>
|
||||
<hr/>
|
||||
<label>{t('html.label.help.retention.examples.plateau')}</label>
|
||||
<img className={'w-100'} alt={t('html.label.help.graph.title')} loading={'lazy'}
|
||||
src={'https://raw.githubusercontent.com/plan-player-analytics/drawio-diagrams-storage/master/image/screenshot/225087828-8db2da1a-578d-43fc-abc5-2aa09e97935e.png'}/>
|
||||
<hr/>
|
||||
<label>{t('html.label.help.retention.examples.adCampaign')}</label>
|
||||
<img className={'w-100'} alt={t('html.label.help.graph.title')} loading={'lazy'}
|
||||
src={'https://raw.githubusercontent.com/plan-player-analytics/drawio-diagrams-storage/master/image/screenshot/225088901-2e30caf6-f141-4998-91de-2034fda5b7e9.png'}/>
|
||||
<hr/>
|
||||
<label>{t('html.label.help.retention.examples.stack')}</label>
|
||||
<img className={'w-100'} alt={t('html.label.help.graph.title')} loading={'lazy'}
|
||||
src={'https://raw.githubusercontent.com/plan-player-analytics/drawio-diagrams-storage/master/image/screenshot/225722723-cde69a1a-09fd-4e19-a8fe-993d60435652.png'}/>
|
||||
</div>
|
||||
}
|
||||
]}/>
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
export default PlayerRetentionGraphHelp
|
|
@ -268,3 +268,43 @@ const fetchJoinAddressByDayNetwork = async (timestamp) => {
|
|||
if (staticSite) url = `/data/graph-joinAddressByDay.json`;
|
||||
return doGetRequest(url, timestamp);
|
||||
}
|
||||
|
||||
export const fetchRetentionData = async (timestamp, identifier) => {
|
||||
if (identifier) {
|
||||
return await fetchServerRetentionData(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchNetworkRetentionData(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchServerRetentionData = async (timestamp, identifier) => {
|
||||
let url = `/v1/retention?server=${identifier}`;
|
||||
if (staticSite) url = `/data/retention-${identifier}.json`;
|
||||
return doGetRequest(url, timestamp);
|
||||
}
|
||||
|
||||
const fetchNetworkRetentionData = async (timestamp) => {
|
||||
let url = `/v1/retention`;
|
||||
if (staticSite) url = `/data/retention.json`;
|
||||
return doGetRequest(url, timestamp);
|
||||
}
|
||||
|
||||
export const fetchPlayerJoinAddresses = async (timestamp, identifier) => {
|
||||
if (identifier) {
|
||||
return await fetchServerPlayerJoinAddresses(timestamp, identifier);
|
||||
} else {
|
||||
return await fetchNetworkPlayerJoinAddresses(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchServerPlayerJoinAddresses = async (timestamp, identifier) => {
|
||||
let url = `/v1/joinAddresses?server=${identifier}`;
|
||||
if (staticSite) url = `/data/joinAddresses-${identifier}.json`;
|
||||
return doGetRequest(url, timestamp);
|
||||
}
|
||||
|
||||
const fetchNetworkPlayerJoinAddresses = async (timestamp) => {
|
||||
let url = `/v1/joinAddresses`;
|
||||
if (staticSite) url = `/data/joinAddresses.json`;
|
||||
return doGetRequest(url, timestamp);
|
||||
}
|
|
@ -37,6 +37,7 @@
|
|||
--color-night-text-dark-bg: #eee8d5;
|
||||
|
||||
--color-theme: var(--color-plan);
|
||||
--color-night: var(--color-night-dark-blue);
|
||||
}
|
||||
|
||||
a {
|
||||
|
|
|
@ -123,6 +123,69 @@ export const colorClassToBgClass = colorClass => {
|
|||
return "bg-" + colorClassToColorName(colorClass);
|
||||
}
|
||||
|
||||
export const hsvToRgb = ([h, s, v]) => {
|
||||
let r, g, b;
|
||||
|
||||
const i = Math.floor(h * 6);
|
||||
const f = h * 6 - i;
|
||||
const p = v * (1 - s);
|
||||
const q = v * (1 - f * s);
|
||||
const t = v * (1 - (1 - f) * s);
|
||||
|
||||
switch (i % 6) {
|
||||
case 0:
|
||||
r = v;
|
||||
g = t;
|
||||
b = p;
|
||||
break;
|
||||
case 1:
|
||||
r = q;
|
||||
g = v;
|
||||
b = p;
|
||||
break;
|
||||
case 2:
|
||||
r = p;
|
||||
g = v;
|
||||
b = t;
|
||||
break;
|
||||
case 3:
|
||||
r = p;
|
||||
g = q;
|
||||
b = v;
|
||||
break;
|
||||
case 4:
|
||||
r = t;
|
||||
g = p;
|
||||
b = v;
|
||||
break;
|
||||
case 5:
|
||||
r = v;
|
||||
g = p;
|
||||
b = q;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return [r * 255, g * 255, b * 255];
|
||||
}
|
||||
|
||||
export const randomHSVColor = (i) => {
|
||||
const goldenRatioConjugate = 0.618033988749895;
|
||||
const hue = i * goldenRatioConjugate % 1;
|
||||
const saturation = 0.7;
|
||||
const value = 0.7 + (Math.random() / 10);
|
||||
return [hue, saturation, value]
|
||||
}
|
||||
|
||||
export const rgbToHexString = ([r, g, b]) => {
|
||||
return '#' + rgbToHex(r) + rgbToHex(g) + rgbToHex(b);
|
||||
}
|
||||
|
||||
const rgbToHex = (component) => {
|
||||
return Math.floor(component).toString(16).padStart(2, '0');
|
||||
}
|
||||
|
||||
// From https://stackoverflow.com/a/3732187
|
||||
export const withReducedSaturation = hex => {
|
||||
const saturationReduction = 0.70;
|
||||
|
|
|
@ -13,7 +13,8 @@ import {
|
|||
faSearch,
|
||||
faServer,
|
||||
faUserGroup,
|
||||
faUsers
|
||||
faUsers,
|
||||
faUsersViewfinder
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import {useAuth} from "../../hooks/authenticationHook";
|
||||
import Sidebar from "../../components/navigation/Sidebar";
|
||||
|
@ -77,7 +78,7 @@ const NetworkSidebar = () => {
|
|||
href: "playerbase"
|
||||
},
|
||||
{name: 'html.label.joinAddresses', icon: faLocationArrow, href: "join-addresses"},
|
||||
// {name: 'html.label.playerRetention', icon: faUsersViewfinder, href: "retention"},
|
||||
{name: 'html.label.playerRetention', icon: faUsersViewfinder, href: "retention"},
|
||||
{name: 'html.label.playerList', icon: faUserGroup, href: "players"},
|
||||
{name: 'html.label.geolocations', icon: faGlobe, href: "geolocations"},
|
||||
]
|
||||
|
@ -87,7 +88,7 @@ const NetworkSidebar = () => {
|
|||
{name: 'html.label.pluginsOverview', icon: faCubes, href: "plugins-overview"}
|
||||
]
|
||||
|
||||
if (extensionData) {
|
||||
if (extensionData?.extensions) {
|
||||
extensionData.extensions.filter(extension => extension.wide)
|
||||
.map(extension => extension.extensionInformation)
|
||||
.map(info => {
|
||||
|
|
|
@ -13,7 +13,8 @@ import {
|
|||
faLocationArrow,
|
||||
faSearch,
|
||||
faUserGroup,
|
||||
faUsers
|
||||
faUsers,
|
||||
faUsersViewfinder
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import {useAuth} from "../../hooks/authenticationHook";
|
||||
import Sidebar from "../../components/navigation/Sidebar";
|
||||
|
@ -67,7 +68,7 @@ const ServerSidebar = () => {
|
|||
href: "playerbase"
|
||||
},
|
||||
{name: 'html.label.joinAddresses', icon: faLocationArrow, href: "join-addresses"},
|
||||
// {name: 'html.label.playerRetention', icon: faUsersViewfinder, href: "retention"},
|
||||
{name: 'html.label.playerRetention', icon: faUsersViewfinder, href: "retention"},
|
||||
{name: 'html.label.playerList', icon: faUserGroup, href: "players"},
|
||||
{name: 'html.label.geolocations', icon: faGlobe, href: "geolocations"},
|
||||
]
|
||||
|
@ -78,7 +79,7 @@ const ServerSidebar = () => {
|
|||
{name: 'html.label.pluginsOverview', icon: faCubes, href: "plugins-overview"}
|
||||
]
|
||||
|
||||
if (extensionData) {
|
||||
if (extensionData?.extensions) {
|
||||
extensionData.extensions.filter(extension => extension.wide)
|
||||
.map(extension => extension.extensionInformation)
|
||||
.map(info => {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import React from 'react';
|
||||
import ExtendableRow from "../../components/layout/extension/ExtendableRow";
|
||||
import {Col} from "react-bootstrap";
|
||||
import LoadIn from "../../components/animation/LoadIn";
|
||||
import PlayerRetentionGraphCard from "../../components/cards/common/PlayerRetentionGraphCard";
|
||||
|
||||
const NetworkPlayerRetention = () => {
|
||||
return (
|
||||
<LoadIn>
|
||||
<section className="network-retention">
|
||||
<ExtendableRow id={'row-network-retention-0'}>
|
||||
<Col lg={12}>
|
||||
<PlayerRetentionGraphCard identifier={null}/>
|
||||
</Col>
|
||||
</ExtendableRow>
|
||||
</section>
|
||||
</LoadIn>
|
||||
)
|
||||
};
|
||||
|
||||
export default NetworkPlayerRetention
|
|
@ -10,7 +10,7 @@ const PlayerPluginData = () => {
|
|||
const {player} = usePlayer();
|
||||
const {serverName} = useParams();
|
||||
|
||||
const extensions = player.extensions.find(extension => extension.serverName === serverName)
|
||||
const extensions = player.extensions ? player.extensions.find(extension => extension.serverName === serverName) : {};
|
||||
|
||||
useEffect(() => {
|
||||
const masonryRow = document.getElementById('extension-masonry-row');
|
||||
|
@ -48,7 +48,7 @@ const PlayerPluginData = () => {
|
|||
<Row id="extension-masonry-row"
|
||||
data-masonry='{"percentPosition": true, "itemSelector": ".extension-wrapper"}'
|
||||
style={{overflowY: 'hidden'}}>
|
||||
{extensions.extensionData.map((extension, i) =>
|
||||
{extensions?.extensionData?.map((extension, i) =>
|
||||
<ExtensionCardWrapper key={'ext-' + i} extension={extension}>
|
||||
<ExtensionCard extension={extension}/>
|
||||
</ExtensionCardWrapper>
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import ExtendableRow from "../../components/layout/extension/ExtendableRow";
|
||||
import {Col} from "react-bootstrap";
|
||||
import LoadIn from "../../components/animation/LoadIn";
|
||||
import PlayerRetentionGraphCard from "../../components/cards/common/PlayerRetentionGraphCard";
|
||||
import {useParams} from "react-router-dom";
|
||||
|
||||
const ServerPlayerRetention = () => {
|
||||
const {identifier} = useParams();
|
||||
return (
|
||||
<LoadIn>
|
||||
<section className="server-retention">
|
||||
<ExtendableRow id={'row-server-retention-0'}>
|
||||
<Col lg={12}>
|
||||
<PlayerRetentionGraphCard identifier={identifier}/>
|
||||
</Col>
|
||||
</ExtendableRow>
|
||||
</section>
|
||||
</LoadIn>
|
||||
)
|
||||
};
|
||||
|
||||
export default ServerPlayerRetention
|
|
@ -11,7 +11,7 @@ import ErrorView from "../ErrorView";
|
|||
const ServerPluginData = () => {
|
||||
const {t} = useTranslation();
|
||||
const {extensionData, extensionDataLoadingError} = useServerExtensionContext();
|
||||
const extensions = useMemo(() => extensionData ? extensionData.extensions.filter(extension => !extension.wide) : [], [extensionData]);
|
||||
const extensions = useMemo(() => extensionData?.extensions ? extensionData.extensions.filter(extension => !extension.wide) : [], [extensionData]);
|
||||
|
||||
useEffect(() => {
|
||||
const masonryRow = document.getElementById('extension-masonry-row');
|
||||
|
|
|
@ -1022,13 +1022,20 @@
|
|||
core-js-pure "^3.25.1"
|
||||
regenerator-runtime "^0.13.11"
|
||||
|
||||
"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.19.4", "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||
"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.19.4", "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||
version "7.20.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b"
|
||||
integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.11"
|
||||
|
||||
"@babel/runtime@^7.12.1":
|
||||
version "7.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
|
||||
integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.11"
|
||||
|
||||
"@babel/template@^7.16.7", "@babel/template@^7.3.3":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
|
||||
|
@ -2216,7 +2223,7 @@
|
|||
dependencies:
|
||||
"@types/unist" "*"
|
||||
|
||||
"@types/hoist-non-react-statics@^3.3.0":
|
||||
"@types/hoist-non-react-statics@^3.3.1":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
||||
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
|
||||
|
@ -2327,16 +2334,6 @@
|
|||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-redux@^7.1.20":
|
||||
version "7.1.24"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.24.tgz#6caaff1603aba17b27d20f8ad073e4c077e975c0"
|
||||
integrity sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==
|
||||
dependencies:
|
||||
"@types/hoist-non-react-statics" "^3.3.0"
|
||||
"@types/react" "*"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
redux "^4.0.0"
|
||||
|
||||
"@types/react-transition-group@^4.4.4":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.5.tgz#aae20dcf773c5aa275d5b9f7cdbca638abc5e416"
|
||||
|
@ -2414,6 +2411,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
|
||||
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
|
||||
|
||||
"@types/use-sync-external-store@^0.0.3":
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
|
||||
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
|
||||
|
||||
"@types/warning@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52"
|
||||
|
@ -2711,11 +2713,16 @@ acorn@^7.0.0, acorn@^7.1.1:
|
|||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
|
||||
acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.0:
|
||||
acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.0:
|
||||
version "8.7.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30"
|
||||
integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==
|
||||
|
||||
acorn@^8.7.1:
|
||||
version "8.8.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
|
||||
integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
|
||||
|
||||
address@^1.0.1, address@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
|
||||
|
@ -3943,18 +3950,18 @@ data-urls@^2.0.0:
|
|||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^8.0.0"
|
||||
|
||||
datatables.net-bs5@>=1.12.1, datatables.net-bs5@^1.13.3:
|
||||
version "1.13.3"
|
||||
resolved "https://registry.yarnpkg.com/datatables.net-bs5/-/datatables.net-bs5-1.13.3.tgz#5b5a51fe48f26f5b8e37f28c8b2aee485291c3ac"
|
||||
integrity sha512-yaZ89SjP1INIotvCVaBkgQ0VPvWTAfywG3dmBaVIosa4u0vUAqlx1+aYyL8WXgqmklSQda3nXdNwJu0OrPw84A==
|
||||
datatables.net-bs5@>=1.12.1, datatables.net-bs5@^1.13.4:
|
||||
version "1.13.4"
|
||||
resolved "https://registry.yarnpkg.com/datatables.net-bs5/-/datatables.net-bs5-1.13.4.tgz#c73058782484cb84d9bc3ae9b8c0f1950b78bf2b"
|
||||
integrity sha512-+gtaiau4vJeuGvnsYWmQy9gqa5XQ15XmkdwpK5EjwYCMzZZEXMQ3wfu2FddBcX5tX9Ual8C+Tf1s2gmqLGNbKQ==
|
||||
dependencies:
|
||||
datatables.net ">=1.12.1"
|
||||
jquery ">=1.7"
|
||||
|
||||
datatables.net-responsive-bs5@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/datatables.net-responsive-bs5/-/datatables.net-responsive-bs5-2.4.0.tgz#ab3a6fb147e5886ae043c9ecd54652f3a5d6d5c0"
|
||||
integrity sha512-2kxigvftgVgdyH+BZ17jbR+BcWYZsacnlTt4PeOH/P98bMuqJKrziss7CLz/6qud/ehHdLEQTjMDoJddN9NfxA==
|
||||
datatables.net-responsive-bs5@^2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/datatables.net-responsive-bs5/-/datatables.net-responsive-bs5-2.4.1.tgz#8342ea3d97f49b2d4ce3af9742367d2feef31000"
|
||||
integrity sha512-gtW0IjNMWCWQ+KHpIPcgXiQrq2Dhxz8yKql4sS2WfuYz+Z7645mk7xmqEhy4aqpWEGXdv4rcaZhr4tt49NLOpQ==
|
||||
dependencies:
|
||||
datatables.net-bs5 ">=1.12.1"
|
||||
datatables.net-responsive ">=2.3.0"
|
||||
|
@ -3968,10 +3975,10 @@ datatables.net-responsive@>=2.3.0:
|
|||
datatables.net ">=1.12.1"
|
||||
jquery ">=1.7"
|
||||
|
||||
datatables.net@>=1.12.1, datatables.net@^1.13.3:
|
||||
version "1.13.3"
|
||||
resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-1.13.3.tgz#ee7d7b16b479b5075412b104d980184693b4325b"
|
||||
integrity sha512-YVnz02oJsaP/OfnclBlqHkuV1il60sSVa+a0Xvs5gyiDLftmAxc+rvVAwCm7O0OpKo09N43k6EcCAf3L9WYI7g==
|
||||
datatables.net@>=1.12.1, datatables.net@^1.13.4:
|
||||
version "1.13.4"
|
||||
resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-1.13.4.tgz#9a809cee82eca0a884e10b4d47a3a3d6e65e9fe7"
|
||||
integrity sha512-yzhArTOB6tPO2QFKm1z3hA4vabtt2hRvgw8XLsT1xqEirinfGYqWDiWXlkTPTaJv2e7gG+Kf985sXkzBFlGrGQ==
|
||||
dependencies:
|
||||
jquery ">=1.7"
|
||||
|
||||
|
@ -4333,10 +4340,10 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1:
|
|||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
enhanced-resolve@^5.9.2:
|
||||
version "5.9.3"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88"
|
||||
integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==
|
||||
enhanced-resolve@^5.10.0:
|
||||
version "5.12.0"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634"
|
||||
integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.4"
|
||||
tapable "^2.2.0"
|
||||
|
@ -5494,10 +5501,10 @@ i18next-chained-backend@^4.2.0:
|
|||
dependencies:
|
||||
"@babel/runtime" "^7.19.4"
|
||||
|
||||
i18next-http-backend@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/i18next-http-backend/-/i18next-http-backend-2.1.1.tgz#72a21d61c2e96eea9ad45ba1b9dd0090e119709a"
|
||||
integrity sha512-jByfUCDVgQ8+/Wens7queQhYYvMcGTW/lR4IJJNEDDXnmqjLrwi8ubXKpmp76/JIWEZHffNdWqnxFJcTVGeaOw==
|
||||
i18next-http-backend@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/i18next-http-backend/-/i18next-http-backend-2.2.0.tgz#f77c06dc8e766c7588bb38da2f5fa0614ba67b3f"
|
||||
integrity sha512-Z4sM7R6tzdLknSPER9GisEBxKPg5FkI07UrQniuroZmS15PHQrcCPLyuGKj8SS68tf+O2aEDYSUnmy1TZqZSbw==
|
||||
dependencies:
|
||||
cross-fetch "3.1.5"
|
||||
|
||||
|
@ -5508,10 +5515,10 @@ i18next-localstorage-backend@^4.1.0:
|
|||
dependencies:
|
||||
"@babel/runtime" "^7.20.6"
|
||||
|
||||
i18next@^22.4.10:
|
||||
version "22.4.10"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-22.4.10.tgz#cfbfc412c6bc83e3c16564f47e6a5c145255960e"
|
||||
integrity sha512-3EqgGK6fAJRjnGgfkNSStl4mYLCjUoJID338yVyLMj5APT67HUtWoqSayZewiiC5elzMUB1VEUwcmSCoeQcNEA==
|
||||
i18next@^22.4.11:
|
||||
version "22.4.11"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-22.4.11.tgz#8b6c9be95176de90d3f10a78af125d95d3a3258d"
|
||||
integrity sha512-ShfTzXVMjXdF2iPiT/wbizOrssLh9Ab6VpuVROihLCAu+u25KbZiEYVgsA0W6g0SgjPa/JmGWcUEV/g6cKzEjQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.20.6"
|
||||
|
||||
|
@ -6423,12 +6430,7 @@ jsesc@~0.5.0:
|
|||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
|
||||
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
|
||||
|
||||
json-parse-better-errors@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
|
||||
integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
|
||||
|
||||
json-parse-even-better-errors@^2.3.0:
|
||||
json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
|
||||
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
|
||||
|
@ -8305,11 +8307,16 @@ react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0:
|
|||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
||||
react-is@^17.0.1, react-is@^17.0.2:
|
||||
react-is@^17.0.1:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||
|
||||
react-is@^18.0.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||
|
||||
react-lifecycles-compat@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
|
@ -8320,17 +8327,17 @@ react-mcjsonchat@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/react-mcjsonchat/-/react-mcjsonchat-1.0.0.tgz#6a0c748b074c06a2d64a66db76e5fb2036c48a9a"
|
||||
integrity sha512-H/OYi1iRYFG2Bntj1EYWfTxOaWtIopHy6ILoaXtD3OFONK7kQnp0lXFf6sw1G3BU0DL7s8NL4+AmMCer/A5eIQ==
|
||||
|
||||
react-redux@^7.2.4:
|
||||
version "7.2.8"
|
||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.8.tgz#a894068315e65de5b1b68899f9c6ee0923dd28de"
|
||||
integrity sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==
|
||||
react-redux@^8.0.5:
|
||||
version "8.0.5"
|
||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.5.tgz#e5fb8331993a019b8aaf2e167a93d10af469c7bd"
|
||||
integrity sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.15.4"
|
||||
"@types/react-redux" "^7.1.20"
|
||||
"@babel/runtime" "^7.12.1"
|
||||
"@types/hoist-non-react-statics" "^3.3.1"
|
||||
"@types/use-sync-external-store" "^0.0.3"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.7.2"
|
||||
react-is "^17.0.2"
|
||||
react-is "^18.0.0"
|
||||
use-sync-external-store "^1.0.0"
|
||||
|
||||
react-refresh@^0.11.0:
|
||||
version "0.11.0"
|
||||
|
@ -8514,7 +8521,7 @@ redux-immutable@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/redux-immutable/-/redux-immutable-4.0.0.tgz#3a1a32df66366462b63691f0e1dc35e472bbc9f3"
|
||||
integrity sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==
|
||||
|
||||
redux@^4.0.0, redux@^4.1.2:
|
||||
redux@^4.1.2:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13"
|
||||
integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==
|
||||
|
@ -8789,10 +8796,10 @@ sass-loader@^12.3.0:
|
|||
klona "^2.0.4"
|
||||
neo-async "^2.6.2"
|
||||
|
||||
sass@^1.58.3:
|
||||
version "1.58.3"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.58.3.tgz#2348cc052061ba4f00243a208b09c40e031f270d"
|
||||
integrity sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==
|
||||
sass@^1.59.3:
|
||||
version "1.59.3"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.59.3.tgz#a1ddf855d75c70c26b4555df4403e1bbf8e4403f"
|
||||
integrity sha512-QCq98N3hX1jfTCoUAsF3eyGuXLsY7BCnCEg9qAact94Yc21npG2/mVOqoDvE0fCbWDqiM4WlcJQla0gWG2YlxQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
|
@ -9439,10 +9446,10 @@ svgo@^2.7.0:
|
|||
picocolors "^1.0.0"
|
||||
stable "^0.1.8"
|
||||
|
||||
swagger-client@=3.19.0-beta.8:
|
||||
version "3.19.0-beta.8"
|
||||
resolved "https://registry.yarnpkg.com/swagger-client/-/swagger-client-3.19.0-beta.8.tgz#86639e3d8704a305ab66109bfacae29c6bdbe411"
|
||||
integrity sha512-idGYcLsr5p3yLRPSRsLRpjWKM8exb5lb28f9xjwZpBUGWo5rgQydWLcPRPTdwxxr5lMvuWXFIKowJ69EvpfUsw==
|
||||
swagger-client@^3.19.1:
|
||||
version "3.19.2"
|
||||
resolved "https://registry.yarnpkg.com/swagger-client/-/swagger-client-3.19.2.tgz#7fabea7d953c19532670f3ee983a61addb134304"
|
||||
integrity sha512-oBR6VtD99yJOY8W3vf1h8zU91H5UpwUk2trSL4xzZIzChWtlaOMyWh+/GyUGgDCmQY4B1E4qTgAD/kFQ4dFnnA==
|
||||
dependencies:
|
||||
"@babel/runtime-corejs3" "^7.20.13"
|
||||
"@swagger-api/apidom-core" "=0.69.0"
|
||||
|
@ -9462,10 +9469,10 @@ swagger-client@=3.19.0-beta.8:
|
|||
traverse "~0.6.6"
|
||||
url "~0.11.0"
|
||||
|
||||
swagger-ui@^4.17.0:
|
||||
version "4.17.0"
|
||||
resolved "https://registry.yarnpkg.com/swagger-ui/-/swagger-ui-4.17.0.tgz#9889f6b44acf60ba1d1ecb455e72ab3f3ce09be5"
|
||||
integrity sha512-gs7c2YTuz6nDgwb2OQWKzgKiNhx7Z1TTCNniuLTgYbrIFrc3Ec652ACAom+XY9O5eq1nN/Xy+/mVOTv9I7tuMw==
|
||||
swagger-ui@^4.18.1:
|
||||
version "4.18.1"
|
||||
resolved "https://registry.yarnpkg.com/swagger-ui/-/swagger-ui-4.18.1.tgz#14b90dba50cb827e57747458ef455f99a677535b"
|
||||
integrity sha512-KMG/Mg+b7oPtBOlpx9abbmU6Rm86kiVUvvpR3EkplBz0CSnseuQZN2XdDZKD7QsvM78NkUhn53y5EZCb+4rd1g==
|
||||
dependencies:
|
||||
"@babel/runtime-corejs3" "^7.18.9"
|
||||
"@braintree/sanitize-url" "=6.0.2"
|
||||
|
@ -9490,7 +9497,7 @@ swagger-ui@^4.17.0:
|
|||
react-immutable-proptypes "2.2.0"
|
||||
react-immutable-pure-component "^2.2.0"
|
||||
react-inspector "^6.0.1"
|
||||
react-redux "^7.2.4"
|
||||
react-redux "^8.0.5"
|
||||
react-syntax-highlighter "^15.5.0"
|
||||
redux "^4.1.2"
|
||||
redux-immutable "^4.0.0"
|
||||
|
@ -9498,7 +9505,7 @@ swagger-ui@^4.17.0:
|
|||
reselect "^4.1.5"
|
||||
serialize-error "^8.1.0"
|
||||
sha.js "^2.4.11"
|
||||
swagger-client "=3.19.0-beta.8"
|
||||
swagger-client "^3.19.1"
|
||||
url-parse "^1.5.8"
|
||||
xml "=1.0.1"
|
||||
xml-but-prettier "^1.0.1"
|
||||
|
@ -9933,6 +9940,11 @@ url@~0.11.0:
|
|||
punycode "1.3.2"
|
||||
querystring "0.2.0"
|
||||
|
||||
use-sync-external-store@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
|
||||
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
|
||||
|
||||
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
@ -10015,10 +10027,10 @@ warning@^4.0.0, warning@^4.0.3:
|
|||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
watchpack@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25"
|
||||
integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==
|
||||
watchpack@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"
|
||||
integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==
|
||||
dependencies:
|
||||
glob-to-regexp "^0.4.1"
|
||||
graceful-fs "^4.1.2"
|
||||
|
@ -10141,33 +10153,33 @@ webpack-sources@^3.2.3:
|
|||
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
|
||||
|
||||
webpack@^5.64.4:
|
||||
version "5.72.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.72.0.tgz#f8bc40d9c6bb489a4b7a8a685101d6022b8b6e28"
|
||||
integrity sha512-qmSmbspI0Qo5ld49htys8GY9XhS9CGqFoHTsOVAnjBdg0Zn79y135R+k4IR4rKK6+eKaabMhJwiVB7xw0SJu5w==
|
||||
version "5.76.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.1.tgz#7773de017e988bccb0f13c7d75ec245f377d295c"
|
||||
integrity sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==
|
||||
dependencies:
|
||||
"@types/eslint-scope" "^3.7.3"
|
||||
"@types/estree" "^0.0.51"
|
||||
"@webassemblyjs/ast" "1.11.1"
|
||||
"@webassemblyjs/wasm-edit" "1.11.1"
|
||||
"@webassemblyjs/wasm-parser" "1.11.1"
|
||||
acorn "^8.4.1"
|
||||
acorn "^8.7.1"
|
||||
acorn-import-assertions "^1.7.6"
|
||||
browserslist "^4.14.5"
|
||||
chrome-trace-event "^1.0.2"
|
||||
enhanced-resolve "^5.9.2"
|
||||
enhanced-resolve "^5.10.0"
|
||||
es-module-lexer "^0.9.0"
|
||||
eslint-scope "5.1.1"
|
||||
events "^3.2.0"
|
||||
glob-to-regexp "^0.4.1"
|
||||
graceful-fs "^4.2.9"
|
||||
json-parse-better-errors "^1.0.2"
|
||||
json-parse-even-better-errors "^2.3.1"
|
||||
loader-runner "^4.2.0"
|
||||
mime-types "^2.1.27"
|
||||
neo-async "^2.6.2"
|
||||
schema-utils "^3.1.0"
|
||||
tapable "^2.1.1"
|
||||
terser-webpack-plugin "^5.1.3"
|
||||
watchpack "^2.3.1"
|
||||
watchpack "^2.4.0"
|
||||
webpack-sources "^3.2.3"
|
||||
|
||||
websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
|
||||
|
|
Loading…
Reference in New Issue