From 3fb8a25a21a5106ecf3322425353edf445c07ef9 Mon Sep 17 00:00:00 2001 From: Manu Mtz-Almeida Date: Wed, 13 May 2015 02:35:16 +0200 Subject: [PATCH] Adds realtime-advanced demo --- examples/realtime-advanced/main.go | 80 +++++++++++ .../resources/room_login.templ.html | 105 +++++++++++++++ .../resources/static/epoch.min.css | 1 + .../resources/static/epoch.min.js | 114 ++++++++++++++++ .../resources/static/realtime.js | 126 ++++++++++++++++++ examples/realtime-advanced/rooms.go | 33 +++++ examples/realtime-advanced/stats.go | 25 ++++ 7 files changed, 484 insertions(+) create mode 100644 examples/realtime-advanced/main.go create mode 100644 examples/realtime-advanced/resources/room_login.templ.html create mode 100644 examples/realtime-advanced/resources/static/epoch.min.css create mode 100644 examples/realtime-advanced/resources/static/epoch.min.js create mode 100644 examples/realtime-advanced/resources/static/realtime.js create mode 100644 examples/realtime-advanced/rooms.go create mode 100644 examples/realtime-advanced/stats.go diff --git a/examples/realtime-advanced/main.go b/examples/realtime-advanced/main.go new file mode 100644 index 00000000..751990bb --- /dev/null +++ b/examples/realtime-advanced/main.go @@ -0,0 +1,80 @@ +package main + +import ( + "io" + "time" + + "github.com/gin-gonic/gin" +) + +func main() { + router := gin.Default() + router.LoadHTMLGlob("resources/*.templ.html") + router.Static("/static", "resources/static") + router.GET("/", index) + router.GET("/room/:roomid", roomGET) + router.POST("/room/:roomid", roomPOST) + //router.DELETE("/room/:roomid", roomDELETE) + router.GET("/stream/:roomid", streamRoom) + + router.Run(":8080") +} + +func index(c *gin.Context) { + c.Redirect(301, "/room/hn") +} + +func roomGET(c *gin.Context) { + roomid := c.ParamValue("roomid") + userid := c.FormValue("nick") + c.HTML(200, "room_login.templ.html", gin.H{ + "roomid": roomid, + "nick": userid, + "timestamp": time.Now().Unix(), + }) + +} + +func roomPOST(c *gin.Context) { + roomid := c.ParamValue("roomid") + nick := c.FormValue("nick") + message := c.PostFormValue("message") + + if len(message) > 200 || len(nick) > 20 { + c.JSON(400, gin.H{ + "status": "failed", + "error": "the message or nickname is too long", + }) + return + } + + post := gin.H{ + "nick": nick, + "message": message, + } + room(roomid).Submit(post) + c.JSON(200, post) +} + +func roomDELETE(c *gin.Context) { + roomid := c.ParamValue("roomid") + deleteBroadcast(roomid) +} + +func streamRoom(c *gin.Context) { + roomid := c.ParamValue("roomid") + listener := openListener(roomid) + ticker := time.NewTicker(1 * time.Second) + defer closeListener(roomid, listener) + defer ticker.Stop() + + c.Stream(func(w io.Writer) bool { + select { + case msg := <-listener: + c.SSEvent("message", msg) + case <-ticker.C: + c.SSEvent("stats", Stats()) + } + return true + }) +} diff --git a/examples/realtime-advanced/resources/room_login.templ.html b/examples/realtime-advanced/resources/room_login.templ.html new file mode 100644 index 00000000..02bc776c --- /dev/null +++ b/examples/realtime-advanced/resources/room_login.templ.html @@ -0,0 +1,105 @@ + + + + + + + Login in Room "{{.roomid}}" + + + + + + + + + + + + + + + + + + +
+
+

Server-Sent Events in Go

+

Server-sent events (SSE) is a technology where a browser receives automatic updates from a server via HTTP connection.

+

The chat and the charts data is provided in realtime using the SSE implemention of Gin Framework.

+
+ {{if not .nick}} +
+ {{end}} +
+ + + + + + + + +
NickMessage
+
+ {{if .nick}} +
+
+ +
+
+ +
+
+ {{end}} + {{if not .nick}} +
+
+
+ Join the SSE real-time chat +
+ + +
+
+ +
+
+
+ {{end}} +
+
+
+
+
+
+

Number of Goroutines

+

+

+

+
+
+

HEAP/Stack bytes

+

+

+

+
+
+

Mallocs/Frees

+

+

+

+
+
+
+
+

© Company 2014

+
+
+ + diff --git a/examples/realtime-advanced/resources/static/epoch.min.css b/examples/realtime-advanced/resources/static/epoch.min.css new file mode 100644 index 00000000..47a80cdc --- /dev/null +++ b/examples/realtime-advanced/resources/static/epoch.min.css @@ -0,0 +1 @@ +.epoch .axis path,.epoch .axis line{shape-rendering:crispEdges;}.epoch .axis.canvas .tick line{shape-rendering:geometricPrecision;}div#_canvas_css_reference{width:0;height:0;position:absolute;top:-1000px;left:-1000px;}div#_canvas_css_reference svg{position:absolute;width:0;height:0;top:-1000px;left:-1000px;}.epoch{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12pt;}.epoch .axis path,.epoch .axis line{fill:none;stroke:#000;}.epoch .axis .tick text{font-size:9pt;}.epoch .line{fill:none;stroke-width:2px;}.epoch.sparklines .line{stroke-width:1px;}.epoch .area{stroke:none;}.epoch .arc.pie{stroke:#fff;stroke-width:1.5px;}.epoch .arc.pie text{stroke:none;fill:white;font-size:9pt;}.epoch .gauge-labels .value{text-anchor:middle;font-size:140%;fill:#666;}.epoch.gauge-tiny{width:120px;height:90px;}.epoch.gauge-tiny .gauge-labels .value{font-size:80%;}.epoch.gauge-tiny .gauge .arc.outer{stroke-width:2px;}.epoch.gauge-small{width:180px;height:135px;}.epoch.gauge-small .gauge-labels .value{font-size:120%;}.epoch.gauge-small .gauge .arc.outer{stroke-width:3px;}.epoch.gauge-medium{width:240px;height:180px;}.epoch.gauge-medium .gauge .arc.outer{stroke-width:3px;}.epoch.gauge-large{width:320px;height:240px;}.epoch.gauge-large .gauge-labels .value{font-size:180%;}.epoch .gauge .arc.outer{stroke-width:4px;stroke:#666;}.epoch .gauge .arc.inner{stroke-width:1px;stroke:#555;}.epoch .gauge .tick{stroke-width:1px;stroke:#555;}.epoch .gauge .needle{fill:orange;}.epoch .gauge .needle-base{fill:#666;}.epoch div.ref.category1,.epoch.category10 div.ref.category1{background-color:#1f77b4;}.epoch .category1 .line,.epoch.category10 .category1 .line{stroke:#1f77b4;}.epoch .category1 .area,.epoch .category1 .dot,.epoch.category10 .category1 .area,.epoch.category10 .category1 .dot{fill:#1f77b4;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category1 path,.epoch.category10 .arc.category1 path{fill:#1f77b4;}.epoch .bar.category1,.epoch.category10 .bar.category1{fill:#1f77b4;}.epoch div.ref.category2,.epoch.category10 div.ref.category2{background-color:#ff7f0e;}.epoch .category2 .line,.epoch.category10 .category2 .line{stroke:#ff7f0e;}.epoch .category2 .area,.epoch .category2 .dot,.epoch.category10 .category2 .area,.epoch.category10 .category2 .dot{fill:#ff7f0e;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category2 path,.epoch.category10 .arc.category2 path{fill:#ff7f0e;}.epoch .bar.category2,.epoch.category10 .bar.category2{fill:#ff7f0e;}.epoch div.ref.category3,.epoch.category10 div.ref.category3{background-color:#2ca02c;}.epoch .category3 .line,.epoch.category10 .category3 .line{stroke:#2ca02c;}.epoch .category3 .area,.epoch .category3 .dot,.epoch.category10 .category3 .area,.epoch.category10 .category3 .dot{fill:#2ca02c;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category3 path,.epoch.category10 .arc.category3 path{fill:#2ca02c;}.epoch .bar.category3,.epoch.category10 .bar.category3{fill:#2ca02c;}.epoch div.ref.category4,.epoch.category10 div.ref.category4{background-color:#d62728;}.epoch .category4 .line,.epoch.category10 .category4 .line{stroke:#d62728;}.epoch .category4 .area,.epoch .category4 .dot,.epoch.category10 .category4 .area,.epoch.category10 .category4 .dot{fill:#d62728;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category4 path,.epoch.category10 .arc.category4 path{fill:#d62728;}.epoch .bar.category4,.epoch.category10 .bar.category4{fill:#d62728;}.epoch div.ref.category5,.epoch.category10 div.ref.category5{background-color:#9467bd;}.epoch .category5 .line,.epoch.category10 .category5 .line{stroke:#9467bd;}.epoch .category5 .area,.epoch .category5 .dot,.epoch.category10 .category5 .area,.epoch.category10 .category5 .dot{fill:#9467bd;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category5 path,.epoch.category10 .arc.category5 path{fill:#9467bd;}.epoch .bar.category5,.epoch.category10 .bar.category5{fill:#9467bd;}.epoch div.ref.category6,.epoch.category10 div.ref.category6{background-color:#8c564b;}.epoch .category6 .line,.epoch.category10 .category6 .line{stroke:#8c564b;}.epoch .category6 .area,.epoch .category6 .dot,.epoch.category10 .category6 .area,.epoch.category10 .category6 .dot{fill:#8c564b;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category6 path,.epoch.category10 .arc.category6 path{fill:#8c564b;}.epoch .bar.category6,.epoch.category10 .bar.category6{fill:#8c564b;}.epoch div.ref.category7,.epoch.category10 div.ref.category7{background-color:#e377c2;}.epoch .category7 .line,.epoch.category10 .category7 .line{stroke:#e377c2;}.epoch .category7 .area,.epoch .category7 .dot,.epoch.category10 .category7 .area,.epoch.category10 .category7 .dot{fill:#e377c2;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category7 path,.epoch.category10 .arc.category7 path{fill:#e377c2;}.epoch .bar.category7,.epoch.category10 .bar.category7{fill:#e377c2;}.epoch div.ref.category8,.epoch.category10 div.ref.category8{background-color:#7f7f7f;}.epoch .category8 .line,.epoch.category10 .category8 .line{stroke:#7f7f7f;}.epoch .category8 .area,.epoch .category8 .dot,.epoch.category10 .category8 .area,.epoch.category10 .category8 .dot{fill:#7f7f7f;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category8 path,.epoch.category10 .arc.category8 path{fill:#7f7f7f;}.epoch .bar.category8,.epoch.category10 .bar.category8{fill:#7f7f7f;}.epoch div.ref.category9,.epoch.category10 div.ref.category9{background-color:#bcbd22;}.epoch .category9 .line,.epoch.category10 .category9 .line{stroke:#bcbd22;}.epoch .category9 .area,.epoch .category9 .dot,.epoch.category10 .category9 .area,.epoch.category10 .category9 .dot{fill:#bcbd22;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category9 path,.epoch.category10 .arc.category9 path{fill:#bcbd22;}.epoch .bar.category9,.epoch.category10 .bar.category9{fill:#bcbd22;}.epoch div.ref.category10,.epoch.category10 div.ref.category10{background-color:#17becf;}.epoch .category10 .line,.epoch.category10 .category10 .line{stroke:#17becf;}.epoch .category10 .area,.epoch .category10 .dot,.epoch.category10 .category10 .area,.epoch.category10 .category10 .dot{fill:#17becf;stroke:rgba(0, 0, 0, 0);}.epoch .arc.category10 path,.epoch.category10 .arc.category10 path{fill:#17becf;}.epoch .bar.category10,.epoch.category10 .bar.category10{fill:#17becf;}.epoch.category20 div.ref.category1{background-color:#1f77b4;}.epoch.category20 .category1 .line{stroke:#1f77b4;}.epoch.category20 .category1 .area,.epoch.category20 .category1 .dot{fill:#1f77b4;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category1 path{fill:#1f77b4;}.epoch.category20 .bar.category1{fill:#1f77b4;}.epoch.category20 div.ref.category2{background-color:#aec7e8;}.epoch.category20 .category2 .line{stroke:#aec7e8;}.epoch.category20 .category2 .area,.epoch.category20 .category2 .dot{fill:#aec7e8;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category2 path{fill:#aec7e8;}.epoch.category20 .bar.category2{fill:#aec7e8;}.epoch.category20 div.ref.category3{background-color:#ff7f0e;}.epoch.category20 .category3 .line{stroke:#ff7f0e;}.epoch.category20 .category3 .area,.epoch.category20 .category3 .dot{fill:#ff7f0e;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category3 path{fill:#ff7f0e;}.epoch.category20 .bar.category3{fill:#ff7f0e;}.epoch.category20 div.ref.category4{background-color:#ffbb78;}.epoch.category20 .category4 .line{stroke:#ffbb78;}.epoch.category20 .category4 .area,.epoch.category20 .category4 .dot{fill:#ffbb78;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category4 path{fill:#ffbb78;}.epoch.category20 .bar.category4{fill:#ffbb78;}.epoch.category20 div.ref.category5{background-color:#2ca02c;}.epoch.category20 .category5 .line{stroke:#2ca02c;}.epoch.category20 .category5 .area,.epoch.category20 .category5 .dot{fill:#2ca02c;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category5 path{fill:#2ca02c;}.epoch.category20 .bar.category5{fill:#2ca02c;}.epoch.category20 div.ref.category6{background-color:#98df8a;}.epoch.category20 .category6 .line{stroke:#98df8a;}.epoch.category20 .category6 .area,.epoch.category20 .category6 .dot{fill:#98df8a;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category6 path{fill:#98df8a;}.epoch.category20 .bar.category6{fill:#98df8a;}.epoch.category20 div.ref.category7{background-color:#d62728;}.epoch.category20 .category7 .line{stroke:#d62728;}.epoch.category20 .category7 .area,.epoch.category20 .category7 .dot{fill:#d62728;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category7 path{fill:#d62728;}.epoch.category20 .bar.category7{fill:#d62728;}.epoch.category20 div.ref.category8{background-color:#ff9896;}.epoch.category20 .category8 .line{stroke:#ff9896;}.epoch.category20 .category8 .area,.epoch.category20 .category8 .dot{fill:#ff9896;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category8 path{fill:#ff9896;}.epoch.category20 .bar.category8{fill:#ff9896;}.epoch.category20 div.ref.category9{background-color:#9467bd;}.epoch.category20 .category9 .line{stroke:#9467bd;}.epoch.category20 .category9 .area,.epoch.category20 .category9 .dot{fill:#9467bd;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category9 path{fill:#9467bd;}.epoch.category20 .bar.category9{fill:#9467bd;}.epoch.category20 div.ref.category10{background-color:#c5b0d5;}.epoch.category20 .category10 .line{stroke:#c5b0d5;}.epoch.category20 .category10 .area,.epoch.category20 .category10 .dot{fill:#c5b0d5;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category10 path{fill:#c5b0d5;}.epoch.category20 .bar.category10{fill:#c5b0d5;}.epoch.category20 div.ref.category11{background-color:#8c564b;}.epoch.category20 .category11 .line{stroke:#8c564b;}.epoch.category20 .category11 .area,.epoch.category20 .category11 .dot{fill:#8c564b;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category11 path{fill:#8c564b;}.epoch.category20 .bar.category11{fill:#8c564b;}.epoch.category20 div.ref.category12{background-color:#c49c94;}.epoch.category20 .category12 .line{stroke:#c49c94;}.epoch.category20 .category12 .area,.epoch.category20 .category12 .dot{fill:#c49c94;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category12 path{fill:#c49c94;}.epoch.category20 .bar.category12{fill:#c49c94;}.epoch.category20 div.ref.category13{background-color:#e377c2;}.epoch.category20 .category13 .line{stroke:#e377c2;}.epoch.category20 .category13 .area,.epoch.category20 .category13 .dot{fill:#e377c2;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category13 path{fill:#e377c2;}.epoch.category20 .bar.category13{fill:#e377c2;}.epoch.category20 div.ref.category14{background-color:#f7b6d2;}.epoch.category20 .category14 .line{stroke:#f7b6d2;}.epoch.category20 .category14 .area,.epoch.category20 .category14 .dot{fill:#f7b6d2;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category14 path{fill:#f7b6d2;}.epoch.category20 .bar.category14{fill:#f7b6d2;}.epoch.category20 div.ref.category15{background-color:#7f7f7f;}.epoch.category20 .category15 .line{stroke:#7f7f7f;}.epoch.category20 .category15 .area,.epoch.category20 .category15 .dot{fill:#7f7f7f;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category15 path{fill:#7f7f7f;}.epoch.category20 .bar.category15{fill:#7f7f7f;}.epoch.category20 div.ref.category16{background-color:#c7c7c7;}.epoch.category20 .category16 .line{stroke:#c7c7c7;}.epoch.category20 .category16 .area,.epoch.category20 .category16 .dot{fill:#c7c7c7;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category16 path{fill:#c7c7c7;}.epoch.category20 .bar.category16{fill:#c7c7c7;}.epoch.category20 div.ref.category17{background-color:#bcbd22;}.epoch.category20 .category17 .line{stroke:#bcbd22;}.epoch.category20 .category17 .area,.epoch.category20 .category17 .dot{fill:#bcbd22;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category17 path{fill:#bcbd22;}.epoch.category20 .bar.category17{fill:#bcbd22;}.epoch.category20 div.ref.category18{background-color:#dbdb8d;}.epoch.category20 .category18 .line{stroke:#dbdb8d;}.epoch.category20 .category18 .area,.epoch.category20 .category18 .dot{fill:#dbdb8d;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category18 path{fill:#dbdb8d;}.epoch.category20 .bar.category18{fill:#dbdb8d;}.epoch.category20 div.ref.category19{background-color:#17becf;}.epoch.category20 .category19 .line{stroke:#17becf;}.epoch.category20 .category19 .area,.epoch.category20 .category19 .dot{fill:#17becf;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category19 path{fill:#17becf;}.epoch.category20 .bar.category19{fill:#17becf;}.epoch.category20 div.ref.category20{background-color:#9edae5;}.epoch.category20 .category20 .line{stroke:#9edae5;}.epoch.category20 .category20 .area,.epoch.category20 .category20 .dot{fill:#9edae5;stroke:rgba(0, 0, 0, 0);}.epoch.category20 .arc.category20 path{fill:#9edae5;}.epoch.category20 .bar.category20{fill:#9edae5;}.epoch.category20b div.ref.category1{background-color:#393b79;}.epoch.category20b .category1 .line{stroke:#393b79;}.epoch.category20b .category1 .area,.epoch.category20b .category1 .dot{fill:#393b79;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category1 path{fill:#393b79;}.epoch.category20b .bar.category1{fill:#393b79;}.epoch.category20b div.ref.category2{background-color:#5254a3;}.epoch.category20b .category2 .line{stroke:#5254a3;}.epoch.category20b .category2 .area,.epoch.category20b .category2 .dot{fill:#5254a3;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category2 path{fill:#5254a3;}.epoch.category20b .bar.category2{fill:#5254a3;}.epoch.category20b div.ref.category3{background-color:#6b6ecf;}.epoch.category20b .category3 .line{stroke:#6b6ecf;}.epoch.category20b .category3 .area,.epoch.category20b .category3 .dot{fill:#6b6ecf;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category3 path{fill:#6b6ecf;}.epoch.category20b .bar.category3{fill:#6b6ecf;}.epoch.category20b div.ref.category4{background-color:#9c9ede;}.epoch.category20b .category4 .line{stroke:#9c9ede;}.epoch.category20b .category4 .area,.epoch.category20b .category4 .dot{fill:#9c9ede;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category4 path{fill:#9c9ede;}.epoch.category20b .bar.category4{fill:#9c9ede;}.epoch.category20b div.ref.category5{background-color:#637939;}.epoch.category20b .category5 .line{stroke:#637939;}.epoch.category20b .category5 .area,.epoch.category20b .category5 .dot{fill:#637939;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category5 path{fill:#637939;}.epoch.category20b .bar.category5{fill:#637939;}.epoch.category20b div.ref.category6{background-color:#8ca252;}.epoch.category20b .category6 .line{stroke:#8ca252;}.epoch.category20b .category6 .area,.epoch.category20b .category6 .dot{fill:#8ca252;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category6 path{fill:#8ca252;}.epoch.category20b .bar.category6{fill:#8ca252;}.epoch.category20b div.ref.category7{background-color:#b5cf6b;}.epoch.category20b .category7 .line{stroke:#b5cf6b;}.epoch.category20b .category7 .area,.epoch.category20b .category7 .dot{fill:#b5cf6b;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category7 path{fill:#b5cf6b;}.epoch.category20b .bar.category7{fill:#b5cf6b;}.epoch.category20b div.ref.category8{background-color:#cedb9c;}.epoch.category20b .category8 .line{stroke:#cedb9c;}.epoch.category20b .category8 .area,.epoch.category20b .category8 .dot{fill:#cedb9c;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category8 path{fill:#cedb9c;}.epoch.category20b .bar.category8{fill:#cedb9c;}.epoch.category20b div.ref.category9{background-color:#8c6d31;}.epoch.category20b .category9 .line{stroke:#8c6d31;}.epoch.category20b .category9 .area,.epoch.category20b .category9 .dot{fill:#8c6d31;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category9 path{fill:#8c6d31;}.epoch.category20b .bar.category9{fill:#8c6d31;}.epoch.category20b div.ref.category10{background-color:#bd9e39;}.epoch.category20b .category10 .line{stroke:#bd9e39;}.epoch.category20b .category10 .area,.epoch.category20b .category10 .dot{fill:#bd9e39;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category10 path{fill:#bd9e39;}.epoch.category20b .bar.category10{fill:#bd9e39;}.epoch.category20b div.ref.category11{background-color:#e7ba52;}.epoch.category20b .category11 .line{stroke:#e7ba52;}.epoch.category20b .category11 .area,.epoch.category20b .category11 .dot{fill:#e7ba52;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category11 path{fill:#e7ba52;}.epoch.category20b .bar.category11{fill:#e7ba52;}.epoch.category20b div.ref.category12{background-color:#e7cb94;}.epoch.category20b .category12 .line{stroke:#e7cb94;}.epoch.category20b .category12 .area,.epoch.category20b .category12 .dot{fill:#e7cb94;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category12 path{fill:#e7cb94;}.epoch.category20b .bar.category12{fill:#e7cb94;}.epoch.category20b div.ref.category13{background-color:#843c39;}.epoch.category20b .category13 .line{stroke:#843c39;}.epoch.category20b .category13 .area,.epoch.category20b .category13 .dot{fill:#843c39;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category13 path{fill:#843c39;}.epoch.category20b .bar.category13{fill:#843c39;}.epoch.category20b div.ref.category14{background-color:#ad494a;}.epoch.category20b .category14 .line{stroke:#ad494a;}.epoch.category20b .category14 .area,.epoch.category20b .category14 .dot{fill:#ad494a;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category14 path{fill:#ad494a;}.epoch.category20b .bar.category14{fill:#ad494a;}.epoch.category20b div.ref.category15{background-color:#d6616b;}.epoch.category20b .category15 .line{stroke:#d6616b;}.epoch.category20b .category15 .area,.epoch.category20b .category15 .dot{fill:#d6616b;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category15 path{fill:#d6616b;}.epoch.category20b .bar.category15{fill:#d6616b;}.epoch.category20b div.ref.category16{background-color:#e7969c;}.epoch.category20b .category16 .line{stroke:#e7969c;}.epoch.category20b .category16 .area,.epoch.category20b .category16 .dot{fill:#e7969c;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category16 path{fill:#e7969c;}.epoch.category20b .bar.category16{fill:#e7969c;}.epoch.category20b div.ref.category17{background-color:#7b4173;}.epoch.category20b .category17 .line{stroke:#7b4173;}.epoch.category20b .category17 .area,.epoch.category20b .category17 .dot{fill:#7b4173;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category17 path{fill:#7b4173;}.epoch.category20b .bar.category17{fill:#7b4173;}.epoch.category20b div.ref.category18{background-color:#a55194;}.epoch.category20b .category18 .line{stroke:#a55194;}.epoch.category20b .category18 .area,.epoch.category20b .category18 .dot{fill:#a55194;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category18 path{fill:#a55194;}.epoch.category20b .bar.category18{fill:#a55194;}.epoch.category20b div.ref.category19{background-color:#ce6dbd;}.epoch.category20b .category19 .line{stroke:#ce6dbd;}.epoch.category20b .category19 .area,.epoch.category20b .category19 .dot{fill:#ce6dbd;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category19 path{fill:#ce6dbd;}.epoch.category20b .bar.category19{fill:#ce6dbd;}.epoch.category20b div.ref.category20{background-color:#de9ed6;}.epoch.category20b .category20 .line{stroke:#de9ed6;}.epoch.category20b .category20 .area,.epoch.category20b .category20 .dot{fill:#de9ed6;stroke:rgba(0, 0, 0, 0);}.epoch.category20b .arc.category20 path{fill:#de9ed6;}.epoch.category20b .bar.category20{fill:#de9ed6;}.epoch.category20c div.ref.category1{background-color:#3182bd;}.epoch.category20c .category1 .line{stroke:#3182bd;}.epoch.category20c .category1 .area,.epoch.category20c .category1 .dot{fill:#3182bd;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category1 path{fill:#3182bd;}.epoch.category20c .bar.category1{fill:#3182bd;}.epoch.category20c div.ref.category2{background-color:#6baed6;}.epoch.category20c .category2 .line{stroke:#6baed6;}.epoch.category20c .category2 .area,.epoch.category20c .category2 .dot{fill:#6baed6;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category2 path{fill:#6baed6;}.epoch.category20c .bar.category2{fill:#6baed6;}.epoch.category20c div.ref.category3{background-color:#9ecae1;}.epoch.category20c .category3 .line{stroke:#9ecae1;}.epoch.category20c .category3 .area,.epoch.category20c .category3 .dot{fill:#9ecae1;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category3 path{fill:#9ecae1;}.epoch.category20c .bar.category3{fill:#9ecae1;}.epoch.category20c div.ref.category4{background-color:#c6dbef;}.epoch.category20c .category4 .line{stroke:#c6dbef;}.epoch.category20c .category4 .area,.epoch.category20c .category4 .dot{fill:#c6dbef;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category4 path{fill:#c6dbef;}.epoch.category20c .bar.category4{fill:#c6dbef;}.epoch.category20c div.ref.category5{background-color:#e6550d;}.epoch.category20c .category5 .line{stroke:#e6550d;}.epoch.category20c .category5 .area,.epoch.category20c .category5 .dot{fill:#e6550d;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category5 path{fill:#e6550d;}.epoch.category20c .bar.category5{fill:#e6550d;}.epoch.category20c div.ref.category6{background-color:#fd8d3c;}.epoch.category20c .category6 .line{stroke:#fd8d3c;}.epoch.category20c .category6 .area,.epoch.category20c .category6 .dot{fill:#fd8d3c;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category6 path{fill:#fd8d3c;}.epoch.category20c .bar.category6{fill:#fd8d3c;}.epoch.category20c div.ref.category7{background-color:#fdae6b;}.epoch.category20c .category7 .line{stroke:#fdae6b;}.epoch.category20c .category7 .area,.epoch.category20c .category7 .dot{fill:#fdae6b;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category7 path{fill:#fdae6b;}.epoch.category20c .bar.category7{fill:#fdae6b;}.epoch.category20c div.ref.category8{background-color:#fdd0a2;}.epoch.category20c .category8 .line{stroke:#fdd0a2;}.epoch.category20c .category8 .area,.epoch.category20c .category8 .dot{fill:#fdd0a2;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category8 path{fill:#fdd0a2;}.epoch.category20c .bar.category8{fill:#fdd0a2;}.epoch.category20c div.ref.category9{background-color:#31a354;}.epoch.category20c .category9 .line{stroke:#31a354;}.epoch.category20c .category9 .area,.epoch.category20c .category9 .dot{fill:#31a354;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category9 path{fill:#31a354;}.epoch.category20c .bar.category9{fill:#31a354;}.epoch.category20c div.ref.category10{background-color:#74c476;}.epoch.category20c .category10 .line{stroke:#74c476;}.epoch.category20c .category10 .area,.epoch.category20c .category10 .dot{fill:#74c476;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category10 path{fill:#74c476;}.epoch.category20c .bar.category10{fill:#74c476;}.epoch.category20c div.ref.category11{background-color:#a1d99b;}.epoch.category20c .category11 .line{stroke:#a1d99b;}.epoch.category20c .category11 .area,.epoch.category20c .category11 .dot{fill:#a1d99b;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category11 path{fill:#a1d99b;}.epoch.category20c .bar.category11{fill:#a1d99b;}.epoch.category20c div.ref.category12{background-color:#c7e9c0;}.epoch.category20c .category12 .line{stroke:#c7e9c0;}.epoch.category20c .category12 .area,.epoch.category20c .category12 .dot{fill:#c7e9c0;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category12 path{fill:#c7e9c0;}.epoch.category20c .bar.category12{fill:#c7e9c0;}.epoch.category20c div.ref.category13{background-color:#756bb1;}.epoch.category20c .category13 .line{stroke:#756bb1;}.epoch.category20c .category13 .area,.epoch.category20c .category13 .dot{fill:#756bb1;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category13 path{fill:#756bb1;}.epoch.category20c .bar.category13{fill:#756bb1;}.epoch.category20c div.ref.category14{background-color:#9e9ac8;}.epoch.category20c .category14 .line{stroke:#9e9ac8;}.epoch.category20c .category14 .area,.epoch.category20c .category14 .dot{fill:#9e9ac8;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category14 path{fill:#9e9ac8;}.epoch.category20c .bar.category14{fill:#9e9ac8;}.epoch.category20c div.ref.category15{background-color:#bcbddc;}.epoch.category20c .category15 .line{stroke:#bcbddc;}.epoch.category20c .category15 .area,.epoch.category20c .category15 .dot{fill:#bcbddc;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category15 path{fill:#bcbddc;}.epoch.category20c .bar.category15{fill:#bcbddc;}.epoch.category20c div.ref.category16{background-color:#dadaeb;}.epoch.category20c .category16 .line{stroke:#dadaeb;}.epoch.category20c .category16 .area,.epoch.category20c .category16 .dot{fill:#dadaeb;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category16 path{fill:#dadaeb;}.epoch.category20c .bar.category16{fill:#dadaeb;}.epoch.category20c div.ref.category17{background-color:#636363;}.epoch.category20c .category17 .line{stroke:#636363;}.epoch.category20c .category17 .area,.epoch.category20c .category17 .dot{fill:#636363;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category17 path{fill:#636363;}.epoch.category20c .bar.category17{fill:#636363;}.epoch.category20c div.ref.category18{background-color:#969696;}.epoch.category20c .category18 .line{stroke:#969696;}.epoch.category20c .category18 .area,.epoch.category20c .category18 .dot{fill:#969696;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category18 path{fill:#969696;}.epoch.category20c .bar.category18{fill:#969696;}.epoch.category20c div.ref.category19{background-color:#bdbdbd;}.epoch.category20c .category19 .line{stroke:#bdbdbd;}.epoch.category20c .category19 .area,.epoch.category20c .category19 .dot{fill:#bdbdbd;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category19 path{fill:#bdbdbd;}.epoch.category20c .bar.category19{fill:#bdbdbd;}.epoch.category20c div.ref.category20{background-color:#d9d9d9;}.epoch.category20c .category20 .line{stroke:#d9d9d9;}.epoch.category20c .category20 .area,.epoch.category20c .category20 .dot{fill:#d9d9d9;stroke:rgba(0, 0, 0, 0);}.epoch.category20c .arc.category20 path{fill:#d9d9d9;}.epoch.category20c .bar.category20{fill:#d9d9d9;}.epoch .category1 .bucket,.epoch.heatmap5 .category1 .bucket{fill:#1f77b4;}.epoch .category2 .bucket,.epoch.heatmap5 .category2 .bucket{fill:#2ca02c;}.epoch .category3 .bucket,.epoch.heatmap5 .category3 .bucket{fill:#d62728;}.epoch .category4 .bucket,.epoch.heatmap5 .category4 .bucket{fill:#8c564b;}.epoch .category5 .bucket,.epoch.heatmap5 .category5 .bucket{fill:#7f7f7f;}.epoch-theme-dark .epoch .axis path,.epoch-theme-dark .epoch .axis line{stroke:#d0d0d0;}.epoch-theme-dark .epoch .axis .tick text{fill:#d0d0d0;}.epoch-theme-dark .arc.pie{stroke:#333;}.epoch-theme-dark .arc.pie text{fill:#333;}.epoch-theme-dark .epoch .gauge-labels .value{fill:#BBB;}.epoch-theme-dark .epoch .gauge .arc.outer{stroke:#999;}.epoch-theme-dark .epoch .gauge .arc.inner{stroke:#AAA;}.epoch-theme-dark .epoch .gauge .tick{stroke:#AAA;}.epoch-theme-dark .epoch .gauge .needle{fill:#F3DE88;}.epoch-theme-dark .epoch .gauge .needle-base{fill:#999;}.epoch-theme-dark .epoch div.ref.category1,.epoch-theme-dark .epoch.category10 div.ref.category1{background-color:#909CFF;}.epoch-theme-dark .epoch .category1 .line,.epoch-theme-dark .epoch.category10 .category1 .line{stroke:#909CFF;}.epoch-theme-dark .epoch .category1 .area,.epoch-theme-dark .epoch .category1 .dot,.epoch-theme-dark .epoch.category10 .category1 .area,.epoch-theme-dark .epoch.category10 .category1 .dot{fill:#909CFF;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category1 path,.epoch-theme-dark .epoch.category10 .arc.category1 path{fill:#909CFF;}.epoch-theme-dark .epoch .bar.category1,.epoch-theme-dark .epoch.category10 .bar.category1{fill:#909CFF;}.epoch-theme-dark .epoch div.ref.category2,.epoch-theme-dark .epoch.category10 div.ref.category2{background-color:#FFAC89;}.epoch-theme-dark .epoch .category2 .line,.epoch-theme-dark .epoch.category10 .category2 .line{stroke:#FFAC89;}.epoch-theme-dark .epoch .category2 .area,.epoch-theme-dark .epoch .category2 .dot,.epoch-theme-dark .epoch.category10 .category2 .area,.epoch-theme-dark .epoch.category10 .category2 .dot{fill:#FFAC89;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category2 path,.epoch-theme-dark .epoch.category10 .arc.category2 path{fill:#FFAC89;}.epoch-theme-dark .epoch .bar.category2,.epoch-theme-dark .epoch.category10 .bar.category2{fill:#FFAC89;}.epoch-theme-dark .epoch div.ref.category3,.epoch-theme-dark .epoch.category10 div.ref.category3{background-color:#E889E8;}.epoch-theme-dark .epoch .category3 .line,.epoch-theme-dark .epoch.category10 .category3 .line{stroke:#E889E8;}.epoch-theme-dark .epoch .category3 .area,.epoch-theme-dark .epoch .category3 .dot,.epoch-theme-dark .epoch.category10 .category3 .area,.epoch-theme-dark .epoch.category10 .category3 .dot{fill:#E889E8;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category3 path,.epoch-theme-dark .epoch.category10 .arc.category3 path{fill:#E889E8;}.epoch-theme-dark .epoch .bar.category3,.epoch-theme-dark .epoch.category10 .bar.category3{fill:#E889E8;}.epoch-theme-dark .epoch div.ref.category4,.epoch-theme-dark .epoch.category10 div.ref.category4{background-color:#78E8D3;}.epoch-theme-dark .epoch .category4 .line,.epoch-theme-dark .epoch.category10 .category4 .line{stroke:#78E8D3;}.epoch-theme-dark .epoch .category4 .area,.epoch-theme-dark .epoch .category4 .dot,.epoch-theme-dark .epoch.category10 .category4 .area,.epoch-theme-dark .epoch.category10 .category4 .dot{fill:#78E8D3;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category4 path,.epoch-theme-dark .epoch.category10 .arc.category4 path{fill:#78E8D3;}.epoch-theme-dark .epoch .bar.category4,.epoch-theme-dark .epoch.category10 .bar.category4{fill:#78E8D3;}.epoch-theme-dark .epoch div.ref.category5,.epoch-theme-dark .epoch.category10 div.ref.category5{background-color:#C2FF97;}.epoch-theme-dark .epoch .category5 .line,.epoch-theme-dark .epoch.category10 .category5 .line{stroke:#C2FF97;}.epoch-theme-dark .epoch .category5 .area,.epoch-theme-dark .epoch .category5 .dot,.epoch-theme-dark .epoch.category10 .category5 .area,.epoch-theme-dark .epoch.category10 .category5 .dot{fill:#C2FF97;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category5 path,.epoch-theme-dark .epoch.category10 .arc.category5 path{fill:#C2FF97;}.epoch-theme-dark .epoch .bar.category5,.epoch-theme-dark .epoch.category10 .bar.category5{fill:#C2FF97;}.epoch-theme-dark .epoch div.ref.category6,.epoch-theme-dark .epoch.category10 div.ref.category6{background-color:#B7BCD1;}.epoch-theme-dark .epoch .category6 .line,.epoch-theme-dark .epoch.category10 .category6 .line{stroke:#B7BCD1;}.epoch-theme-dark .epoch .category6 .area,.epoch-theme-dark .epoch .category6 .dot,.epoch-theme-dark .epoch.category10 .category6 .area,.epoch-theme-dark .epoch.category10 .category6 .dot{fill:#B7BCD1;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category6 path,.epoch-theme-dark .epoch.category10 .arc.category6 path{fill:#B7BCD1;}.epoch-theme-dark .epoch .bar.category6,.epoch-theme-dark .epoch.category10 .bar.category6{fill:#B7BCD1;}.epoch-theme-dark .epoch div.ref.category7,.epoch-theme-dark .epoch.category10 div.ref.category7{background-color:#FF857F;}.epoch-theme-dark .epoch .category7 .line,.epoch-theme-dark .epoch.category10 .category7 .line{stroke:#FF857F;}.epoch-theme-dark .epoch .category7 .area,.epoch-theme-dark .epoch .category7 .dot,.epoch-theme-dark .epoch.category10 .category7 .area,.epoch-theme-dark .epoch.category10 .category7 .dot{fill:#FF857F;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category7 path,.epoch-theme-dark .epoch.category10 .arc.category7 path{fill:#FF857F;}.epoch-theme-dark .epoch .bar.category7,.epoch-theme-dark .epoch.category10 .bar.category7{fill:#FF857F;}.epoch-theme-dark .epoch div.ref.category8,.epoch-theme-dark .epoch.category10 div.ref.category8{background-color:#F3DE88;}.epoch-theme-dark .epoch .category8 .line,.epoch-theme-dark .epoch.category10 .category8 .line{stroke:#F3DE88;}.epoch-theme-dark .epoch .category8 .area,.epoch-theme-dark .epoch .category8 .dot,.epoch-theme-dark .epoch.category10 .category8 .area,.epoch-theme-dark .epoch.category10 .category8 .dot{fill:#F3DE88;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category8 path,.epoch-theme-dark .epoch.category10 .arc.category8 path{fill:#F3DE88;}.epoch-theme-dark .epoch .bar.category8,.epoch-theme-dark .epoch.category10 .bar.category8{fill:#F3DE88;}.epoch-theme-dark .epoch div.ref.category9,.epoch-theme-dark .epoch.category10 div.ref.category9{background-color:#C9935E;}.epoch-theme-dark .epoch .category9 .line,.epoch-theme-dark .epoch.category10 .category9 .line{stroke:#C9935E;}.epoch-theme-dark .epoch .category9 .area,.epoch-theme-dark .epoch .category9 .dot,.epoch-theme-dark .epoch.category10 .category9 .area,.epoch-theme-dark .epoch.category10 .category9 .dot{fill:#C9935E;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category9 path,.epoch-theme-dark .epoch.category10 .arc.category9 path{fill:#C9935E;}.epoch-theme-dark .epoch .bar.category9,.epoch-theme-dark .epoch.category10 .bar.category9{fill:#C9935E;}.epoch-theme-dark .epoch div.ref.category10,.epoch-theme-dark .epoch.category10 div.ref.category10{background-color:#A488FF;}.epoch-theme-dark .epoch .category10 .line,.epoch-theme-dark .epoch.category10 .category10 .line{stroke:#A488FF;}.epoch-theme-dark .epoch .category10 .area,.epoch-theme-dark .epoch .category10 .dot,.epoch-theme-dark .epoch.category10 .category10 .area,.epoch-theme-dark .epoch.category10 .category10 .dot{fill:#A488FF;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch .arc.category10 path,.epoch-theme-dark .epoch.category10 .arc.category10 path{fill:#A488FF;}.epoch-theme-dark .epoch .bar.category10,.epoch-theme-dark .epoch.category10 .bar.category10{fill:#A488FF;}.epoch-theme-dark .epoch.category20 div.ref.category1{background-color:#909CFF;}.epoch-theme-dark .epoch.category20 .category1 .line{stroke:#909CFF;}.epoch-theme-dark .epoch.category20 .category1 .area,.epoch-theme-dark .epoch.category20 .category1 .dot{fill:#909CFF;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category1 path{fill:#909CFF;}.epoch-theme-dark .epoch.category20 .bar.category1{fill:#909CFF;}.epoch-theme-dark .epoch.category20 div.ref.category2{background-color:#626AAD;}.epoch-theme-dark .epoch.category20 .category2 .line{stroke:#626AAD;}.epoch-theme-dark .epoch.category20 .category2 .area,.epoch-theme-dark .epoch.category20 .category2 .dot{fill:#626AAD;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category2 path{fill:#626AAD;}.epoch-theme-dark .epoch.category20 .bar.category2{fill:#626AAD;}.epoch-theme-dark .epoch.category20 div.ref.category3{background-color:#FFAC89;}.epoch-theme-dark .epoch.category20 .category3 .line{stroke:#FFAC89;}.epoch-theme-dark .epoch.category20 .category3 .area,.epoch-theme-dark .epoch.category20 .category3 .dot{fill:#FFAC89;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category3 path{fill:#FFAC89;}.epoch-theme-dark .epoch.category20 .bar.category3{fill:#FFAC89;}.epoch-theme-dark .epoch.category20 div.ref.category4{background-color:#BD7F66;}.epoch-theme-dark .epoch.category20 .category4 .line{stroke:#BD7F66;}.epoch-theme-dark .epoch.category20 .category4 .area,.epoch-theme-dark .epoch.category20 .category4 .dot{fill:#BD7F66;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category4 path{fill:#BD7F66;}.epoch-theme-dark .epoch.category20 .bar.category4{fill:#BD7F66;}.epoch-theme-dark .epoch.category20 div.ref.category5{background-color:#E889E8;}.epoch-theme-dark .epoch.category20 .category5 .line{stroke:#E889E8;}.epoch-theme-dark .epoch.category20 .category5 .area,.epoch-theme-dark .epoch.category20 .category5 .dot{fill:#E889E8;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category5 path{fill:#E889E8;}.epoch-theme-dark .epoch.category20 .bar.category5{fill:#E889E8;}.epoch-theme-dark .epoch.category20 div.ref.category6{background-color:#995A99;}.epoch-theme-dark .epoch.category20 .category6 .line{stroke:#995A99;}.epoch-theme-dark .epoch.category20 .category6 .area,.epoch-theme-dark .epoch.category20 .category6 .dot{fill:#995A99;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category6 path{fill:#995A99;}.epoch-theme-dark .epoch.category20 .bar.category6{fill:#995A99;}.epoch-theme-dark .epoch.category20 div.ref.category7{background-color:#78E8D3;}.epoch-theme-dark .epoch.category20 .category7 .line{stroke:#78E8D3;}.epoch-theme-dark .epoch.category20 .category7 .area,.epoch-theme-dark .epoch.category20 .category7 .dot{fill:#78E8D3;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category7 path{fill:#78E8D3;}.epoch-theme-dark .epoch.category20 .bar.category7{fill:#78E8D3;}.epoch-theme-dark .epoch.category20 div.ref.category8{background-color:#4F998C;}.epoch-theme-dark .epoch.category20 .category8 .line{stroke:#4F998C;}.epoch-theme-dark .epoch.category20 .category8 .area,.epoch-theme-dark .epoch.category20 .category8 .dot{fill:#4F998C;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category8 path{fill:#4F998C;}.epoch-theme-dark .epoch.category20 .bar.category8{fill:#4F998C;}.epoch-theme-dark .epoch.category20 div.ref.category9{background-color:#C2FF97;}.epoch-theme-dark .epoch.category20 .category9 .line{stroke:#C2FF97;}.epoch-theme-dark .epoch.category20 .category9 .area,.epoch-theme-dark .epoch.category20 .category9 .dot{fill:#C2FF97;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category9 path{fill:#C2FF97;}.epoch-theme-dark .epoch.category20 .bar.category9{fill:#C2FF97;}.epoch-theme-dark .epoch.category20 div.ref.category10{background-color:#789E5E;}.epoch-theme-dark .epoch.category20 .category10 .line{stroke:#789E5E;}.epoch-theme-dark .epoch.category20 .category10 .area,.epoch-theme-dark .epoch.category20 .category10 .dot{fill:#789E5E;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category10 path{fill:#789E5E;}.epoch-theme-dark .epoch.category20 .bar.category10{fill:#789E5E;}.epoch-theme-dark .epoch.category20 div.ref.category11{background-color:#B7BCD1;}.epoch-theme-dark .epoch.category20 .category11 .line{stroke:#B7BCD1;}.epoch-theme-dark .epoch.category20 .category11 .area,.epoch-theme-dark .epoch.category20 .category11 .dot{fill:#B7BCD1;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category11 path{fill:#B7BCD1;}.epoch-theme-dark .epoch.category20 .bar.category11{fill:#B7BCD1;}.epoch-theme-dark .epoch.category20 div.ref.category12{background-color:#7F8391;}.epoch-theme-dark .epoch.category20 .category12 .line{stroke:#7F8391;}.epoch-theme-dark .epoch.category20 .category12 .area,.epoch-theme-dark .epoch.category20 .category12 .dot{fill:#7F8391;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category12 path{fill:#7F8391;}.epoch-theme-dark .epoch.category20 .bar.category12{fill:#7F8391;}.epoch-theme-dark .epoch.category20 div.ref.category13{background-color:#CCB889;}.epoch-theme-dark .epoch.category20 .category13 .line{stroke:#CCB889;}.epoch-theme-dark .epoch.category20 .category13 .area,.epoch-theme-dark .epoch.category20 .category13 .dot{fill:#CCB889;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category13 path{fill:#CCB889;}.epoch-theme-dark .epoch.category20 .bar.category13{fill:#CCB889;}.epoch-theme-dark .epoch.category20 div.ref.category14{background-color:#A1906B;}.epoch-theme-dark .epoch.category20 .category14 .line{stroke:#A1906B;}.epoch-theme-dark .epoch.category20 .category14 .area,.epoch-theme-dark .epoch.category20 .category14 .dot{fill:#A1906B;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category14 path{fill:#A1906B;}.epoch-theme-dark .epoch.category20 .bar.category14{fill:#A1906B;}.epoch-theme-dark .epoch.category20 div.ref.category15{background-color:#F3DE88;}.epoch-theme-dark .epoch.category20 .category15 .line{stroke:#F3DE88;}.epoch-theme-dark .epoch.category20 .category15 .area,.epoch-theme-dark .epoch.category20 .category15 .dot{fill:#F3DE88;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category15 path{fill:#F3DE88;}.epoch-theme-dark .epoch.category20 .bar.category15{fill:#F3DE88;}.epoch-theme-dark .epoch.category20 div.ref.category16{background-color:#A89A5E;}.epoch-theme-dark .epoch.category20 .category16 .line{stroke:#A89A5E;}.epoch-theme-dark .epoch.category20 .category16 .area,.epoch-theme-dark .epoch.category20 .category16 .dot{fill:#A89A5E;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category16 path{fill:#A89A5E;}.epoch-theme-dark .epoch.category20 .bar.category16{fill:#A89A5E;}.epoch-theme-dark .epoch.category20 div.ref.category17{background-color:#FF857F;}.epoch-theme-dark .epoch.category20 .category17 .line{stroke:#FF857F;}.epoch-theme-dark .epoch.category20 .category17 .area,.epoch-theme-dark .epoch.category20 .category17 .dot{fill:#FF857F;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category17 path{fill:#FF857F;}.epoch-theme-dark .epoch.category20 .bar.category17{fill:#FF857F;}.epoch-theme-dark .epoch.category20 div.ref.category18{background-color:#BA615D;}.epoch-theme-dark .epoch.category20 .category18 .line{stroke:#BA615D;}.epoch-theme-dark .epoch.category20 .category18 .area,.epoch-theme-dark .epoch.category20 .category18 .dot{fill:#BA615D;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category18 path{fill:#BA615D;}.epoch-theme-dark .epoch.category20 .bar.category18{fill:#BA615D;}.epoch-theme-dark .epoch.category20 div.ref.category19{background-color:#A488FF;}.epoch-theme-dark .epoch.category20 .category19 .line{stroke:#A488FF;}.epoch-theme-dark .epoch.category20 .category19 .area,.epoch-theme-dark .epoch.category20 .category19 .dot{fill:#A488FF;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category19 path{fill:#A488FF;}.epoch-theme-dark .epoch.category20 .bar.category19{fill:#A488FF;}.epoch-theme-dark .epoch.category20 div.ref.category20{background-color:#7662B8;}.epoch-theme-dark .epoch.category20 .category20 .line{stroke:#7662B8;}.epoch-theme-dark .epoch.category20 .category20 .area,.epoch-theme-dark .epoch.category20 .category20 .dot{fill:#7662B8;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20 .arc.category20 path{fill:#7662B8;}.epoch-theme-dark .epoch.category20 .bar.category20{fill:#7662B8;}.epoch-theme-dark .epoch.category20b div.ref.category1{background-color:#909CFF;}.epoch-theme-dark .epoch.category20b .category1 .line{stroke:#909CFF;}.epoch-theme-dark .epoch.category20b .category1 .area,.epoch-theme-dark .epoch.category20b .category1 .dot{fill:#909CFF;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category1 path{fill:#909CFF;}.epoch-theme-dark .epoch.category20b .bar.category1{fill:#909CFF;}.epoch-theme-dark .epoch.category20b div.ref.category2{background-color:#7680D1;}.epoch-theme-dark .epoch.category20b .category2 .line{stroke:#7680D1;}.epoch-theme-dark .epoch.category20b .category2 .area,.epoch-theme-dark .epoch.category20b .category2 .dot{fill:#7680D1;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category2 path{fill:#7680D1;}.epoch-theme-dark .epoch.category20b .bar.category2{fill:#7680D1;}.epoch-theme-dark .epoch.category20b div.ref.category3{background-color:#656DB2;}.epoch-theme-dark .epoch.category20b .category3 .line{stroke:#656DB2;}.epoch-theme-dark .epoch.category20b .category3 .area,.epoch-theme-dark .epoch.category20b .category3 .dot{fill:#656DB2;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category3 path{fill:#656DB2;}.epoch-theme-dark .epoch.category20b .bar.category3{fill:#656DB2;}.epoch-theme-dark .epoch.category20b div.ref.category4{background-color:#525992;}.epoch-theme-dark .epoch.category20b .category4 .line{stroke:#525992;}.epoch-theme-dark .epoch.category20b .category4 .area,.epoch-theme-dark .epoch.category20b .category4 .dot{fill:#525992;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category4 path{fill:#525992;}.epoch-theme-dark .epoch.category20b .bar.category4{fill:#525992;}.epoch-theme-dark .epoch.category20b div.ref.category5{background-color:#FFAC89;}.epoch-theme-dark .epoch.category20b .category5 .line{stroke:#FFAC89;}.epoch-theme-dark .epoch.category20b .category5 .area,.epoch-theme-dark .epoch.category20b .category5 .dot{fill:#FFAC89;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category5 path{fill:#FFAC89;}.epoch-theme-dark .epoch.category20b .bar.category5{fill:#FFAC89;}.epoch-theme-dark .epoch.category20b div.ref.category6{background-color:#D18D71;}.epoch-theme-dark .epoch.category20b .category6 .line{stroke:#D18D71;}.epoch-theme-dark .epoch.category20b .category6 .area,.epoch-theme-dark .epoch.category20b .category6 .dot{fill:#D18D71;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category6 path{fill:#D18D71;}.epoch-theme-dark .epoch.category20b .bar.category6{fill:#D18D71;}.epoch-theme-dark .epoch.category20b div.ref.category7{background-color:#AB735C;}.epoch-theme-dark .epoch.category20b .category7 .line{stroke:#AB735C;}.epoch-theme-dark .epoch.category20b .category7 .area,.epoch-theme-dark .epoch.category20b .category7 .dot{fill:#AB735C;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category7 path{fill:#AB735C;}.epoch-theme-dark .epoch.category20b .bar.category7{fill:#AB735C;}.epoch-theme-dark .epoch.category20b div.ref.category8{background-color:#92624E;}.epoch-theme-dark .epoch.category20b .category8 .line{stroke:#92624E;}.epoch-theme-dark .epoch.category20b .category8 .area,.epoch-theme-dark .epoch.category20b .category8 .dot{fill:#92624E;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category8 path{fill:#92624E;}.epoch-theme-dark .epoch.category20b .bar.category8{fill:#92624E;}.epoch-theme-dark .epoch.category20b div.ref.category9{background-color:#E889E8;}.epoch-theme-dark .epoch.category20b .category9 .line{stroke:#E889E8;}.epoch-theme-dark .epoch.category20b .category9 .area,.epoch-theme-dark .epoch.category20b .category9 .dot{fill:#E889E8;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category9 path{fill:#E889E8;}.epoch-theme-dark .epoch.category20b .bar.category9{fill:#E889E8;}.epoch-theme-dark .epoch.category20b div.ref.category10{background-color:#BA6EBA;}.epoch-theme-dark .epoch.category20b .category10 .line{stroke:#BA6EBA;}.epoch-theme-dark .epoch.category20b .category10 .area,.epoch-theme-dark .epoch.category20b .category10 .dot{fill:#BA6EBA;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category10 path{fill:#BA6EBA;}.epoch-theme-dark .epoch.category20b .bar.category10{fill:#BA6EBA;}.epoch-theme-dark .epoch.category20b div.ref.category11{background-color:#9B5C9B;}.epoch-theme-dark .epoch.category20b .category11 .line{stroke:#9B5C9B;}.epoch-theme-dark .epoch.category20b .category11 .area,.epoch-theme-dark .epoch.category20b .category11 .dot{fill:#9B5C9B;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category11 path{fill:#9B5C9B;}.epoch-theme-dark .epoch.category20b .bar.category11{fill:#9B5C9B;}.epoch-theme-dark .epoch.category20b div.ref.category12{background-color:#7B487B;}.epoch-theme-dark .epoch.category20b .category12 .line{stroke:#7B487B;}.epoch-theme-dark .epoch.category20b .category12 .area,.epoch-theme-dark .epoch.category20b .category12 .dot{fill:#7B487B;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category12 path{fill:#7B487B;}.epoch-theme-dark .epoch.category20b .bar.category12{fill:#7B487B;}.epoch-theme-dark .epoch.category20b div.ref.category13{background-color:#78E8D3;}.epoch-theme-dark .epoch.category20b .category13 .line{stroke:#78E8D3;}.epoch-theme-dark .epoch.category20b .category13 .area,.epoch-theme-dark .epoch.category20b .category13 .dot{fill:#78E8D3;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category13 path{fill:#78E8D3;}.epoch-theme-dark .epoch.category20b .bar.category13{fill:#78E8D3;}.epoch-theme-dark .epoch.category20b div.ref.category14{background-color:#60BAAA;}.epoch-theme-dark .epoch.category20b .category14 .line{stroke:#60BAAA;}.epoch-theme-dark .epoch.category20b .category14 .area,.epoch-theme-dark .epoch.category20b .category14 .dot{fill:#60BAAA;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category14 path{fill:#60BAAA;}.epoch-theme-dark .epoch.category20b .bar.category14{fill:#60BAAA;}.epoch-theme-dark .epoch.category20b div.ref.category15{background-color:#509B8D;}.epoch-theme-dark .epoch.category20b .category15 .line{stroke:#509B8D;}.epoch-theme-dark .epoch.category20b .category15 .area,.epoch-theme-dark .epoch.category20b .category15 .dot{fill:#509B8D;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category15 path{fill:#509B8D;}.epoch-theme-dark .epoch.category20b .bar.category15{fill:#509B8D;}.epoch-theme-dark .epoch.category20b div.ref.category16{background-color:#3F7B70;}.epoch-theme-dark .epoch.category20b .category16 .line{stroke:#3F7B70;}.epoch-theme-dark .epoch.category20b .category16 .area,.epoch-theme-dark .epoch.category20b .category16 .dot{fill:#3F7B70;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category16 path{fill:#3F7B70;}.epoch-theme-dark .epoch.category20b .bar.category16{fill:#3F7B70;}.epoch-theme-dark .epoch.category20b div.ref.category17{background-color:#C2FF97;}.epoch-theme-dark .epoch.category20b .category17 .line{stroke:#C2FF97;}.epoch-theme-dark .epoch.category20b .category17 .area,.epoch-theme-dark .epoch.category20b .category17 .dot{fill:#C2FF97;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category17 path{fill:#C2FF97;}.epoch-theme-dark .epoch.category20b .bar.category17{fill:#C2FF97;}.epoch-theme-dark .epoch.category20b div.ref.category18{background-color:#9FD17C;}.epoch-theme-dark .epoch.category20b .category18 .line{stroke:#9FD17C;}.epoch-theme-dark .epoch.category20b .category18 .area,.epoch-theme-dark .epoch.category20b .category18 .dot{fill:#9FD17C;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category18 path{fill:#9FD17C;}.epoch-theme-dark .epoch.category20b .bar.category18{fill:#9FD17C;}.epoch-theme-dark .epoch.category20b div.ref.category19{background-color:#7DA361;}.epoch-theme-dark .epoch.category20b .category19 .line{stroke:#7DA361;}.epoch-theme-dark .epoch.category20b .category19 .area,.epoch-theme-dark .epoch.category20b .category19 .dot{fill:#7DA361;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category19 path{fill:#7DA361;}.epoch-theme-dark .epoch.category20b .bar.category19{fill:#7DA361;}.epoch-theme-dark .epoch.category20b div.ref.category20{background-color:#65854E;}.epoch-theme-dark .epoch.category20b .category20 .line{stroke:#65854E;}.epoch-theme-dark .epoch.category20b .category20 .area,.epoch-theme-dark .epoch.category20b .category20 .dot{fill:#65854E;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20b .arc.category20 path{fill:#65854E;}.epoch-theme-dark .epoch.category20b .bar.category20{fill:#65854E;}.epoch-theme-dark .epoch.category20c div.ref.category1{background-color:#B7BCD1;}.epoch-theme-dark .epoch.category20c .category1 .line{stroke:#B7BCD1;}.epoch-theme-dark .epoch.category20c .category1 .area,.epoch-theme-dark .epoch.category20c .category1 .dot{fill:#B7BCD1;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category1 path{fill:#B7BCD1;}.epoch-theme-dark .epoch.category20c .bar.category1{fill:#B7BCD1;}.epoch-theme-dark .epoch.category20c div.ref.category2{background-color:#979DAD;}.epoch-theme-dark .epoch.category20c .category2 .line{stroke:#979DAD;}.epoch-theme-dark .epoch.category20c .category2 .area,.epoch-theme-dark .epoch.category20c .category2 .dot{fill:#979DAD;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category2 path{fill:#979DAD;}.epoch-theme-dark .epoch.category20c .bar.category2{fill:#979DAD;}.epoch-theme-dark .epoch.category20c div.ref.category3{background-color:#6E717D;}.epoch-theme-dark .epoch.category20c .category3 .line{stroke:#6E717D;}.epoch-theme-dark .epoch.category20c .category3 .area,.epoch-theme-dark .epoch.category20c .category3 .dot{fill:#6E717D;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category3 path{fill:#6E717D;}.epoch-theme-dark .epoch.category20c .bar.category3{fill:#6E717D;}.epoch-theme-dark .epoch.category20c div.ref.category4{background-color:#595C66;}.epoch-theme-dark .epoch.category20c .category4 .line{stroke:#595C66;}.epoch-theme-dark .epoch.category20c .category4 .area,.epoch-theme-dark .epoch.category20c .category4 .dot{fill:#595C66;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category4 path{fill:#595C66;}.epoch-theme-dark .epoch.category20c .bar.category4{fill:#595C66;}.epoch-theme-dark .epoch.category20c div.ref.category5{background-color:#FF857F;}.epoch-theme-dark .epoch.category20c .category5 .line{stroke:#FF857F;}.epoch-theme-dark .epoch.category20c .category5 .area,.epoch-theme-dark .epoch.category20c .category5 .dot{fill:#FF857F;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category5 path{fill:#FF857F;}.epoch-theme-dark .epoch.category20c .bar.category5{fill:#FF857F;}.epoch-theme-dark .epoch.category20c div.ref.category6{background-color:#DE746E;}.epoch-theme-dark .epoch.category20c .category6 .line{stroke:#DE746E;}.epoch-theme-dark .epoch.category20c .category6 .area,.epoch-theme-dark .epoch.category20c .category6 .dot{fill:#DE746E;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category6 path{fill:#DE746E;}.epoch-theme-dark .epoch.category20c .bar.category6{fill:#DE746E;}.epoch-theme-dark .epoch.category20c div.ref.category7{background-color:#B55F5A;}.epoch-theme-dark .epoch.category20c .category7 .line{stroke:#B55F5A;}.epoch-theme-dark .epoch.category20c .category7 .area,.epoch-theme-dark .epoch.category20c .category7 .dot{fill:#B55F5A;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category7 path{fill:#B55F5A;}.epoch-theme-dark .epoch.category20c .bar.category7{fill:#B55F5A;}.epoch-theme-dark .epoch.category20c div.ref.category8{background-color:#964E4B;}.epoch-theme-dark .epoch.category20c .category8 .line{stroke:#964E4B;}.epoch-theme-dark .epoch.category20c .category8 .area,.epoch-theme-dark .epoch.category20c .category8 .dot{fill:#964E4B;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category8 path{fill:#964E4B;}.epoch-theme-dark .epoch.category20c .bar.category8{fill:#964E4B;}.epoch-theme-dark .epoch.category20c div.ref.category9{background-color:#F3DE88;}.epoch-theme-dark .epoch.category20c .category9 .line{stroke:#F3DE88;}.epoch-theme-dark .epoch.category20c .category9 .area,.epoch-theme-dark .epoch.category20c .category9 .dot{fill:#F3DE88;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category9 path{fill:#F3DE88;}.epoch-theme-dark .epoch.category20c .bar.category9{fill:#F3DE88;}.epoch-theme-dark .epoch.category20c div.ref.category10{background-color:#DBC87B;}.epoch-theme-dark .epoch.category20c .category10 .line{stroke:#DBC87B;}.epoch-theme-dark .epoch.category20c .category10 .area,.epoch-theme-dark .epoch.category20c .category10 .dot{fill:#DBC87B;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category10 path{fill:#DBC87B;}.epoch-theme-dark .epoch.category20c .bar.category10{fill:#DBC87B;}.epoch-theme-dark .epoch.category20c div.ref.category11{background-color:#BAAA68;}.epoch-theme-dark .epoch.category20c .category11 .line{stroke:#BAAA68;}.epoch-theme-dark .epoch.category20c .category11 .area,.epoch-theme-dark .epoch.category20c .category11 .dot{fill:#BAAA68;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category11 path{fill:#BAAA68;}.epoch-theme-dark .epoch.category20c .bar.category11{fill:#BAAA68;}.epoch-theme-dark .epoch.category20c div.ref.category12{background-color:#918551;}.epoch-theme-dark .epoch.category20c .category12 .line{stroke:#918551;}.epoch-theme-dark .epoch.category20c .category12 .area,.epoch-theme-dark .epoch.category20c .category12 .dot{fill:#918551;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category12 path{fill:#918551;}.epoch-theme-dark .epoch.category20c .bar.category12{fill:#918551;}.epoch-theme-dark .epoch.category20c div.ref.category13{background-color:#C9935E;}.epoch-theme-dark .epoch.category20c .category13 .line{stroke:#C9935E;}.epoch-theme-dark .epoch.category20c .category13 .area,.epoch-theme-dark .epoch.category20c .category13 .dot{fill:#C9935E;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category13 path{fill:#C9935E;}.epoch-theme-dark .epoch.category20c .bar.category13{fill:#C9935E;}.epoch-theme-dark .epoch.category20c div.ref.category14{background-color:#B58455;}.epoch-theme-dark .epoch.category20c .category14 .line{stroke:#B58455;}.epoch-theme-dark .epoch.category20c .category14 .area,.epoch-theme-dark .epoch.category20c .category14 .dot{fill:#B58455;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category14 path{fill:#B58455;}.epoch-theme-dark .epoch.category20c .bar.category14{fill:#B58455;}.epoch-theme-dark .epoch.category20c div.ref.category15{background-color:#997048;}.epoch-theme-dark .epoch.category20c .category15 .line{stroke:#997048;}.epoch-theme-dark .epoch.category20c .category15 .area,.epoch-theme-dark .epoch.category20c .category15 .dot{fill:#997048;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category15 path{fill:#997048;}.epoch-theme-dark .epoch.category20c .bar.category15{fill:#997048;}.epoch-theme-dark .epoch.category20c div.ref.category16{background-color:#735436;}.epoch-theme-dark .epoch.category20c .category16 .line{stroke:#735436;}.epoch-theme-dark .epoch.category20c .category16 .area,.epoch-theme-dark .epoch.category20c .category16 .dot{fill:#735436;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category16 path{fill:#735436;}.epoch-theme-dark .epoch.category20c .bar.category16{fill:#735436;}.epoch-theme-dark .epoch.category20c div.ref.category17{background-color:#A488FF;}.epoch-theme-dark .epoch.category20c .category17 .line{stroke:#A488FF;}.epoch-theme-dark .epoch.category20c .category17 .area,.epoch-theme-dark .epoch.category20c .category17 .dot{fill:#A488FF;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category17 path{fill:#A488FF;}.epoch-theme-dark .epoch.category20c .bar.category17{fill:#A488FF;}.epoch-theme-dark .epoch.category20c div.ref.category18{background-color:#8670D1;}.epoch-theme-dark .epoch.category20c .category18 .line{stroke:#8670D1;}.epoch-theme-dark .epoch.category20c .category18 .area,.epoch-theme-dark .epoch.category20c .category18 .dot{fill:#8670D1;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category18 path{fill:#8670D1;}.epoch-theme-dark .epoch.category20c .bar.category18{fill:#8670D1;}.epoch-theme-dark .epoch.category20c div.ref.category19{background-color:#705CAD;}.epoch-theme-dark .epoch.category20c .category19 .line{stroke:#705CAD;}.epoch-theme-dark .epoch.category20c .category19 .area,.epoch-theme-dark .epoch.category20c .category19 .dot{fill:#705CAD;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category19 path{fill:#705CAD;}.epoch-theme-dark .epoch.category20c .bar.category19{fill:#705CAD;}.epoch-theme-dark .epoch.category20c div.ref.category20{background-color:#52447F;}.epoch-theme-dark .epoch.category20c .category20 .line{stroke:#52447F;}.epoch-theme-dark .epoch.category20c .category20 .area,.epoch-theme-dark .epoch.category20c .category20 .dot{fill:#52447F;stroke:rgba(0, 0, 0, 0);}.epoch-theme-dark .epoch.category20c .arc.category20 path{fill:#52447F;}.epoch-theme-dark .epoch.category20c .bar.category20{fill:#52447F;} \ No newline at end of file diff --git a/examples/realtime-advanced/resources/static/epoch.min.js b/examples/realtime-advanced/resources/static/epoch.min.js new file mode 100644 index 00000000..0c654b86 --- /dev/null +++ b/examples/realtime-advanced/resources/static/epoch.min.js @@ -0,0 +1,114 @@ +(function(){var e;null==window.Epoch&&(window.Epoch={});null==(e=window.Epoch).Chart&&(e.Chart={});null==(e=window.Epoch).Time&&(e.Time={});null==(e=window.Epoch).Util&&(e.Util={});null==(e=window.Epoch).Formats&&(e.Formats={});Epoch.warn=function(g){return(console.warn||console.log)("Epoch Warning: "+g)};Epoch.exception=function(g){throw"Epoch Error: "+g;}}).call(this); +(function(){Epoch.TestContext=function(){function e(){var c,a,d;this._log=[];a=0;for(d=g.length;ac){if((c|0)!==c||d)c=c.toFixed(a);return c}f="KMGTPEZY".split("");for(h in f)if(k=f[h],b=Math.pow(10,3*((h|0)+1)),c>=b&&cc){if(0!==c%1||d)c=c.toFixed(a);return""+c+" B"}f="KB MB GB TB PB EB ZB YB".split(" ");for(h in f)if(k=f[h],b=Math.pow(1024,(h|0)+1),c>=b&&cf;k=1<=f?++a:--a)q.push(arguments[k]);return q}.apply(this,arguments);c=this._events[a];m=[];f=0;for(q=c.length;fthis.options.windowSize+1&&a.values.shift();b=[this._ticks[0],this._ticks[this._ticks.length-1]];a=b[0];b=b[1];null!=b&&b.enter&&(b.enter=!1,b.opacity=1);null!=a&&a.exit&&this._shiftTick();this.animation.frame=0;this.trigger("transition:end");if(0this.options.queueSize&&this._queue.splice(this.options.queueSize,this._queue.length-this.options.queueSize);if(this._queue.length===this.options.queueSize)return!1;this._queue.push(a.map(function(a){return function(b){return a._prepareEntry(b)}}(this)));this.trigger("push");if(!this.inTransition())return this._startTransition()}; +a.prototype._shift=function(){var a,b,c,d;this.trigger("before:shift");a=this._queue.shift();d=this.data;for(b in d)c=d[b],c.values.push(a[b]);this._updateTicks(a[0].time);this._transitionRangeAxes();return this.trigger("after:shift")};a.prototype._transitionRangeAxes=function(){this.hasAxis("left")&&this.svg.selectAll(".y.axis.left").transition().duration(500).ease("linear").call(this.leftAxis());if(this.hasAxis("right"))return this.svg.selectAll(".y.axis.right").transition().duration(500).ease("linear").call(this.rightAxis())}; +a.prototype._animate=function(){if(this.inTransition())return++this.animation.frame===this.animation.duration&&this._stopTransition(),this.draw(this.animation.frame*this.animation.delta()),this._updateTimeAxes()};a.prototype.y=function(){return d3.scale.linear().domain(this.extent(function(a){return a.y})).range([this.innerHeight(),0])};a.prototype.ySvg=function(){return d3.scale.linear().domain(this.extent(function(a){return a.y})).range([this.innerHeight()/this.pixelRatio,0])};a.prototype.w=function(){return this.innerWidth()/ +this.options.windowSize};a.prototype._updateTicks=function(a){if(this.hasAxis("top")||this.hasAxis("bottom"))if(++this._tickTimer%this.options.ticks.time||this._pushTick(this.options.windowSize,a,!0),!(0<=this._ticks[0].x-this.w()/this.pixelRatio))return this._ticks[0].exit=!0};a.prototype._pushTick=function(a,b,c,d){null==c&&(c=!1);null==d&&(d=!1);if(this.hasAxis("top")||this.hasAxis("bottom"))return b={time:b,x:a*(this.w()/this.pixelRatio)+this._offsetX(),opacity:c?0:1,enter:c?!0:!1,exit:!1},this.hasAxis("bottom")&& +(a=this.bottomAxis.append("g").attr("class","tick major").attr("transform","translate("+(b.x+1)+",0)").style("opacity",b.opacity),a.append("line").attr("y2",6),a.append("text").attr("text-anchor","middle").attr("dy",19).text(this.options.tickFormats.bottom(b.time)),b.bottomEl=a),this.hasAxis("top")&&(a=this.topAxis.append("g").attr("class","tick major").attr("transform","translate("+(b.x+1)+",0)").style("opacity",b.opacity),a.append("line").attr("y2",-6),a.append("text").attr("text-anchor","middle").attr("dy", +-10).text(this.options.tickFormats.top(b.time)),b.topEl=a),d?this._ticks.unshift(b):this._ticks.push(b),b};a.prototype._shiftTick=function(){var a;if(0f;b=0<=f?++c:--c)k=0,e.push(function(){var a,c,d,f;d=this.data;f=[];a=0;for(c=d.length;ag;a=0<=g?++f:--f){b=e=k=0;for(m=this.data.length;0<=m?em;b=0<=m?++e:--e)k+=this.data[b].values[a].y;k>c&&(c=k)}return[0,c]};return a}(Epoch.Time.Plot)}).call(this); +(function(){var e={}.hasOwnProperty,g=function(c,a){function d(){this.constructor=c}for(var b in a)e.call(a,b)&&(c[b]=a[b]);d.prototype=a.prototype;c.prototype=new d;c.__super__=a.prototype;return c};Epoch.Time.Area=function(c){function a(){return a.__super__.constructor.apply(this,arguments)}g(a,c);a.prototype.setStyles=function(a){a=null!=a.className?this.getStyles("g."+a.className.replace(/\s/g,".")+" path.area"):this.getStyles("g path.area");this.ctx.fillStyle=a.fill;null!=a.stroke&&(this.ctx.strokeStyle= +a.stroke);if(null!=a["stroke-width"])return this.ctx.lineWidth=a["stroke-width"].replace("px","")};a.prototype._drawAreas=function(a){var b,c,k,f,e,g,m,l,n,p;null==a&&(a=0);g=[this.y(),this.w()];m=g[0];g=g[1];p=[];for(c=l=n=this.data.length-1;0>=n?0>=l:0<=l;c=0>=n?++l:--l){f=this.data[c];this.setStyles(f);this.ctx.beginPath();e=[this.options.windowSize,f.values.length,this.inTransition()];c=e[0];k=e[1];for(e=e[2];-2<=--c&&0<=--k;)b=f.values[k],b=[(c+1)*g+a,m(b.y+b.y0)],e&&(b[0]+=g),c===this.options.windowSize- +1?this.ctx.moveTo.apply(this.ctx,b):this.ctx.lineTo.apply(this.ctx,b);c=e?(c+3)*g+a:(c+2)*g+a;this.ctx.lineTo(c,this.innerHeight());this.ctx.lineTo(this.width*this.pixelRatio+g+a,this.innerHeight());this.ctx.closePath();p.push(this.ctx.fill())}return p};a.prototype._drawStrokes=function(a){var b,c,k,f,e,g,m,l,n,p;null==a&&(a=0);c=[this.y(),this.w()];m=c[0];g=c[1];p=[];for(c=l=n=this.data.length-1;0>=n?0>=l:0<=l;c=0>=n?++l:--l){f=this.data[c];this.setStyles(f);this.ctx.beginPath();e=[this.options.windowSize, +f.values.length,this.inTransition()];c=e[0];k=e[1];for(e=e[2];-2<=--c&&0<=--k;)b=f.values[k],b=[(c+1)*g+a,m(b.y+b.y0)],e&&(b[0]+=g),c===this.options.windowSize-1?this.ctx.moveTo.apply(this.ctx,b):this.ctx.lineTo.apply(this.ctx,b);p.push(this.ctx.stroke())}return p};a.prototype.draw=function(c){null==c&&(c=0);this.clear();this._drawAreas(c);this._drawStrokes(c);return a.__super__.draw.call(this)};return a}(Epoch.Time.Stack)}).call(this); +(function(){var e={}.hasOwnProperty,g=function(c,a){function d(){this.constructor=c}for(var b in a)e.call(a,b)&&(c[b]=a[b]);d.prototype=a.prototype;c.prototype=new d;c.__super__=a.prototype;return c};Epoch.Time.Bar=function(c){function a(){return a.__super__.constructor.apply(this,arguments)}g(a,c);a.prototype._offsetX=function(){return 0.5*this.w()/this.pixelRatio};a.prototype.setStyles=function(a){a=this.getStyles("rect.bar."+a.replace(/\s/g,"."));this.ctx.fillStyle=a.fill;this.ctx.strokeStyle= +null==a.stroke||"none"===a.stroke?"transparent":a.stroke;if(null!=a["stroke-width"])return this.ctx.lineWidth=a["stroke-width"].replace("px","")};a.prototype.draw=function(c){var b,h,k,f,e,g,m,l,n,p,r,s,t;null==c&&(c=0);this.clear();f=[this.y(),this.w()];p=f[0];n=f[1];t=this.data;r=0;for(s=t.length;r=e&&0<=--g;)b=m.values[g],k=[f*n+c, +b.y,b.y0],b=k[0],h=k[1],k=k[2],l&&(b+=n),b=[b+1,p(h+k),n-2,this.innerHeight()-p(h)+0.5*this.pixelRatio],this.ctx.fillRect.apply(this.ctx,b),this.ctx.strokeRect.apply(this.ctx,b);return a.__super__.draw.call(this)};return a}(Epoch.Time.Stack)}).call(this); +(function(){var e={}.hasOwnProperty,g=function(c,a){function d(){this.constructor=c}for(var b in a)e.call(a,b)&&(c[b]=a[b]);d.prototype=a.prototype;c.prototype=new d;c.__super__=a.prototype;return c};Epoch.Time.Gauge=function(c){function a(c){this.options=null!=c?c:{};a.__super__.constructor.call(this,this.options=Epoch.Util.defaults(this.options,d));this.value=this.options.value||0;"absolute"!==this.el.style("position")&&"relative"!==this.el.style("position")&&this.el.style("position","relative"); +this.svg=this.el.insert("svg",":first-child").attr("width",this.width).attr("height",this.height).attr("class","gauge-labels");this.svg.style({position:"absolute","z-index":"1"});this.svg.append("g").attr("transform","translate("+this.textX()+", "+this.textY()+")").append("text").attr("class","value").text(this.options.format(this.value));this.animation={interval:null,active:!1,delta:0,target:0};this._animate=function(a){return function(){Math.abs(a.animation.target-a.value)=t;b=0<=t?++s:--s)b=l(b),b=[Math.cos(b),Math.sin(b)],c=b[0],m=b[1],b=c*(g-n)+d,r=m*(g-n)+e,c=c*(g-n-p)+d,m=m*(g-n-p)+e,this.ctx.moveTo(b,r),this.ctx.lineTo(c,m);this.ctx.stroke();this.setStyles(".epoch .gauge .arc.outer");this.ctx.beginPath();this.ctx.arc(d,e,g,-1.125* +Math.PI,0.125*Math.PI,!1);this.ctx.stroke();this.setStyles(".epoch .gauge .arc.inner");this.ctx.beginPath();this.ctx.arc(d,e,g-10,-1.125*Math.PI,0.125*Math.PI,!1);this.ctx.stroke();this.drawNeedle();return a.__super__.draw.call(this)};a.prototype.drawNeedle=function(){var a,b,c;c=[this.centerX(),this.centerY(),this.radius()];a=c[0];b=c[1];c=c[2];this.setStyles(".epoch .gauge .needle");this.ctx.beginPath();this.ctx.save();this.ctx.translate(a,b);this.ctx.rotate(this.getAngle(this.value));this.ctx.moveTo(4* +this.pixelRatio,0);this.ctx.lineTo(-4*this.pixelRatio,0);this.ctx.lineTo(-1*this.pixelRatio,19-c);this.ctx.lineTo(1,19-c);this.ctx.fill();this.setStyles(".epoch .gauge .needle-base");this.ctx.beginPath();this.ctx.arc(0,0,this.getWidth()/25,0,2*Math.PI);this.ctx.fill();return this.ctx.restore()};a.prototype.domainChanged=function(){return this.draw()};a.prototype.ticksChanged=function(){return this.draw()};a.prototype.tickSizeChanged=function(){return this.draw()};a.prototype.tickOffsetChanged=function(){return this.draw()}; +a.prototype.formatChanged=function(){return this.svg.select("text.value").text(this.options.format(this.value))};return a}(Epoch.Chart.Canvas)}).call(this); +(function(){var e={}.hasOwnProperty,g=function(c,a){function d(){this.constructor=c}for(var b in a)e.call(a,b)&&(c[b]=a[b]);d.prototype=a.prototype;c.prototype=new d;c.__super__=a.prototype;return c};Epoch.Time.Heatmap=function(c){function a(c){this.options=c;a.__super__.constructor.call(this,this.options=Epoch.Util.defaults(this.options,b));this._setOpacityFunction();this._setupPaintCanvas();this.onAll(e)}var d,b,e;g(a,c);b={buckets:10,bucketRange:[0,100],opacity:"linear",bucketPadding:2,paintZeroValues:!1, +cutOutliers:!1};d={root:function(a,b){return Math.pow(a/b,0.5)},linear:function(a,b){return a/b},quadratic:function(a,b){return Math.pow(a/b,2)},cubic:function(a,b){return Math.pow(a/b,3)},quartic:function(a,b){return Math.pow(a/b,4)},quintic:function(a,b){return Math.pow(a/b,5)}};e={"option:buckets":"bucketsChanged","option:bucketRange":"bucketRangeChanged","option:opacity":"opacityChanged","option:bucketPadding":"bucketPaddingChanged","option:paintZeroValues":"paintZeroValuesChanged","option:cutOutliers":"cutOutliersChanged"}; +a.prototype._setOpacityFunction=function(){if(Epoch.isString(this.options.opacity)){if(this._opacityFn=d[this.options.opacity],null==this._opacityFn)return Epoch.exception("Unknown coloring function provided '"+this.options.opacity+"'")}else return Epoch.isFunction(this.options.opacity)?this._opacityFn=this.options.opacity:Epoch.exception("Unknown type for provided coloring function.")};a.prototype.setData=function(b){var c,d,e,g;a.__super__.setData.call(this,b);e=this.data;g=[];c=0;for(d=e.length;c< +d;c++)b=e[c],g.push(b.values=b.values.map(function(a){return function(b){return a._prepareEntry(b)}}(this)));return g};a.prototype._getBuckets=function(a){var b,c,d,e,g;e=a.time;g=[];b=0;for(d=this.options.buckets;0<=d?bd;0<=d?++b:--b)g.push(0);e={time:e,max:0,buckets:g};b=(this.options.bucketRange[1]-this.options.bucketRange[0])/this.options.buckets;g=a.histogram;for(c in g)a=g[c],d=parseInt((c-this.options.bucketRange[0])/b),this.options.cutOutliers&&(0>d||d>=this.options.buckets)||(0>d?d= +0:d>=this.options.buckets&&(d=this.options.buckets-1),e.buckets[d]+=parseInt(a));c=a=0;for(b=e.buckets.length;0<=b?ab;c=0<=b?++a:--a)e.max=Math.max(e.max,e.buckets[c]);return e};a.prototype.y=function(){return d3.scale.linear().domain(this.options.bucketRange).range([this.innerHeight(),0])};a.prototype.ySvg=function(){return d3.scale.linear().domain(this.options.bucketRange).range([this.innerHeight()/this.pixelRatio,0])};a.prototype.h=function(){return this.innerHeight()/this.options.buckets}; +a.prototype._offsetX=function(){return 0.5*this.w()/this.pixelRatio};a.prototype._setupPaintCanvas=function(){this.paintWidth=(this.options.windowSize+1)*this.w();this.paintHeight=this.height*this.pixelRatio;this.paint=document.createElement("CANVAS");this.paint.width=this.paintWidth;this.paint.height=this.paintHeight;this.p=Epoch.Util.getContext(this.paint);this.redraw();this.on("after:shift","_paintEntry");this.on("transition:end","_shiftPaintCanvas");return this.on("transition:end",function(a){return function(){return a.draw(a.animation.frame* +a.animation.delta())}}(this))};a.prototype.redraw=function(){var a,b;b=this.data[0].values.length;a=this.options.windowSize;for(this.inTransition()&&a++;0<=--b&&0<=--a;)this._paintEntry(b,a);return this.draw(this.animation.frame*this.animation.delta())};a.prototype._computeColor=function(a,b,c){return Epoch.Util.toRGBA(c,this._opacityFn(a,b))};a.prototype._paintEntry=function(a,b){var c,d,e,g,h,p,r,s,t,v,y,w,A,z;null==a&&(a=null);null==b&&(b=null);g=[this.w(),this.h()];y=g[0];p=g[1];null==a&&(a=this.data[0].values.length- +1);null==b&&(b=this.options.windowSize);g=[];var x;x=[];h=0;for(v=this.options.buckets;0<=v?hv;0<=v?++h:--h)x.push(0);v=0;t=this.data;d=0;for(r=t.length;d"+message+""; + $('#chat').append(html); + + $("#chat-scroll").scrollTop($("#chat-scroll")[0].scrollHeight); +} + +function histogram(windowSize, timestamp) { + var entries = new Array(windowSize); + for(var i = 0; i < windowSize; i++) { + entries[i] = {time: (timestamp-windowSize+i-1), y:0}; + } + return entries; +} + +var entityMap = { + "&": "&", + "<": "<", + ">": ">", + '"': '"', + "'": ''', + "/": '/' +}; + + +function escapeHtml(string) { + return String(string).replace(/[&<>"'\/]/g, function (s) { + return entityMap[s]; + }); +} + +window.StartRealtime = StartRealtime diff --git a/examples/realtime-advanced/rooms.go b/examples/realtime-advanced/rooms.go new file mode 100644 index 00000000..8c62bece --- /dev/null +++ b/examples/realtime-advanced/rooms.go @@ -0,0 +1,33 @@ +package main + +import "github.com/dustin/go-broadcast" + +var roomChannels = make(map[string]broadcast.Broadcaster) + +func openListener(roomid string) chan interface{} { + listener := make(chan interface{}) + room(roomid).Register(listener) + return listener +} + +func closeListener(roomid string, listener chan interface{}) { + room(roomid).Unregister(listener) + close(listener) +} + +func deleteBroadcast(roomid string) { + b, ok := roomChannels[roomid] + if ok { + b.Close() + delete(roomChannels, roomid) + } +} + +func room(roomid string) broadcast.Broadcaster { + b, ok := roomChannels[roomid] + if !ok { + b = broadcast.NewBroadcaster(10) + roomChannels[roomid] = b + } + return b +} diff --git a/examples/realtime-advanced/stats.go b/examples/realtime-advanced/stats.go new file mode 100644 index 00000000..0b9b8448 --- /dev/null +++ b/examples/realtime-advanced/stats.go @@ -0,0 +1,25 @@ +package main + +import ( + "runtime" + "time" +) + +func Stats() map[string]uint64 { + var stats runtime.MemStats + runtime.ReadMemStats(&stats) + + return map[string]uint64{ + "timestamp": uint64(time.Now().Unix()), + "HeapInuse": stats.HeapInuse, + "StackInuse": stats.StackInuse, + "NuGoroutines": uint64(runtime.NumGoroutine()), + //"Latency": latency, + "Mallocs": stats.Mallocs, + "Frees": stats.Mallocs, + // "HeapIdle": stats.HeapIdle, + // "HeapInuse": stats.HeapInuse, + // "HeapReleased": stats.HeapReleased, + // "HeapObjects": stats.HeapObjects, + } +}