├── 20211105181256_1.jpg ├── LICENSE ├── README.md ├── cl_mdt.lua ├── fxmanifest.lua ├── sv_mdt.lua ├── sv_vehcolors.lua ├── ui ├── badges │ └── police.png ├── footer.png ├── index.html ├── main.css ├── mugshot.png ├── script.js ├── styles │ └── police.css └── vue.min.js └── user_mdt.sql /20211105181256_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matetv/mdt_qbcore/2b33f476bc8c7dbcd8558681c112c4e85a725352/20211105181256_1.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 distritic 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #No more support!!! Outdated version! 2 | #MDT qbcore! Entries extended "blood group" & "fingerprint"! 3 | !#If necessary someone can use it! 4 | 5 | #[QBCORE] Fingerabdrücke und Blutgruppe im MDT! 6 | # https://forum.friendz-club.de/forum/index.php?thread/722-qbcore-fingerabdr%C3%BCcke-und-blutgruppe-im-mdt/&postID=1884#post1884 7 | 8 | 9 | #Edit: Entries extended "BLOOD GROUP" & "FINGERPRINT" & "NATIONALITY" 10 | ![20211105182410_1](https://user-images.githubusercontent.com/35634379/140554454-eea23f2e-e7b2-4bcb-9443-a444eb55bb18.jpg) 11 | 12 | Update: Missing data uploaded!# Must change the "#" in your PLAYERS table in the database to "id" like this !! 13 | 14 | ![image](https://user-images.githubusercontent.com/57848836/124848636-e06d9880-df62-11eb-88aa-c0e211b039e3.png) 15 | 16 | ![image](https://user-images.githubusercontent.com/57848836/133552468-22a54f28-98ca-4eaf-b3a8-79f13d8b3d35.png) 17 | 18 | QBCORE: https://github.com/GhzGarage/mdt 19 | Original: https://forum.cfx.re/t/esx-mobile-data-terminal-reports-warrants-calls-searches-more/1701472 20 | -------------------------------------------------------------------------------- /cl_mdt.lua: -------------------------------------------------------------------------------- 1 | local isVisible = false 2 | local tabletObject = nil 3 | local callBip = nil 4 | local zones = { ['AIRP'] = "Los Santos International Airport", ['ALAMO'] = "Alamo Sea", ['ALTA'] = "Alta", ['ARMYB'] = "Fort Zancudo", ['BANHAMC'] = "Banham Canyon Dr", ['BANNING'] = "Banning", ['BEACH'] = "Vespucci Beach", ['BHAMCA'] = "Banham Canyon", ['BRADP'] = "Braddock Pass", ['BRADT'] = "Braddock Tunnel", ['BURTON'] = "Burton", ['CALAFB'] = "Calafia Bridge", ['CANNY'] = "Raton Canyon", ['CCREAK'] = "Cassidy Creek", ['CHAMH'] = "Chamberlain Hills", ['CHIL'] = "Vinewood Hills", ['CHU'] = "Chumash", ['CMSW'] = "Chiliad Mountain State Wilderness", ['CYPRE'] = "Cypress Flats", ['DAVIS'] = "Davis", ['DELBE'] = "Del Perro Beach", ['DELPE'] = "Del Perro", ['DELSOL'] = "La Puerta", ['DESRT'] = "Grand Senora Desert", ['DOWNT'] = "Downtown", ['DTVINE'] = "Downtown Vinewood", ['EAST_V'] = "East Vinewood", ['EBURO'] = "El Burro Heights", ['ELGORL'] = "El Gordo Lighthouse", ['ELYSIAN'] = "Elysian Island", ['GALFISH'] = "Galilee", ['GOLF'] = "GWC and Golfing Society", ['GRAPES'] = "Grapeseed", ['GREATC'] = "Great Chaparral", ['HARMO'] = "Harmony", ['HAWICK'] = "Hawick", ['HORS'] = "Vinewood Racetrack", ['HUMLAB'] = "Humane Labs and Research", ['JAIL'] = "Bolingbroke Penitentiary", ['KOREAT'] = "Little Seoul", ['LACT'] = "Land Act Reservoir", ['LAGO'] = "Lago Zancudo", ['LDAM'] = "Land Act Dam", ['LEGSQU'] = "Legion Square", ['LMESA'] = "La Mesa", ['LOSPUER'] = "La Puerta", ['MIRR'] = "Mirror Park", ['MORN'] = "Morningwood", ['MOVIE'] = "Richards Majestic", ['MTCHIL'] = "Mount Chiliad", ['MTGORDO'] = "Mount Gordo", ['MTJOSE'] = "Mount Josiah", ['MURRI'] = "Murrieta Heights", ['NCHU'] = "North Chumash", ['NOOSE'] = "N.O.O.S.E", ['OCEANA'] = "Pacific Ocean", ['PALCOV'] = "Paleto Cove", ['PALETO'] = "Paleto Bay", ['PALFOR'] = "Paleto Forest", ['PALHIGH'] = "Palomino Highlands", ['PALMPOW'] = "Palmer-Taylor Power Station", ['PBLUFF'] = "Pacific Bluffs", ['PBOX'] = "Pillbox Hill", ['PROCOB'] = "Procopio Beach", ['RANCHO'] = "Rancho", ['RGLEN'] = "Richman Glen", ['RICHM'] = "Richman", ['ROCKF'] = "Rockford Hills", ['RTRAK'] = "Redwood Lights Track", ['SANAND'] = "San Andreas", ['SANCHIA'] = "San Chianski Mountain Range", ['SANDY'] = "Sandy Shores", ['SKID'] = "Mission Row", ['SLAB'] = "Stab City", ['STAD'] = "Maze Bank Arena", ['STRAW'] = "Strawberry", ['TATAMO'] = "Tataviam Mountains", ['TERMINA'] = "Terminal", ['TEXTI'] = "Textile City", ['TONGVAH'] = "Tongva Hills", ['TONGVAV'] = "Tongva Valley", ['VCANA'] = "Vespucci Canals", ['VESP'] = "Vespucci", ['VINE'] = "Vinewood", ['WINDF'] = "Ron Alternates Wind Farm", ['WVINE'] = "West Vinewood", ['ZANCUDO'] = "Zancudo River", ['ZP_ORT'] = "Port of South Los Santos", ['ZQ_UAR'] = "Davis Quartz" } 5 | 6 | RegisterCommand('mdt', function() 7 | local playerPed = PlayerPedId() 8 | local playerVeh = GetVehiclePedIsIn(playerPed, false) 9 | if not isVisible and IsPedInAnyPoliceVehicle(playerPed) and GetEntitySpeed(playerVeh) < 5.0 then 10 | if GetVehicleNumberPlateText(getVehicleInFront()) then 11 | TriggerServerEvent("mdt:performVehicleSearchInFront", GetVehicleNumberPlateText(getVehicleInFront())) 12 | else 13 | TriggerServerEvent("mdt:hotKeyOpen") 14 | end 15 | elseif not IsPedInAnyPoliceVehicle(playerPed) then 16 | TriggerServerEvent("mdt:hotKeyOpen") 17 | end 18 | if DoesEntityExist(playerPed) and IsPedUsingActionMode(playerPed) then -- disable action mode/combat stance when engaged in combat (thing which makes you run around like an idiot when shooting) 19 | SetPedUsingActionMode(playerPed, -1, -1, 1) 20 | end 21 | end, false) 22 | 23 | RegisterKeyMapping('mdt', 'Display the mdt', 'keyboard', 'delete') 24 | 25 | TriggerServerEvent("mdt:getOffensesAndOfficer") 26 | 27 | RegisterNetEvent("mdt:toggleVisibilty") 28 | AddEventHandler("mdt:toggleVisibilty", function(reports, warrants, officer, job, grade) 29 | local playerPed = PlayerPedId() 30 | if not isVisible then 31 | local dict = "amb@world_human_seat_wall_tablet@female@base" 32 | RequestAnimDict(dict) 33 | if tabletObject == nil then 34 | tabletObject = CreateObject(GetHashKey('prop_cs_tablet'), GetEntityCoords(playerPed), 1, 1, 1) 35 | AttachEntityToEntity(tabletObject, playerPed, GetPedBoneIndex(playerPed, 28422), 0.0, 0.0, 0.03, 0.0, 0.0, 0.0, 1, 1, 0, 1, 0, 1) 36 | end 37 | while not HasAnimDictLoaded(dict) do Citizen.Wait(100) end 38 | if not IsEntityPlayingAnim(playerPed, dict, 'base', 3) then 39 | TaskPlayAnim(playerPed, dict, "base", 8.0, 1.0, -1, 49, 1.0, 0, 0, 0) 40 | end 41 | else 42 | DeleteEntity(tabletObject) 43 | ClearPedTasks(playerPed) 44 | tabletObject = nil 45 | end 46 | if #warrants == 0 then warrants = false end 47 | if #reports == 0 then reports = false end 48 | SendNUIMessage({ 49 | type = "recentReportsAndWarrantsLoaded", 50 | reports = reports, 51 | warrants = warrants, 52 | officer = officer, 53 | department = job, 54 | rank = grade 55 | }) 56 | ToggleGUI() 57 | end) 58 | 59 | RegisterNUICallback("close", function(data, cb) 60 | local playerPed = PlayerPedId() 61 | DeleteEntity(tabletObject) 62 | ClearPedTasks(playerPed) 63 | tabletObject = nil 64 | ToggleGUI(false) 65 | cb('ok') 66 | end) 67 | 68 | RegisterNUICallback("performOffenderSearch", function(data, cb) 69 | TriggerServerEvent("mdt:performOffenderSearch", data.query) 70 | TriggerServerEvent("mdt:getOffensesAndOfficer") 71 | cb('ok') 72 | end) 73 | 74 | RegisterNUICallback("viewOffender", function(data, cb) 75 | TriggerServerEvent("mdt:getOffenderDetails", data.offender) 76 | cb('ok') 77 | end) 78 | 79 | RegisterNUICallback("saveOffenderChanges", function(data, cb) 80 | TriggerServerEvent("mdt:saveOffenderChanges", data.id, data.changes, data.identifier) 81 | cb('ok') 82 | end) 83 | 84 | RegisterNUICallback("submitNewReport", function(data, cb) 85 | TriggerServerEvent("mdt:submitNewReport", data) 86 | cb('ok') 87 | end) 88 | 89 | RegisterNUICallback("performReportSearch", function(data, cb) 90 | TriggerServerEvent("mdt:performReportSearch", data.query) 91 | cb('ok') 92 | end) 93 | 94 | RegisterNUICallback("getOffender", function(data, cb) 95 | TriggerServerEvent("mdt:getOffenderDetailsById", data.char_id) 96 | cb('ok') 97 | end) 98 | 99 | RegisterNUICallback("deleteReport", function(data, cb) 100 | TriggerServerEvent("mdt:deleteReport", data.id) 101 | cb('ok') 102 | end) 103 | 104 | RegisterNUICallback("saveReportChanges", function(data, cb) 105 | TriggerServerEvent("mdt:saveReportChanges", data) 106 | cb('ok') 107 | end) 108 | 109 | RegisterNUICallback("vehicleSearch", function(data, cb) 110 | TriggerServerEvent("mdt:performVehicleSearch", data.plate) 111 | cb('ok') 112 | end) 113 | 114 | RegisterNUICallback("getVehicle", function(data, cb) 115 | TriggerServerEvent("mdt:getVehicle", data.vehicle) 116 | cb('ok') 117 | end) 118 | 119 | RegisterNUICallback("getWarrants", function(data, cb) 120 | TriggerServerEvent("mdt:getWarrants") 121 | end) 122 | 123 | RegisterNUICallback("submitNewWarrant", function(data, cb) 124 | TriggerServerEvent("mdt:submitNewWarrant", data) 125 | cb('ok') 126 | end) 127 | 128 | RegisterNUICallback("deleteWarrant", function(data, cb) 129 | TriggerServerEvent("mdt:deleteWarrant", data.id) 130 | cb('ok') 131 | end) 132 | 133 | RegisterNUICallback("deleteWarrant", function(data, cb) 134 | TriggerServerEvent("mdt:deleteWarrant", data.id) 135 | cb('ok') 136 | end) 137 | 138 | RegisterNUICallback("getReport", function(data, cb) 139 | TriggerServerEvent("mdt:getReportDetailsById", data.id) 140 | cb('ok') 141 | end) 142 | 143 | RegisterNUICallback("getCalls", function(data, cb) 144 | TriggerServerEvent("mdt:getCalls") 145 | end) 146 | 147 | RegisterNUICallback("attachToCall", function(data, cb) 148 | TriggerServerEvent("mdt:attachToCall", data.index) 149 | if not callBlip then 150 | callBlip = AddBlipForCoord(data.coords[1], data.coords[2], data.coords[3]) 151 | SetBlipSprite(callBlip, 304) 152 | SetBlipDisplay(callBlip, 2) 153 | SetBlipScale(callBlip, 1.2) 154 | SetBlipColour(callBlip, 29) 155 | BeginTextCommandSetBlipName("STRING") 156 | AddTextComponentString("911 Call") 157 | EndTextCommandSetBlipName(callBlip) 158 | end 159 | cb('ok') 160 | end) 161 | 162 | RegisterNUICallback("detachFromCall", function(data, cb) 163 | TriggerServerEvent("mdt:detachFromCall", data.index) 164 | if callBlip then 165 | RemoveBlip(callBlip) 166 | callBlip = nil 167 | end 168 | cb('ok') 169 | end) 170 | 171 | RegisterNUICallback("setCallWaypoint", function(data, cb) 172 | SetNewWaypoint(data.coords[1], data.coords[2]) 173 | cb('ok') 174 | end) 175 | 176 | RegisterNUICallback("editCall", function(data, cb) 177 | TriggerServerEvent("mdt:editCall", data.index, data.details) 178 | cb('ok') 179 | end) 180 | 181 | RegisterNUICallback("deleteCall", function(data, cb) 182 | TriggerServerEvent("mdt:deleteCall", data.index) 183 | cb('ok') 184 | end) 185 | 186 | RegisterNUICallback("deleteCallBlip", function(data, cb) 187 | if callBlip then 188 | RemoveBlip(callBlip) 189 | callBlip = nil 190 | end 191 | end) 192 | 193 | RegisterNUICallback("saveVehicleChanges", function(data, cb) 194 | TriggerServerEvent("mdt:saveVehicleChanges", data) 195 | cb('ok') 196 | end) 197 | 198 | RegisterNetEvent("mdt:returnOffenderSearchResults") 199 | AddEventHandler("mdt:returnOffenderSearchResults", function(results) 200 | SendNUIMessage({ 201 | type = "returnedPersonMatches", 202 | matches = results 203 | }) 204 | end) 205 | 206 | RegisterNetEvent("mdt:closeModal") 207 | AddEventHandler("mdt:closeModal", function() 208 | SendNUIMessage({ 209 | type = "closeModal" 210 | }) 211 | end) 212 | 213 | RegisterNetEvent("mdt:returnOffenderDetails") 214 | AddEventHandler("mdt:returnOffenderDetails", function(data) 215 | for i = 1, #data.vehicles do 216 | data.vehicles[i].model = GetLabelText(GetDisplayNameFromVehicleModel(data.vehicles[i].model)) 217 | end 218 | SendNUIMessage({ 219 | type = "returnedOffenderDetails", 220 | details = data 221 | }) 222 | end) 223 | 224 | RegisterNetEvent("mdt:returnOffensesAndOfficer") 225 | AddEventHandler("mdt:returnOffensesAndOfficer", function(data, name) 226 | SendNUIMessage({ 227 | type = "offensesAndOfficerLoaded", 228 | offenses = data, 229 | name = name 230 | }) 231 | end) 232 | 233 | RegisterNetEvent("mdt:returnReportSearchResults") 234 | AddEventHandler("mdt:returnReportSearchResults", function(results) 235 | SendNUIMessage({ 236 | type = "returnedReportMatches", 237 | matches = results 238 | }) 239 | end) 240 | 241 | RegisterNetEvent("mdt:returnVehicleSearchInFront") 242 | AddEventHandler("mdt:returnVehicleSearchInFront", function(results, plate) 243 | SendNUIMessage({ 244 | type = "returnedVehicleMatchesInFront", 245 | matches = results, 246 | plate = plate 247 | }) 248 | end) 249 | 250 | RegisterNetEvent("mdt:returnVehicleSearchResults") 251 | AddEventHandler("mdt:returnVehicleSearchResults", function(results) 252 | SendNUIMessage({ 253 | type = "returnedVehicleMatches", 254 | matches = results 255 | }) 256 | end) 257 | 258 | RegisterNetEvent("mdt:returnVehicleDetails") 259 | AddEventHandler("mdt:returnVehicleDetails", function(data) 260 | if type(data.model) == 'number' then 261 | data.model = GetLabelText(GetDisplayNameFromVehicleModel(data.model)) 262 | end 263 | SendNUIMessage({ 264 | type = "returnedVehicleDetails", 265 | details = data 266 | }) 267 | end) 268 | 269 | RegisterNetEvent("mdt:returnWarrants") 270 | AddEventHandler("mdt:returnWarrants", function(data) 271 | SendNUIMessage({ 272 | type = "returnedWarrants", 273 | warrants = data 274 | }) 275 | end) 276 | 277 | RegisterNetEvent("mdt:completedWarrantAction") 278 | AddEventHandler("mdt:completedWarrantAction", function(data) 279 | SendNUIMessage({ 280 | type = "completedWarrantAction" 281 | }) 282 | end) 283 | 284 | RegisterNetEvent("mdt:returnReportDetails") 285 | AddEventHandler("mdt:returnReportDetails", function(data) 286 | SendNUIMessage({ 287 | type = "returnedReportDetails", 288 | details = data 289 | }) 290 | end) 291 | 292 | RegisterNetEvent("mdt:sendNUIMessage") 293 | AddEventHandler("mdt:sendNUIMessage", function(messageTable) 294 | SendNUIMessage(messageTable) 295 | end) 296 | 297 | RegisterNetEvent("mdt:sendNotification") 298 | AddEventHandler("mdt:sendNotification", function(message) 299 | SendNUIMessage({ 300 | type = "sendNotification", 301 | message = message 302 | }) 303 | end) 304 | 305 | RegisterNetEvent("mdt:getNewCallCoords") 306 | AddEventHandler("mdt:getNewCallCoords", function(details, callid) 307 | local coords = GetEntityCoords(PlayerPedId()) 308 | TriggerServerEvent("mdt:newCall", details, callid, coords) 309 | end) 310 | 311 | RegisterNetEvent("mdt:newCall") 312 | AddEventHandler("mdt:newCall", function(details, callid, coords, index) 313 | local x, y, z = table.unpack(coords) 314 | local var1, var2 = GetStreetNameAtCoord(x, y, z, Citizen.ResultAsInteger(), Citizen.ResultAsInteger()) 315 | local location = GetStreetNameFromHashKey(var1)..', '..zones[GetNameOfZone(x, y, z)] 316 | SendNUIMessage({ 317 | type = "newCall", 318 | details = details, 319 | source = callid, 320 | coords = {x, y, z}, 321 | location = location, 322 | id = index 323 | }) 324 | end) 325 | 326 | RegisterNetEvent("mdt:newCallAttach") 327 | AddEventHandler("mdt:newCallAttach", function(index, charname) 328 | SendNUIMessage({ 329 | type = "newCallAttach", 330 | call = index, 331 | charname = charname 332 | }) 333 | end) 334 | 335 | RegisterNetEvent("mdt:newCallDetach") 336 | AddEventHandler("mdt:newCallDetach", function(index, charname) 337 | SendNUIMessage({ 338 | type = "newCallDetach", 339 | call = index, 340 | charname = charname 341 | }) 342 | end) 343 | 344 | RegisterNetEvent("mdt:editCall") 345 | AddEventHandler("mdt:editCall", function(index, details) 346 | SendNUIMessage({ 347 | type = "editCall", 348 | call = index, 349 | details = details 350 | }) 351 | end) 352 | 353 | RegisterNetEvent("mdt:deleteCall") 354 | AddEventHandler("mdt:deleteCall", function(index) 355 | SendNUIMessage({ 356 | type = "deleteCall", 357 | call = index 358 | }) 359 | end) 360 | 361 | function ToggleGUI(explicit_status) 362 | if explicit_status ~= nil then 363 | isVisible = explicit_status 364 | else 365 | isVisible = not isVisible 366 | end 367 | SetNuiFocus(isVisible, isVisible) 368 | SendNUIMessage({ 369 | type = "enable", 370 | isVisible = isVisible 371 | }) 372 | end 373 | 374 | function getVehicleInFront() 375 | local playerPed = PlayerPedId() 376 | local coordA = GetEntityCoords(playerPed, 1) 377 | local coordB = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 10.0, 0.0) 378 | local targetVehicle = getVehicleInDirection(coordA, coordB) 379 | return targetVehicle 380 | end 381 | 382 | function getVehicleInDirection(coordFrom, coordTo) 383 | local rayHandle = CastRayPointToPoint(coordFrom.x, coordFrom.y, coordFrom.z, coordTo.x, coordTo.y, coordTo.z, 10, GetPlayerPed(-1), 0) 384 | local a, b, c, d, vehicle = GetRaycastResult(rayHandle) 385 | return vehicle 386 | end 387 | 388 | function tprint (tbl, indent) 389 | if not indent then indent = 0 end 390 | local toprint = string.rep(" ", indent) .. "{\r\n" 391 | indent = indent + 2 392 | for k, v in pairs(tbl) do 393 | toprint = toprint .. string.rep(" ", indent) 394 | if (type(k) == "number") then 395 | toprint = toprint .. "[" .. k .. "] = " 396 | elseif (type(k) == "string") then 397 | toprint = toprint .. k .. "= " 398 | end 399 | if (type(v) == "number") then 400 | toprint = toprint .. v .. ",\r\n" 401 | elseif (type(v) == "string") then 402 | toprint = toprint .. "\"" .. v .. "\",\r\n" 403 | elseif (type(v) == "table") then 404 | toprint = toprint .. tprint(v, indent + 2) .. ",\r\n" 405 | else 406 | toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n" 407 | end 408 | end 409 | toprint = toprint .. string.rep(" ", indent-2) .. "}" 410 | return toprint 411 | end 412 | -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | -- Made by distritic 2 | -- Do not sell, redistribute or claim this code as your own without my permission, thank you. <3 3 | fx_version 'adamant' 4 | game 'gta5' 5 | 6 | ui_page "ui/index.html" 7 | 8 | files { 9 | "ui/index.html", 10 | "ui/vue.min.js", 11 | "ui/script.js", 12 | "ui/main.css", 13 | "ui/styles/police.css", 14 | "ui/badges/police.png", 15 | "ui/footer.png", 16 | "ui/mugshot.png" 17 | } 18 | 19 | server_scripts { 20 | "sv_mdt.lua", 21 | "sv_vehcolors.lua" 22 | } 23 | 24 | client_script "cl_mdt.lua" 25 | shared_script '@qb-core/import.lua' -------------------------------------------------------------------------------- /sv_mdt.lua: -------------------------------------------------------------------------------- 1 | QBCore = exports['qb-core']:GetCoreObject() 2 | local call_index = 0 3 | 4 | RegisterServerEvent("mdt:hotKeyOpen") 5 | AddEventHandler("mdt:hotKeyOpen", function() 6 | local usource = source 7 | local xPlayer = QBCore.Functions.GetPlayer(usource) 8 | if xPlayer.PlayerData.job.name == 'police' then 9 | exports.oxmysql:fetch("SELECT * FROM (SELECT * FROM `mdt_reports` ORDER BY `id` DESC LIMIT 3) sub ORDER BY `id` DESC", {}, function(reports) 10 | for r = 1, #reports do 11 | reports[r].charges = json.decode(reports[r].charges) 12 | end 13 | exports.oxmysql:fetch("SELECT * FROM (SELECT * FROM `mdt_warrants` ORDER BY `id` DESC LIMIT 3) sub ORDER BY `id` DESC", {}, function(warrants) 14 | for w = 1, #warrants do 15 | warrants[w].charges = json.decode(warrants[w].charges) 16 | end 17 | local officer = GetCharacterName(usource) 18 | TriggerClientEvent('mdt:toggleVisibilty', usource, reports, warrants, officer, xPlayer.PlayerData.job.name, xPlayer.PlayerData.job.grade.name) 19 | end) 20 | end) 21 | end 22 | end) 23 | 24 | RegisterServerEvent("mdt:getOffensesAndOfficer") 25 | AddEventHandler("mdt:getOffensesAndOfficer", function() 26 | local usource = source 27 | local charges = {} 28 | exports.oxmysql:fetch('SELECT * FROM fine_types', {}, function(fines) 29 | for j = 1, #fines do 30 | if fines[j].category == 0 or fines[j].category == 1 or fines[j].category == 2 or fines[j].category == 3 then 31 | table.insert(charges, fines[j]) 32 | end 33 | end 34 | 35 | local officer = GetCharacterName(usource) 36 | 37 | TriggerClientEvent("mdt:returnOffensesAndOfficer", usource, charges, officer) 38 | end) 39 | end) 40 | 41 | RegisterServerEvent("mdt:performOffenderSearch") 42 | AddEventHandler("mdt:performOffenderSearch", function(query) 43 | local usource = source 44 | local matches = {} 45 | exports.oxmysql:fetch("SELECT * FROM `players` WHERE `charinfo` LIKE ? OR `metadata` LIKE ?", {string.lower('%'..query..'%'),string.lower('%'..query..'%')}, function(result) -- % wildcard, needed to search for all alike results 46 | for index, data in ipairs(result) do 47 | if data.charinfo then 48 | local player = json.decode(data.charinfo) 49 | local metadata = json.decode(data.metadata) 50 | local core = QBCore.Functions.GetPlayerByCitizenId(data.citizenid) 51 | 52 | if core then 53 | player = core['PlayerData']['charinfo'] 54 | metadata = core['PlayerData']['metadata'] 55 | end 56 | 57 | player.id = data.id 58 | player.metadata = metadata 59 | player.bloodtype = metadata.bloodtype 60 | player.fingerprint = metadata.fingerprint 61 | player.citizenid = data.citizenid 62 | table.insert(matches, player) 63 | end 64 | end 65 | 66 | TriggerClientEvent("mdt:returnOffenderSearchResults", usource, matches) 67 | end) 68 | end) 69 | 70 | RegisterServerEvent("mdt:getOffenderDetails") 71 | AddEventHandler("mdt:getOffenderDetails", function(offender) 72 | local usource = source 73 | GetLicenses(offender.citizenid, function(licenses) offender.licenses = licenses end) 74 | while offender.licenses == nil do Citizen.Wait(0) end 75 | exports.oxmysql:fetch('SELECT * FROM `user_mdt` WHERE `char_id` = ?', {offender.id}, function(result) 76 | 77 | offender.notes = "" 78 | offender.mugshot_url = "" 79 | offender.bail = false 80 | if result[1] then 81 | offender.notes = result[1].notes 82 | offender.mugshot_url = result[1].mugshot_url 83 | offender.bail = result[1].bail 84 | end 85 | 86 | exports.oxmysql:fetch('SELECT * FROM `user_convictions` WHERE `char_id` = ?', {offender.id}, function(convictions) 87 | 88 | if convictions[1] then 89 | offender.convictions = {} 90 | for i = 1, #convictions do 91 | local conviction = convictions[i] 92 | offender.convictions[conviction.offense] = conviction.count 93 | end 94 | end 95 | 96 | exports.oxmysql:fetch('SELECT * FROM `mdt_warrants` WHERE `char_id` = ?', {offender.id}, function(warrants) 97 | 98 | if warrants[1] then 99 | offender.haswarrant = true 100 | end 101 | 102 | exports.oxmysql:fetch('SELECT * FROM `player_vehicles` WHERE `citizenid` = ?', {offender.id}, function(vehicles) 103 | for i = 1, #vehicles do 104 | vehicles[i].model = vehicles[i].vehicle 105 | if vehicles[i].mods then 106 | local vehmods = json.decode(vehicles[i].mods) 107 | if colors[tostring(vehmods.color2)] and colors[tostring(vehmods.color1)] then 108 | vehicles[i].color = colors[tostring(vehmods.color2)] .. " on " .. colors[tostring(vehmods.color1)] 109 | elseif colors[tostring(vehmods.color1)] then 110 | vehicles[i].color = colors[tostring(vehmods.color1)] 111 | elseif colors[tostring(vehmods.color2)] then 112 | vehicles[i].color = colors[tostring(vehmods.color2)] 113 | else 114 | vehicles[i].color = "Unknown" 115 | end 116 | end 117 | vehicles[i].vehicle = nil 118 | end 119 | offender.vehicles = vehicles 120 | offender.phone_number = offender.phone 121 | offender.dateofbirth = offender.birthdate 122 | TriggerClientEvent("mdt:returnOffenderDetails", usource, offender) 123 | end) 124 | end) 125 | end) 126 | end) 127 | end) 128 | 129 | RegisterServerEvent("mdt:getOffenderDetailsById") 130 | AddEventHandler("mdt:getOffenderDetailsById", function(char_id) 131 | local usource = source 132 | exports.oxmysql:fetch('SELECT * FROM `players` WHERE `id` = ?', {char_id}, function(result) 133 | local charinfo = json.decode(result[1].charinfo) 134 | local offender = result[1] 135 | 136 | if not offender then 137 | TriggerClientEvent("mdt:closeModal", usource) 138 | TriggerClientEvent("mdt:sendNotification", usource, "This person no longer exists.") 139 | return 140 | end 141 | 142 | GetLicenses(offender.citizenid, function(licenses) offender.licenses = licenses end) 143 | while offender.licenses == nil do Citizen.Wait(0) end 144 | 145 | exports.oxmysql:fetch('SELECT * FROM `user_mdt` WHERE `char_id` = ?', {offender.id}, function(result) 146 | 147 | offender.notes = "" 148 | offender.mugshot_url = "" 149 | offender.bail = false 150 | if result[1] then 151 | offender.notes = result[1].notes 152 | offender.mugshot_url = result[1].mugshot_url 153 | offender.bail = result[1].bail 154 | end 155 | 156 | exports.oxmysql:fetch('SELECT * FROM `user_convictions` WHERE `char_id` = ?', {offender.id}, function(convictions) 157 | 158 | if convictions[1] then 159 | offender.convictions = {} 160 | for i = 1, #convictions do 161 | local conviction = convictions[i] 162 | offender.convictions[conviction.offense] = conviction.count 163 | end 164 | end 165 | 166 | exports.oxmysql:fetch('SELECT * FROM `mdt_warrants` WHERE `char_id` = ?', {offender.id}, function(warrants) 167 | 168 | if warrants[1] then 169 | offender.haswarrant = true 170 | end 171 | 172 | exports.oxmysql:fetch('SELECT * FROM `player_vehicles` WHERE `citizenid` = ?', {offender.citizenid}, function(vehicles) 173 | for i = 1, #vehicles do 174 | vehicles[i].model = vehicles[i].vehicle 175 | if vehicles[i].mods then 176 | local vehmods = json.decode(vehicles[i].mods) 177 | if colors[tostring(vehmods.color2)] and colors[tostring(vehmods.color1)] then 178 | vehicles[i].color = colors[tostring(vehmods.color2)] .. " on " .. colors[tostring(vehmods.color1)] 179 | elseif colors[tostring(vehmods.color1)] then 180 | vehicles[i].color = colors[tostring(vehmods.color1)] 181 | elseif colors[tostring(vehmods.color2)] then 182 | vehicles[i].color = colors[tostring(vehmods.color2)] 183 | else 184 | vehicles[i].color = "Unknown" 185 | end 186 | end 187 | vehicles[i].vehicle = nil 188 | end 189 | offender.vehicles = vehicles 190 | offender.firstname = charinfo.firstname 191 | offender.lastname = charinfo.lastname 192 | offender.phone_number = charinfo.phone 193 | offender.dateofbirth = charinfo.birthdate 194 | offender.bloodtype = charinfo.bloodtype 195 | offender.nationality = charinfo.nationality 196 | TriggerClientEvent("mdt:returnOffenderDetails", usource, offender) 197 | end) 198 | end) 199 | end) 200 | end) 201 | end) 202 | end) 203 | 204 | RegisterServerEvent("mdt:saveOffenderChanges") 205 | AddEventHandler("mdt:saveOffenderChanges", function(id, changes, identifier) 206 | local usource = source 207 | exports.oxmysql:fetch('SELECT * FROM `user_mdt` WHERE `char_id` = ?', {id}, function(result) 208 | if result[1] then 209 | exports.oxmysql:execute('UPDATE `user_mdt` SET `notes` = ?, `mugshot_url` = ?, `bail` = ? WHERE `char_id` = ?', {id, changes.notes, changes.mugshot_url, changes.bail}) 210 | else 211 | exports.oxmysql:insert('INSERT INTO `user_mdt` (`char_id`, `notes`, `mugshot_url`, `bail`) VALUES (?, ?, ?, ?)', {id, changes.notes, changes.mugshot_url, changes.bail}) 212 | end 213 | for i = 1, #changes.licenses_removed do 214 | local license = changes.licenses_removed[i] 215 | exports.oxmysql:execute('DELETE FROM `user_licenses` WHERE `type` = ? AND `owner` = ?', {license.type, identifier}) 216 | end 217 | 218 | if changes.convictions ~= nil then 219 | for conviction, amount in pairs(changes.convictions) do 220 | exports.oxmysql:execute('UPDATE `user_convictions` SET `count` = ? WHERE `char_id` = ? AND `offense` = ?', {id, amount, conviction}) 221 | end 222 | end 223 | 224 | for i = 1, #changes.convictions_removed do 225 | exports.oxmysql:execute('DELETE FROM `user_convictions` WHERE `char_id` = ? AND `offense` = ?', {id, changes.convictions_removed[i]}) 226 | end 227 | 228 | TriggerClientEvent("mdt:sendNotification", usource, "Offender changes have been saved.") 229 | end) 230 | end) 231 | 232 | RegisterServerEvent("mdt:saveReportChanges") 233 | AddEventHandler("mdt:saveReportChanges", function(data) 234 | exports.oxmysql:execute('UPDATE `mdt_reports` SET `title` = ?, `incident` = ? WHERE `id` = ?', {data.id, data.title, data.incident}) 235 | TriggerClientEvent("mdt:sendNotification", source, "Report changes have been saved.") 236 | end) 237 | 238 | RegisterServerEvent("mdt:deleteReport") 239 | AddEventHandler("mdt:deleteReport", function(id) 240 | exports.oxmysql:execute('DELETE FROM `mdt_reports` WHERE `id` = ?', {id}) 241 | TriggerClientEvent("mdt:sendNotification", source, "Report has been successfully deleted.") 242 | end) 243 | 244 | RegisterServerEvent("mdt:submitNewReport") 245 | AddEventHandler("mdt:submitNewReport", function(data) 246 | local usource = source 247 | local author = GetCharacterName(source) 248 | charges = json.encode(data.charges) 249 | data.date = os.date('%m-%d-%Y %H:%M:%S', os.time()) 250 | exports.oxmysql:insert('INSERT INTO `mdt_reports` (`char_id`, `title`, `incident`, `charges`, `author`, `name`, `date`) VALUES (?, ?, ?, ?, ?, ?, ?)', {data.char_id, data.title, data.incident, charges, author, data.name, data.date,}, function(id) 251 | TriggerEvent("mdt:getReportDetailsById", id, usource) 252 | TriggerClientEvent("mdt:sendNotification", usource, "A new report has been submitted.") 253 | end) 254 | 255 | for offense, count in pairs(data.charges) do 256 | exports.oxmysql:fetch('SELECT * FROM `user_convictions` WHERE `offense` = ? AND `char_id` = ?', {offense, data.char_id}, function(result) 257 | if result[1] then 258 | exports.oxmysql:execute('UPDATE `user_convictions` SET `count` = ? WHERE `offense` = ? AND `char_id` = ?', {data.char_id, offense, count + 1}) 259 | else 260 | exports.oxmysql:insert('INSERT INTO `user_convictions` (`char_id`, `offense`, `count`) VALUES (?, ?, ?)', {data.char_id, offense, count}) 261 | end 262 | end) 263 | end 264 | end) 265 | 266 | RegisterServerEvent("mdt:performReportSearch") 267 | AddEventHandler("mdt:performReportSearch", function(query) 268 | local usource = source 269 | local matches = {} 270 | exports.oxmysql:fetch("SELECT * FROM `mdt_reports` WHERE `id` LIKE :test OR LOWER(`title`) LIKE :test OR LOWER(`name`) LIKE :test OR LOWER(`author`) LIKE :test or LOWER(`charges`) LIKE :test", { 271 | test = string.lower('%'..query..'%') 272 | }, function(result) -- % wildcard, needed to search for all alike results 273 | 274 | for index, data in ipairs(result) do 275 | data.charges = json.decode(data.charges) 276 | table.insert(matches, data) 277 | end 278 | 279 | TriggerClientEvent("mdt:returnReportSearchResults", usource, matches) 280 | end) 281 | end) 282 | 283 | RegisterServerEvent("mdt:performVehicleSearch") 284 | AddEventHandler("mdt:performVehicleSearch", function(query) 285 | local usource = source 286 | local matches = {} 287 | exports.oxmysql:fetch("SELECT * FROM `player_vehicles` WHERE LOWER(`plate`) LIKE ?", {string.lower('%'..query..'%')}, function(result) -- % wildcard, needed to search for all alike results 288 | for index, data in ipairs(result) do 289 | data.model = data.vehicle 290 | if data.mods ~= nil then 291 | local vehmods = json.decode(data.mods) 292 | data.color = colors[tostring(vehmods.color1)] 293 | if colors[tostring(vehmods.color2)] then 294 | data.color = colors[tostring(vehmods.color2)] .. " on " .. colors[tostring(vehmods.color1)] 295 | end 296 | end 297 | table.insert(matches, data) 298 | end 299 | 300 | TriggerClientEvent("mdt:returnVehicleSearchResults", usource, matches) 301 | end) 302 | end) 303 | 304 | RegisterServerEvent("mdt:performVehicleSearchInFront") 305 | AddEventHandler("mdt:performVehicleSearchInFront", function(query) 306 | local usource = source 307 | local xPlayer = QBCore.Functions.GetPlayer(usource) 308 | if xPlayer.PlayerData.job.name == 'police' then 309 | exports.oxmysql:fetch("SELECT * FROM (SELECT * FROM `mdt_reports` ORDER BY `id` DESC LIMIT 3) sub ORDER BY `id` DESC", {}, function(reports) 310 | for r = 1, #reports do 311 | reports[r].charges = json.decode(reports[r].charges) 312 | end 313 | exports.oxmysql:fetch("SELECT * FROM (SELECT * FROM `mdt_warrants` ORDER BY `id` DESC LIMIT 3) sub ORDER BY `id` DESC", {}, function(warrants) 314 | for w = 1, #warrants do 315 | warrants[w].charges = json.decode(warrants[w].charges) 316 | end 317 | exports.oxmysql:fetch("SELECT * FROM `player_vehicles` WHERE `plate` = ?", {query}, function(result) 318 | local officer = GetCharacterName(usource) 319 | TriggerClientEvent('mdt:toggleVisibilty', usource, reports, warrants, officer, xPlayer.PlayerData.job.name) 320 | TriggerClientEvent("mdt:returnVehicleSearchInFront", usource, result, query) 321 | end) 322 | end) 323 | end) 324 | end 325 | end) 326 | 327 | RegisterServerEvent("mdt:getVehicle") 328 | AddEventHandler("mdt:getVehicle", function(vehicle) 329 | local usource = source 330 | exports.oxmysql:fetch("SELECT * FROM `players` WHERE `citizenid` = ?", {vehicle.citizenid}, function(result) 331 | 332 | if result[1] then 333 | local player = json.decode(result[1].charinfo) 334 | vehicle.owner = player.firstname .. ' ' .. player.lastname 335 | vehicle.owner_id = result[1].id 336 | end 337 | 338 | exports.oxmysql:fetch('SELECT * FROM `vehicle_mdt` WHERE `plate` = ?', {vehicle.plate}, function(data) 339 | 340 | if data[1] then 341 | if data[1].stolen == 1 then vehicle.stolen = true else vehicle.stolen = false end 342 | if data[1].notes ~= null then vehicle.notes = data[1].notes else vehicle.notes = '' end 343 | else 344 | vehicle.stolen = false 345 | vehicle.notes = '' 346 | end 347 | 348 | exports.oxmysql:fetch('SELECT * FROM `mdt_warrants` WHERE `char_id` = ?', {vehicle.owner_id}, function(warrants) 349 | 350 | if warrants[1] then 351 | vehicle.haswarrant = true 352 | end 353 | 354 | exports.oxmysql:fetch('SELECT `bail` FROM user_mdt WHERE `char_id` = ?', {vehicle.owner_id}, function(bail) 355 | 356 | if bail and bail[1] and bail[1].bail == 1 then 357 | vehicle.bail = true 358 | else 359 | vehicle.bail = false 360 | end 361 | vehicle.type = 'Vehicle' 362 | TriggerClientEvent("mdt:returnVehicleDetails", usource, vehicle) 363 | end) 364 | end) 365 | end) 366 | end) 367 | end) 368 | 369 | RegisterServerEvent("mdt:getWarrants") 370 | AddEventHandler("mdt:getWarrants", function() 371 | local usource = source 372 | exports.oxmysql:fetch("SELECT * FROM `mdt_warrants`", {}, function(warrants) 373 | for i = 1, #warrants do 374 | warrants[i].expire_time = "" 375 | warrants[i].charges = json.decode(warrants[i].charges) 376 | end 377 | TriggerClientEvent("mdt:returnWarrants", usource, warrants) 378 | end) 379 | end) 380 | 381 | RegisterServerEvent("mdt:submitNewWarrant") 382 | AddEventHandler("mdt:submitNewWarrant", function(data) 383 | local usource = source 384 | data.charges = json.encode(data.charges) 385 | data.author = GetCharacterName(source) 386 | data.date = os.date('%m-%d-%Y %H:%M:%S', os.time()) 387 | exports.oxmysql:insert('INSERT INTO `mdt_warrants` (`name`, `char_id`, `report_id`, `report_title`, `charges`, `date`, `expire`, `notes`, `author`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', {data.name, data.char_id, data.report_id, data.report_title, data.charges, data.date, data.expire, data.notes, data.author}, function() 388 | TriggerClientEvent("mdt:completedWarrantAction", usource) 389 | TriggerClientEvent("mdt:sendNotification", usource, "A new warrant has been created.") 390 | end) 391 | end) 392 | 393 | RegisterServerEvent("mdt:deleteWarrant") 394 | AddEventHandler("mdt:deleteWarrant", function(id) 395 | local usource = source 396 | exports.oxmysql:execute('DELETE FROM `mdt_warrants` WHERE `id` = ?', {id}, function() 397 | TriggerClientEvent("mdt:completedWarrantAction", usource) 398 | end) 399 | TriggerClientEvent("mdt:sendNotification", usource, "Warrant has been successfully deleted.") 400 | end) 401 | 402 | RegisterServerEvent("mdt:getReportDetailsById") 403 | AddEventHandler("mdt:getReportDetailsById", function(query, _source) 404 | if _source then source = _source end 405 | local usource = source 406 | exports.oxmysql:fetch("SELECT * FROM `mdt_reports` WHERE `id` = ?", {query}, function(result) 407 | if result and result[1] then 408 | result[1].charges = json.decode(result[1].charges) 409 | TriggerClientEvent("mdt:returnReportDetails", usource, result[1]) 410 | else 411 | TriggerClientEvent("mdt:closeModal", usource) 412 | TriggerClientEvent("mdt:sendNotification", usource, "This report cannot be found.") 413 | end 414 | end) 415 | end) 416 | 417 | RegisterServerEvent("mdt:newCall") 418 | AddEventHandler("mdt:newCall", function(details, caller, coords, sendNotification) 419 | call_index = call_index + 1 420 | local xPlayers = QBCore.Functions.GetPlayers() 421 | for i= 1, #xPlayers do 422 | local source = xPlayers[i] 423 | local xPlayer = QBCore.Functions.GetPlayer(source) 424 | if xPlayer.PlayerData.job.name == 'police' then 425 | TriggerClientEvent("mdt:newCall", source, details, caller, coords, call_index) 426 | if sendNotification ~= false then 427 | TriggerClientEvent("InteractSound_CL:PlayOnOne", source, 'demo', 0.0) 428 | TriggerClientEvent("mythic_notify:client:SendAlert", source, {type="infom", text="You have received a new call.", length=5000, style = { ['background-color'] = '#ffffff', ['color'] = '#000000' }}) 429 | end 430 | end 431 | end 432 | end) 433 | 434 | RegisterServerEvent("mdt:attachToCall") 435 | AddEventHandler("mdt:attachToCall", function(index) 436 | local usource = source 437 | local charname = GetCharacterName(usource) 438 | local xPlayers = QBCore.Functions.GetPlayers() 439 | for i= 1, #xPlayers do 440 | local source = xPlayers[i] 441 | local xPlayer = QBCore.Functions.GetPlayer(source) 442 | if xPlayer.PlayerData.job.name == 'police' then 443 | TriggerClientEvent("mdt:newCallAttach", source, index, charname) 444 | end 445 | end 446 | TriggerClientEvent("mdt:sendNotification", usource, "You have attached to this call.") 447 | end) 448 | 449 | RegisterServerEvent("mdt:detachFromCall") 450 | AddEventHandler("mdt:detachFromCall", function(index) 451 | local usource = source 452 | local charname = GetCharacterName(usource) 453 | local xPlayers = QBCore.Functions.GetPlayers() 454 | for i= 1, #xPlayers do 455 | local source = xPlayers[i] 456 | local xPlayer = QBCore.Functions.GetPlayer(source) 457 | if xPlayer.PlayerData.job.name == 'police' then 458 | TriggerClientEvent("mdt:newCallDetach", source, index, charname) 459 | end 460 | end 461 | TriggerClientEvent("mdt:sendNotification", usource, "You have detached from this call.") 462 | end) 463 | 464 | RegisterServerEvent("mdt:editCall") 465 | AddEventHandler("mdt:editCall", function(index, details) 466 | local usource = source 467 | local xPlayers = QBCore.Functions.GetPlayers() 468 | for i= 1, #xPlayers do 469 | local source = xPlayers[i] 470 | local xPlayer = QBCore.Functions.GetPlayer(source) 471 | if xPlayer.PlayerData.job.name == 'police' then 472 | TriggerClientEvent("mdt:editCall", source, index, details) 473 | end 474 | end 475 | TriggerClientEvent("mdt:sendNotification", usource, "You have edited this call.") 476 | end) 477 | 478 | RegisterServerEvent("mdt:deleteCall") 479 | AddEventHandler("mdt:deleteCall", function(index) 480 | local usource = source 481 | local xPlayers = QBCore.Functions.GetPlayers() 482 | for i= 1, #xPlayers do 483 | local source = xPlayers[i] 484 | local xPlayer = QBCore.Functions.GetPlayer(source) 485 | if xPlayer.PlayerData.job.name == 'police' then 486 | TriggerClientEvent("mdt:deleteCall", source, index) 487 | end 488 | end 489 | TriggerClientEvent("mdt:sendNotification", usource, "You have deleted this call.") 490 | end) 491 | 492 | RegisterServerEvent("mdt:saveVehicleChanges") 493 | AddEventHandler("mdt:saveVehicleChanges", function(data) 494 | if data.stolen then data.stolen = 1 else data.stolen = 0 end 495 | local usource = source 496 | exports.oxmysql:fetch('SELECT * FROM `vehicle_mdt` WHERE `plate` = ?', {data.plate}, function(result) 497 | if result[1] then 498 | exports.oxmysql:execute('UPDATE `vehicle_mdt` SET `stolen` = ?, `notes` = ? WHERE `plate` = ?', {data.plate, data.stolen, data.notes}) 499 | else 500 | exports.oxmysql:insert('INSERT INTO `vehicle_mdt` (`plate`, `stolen`, `notes`) VALUES (?, ?, ?)', {data.plate, data.stolen, data.notes}) 501 | end 502 | 503 | TriggerClientEvent("mdt:sendNotification", usource, "Vehicle changes have been saved.") 504 | end) 505 | end) 506 | 507 | function GetLicenses(identifier, cb) 508 | local player = QBCore.Functions.GetPlayerByCitizenId(identifier) 509 | if player ~= nil then 510 | local playerlicenses = player.PlayerData.metadata["licences"] 511 | local licenses = {} 512 | 513 | for type,_ in pairs(playerlicenses) do 514 | if playerlicenses[type] then 515 | local licenseType = nil 516 | local label = nil 517 | 518 | if type == "driver" then 519 | licenseType = "driver_license" label = "Drivers License" 520 | elseif type == "weapon" then 521 | licenseType = "weapon_license" label = "Weapons License" 522 | end 523 | 524 | table.insert(licenses, { 525 | type = licenseType, 526 | label = label 527 | }) 528 | end 529 | end 530 | cb(licenses) 531 | else 532 | cb(false) 533 | end 534 | end 535 | 536 | function GetCharacterName(source) 537 | local xPlayer = QBCore.Functions.GetPlayer(source) 538 | if xPlayer then 539 | return xPlayer.PlayerData.charinfo.firstname 540 | end 541 | end 542 | 543 | function tprint (tbl, indent) 544 | if not indent then indent = 0 end 545 | local toprint = string.rep(" ", indent) .. "{\r\n" 546 | indent = indent + 2 547 | for k, v in pairs(tbl) do 548 | toprint = toprint .. string.rep(" ", indent) 549 | if (type(k) == "number") then 550 | toprint = toprint .. "[" .. k .. "] = " 551 | elseif (type(k) == "string") then 552 | toprint = toprint .. k .. "= " 553 | end 554 | if (type(v) == "number") then 555 | toprint = toprint .. v .. ",\r\n" 556 | elseif (type(v) == "string") then 557 | toprint = toprint .. "\"" .. v .. "\",\r\n" 558 | elseif (type(v) == "table") then 559 | toprint = toprint .. tprint(v, indent + 2) .. ",\r\n" 560 | else 561 | toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n" 562 | end 563 | end 564 | toprint = toprint .. string.rep(" ", indent-2) .. "}" 565 | return toprint 566 | end 567 | -------------------------------------------------------------------------------- /sv_vehcolors.lua: -------------------------------------------------------------------------------- 1 | colors = { 2 | ['0'] = "Metallic Black", 3 | ['1'] = "Metallic Graphite Black", 4 | ['2'] = "Metallic Black Steel", 5 | ['3'] = "Metallic Dark Silver", 6 | ['4'] = "Metallic Silver", 7 | ['5'] = "Metallic Blue Silver", 8 | ['6'] = "Metallic Steel Gray", 9 | ['7'] = "Metallic Shadow Silver", 10 | ['8'] = "Metallic Stone Silver", 11 | ['9'] = "Metallic Midnight Silver", 12 | ['10'] = "Metallic Gun Metal", 13 | ['11'] = "Metallic Anthracite Grey", 14 | ['12'] = "Matte Black", 15 | ['13'] = "Matte Gray", 16 | ['14'] = "Matte Light Grey", 17 | ['15'] = "Util Black", 18 | ['16'] = "Util Black Poly", 19 | ['17'] = "Util Dark silver", 20 | ['18'] = "Util Silver", 21 | ['19'] = "Util Gun Metal", 22 | ['20'] = "Util Shadow Silver", 23 | ['21'] = "Worn Black", 24 | ['22'] = "Worn Graphite", 25 | ['23'] = "Worn Silver Grey", 26 | ['24'] = "Worn Silver", 27 | ['25'] = "Worn Blue Silver", 28 | ['26'] = "Worn Shadow Silver", 29 | ['27'] = "Metallic Red", 30 | ['28'] = "Metallic Torino Red", 31 | ['29'] = "Metallic Formula Red", 32 | ['30'] = "Metallic Blaze Red", 33 | ['31'] = "Metallic Graceful Red", 34 | ['32'] = "Metallic Garnet Red", 35 | ['33'] = "Metallic Desert Red", 36 | ['34'] = "Metallic Cabernet Red", 37 | ['35'] = "Metallic Candy Red", 38 | ['36'] = "Metallic Sunrise Orange", 39 | ['37'] = "Metallic Classic Gold", 40 | ['38'] = "Metallic Orange", 41 | ['39'] = "Matte Red", 42 | ['40'] = "Matte Dark Red", 43 | ['41'] = "Matte Orange", 44 | ['42'] = "Matte Yellow", 45 | ['43'] = "Util Red", 46 | ['44'] = "Util Bright Red", 47 | ['45'] = "Util Garnet Red", 48 | ['46'] = "Worn Red", 49 | ['47'] = "Worn Golden Red", 50 | ['48'] = "Worn Dark Red", 51 | ['49'] = "Metallic Dark Green", 52 | ['50'] = "Metallic Racing Green", 53 | ['51'] = "Metallic Sea Green", 54 | ['52'] = "Metallic Olive Green", 55 | ['53'] = "Metallic Green", 56 | ['54'] = "Metallic Gasoline Blue Green", 57 | ['55'] = "Matte Lime Green", 58 | ['56'] = "Util Dark Green", 59 | ['57'] = "Util Green", 60 | ['58'] = "Worn Dark Green", 61 | ['59'] = "Worn Green", 62 | ['60'] = "Worn Sea Wash", 63 | ['61'] = "Metallic Midnight Blue", 64 | ['62'] = "Metallic Dark Blue", 65 | ['63'] = "Metallic Saxony Blue", 66 | ['64'] = "Metallic Blue", 67 | ['65'] = "Metallic Mariner Blue", 68 | ['66'] = "Metallic Harbor Blue", 69 | ['67'] = "Metallic Diamond Blue", 70 | ['68'] = "Metallic Surf Blue", 71 | ['69'] = "Metallic Nautical Blue", 72 | ['70'] = "Metallic Bright Blue", 73 | ['71'] = "Metallic Purple Blue", 74 | ['72'] = "Metallic Spinnaker Blue", 75 | ['73'] = "Metallic Ultra Blue", 76 | ['74'] = "Metallic Bright Blue", 77 | ['75'] = "Util Dark Blue", 78 | ['76'] = "Util Midnight Blue", 79 | ['77'] = "Util Blue", 80 | ['78'] = "Util Sea Foam Blue", 81 | ['79'] = "Uil Lightning blue", 82 | ['80'] = "Util Maui Blue Poly", 83 | ['81'] = "Util Bright Blue", 84 | ['82'] = "Matte Dark Blue", 85 | ['83'] = "Matte Blue", 86 | ['84'] = "Matte Midnight Blue", 87 | ['85'] = "Worn Dark blue", 88 | ['86'] = "Worn Blue", 89 | ['87'] = "Worn Light blue", 90 | ['88'] = "Metallic Taxi Yellow", 91 | ['89'] = "Metallic Race Yellow", 92 | ['90'] = "Metallic Bronze", 93 | ['91'] = "Metallic Yellow Bird", 94 | ['92'] = "Metallic Lime", 95 | ['93'] = "Metallic Champagne", 96 | ['94'] = "Metallic Pueblo Beige", 97 | ['95'] = "Metallic Dark Ivory", 98 | ['96'] = "Metallic Choco Brown", 99 | ['97'] = "Metallic Golden Brown", 100 | ['98'] = "Metallic Light Brown", 101 | ['99'] = "Metallic Straw Beige", 102 | ['100'] = "Metallic Moss Brown", 103 | ['101'] = "Metallic Biston Brown", 104 | ['102'] = "Metallic Beechwood", 105 | ['103'] = "Metallic Dark Beechwood", 106 | ['104'] = "Metallic Choco Orange", 107 | ['105'] = "Metallic Beach Sand", 108 | ['106'] = "Metallic Sun Bleeched Sand", 109 | ['107'] = "Metallic Cream", 110 | ['108'] = "Util Brown", 111 | ['109'] = "Util Medium Brown", 112 | ['110'] = "Util Light Brown", 113 | ['111'] = "Metallic White", 114 | ['112'] = "Metallic Frost White", 115 | ['113'] = "Worn Honey Beige", 116 | ['114'] = "Worn Brown", 117 | ['115'] = "Worn Dark Brown", 118 | ['116'] = "Worn straw beige", 119 | ['117'] = "Brushed Steel", 120 | ['118'] = "Brushed Black Steel", 121 | ['119'] = "Brushed Aluminium", 122 | ['120'] = "Chrome", 123 | ['121'] = "Worn Off White", 124 | ['122'] = "Util Off White", 125 | ['123'] = "Worn Orange", 126 | ['124'] = "Worn Light Orange", 127 | ['125'] = "Metallic Securicor Green", 128 | ['126'] = "Worn Taxi Yellow", 129 | ['127'] = "Police Car Blue", 130 | ['128'] = "Matte Green", 131 | ['129'] = "Matte Brown", 132 | ['130'] = "Worn Orange", 133 | ['131'] = "Matte White", 134 | ['132'] = "Worn White", 135 | ['133'] = "Worn Olive Army Green", 136 | ['134'] = "Pure White", 137 | ['135'] = "Hot Pink", 138 | ['136'] = "Salmon pink", 139 | ['137'] = "Metallic Vermillion Pink", 140 | ['138'] = "Orange", 141 | ['139'] = "Green", 142 | ['140'] = "Blue", 143 | ['141'] = "Mettalic Black Blue", 144 | ['142'] = "Metallic Black Purple", 145 | ['143'] = "Metallic Black Red", 146 | ['144'] = "hunter green", 147 | ['145'] = "Metallic Purple", 148 | ['146'] = "Metallic Dark Blue", 149 | ['147'] = "Black", 150 | ['148'] = "Matte Purple", 151 | ['149'] = "Matte Dark Purple", 152 | ['150'] = "Metallic Lava Red", 153 | ['151'] = "Matte Forest Green", 154 | ['152'] = "Matte Olive Drab", 155 | ['153'] = "Matte Desert Brown", 156 | ['154'] = "Matte Desert Tan", 157 | ['155'] = "Matte Foilage Green", 158 | ['156'] = "Default Alloy Color", 159 | ['157'] = "Epsilon Blue", 160 | ['158'] = "Pure Gold", 161 | ['159'] = "Brushed Gold", 162 | ['160'] = "MP100" 163 | } 164 | 165 | types = { 166 | ['car'] = 'Automobile', 167 | ['boat'] = 'Vessel', 168 | ['aircraft'] = 'Aircraft' 169 | } 170 | -------------------------------------------------------------------------------- /ui/badges/police.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matetv/mdt_qbcore/2b33f476bc8c7dbcd8558681c112c4e85a725352/ui/badges/police.png -------------------------------------------------------------------------------- /ui/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matetv/mdt_qbcore/2b33f476bc8c7dbcd8558681c112c4e85a725352/ui/footer.png -------------------------------------------------------------------------------- /ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 16 |
17 |
18 |

San Andreas State Database

19 |

Welcome, {{ officer.rank }}{{ officer.name }}.

20 |
21 | 35 | 36 |
37 |
38 | 39 |

HOME

40 | 41 |
42 |

RECENT REPORTS

43 |
44 |

...

45 | 46 |

{{ result.date }} - ID: {{ result.id }}

47 | 48 |
49 |
50 |
51 | 52 |
53 |

PERSON SEARCHES

54 |
55 |

...

56 | 57 | 58 |
59 |
60 |
61 | 62 |
63 |

RECENT WARRANTS

64 |
65 |

...

66 | 67 |

{{ warrant.date }} - ID: {{ warrant.id }}

68 | 69 |
70 |
71 |
72 | 73 |
74 |

VEHICLE SEARCHES

75 |
76 |

...

77 | 78 | 79 |
80 |
81 |
82 | 83 | 84 |
85 | 86 |
87 | 88 |

SEARCH DATABASE

89 | 90 | 91 | 92 | 93 | 94 | 95 |
96 | 97 |
98 |

DATE

99 |

{{ report_selected.date }}

100 |

...

101 |

NAME

102 |

{{ report_selected.name }}

103 |

...

104 |

INCIDENT #{{ report_selected.id}}

105 |

{{ report_selected.title }}

106 |

...

107 |

CHARGES

108 |

...

109 | 110 |

111 | {{ offense }} (x{{ amount }}) 112 |

113 |
114 |

INCIDENT OFFICER

115 |

{{ report_selected.author }}

116 |

...

117 |
118 | 119 | 120 | 121 | 122 |
123 | 124 |
125 |
126 |

SEARCH RESULTS

127 |

Finding results for '{{ report_results.query }}'...

128 | 129 |

{{ result.date }} - ID: {{ result.id }}

130 | 131 |
132 |
133 |
134 |
135 |
136 | 137 |
138 | 139 |

NEW REPORT

140 | 141 |
142 | 143 |

NAME

144 |

{{ report_new.name }}

145 |

...

146 |

INCIDENT

147 | 148 |

DETAILS

149 | 151 |

CHARGES

152 |

...

153 | 154 |

155 | (-) 156 | {{ offense }} (x{{ amount }}) 157 |

158 |
159 |

Fine: ${{report_new.recommended_fine}}

160 |
161 | 162 | 163 | 164 |
165 |
166 | 167 |
168 |
169 |

SEARCH OFFENDER

170 | 171 | 172 | 173 | 174 | 175 |
176 |

SEARCH RESULTS

177 |

Finding results for '{{ offender_results.query }}'...

178 | 179 | 180 |
181 |
182 |
183 |
184 | 185 |
186 |

SEARCH CHARGES

187 |
188 | 189 | 190 | 191 | 192 | 193 |
194 |
195 |
196 |

Loading charges...

197 |
198 |
199 |
200 | 201 |
202 | 203 |

SEARCH DATABASE

204 | 205 | 206 | 207 | 208 | 209 | 210 |
211 | 212 |
213 |

NAME

214 |

{{ offender_selected.firstname }} {{ offender_selected.lastname }}

215 |

...

216 |

NOTES

217 |

{{ offender_selected.notes }}

218 |

{{ offender_selected.firstname}} {{offender_selected.lastname}} has an active warrant.

219 |

{{ offender_selected.firstname}} {{offender_selected.lastname}} is on bail.

220 |

...

221 |

TELEFON

222 |

{{offender_selected.phone_number}}

223 |

...

224 | 225 | 226 |

NATIONALITÄT

227 |

{{offender_selected.nationality}}

228 |

...

229 | 230 |

BLUTGRUPPE

231 |

{{offender_selected.bloodtype}}

232 |

...

233 | 234 |

FINGERPRINT

235 |

{{offender_selected.fingerprint}}

236 |

...

237 | 238 |

LICENSES

239 |

...

240 | 241 |

{{ license.label }}

242 |
243 |

GEBURTSDATUM

244 |

{{ offender_selected.dateofbirth }}

245 |

...

246 |

VORSTRAFEN

247 |

...

248 | 249 |

{{ name }} x{{ value }}

250 |
251 |
252 | 253 | 254 | 255 |
256 | 257 |
258 |
259 |

SEARCH RESULTS

260 |

Finding results for '{{ offender_results.query }}'...

261 | 262 | 263 |
264 |
265 |
266 | 267 |
268 | BAIL 269 | WARRANT 270 | mugshot 271 | mugshot 272 |
273 |
274 | 275 | 295 | 332 |
333 | 334 |
335 |

REPORT DETAILS

336 |
337 |
338 |

DATE

339 |

{{ report_selected.date }}

340 |

...

341 |

NAME

342 |

{{ report_selected.name }}

343 |

...

344 | 349 | 353 | 358 | 365 |

CHARGES

366 | 367 |

368 | {{ offense }} (x{{ amount }}) 369 |

370 |
371 |

INCIDENT OFFICER

372 |

{{ report_selected.author }}

373 |

...

374 |
375 | 376 | 377 | 378 | 382 |
383 |
384 | 385 |
386 |

ACTIVE WARRANTS

387 | 388 | 389 | 390 |
391 | 392 |
393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 |
NameReportIssue DateExpires
{{warrant.name}}{{warrant.report_title}}{{warrant.date}}{{warrant.expire_time}}
407 |


No warrants found!

408 |
409 | 410 |
411 |
412 |
413 | 414 |
415 |

SEARCH DATABASE

416 | 417 | 418 | 419 | 420 | 421 | 422 |
423 | 424 |
425 |

PLATE

426 |

{{vehicle_selected.plate}}

427 |

...

428 |

TYPE

429 |

{{vehicle_selected.type}}

430 |

...

431 |

NOTES

432 |

{{vehicle_selected.notes}}

433 |

{{vehicle_selected.owner}} has an active warrant.

434 |

{{vehicle_selected.owner}} is on bail.

435 |

This vehicle is flagged as stolen.

436 |

...

437 |

OWNER

438 |

{{vehicle_selected.owner}}

439 |

...

440 |

MODEL

441 |

{{vehicle_selected.model}}

442 |

...

443 |

COLOR

444 |

{{vehicle_selected.color}}

445 |

...

446 | 447 |
448 | 449 | 450 |
451 |
452 |

SEARCH RESULTS

453 |

Finding results for '{{ vehicle_results.query }}'...

454 | 455 | 456 |
457 |
458 |
459 |
460 | 461 | 475 | 476 |
477 | 478 |
479 |

NEW WARRANT

480 | 481 |
482 | 483 |

REPORT

484 |

{{ warrant_new.report_title }}

485 |

...

486 |

NAME

487 |

{{ warrant_new.name }}

488 |

...

489 |

NOTES

490 | 491 |

CHARGES

492 |

...

493 | 494 |

495 | {{ offense }} (x{{ amount }}) 496 |

497 |
498 | 499 |
500 |
501 | 502 |
503 |

SEARCH RESULTS

504 |

SEARCH REPORTS

505 |
506 | 507 | 508 | 509 | 510 |
511 |

Finding results for '{{ warrant_new.report_search }}'...

512 | 513 |

{{ result.date }} - ID: {{ result.id }}

514 | 515 |
516 |
517 |
518 |
519 |
520 | 521 |
522 |

WARRANT DETAILS

523 |
524 |
525 |

DATE

526 |

{{ warrant_selected.date }}

527 |

...

528 |

NAME

529 |

{{ warrant_selected.name }}

530 |

...

531 |

REPORT

532 |

{{ warrant_selected.report_title }}

533 |

...

534 |

NOTES

535 |

{{ warrant_selected.notes }}

536 |

...

537 |

CHARGES

538 | 539 |

540 | {{ offense }} (x{{ amount }}) 541 |

542 |
543 |

AUTHOR

544 |

{{ warrant_selected.author }}

545 |

...

546 |

EXPIRES

547 |

{{ warrant_selected.expire_time }}

548 |

...

549 |
550 | 551 | 552 |
553 |
554 | 555 |
556 |

CALL MONITOR

557 |

No incoming calls.

558 |
559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 584 | 585 |
#CallerDetailsDateLocationNo. AttachedActions
{{index}}{{call.source}}{{call.details}}{{call.time}}{{call.location}}{{attached(index)}} 577 | 578 | 579 | 580 | 581 | 582 | 583 |
586 |
587 | 588 | 606 | 607 | 619 |
620 | 621 | 626 | 627 |
628 |

{{notify}}

629 |
630 |

631 |
632 |
633 |
634 | 635 | 636 | 637 | 642 | 643 | 654 | 655 | 656 | -------------------------------------------------------------------------------- /ui/main.css: -------------------------------------------------------------------------------- 1 | #main { 2 | position: relative; 3 | text-align: center; 4 | top: 5%; 5 | width: 80%; 6 | margin: auto; 7 | } 8 | 9 | #notification h4 { 10 | font-weight: bold; 11 | margin: 0; 12 | color: white !important; 13 | } 14 | 15 | .page-title { 16 | margin-bottom: 30px; 17 | } 18 | .noselect { 19 | user-select: none; 20 | } 21 | .left-side { 22 | float: left; 23 | max-width: 50%; 24 | max-height: 550px; 25 | overflow-y: auto; 26 | margin-left: 5%; 27 | height: auto; 28 | text-align: left; 29 | user-select: none; 30 | } 31 | .right-side { 32 | position: absolute; 33 | left: 75%; 34 | right: 10%; 35 | width: 35%; 36 | max-width: 300%; 37 | max-height: 550px; 38 | overflow-y: auto; 39 | height: auto; 40 | text-align: left; 41 | user-select: none; 42 | } 43 | .modal { 44 | position: fixed; /* Stay in place */ 45 | z-index: 1; /* Sit on top */ 46 | left: 0; 47 | top: 0; 48 | width: 100%; /* Full width */ 49 | height: 100%; /* Full height */ 50 | overflow: auto; /* Enable scroll if needed */ 51 | background-color: rgb(0, 0, 0); /* Fallback color */ 52 | background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */ 53 | border-radius: 5px; 54 | } 55 | .nav-active { 56 | opacity: 0.5; 57 | } 58 | 59 | .ellipsis { 60 | position: relative; 61 | width: 200px; 62 | } 63 | .ellipsis:before { 64 | content: " "; 65 | visibility: hidden; 66 | width: 200px; 67 | } 68 | .ellipsis span { 69 | position: absolute; 70 | left: 0; 71 | right: 0; 72 | white-space: nowrap; 73 | overflow: hidden; 74 | text-overflow: ellipsis; 75 | margin: 0 10px; 76 | width: 200px; 77 | } 78 | .remove { 79 | color: red; 80 | font-weight: all; 81 | } 82 | br { 83 | user-select: none; 84 | } 85 | p { 86 | font-family: "Courier"; 87 | color: #dcdcdc; 88 | } 89 | ul { 90 | list-style-type: none; 91 | margin: 0; 92 | padding: 0; 93 | overflow: hidden; 94 | } 95 | input:focus { 96 | outline: none; 97 | } 98 | button:focus { 99 | outline: none; 100 | } 101 | ::-webkit-scrollbar { 102 | width: 5px; 103 | height: 5px; 104 | } 105 | ::-webkit-scrollbar-track { 106 | box-shadow: inset 0 0 5px grey; 107 | border-radius: 5px; 108 | } -------------------------------------------------------------------------------- /ui/mugshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matetv/mdt_qbcore/2b33f476bc8c7dbcd8558681c112c4e85a725352/ui/mugshot.png -------------------------------------------------------------------------------- /ui/script.js: -------------------------------------------------------------------------------- 1 | const mdtApp = new Vue({ 2 | el: "#container", 3 | data: { 4 | page: "Home", 5 | officer: { 6 | name: "Guest", 7 | department: "police", 8 | rank: '' 9 | }, 10 | style: { 11 | police: true 12 | }, 13 | 14 | offenses: [], 15 | modal: null, 16 | notify: null, 17 | 18 | homepage: { 19 | button_press: 0, 20 | reports: false, 21 | warrants: false 22 | }, 23 | recent_searches: { 24 | person: [], 25 | vehicle: [] 26 | }, 27 | 28 | report_search: "", 29 | report_edit: { 30 | enable: false, 31 | data: {} 32 | }, 33 | report_results: { 34 | query: "", 35 | results: false 36 | }, 37 | report_selected: { 38 | id: null, 39 | date: null, 40 | name: null, 41 | title: null, 42 | incident: null, 43 | charges: null, 44 | author: null, 45 | jailtime: null 46 | }, 47 | report_new: { 48 | title: "", 49 | charges: {}, 50 | charges_search: "", 51 | incident: "", 52 | name: null, 53 | char_id: null, 54 | focus: "name", 55 | recommended_fine: 0, 56 | }, 57 | 58 | calls: {}, 59 | current_call: { 60 | source: null, 61 | details: null, 62 | id: null, 63 | time: null, 64 | officers: null, 65 | coords: null, 66 | location: null 67 | }, 68 | selected_call: null, 69 | edit_call: { 70 | details: "", 71 | index: null 72 | }, 73 | 74 | offender_search: "", 75 | offender_results: { 76 | query: "", 77 | results: false 78 | }, 79 | offender_selected: { 80 | firstname: null, 81 | lastname: null, 82 | notes: "", 83 | licenses: false, 84 | properties: {}, 85 | phone_number: null, 86 | bloodtype: null, 87 | fingerprint: null, 88 | nationality: null, 89 | convictions: null, 90 | mugshot_url: "", 91 | dateofbirth: null, 92 | id: null, 93 | identifier: null, 94 | haswarrant: false, 95 | vehicles: {} 96 | }, 97 | offender_changes: { 98 | notes: "", 99 | mugshot_url: "", 100 | licenses: [], 101 | licenses_removed: [], 102 | convictions: [], 103 | convictions_removed: [], 104 | bail: false 105 | }, 106 | 107 | vehicle_search: "", 108 | vehicle_results: { 109 | query: "", 110 | results: false 111 | }, 112 | vehicle_selected: { 113 | plate: null, 114 | type: null, 115 | owner: null, 116 | owner_id: null, 117 | model: null, 118 | color: null 119 | }, 120 | edit_vehicle: { 121 | stolen: false, 122 | notes: "" 123 | }, 124 | 125 | warrants: [], 126 | warrant_search: "", 127 | warrant_results: { 128 | query: "", 129 | results: {} 130 | }, 131 | warrant_selected: { 132 | name: null, 133 | id: null, 134 | char_id: null, 135 | report_id: null, 136 | report_title: null, 137 | report_charges: {}, 138 | date: null, 139 | expire: null, 140 | notes: null 141 | }, 142 | warrant_new: { 143 | name: null, 144 | char_id: null, 145 | report_id: null, 146 | report_title: null, 147 | report_search: "", 148 | charges: {}, 149 | notes: null 150 | } 151 | }, 152 | methods: { 153 | changePage(page) { 154 | this.page = page; 155 | ClearActiveNavItems(); 156 | if (page == "Home") { 157 | $("#home").addClass("nav-active"); 158 | } else if (page == "Search Reports") { 159 | $("#search-reports").addClass("nav-active"); 160 | } else if (page == "Search Offenders") { 161 | $("#search-offenders").addClass("nav-active"); 162 | } else if (page == "Search Vehicles") { 163 | $("#search-vehicles").addClass("nav-active"); 164 | } else if (page == "Warrants") { 165 | $.post('http://mdt/getWarrants'); 166 | $("#warrants").addClass("nav-active"); 167 | } else if (page == "Submit Report") { 168 | $("#submit-report").addClass("nav-active"); 169 | } else if (page == "Calls") { 170 | $('#calls').addClass('nav-active'); 171 | $.post('http://mdt/getCalls'); 172 | } 173 | }, 174 | closeMDT() { 175 | $.post('http://mdt/close', JSON.stringify({})); 176 | }, 177 | getClass(element) { 178 | if (this.style.police) { 179 | return element 180 | } 181 | }, 182 | OffenderSearch() { 183 | if (this.offender_search) { 184 | 185 | this.offender_results.query = this.offender_search; 186 | $.post('http://mdt/performOffenderSearch', JSON.stringify({ 187 | query: this.offender_search 188 | })); 189 | 190 | this.offender_results.results = false; 191 | return; 192 | } 193 | }, 194 | OpenOffenderDetails(id) { 195 | for (var key in this.offender_results.results) { 196 | if (id == this.offender_results.results[key].id) { 197 | 198 | $.post('http://mdt/viewOffender', JSON.stringify({ 199 | offender: this.offender_results.results[key] 200 | })); 201 | 202 | this.modal = 'loading'; 203 | 204 | return; 205 | } 206 | } 207 | }, 208 | SaveOffenderChanges() { 209 | $.post('http://mdt/saveOffenderChanges', JSON.stringify({ 210 | changes: this.offender_changes, 211 | id: this.offender_selected.id, 212 | identifier: this.offender_selected.identifier 213 | })); 214 | this.modal = null; 215 | this.offender_selected.notes = this.offender_changes.notes; 216 | this.offender_selected.mugshot_url = this.offender_changes.mugshot_url; 217 | this.offender_selected.licenses = this.offender_changes.licenses; 218 | this.offender_selected.convictions = this.offender_changes.convictions; 219 | this.offender_selected.bail = this.offender_changes.bail; 220 | return; 221 | }, 222 | ReportSearch() { 223 | if (this.report_search) { 224 | 225 | this.report_results.query = this.report_search 226 | this.warrant_new.report_search = this.report_search 227 | $.post('http://mdt/performReportSearch', JSON.stringify({ 228 | query: this.report_search 229 | })); 230 | 231 | this.report_results.results = false; 232 | this.report_selected = { 233 | id: null, 234 | date: null, 235 | name: null, 236 | title: null, 237 | report: null, 238 | charges: null, 239 | author: null 240 | }; 241 | return; 242 | } 243 | }, 244 | AddCharge(id) { 245 | for (var key in this.offenses) { 246 | if (id == this.offenses[key].id) { 247 | var offense_name = this.offenses[key].label 248 | if (this.report_new.charges[offense_name]) { 249 | Vue.set(this.report_new.charges, offense_name, this.report_new.charges[offense_name] + 1); 250 | } else { 251 | Vue.set(this.report_new.charges, offense_name, 1); 252 | } 253 | 254 | this.report_new.recommended_fine = this.report_new.recommended_fine + this.offenses[key].amount 255 | 256 | return; 257 | } 258 | } 259 | 260 | }, 261 | RemoveCharge(offense) { 262 | for (var key in this.report_new.charges) { 263 | if (offense == key) { 264 | if ((this.report_new.charges[offense] - 1) > 0) { 265 | Vue.set(this.report_new.charges, offense, this.report_new.charges[offense] - 1) 266 | } else { 267 | Vue.delete(this.report_new.charges, offense) 268 | } 269 | 270 | for (var key in this.offenses) { 271 | if (offense == this.offenses[key].label) { 272 | this.report_new.recommended_fine = this.report_new.recommended_fine - this.offenses[key].amount 273 | } 274 | } 275 | 276 | return; 277 | } 278 | } 279 | }, 280 | SubmitNewReport() { 281 | if (this.report_new.title && this.report_new.char_id && this.report_new.incident) { 282 | $.post('http://mdt/submitNewReport', JSON.stringify({ 283 | title: this.report_new.title, 284 | char_id: this.report_new.char_id, 285 | name: this.report_new.name, 286 | charges: this.report_new.charges, 287 | incident: this.report_new.incident, 288 | })); 289 | 290 | this.report_new.title = ""; 291 | this.report_new.charges = {}; 292 | this.report_new.charges_search = ""; 293 | this.report_new.incident = ""; 294 | this.report_new.name = null; 295 | this.report_new.char_id = null; 296 | this.report_new.focus = "name"; 297 | this.report_new.recommended_fine = 0; 298 | this.offender_search = ""; 299 | this.offender_results.query = ""; 300 | this.offender_results.results = false; 301 | this.changePage("Search Reports"); 302 | return; 303 | } 304 | }, 305 | OpenOffenderDetailsById(id) { 306 | $.post('http://mdt/getOffender', JSON.stringify({ 307 | char_id: id 308 | })); 309 | 310 | this.modal = 'loading'; 311 | return; 312 | }, 313 | ToggleReportEdit() { 314 | if (this.report_edit.enable) { 315 | this.report_edit.enable = false; 316 | this.report_edit.data = {} 317 | } else { 318 | this.report_edit.enable = true; 319 | this.report_edit.data.title = this.report_selected.title; 320 | this.report_edit.data.incident = this.report_selected.incident; 321 | } 322 | return; 323 | }, 324 | DeleteSelectedReport() { 325 | $.post('http://mdt/deleteReport', JSON.stringify({ 326 | id: this.report_selected.id, 327 | })); 328 | this.changePage("Search Reports"); 329 | this.report_selected = { 330 | id: null, 331 | date: null, 332 | name: null, 333 | title: null, 334 | report: null, 335 | charges: null, 336 | author: null 337 | }; 338 | this.report_results = { 339 | query: "", 340 | results: false 341 | }; 342 | this.report_search = ""; 343 | return; 344 | }, 345 | SaveReportEditChanges() { 346 | $.post('http://mdt/saveReportChanges', JSON.stringify({ 347 | id: this.report_selected.id, 348 | title: this.report_edit.data.title, 349 | incident: this.report_edit.data.incident 350 | })); 351 | 352 | this.report_selected.title = this.report_edit.data.title; 353 | this.report_selected.incident = this.report_edit.data.incident; 354 | this.ToggleReportEdit(); 355 | return; 356 | }, 357 | VehicleSearch() { 358 | if (this.vehicle_search) { 359 | 360 | this.vehicle_results.query = this.vehicle_search; 361 | $.post('http://mdt/vehicleSearch', JSON.stringify({ 362 | plate: this.vehicle_search 363 | })); 364 | 365 | this.vehicle_results.results = false; 366 | return; 367 | } 368 | }, 369 | OpenVehicleDetails(result) { 370 | $.post('http://mdt/getVehicle', JSON.stringify({ 371 | vehicle: result 372 | })); 373 | 374 | this.modal = 'loading'; 375 | return; 376 | }, 377 | WarrantReportSearch() { 378 | if (this.warrant_new.report_search) { 379 | 380 | this.report_results.query = this.report_search 381 | $.post('http://mdt/performReportSearch', JSON.stringify({ 382 | query: this.report_search 383 | })); 384 | 385 | this.report_results.results = false; 386 | this.report_selected = { 387 | id: null, 388 | date: null, 389 | name: null, 390 | title: null, 391 | report: null, 392 | charges: null, 393 | author: null 394 | }; 395 | return; 396 | } 397 | }, 398 | SubmitNewWarrant() { 399 | var date = new Date(); 400 | date.setDate(date.getDate() + 7); 401 | $.post('http://mdt/submitNewWarrant', JSON.stringify({ 402 | name: this.warrant_new.name, 403 | char_id: this.warrant_new.char_id, 404 | report_id: this.warrant_new.report_id, 405 | report_title: this.warrant_new.report_title, 406 | charges: this.warrant_new.charges, 407 | notes: this.warrant_new.notes, 408 | expire: date 409 | })); 410 | this.warrant_new = { 411 | name: null, 412 | char_id: null, 413 | report_id: null, 414 | report_title: null, 415 | report_search: "", 416 | charges: {}, 417 | notes: null 418 | } 419 | this.report_results.results = false; 420 | this.report_results.query = ""; 421 | return; 422 | }, 423 | DeleteSelectedWarrant() { 424 | $.post('http://mdt/deleteWarrant', JSON.stringify({ 425 | id: this.warrant_selected.id, 426 | })); 427 | this.warrant_selected = { 428 | name: null, 429 | id: null, 430 | char_id: null, 431 | report_id: null, 432 | report_title: null, 433 | report_charges: {}, 434 | date: null, 435 | expire: null, 436 | notes: null 437 | }; 438 | return; 439 | }, 440 | OpenReportById(id) { 441 | $.post('http://mdt/getReport', JSON.stringify({ 442 | id: id 443 | })); 444 | this.modal = 'loading'; 445 | return; 446 | }, 447 | RemoveLicense(license) { 448 | for (var key in this.offender_selected.licenses) { 449 | var license2 = this.offender_selected.licenses[key] 450 | if (license.label == license2.label) { 451 | Vue.delete(this.offender_changes.licenses, key) 452 | this.offender_changes.licenses_removed.push(license) 453 | } 454 | } 455 | }, 456 | RemoveConviction(conviction) { 457 | for (var offense in this.offender_changes.convictions) { 458 | if (offense == conviction) { 459 | if ((this.offender_changes.convictions[offense] - 1) > 0) { 460 | Vue.set(this.offender_changes.convictions, offense, this.offender_changes.convictions[offense] - 1) 461 | } else { 462 | Vue.delete(this.offender_changes.convictions, offense) 463 | this.offender_changes.convictions_removed.push(offense) 464 | } 465 | } 466 | } 467 | }, 468 | AttachToCall(index) { 469 | $.post('http://mdt/attachToCall', JSON.stringify({ 470 | index: index, 471 | coords: this.calls[index].coords 472 | })); 473 | this.current_call = this.calls[index] 474 | return; 475 | }, 476 | DetachFromCall(index) { 477 | $.post('http://mdt/detachFromCall', JSON.stringify({ 478 | index: index 479 | })); 480 | this.current_call = { 481 | source: null, 482 | details: null, 483 | id: null, 484 | time: null, 485 | officers: null, 486 | coords: null, 487 | location: null 488 | } 489 | return; 490 | }, 491 | SetCallWaypoint(index) { 492 | $.post('http://mdt/setCallWaypoint', JSON.stringify({ 493 | coords: this.calls[index].coords 494 | })); 495 | return; 496 | }, 497 | ShowCallDetails(index) { 498 | this.modal = "call_details"; 499 | this.selected_call = index; 500 | return; 501 | }, 502 | EditCall(index){ 503 | this.modal = 'edit_call'; 504 | this.edit_call.details = this.current_call.details; 505 | this.edit_call.index = index; 506 | return; 507 | }, 508 | SaveEditCall() { 509 | $.post('http://mdt/editCall', JSON.stringify({ 510 | index: this.edit_call.index, 511 | details: this.edit_call.details 512 | })); 513 | this.modal = null; 514 | this.edit_call.details = ""; 515 | this.edit_call.index = null; 516 | return; 517 | }, 518 | DeleteCall(index) { 519 | $.post('http://mdt/deleteCall', JSON.stringify({ 520 | index: index 521 | })); 522 | return; 523 | }, 524 | showNotification(message) { 525 | this.notify = message; 526 | $('#notification').show('fast', 'swing'); 527 | setTimeout(function(){ 528 | $('#notification').hide('fast', 'swing'); 529 | }, 2500); 530 | return; 531 | }, 532 | SaveVehicleEditChanges() { 533 | $.post('http://mdt/saveVehicleChanges', JSON.stringify({ 534 | plate: this.vehicle_selected.plate, 535 | stolen: this.edit_vehicle.stolen, 536 | notes: this.edit_vehicle.notes 537 | })) 538 | 539 | this.vehicle_selected.stolen = this.edit_vehicle.stolen; 540 | this.vehicle_selected.notes = this.edit_vehicle.notes; 541 | this.edit_vehicle = { 542 | stolen: false, 543 | notes: "" 544 | }; 545 | this.modal = null; 546 | return; 547 | }, 548 | attached: function(index) { 549 | return Object.keys(this.calls[index].officers).length 550 | } 551 | }, 552 | computed: { 553 | filtered_offenses() { 554 | return this.offenses.filter(offense => { 555 | if ( 556 | offense.label.toLowerCase().search(this.report_new.charges_search.toLowerCase()) != -1 557 | ) 558 | return offense; 559 | }) 560 | }, 561 | filtered_warrants() { 562 | return this.warrants.filter(warrant => { 563 | if ( 564 | warrant.name.toLowerCase().search(this.warrant_search.toLowerCase()) != -1 565 | ) 566 | return warrant; 567 | }) 568 | } 569 | } 570 | }); 571 | 572 | $("#home").addClass("nav-active"); 573 | 574 | document.onreadystatechange = () => { 575 | if (document.readyState === "complete") { 576 | window.addEventListener('message', function(event) { 577 | if (event.data.type == "enable") { 578 | document.body.style.display = event.data.isVisible ? "block" : "none"; 579 | } else if (event.data.type == "returnedPersonMatches") { 580 | mdtApp.offender_results.results = event.data.matches; 581 | } else if (event.data.type == "returnedOffenderDetails") { 582 | mdtApp.offender_selected = event.data.details; 583 | mdtApp.offender_results.results = false; 584 | mdtApp.offender_results.query = ""; 585 | mdtApp.offender_changes.notes = mdtApp.offender_selected.notes; 586 | mdtApp.offender_changes.mugshot_url = mdtApp.offender_selected.mugshot_url; 587 | mdtApp.offender_changes.licenses = mdtApp.offender_selected.licenses; 588 | mdtApp.offender_changes.licenses_removed = []; 589 | mdtApp.offender_changes.convictions = mdtApp.offender_selected.convictions; 590 | mdtApp.offender_changes.convictions_removed = []; 591 | mdtApp.offender_changes.bail = mdtApp.offender_selected.bail; 592 | mdtApp.offender_search = mdtApp.offender_selected.firstname + " " + mdtApp.offender_selected.lastname; 593 | mdtApp.changePage("Search Offenders"); 594 | 595 | mdtApp.recent_searches.person.unshift(event.data.details); 596 | if (mdtApp.recent_searches.person.length > 3) { 597 | Vue.delete(mdtApp.recent_searches.person, 3) 598 | } 599 | 600 | mdtApp.modal = null; 601 | } else if (event.data.type == "offensesAndOfficerLoaded") { 602 | mdtApp.offenses = event.data.offenses; 603 | mdtApp.officer.name = event.data.name; 604 | } else if (event.data.type == "returnedReportMatches") { 605 | mdtApp.report_results.results = event.data.matches; 606 | } else if (event.data.type == "returnedVehicleMatches") { 607 | mdtApp.vehicle_results.results = event.data.matches; 608 | mdtApp.vehicle_selected = { 609 | plate: null, 610 | type: null, 611 | owner: null, 612 | owner_id: null, 613 | model: null, 614 | color: null 615 | }; 616 | } else if (event.data.type == "returnedVehicleDetails") { 617 | mdtApp.vehicle_selected = event.data.details; 618 | mdtApp.vehicle_search = mdtApp.vehicle_selected.plate; 619 | 620 | mdtApp.recent_searches.vehicle.unshift(event.data.details); 621 | if (mdtApp.recent_searches.vehicle.length > 3) { 622 | Vue.delete(mdtApp.recent_searches.vehicle, 3) 623 | } 624 | mdtApp.changePage("Search Vehicles"); 625 | 626 | mdtApp.modal = null; 627 | } else if (event.data.type == "returnedVehicleMatchesInFront") { 628 | mdtApp.vehicle_results.results = event.data.matches; 629 | mdtApp.vehicle_results.query = event.data.plate; 630 | mdtApp.vehicle_search = event.data.plate; 631 | mdtApp.vehicle_selected = { 632 | plate: null, 633 | type: null, 634 | owner: null, 635 | owner_id: null, 636 | model: null, 637 | color: null 638 | }; 639 | mdtApp.changePage("Search Vehicles"); 640 | } else if (event.data.type == "returnedWarrants") { 641 | mdtApp.warrants = event.data.warrants; 642 | } else if (event.data.type == "completedWarrantAction") { 643 | mdtApp.changePage("Warrants"); 644 | } else if (event.data.type == "returnedReportDetails") { 645 | mdtApp.changePage("Search Reports"); 646 | mdtApp.report_selected = event.data.details; 647 | 648 | mdtApp.modal = null; 649 | } else if (event.data.type == "recentReportsAndWarrantsLoaded") { 650 | mdtApp.homepage.reports = event.data.reports; 651 | mdtApp.homepage.warrants = event.data.warrants; 652 | mdtApp.officer.name = event.data.officer; 653 | mdtApp.officer.rank = event.data.rank + ' '; 654 | if (mdtApp.officer.department != event.data.department) { 655 | mdtApp.officer.department = event.data.department; 656 | if (event.data.department == 'police') { 657 | mdtApp.style.police = true; 658 | } 659 | } 660 | } else if (event.data.type == "sendNotification") { 661 | mdtApp.showNotification(event.data.message); 662 | } else if (event.data.type == "newCall") { 663 | var today = new Date(); 664 | var time = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate() + " " + today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds(); 665 | var call = { 666 | source: event.data.source, 667 | id: event.data.id, 668 | details: event.data.details, 669 | coords: event.data.coords, 670 | location: event.data.location, 671 | time: time, 672 | officers: [] 673 | } 674 | Vue.set(mdtApp.calls, event.data.id, call) 675 | } else if (event.data.type == "newCallAttach") { 676 | mdtApp.calls[event.data.call].officers.push(event.data.charname) 677 | } else if (event.data.type == "newCallDetach") { 678 | var i = mdtApp.calls[event.data.call].officers.length 679 | while (i--) { 680 | if (mdtApp.calls[event.data.call].officers[i] == event.data.charname) { 681 | mdtApp.calls[event.data.call].officers.splice(i, 1); 682 | } 683 | } 684 | } else if (event.data.type == "editCall") { 685 | mdtApp.calls[event.data.call].details = event.data.details; 686 | } else if (event.data.type == "deleteCall") { 687 | if (mdtApp.current_call.id == mdtApp.calls[event.data.call].id) { 688 | $.post('http://mdt/deleteCallBlip') 689 | mdtApp.current_call = { 690 | source: null, 691 | details: null, 692 | id: null, 693 | time: null, 694 | officers: null, 695 | coords: null, 696 | location: null 697 | } 698 | } 699 | Vue.delete(mdtApp.calls, event.data.call) 700 | } else if (event.data.type == "closeModal") { 701 | mdtApp.modal = null; 702 | }; 703 | }); 704 | }; 705 | }; 706 | 707 | document.onkeydown = function (data) { 708 | if (data.which == 27 || data.which == 112) { // ESC or F1 709 | $.post('http://mdt/close', JSON.stringify({})); 710 | } else if (data.which == 13) { // enter 711 | /* stop enter key from crashing MDT in an input? */ 712 | var textarea = document.getElementsByTagName('textarea'); 713 | if (!$(textarea).is(':focus')) { 714 | return false; 715 | } 716 | } 717 | }; 718 | 719 | function ClearActiveNavItems() { 720 | $("#home").removeClass("nav-active"); 721 | $("#search-reports").removeClass("nav-active"); 722 | $("#search-offenders").removeClass("nav-active"); 723 | $("#search-vehicles").removeClass("nav-active"); 724 | $("#warrants").removeClass("nav-active"); 725 | $("#submit-report").removeClass("nav-active"); 726 | $("#calls").removeClass("nav-active"); 727 | } 728 | 729 | function WarrantTimer() { 730 | var timer = setInterval(function() { 731 | for (var key in mdtApp.warrants) { 732 | var warrant = mdtApp.warrants[key] 733 | var now = new Date().getTime(); 734 | var expire_time = new Date(warrant.expire).getTime(); 735 | var t = expire_time - now; 736 | if (t >= 0) { 737 | var days = Math.floor(t / (1000 * 60 * 60 * 24)); 738 | var hours = Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); 739 | var mins = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60)); 740 | var secs = Math.floor((t % (1000 * 60)) / 1000); 741 | warrant.expire_time = days + 'd ' + hours + 'h ' + mins + 'm ' + secs + 's'; 742 | } else { 743 | warrant.expire_time = 'EXPIRED'; 744 | $.post('http://mdt/deleteWarrant', JSON.stringify({ 745 | id: warrant.id 746 | })); 747 | Vue.delete(mdtApp.warrants, key) 748 | } 749 | } 750 | }, 1000); 751 | } 752 | 753 | WarrantTimer() 754 | -------------------------------------------------------------------------------- /ui/styles/police.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@100&display=swap"); 2 | 3 | * { 4 | font-family: "Poppins", sans-serif; 5 | } 6 | .content { 7 | position: absolute; 8 | border-radius: 5px; 9 | width: 75%; 10 | height: 80%; 11 | top: 50%; 12 | left: 50%; 13 | transform: translate(-50%, -50%); 14 | background-color: #324558; 15 | box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.2) inset, 16 | 1px 1px 6px 1px rgba(0, 0, 0, 0.2); 17 | } 18 | /*HOME*/ 19 | .content h2 { 20 | font-family: "Poppins"; 21 | font-style: medium; 22 | font-weight: 700; 23 | user-select: none; 24 | color: #dcdcdc; 25 | margin: 1px 1px 1px 1px; 26 | } 27 | /*Home page Text*/ 28 | .content h3 { 29 | font-family: "Poppins"; 30 | user-select: none; 31 | font-weight: bolder; 32 | color: #ffbb24; 33 | margin: 1px 1px 1px 1px; 34 | } 35 | /*SubText for calls and warrants*/ 36 | .content h4 { 37 | font-family: "Poppins"; 38 | font-weight: bolder; 39 | font-size: 14px; 40 | user-select: none; 41 | color: white; 42 | margin: 1px 1px 10px 1px; 43 | } 44 | 45 | /*Sidebar text*/ 46 | .content li { 47 | font-family: "Poppins"; 48 | font-weight: 780; 49 | color: #dcdcdc; 50 | float: bottom; 51 | padding-top: 25px; 52 | padding-bottom: 25px; 53 | font-size: 14px; 54 | } 55 | .content li:last-child { 56 | border-right: none; 57 | } 58 | .content button { 59 | background-color: #2d3139; 60 | color: #dcdcdc; 61 | font-family: "Poppins"; 62 | font-weight: bolder; 63 | border: 5px solid #2d3139; 64 | font-size: 12pt; 65 | text-align: center; 66 | padding: 4px 2px; 67 | } 68 | .content input { 69 | background-color: #202020; 70 | font-family: "Courier New"; 71 | border: 2px solid #383838; 72 | color: #dcdcdc; 73 | font-size: 12pt; 74 | padding: 7px 15px 5px 15px; 75 | margin-top: 5px; 76 | margin-bottom: 5px; 77 | text-overflow: ellipsis; 78 | text-align: left; 79 | } 80 | .content textarea { 81 | background-color: #202020; 82 | white-space: pre-line; 83 | white-space: pre-wrap; 84 | font-family: "Courier New"; 85 | font-weight: bolder; 86 | font-size: 14px; 87 | border: 2px solid #383838; 88 | color: #dcdcdc; 89 | font-size: 12pt; 90 | padding: 0px 0px 0px 0px; 91 | width: 550px; 92 | margin-top: 5px; 93 | margin-bottom: 5px; 94 | text-overflow: ellipsis; 95 | text-align: left; 96 | outline: none; 97 | } 98 | .content th { 99 | font-family: "Courier New"; 100 | font-weight: bolder; 101 | font-size: 14px; 102 | color: #dcdcdc; 103 | padding: 5px 10px; 104 | text-align: center; 105 | border-bottom: 3px solid #383838; 106 | } 107 | .content td { 108 | font-family: "Courier New"; 109 | font-size: 14px; 110 | color: #dcdcdc; 111 | padding: 10px; 112 | text-align: center; 113 | border-top: 1px solid #383838; 114 | } 115 | .content table { 116 | border-collapse: collapse; 117 | column-gap: 3px solid #383838; 118 | } 119 | .content table td + td { 120 | border-left: 2px solid #383838; 121 | } 122 | .content table th + th { 123 | border-left: 2px solid #383838; 124 | } 125 | .content tr:not(:first-child):hover { 126 | background-color: #295f56; 127 | } 128 | .content button:hover { 129 | background-color: #ffbb24; 130 | border-color: #ffbb24; 131 | } 132 | .content ::-webkit-scrollbar-thumb { 133 | background: #585858; 134 | border-radius: 5px; 135 | } 136 | .badge { 137 | position: fixed; 138 | display: inline-block; 139 | left: 3.245%; 140 | top: 1.5%; 141 | max-width: 150px; 142 | height: auto; 143 | } 144 | .mugshot { 145 | display: inline-block; 146 | max-width: 215px; 147 | height: auto; 148 | border: 2px solid #585858; 149 | user-select: none; 150 | } 151 | .notification { 152 | display: none; 153 | z-index: 1; 154 | position: fixed; 155 | top: 1%; 156 | right: 0%; 157 | max-width: 25%; 158 | padding: 15px; 159 | background-color: #202020; 160 | border-bottom: 2px solid #ffbb24; 161 | } 162 | .report-input { 163 | font-family: "Courier New"; 164 | border-width: 0px; 165 | border: none; 166 | color: #dcdcdc; 167 | font-size: 12pt; 168 | padding: 0px 0px 0px 0px; 169 | width: 550px; 170 | margin-right: 10px; 171 | text-overflow: ellipsis; 172 | text-align: left; 173 | font-weight: bolder; 174 | } 175 | 176 | .wrapper { 177 | display: flex; 178 | position: relative; 179 | } 180 | 181 | .content .sidebar { 182 | background: #324558; 183 | width: 12%; 184 | height: 100%; 185 | } 186 | 187 | .content .sidebar h2 { 188 | margin-bottom: 20px; 189 | } 190 | 191 | .content .sidebar ul li { 192 | padding: 15px; 193 | text-align: left; 194 | line-height: 65px; 195 | height: 7%; 196 | border-right: 1px solid #ffbb24; 197 | transition: ease-out 0.3s; 198 | } 199 | 200 | .content .sidebar ul li a .fas { 201 | width: 25px; 202 | } 203 | 204 | .content .sidebar ul li:hover { 205 | opacity: 0.5; 206 | } 207 | 208 | .modal-content { 209 | position: relative; 210 | background-color: #202020; 211 | margin: auto; 212 | padding: 0; 213 | margin: 0 auto; 214 | border: 2px solid #383838; 215 | border-radius: 2px; 216 | box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 217 | -webkit-animation-name: animatetop; 218 | -webkit-animation-duration: 0.4s; 219 | animation-name: animatetop; 220 | animation-duration: 0.4s; 221 | } 222 | .close { 223 | color: #383838; 224 | float: right; 225 | font-size: 1.4em; 226 | } 227 | .close:hover, 228 | .close:focus { 229 | color: #dc143c; 230 | text-decoration: none; 231 | cursor: pointer; 232 | } 233 | 234 | .close:hover { 235 | color: #dc143c; 236 | text-decoration: none; 237 | cursor: pointer; 238 | } 239 | .clickable { 240 | text-decoration: underline; 241 | text-decoration-color: #383838; 242 | } 243 | .clickable:hover, 244 | .clickable2:hover { 245 | color: #dc143c; 246 | } 247 | .important h4 { 248 | text-decoration: underline; 249 | text-decoration-color: #383838; 250 | } 251 | .img-block { 252 | padding: 5px; 253 | color: #011b37; 254 | background-color: #383838; 255 | border: 2px solid #383838; 256 | position: absolute; 257 | font-family: Courier; 258 | font-weight: bold; 259 | text-decoration: underline; 260 | } 261 | .textarea { 262 | font-size: 14px; 263 | border: 2px solid #202020; 264 | padding: 7px 15px 5px 15px; 265 | } -------------------------------------------------------------------------------- /ui/vue.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Vue.js v2.5.13 3 | * (c) 2014-2017 Evan You 4 | * Released under the MIT License. 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Vue=e()}(this,function(){"use strict";function t(t){return void 0===t||null===t}function e(t){return void 0!==t&&null!==t}function n(t){return!0===t}function r(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function i(t){return null!==t&&"object"==typeof t}function o(t){return"[object Object]"===Nn.call(t)}function a(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function s(t){return null==t?"":"object"==typeof t?JSON.stringify(t,null,2):String(t)}function c(t){var e=parseFloat(t);return isNaN(e)?t:e}function u(t,e){for(var n=Object.create(null),r=t.split(","),i=0;i-1)return t.splice(n,1)}}function f(t,e){return Mn.call(t,e)}function p(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}function d(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n}function v(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function h(t,e){for(var n in e)t[n]=e[n];return t}function m(t){for(var e={},n=0;n0&&(tt((s=et(s,(o||"")+"_"+a))[0])&&tt(u)&&(l[c]=x(u.text+s[0].text),s.shift()),l.push.apply(l,s)):r(s)?tt(u)?l[c]=x(u.text+s):""!==s&&l.push(x(s)):tt(s)&&tt(u)?l[c]=x(u.text+s.text):(n(i._isVList)&&e(s.tag)&&t(s.key)&&e(o)&&(s.key="__vlist"+o+"_"+a+"__"),l.push(s)));return l}function nt(t,e){return(t.__esModule||fr&&"Module"===t[Symbol.toStringTag])&&(t=t.default),i(t)?e.extend(t):t}function rt(t){return t.isComment&&t.asyncFactory}function it(t){if(Array.isArray(t))for(var n=0;n=0||n.indexOf(t[i])<0)&&r.push(t[i]);return r}return t}}(n[o],r[o],i[o]));return e}(t);r&&h(t.extendOptions,r),(e=t.options=F(n,t.extendOptions)).name&&(e.components[e.name]=t)}}return e}function Rt(t){this._init(t)}function Ht(t){t.cid=0;var e=1;t.extend=function(t){t=t||{};var n=this,r=n.cid,i=t._Ctor||(t._Ctor={});if(i[r])return i[r];var o=t.name||n.options.name,a=function(t){this._init(t)};return a.prototype=Object.create(n.prototype),a.prototype.constructor=a,a.cid=e++,a.options=F(n.options,t),a.super=n,a.options.props&&function(t){var e=t.options.props;for(var n in e)mt(t.prototype,"_props",n)}(a),a.options.computed&&function(t){var e=t.options.computed;for(var n in e)gt(t.prototype,n,e[n])}(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,zn.forEach(function(t){a[t]=n[t]}),o&&(a.options.components[o]=a),a.superOptions=n.options,a.extendOptions=t,a.sealedOptions=h({},a.options),i[r]=a,a}}function Bt(t){return t&&(t.Ctor.options.name||t.tag)}function Ut(t,e){return Array.isArray(t)?t.indexOf(e)>-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!function(t){return"[object RegExp]"===Nn.call(t)}(t)&&t.test(e)}function Vt(t,e){var n=t.cache,r=t.keys,i=t._vnode;for(var o in n){var a=n[o];if(a){var s=Bt(a.componentOptions);s&&!e(s)&&zt(n,o,r,i)}}}function zt(t,e,n,r){var i=t[e];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),t[e]=null,l(n,e)}function Kt(t){for(var n=t.data,r=t,i=t;e(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(n=Jt(i.data,n));for(;e(r=r.parent);)r&&r.data&&(n=Jt(n,r.data));return function(t,n){if(e(t)||e(n))return qt(t,Wt(n));return""}(n.staticClass,n.class)}function Jt(t,n){return{staticClass:qt(t.staticClass,n.staticClass),class:e(t.class)?[t.class,n.class]:n.class}}function qt(t,e){return t?e?t+" "+e:t:e||""}function Wt(t){return Array.isArray(t)?function(t){for(var n,r="",i=0,o=t.length;i=0&&" "===(m=t.charAt(h));h--);m&&Ii.test(m)||(l=!0)}}else void 0===o?(v=i+1,o=t.slice(0,i).trim()):e();if(void 0===o?o=t.slice(0,i).trim():0!==v&&e(),a)for(i=0;i-1?{exp:t.slice(0,ii),key:'"'+t.slice(ii+1)+'"'}:{exp:t,key:null};ni=t,ii=oi=ai=0;for(;!_e();)be(ri=ge())?$e(ri):91===ri&&function(t){var e=1;oi=ii;for(;!_e();)if(t=ge(),be(t))$e(t);else if(91===t&&e++,93===t&&e--,0===e){ai=ii;break}}(ri);return{exp:t.slice(0,oi),key:t.slice(oi+1,ai)}}(t);return null===n.key?t+"="+e:"$set("+n.exp+", "+n.key+", "+e+")"}function ge(){return ni.charCodeAt(++ii)}function _e(){return ii>=ei}function be(t){return 34===t||39===t}function $e(t){for(var e=t;!_e()&&(t=ge())!==e;);}function Ce(t,e,n,r,i){e=function(t){return t._withTask||(t._withTask=function(){Er=!0;var e=t.apply(null,arguments);return Er=!1,e})}(e),n&&(e=function(t,e,n){var r=si;return function i(){null!==t.apply(null,arguments)&&we(e,i,n,r)}}(e,t,r)),si.addEventListener(t,e,or?{capture:r,passive:i}:r)}function we(t,e,n,r){(r||si).removeEventListener(t,e._withTask||e,n)}function xe(n,r){if(!t(n.data.on)||!t(r.data.on)){var i=r.data.on||{},o=n.data.on||{};si=r.elm,function(t){if(e(t[Li])){var n=Qn?"change":"input";t[n]=[].concat(t[Li],t[n]||[]),delete t[Li]}e(t[Mi])&&(t.change=[].concat(t[Mi],t.change||[]),delete t[Mi])}(i),X(i,o,Ce,we,r.context),si=void 0}}function ke(n,r){if(!t(n.data.domProps)||!t(r.data.domProps)){var i,o,a=r.elm,s=n.data.domProps||{},u=r.data.domProps||{};e(u.__ob__)&&(u=r.data.domProps=h({},u));for(i in s)t(u[i])&&(a[i]="");for(i in u){if(o=u[i],"textContent"===i||"innerHTML"===i){if(r.children&&(r.children.length=0),o===s[i])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===i){a._value=o;var l=t(o)?"":String(o);(function(t,n){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,n)||function(t,n){var r=t.value,i=t._vModifiers;if(e(i)){if(i.lazy)return!1;if(i.number)return c(r)!==c(n);if(i.trim)return r.trim()!==n.trim()}return r!==n}(t,n))})(a,l)&&(a.value=l)}else a[i]=o}}}function Ae(t){var e=Oe(t.style);return t.staticStyle?h(t.staticStyle,e):e}function Oe(t){return Array.isArray(t)?m(t):"string"==typeof t?Fi(t):t}function Se(n,r){var i=r.data,o=n.data;if(!(t(i.staticStyle)&&t(i.style)&&t(o.staticStyle)&&t(o.style))){var a,s,c=r.elm,u=o.staticStyle,l=o.normalizedStyle||o.style||{},f=u||l,p=Oe(r.data.style)||{};r.data.normalizedStyle=e(p.__ob__)?h({},p):p;var d=function(t,e){var n,r={};if(e)for(var i=t;i.componentInstance;)(i=i.componentInstance._vnode)&&i.data&&(n=Ae(i.data))&&h(r,n);(n=Ae(t.data))&&h(r,n);for(var o=t;o=o.parent;)o.data&&(n=Ae(o.data))&&h(r,n);return r}(r,!0);for(s in f)t(d[s])&&Bi(c,s,"");for(s in d)(a=d[s])!==f[s]&&Bi(c,s,null==a?"":a)}}function Te(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.add(e)}):t.classList.add(e);else{var n=" "+(t.getAttribute("class")||"")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Ee(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.remove(e)}):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" "+(t.getAttribute("class")||"")+" ",r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function je(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&h(e,Ki(t.name||"v")),h(e,t),e}return"string"==typeof t?Ki(t):void 0}}function Ne(t){Qi(function(){Qi(t)})}function Ie(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),Te(t,e))}function Le(t,e){t._transitionClasses&&l(t._transitionClasses,e),Ee(t,e)}function Me(t,e,n){var r=De(t,e),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===qi?Zi:Yi,c=0,u=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++c>=a&&u()};setTimeout(function(){c0&&(n=qi,l=a,f=o.length):e===Wi?u>0&&(n=Wi,l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?qi:Wi:null)?n===qi?o.length:c.length:0;return{type:n,timeout:l,propCount:f,hasTransform:n===qi&&to.test(r[Gi+"Property"])}}function Pe(t,e){for(;t.length1}function Ve(t,e){!0!==e.data.show&&Re(e)}function ze(t,e,n){Ke(t,e,n),(Qn||er)&&setTimeout(function(){Ke(t,e,n)},0)}function Ke(t,e,n){var r=e.value,i=t.multiple;if(!i||Array.isArray(r)){for(var o,a,s=0,c=t.options.length;s-1,a.selected!==o&&(a.selected=o);else if(g(qe(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));i||(t.selectedIndex=-1)}}function Je(t,e){return e.every(function(e){return!g(e,t)})}function qe(t){return"_value"in t?t._value:t.value}function We(t){t.target.composing=!0}function Ge(t){t.target.composing&&(t.target.composing=!1,Ze(t.target,"input"))}function Ze(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Xe(t){return!t.componentInstance||t.data&&t.data.transition?t:Xe(t.componentInstance._vnode)}function Ye(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Ye(it(e.children)):t}function Qe(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var i=n._parentListeners;for(var o in i)e[Pn(o)]=i[o];return e}function tn(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}function en(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function nn(t){t.data.newPos=t.elm.getBoundingClientRect()}function rn(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,i=e.top-n.top;if(r||i){t.data.moved=!0;var o=t.elm.style;o.transform=o.WebkitTransform="translate("+r+"px,"+i+"px)",o.transitionDuration="0s"}}function on(t,e){var n=e?zo:Vo;return t.replace(n,function(t){return Uo[t]})}function an(t,e,n){return{type:1,tag:t,attrsList:e,attrsMap:function(t){for(var e={},n=0,r=t.length;n=0&&a[i].lowerCasedTag!==s;i--);else i=0;if(i>=0){for(var c=a.length-1;c>=i;c--)e.end&&e.end(a[c].tag,n,r);a.length=i,o=i&&a[i-1].tag}else"br"===s?e.start&&e.start(t,[],!0,n,r):"p"===s&&(e.start&&e.start(t,[],!1,n,r),e.end&&e.end(t,n,r))}for(var i,o,a=[],s=e.expectHTML,c=e.isUnaryTag||Bn,u=e.canBeLeftOpenTag||Bn,l=0;t;){if(i=t,o&&Ho(o)){var f=0,p=o.toLowerCase(),d=Bo[p]||(Bo[p]=new RegExp("([\\s\\S]*?)(]*>)","i")),v=t.replace(d,function(t,n,r){return f=r.length,Ho(p)||"noscript"===p||(n=n.replace(//g,"$1").replace(//g,"$1")),Jo(p,n)&&(n=n.slice(1)),e.chars&&e.chars(n),""});l+=t.length-v.length,t=v,r(p,l-f,l)}else{var h=t.indexOf("<");if(0===h){if(Ao.test(t)){var m=t.indexOf("--\x3e");if(m>=0){e.shouldKeepComment&&e.comment(t.substring(4,m)),n(m+3);continue}}if(Oo.test(t)){var y=t.indexOf("]>");if(y>=0){n(y+2);continue}}var g=t.match(ko);if(g){n(g[0].length);continue}var _=t.match(xo);if(_){var b=l;n(_[0].length),r(_[1],b,l);continue}var $=function(){var e=t.match(Co);if(e){var r={tagName:e[1],attrs:[],start:l};n(e[0].length);for(var i,o;!(i=t.match(wo))&&(o=t.match(_o));)n(o[0].length),r.attrs.push(o);if(i)return r.unarySlash=i[1],n(i[0].length),r.end=l,r}}();if($){!function(t){var n=t.tagName,i=t.unarySlash;s&&("p"===o&&go(n)&&r(o),u(n)&&o===n&&r(n));for(var l=c(n)||!!i,f=t.attrs.length,p=new Array(f),d=0;d=0){for(w=t.slice(h);!(xo.test(w)||Co.test(w)||Ao.test(w)||Oo.test(w)||(x=w.indexOf("<",1))<0);)h+=x,w=t.slice(h);C=t.substring(0,h),n(h)}h<0&&(C=t,t=""),e.chars&&C&&e.chars(C)}if(t===i){e.chars&&e.chars(t);break}}r()}(t,{warn:To,expectHTML:e.expectHTML,isUnaryTag:e.isUnaryTag,canBeLeftOpenTag:e.canBeLeftOpenTag,shouldDecodeNewlines:e.shouldDecodeNewlines,shouldDecodeNewlinesForHref:e.shouldDecodeNewlinesForHref,shouldKeepComment:e.comments,start:function(t,a,u){var l=i&&i.ns||Do(t);Qn&&"svg"===l&&(a=function(t){for(var e=[],n=0;nc&&(s.push(o=t.slice(c,i)),a.push(JSON.stringify(o)));var u=ae(r[1].trim());a.push("_s("+u+")"),s.push({"@binding":u}),c=i+r[0].length}return c':'
',Ro.innerHTML.indexOf(" ")>0}var jn=Object.freeze({}),Nn=Object.prototype.toString,In=u("slot,component",!0),Ln=u("key,ref,slot,slot-scope,is"),Mn=Object.prototype.hasOwnProperty,Dn=/-(\w)/g,Pn=p(function(t){return t.replace(Dn,function(t,e){return e?e.toUpperCase():""})}),Fn=p(function(t){return t.charAt(0).toUpperCase()+t.slice(1)}),Rn=/\B([A-Z])/g,Hn=p(function(t){return t.replace(Rn,"-$1").toLowerCase()}),Bn=function(t,e,n){return!1},Un=function(t){return t},Vn="data-server-rendered",zn=["component","directive","filter"],Kn=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],Jn={optionMergeStrategies:Object.create(null),silent:!1,productionTip:!1,devtools:!1,performance:!1,errorHandler:null,warnHandler:null,ignoredElements:[],keyCodes:Object.create(null),isReservedTag:Bn,isReservedAttr:Bn,isUnknownElement:Bn,getTagNamespace:y,parsePlatformTagName:Un,mustUseProp:Bn,_lifecycleHooks:Kn},qn=/[^\w.$]/,Wn="__proto__"in{},Gn="undefined"!=typeof window,Zn="undefined"!=typeof WXEnvironment&&!!WXEnvironment.platform,Xn=Zn&&WXEnvironment.platform.toLowerCase(),Yn=Gn&&window.navigator.userAgent.toLowerCase(),Qn=Yn&&/msie|trident/.test(Yn),tr=Yn&&Yn.indexOf("msie 9.0")>0,er=Yn&&Yn.indexOf("edge/")>0,nr=Yn&&Yn.indexOf("android")>0||"android"===Xn,rr=Yn&&/iphone|ipad|ipod|ios/.test(Yn)||"ios"===Xn,ir=(Yn&&/chrome\/\d+/.test(Yn),{}.watch),or=!1;if(Gn)try{var ar={};Object.defineProperty(ar,"passive",{get:function(){or=!0}}),window.addEventListener("test-passive",null,ar)}catch(t){}var sr,cr,ur=function(){return void 0===sr&&(sr=!Gn&&"undefined"!=typeof global&&"server"===global.process.env.VUE_ENV),sr},lr=Gn&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,fr="undefined"!=typeof Symbol&&w(Symbol)&&"undefined"!=typeof Reflect&&w(Reflect.ownKeys);cr="undefined"!=typeof Set&&w(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var pr=y,dr=0,vr=function(){this.id=dr++,this.subs=[]};vr.prototype.addSub=function(t){this.subs.push(t)},vr.prototype.removeSub=function(t){l(this.subs,t)},vr.prototype.depend=function(){vr.target&&vr.target.addDep(this)},vr.prototype.notify=function(){for(var t=this.subs.slice(),e=0,n=t.length;eVr&&Fr[n].id>t.id;)n--;Fr.splice(n+1,0,t)}else Fr.push(t);Br||(Br=!0,q(ht))}}(this)},Kr.prototype.run=function(){if(this.active){var t=this.get();if(t!==this.value||i(t)||this.deep){var e=this.value;if(this.value=t,this.user)try{this.cb.call(this.vm,t,e)}catch(t){V(t,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,t,e)}}},Kr.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},Kr.prototype.depend=function(){for(var t=this.deps.length;t--;)this.deps[t].depend()},Kr.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||l(this.vm._watchers,this);for(var t=this.deps.length;t--;)this.deps[t].removeSub(this);this.active=!1}};var Jr={enumerable:!0,configurable:!0,get:y,set:y},qr={lazy:!0};Nt(It.prototype);var Wr={init:function(t,n,r,i){if(!t.componentInstance||t.componentInstance._isDestroyed){(t.componentInstance=function(t,n,r,i){var o={_isComponent:!0,parent:n,_parentVnode:t,_parentElm:r||null,_refElm:i||null},a=t.data.inlineTemplate;return e(a)&&(o.render=a.render,o.staticRenderFns=a.staticRenderFns),new t.componentOptions.Ctor(o)}(t,Pr,r,i)).$mount(n?t.elm:void 0,n)}else if(t.data.keepAlive){var o=t;Wr.prepatch(o,o)}},prepatch:function(t,e){var n=e.componentOptions;!function(t,e,n,r,i){var o=!!(i||t.$options._renderChildren||r.data.scopedSlots||t.$scopedSlots!==jn);if(t.$options._parentVnode=r,t.$vnode=r,t._vnode&&(t._vnode.parent=r),t.$options._renderChildren=i,t.$attrs=r.data&&r.data.attrs||jn,t.$listeners=n||jn,e&&t.$options.props){Cr.shouldConvert=!1;for(var a=t._props,s=t.$options._propKeys||[],c=0;c1?v(n):n;for(var r=v(arguments,1),i=0,o=n.length;iparseInt(this.max)&&zt(a,s[0],s,this._vnode)),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={};e.get=function(){return Jn},Object.defineProperty(t,"config",e),t.util={warn:pr,extend:h,mergeOptions:F,defineReactive:E},t.set=j,t.delete=N,t.nextTick=q,t.options=Object.create(null),zn.forEach(function(e){t.options[e+"s"]=Object.create(null)}),t.options._base=t,h(t.options.components,ti),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=v(arguments,1);return n.unshift(this),"function"==typeof t.install?t.install.apply(t,n):"function"==typeof t&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=F(this.options,t),this}}(t),Ht(t),function(t){zn.forEach(function(e){t[e]=function(t,n){return n?("component"===e&&o(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&"function"==typeof n&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}})}(t)}(Rt),Object.defineProperty(Rt.prototype,"$isServer",{get:ur}),Object.defineProperty(Rt.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Rt.version="2.5.13";var ei,ni,ri,ii,oi,ai,si,ci,ui=u("style,class"),li=u("input,textarea,option,select,progress"),fi=function(t,e,n){return"value"===n&&li(t)&&"button"!==e||"selected"===n&&"option"===t||"checked"===n&&"input"===t||"muted"===n&&"video"===t},pi=u("contenteditable,draggable,spellcheck"),di=u("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),vi="http://www.w3.org/1999/xlink",hi=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},mi=function(t){return hi(t)?t.slice(6,t.length):""},yi=function(t){return null==t||!1===t},gi={svg:"http://www.w3.org/2000/svg",math:"http://www.w3.org/1998/Math/MathML"},_i=u("html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot"),bi=u("svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view",!0),$i=function(t){return _i(t)||bi(t)},Ci=Object.create(null),wi=u("text,number,password,search,email,tel,url"),xi=Object.freeze({createElement:function(t,e){var n=document.createElement(t);return"select"!==t?n:(e.data&&e.data.attrs&&void 0!==e.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n)},createElementNS:function(t,e){return document.createElementNS(gi[t],e)},createTextNode:function(t){return document.createTextNode(t)},createComment:function(t){return document.createComment(t)},insertBefore:function(t,e,n){t.insertBefore(e,n)},removeChild:function(t,e){t.removeChild(e)},appendChild:function(t,e){t.appendChild(e)},parentNode:function(t){return t.parentNode},nextSibling:function(t){return t.nextSibling},tagName:function(t){return t.tagName},setTextContent:function(t,e){t.textContent=e},setAttribute:function(t,e,n){t.setAttribute(e,n)}}),ki={create:function(t,e){Xt(e)},update:function(t,e){t.data.ref!==e.data.ref&&(Xt(t,!0),Xt(e))},destroy:function(t){Xt(t,!0)}},Ai=new mr("",{},[]),Oi=["create","activate","update","remove","destroy"],Si={create:te,update:te,destroy:function(t){te(t,Ai)}},Ti=Object.create(null),Ei=[ki,Si],ji={create:re,update:re},Ni={create:oe,update:oe},Ii=/[\w).+\-_$\]]/,Li="__r",Mi="__c",Di={create:xe,update:xe},Pi={create:ke,update:ke},Fi=p(function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach(function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}}),e}),Ri=/^--/,Hi=/\s*!important$/,Bi=function(t,e,n){if(Ri.test(e))t.style.setProperty(e,n);else if(Hi.test(n))t.style.setProperty(e,n.replace(Hi,""),"important");else{var r=Vi(e);if(Array.isArray(n))for(var i=0,o=n.length;id?v(n,t(i[g+1])?null:i[g+1].elm,i,p,g,o):p>g&&m(0,r,f,d)}function _(r,i,o,a){if(r!==i){var s=i.elm=r.elm;if(n(r.isAsyncPlaceholder))e(i.asyncFactory.resolved)?$(r.elm,i,o):i.isAsyncPlaceholder=!0;else if(n(i.isStatic)&&n(r.isStatic)&&i.key===r.key&&(n(i.isCloned)||n(i.isOnce)))i.componentInstance=r.componentInstance;else{var c,u=i.data;e(u)&&e(c=u.hook)&&e(c=c.prepatch)&&c(r,i);var l=r.children,p=i.children;if(e(u)&&f(i)){for(c=0;c-1?Ci[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:Ci[t]=/HTMLUnknownElement/.test(e.toString())},h(Rt.options.directives,ro),h(Rt.options.components,so),Rt.prototype.__patch__=Gn?eo:y,Rt.prototype.$mount=function(t,e){return t=t&&Gn?Zt(t):void 0,function(t,e,n){t.$el=e,t.$options.render||(t.$options.render=gr),vt(t,"beforeMount");var r;return r=function(){t._update(t._render(),n)},new Kr(t,r,y,null,!0),n=!1,null==t.$vnode&&(t._isMounted=!0,vt(t,"mounted")),t}(this,t,e)},Rt.nextTick(function(){Jn.devtools&&lr&&lr.emit("init",Rt)},0);var co,uo=/\{\{((?:.|\n)+?)\}\}/g,lo=/[-.*+?^${}()|[\]\/\\]/g,fo=p(function(t){var e=t[0].replace(lo,"\\$&"),n=t[1].replace(lo,"\\$&");return new RegExp(e+"((?:.|\\n)+?)"+n,"g")}),po={staticKeys:["staticClass"],transformNode:function(t,e){e.warn;var n=he(t,"class");n&&(t.staticClass=JSON.stringify(n));var r=ve(t,"class",!1);r&&(t.classBinding=r)},genData:function(t){var e="";return t.staticClass&&(e+="staticClass:"+t.staticClass+","),t.classBinding&&(e+="class:"+t.classBinding+","),e}},vo={staticKeys:["staticStyle"],transformNode:function(t,e){e.warn;var n=he(t,"style");n&&(t.staticStyle=JSON.stringify(Fi(n)));var r=ve(t,"style",!1);r&&(t.styleBinding=r)},genData:function(t){var e="";return t.staticStyle&&(e+="staticStyle:"+t.staticStyle+","),t.styleBinding&&(e+="style:("+t.styleBinding+"),"),e}},ho=function(t){return co=co||document.createElement("div"),co.innerHTML=t,co.textContent},mo=u("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),yo=u("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),go=u("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),_o=/^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,bo="[a-zA-Z_][\\w\\-\\.]*",$o="((?:"+bo+"\\:)?"+bo+")",Co=new RegExp("^<"+$o),wo=/^\s*(\/?)>/,xo=new RegExp("^<\\/"+$o+"[^>]*>"),ko=/^]+>/i,Ao=/^