doctype html html head meta(http-equiv="Content-Type" content="text/html;charset=utf-8") meta(http-equiv="Cache-Control" content="no-cache") meta(http-equiv="referrer" content="no-referrer") meta(http-equiv="viewport" content="width=device-width,initial-scale=1,user-scalable=no") title VRCXVR link(rel="dns-prefetch" href="https://fonts.gstatic.com") link(rel="preconnect" href="https://api.vrchat.cloud") link(rel="preconnect" href="https://d348imysud55la.cloudfront.net") link(rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans+JP|Noto+Sans+KR&display=swap") link(rel="stylesheet" href="vr.css") body .x-app#x-app(v-if="appType === '1'" class="x-app-type" :class="{ background: config && config.backgroundEnabled }") .x-container(style="flex:1") .x-friend-list(ref="list" style="color:#aaa") template(v-if="config && config.minimalFeed") template(v-for="feed in wristFeed") .x-friend-item(v-if="feed.type === 'GPS'" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] #[location(:location="feed.location" :hint="feed.worldName")] div(v-else-if="feed.type === 'Offline'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] ✖️ div(v-else-if="feed.type === 'Online'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] ✔ div(v-else-if="feed.type === 'Status'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] template(v-if="feed.statusDescription === feed.previousStatusDescription") i.x-user-status(:class="statusClass(feed.previousStatus)") i.el-icon-right i.x-user-status(:class="statusClass(feed.status)") template(v-else) | #[i.x-user-status(:class="statusClass(feed.status)")] {{feed.statusDescription}} div(v-else-if="feed.type === 'OnPlayerJoined'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | ▶️ #[span.name(v-text="feed.displayName")] div(v-else-if="feed.type === 'OnPlayerLeft'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | ◀️ #[span.name(v-text="feed.displayName")] div(v-else-if="feed.type === 'OnPlayerJoining'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} span.spin ▶️ span.name(v-text="feed.displayName" style="margin-left:20px") div(v-else-if="feed.type === 'Location'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} location(:location="feed.location" :hint="feed.worldName") div(v-else-if="feed.type === 'VideoPlay'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 🎵 #[span.name(v-text="feed.displayName")] template(v-if="feed.videoName") | #[span(v-text="feed.videoName")] template(v-else) | #[span(v-text="feed.videoUrl")] div(v-else-if="feed.type === 'invite'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 📨 #[span.name(v-text="feed.senderUsername")] #[location(:location="feed.details.worldId" :hint="feed.details.worldName")] #[span(v-text="feed.details.inviteMessage")] div(v-else-if="feed.type === 'requestInvite'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 📩 #[span.name(v-text="feed.senderUsername")] #[span(v-text="feed.details.requestMessage")] div(v-else-if="feed.type === 'inviteResponse'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 💬 #[span.name(v-text="feed.senderUsername")] #[span(v-text="feed.details.responseMessage")] div(v-else-if="feed.type === 'requestInviteResponse'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 💬 #[span.name(v-text="feed.senderUsername")] #[span(v-text="feed.details.responseMessage")] div(v-else-if="feed.type === 'friendRequest'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 💚 #[span.name(v-text="feed.senderUsername")] div(v-else-if="feed.type === 'Friend'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 💖 #[span.name(v-text="feed.displayName")] div(v-else-if="feed.type === 'Unfriend'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 💔 #[span.name(v-text="feed.displayName")] div(v-else-if="feed.type === 'DisplayName'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 📃 #[span.name(v-text="feed.previousDisplayName")] #[i.el-icon-right] #[span.name(v-text="feed.displayName")] div(v-else-if="feed.type === 'TrustLevel'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 🤝 #[span.name(v-text="feed.displayName")] {{ feed.previousTrustLevel }} #[i.el-icon-right] {{ feed.trustLevel }} div(v-else-if="feed.type === 'PortalSpawn'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | ✨ #[span.name(v-text="feed.displayName")] template(v-if="feed.worldName") | #[location(:location="feed.instanceId" :hint="feed.worldName")] div(v-else-if="feed.type === 'AvatarChange'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 🧍 #[span.name(v-text="feed.displayName")] {{ feed.name }} template(v-if="feed.description && feed.description !== feed.name") | - {{ feed.description }} div(v-else-if="feed.type === 'Event'" class="x-friend-item") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 🛑 #[span.name(v-text="feed.data")] div(v-else-if="feed.type === 'VideoPlay'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | 🎵 #[span.name(v-text="feed.data")] div(v-else-if="feed.type === 'BlockedOnPlayerJoined'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | ▶️ 🚫 #[span.name(v-text="feed.displayName")] div(v-else-if="feed.type === 'BlockedOnPlayerLeft'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | ◀️ 🚫 #[span.name(v-text="feed.displayName")] div(v-else-if="feed.type === 'MutedOnPlayerJoined'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | ▶️ 🔇 #[span.name(v-text="feed.displayName")] div(v-else-if="feed.type === 'MutedOnPlayerLeft'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | ◀️ 🔇 #[span.name(v-text="feed.displayName")] template(v-else) template(v-for="feed in wristFeed") .x-friend-item(v-if="feed.type === 'GPS'" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] is in #[location(:location="feed.location" :hint="feed.worldName")] div(v-else-if="feed.type === 'Offline'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] has logged out div(v-else-if="feed.type === 'Online'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] has logged in div(v-else-if="feed.type === 'Status'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] template(v-if="feed.statusDescription === feed.previousStatusDescription") i.x-user-status(:class="statusClass(feed.previousStatus)") i.el-icon-right i.x-user-status(:class="statusClass(feed.status)") template(v-else) | #[i.x-user-status(:class="statusClass(feed.status)")] {{feed.statusDescription}} div(v-else-if="feed.type === 'OnPlayerJoined'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] has joined div(v-else-if="feed.type === 'OnPlayerLeft'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] has left div(v-else-if="feed.type === 'OnPlayerJoining'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] is joining div(v-else-if="feed.type === 'Location'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} location(:location="feed.location" :hint="feed.worldName") div(v-else-if="feed.type === 'VideoPlay'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] changed video to template(v-if="feed.videoName") | #[span(v-text="feed.videoName")] template(v-else) | #[span(v-text="feed.videoUrl")] div(v-else-if="feed.type === 'invite'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.senderUsername")] has invited you to #[location(:location="feed.details.worldId" :hint="feed.details.worldName")] #[span(v-text="feed.details.inviteMessage")] div(v-else-if="feed.type === 'requestInvite'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.senderUsername")] has requested an invite #[span(v-text="feed.details.requestMessage")] div(v-else-if="feed.type === 'inviteResponse'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.senderUsername")] has responded to your invite #[span(v-text="feed.details.responseMessage")] div(v-else-if="feed.type === 'requestInviteResponse'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.senderUsername")] has responded to your invite request #[span(v-text="feed.details.responseMessage")] div(v-else-if="feed.type === 'friendRequest'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.senderUsername")] has sent you a friend request div(v-else-if="feed.type === 'Friend'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] is now your friend div(v-else-if="feed.type === 'Unfriend'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] is no longer your friend div(v-else-if="feed.type === 'DisplayName'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.previousDisplayName")] changed their name to #[span.name(v-text="feed.displayName")] div(v-else-if="feed.type === 'TrustLevel'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] trust level is now {{ feed.trustLevel }} div(v-else-if="feed.type === 'PortalSpawn'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] has spawned a portal template(v-if="feed.worldName") | to #[location(:location="feed.instanceId" :hint="feed.worldName")] div(v-else-if="feed.type === 'AvatarChange'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | #[span.name(v-text="feed.displayName")] changed into avatar {{ feed.name }} template(v-if="feed.description && feed.description !== feed.name") | - {{ feed.description }} div(v-else-if="feed.type === 'Event'" class="x-friend-item") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | Event: #[span.name(v-text="feed.data")] div(v-else-if="feed.type === 'VideoPlay'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | Now playing: #[span.name(v-text="feed.data")] div(v-else-if="feed.type === 'BlockedOnPlayerJoined'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | Blocked user #[span.name(v-text="feed.displayName")] has joined div(v-else-if="feed.type === 'BlockedOnPlayerLeft'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | Blocked user #[span.name(v-text="feed.displayName")] has left div(v-else-if="feed.type === 'MutedOnPlayerJoined'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | Muted user #[span.name(v-text="feed.displayName")] has joined div(v-else-if="feed.type === 'MutedOnPlayerLeft'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate('HH:MI') }} | Muted user #[span.name(v-text="feed.displayName")] has left .x-containerbottom div(style="display:flex;flex-direction:row") template(v-if="devices.length") div(v-for="device in devices" style="flex:none;text-align:center;width:58px;height:74px") template(v-if="device[0] === 'tracker'") img(v-if="device[1] !== 'connected'" src="images/tracker_status_off.png" style="width:32px;height:32px") img(v-else-if="device[2] < 20" src="images/tracker_status_ready_low.png" style="width:32px;height:32px") img(v-else src="images/tracker_status_ready.png" style="width:32px;height:32px") br span {{ device[2] }}% template(v-else-if="device[0] === 'leftController'") img(v-if="device[1] !== 'connected'" src="images/controller_status_off.png" style="width:32px;height:32px") img(v-else-if="device[2] < 20" src="images/controller_status_ready_low.png" style="width:32px;height:32px") img(v-else src="images/controller_status_ready.png" style="width:32px;height:32px") br span L:{{ device[2] }}% template(v-else-if="device[0] === 'rightController'") img(v-if="device[1] !== 'connected'" src="images/controller_status_off.png" style="width:32px;height:32px") img(v-else-if="device[2] < 20" src="images/controller_status_ready_low.png" style="width:32px;height:32px") img(v-else src="images/controller_status_ready.png" style="width:32px;height:32px") br span R:{{ device[2] }}% template(v-else-if="device[0] === 'controller'") img(v-if="device[1] !== 'connected'" src="images/controller_status_off.png" style="width:32px;height:32px") img(v-else-if="device[2] < 20" src="images/controller_status_ready_low.png" style="width:32px;height:32px") img(v-else src="images/controller_status_ready.png" style="width:32px;height:32px") br span {{ device[2] }}% template(v-else-if="device[0] === 'base'") img(v-if="device[1] !== 'connected'" src="images/base_status_off.png" style="width:32px;height:32px") img(v-else-if="device[2] < 20" src="images/base_status_ready_low.png" style="width:32px;height:32px") img(v-else src="images/base_status_ready.png" style="width:32px;height:32px") br span {{ device[2] }}% template(v-else) img(v-if="device[1] !== 'connected'" src="images/other_status_off.png" style="width:32px;height:32px") img(v-else-if="device[2] < 20" src="images/other_status_ready_low.png" style="width:32px;height:32px") img(v-else src="images/other_status_ready.png" style="width:32px;height:32px") br span {{ device[2] }}% .x-containerbottom template(v-if="nowPlaying.playing") span(style="float:right;padding-left:10px") {{ nowPlaying.remainingText }} marquee-text {{ nowPlaying.name }} ‎ div.np-progress-bar(:style="{ width: nowPlaying.percentage + '%' }") template(v-if="config && config.minimalFeed") template(v-if="config.downloadProgress === 100") span(style="display:inline-block;margin-right:5px") #[i.el-icon-loading] template(v-else-if="config.downloadProgress > 0") span(style="display:inline-block;margin-right:5px") {{ config.downloadProgress }}% template(v-if="lastLocation.date !== 0") span(style="float:right") {{ lastLocationTimer }} span(style="display:inline-block") {{ lastLocation.playerList.length }} span(style="display:inline-block;font-weight:bold") {{ lastLocation.friendList.length !== 0 ? `‎‎‎‎‎‎‎‎‏‏‎ ‎(${lastLocation.friendList.length})` : ''}} template(v-else) template(v-if="config.downloadProgress === 100") span(style="display:inline-block;margin-right:5px") Downloading: #[i.el-icon-loading] template(v-else-if="config.downloadProgress > 0") span(style="display:inline-block;margin-right:5px") Downloading: {{ config.downloadProgress }}% template(v-if="lastLocation.date !== 0") span(style="float:right") Timer: {{ lastLocationTimer }} span(style="display:inline-block") Players: {{ lastLocation.playerList.length }} span(style="display:inline-block;font-weight:bold") {{ lastLocation.friendList.length !== 0 ? `‎‎‎‎‎‎‎‎‏‏‎ ‎(${lastLocation.friendList.length})` : ''}} br span(style="float:right") {{ currentTime | formatDate('YYYY-MM-DD HH:MI:SS AMPM') }} span CPU {{ cpuUsage }}% svg(v-if="appType === '2'" class="np-progress-circle") circle(class="np-progress-circle-stroke" cx="60" cy="60" stroke="white" r="30" fill="transparent" stroke-width="60") script(src="vendor.js") script(src="vr.js")