2021-06-25 06:55:49 -07:00
< template >
2021-08-19 11:37:59 -07:00
< transition name = "slide-fade" appear >
2021-08-23 01:59:27 -07:00
< div v-if ="monitor" >
2021-08-19 11:37:59 -07:00
< h1 > { { monitor . name } } < / h1 >
2021-08-26 03:55:19 -07:00
< div class = "tags" >
< Tag v -for = " tag in monitor.tags " :key ="tag.id" :item ="tag" :size ="'sm'" / >
< / div >
2021-08-19 11:37:59 -07:00
< p class = "url" >
< a v-if ="monitor.type === 'http' || monitor.type === 'keyword' " :href="monitor.url" target="_blank" > {{ monitor.url }} < / a >
< span v-if ="monitor.type === 'port'" > TCP Ping {{ monitor.hostname }} : {{ monitor.port }} < / span >
< span v-if ="monitor.type === 'ping'" > Ping : {{ monitor.hostname }} < / span >
< span v-if ="monitor.type === 'keyword'" >
< br >
2021-08-25 17:43:26 -07:00
< span > { { $t ( "Keyword" ) } } : < / span > < span class = "keyword" > { { monitor . keyword } } < / span >
2021-08-19 11:37:59 -07:00
< / span >
2021-08-28 18:57:26 -07:00
< span v-if ="monitor.type === 'dns'" > [ {{ monitor.dns_resolve_type }} ] {{ monitor.hostname }}
< br >
< span > { { $t ( "Last Result" ) } } : < / span > < span class = "keyword" > { { monitor . dns _last _result } } < / span >
< / span >
2021-08-19 11:37:59 -07:00
< / p >
2021-06-25 06:55:49 -07:00
2021-08-19 11:37:59 -07:00
< div class = "functions" >
< button v-if ="monitor.active" class="btn btn-light" @click="pauseDialog" >
2021-08-24 03:26:44 -07:00
< font -awesome -icon icon = "pause" / > { { $t ( "Pause" ) } }
2021-08-19 11:37:59 -07:00
< / button >
< button v-if ="! monitor.active" class="btn btn-primary" @click="resumeMonitor" >
2021-08-24 03:26:44 -07:00
< font -awesome -icon icon = "play" / > { { $t ( "Resume" ) } }
2021-08-19 11:37:59 -07:00
< / button >
< router -link : to = " '/edit/' + monitor.id " class = "btn btn-secondary" >
2021-08-24 03:26:44 -07:00
< font -awesome -icon icon = "edit" / > { { $t ( "Edit" ) } }
2021-08-19 11:37:59 -07:00
< / r o u t e r - l i n k >
< button class = "btn btn-danger" @click ="deleteDialog" >
2021-08-24 03:26:44 -07:00
< font -awesome -icon icon = "trash" / > { { $t ( "Delete" ) } }
2021-08-19 11:37:59 -07:00
< / button >
2021-06-25 06:55:49 -07:00
< / div >
2021-08-19 11:37:59 -07:00
< div class = "shadow-box" >
< div class = "row" >
< div class = "col-md-8" >
< HeartbeatBar :monitor-id ="monitor.id" / >
2021-08-24 03:26:44 -07:00
< span class = "word" > { { $t ( "checkEverySecond" , [ monitor . interval ] ) } } < / span >
2021-08-19 11:37:59 -07:00
< / div >
< div class = "col-md-4 text-center" >
2021-10-18 09:19:26 -07:00
< span class = "badge rounded-pill" : class = " 'bg-' + status.color " style = "font-size: 30px;" > { { status . text } } < / span >
2021-08-19 11:37:59 -07:00
< / div >
< / div >
2021-06-30 06:04:58 -07:00
< / div >
2021-07-26 07:53:07 -07:00
2021-08-19 11:37:59 -07:00
< div class = "shadow-box big-padding text-center stats" >
< div class = "row" >
< div class = "col" >
2021-09-19 06:15:12 -07:00
< h4 > { { pingTitle ( ) } } < / h4 >
2021-08-24 03:26:44 -07:00
< p > ( { { $t ( "Current" ) } } ) < / p >
2021-08-19 11:37:59 -07:00
< span class = "num" >
< a href = "#" @ click.prevent = " showPingChartBox = ! showPingChartBox " >
< CountUp :value ="ping" / >
< / a >
< / span >
< / div >
< div class = "col" >
2021-09-19 06:15:12 -07:00
< h4 > { { pingTitle ( true ) } } < / h4 >
2021-08-24 03:26:44 -07:00
< p > ( 24 { { $t ( "-hour" ) } } ) < / p >
2021-08-19 11:37:59 -07:00
< span class = "num" > < CountUp :value ="avgPing" / > < / span >
< / div >
< div class = "col" >
2021-08-24 03:26:44 -07:00
< h4 > { { $t ( "Uptime" ) } } < / h4 >
< p > ( 24 { { $t ( "-hour" ) } } ) < / p >
2021-08-19 11:37:59 -07:00
< span class = "num" > < Uptime :monitor ="monitor" type = "24" / > < / span >
< / div >
< div class = "col" >
2021-08-24 03:26:44 -07:00
< h4 > { { $t ( "Uptime" ) } } < / h4 >
< p > ( 30 { { $t ( "-day" ) } } ) < / p >
2021-08-19 11:37:59 -07:00
< span class = "num" > < Uptime :monitor ="monitor" type = "720" / > < / span >
< / div >
2021-10-01 03:44:32 -07:00
< div v-if ="tlsInfo" class="col" >
2021-08-24 03:26:44 -07:00
< h4 > { { $t ( "Cert Exp." ) } } < / h4 >
2021-10-01 03:44:32 -07:00
< p > ( < Datetime :value ="tlsInfo.certInfo.validTo" date -only / > ) < / p >
2021-08-19 11:37:59 -07:00
< span class = "num" >
2021-10-01 03:44:32 -07:00
< a href = "#" @ click.prevent = " toggleCertInfoBox = ! toggleCertInfoBox " > { { tlsInfo . certInfo . daysRemaining } } { { $t ( "days" ) } } < / a >
2021-08-19 11:37:59 -07:00
< / span >
< / div >
< / div >
2021-07-26 07:53:07 -07:00
< / div >
2021-06-30 06:04:58 -07:00
2021-10-09 04:08:38 -07:00
<!-- Cert Info Box -- >
2021-08-19 11:37:59 -07:00
< transition name = "slide-fade" appear >
< div v-if ="showCertInfoBox" class="shadow-box big-padding text-center" >
< div class = "row" >
< div class = "col" >
2021-10-01 03:44:32 -07:00
< certificate -info :certInfo ="tlsInfo.certInfo" :valid ="tlsInfo.valid" / >
2021-08-19 11:37:59 -07:00
< / div >
< / div >
< / div >
< / transition >
2021-10-09 04:08:38 -07:00
<!-- Ping Chart -- >
2021-08-19 11:37:59 -07:00
< div v-if ="showPingChartBox" class="shadow-box big-padding text-center ping-chart-wrapper" >
< div class = "row" >
< div class = "col" >
< PingChart :monitor-id ="monitor.id" / >
< / div >
< / div >
2021-08-10 04:34:47 -07:00
< / div >
2021-08-23 11:02:38 -07:00
< div class = "shadow-box table-shadow-box" >
2021-08-29 09:47:01 -07:00
< div class = "dropdown dropdown-clear-data" >
< button class = "btn btn-sm btn-outline-danger dropdown-toggle" type = "button" data -bs -toggle = " dropdown " >
< font -awesome -icon icon = "trash" / > { { $t ( "Clear Data" ) } }
< / button >
< ul class = "dropdown-menu dropdown-menu-end" >
< li >
< button type = "button" class = "dropdown-item" @click ="clearEventsDialog" >
{ { $t ( "Events" ) } }
< / button >
< / li >
< li >
< button type = "button" class = "dropdown-item" @click ="clearHeartbeatsDialog" >
{ { $t ( "Heartbeats" ) } }
< / button >
< / li >
< / ul >
< / div >
2021-08-19 11:37:59 -07:00
< table class = "table table-borderless table-hover" >
< thead >
< tr >
2021-08-24 03:26:44 -07:00
< th > { { $t ( "Status" ) } } < / th >
< th > { { $t ( "DateTime" ) } } < / th >
< th > { { $t ( "Message" ) } } < / th >
2021-07-20 21:09:09 -07:00
< / tr >
2021-08-19 11:37:59 -07:00
< / thead >
< tbody >
2021-08-22 16:22:55 -07:00
< tr v-for ="(beat, index) in displayedRecords" :key="index" :class="{ 'shadow-box': $root.windowWidth <= 550}" style="padding: 10px;" >
2021-08-19 11:37:59 -07:00
< td > < Status :status ="beat.status" / > < / td >
2021-08-22 16:22:55 -07:00
< td : class = "{ 'border-0':! beat.msg}" > < Datetime :value ="beat.time" / > < / td >
< td class = "border-0" > { { beat . msg } } < / td >
2021-07-20 21:09:09 -07:00
< / tr >
2021-08-19 11:37:59 -07:00
< tr v-if ="importantHeartBeatList.length === 0" >
< td colspan = "3" >
2021-08-24 03:26:44 -07:00
{ { $t ( "No important events" ) } }
2021-07-27 10:47:13 -07:00
< / td >
2021-07-20 21:09:09 -07:00
< / tr >
< / tbody >
< / table >
2021-08-19 11:37:59 -07:00
< div class = "d-flex justify-content-center kuma_pagination" >
< pagination
v - model = "page"
: records = "importantHeartBeatList.length"
: per - page = "perPage"
2021-09-26 08:20:12 -07:00
: options = "paginationConfig"
2021-08-19 11:37:59 -07:00
/ >
< / div >
< / div >
2021-06-30 06:04:58 -07:00
2021-08-28 19:03:55 -07:00
< Confirm ref = "confirmPause" :yes-text ="$t('Yes')" :no-text ="$t('No')" @yes ="pauseMonitor" >
{ { $t ( "pauseMonitorMsg" ) } }
2021-08-19 11:37:59 -07:00
< / Confirm >
2021-07-17 18:04:40 -07:00
2021-08-25 17:43:26 -07:00
< Confirm ref = "confirmDelete" btn -style = " btn -danger " :yes-text ="$t('Yes')" :no-text ="$t('No')" @yes ="deleteMonitor" >
{ { $t ( "deleteMonitorMsg" ) } }
2021-08-19 11:37:59 -07:00
< / Confirm >
2021-08-29 09:47:01 -07:00
< Confirm ref = "confirmClearEvents" btn -style = " btn -danger " :yes-text ="$t('Yes')" :no-text ="$t('No')" @yes ="clearEvents" >
{ { $t ( "clearEventsMsg" ) } }
< / Confirm >
< Confirm ref = "confirmClearHeartbeats" btn -style = " btn -danger " :yes-text ="$t('Yes')" :no-text ="$t('No')" @yes ="clearHeartbeats" >
{ { $t ( "clearHeartbeatsMsg" ) } }
< / Confirm >
2021-07-17 18:04:40 -07:00
< / div >
2021-08-19 11:37:59 -07:00
< / transition >
2021-06-25 06:55:49 -07:00
< / template >
< script >
2021-08-11 09:47:58 -07:00
import { defineAsyncComponent } from "vue" ;
2021-10-01 03:44:32 -07:00
import { useToast } from "vue-toastification" ;
const toast = useToast ( ) ;
2021-06-25 06:55:49 -07:00
import Confirm from "../components/Confirm.vue" ;
2021-06-25 12:03:06 -07:00
import HeartbeatBar from "../components/HeartbeatBar.vue" ;
2021-06-30 06:04:58 -07:00
import Status from "../components/Status.vue" ;
import Datetime from "../components/Datetime.vue" ;
import CountUp from "../components/CountUp.vue" ;
2021-06-30 22:11:16 -07:00
import Uptime from "../components/Uptime.vue" ;
2021-07-17 18:04:40 -07:00
import Pagination from "v-pagination-3" ;
2021-08-11 09:47:58 -07:00
const PingChart = defineAsyncComponent ( ( ) => import ( "../components/PingChart.vue" ) ) ;
2021-08-26 03:55:19 -07:00
import Tag from "../components/Tag.vue" ;
2021-10-01 03:44:32 -07:00
import CertificateInfo from "../components/CertificateInfo.vue" ;
2021-06-25 06:55:49 -07:00
export default {
components : {
2021-06-30 22:11:16 -07:00
Uptime ,
2021-06-30 06:04:58 -07:00
CountUp ,
Datetime ,
2021-06-25 12:03:06 -07:00
HeartbeatBar ,
2021-06-30 06:04:58 -07:00
Confirm ,
Status ,
2021-07-17 18:04:40 -07:00
Pagination ,
2021-08-10 04:34:47 -07:00
PingChart ,
2021-08-26 03:55:19 -07:00
Tag ,
2021-10-01 03:44:32 -07:00
CertificateInfo ,
2021-06-25 06:55:49 -07:00
} ,
data ( ) {
return {
2021-07-17 18:04:40 -07:00
page : 1 ,
perPage : 25 ,
heartBeatList : [ ] ,
2021-07-26 07:53:07 -07:00
toggleCertInfoBox : false ,
2021-08-11 05:59:33 -07:00
showPingChartBox : true ,
2021-09-26 08:20:12 -07:00
paginationConfig : {
2021-10-29 04:37:38 -07:00
hideCount : true ,
2021-10-26 09:03:49 -07:00
chunksNavigation : "scroll" ,
} ,
2021-10-01 03:44:32 -07:00
} ;
2021-06-25 06:55:49 -07:00
} ,
computed : {
monitor ( ) {
2021-10-01 03:44:32 -07:00
let id = this . $route . params . id ;
2021-06-27 01:10:55 -07:00
return this . $root . monitorList [ id ] ;
} ,
2021-06-25 06:55:49 -07:00
2021-06-27 01:10:55 -07:00
lastHeartBeat ( ) {
if ( this . monitor . id in this . $root . lastHeartbeatList && this . $root . lastHeartbeatList [ this . monitor . id ] ) {
2021-10-01 03:44:32 -07:00
return this . $root . lastHeartbeatList [ this . monitor . id ] ;
2021-07-27 10:47:13 -07:00
}
return {
status : - 1 ,
2021-10-01 03:44:32 -07:00
} ;
2021-06-25 06:55:49 -07:00
} ,
2021-06-27 01:10:55 -07:00
2021-06-30 06:04:58 -07:00
ping ( ) {
2021-07-11 20:20:18 -07:00
if ( this . lastHeartBeat . ping || this . lastHeartBeat . ping === 0 ) {
2021-06-30 06:04:58 -07:00
return this . lastHeartBeat . ping ;
}
2021-07-27 10:47:13 -07:00
2021-10-01 03:44:32 -07:00
return this . $t ( "notAvailableShort" ) ;
2021-06-30 06:04:58 -07:00
} ,
avgPing ( ) {
2021-07-11 20:20:18 -07:00
if ( this . $root . avgPingList [ this . monitor . id ] || this . $root . avgPingList [ this . monitor . id ] === 0 ) {
2021-06-30 06:04:58 -07:00
return this . $root . avgPingList [ this . monitor . id ] ;
}
2021-07-27 10:47:13 -07:00
2021-10-01 03:44:32 -07:00
return this . $t ( "notAvailableShort" ) ;
2021-06-30 06:04:58 -07:00
} ,
importantHeartBeatList ( ) {
if ( this . $root . importantHeartbeatList [ this . monitor . id ] ) {
2021-09-04 11:03:40 -07:00
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
2021-07-17 18:04:40 -07:00
this . heartBeatList = this . $root . importantHeartbeatList [ this . monitor . id ] ;
2021-10-01 03:44:32 -07:00
return this . $root . importantHeartbeatList [ this . monitor . id ] ;
2021-06-30 06:04:58 -07:00
}
2021-07-27 10:47:13 -07:00
return [ ] ;
2021-06-30 06:04:58 -07:00
} ,
2021-06-27 01:10:55 -07:00
status ( ) {
if ( this . $root . statusList [ this . monitor . id ] ) {
2021-10-01 03:44:32 -07:00
return this . $root . statusList [ this . monitor . id ] ;
2021-06-27 01:10:55 -07:00
}
2021-07-27 10:47:13 -07:00
2021-10-01 03:44:32 -07:00
return { } ;
2021-07-17 18:04:40 -07:00
} ,
2021-06-27 01:10:55 -07:00
2021-10-01 03:44:32 -07:00
tlsInfo ( ) {
2021-10-09 04:08:38 -07:00
// Add: this.$root.tlsInfoList[this.monitor.id].certInfo
// Fix: TypeError: Cannot read properties of undefined (reading 'validTo')
// Reason: TLS Info object format is changed in 1.8.0, if for some reason, it cannot connect to the site after update to 1.8.0, the object is still in the old format.
if ( this . $root . tlsInfoList [ this . monitor . id ] && this . $root . tlsInfoList [ this . monitor . id ] . certInfo ) {
2021-10-01 03:44:32 -07:00
return this . $root . tlsInfoList [ this . monitor . id ] ;
2021-07-20 21:09:09 -07:00
}
2021-07-27 10:47:13 -07:00
2021-10-01 03:44:32 -07:00
return null ;
2021-07-20 21:09:09 -07:00
} ,
2021-07-26 07:53:07 -07:00
showCertInfoBox ( ) {
2021-10-01 03:44:32 -07:00
return this . tlsInfo != null && this . toggleCertInfoBox ;
2021-07-26 07:53:07 -07:00
} ,
2021-07-17 18:04:40 -07:00
displayedRecords ( ) {
const startIndex = this . perPage * ( this . page - 1 ) ;
const endIndex = startIndex + this . perPage ;
return this . heartBeatList . slice ( startIndex , endIndex ) ;
} ,
2021-07-27 10:47:13 -07:00
} ,
mounted ( ) {
2021-06-25 06:55:49 -07:00
} ,
methods : {
2021-06-30 06:04:58 -07:00
testNotification ( ) {
2021-10-01 03:44:32 -07:00
this . $root . getSocket ( ) . emit ( "testNotification" , this . monitor . id ) ;
toast . success ( "Test notification is requested." ) ;
2021-06-30 06:04:58 -07:00
} ,
2021-06-25 06:55:49 -07:00
pauseDialog ( ) {
this . $refs . confirmPause . show ( ) ;
} ,
2021-06-30 06:04:58 -07:00
2021-06-25 06:55:49 -07:00
resumeMonitor ( ) {
this . $root . getSocket ( ) . emit ( "resumeMonitor" , this . monitor . id , ( res ) => {
2021-10-01 03:44:32 -07:00
this . $root . toastRes ( res ) ;
} ) ;
2021-06-25 06:55:49 -07:00
} ,
2021-06-30 06:04:58 -07:00
2021-06-25 06:55:49 -07:00
pauseMonitor ( ) {
this . $root . getSocket ( ) . emit ( "pauseMonitor" , this . monitor . id , ( res ) => {
2021-10-01 03:44:32 -07:00
this . $root . toastRes ( res ) ;
} ) ;
2021-06-25 06:55:49 -07:00
} ,
2021-06-30 06:04:58 -07:00
2021-06-25 06:55:49 -07:00
deleteDialog ( ) {
this . $refs . confirmDelete . show ( ) ;
} ,
2021-06-30 06:04:58 -07:00
2021-08-29 09:47:01 -07:00
clearEventsDialog ( ) {
this . $refs . confirmClearEvents . show ( ) ;
} ,
clearHeartbeatsDialog ( ) {
this . $refs . confirmClearHeartbeats . show ( ) ;
} ,
2021-06-25 06:55:49 -07:00
deleteMonitor ( ) {
this . $root . deleteMonitor ( this . monitor . id , ( res ) => {
if ( res . ok ) {
toast . success ( res . msg ) ;
2021-10-01 03:44:32 -07:00
this . $router . push ( "/dashboard" ) ;
2021-06-25 06:55:49 -07:00
} else {
toast . error ( res . msg ) ;
}
2021-10-01 03:44:32 -07:00
} ) ;
2021-07-27 10:47:13 -07:00
} ,
2021-06-30 06:04:58 -07:00
2021-08-29 09:47:01 -07:00
clearEvents ( ) {
this . $root . clearEvents ( this . monitor . id , ( res ) => {
2021-09-04 11:03:40 -07:00
if ( ! res . ok ) {
2021-08-29 09:47:01 -07:00
toast . error ( res . msg ) ;
}
2021-10-01 03:44:32 -07:00
} ) ;
2021-08-29 09:47:01 -07:00
} ,
clearHeartbeats ( ) {
this . $root . clearHeartbeats ( this . monitor . id , ( res ) => {
2021-09-04 11:03:40 -07:00
if ( ! res . ok ) {
2021-08-29 09:47:01 -07:00
toast . error ( res . msg ) ;
}
2021-10-01 03:44:32 -07:00
} ) ;
2021-08-29 09:47:01 -07:00
} ,
2021-09-19 06:15:12 -07:00
pingTitle ( average = false ) {
2021-10-01 03:44:32 -07:00
let translationPrefix = "" ;
2021-09-19 06:15:12 -07:00
if ( average ) {
2021-10-01 03:44:32 -07:00
translationPrefix = "Avg. " ;
2021-09-19 06:15:12 -07:00
}
if ( this . monitor . type === "http" ) {
return this . $t ( translationPrefix + "Response" ) ;
}
return this . $t ( translationPrefix + "Ping" ) ;
} ,
2021-07-27 10:47:13 -07:00
} ,
2021-10-01 03:44:32 -07:00
} ;
2021-06-25 06:55:49 -07:00
< / script >
< style lang = "scss" scoped >
@ import "../assets/vars.scss" ;
2021-08-17 21:22:45 -07:00
@ media ( max - width : 767 px ) {
2021-08-11 02:16:53 -07:00
. badge {
margin - top : 14 px ;
}
}
2021-08-17 21:22:45 -07:00
@ media ( max - width : 550 px ) {
2021-08-10 09:29:47 -07:00
. functions {
text - align : center ;
2021-08-29 09:47:01 -07:00
button , a {
margin - left : 10 px ! important ;
margin - right : 10 px ! important ;
}
2021-08-10 09:29:47 -07:00
}
2021-08-17 21:22:45 -07:00
. ping - chart - wrapper {
padding : 10 px ! important ;
}
2021-08-29 09:47:01 -07:00
. dropdown - clear - data {
margin - bottom : 10 px ;
}
2021-08-10 09:29:47 -07:00
}
2021-08-17 21:22:45 -07:00
@ media ( max - width : 400 px ) {
2021-08-10 09:29:47 -07:00
. btn {
display : inline - flex ;
flex - direction : column ;
align - items : center ;
padding - top : 10 px ;
}
a . btn {
padding - left : 25 px ;
padding - right : 25 px ;
}
2021-08-29 09:47:01 -07:00
. dropdown - clear - data {
button {
display : block ;
padding - top : 4 px ;
}
}
2021-08-10 09:29:47 -07:00
}
2021-06-27 01:10:55 -07:00
. url {
2021-06-25 06:55:49 -07:00
color : $primary ;
margin - bottom : 20 px ;
2021-06-27 01:10:55 -07:00
font - weight : bold ;
a {
color : $primary ;
}
2021-06-25 06:55:49 -07:00
}
. functions {
button , a {
margin - right : 20 px ;
}
}
. shadow - box {
padding : 20 px ;
margin - top : 25 px ;
}
2021-06-27 01:10:55 -07:00
. word {
2021-08-24 08:38:25 -07:00
color : # aaa ;
2021-06-27 01:10:55 -07:00
font - size : 14 px ;
}
2021-06-30 06:04:58 -07:00
table {
font - size : 14 px ;
tr {
transition : all ease - in - out 0.2 ms ;
}
}
. stats p {
font - size : 13 px ;
2021-08-24 08:38:25 -07:00
color : # aaa ;
2021-06-30 06:04:58 -07:00
}
2021-07-26 07:53:07 -07:00
. stats {
padding : 10 px ;
. col {
margin : 20 px 0 ;
}
}
2021-08-07 22:47:29 -07:00
. keyword {
color : black ;
}
2021-08-29 09:47:01 -07:00
. dropdown - clear - data {
float : right ;
}
2021-08-24 08:38:25 -07:00
. dark {
2021-08-07 22:47:29 -07:00
. keyword {
color : $dark - font - color ;
}
2021-08-29 09:47:01 -07:00
. dropdown - clear - data {
ul {
background - color : $dark - bg ;
border - color : $dark - bg2 ;
border - width : 2 px ;
2021-09-04 11:03:40 -07:00
li button {
2021-08-29 09:47:01 -07:00
color : $dark - font - color ;
}
li button : hover {
background - color : $dark - bg2 ;
}
}
}
2021-08-07 22:47:29 -07:00
}
2021-08-29 11:22:49 -07:00
2021-08-26 03:55:19 -07:00
. tags {
margin - bottom : 0.5 rem ;
}
. tags > div : first - child {
margin - left : 0 ! important ;
}
2021-06-25 06:55:49 -07:00
< / style >