[tor-commits] [metrics-web/master] Refactors news item presentation using JSTL

karsten at torproject.org karsten at torproject.org
Wed Mar 21 15:50:58 UTC 2018


commit c828a2f50028484ee8101fd5357c2bef3e5738b3
Author: Iain R. Learmonth <irl at fsfe.org>
Date:   Tue Mar 20 17:16:49 2018 +0000

    Refactors news item presentation using JSTL
    
    Instead of rendering HTML using News.formatAsTableRow(), News entries
    and now handed directly to the JSP which uses JSTL to take care of
    presentation.
    
    The format of news.json is changed to make links into an array of
    dictionaries containing targets and labels instead of HTML snippets and
    an additional field, shortDescription, is added with a non-HTML short
    description of the news item.
---
 .../org/torproject/metrics/web/GraphServlet.java   |    4 +-
 src/main/java/org/torproject/metrics/web/News.java |  150 +-
 .../org/torproject/metrics/web/NewsServlet.java    |    4 +-
 .../org/torproject/metrics/web/UpdateNews.java     |   32 +-
 src/main/resources/web/css/style.css               |    4 +-
 src/main/resources/web/json/news.json              | 2432 ++++++++++++++++----
 src/main/resources/web/jsps/graph.jsp              |    4 +-
 src/main/resources/web/jsps/news-item.jsp          |   62 +
 src/main/resources/web/jsps/news.jsp               |    2 +-
 9 files changed, 2163 insertions(+), 531 deletions(-)

diff --git a/src/main/java/org/torproject/metrics/web/GraphServlet.java b/src/main/java/org/torproject/metrics/web/GraphServlet.java
index 2781be0..73aaec7 100644
--- a/src/main/java/org/torproject/metrics/web/GraphServlet.java
+++ b/src/main/java/org/torproject/metrics/web/GraphServlet.java
@@ -244,7 +244,7 @@ public class GraphServlet extends MetricServlet {
         if (!"off".equals(eventsParameter)) {
           request.setAttribute("displayEventsNotice", true);
         }
-        List<String> relatedEvents = new ArrayList<>();
+        List<News> relatedEvents = new ArrayList<>();
         for (News event : this.sortedEvents) {
           if (null == event.getStart()) {
             /* Skip event without start date. */
@@ -272,7 +272,7 @@ public class GraphServlet extends MetricServlet {
           }
           /* We could filter by transport or version here, but that's a
            * non-trivial task. */
-          relatedEvents.add(event.formatAsTableRow());
+          relatedEvents.add(event);
         }
         request.setAttribute("relatedEvents", relatedEvents);
       }
diff --git a/src/main/java/org/torproject/metrics/web/News.java b/src/main/java/org/torproject/metrics/web/News.java
index ee1b09f..d24a11c 100644
--- a/src/main/java/org/torproject/metrics/web/News.java
+++ b/src/main/java/org/torproject/metrics/web/News.java
@@ -3,12 +3,26 @@
 
 package org.torproject.metrics.web;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
 public class News {
 
+  public class Link {
+    String label;
+    String target;
+
+    public String getLabel() {
+      return label;
+    }
+
+    public String getTarget() {
+      return target;
+    }
+  }
+
   String start;
 
   String end;
@@ -19,17 +33,29 @@ public class News {
 
   List<String> protocols;
 
+  String shortDescription;
+
   String description;
 
-  List<String> links;
+  List<Link> links;
 
   Boolean unknown;
 
-  String getStart() {
+  void addLink(String label, String target) {
+    if (null == links) {
+      links = new ArrayList<>();
+    }
+    Link link = new Link();
+    link.label = label;
+    link.target = target;
+    links.add(link);
+  }
+
+  public String getStart() {
     return this.start;
   }
 
-  String getEnd() {
+  public String getEnd() {
     return this.end;
   }
 
@@ -37,7 +63,7 @@ public class News {
    * Returns whether or not the event is ongoing. If no value was set, it is
    * assumed that the event is not ongoing.
    */
-  boolean getOngoing() {
+  public boolean isOngoing() {
     if (this.ongoing != null) {
       return this.ongoing;
     } else {
@@ -45,27 +71,52 @@ public class News {
     }
   }
 
-  List<String> getPlaces() {
+  public List<String> getPlaces() {
     return this.places;
   }
 
-  String[] getProtocols() {
-    return (String[]) this.protocols.toArray();
+  /**
+   * Returns an array of country names looked up from the country codes
+   * associated with this news entry. If a country is unknown, that country
+   * will be added to the list as "Unknown Country". There is no deduplication
+   * of countries, including the output of "Unknown Country".
+   */
+  public List<String> getPlaceNames() {
+    if (null == this.places) {
+      return null;
+    }
+    List<String> placeNames = new ArrayList<>();
+    for (String place : this.places) {
+      if (countries.containsKey(place)) {
+        placeNames.add(countries.get(place));
+      } else {
+        placeNames.add("Unknown Country");
+      }
+    }
+    return placeNames;
   }
 
-  String getDescription() {
+  public List<String> getProtocols() {
+    return this.protocols;
+  }
+
+  public String getDescription() {
     return this.description;
   }
 
-  String[] getLinks() {
-    return (String[]) this.links.toArray();
+  public String getShortDescription() {
+    return this.shortDescription;
+  }
+
+  public List<Link> getLinks() {
+    return this.links;
   }
 
   /**
    * Returns whether or not the reason for an event is known. If no value was
    * set, it is assumed that the reason is known.
    */
-  boolean isUnknown() {
+  public boolean isUnknown() {
     if (this.unknown != null) {
       return this.unknown;
     } else {
@@ -82,81 +133,4 @@ public class News {
     }
   }
 
-  String formatAsTableRow() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("<tr><td><span class=\"dates\">");
-    if (null == this.start) {
-      /* Invalid event without start date. */
-      sb.append("N/A");
-    } else if (this.getOngoing()) {
-      /* Ongoing event. */
-      sb.append(this.start).append(" to present");
-    } else if (null == this.end || this.start.equals(this.end)) {
-      /* Single-day event. */
-      sb.append(this.start);
-    } else {
-      /* Multi-day event. */
-      sb.append(this.start).append(" to ").append(this.end);
-    }
-    sb.append("</span></td><td>");
-    if (null != this.places) {
-      boolean appendUnknownCountry = false;
-      for (String place : this.getPlaces()) {
-        if (countries.containsKey(place)) {
-          sb.append(" <span class=\"label label-warning\">")
-              .append(countries.get(place)).append("</span>");
-        } else {
-          appendUnknownCountry = true;
-        }
-      }
-      if (appendUnknownCountry) {
-        sb.append(" <span class=\"label label-warning\">"
-            + "Unknown country</span>");
-      }
-    }
-    if (null != this.protocols) {
-      for (String protocol : this.protocols) {
-        switch (protocol) {
-          case "relay":
-            sb.append(" <span class=\"label label-success\">Relays</span>");
-            break;
-          case "bridge":
-            sb.append(" <span class=\"label label-primary\">Bridges</span>");
-            break;
-          case "<OR>":
-            sb.append(" <span class=\"label label-info\"><OR></span>");
-            break;
-          default:
-            sb.append(" <span class=\"label label-info\">").append(protocol)
-                .append("</span>");
-            break;
-        }
-      }
-    }
-    if (this.isUnknown()) {
-      sb.append(" <span class=\"label label-default\">Unknown</span>");
-    }
-    sb.append("</td><td>");
-    if (null != this.description) {
-      sb.append(this.description).append("<br/>");
-    }
-    if (null != this.links) {
-      for (String link : this.links) {
-        int tagEnd = link.indexOf('>');
-        if (tagEnd < 0 || tagEnd + 2 > link.length()) {
-          continue;
-        }
-        sb.append(link, 0, tagEnd);
-        sb.append(" class=\"link\"");
-        if (!link.startsWith("<a href=\"https://metrics.torproject.org/")) {
-          sb.append(" target=\"_blank\"");
-        }
-        sb.append('>')
-            .append(link.substring(tagEnd + 1, tagEnd + 2).toUpperCase())
-            .append(link.substring(tagEnd + 2));
-      }
-    }
-    sb.append("</td></tr>");
-    return sb.toString();
-  }
 }
diff --git a/src/main/java/org/torproject/metrics/web/NewsServlet.java b/src/main/java/org/torproject/metrics/web/NewsServlet.java
index 131bd11..3bfb1b7 100644
--- a/src/main/java/org/torproject/metrics/web/NewsServlet.java
+++ b/src/main/java/org/torproject/metrics/web/NewsServlet.java
@@ -80,14 +80,14 @@ public class NewsServlet extends AnyServlet {
         .getStart()) > 0);
 
     /* Sort news into categories. */
-    Map<String[], List<String>> newsByCategory = new LinkedHashMap<>();
+    Map<String[], List<News>> newsByCategory = new LinkedHashMap<>();
     for (String[] category : cutOffDates.values()) {
       newsByCategory.put(category, new ArrayList<>());
     }
     for (News news : this.sortedNews) {
       for (Map.Entry<String, String[]> category : cutOffDates.entrySet()) {
         if (news.getStart().compareTo(category.getKey()) >= 0) {
-          newsByCategory.get(category.getValue()).add(news.formatAsTableRow());
+          newsByCategory.get(category.getValue()).add(news);
           break;
         }
       }
diff --git a/src/main/java/org/torproject/metrics/web/UpdateNews.java b/src/main/java/org/torproject/metrics/web/UpdateNews.java
index 3e23233..3705d4a 100644
--- a/src/main/java/org/torproject/metrics/web/UpdateNews.java
+++ b/src/main/java/org/torproject/metrics/web/UpdateNews.java
@@ -33,12 +33,7 @@ public class UpdateNews {
         if (!line.startsWith("||") || line.startsWith("||=start")) {
           continue;
         }
-        line = line.trim()
-            .replaceAll("×", "×")
-            .replaceAll("§", "§")
-            .replaceAll("–", "–")
-            .replaceAll("“", "“")
-            .replaceAll("”", "”");
+        line = line.trim();
         String[] parts = line.split("\\|\\|");
         News entry = new News();
         entry.start = parts[1].replaceAll("~", "").trim();
@@ -97,18 +92,31 @@ public class UpdateNews {
               + desc.substring(open + 1, close) + "</code>"
               + desc.substring(close + 1);
         }
-        entry.description = desc;
+        entry.description = desc
+            .replaceAll("&", "&")
+            .replaceAll("×", "×")
+            .replaceAll("§", "§")
+            .replaceAll("–", "–")
+            .replaceAll("“", "“")
+            .replaceAll("”", "”");
+        String shortDesc = desc
+            .replaceAll("\\<.*?\\>", "")
+            .replaceAll("&.*;", "");
+        if (shortDesc.indexOf(". ") != -1) {
+          shortDesc = shortDesc.substring(0, shortDesc.indexOf(". "));
+        }
+        if (shortDesc.indexOf(" (") != -1) {
+          shortDesc = shortDesc.substring(0, shortDesc.indexOf(" ("));
+        }
+        entry.shortDescription = shortDesc;
         if (parts.length >= 7) {
           for (String link : parts[6].split("[\\[\\]]")) {
             link = link.trim();
             if (link.isEmpty()) {
               continue;
             }
-            if (null == entry.links) {
-              entry.links = new ArrayList<>();
-            }
-            entry.links.add("<a href=\"" + link.substring(0, link.indexOf(" "))
-                + "\">" + link.substring(link.indexOf(" ") + 1) + "</a>");
+            entry.addLink(link.substring(link.indexOf(" ") + 1),
+              link.substring(0, link.indexOf(" ")));
           }
         }
         entry.unknown = unknown;
diff --git a/src/main/resources/web/css/style.css b/src/main/resources/web/css/style.css
index 108f95c..590b31f 100644
--- a/src/main/resources/web/css/style.css
+++ b/src/main/resources/web/css/style.css
@@ -472,7 +472,9 @@ a.btn[target="_blank"]:before {
     top: -2px;
     margin-left: 5px;
 }
-
+.metrics-news-link {
+    text-transform: capitalize;
+}
 
 /* faq */
 .faq h2 {
diff --git a/src/main/resources/web/json/news.json b/src/main/resources/web/json/news.json
index 49ba5a2..00c4cf1 100644
--- a/src/main/resources/web/json/news.json
+++ b/src/main/resources/web/json/news.json
@@ -4,9 +4,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated",
     "description": "geoip database updated (<code>geoip-db-digest C4F4C0FDC9D15AEA7132404B6D51E11ACB828023</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=d232d2d188f405b50cc6f857be025079fd4a9d1f\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=d232d2d188f405b50cc6f857be025079fd4a9d1f"
+      }
     ]
   },
   {
@@ -14,9 +18,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated",
     "description": "geoip database updated (<code>geoip-db-digest 947841EF4BED1B4E891BBDEC3E7643D62AFDD544</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=a1aeaf308964a18a876120b97cabe35dc89f1d86\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=a1aeaf308964a18a876120b97cabe35dc89f1d86"
+      }
     ]
   },
   {
@@ -24,9 +32,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"June 9 2008 ip-to-country db\"",
     "description": "geoip database updated to \"June 9 2008 ip-to-country db\" (<code>geoip-db-digest 43DBBB309037C48A70B2C31512E21D45E95C72B0</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=89c903d9aa5b02f1b212178cdc3d41430060959e\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=89c903d9aa5b02f1b212178cdc3d41430060959e"
+      }
     ]
   },
   {
@@ -34,9 +46,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"September 1 2008 ip-to-country db\"",
     "description": "geoip database updated to \"September 1 2008 ip-to-country db\" (<code>geoip-db-digest 64129F664F291BC3D2D746BBBFD83FE7CB2264D3</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=29abfab8bfdc14d4f2f725aee6755dfc2bd6036b\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=29abfab8bfdc14d4f2f725aee6755dfc2bd6036b"
+      }
     ]
   },
   {
@@ -44,9 +60,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"December 19 2008 ip-to-country db\"",
     "description": "geoip database updated to \"December 19 2008 ip-to-country db\" (<code>geoip-db-digest 79365660714FF9D3F5AD1DE427A604251188F94B</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=d1351750ed7c7c7f8d8716d1a9a004c96cce5f2c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=d1351750ed7c7c7f8d8716d1a9a004c96cce5f2c"
+      }
     ]
   },
   {
@@ -54,9 +74,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"January 23 2009 ip-to-country db\"",
     "description": "geoip database updated to \"January 23 2009 ip-to-country db\" (<code>geoip-db-digest E6455B416994835C4F355AF8386F71D606C56937</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=b03f78e8af442bfd554023fbe6ac0b17b664e496\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=b03f78e8af442bfd554023fbe6ac0b17b664e496"
+      }
     ]
   },
   {
@@ -64,9 +88,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"February 26 2009 ip-to-country db\"",
     "description": "geoip database updated to \"February 26 2009 ip-to-country db\" (<code>geoip-db-digest 07D75C8790B6D575061EE3D19B46BD4478B7AAEC</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=0f46c1dc6ecf2aef559983e555b2237fc5c08744\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=0f46c1dc6ecf2aef559983e555b2237fc5c08744"
+      }
     ]
   },
   {
@@ -74,9 +102,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"April 3 2009 ip-to-country db\"",
     "description": "geoip database updated to \"April 3 2009 ip-to-country db\" (<code>geoip-db-digest 94674ED08A3AB5A5722749314870F176776CBEA3</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=72e4d48c7a8a7722d01c914766a8a663f97c77ec\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=72e4d48c7a8a7722d01c914766a8a663f97c77ec"
+      }
     ]
   },
   {
@@ -84,9 +116,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"June 3 2009 ip-to-country db\"",
     "description": "geoip database updated to \"June 3 2009 ip-to-country db\" (<code>geoip-db-digest 507DBE49979319B61E8EC637BDC72D53C91A907A</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=48bf1d97eeed9fd0812e281cbc1f08c6c5ade89c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=48bf1d97eeed9fd0812e281cbc1f08c6c5ade89c"
+      }
     ]
   },
   {
@@ -94,9 +130,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"May 1 2010 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"May 1 2010 Maxmind GeoLite Country\" (<code>geoip-db-digest 2F36F923FD3368E208924A81169F8B4B3468A6E8</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=befcc84f432800532a092402daecd2c95addf45c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=befcc84f432800532a092402daecd2c95addf45c"
+      }
     ]
   },
   {
@@ -104,9 +144,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"June 1 2010 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"June 1 2010 Maxmind GeoLite Country\" (<code>geoip-db-digest 0F7A148E7A934235263345AD913E44C9E44BF495</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=f60e4bcdd9b24cdc1d9b05a94088eb4aef6c7fec\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=f60e4bcdd9b24cdc1d9b05a94088eb4aef6c7fec"
+      }
     ]
   },
   {
@@ -114,9 +158,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"August 1 2010 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"August 1 2010 Maxmind GeoLite Country\" (<code>geoip-db-digest 60B2587014A74FF8E5A1BD52AD081F02D57098D5</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=f206209abfc1f98bbbd0be5b6e36fdec6709953d\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=f206209abfc1f98bbbd0be5b6e36fdec6709953d"
+      }
     ]
   },
   {
@@ -124,9 +172,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"September 1 2010 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"September 1 2010 Maxmind GeoLite Country\" (<code>geoip-db-digest 952F4038C3D493AB62673577191B0F779A40D7BB</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=80d9dbac20fec1585e03c04da4f321ece3804ce4\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=80d9dbac20fec1585e03c04da4f321ece3804ce4"
+      }
     ]
   },
   {
@@ -134,9 +186,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"October 1 2010 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"October 1 2010 Maxmind GeoLite Country\" (<code>geoip-db-digest F090EBEEC4A0E05B2A2D33EE9F2AA8B73FB2C350</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=bad609ae6b5505783034cd3951afd382c528c532\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=bad609ae6b5505783034cd3951afd382c528c532"
+      }
     ]
   },
   {
@@ -144,9 +200,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"December 1 2010 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"December 1 2010 Maxmind GeoLite Country\" (<code>geoip-db-digest 7726B7A80C3EC4534EA2A5C62D2AC1096931DD39</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=35148ba5329eef357bd020d1ef5f2d10a1c28693\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=35148ba5329eef357bd020d1ef5f2d10a1c28693"
+      }
     ]
   },
   {
@@ -154,9 +214,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"January 1 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"January 1 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest 9D4EBE51F94EAAD7DC40DF26837E5E892345BB7C</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=d43cba6c690d9c227b13cd7426285b82b9523611\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=d43cba6c690d9c227b13cd7426285b82b9523611"
+      }
     ]
   },
   {
@@ -164,10 +228,17 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Release of tor 0.2.2.22-alpha",
     "description": "Release of tor 0.2.2.22-alpha. Changes the TLS Diffie–Hellman parameter to match that used by Apache mod_ssl, to evade blocking in Iran.",
     "links": [
-      "<a href=\"https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki/CensorshipCircumvention/TorChanges#a0.2.2.22-alpha\">censorshipwiki entry</a>",
-      "<a href=\"https://trac.torproject.org/projects/tor/wiki/org/projects/Tor/TLSHistory#Stage2:Tor0.2.0.20through0.2.3.6\">tor TLSHistory</a>"
+      {
+        "label": "censorshipwiki entry",
+        "target": "https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki/CensorshipCircumvention/TorChanges#a0.2.2.22-alpha"
+      },
+      {
+        "label": "tor TLSHistory",
+        "target": "https://trac.torproject.org/projects/tor/wiki/org/projects/Tor/TLSHistory#Stage2:Tor0.2.0.20through0.2.3.6"
+      }
     ]
   },
   {
@@ -175,9 +246,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"February 1 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"February 1 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest 12EBCF2FB208695E447EF151038881F08FDCBFD8</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=9c2cb6fc8929cb02d500e8d276445205937ab01b\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=9c2cb6fc8929cb02d500e8d276445205937ab01b"
+      }
     ]
   },
   {
@@ -185,9 +260,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"March 1 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"March 1 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest 8CCD8DB72C71E6D764DF888511DC37DD5A13ED97</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=d080fe8db14817e6eaf37359c638805909a306a1\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=d080fe8db14817e6eaf37359c638805909a306a1"
+      }
     ]
   },
   {
@@ -195,9 +274,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"April 1 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"April 1 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest 754DCDF6CCF1BB631B0C14D2EBFECE649501A88D</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=0cdd2629418f019bda5fa2daa271aae4f7131fa6\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=0cdd2629418f019bda5fa2daa271aae4f7131fa6"
+      }
     ]
   },
   {
@@ -205,9 +288,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"May 1 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"May 1 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest 9CA15F4E4D1235116956F3DEA9B3E8A714D15D5D</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=e7b10e5ecfdf3ede4123f921c1d2419268235176\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=e7b10e5ecfdf3ede4123f921c1d2419268235176"
+      }
     ]
   },
   {
@@ -215,9 +302,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"June 1 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"June 1 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest C5C0785F3E1DF5319609B87FCA295FC7D0CE6215</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=bf4b819aae43c11db824f3e790f8a92260e9988e\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=bf4b819aae43c11db824f3e790f8a92260e9988e"
+      }
     ]
   },
   {
@@ -225,9 +316,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"July 1 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"July 1 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest CCABBFAF7036BA3E7580D7F71845AC0673B9E922</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=51d6e950235a76cbc2eaef0e2a28bd8da338ac2a\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=51d6e950235a76cbc2eaef0e2a28bd8da338ac2a"
+      }
     ]
   },
   {
@@ -235,9 +330,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"August 2 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"August 2 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest F8D51025DD9B5CC482B3171D3B43FB81868568A9</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=c75ee94ab41e3a76e8159366defe3159614b497c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=c75ee94ab41e3a76e8159366defe3159614b497c"
+      }
     ]
   },
   {
@@ -245,9 +344,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"September 6 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"September 6 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest F39A5F424559CF5654C793531982BA536D1CEDCA</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=679f617345dc31c46560b09d3b5d5d350e06ab23\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=679f617345dc31c46560b09d3b5d5d350e06ab23"
+      }
     ]
   },
   {
@@ -255,10 +358,17 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Release of tor 0.2.3.4-alpha",
     "description": "Release of tor 0.2.3.4-alpha. Changes the expiration time of TLS certificates, to evade blocking in Iran.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/4014\">ticket</a>",
-      "<a href=\"https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki/CensorshipCircumvention/TorChanges#a0.2.3.4-alpha\">censorshipwiki entry</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/4014"
+      },
+      {
+        "label": "censorshipwiki entry",
+        "target": "https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki/CensorshipCircumvention/TorChanges#a0.2.3.4-alpha"
+      }
     ]
   },
   {
@@ -266,9 +376,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"October 4 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"October 4 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest 25138998CF10DDAC1B4F745EBC6790DA4E5A6F1B</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=ee545cd4cb32b2aa6a37285d0afcd1e4d11fa27c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=ee545cd4cb32b2aa6a37285d0afcd1e4d11fa27c"
+      }
     ]
   },
   {
@@ -276,9 +390,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"November 1 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"November 1 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest F730E870057D6CA19EE55BC80604E41BEEB5B607</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=6d45c6d548bd3467cbc816327d1a7778e6fc9539\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=6d45c6d548bd3467cbc816327d1a7778e6fc9539"
+      }
     ]
   },
   {
@@ -286,9 +404,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"December 6 2011 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"December 6 2011 Maxmind GeoLite Country\" (<code>geoip-db-digest 916A3CA8B7DF61473D5AE5B21711F35F301CE9E8</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=ff2c9acbb39d7ae917501b1e719cf5be994fe4e2\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=ff2c9acbb39d7ae917501b1e719cf5be994fe4e2"
+      }
     ]
   },
   {
@@ -296,9 +418,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"January 3 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"January 3 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest DCF8969A2B080FAE2664F1D46F758B1CB08C286C</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=1db1b23a7b12f4e9b0419b7264456ad7817678e0\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=1db1b23a7b12f4e9b0419b7264456ad7817678e0"
+      }
     ]
   },
   {
@@ -310,9 +436,13 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Iran partially blocks Tor.",
     "description": "Iran partially blocks Tor.",
     "links": [
-      "<a href=\"https://blog.torproject.org/iran-partially-blocks-encrypted-network-traffic\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/iran-partially-blocks-encrypted-network-traffic"
+      }
     ]
   },
   {
@@ -320,9 +450,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"February 7 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"February 7 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest 3BCA888461BCC79CA29E78603DC197090F8C96CB</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=4180624a7d5a3e528be2cf2fe7f9f673b3964a23\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=4180624a7d5a3e528be2cf2fe7f9f673b3964a23"
+      }
     ]
   },
   {
@@ -330,9 +464,13 @@
     "protocols": [
       "obfs2"
     ],
+    "shortDescription": "First release of \"Tor Obfsproxy Browser Bundle\", containing 2 obfs2 bridges",
     "description": "First release of \"Tor Obfsproxy Browser Bundle\", containing 2 obfs2 bridges. Version number unknown; no bundle containing 2 bridges exists at https://archive.torproject.org/tor-package-archive/obfsproxy/.",
     "links": [
-      "<a href=\"https://blog.torproject.org/obfsproxy-next-step-censorship-arms-race\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/obfsproxy-next-step-censorship-arms-race"
+      }
     ]
   },
   {
@@ -340,11 +478,21 @@
     "protocols": [
       "obfs2"
     ],
+    "shortDescription": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.10, containing 14 obfs2 bridges.",
     "description": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.10, containing 14 obfs2 bridges.",
     "links": [
-      "<a href=\"https://blog.torproject.org/obfsproxy-next-step-censorship-arms-race\">blog post</a>",
-      "<a href=\"https://archive.torproject.org/tor-package-archive/obfsproxy/\">package archive</a>",
-      "<a href=\"https://gitweb.torproject.org/project/web/webwml.git/diff/projects/en/obfsproxy.wml?id2=8e52e5e4f8b9cb7b7cb65602446cfec0e0d17ff0&id=d83582eeefe41ffb0125e47d4bde8b3c7f629511\">commits</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/obfsproxy-next-step-censorship-arms-race"
+      },
+      {
+        "label": "package archive",
+        "target": "https://archive.torproject.org/tor-package-archive/obfsproxy/"
+      },
+      {
+        "label": "commits",
+        "target": "https://gitweb.torproject.org/project/web/webwml.git/diff/projects/en/obfsproxy.wml?id2=8e52e5e4f8b9cb7b7cb65602446cfec0e0d17ff0&id=d83582eeefe41ffb0125e47d4bde8b3c7f629511"
+      }
     ]
   },
   {
@@ -352,11 +500,21 @@
     "protocols": [
       "obfs2"
     ],
+    "shortDescription": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.12, containing 13 obfs2 bridges",
     "description": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.12, containing 13 obfs2 bridges (removed 128.30.30.25:51420 relative to version 2.3.10).",
     "links": [
-      "<a href=\"https://blog.torproject.org/obfsproxy-next-step-censorship-arms-race\">blog post</a>",
-      "<a href=\"https://archive.torproject.org/tor-package-archive/obfsproxy/\">package archive</a>",
-      "<a href=\"https://gitweb.torproject.org/project/web/webwml.git/diff/projects/en/obfsproxy.wml?id2=d83582eeefe41ffb0125e47d4bde8b3c7f629511&id=34941f5f8d7f3452b494e384b556a21fe763ad33\">commits</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/obfsproxy-next-step-censorship-arms-race"
+      },
+      {
+        "label": "package archive",
+        "target": "https://archive.torproject.org/tor-package-archive/obfsproxy/"
+      },
+      {
+        "label": "commits",
+        "target": "https://gitweb.torproject.org/project/web/webwml.git/diff/projects/en/obfsproxy.wml?id2=d83582eeefe41ffb0125e47d4bde8b3c7f629511&id=34941f5f8d7f3452b494e384b556a21fe763ad33"
+      }
     ]
   },
   {
@@ -364,10 +522,17 @@
     "protocols": [
       "obfs2"
     ],
+    "shortDescription": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.12-2, for Windows and Mac OS X only.",
     "description": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.12-2, for Windows and Mac OS X only.",
     "links": [
-      "<a href=\"https://archive.torproject.org/tor-package-archive/obfsproxy/\">package archive</a>",
-      "<a href=\"https://gitweb.torproject.org/project/web/webwml.git/commit/projects/en/obfsproxy.wml?id=b3ba7c694b8dcd21ab738d753d5dac05e7157ba6\">commit</a>"
+      {
+        "label": "package archive",
+        "target": "https://archive.torproject.org/tor-package-archive/obfsproxy/"
+      },
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/project/web/webwml.git/commit/projects/en/obfsproxy.wml?id=b3ba7c694b8dcd21ab738d753d5dac05e7157ba6"
+      }
     ]
   },
   {
@@ -375,10 +540,17 @@
     "protocols": [
       "obfs2"
     ],
+    "shortDescription": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.12-3, for Windows and Linux only.",
     "description": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.12-3, for Windows and Linux only.",
     "links": [
-      "<a href=\"https://archive.torproject.org/tor-package-archive/obfsproxy/\">package archive</a>",
-      "<a href=\"https://gitweb.torproject.org/project/web/webwml.git/diff/projects/en/obfsproxy.wml?id2=ab4e421afab1a3ff2a6fb1a8cbe33cd63a24ceda&id=b3ba7c694b8dcd21ab738d753d5dac05e7157ba6\">commits</a>"
+      {
+        "label": "package archive",
+        "target": "https://archive.torproject.org/tor-package-archive/obfsproxy/"
+      },
+      {
+        "label": "commits",
+        "target": "https://gitweb.torproject.org/project/web/webwml.git/diff/projects/en/obfsproxy.wml?id2=ab4e421afab1a3ff2a6fb1a8cbe33cd63a24ceda&id=b3ba7c694b8dcd21ab738d753d5dac05e7157ba6"
+      }
     ]
   },
   {
@@ -386,9 +558,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"February 22 2012 Maxmind GeoLite IPv6 Country\"",
     "description": "geoip6 database updated to \"February 22 2012 Maxmind GeoLite IPv6 Country\" (<code>geoip6-db-digest E39E1056F219DDF6E1C12F27CC50963D0F9774ED</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=abb886014e1ee35909e8876fe3361cbfd26cc27c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=abb886014e1ee35909e8876fe3361cbfd26cc27c"
+      }
     ]
   },
   {
@@ -400,10 +576,17 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Kazakhstan blocks Tor TLS by ClientHello and ServerHello fingerprints.",
     "description": "Kazakhstan blocks Tor TLS by ClientHello and ServerHello fingerprints.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/6140\">ticket</a>",
-      "<a href=\"https://gitweb.torproject.org/censorship-timeline.git/tree/patches/kazakhstan/notes.txt?id=3b09a1571c67f53dc81533c81f99cfadfd550d26\">tor patches</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/6140"
+      },
+      {
+        "label": "tor patches",
+        "target": "https://gitweb.torproject.org/censorship-timeline.git/tree/patches/kazakhstan/notes.txt?id=3b09a1571c67f53dc81533c81f99cfadfd550d26"
+      }
     ]
   },
   {
@@ -411,9 +594,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"March 6 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"March 6 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest 51EA5ED511A11D31FB4DAFCEC05B5347F6462B56</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=c5d7ee714f161f4963948cf948fb94a072b0017c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=c5d7ee714f161f4963948cf948fb94a072b0017c"
+      }
     ]
   },
   {
@@ -421,9 +608,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"February 22 2012 Maxmind GeoLite IPv6 Country\"",
     "description": "geoip6 database updated to \"February 22 2012 Maxmind GeoLite IPv6 Country\" (<code>geoip6-db-digest 2B442C5D9781145C0172ECC250DF71E25F0A957E</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=c03e3d66a910d103d3cce50a3bc1b778f68c36f2\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=c03e3d66a910d103d3cce50a3bc1b778f68c36f2"
+      }
     ]
   },
   {
@@ -431,9 +622,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"April 3 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"April 3 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest A27BE984989AB31C50D0861C7106B17A7EEC3756</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=b395b59353ea4b1b3221e220b47420b93aadcd0b\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=b395b59353ea4b1b3221e220b47420b93aadcd0b"
+      }
     ]
   },
   {
@@ -441,10 +636,17 @@
     "protocols": [
       "obfs2"
     ],
+    "shortDescription": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.12-4.",
     "description": "Release of \"Tor Obfsproxy Browser Bundle\" 2.3.12-4.",
     "links": [
-      "<a href=\"https://archive.torproject.org/tor-package-archive/obfsproxy/\">package archive</a>",
-      "<a href=\"https://gitweb.torproject.org/project/web/webwml.git/commit/projects/en/obfsproxy.wml?id=69f23bb361501c4cff1faeeeddb213f6c96b841a\">commit</a>"
+      {
+        "label": "package archive",
+        "target": "https://archive.torproject.org/tor-package-archive/obfsproxy/"
+      },
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/project/web/webwml.git/commit/projects/en/obfsproxy.wml?id=69f23bb361501c4cff1faeeeddb213f6c96b841a"
+      }
     ]
   },
   {
@@ -452,9 +654,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"May 1 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"May 1 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest 207A8167FC83230884A7B463B8EE12385CF1874F</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=24731ce6a779d67af832d882425bf7a6c6a6f9d2\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=24731ce6a779d67af832d882425bf7a6c6a6f9d2"
+      }
     ]
   },
   {
@@ -466,13 +672,29 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Ethiopia blocks Tor TLS.",
     "description": "Ethiopia blocks Tor TLS.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/6045\">ticket</a>",
-      "<a href=\"https://blog.torproject.org/blog/ethiopia-introduces-deep-packet-inspection\">blog post 1</a>",
-      "<a href=\"https://blog.torproject.org/blog/update-censorship-ethiopia\">blog post 2</a>",
-      "<a href=\"https://gitweb.torproject.org/censorship-timeline.git/tree/binaries/ethiopia?id=3b09a1571c67f53dc81533c81f99cfadfd550d26\">sample packets</a>",
-      "<a href=\"https://gitweb.torproject.org/censorship-timeline.git/tree/patches/ethiopia?id=3b09a1571c67f53dc81533c81f99cfadfd550d26\">tor patches</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/6045"
+      },
+      {
+        "label": "blog post 1",
+        "target": "https://blog.torproject.org/blog/ethiopia-introduces-deep-packet-inspection"
+      },
+      {
+        "label": "blog post 2",
+        "target": "https://blog.torproject.org/blog/update-censorship-ethiopia"
+      },
+      {
+        "label": "sample packets",
+        "target": "https://gitweb.torproject.org/censorship-timeline.git/tree/binaries/ethiopia?id=3b09a1571c67f53dc81533c81f99cfadfd550d26"
+      },
+      {
+        "label": "tor patches",
+        "target": "https://gitweb.torproject.org/censorship-timeline.git/tree/patches/ethiopia?id=3b09a1571c67f53dc81533c81f99cfadfd550d26"
+      }
     ]
   },
   {
@@ -480,9 +702,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"June 6 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"June 6 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest B7DC8C42403B1E0B50C671587DE406AED8DC5831</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=229abbf4bbb86b3fd2c138ec62460e1a0fda395f\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=229abbf4bbb86b3fd2c138ec62460e1a0fda395f"
+      }
     ]
   },
   {
@@ -490,10 +716,17 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Release of tor 0.2.3.17-beta",
     "description": "Release of tor 0.2.3.17-beta. Changes the TLS ciphersuite list to match that of Firefox 8, to evade blocking by China.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/4744\">ticket</a>",
-      "<a href=\"https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki/CensorshipCircumvention/TorChanges#a0.2.3.17-beta\">censorshipwiki entry</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/4744"
+      },
+      {
+        "label": "censorshipwiki entry",
+        "target": "https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki/CensorshipCircumvention/TorChanges#a0.2.3.17-beta"
+      }
     ]
   },
   {
@@ -501,9 +734,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"May 1 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"May 1 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest 207A8167FC83230884A7B463B8EE12385CF1874F</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=4e7552e5528e9e7f2f8ddaee81fe2da9606091b2\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=4e7552e5528e9e7f2f8ddaee81fe2da9606091b2"
+      }
     ]
   },
   {
@@ -511,9 +748,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"October 16 2012 Maxmind GeoLite IPv6 Country\"",
     "description": "geoip6 database updated to \"October 16 2012 Maxmind GeoLite IPv6 Country\" (<code>geoip6-db-digest 7F82A502C248B0CFBCCF6FE370919E34E04A21FA</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=96a731347592f1cbd4ddba9bfd7bc418344c4e38\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=96a731347592f1cbd4ddba9bfd7bc418344c4e38"
+      }
     ]
   },
   {
@@ -521,9 +762,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"November 7 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"November 7 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest 0D1734EB51EC9168C6428CD771945567B927F45C</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=d2cfd52d2c41a60cbf297aa9792cb63b22ad2ef9\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=d2cfd52d2c41a60cbf297aa9792cb63b22ad2ef9"
+      }
     ]
   },
   {
@@ -531,9 +776,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"December 5 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"December 5 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest 5A258599E3F768D0CEFBBD26F1D039760D43BB15</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=c9a5d613a6f12b7824ab03aa7c991a756fd14e19\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=c9a5d613a6f12b7824ab03aa7c991a756fd14e19"
+      }
     ]
   },
   {
@@ -541,9 +790,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"December 5 2012 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"December 5 2012 Maxmind GeoLite Country\" (<code>geoip-db-digest E00C7CD522D9ED6BEF69C6A904DCE51EC54EB768</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=6bdfa295b5bc921cba33bde15e1724a04780dea1\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=6bdfa295b5bc921cba33bde15e1724a04780dea1"
+      }
     ]
   },
   {
@@ -551,9 +804,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"January 2 2013 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"January 2 2013 Maxmind GeoLite Country\" (<code>geoip-db-digest DBBBA6D1F6CD90E860DDD42C90A21CF8A1B8395F</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=32114d70ae595eb570ceb7d4f9648fe83a361605\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=32114d70ae595eb570ceb7d4f9648fe83a361605"
+      }
     ]
   },
   {
@@ -563,9 +820,13 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of the pluggable transports browser bundle 2.4.7-alpha-1, containing flash proxy, obfs2, and obfs3 built in and enabled by default.",
     "description": "Release of the pluggable transports browser bundle 2.4.7-alpha-1, containing flash proxy, obfs2, and obfs3 built in and enabled by default.",
     "links": [
-      "<a href=\"https://blog.torproject.org/combined-flash-proxy-pyobfsproxy-browser-bundles\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/combined-flash-proxy-pyobfsproxy-browser-bundles"
+      }
     ]
   },
   {
@@ -573,9 +834,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated",
     "description": "geoip database updated (<code>geoip-db-digest 29DF86915FF87E2FBE12F3514776B7292B556CCD</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=adff7f944a50dd03bc74967343a376637b4195d1\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=adff7f944a50dd03bc74967343a376637b4195d1"
+      }
     ]
   },
   {
@@ -583,9 +848,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"March 6 2013 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"March 6 2013 Maxmind GeoLite Country\" (<code>geoip-db-digest CB30D739CF972BEE0EF0635838A2AD76E2171004</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=3dde6d5d29640fcab583e0f4a16b6aa1b000618d\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=3dde6d5d29640fcab583e0f4a16b6aa1b000618d"
+      }
     ]
   },
   {
@@ -595,9 +864,13 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of the pluggable transports browser bundle 0.2.4.11-alpha-2.",
     "description": "Release of the pluggable transports browser bundle 0.2.4.11-alpha-2.",
     "links": [
-      "<a href=\"https://blog.torproject.org/new-pluggable-transports-bundles-02411-alpha-flashproxy-obfsproxy\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/new-pluggable-transports-bundles-02411-alpha-flashproxy-obfsproxy"
+      }
     ]
   },
   {
@@ -605,9 +878,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"April 3 2013 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"April 3 2013 Maxmind GeoLite Country\" (<code>geoip-db-digest 7DDD315EBCDC2A8BCA47A8B5153EB697947AC851</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=b41f03f6dfd855e34628d935340d0f6292c82af8\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=b41f03f6dfd855e34628d935340d0f6292c82af8"
+      }
     ]
   },
   {
@@ -615,9 +892,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"May 9 2013 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"May 9 2013 Maxmind GeoLite Country\" (<code>geoip-db-digest 2ADCA1913666A685B141C03E7B2F50B3DB84FDC9</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=f8053179c972130482b70f62695ad0b0265e377d\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=f8053179c972130482b70f62695ad0b0265e377d"
+      }
     ]
   },
   {
@@ -627,9 +908,13 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of the pluggable transports browser bundle 2.4.12-alpha-2-pt1.",
     "description": "Release of the pluggable transports browser bundle 2.4.12-alpha-2-pt1.",
     "links": [
-      "<a href=\"https://blog.torproject.org/pluggable-transports-bundles-2412-alpha-2-pt1-firefox-1706esr\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/pluggable-transports-bundles-2412-alpha-2-pt1-firefox-1706esr"
+      }
     ]
   },
   {
@@ -637,9 +922,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"June 5 2013 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"June 5 2013 Maxmind GeoLite Country\" (<code>geoip-db-digest 5E570BB92DBEE1D517E35DAA4A52F58FDA6BB44E</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=d34753174eeaaae73be9cb9890368fab04afefd2\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=d34753174eeaaae73be9cb9890368fab04afefd2"
+      }
     ]
   },
   {
@@ -647,9 +936,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"July 3 2013 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"July 3 2013 Maxmind GeoLite Country\" (<code>geoip-db-digest 4D558EA73DD91A0361DE3FA3E83171DCD38D1A2D</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=2a61b0dd6be2eba9525b777dcb4400b93b695a2d\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=2a61b0dd6be2eba9525b777dcb4400b93b695a2d"
+      }
     ]
   },
   {
@@ -659,9 +952,13 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of the pluggable transports browser bundle 2.4.15-beta-2-pt1.",
     "description": "Release of the pluggable transports browser bundle 2.4.15-beta-2-pt1.",
     "links": [
-      "<a href=\"https://blog.torproject.org/pluggable-transports-bundles-2415-beta-2-pt1-firefox-1708esr\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/pluggable-transports-bundles-2415-beta-2-pt1-firefox-1708esr"
+      }
     ]
   },
   {
@@ -669,9 +966,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"August 7 2013 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"August 7 2013 Maxmind GeoLite Country\" (<code>geoip-db-digest 83CCB5AF823A5CCF3C86C3CA33AF801D4E8996EC</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=41bf8fa8892bc7ee2fc5c1d176535e9218d15afa\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=41bf8fa8892bc7ee2fc5c1d176535e9218d15afa"
+      }
     ]
   },
   {
@@ -681,12 +982,25 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Relay users increase globally from about 800K to over 5M, when computers in the Mevade/Sefnit botnet began using Tor to communicate",
     "description": "Relay users increase globally from about 800K to over 5M, when computers in the <a href=\"https://en.wikipedia.org/wiki/Mevade_Botnet\">Mevade/Sefnit botnet</a> began using Tor to communicate. The user count decreased in the following months through efforts to clean up the botnet. Sometime in 2014-04, the botnet switched from using Tor to using SSH.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/how-to-handle-millions-new-tor-clients\">blog post</a>",
-      "<a href=\"https://research.torproject.org/techreports/botnet-tr-2013-11-20.pdf\">tech report</a>",
-      "<a href=\"https://blog.fox-it.com/2013/09/05/large-botnet-cause-of-recent-tor-network-overload/\">analysis</a>",
-      "<a href=\"https://www.facebook.com/notes/protect-the-graph/sefnit-is-back/1448087102098103\">switch to SSH</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/how-to-handle-millions-new-tor-clients"
+      },
+      {
+        "label": "tech report",
+        "target": "https://research.torproject.org/techreports/botnet-tr-2013-11-20.pdf"
+      },
+      {
+        "label": "analysis",
+        "target": "https://blog.fox-it.com/2013/09/05/large-botnet-cause-of-recent-tor-network-overload/"
+      },
+      {
+        "label": "switch to SSH",
+        "target": "https://www.facebook.com/notes/protect-the-graph/sefnit-is-back/1448087102098103"
+      }
     ]
   },
   {
@@ -694,9 +1008,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"September 4 2013 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"September 4 2013 Maxmind GeoLite Country\" (<code>geoip-db-digest CB632F60547F141E06FB0705D1F171047165722E</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=13d192c1d8aebb331f49621abb0702624fdceef8\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=13d192c1d8aebb331f49621abb0702624fdceef8"
+      }
     ]
   },
   {
@@ -706,9 +1024,13 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of the pluggable transports browser bundle 2.4.17-beta-2-pt3.",
     "description": "Release of the pluggable transports browser bundle 2.4.17-beta-2-pt3.",
     "links": [
-      "<a href=\"https://blog.torproject.org/pluggable-transports-bundles-2417-beta-2-pt3-firefox-1709esr\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/pluggable-transports-bundles-2417-beta-2-pt3-firefox-1709esr"
+      }
     ]
   },
   {
@@ -716,9 +1038,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"October 2 2013 Maxmind GeoLite Country\"",
     "description": "geoip database updated to \"October 2 2013 Maxmind GeoLite Country\" (<code>geoip-db-digest A28267CED18A1D80B4298796E9FE42EC755420C0</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=3b0265198fc8a55279f2a8501104d2c54900c9d0\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=3b0265198fc8a55279f2a8501104d2c54900c9d0"
+      }
     ]
   },
   {
@@ -727,9 +1053,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Microsoft adds the Mevade/Sefnit botnet signature to various security scanners.",
     "description": "Microsoft adds the Mevade/Sefnit botnet signature to various security scanners.",
     "links": [
-      "<a href=\"https://blogs.technet.microsoft.com/mmpc/2014/01/09/tackling-the-sefnit-botnet-tor-hazard/\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blogs.technet.microsoft.com/mmpc/2014/01/09/tackling-the-sefnit-botnet-tor-hazard/"
+      }
     ]
   },
   {
@@ -738,9 +1068,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Microsoft adds the Mevade/Sefnit botnet signature to their Malicious Software Removal Tool.",
     "description": "Microsoft adds the Mevade/Sefnit botnet signature to their Malicious Software Removal Tool.",
     "links": [
-      "<a href=\"https://blogs.technet.microsoft.com/mmpc/2014/01/09/tackling-the-sefnit-botnet-tor-hazard/\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blogs.technet.microsoft.com/mmpc/2014/01/09/tackling-the-sefnit-botnet-tor-hazard/"
+      }
     ]
   },
   {
@@ -750,9 +1084,13 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of the pluggable transports browser bundle 2.4.17-rc-1-pt1.",
     "description": "Release of the pluggable transports browser bundle 2.4.17-rc-1-pt1.",
     "links": [
-      "<a href=\"https://blog.torproject.org/pluggable-transports-bundles-2417-rc-1-pt1-firefox-17010esr\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/pluggable-transports-bundles-2417-rc-1-pt1-firefox-17010esr"
+      }
     ]
   },
   {
@@ -762,9 +1100,13 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of the pluggable transports browser bundle 2.4.17-rc-1-pt2.",
     "description": "Release of the pluggable transports browser bundle 2.4.17-rc-1-pt2.",
     "links": [
-      "<a href=\"https://blog.torproject.org/pluggable-transports-bundles-2417-rc-1-pt2-firefox-17010esr\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/pluggable-transports-bundles-2417-rc-1-pt2-firefox-17010esr"
+      }
     ]
   },
   {
@@ -774,9 +1116,13 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of the pluggable transports browser bundle 2.4.18-rc-1-pt1 and 2.4.18-rc-2-pt1.",
     "description": "Release of the pluggable transports browser bundle 2.4.18-rc-1-pt1 and 2.4.18-rc-2-pt1.",
     "links": [
-      "<a href=\"https://blog.torproject.org/pluggable-transports-bundles-2418-rc-1-pt1-and-2418-rc-2-pt1-firefox-17011esr\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/pluggable-transports-bundles-2418-rc-1-pt1-and-2418-rc-2-pt1-firefox-17011esr"
+      }
     ]
   },
   {
@@ -784,9 +1130,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "First public announcement of meek.",
     "description": "First public announcement of meek.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2014-January/006159.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2014-January/006159.html"
+      }
     ]
   },
   {
@@ -794,9 +1144,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"February 7 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"February 7 2014 Maxmind GeoLite2 Country\" (<code>geoip-db-digest FA903A1122A248E107A1C17A5AC50A5852F03966</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=26dd328891b26fb3861851a6963c6dd628a35772\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=26dd328891b26fb3861851a6963c6dd628a35772"
+      }
     ]
   },
   {
@@ -804,9 +1158,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"February 7 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip6 database updated to \"February 7 2014 Maxmind GeoLite2 Country\" (<code>geoip6-db-digest FB95DF46D6B29167668F4D2CAC9F947C4B2A0C26</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=f6f691df7373cbf571f0e8d98deff87fb9a1e34e\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=f6f691df7373cbf571f0e8d98deff87fb9a1e34e"
+      }
     ]
   },
   {
@@ -815,6 +1173,7 @@
       "flashproxy",
       "meek"
     ],
+    "shortDescription": "Began running meek-server on bridge already hosting websocket-server for flash proxy.",
     "description": "Began running meek-server on bridge already hosting websocket-server for flash proxy."
   },
   {
@@ -822,9 +1181,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"February 7 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"February 7 2014 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 182195DB4DA9A979A829012F71CF128FAF1203F7</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=2658e70d16eccfdd4b37d23a8399fce492d0eea1\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=2658e70d16eccfdd4b37d23a8399fce492d0eea1"
+      }
     ]
   },
   {
@@ -835,16 +1198,24 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of Tor Browser 3.6-beta-1, the first release with integrated pluggable transports.",
     "description": "Release of Tor Browser 3.6-beta-1, the first release with integrated pluggable transports.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-36-beta-1-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-36-beta-1-released"
+      }
     ]
   },
   {
     "start": "2014-04-11",
+    "shortDescription": "Release of Tor Browser 3.6-beta-2.",
     "description": "Release of Tor Browser 3.6-beta-2.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-36-beta-2-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-36-beta-2-released"
+      }
     ]
   },
   {
@@ -855,10 +1226,17 @@
       "obfs2",
       "obfs3"
     ],
+    "shortDescription": "Release of Tor Browser 3.6, the first stable release with integrated pluggable transports.",
     "description": "Release of Tor Browser 3.6, the first stable release with integrated pluggable transports.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-36-released\">blog post</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-transport.html?start=2014-03-17&end=2014-06-15&transport=obfs2&transport=obfs3&transport=websocket&transport=%3COR%3E\">transport graph</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-36-released"
+      },
+      {
+        "label": "transport graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-transport.html?start=2014-03-17&end=2014-06-15&transport=obfs2&transport=obfs3&transport=websocket&transport=%3COR%3E"
+      }
     ]
   },
   {
@@ -867,6 +1245,7 @@
       "flashproxy",
       "meek"
     ],
+    "shortDescription": "Reinstalled the bridge running meek and flash proxy.",
     "description": "Reinstalled the bridge running meek and flash proxy."
   },
   {
@@ -874,9 +1253,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"June 4 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"June 4 2014 Maxmind GeoLite2 Country\" (<code>geoip-db-digest BFC7453BBEAD611B7FF97AD71BE3392AA8BCFBE3</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=555c43cd03b8a9c8ed1bb230ba206b3b62b9fec8\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=555c43cd03b8a9c8ed1bb230ba206b3b62b9fec8"
+      }
     ]
   },
   {
@@ -884,9 +1267,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"June 4 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip6 database updated to \"June 4 2014 Maxmind GeoLite2 Country\" (<code>geoip6-db-digest E0A79ABC85672AACD47878029C2C383D4C669335</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=40579cb6a5dca93f8d85d632f4589d29ab062a7c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=40579cb6a5dca93f8d85d632f4589d29ab062a7c"
+      }
     ]
   },
   {
@@ -894,9 +1281,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"July 10 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"July 10 2014 Maxmind GeoLite2 Country\" (<code>geoip-db-digest F2E34A314F2101E3F5AE0774660C4BA670646B8D</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=6d5efbef22739364c9d02d9237b66d26ac3ebb57\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=6d5efbef22739364c9d02d9237b66d26ac3ebb57"
+      }
     ]
   },
   {
@@ -904,9 +1295,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"July 10 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip6 database updated to \"July 10 2014 Maxmind GeoLite2 Country\" (<code>geoip6-db-digest 45893A1BDDABACCEB346DE4644A155450FD28B0E</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=6345dfa1fe6651f0ce447c78028b30c3d5a1b6d0\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=6345dfa1fe6651f0ce447c78028b30c3d5a1b6d0"
+      }
     ]
   },
   {
@@ -915,9 +1310,13 @@
     "places": [
       "ir"
     ],
+    "shortDescription": "Iran blocks Tor directory authorities.",
     "description": "Iran blocks Tor directory authorities.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/12727\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/12727"
+      }
     ]
   },
   {
@@ -925,13 +1324,18 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Set up meek-amazon CDN configuration.",
     "description": "Set up meek-amazon CDN configuration."
   },
   {
     "start": "2014-08-12",
+    "shortDescription": "Tor Browser 3.6.4 released.",
     "description": "Tor Browser 3.6.4 released.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-364-and-40-alpha-1-are-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-364-and-40-alpha-1-are-released"
+      }
     ]
   },
   {
@@ -940,9 +1344,13 @@
       "meek",
       "scramblesuit"
     ],
+    "shortDescription": "Tor Browser 4.0-alpha-1 released",
     "description": "Tor Browser 4.0-alpha-1 released. This is the first release to have meek and ScrambleSuit built in.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-364-and-40-alpha-1-are-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-364-and-40-alpha-1-are-released"
+      }
     ]
   },
   {
@@ -950,9 +1358,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"August 7 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"August 7 2014 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 9EF0A1874377BFB6413ED3F9EB5504B1DB17BE13</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=b98e3f993617fb6cb2e5f41bfa49c16a21965a4c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=b98e3f993617fb6cb2e5f41bfa49c16a21965a4c"
+      }
     ]
   },
   {
@@ -960,9 +1372,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"August 7 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip6 database updated to \"August 7 2014 Maxmind GeoLite2 Country\" (<code>geoip6-db-digest 542D349827A88738A04332DAFF2516A384BCC8FF</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=6235b4769d97df383472f8d0d5533b5b23a82f52\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=6235b4769d97df383472f8d0d5533b5b23a82f52"
+      }
     ]
   },
   {
@@ -970,9 +1386,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "'How to use the “meek” pluggable transport' blog post is published.",
     "description": "'How to use the “meek” pluggable transport' blog post is published.",
     "links": [
-      "<a href=\"https://blog.torproject.org/how-use-meek-pluggable-transport\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/how-use-meek-pluggable-transport"
+      }
     ]
   },
   {
@@ -981,9 +1401,13 @@
     "protocols": [
       "fte"
     ],
+    "shortDescription": "Decrease in fte users, perhaps caused by an outage of one of the default Tor Browser bridges.",
     "description": "Decrease in fte users, perhaps caused by an outage of one of the default Tor Browser bridges.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2014-September/007494.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2014-September/007494.html"
+      }
     ]
   },
   {
@@ -992,9 +1416,13 @@
       "flashproxy",
       "meek"
     ],
+    "shortDescription": "Split the bridge running meek and flashproxy into separate processes in order to avoid spurious correlation in user counts.",
     "description": "Split the bridge running meek and flashproxy into separate processes in order to avoid spurious correlation in user counts.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2014-September/007486.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2014-September/007486.html"
+      }
     ]
   },
   {
@@ -1002,9 +1430,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Switched meek-amazon to HTTPS.",
     "description": "Switched meek-amazon to HTTPS.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/13174\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/13174"
+      }
     ]
   },
   {
@@ -1012,6 +1444,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Changed the bridge backing meek-amazon.",
     "description": "Changed the bridge backing meek-amazon."
   },
   {
@@ -1019,9 +1452,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Enabled PublishServerDescriptor on the meek-amazon bridge",
     "description": "Enabled PublishServerDescriptor on the meek-amazon bridge. Between 2014-09-29 and 2014-10-14, meek-amazon users were not being counted.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2014-October/007611.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2014-October/007611.html"
+      }
     ]
   },
   {
@@ -1030,9 +1467,13 @@
       "meek",
       "scramblesuit"
     ],
+    "shortDescription": "Tor Browser 4.0 released",
     "description": "Tor Browser 4.0 released. This is the first stable release with meek and ScrambleSuit built in.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-browser-40-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/tor-browser-40-released"
+      }
     ]
   },
   {
@@ -1040,6 +1481,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Changed the bridge backing meek-google.",
     "description": "Changed the bridge backing meek-google."
   },
   {
@@ -1047,6 +1489,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Changed the meek-google App Engine instance to the F2 class, from F1.",
     "description": "Changed the meek-google App Engine instance to the F2 class, from F1."
   },
   {
@@ -1054,6 +1497,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Changed the meek-google App Engine instance back to the F1 class, from F2.",
     "description": "Changed the meek-google App Engine instance back to the F1 class, from F2."
   },
   {
@@ -1061,6 +1505,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Changed the meek-google App Engine instance to the F2 class again, from F1.",
     "description": "Changed the meek-google App Engine instance to the F2 class again, from F1."
   },
   {
@@ -1068,6 +1513,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Changed the meek-google App Engine instance back to the F1 class, from F2.",
     "description": "Changed the meek-google App Engine instance back to the F1 class, from F2."
   },
   {
@@ -1075,6 +1521,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Moved the meek-google bridge to better hardware.",
     "description": "Moved the meek-google bridge to better hardware."
   },
   {
@@ -1082,9 +1529,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Release of Tor Browser 4.5-alpha-1, first alpha release with obfs4",
     "description": "Release of Tor Browser 4.5-alpha-1, first alpha release with obfs4. (Tor Browser changelog says 2014-11-14.)",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-45-alpha-1-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-45-alpha-1-released"
+      }
     ]
   },
   {
@@ -1092,9 +1543,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"November 15 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"November 15 2014 Maxmind GeoLite2 Country\" (<code>geoip-db-digest DC1A94D962AE165EF4AA1F14857A23C34875F39D</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=8611c6bccd9fe4c688e83b28fb4e2b2b0fe7a6b3\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=8611c6bccd9fe4c688e83b28fb4e2b2b0fe7a6b3"
+      }
     ]
   },
   {
@@ -1102,9 +1557,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"November 15 2014 Maxmind GeoLite2 Country\"",
     "description": "geoip6 database updated to \"November 15 2014 Maxmind GeoLite2 Country\" (<code>geoip6-db-digest 923BA7ED922B2A4B30C9B76EE7E72D1D1714BFAF</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=5441c733e07beafaba61251b0fafed4bd96eaf40\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=5441c733e07beafaba61251b0fafed4bd96eaf40"
+      }
     ]
   },
   {
@@ -1112,9 +1571,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"January 7 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"January 7 2015 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 49D309B9663C4EFB8D126D84BBB373D7C84658C3</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=c3f8f5ab0e74db2269d55ff51a0918a41b374fc6\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=c3f8f5ab0e74db2269d55ff51a0918a41b374fc6"
+      }
     ]
   },
   {
@@ -1122,9 +1585,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"January 7 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip6 database updated to \"January 7 2015 Maxmind GeoLite2 Country\" (<code>geoip6-db-digest 9B26276EA470137894566882885AD82701D38D62</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=a9ce0cd659fae01a139f4aed5745817717ccabc0\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=a9ce0cd659fae01a139f4aed5745817717ccabc0"
+      }
     ]
   },
   {
@@ -1132,9 +1599,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Release of Orbot v15-alpha-3, first release with meek.",
     "description": "Release of Orbot v15-alpha-3, first release with meek.",
     "links": [
-      "<a href=\"https://lists.mayfirst.org/pipermail/guardian-dev/2015-February/004243.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.mayfirst.org/pipermail/guardian-dev/2015-February/004243.html"
+      }
     ]
   },
   {
@@ -1142,6 +1613,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Altered performance settings on the meek-google App Engine instance in an effort to reduce instance hours",
     "description": "Altered performance settings on the meek-google App Engine instance in an effort to reduce instance hours. Set max idle instances to 4 and min pending latency to 500 ms."
   },
   {
@@ -1149,9 +1621,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"March 3 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"March 3 2015 Maxmind GeoLite2 Country\" (<code>geoip-db-digest C1EB5237F2FBAF63381D8551157F13D12EFCCA25</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=beda8d2934e41e9b4b5d36f172deed9e71e91f24\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=beda8d2934e41e9b4b5d36f172deed9e71e91f24"
+      }
     ]
   },
   {
@@ -1159,9 +1635,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"March 3 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip6 database updated to \"March 3 2015 Maxmind GeoLite2 Country\" (<code>geoip6-db-digest 1F99B6B0EC78E9DB34D61AE7E0FC261D558E8E5D</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=62714068d94772e74e7eb8c1ea63cfa5304a4403\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=62714068d94772e74e7eb8c1ea63cfa5304a4403"
+      }
     ]
   },
   {
@@ -1169,9 +1649,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Implemented persistent connections for meek-azure, increasing performance.",
     "description": "Implemented persistent connections for meek-azure, increasing performance.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2015-April/008637.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2015-April/008637.html"
+      }
     ]
   },
   {
@@ -1179,9 +1663,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Tor Weekly News covers the meek-azure performance improvement.",
     "description": "Tor Weekly News covers the meek-azure performance improvement.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-weekly-news-%E2%80%94-april-15th-2015\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/tor-weekly-news-%E2%80%94-april-15th-2015"
+      }
     ]
   },
   {
@@ -1190,9 +1678,13 @@
       "meek",
       "obfs4"
     ],
+    "shortDescription": "Release of Orbot v15 alpha 5, first release with obfs4.",
     "description": "Release of Orbot v15 alpha 5, first release with obfs4.",
     "links": [
-      "<a href=\"https://lists.mayfirst.org/pipermail/guardian-dev/2015-March/004283.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.mayfirst.org/pipermail/guardian-dev/2015-March/004283.html"
+      }
     ]
   },
   {
@@ -1200,9 +1692,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"April 8 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"April 8 2015 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 0A1F9C09E08F6F2490E8880664D4E863D1680A12</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=bcc0a48cfe6cfd3a96580fc345553fa3fb37c5b1\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=bcc0a48cfe6cfd3a96580fc345553fa3fb37c5b1"
+      }
     ]
   },
   {
@@ -1210,9 +1706,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"April 8 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip6 database updated to \"April 8 2015 Maxmind GeoLite2 Country\" (<code>geoip6-db-digest A6E9B5DE6F887315749B29F9C9F698215BE5240A</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=b5f64958764aae7f2ccb7c873fa61b47a2a7e9ba\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=b5f64958764aae7f2ccb7c873fa61b47a2a7e9ba"
+      }
     ]
   },
   {
@@ -1220,9 +1720,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Release of Tor Browser 4.5, the first stable release with obfs4.",
     "description": "Release of Tor Browser 4.5, the first stable release with obfs4.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-45-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-45-released"
+      }
     ]
   },
   {
@@ -1230,6 +1734,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Rate-limited the meek-google bridge to 1.5 MB/s.",
     "description": "Rate-limited the meek-google bridge to 1.5 MB/s."
   },
   {
@@ -1237,6 +1742,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Further rate-limited meek-google to 1.1 MB/s, from 1.5 MB/s.",
     "description": "Further rate-limited meek-google to 1.1 MB/s, from 1.5 MB/s."
   },
   {
@@ -1244,6 +1750,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Rate-limited the meek-amazon bridge to 1.1 MB/s.",
     "description": "Rate-limited the meek-amazon bridge to 1.1 MB/s."
   },
   {
@@ -1251,9 +1758,13 @@
     "protocols": [
       "ipv4"
     ],
+    "shortDescription": "geoip database updated to \"June 3 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip database updated to \"June 3 2015 Maxmind GeoLite2 Country\" (<code>geoip-db-digest D095D62E8A1607C2C3AF61366929BCAD0E6D3184</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=e5907e94c225cabec1f5cf94870c424fc1767c7e\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=e5907e94c225cabec1f5cf94870c424fc1767c7e"
+      }
     ]
   },
   {
@@ -1261,9 +1772,13 @@
     "protocols": [
       "ipv6"
     ],
+    "shortDescription": "geoip6 database updated to \"June 3 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip6 database updated to \"June 3 2015 Maxmind GeoLite2 Country\" (<code>geoip6-db-digest AC1BE3D0707D16AB04092FE00C9732658C926CD8</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=08e14e1448fdf8e82e0336c6f7bfb729572d6b29\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=08e14e1448fdf8e82e0336c6f7bfb729572d6b29"
+      }
     ]
   },
   {
@@ -1272,10 +1787,17 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Outage of meek-azure.",
     "description": "Outage of meek-azure.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2015-July/038487.html\">mailing list post about start</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2015-August/038780.html\">mailing list post about end</a>"
+      {
+        "label": "mailing list post about start",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2015-July/038487.html"
+      },
+      {
+        "label": "mailing list post about end",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2015-August/038780.html"
+      }
     ]
   },
   {
@@ -1283,9 +1805,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Published a workaround for the meek-azure outage that started 2015-07-20.",
     "description": "Published a workaround for the meek-azure outage that started 2015-07-20.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2015-July/038496.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2015-July/038496.html"
+      }
     ]
   },
   {
@@ -1294,9 +1820,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"July 8 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"July 8 2015 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 6882B8663F74C23E26E3C2274C24CAB2E82D67A2</code>, <code>geoip6-db-digest F063BD5247EB9829E6B9E586393D7036656DAF44</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=7004d67430857f8b279bbfe789eb127c954f69eb\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=7004d67430857f8b279bbfe789eb127c954f69eb"
+      }
     ]
   },
   {
@@ -1304,11 +1834,21 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Tor Browser 5.0 and 5.5a1 released",
     "description": "Tor Browser 5.0 and 5.5a1 released. They have an updated configuration to work around the meek-azure outage that started 2015-07-20.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-50-released\">blog post</a>",
-      "<a href=\"https://blog.torproject.org/tor-browser-55a1-released\">blog post</a>",
-      "<a href=\"https://bugs.torproject.org/16634\">ticket</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-50-released"
+      },
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-55a1-released"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/16634"
+      }
     ]
   },
   {
@@ -1316,9 +1856,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Upgraded meek-azure bridge from KVM to Xen.",
     "description": "Upgraded meek-azure bridge from KVM to Xen.",
     "links": [
-      "<a href=\"https://blog.linode.com/2015/06/16/linode-turns-12-heres-some-kvm/\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.linode.com/2015/06/16/linode-turns-12-heres-some-kvm/"
+      }
     ]
   },
   {
@@ -1327,9 +1871,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"September 3 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"September 3 2015 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 022B9BADD23D743E51F165FB4C87E78E59F0BCB8</code>, <code>geoip6-db-digest DE13219FCF0F27999D1F91174CF80291B1746C95</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=8b3e0b772991b5611f06596865b6a61dd394237f\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=8b3e0b772991b5611f06596865b6a61dd394237f"
+      }
     ]
   },
   {
@@ -1338,11 +1886,21 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Outage of meek-amazon caused by an expired certificate",
     "description": "Outage of meek-amazon caused by an expired certificate. As a result of being rebooted, the bridge also changes its fingerprint from 4EE0CC769EB4B15A872F742EDE27D298A59DCADE to 6DDD1DB8526282837C50E9AB5D14AB50150CD624.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2015-October/039231.html\">mailing list post about start</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2015-October/039234.html\">mailing list post about end</a>",
-      "<a href=\"https://bugs.torproject.org/17473\">ticket</a>"
+      {
+        "label": "mailing list post about start",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2015-October/039231.html"
+      },
+      {
+        "label": "mailing list post about end",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2015-October/039234.html"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/17473"
+      }
     ]
   },
   {
@@ -1350,6 +1908,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Rate-limited the meek-azure bridge to 1.1 MB/s",
     "description": "Rate-limited the meek-azure bridge to 1.1 MB/s. (Azure grant expired.)"
   },
   {
@@ -1357,9 +1916,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "The fingerprint of the meek-amazon bridge changes, as a result of begin rebooted",
     "description": "The fingerprint of the meek-amazon bridge changes, as a result of begin rebooted. Released Tor Browsers with the former fingerprint are unable to connect. The fingerprint changed from 4EE0CC769EB4B15A872F742EDE27D298A59DCADE to 6DDD1DB8526282837C50E9AB5D14AB50150CD624, then again to B9E7141C594AF25699E0079C1F0146F409495296. The new fingerprint shipped with Tor Browser 5.0.4 and 5.5a4 on 2015-11-04.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/17473\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/17473"
+      }
     ]
   },
   {
@@ -1368,9 +1931,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"October 9 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"October 9 2015 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 5BF366AD4A0572D82A1A0F6628AF8EF7725E3AB9</code>, <code>geoip6-db-digest 212DE17D5A368DCAFA19B95F168BFFA101145A93</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=62b02a1941c6c51efe36f804ddd10f62a3606d41\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=62b02a1941c6c51efe36f804ddd10f62a3606d41"
+      }
     ]
   },
   {
@@ -1378,6 +1945,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Altered the performance settings on the meek-google App Engine instance",
     "description": "Altered the performance settings on the meek-google App Engine instance. Set max idle instances to 2 and min pending latency to 1000 ms. This used to be configured through the web interface but is now configured in an application file, which at some point caused the settings from 2015-02-28 to be lost."
   },
   {
@@ -1385,6 +1953,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Further rate-limited the meek-azure bridge to 0.8 MB/s, from 1.1 MB/s.",
     "description": "Further rate-limited the meek-azure bridge to 0.8 MB/s, from 1.1 MB/s."
   },
   {
@@ -1392,11 +1961,21 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Tor Browser 5.0.4 and 5.5a4 released, containing a fixed fingerprint for meek-amazon.",
     "description": "Tor Browser 5.0.4 and 5.5a4 released, containing a fixed fingerprint for meek-amazon.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-504-released\">5.0.4 blog post</a>",
-      "<a href=\"https://blog.torproject.org/tor-browser-55a4-released\">5.5a4 blog post</a>",
-      "<a href=\"https://bugs.torproject.org/17473\">ticket</a>"
+      {
+        "label": "5.0.4 blog post",
+        "target": "https://blog.torproject.org/tor-browser-504-released"
+      },
+      {
+        "label": "5.5a4 blog post",
+        "target": "https://blog.torproject.org/tor-browser-55a4-released"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/17473"
+      }
     ]
   },
   {
@@ -1410,11 +1989,21 @@
       "obfs3",
       "obfs4"
     ],
+    "shortDescription": "Bangladesh blocks Facebook, WhatsApp, and Viber.",
     "description": "Bangladesh blocks Facebook, WhatsApp, and Viber.",
     "links": [
-      "<a href=\"http://phys.org/news/2015-12-bangladesh-facebook.html\">news article</a>",
-      "<a href=\"https://archive.fo/fc2WQ\">(archive)</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2015-08-01&end=2016-02-01&country=bd&events=off\">relay graph</a>"
+      {
+        "label": "news article",
+        "target": "http://phys.org/news/2015-12-bangladesh-facebook.html"
+      },
+      {
+        "label": "(archive)",
+        "target": "https://archive.fo/fc2WQ"
+      },
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2015-08-01&end=2016-02-01&country=bd&events=off"
+      }
     ]
   },
   {
@@ -1423,9 +2012,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"December 1 2015 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"December 1 2015 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 6346E26E2BC96F8511588CE2695E9B0339A75D32</code>, <code>geoip6-db-digest 43CCB43DBC653D8CC16396A882C5F116A6004F0C</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=dbb919cf9400738987bbb91166b7b30c4cf770e9\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=dbb919cf9400738987bbb91166b7b30c4cf770e9"
+      }
     ]
   },
   {
@@ -1433,9 +2026,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Enabled client IP statistics on the meek-azure bridge.",
     "description": "Enabled client IP statistics on the meek-azure bridge.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/13171#comment:7\">comment</a>"
+      {
+        "label": "comment",
+        "target": "https://bugs.torproject.org/13171#comment:7"
+      }
     ]
   },
   {
@@ -1443,9 +2040,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Enabled client IP statistics on the meek-google bridge.",
     "description": "Enabled client IP statistics on the meek-google bridge.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/13171#comment:10\">comment</a>"
+      {
+        "label": "comment",
+        "target": "https://bugs.torproject.org/13171#comment:10"
+      }
     ]
   },
   {
@@ -1453,6 +2054,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Established an unthrottled bridge C20658946DD706A7A2181159A1A04CD838570D04 for people who set up their own meek CDN configuration.",
     "description": "Established an unthrottled bridge <a href=\"https://metrics.torproject.org/rs.html#details/C20658946DD706A7A2181159A1A04CD838570D04\">C20658946DD706A7A2181159A1A04CD838570D04</a> for people who set up their own meek CDN configuration."
   },
   {
@@ -1461,9 +2063,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"January 5 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"January 5 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 44FC92E4D3F8C9A3A49EE9A594790C52E684298A</code>, <code>geoip6-db-digest BB261912C96611967FE5C1AE2700C965DBB8D61C</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=1496056c121d02193433d98173213e52eb3e90a7\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=1496056c121d02193433d98173213e52eb3e90a7"
+      }
     ]
   },
   {
@@ -1471,9 +2077,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Enabled client IP statistics on the meek-amazon bridge.",
     "description": "Enabled client IP statistics on the meek-amazon bridge.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/13171#comment:13\">comment</a>"
+      {
+        "label": "comment",
+        "target": "https://bugs.torproject.org/13171#comment:13"
+      }
     ]
   },
   {
@@ -1481,6 +2091,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Increased rate limit of the meek-azure bridge to 3 MB/s, from 0.8 MB/s.",
     "description": "Increased rate limit of the meek-azure bridge to 3 MB/s, from 0.8 MB/s."
   },
   {
@@ -1488,6 +2099,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Increased rate limit of the meek-google bridge to 3 MB/s, from 1.1 MB/s.",
     "description": "Increased rate limit of the meek-google bridge to 3 MB/s, from 1.1 MB/s."
   },
   {
@@ -1495,6 +2107,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Increased rate limit of the meek-amazon bridge to 3 MB/s, from 1.1 MB/s.",
     "description": "Increased rate limit of the meek-amazon bridge to 3 MB/s, from 1.1 MB/s."
   },
   {
@@ -1506,9 +2119,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Temporary blocking of an Azure edge server in China.",
     "description": "Temporary blocking of an Azure edge server in China.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2016-February/040199.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2016-February/040199.html"
+      }
     ]
   },
   {
@@ -1517,9 +2134,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"February 2 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"February 2 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 9E16EDBB826B958A7B8B84674EA98B78C13F1177</code>, <code>geoip6-db-digest DF9538534517275080F8335DDEE4B879A3314ED4</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=d5ac79e056bdb740adecf45ef3b50d1c16cf394f\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=d5ac79e056bdb740adecf45ef3b50d1c16cf394f"
+      }
     ]
   },
   {
@@ -1528,9 +2149,13 @@
     "places": [
       "ug"
     ],
+    "shortDescription": "Social media blackout in Uganda during presidential election.",
     "description": "Social media blackout in Uganda during presidential election.",
     "links": [
-      "<a href=\"https://freedomhouse.org/report/freedom-net/2016/uganda#a2-limits\">Freedom House report</a>"
+      {
+        "label": "Freedom House report",
+        "target": "https://freedomhouse.org/report/freedom-net/2016/uganda#a2-limits"
+      }
     ]
   },
   {
@@ -1539,9 +2164,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"March 3 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"March 3 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest A34F49E5A871FA4D243C46C04B67BB3CAAFE6F74</code>, <code>geoip6-db-digest 9C8C4F7C7612849C88206726FCDA8CB85B8D27F3</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=8e2640b15ab72630e0f391a51f927c042346b503\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=8e2640b15ab72630e0f391a51f927c042346b503"
+      }
     ]
   },
   {
@@ -1550,6 +2179,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Outage of meek-azure bridge, caused by an expired TLS certificate.",
     "description": "Outage of meek-azure bridge, caused by an expired TLS certificate."
   },
   {
@@ -1558,9 +2188,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Temporarily ran an experimental branch for IPv6 counting on the meek-azure bridge.",
     "description": "Temporarily ran an experimental branch for IPv6 counting on the meek-azure bridge.",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/karsten/tor.git/log/?h=task-18460-2&id=b79d859\">task-18460-2 branch</a>"
+      {
+        "label": "task-18460-2 branch",
+        "target": "https://gitweb.torproject.org/karsten/tor.git/log/?h=task-18460-2&id=b79d859"
+      }
     ]
   },
   {
@@ -1569,9 +2203,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"April 5 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"April 5 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest F9DFB82B6F1A480F07F4B87992CBFB7A48CB8DA2</code>, <code>geoip6-db-digest 769B499E6AE9FE0C2366141B931A3DB1B5489114</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=97c6e717b9f3f198163c6d5b4bde86e7f3da28d0\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=97c6e717b9f3f198163c6d5b4bde86e7f3da28d0"
+      }
     ]
   },
   {
@@ -1579,11 +2217,21 @@
     "protocols": [
       "fte"
     ],
+    "shortDescription": "Tor Browser 6.0a5 and 6.0a5-hardened released, which lacks the fte pluggable transport on Mac.",
     "description": "Tor Browser 6.0a5 and 6.0a5-hardened released, which lacks the fte pluggable transport on Mac.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-browser-60a5-released\">6.0a5 blog post</a>",
-      "<a href=\"https://blog.torproject.org/blog/tor-browser-60a5-hardened-released\">6.0a5-hardened blog post</a>",
-      "<a href=\"https://bugs.torproject.org/18495\">ticket</a>"
+      {
+        "label": "6.0a5 blog post",
+        "target": "https://blog.torproject.org/blog/tor-browser-60a5-released"
+      },
+      {
+        "label": "6.0a5-hardened blog post",
+        "target": "https://blog.torproject.org/blog/tor-browser-60a5-hardened-released"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/18495"
+      }
     ]
   },
   {
@@ -1595,11 +2243,21 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "WhatsApp block in Brazil",
     "description": "WhatsApp block in Brazil",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tracking-impact-whatsapp-blockage-tor\">blog post</a>",
-      "<a href=\"https://ooni.torproject.org/post/brazil-whatsapp-block/\">OONI report</a>",
-      "<a href=\"http://bloqueios.info/en/casos/block-for-non-compliance-with-judicial-requests-for-user-data-3/\">bloqueios report</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/tracking-impact-whatsapp-blockage-tor"
+      },
+      {
+        "label": "OONI report",
+        "target": "https://ooni.torproject.org/post/brazil-whatsapp-block/"
+      },
+      {
+        "label": "bloqueios report",
+        "target": "http://bloqueios.info/en/casos/block-for-non-compliance-with-judicial-requests-for-user-data-3/"
+      }
     ]
   },
   {
@@ -1608,9 +2266,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"May 4 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"May 4 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 76631C314A048A59A1D801515CC7FD55CE719499</code>, <code>geoip6-db-digest C9392F0337A7509F1187890925CF7006F884ECBA</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=3c2d4611ce52024364bc729a97749651ac239e80\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=3c2d4611ce52024364bc729a97749651ac239e80"
+      }
     ]
   },
   {
@@ -1619,11 +2281,21 @@
     "places": [
       "ug"
     ],
+    "shortDescription": "Social media blackout in Uganda following presidential inauguration.",
     "description": "Social media blackout in Uganda following presidential inauguration.",
     "links": [
-      "<a href=\"https://advox.globalvoices.org/2016/05/17/ugandans-are-finally-back-on-social-media-after-days-long-blackout/\">advox article</a>",
-      "<a href=\"https://ooni.torproject.org/post/uganda-social-media-blocked/\">OONI report</a>",
-      "<a href=\"https://freedomhouse.org/report/freedom-net/2016/uganda#a2-limits\">Freedom House report</a>"
+      {
+        "label": "advox article",
+        "target": "https://advox.globalvoices.org/2016/05/17/ugandans-are-finally-back-on-social-media-after-days-long-blackout/"
+      },
+      {
+        "label": "OONI report",
+        "target": "https://ooni.torproject.org/post/uganda-social-media-blocked/"
+      },
+      {
+        "label": "Freedom House report",
+        "target": "https://freedomhouse.org/report/freedom-net/2016/uganda#a2-limits"
+      }
     ]
   },
   {
@@ -1631,9 +2303,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "meek-google's App Engine instance is suspended and meek-google stops working.",
     "description": "meek-google's App Engine instance is suspended and meek-google stops working.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2016-June/041057.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2016-June/041057.html"
+      }
     ]
   },
   {
@@ -1641,10 +2317,17 @@
     "protocols": [
       "fte"
     ],
+    "shortDescription": "Tor Browser 6.0 released, which lacks the fte pluggable transport on Mac.",
     "description": "Tor Browser 6.0 released, which lacks the fte pluggable transport on Mac.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-browser-60-released\">6.0 blog post</a>",
-      "<a href=\"https://bugs.torproject.org/18495\">ticket</a>"
+      {
+        "label": "6.0 blog post",
+        "target": "https://blog.torproject.org/blog/tor-browser-60-released"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/18495"
+      }
     ]
   },
   {
@@ -1656,9 +2339,13 @@
       "<OR>",
       "obfs4"
     ],
+    "shortDescription": "Kazakhstan blocks vanilla Tor TLS",
     "description": "Kazakhstan blocks vanilla Tor TLS. Users mostly switch to obfs4.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20348\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20348"
+      }
     ]
   },
   {
@@ -1667,9 +2354,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"June 7 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"June 7 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest DA31976A9C7D48C2C16EA70BCE9006772A0F4A34</code>, <code>geoip6-db-digest FF1DD08CA9EB6528E1A6389E7154BD9586F24370</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=c14c662758e95e85aa251c959c4d03c7598783d8\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=c14c662758e95e85aa251c959c4d03c7598783d8"
+      }
     ]
   },
   {
@@ -1680,10 +2371,17 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Coup attempt in Turkey",
     "description": "Coup attempt in Turkey. A paper (§ 4.1) reports a decline in Tor users.",
     "links": [
-      "<a href=\"https://www.usenix.org/conference/foci17/workshop-program/presentation/tanash\">paper</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2016-04-01&end=2016-09-01&country=tr\">relay graph</a>"
+      {
+        "label": "paper",
+        "target": "https://www.usenix.org/conference/foci17/workshop-program/presentation/tanash"
+      },
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2016-04-01&end=2016-09-01&country=tr"
+      }
     ]
   },
   {
@@ -1692,9 +2390,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"July 6 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"July 6 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 19FC902B6A860BA7E4BADCB5404482995F7E0763</code>, <code>geoip6-db-digest 7E717154718F2065240B90F8132F305AF78C9A9D</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=79939c6f11edbd5bec21594b1f4337d8cfa2a843\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=79939c6f11edbd5bec21594b1f4337d8cfa2a843"
+      }
     ]
   },
   {
@@ -1703,9 +2405,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"August 2 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"August 2 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 9DD185BEC4F482DDD20A0221B3DD3F40175F0123</code>, <code>geoip6-db-digest B1C1B6BDC9627E3D87530A2C70578AC69C20C5C6</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=1410947351a0e498c2a4c568db3a55b44fd9aa6e\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=1410947351a0e498c2a4c568db3a55b44fd9aa6e"
+      }
     ]
   },
   {
@@ -1713,6 +2419,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Changed the meek-amazon CDN price class from \"All\" to \"Use Only US, Canada and Europe.\"",
     "description": "Changed the meek-amazon CDN price class from \"All\" to \"Use Only US, Canada and Europe.\""
   },
   {
@@ -1723,9 +2430,13 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Iran somehow blocks most direct Tor connections",
     "description": "Iran somehow blocks most direct Tor connections. May also affect bridge users, but it's hard to tell because there were few vanilla bridge users anyway.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20216\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20216"
+      }
     ]
   },
   {
@@ -1733,9 +2444,13 @@
     "protocols": [
       "bridge"
     ],
+    "shortDescription": "tor 0.2.8.7 and 0.2.9.2-alpha are released, changing the bridge authority from Tonga to Bifroest.",
     "description": "tor 0.2.8.7 and 0.2.9.2-alpha are released, changing the bridge authority from Tonga to Bifroest.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-0287-released-important-fixes\">0.2.8.7 announcement</a>"
+      {
+        "label": "0.2.8.7 announcement",
+        "target": "https://blog.torproject.org/blog/tor-0287-released-important-fixes"
+      }
     ]
   },
   {
@@ -1743,9 +2458,13 @@
     "protocols": [
       "bridge"
     ],
+    "shortDescription": "CollecTor begins publishing bridge stats from the new bridge authority Bifroest.",
     "description": "CollecTor begins publishing bridge stats from the new bridge authority Bifroest.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2016-August/011336.html\">post</a>"
+      {
+        "label": "post",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2016-August/011336.html"
+      }
     ]
   },
   {
@@ -1753,11 +2472,21 @@
     "protocols": [
       "bridge"
     ],
+    "shortDescription": "The former bridge authority Tonga shuts down",
     "description": "The former bridge authority Tonga shuts down. Bridges that have not updated to tor 0.2.8.7 or 0.2.9.2-alpha (which include all 5 default obfs3 bridges and 3/16 default obfs4 bridges) stop reporting statistics.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/19690#comment:17\">shutdown notice</a>",
-      "<a href=\"https://blog.torproject.org/blog/new-bridge-authority\">blog post</a>",
-      "<a href=\"https://metrics.torproject.org/networksize.html?start=2016-07-01&end=2016-09-23\">loss of reporting bridges</a>"
+      {
+        "label": "shutdown notice",
+        "target": "https://bugs.torproject.org/19690#comment:17"
+      },
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/new-bridge-authority"
+      },
+      {
+        "label": "loss of reporting bridges",
+        "target": "https://metrics.torproject.org/networksize.html?start=2016-07-01&end=2016-09-23"
+      }
     ]
   },
   {
@@ -1768,9 +2497,13 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Iran intensifies the blocking begun on 2016-08-20, getting most of the remaining direct users",
     "description": "Iran intensifies the blocking begun on 2016-08-20, getting most of the remaining direct users. There is interference in the graphs from the bridge authority changeover on 2016-09-02, but because the changeover would not have affected counts of ''direct'' users, it may be a coincidence.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20216\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20216"
+      }
     ]
   },
   {
@@ -1779,9 +2512,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"September 6 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"September 6 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 72F8AD2CD7C97D173AD53276366EAD32B13E0A50</code>, <code>geoip6-db-digest B6427DEAD2291FBF8311A2233AF4960BF4009713</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=56f95ba94dfeaacee63047b1613129de3d01be87\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=56f95ba94dfeaacee63047b1613129de3d01be87"
+      }
     ]
   },
   {
@@ -1789,9 +2526,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "macOS 10.12",
     "description": "macOS 10.12 (Sierra) is released, breaking some programs that are built with Go <1.7, including the meek-client that comes with Tor Browser. (See 2016-11-15 unbreaking event.)",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20250\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20250"
+      }
     ]
   },
   {
@@ -1799,9 +2540,13 @@
     "protocols": [
       "obfs3"
     ],
+    "shortDescription": "Default obfs3 bridges ndnop0 and ndnop2 upgrade and begin reporting statistics to the new bridge authority Bifroest.",
     "description": "Default obfs3 bridges ndnop0 and ndnop2 upgrade and begin reporting statistics to the new bridge authority Bifroest.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2016-September/000217.html\">post on bridges not reporting statistics</a>"
+      {
+        "label": "post on bridges not reporting statistics",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2016-September/000217.html"
+      }
     ]
   },
   {
@@ -1809,9 +2554,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Default obfs3 bridges ndnop3 and ndnop5 upgrade and begin reporting statistics to the new bridge authority Bifroest.",
     "description": "Default obfs3 bridges ndnop3 and ndnop5 upgrade and begin reporting statistics to the new bridge authority Bifroest.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2016-September/000217.html\">post on bridges not reporting statistics</a>"
+      {
+        "label": "post on bridges not reporting statistics",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2016-September/000217.html"
+      }
     ]
   },
   {
@@ -1819,6 +2568,7 @@
     "protocols": [
       "obfs3"
     ],
+    "shortDescription": "Default obfs3 bridges \"Unnamed\" and \"Unnamed\"",
     "description": "Default obfs3 bridges \"Unnamed\" and \"Unnamed\" (fingerprint <a href=\"https://metrics.torproject.org/rs.html#details/AF9F66B7B04F8FF6F32D455F05135250A16543C9\">AF9F66B7B04F8FF6F32D455F05135250A16543C9</a>) upgrade and begin reporting statistics to the new bridge authority Bifroest."
   },
   {
@@ -1827,6 +2577,7 @@
     "protocols": [
       "obfs3"
     ],
+    "shortDescription": "Outage of default obfs3 bridges \"Unnamed\" and \"Unnamed\"",
     "description": "Outage of default obfs3 bridges \"Unnamed\" and \"Unnamed\" (fingerprint <a href=\"https://metrics.torproject.org/rs.html#details/AF9F66B7B04F8FF6F32D455F05135250A16543C9\">AF9F66B7B04F8FF6F32D455F05135250A16543C9</a>). (Start date not known for sure, though it must have been after 2016-09-23; discussed in non-archived tor-team email.)"
   },
   {
@@ -1834,6 +2585,7 @@
     "protocols": [
       "obfs3"
     ],
+    "shortDescription": "Default obfs3 bridge LeifEricson upgrades and begins reporting statistics to the new bridge authority Bifroest",
     "description": "Default obfs3 bridge LeifEricson upgrades and begins reporting statistics to the new bridge authority Bifroest. This is the last obfs3 bridge that hadn't upgraded."
   },
   {
@@ -1841,6 +2593,7 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Default obfs4 bridge LeifEricson upgrades and begins reporting statistics to the new bridge authority Bifroest",
     "description": "Default obfs4 bridge LeifEricson upgrades and begins reporting statistics to the new bridge authority Bifroest. This is the last obfs4 bridge that hadn't upgraded."
   },
   {
@@ -1848,6 +2601,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Rate limit on the meek-amazon bridge returns to 3.0 MB/s, having been set to about 1.0 MB/s for some time, cause uncertain.",
     "description": "Rate limit on the meek-amazon bridge returns to 3.0 MB/s, having been set to about 1.0 MB/s for some time, cause uncertain."
   },
   {
@@ -1860,9 +2614,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Reports that direct connections from Egypt are blocked; bridges are required",
     "description": "Reports that direct connections from Egypt are blocked; bridges are required. Maybe be the same as the block beginning 2016-10-25.",
     "links": [
-      "<a href=\"https://ooni.torproject.org/post/egypt-network-interference/#attempts-to-block-tor\">OONI report</a>"
+      {
+        "label": "OONI report",
+        "target": "https://ooni.torproject.org/post/egypt-network-interference/#attempts-to-block-tor"
+      }
     ]
   },
   {
@@ -1871,9 +2629,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"October 4 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"October 4 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest C14DF5AE94101562DEACDD296278B0EFA3EA26E5</code>, <code>geoip6-db-digest A88A828020A558D37F97CF683D4521270F0511A2</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=1b4984f196848cd404456fd1251e0352b9abf05e\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=1b4984f196848cd404456fd1251e0352b9abf05e"
+      }
     ]
   },
   {
@@ -1881,9 +2643,13 @@
     "places": [
       "et"
     ],
+    "shortDescription": "Ethiopia declares a state of emergency and implements network blocks.",
     "description": "Ethiopia declares a state of emergency and implements network blocks.",
     "links": [
-      "<a href=\"https://ooni.torproject.org/post/ethiopia-report/#internet-shutdown\">OONI report</a>"
+      {
+        "label": "OONI report",
+        "target": "https://ooni.torproject.org/post/ethiopia-report/#internet-shutdown"
+      }
     ]
   },
   {
@@ -1892,11 +2658,21 @@
     "places": [
       "tr"
     ],
+    "shortDescription": "Turkey blocks storage services including Dropbox, Google Drive, OneDrive, and GitHub",
     "description": "Turkey blocks storage services including Dropbox, Google Drive, OneDrive, and GitHub. Most (all?) of the blocks were rescinded the next day.",
     "links": [
-      "<a href=\"https://turkeyblocks.org/2016/10/08/google-drive-dropbox-blocked-in-turkey/\">blocking article</a>",
-      "<a href=\"https://twitter.com/TurkeyBlocks/status/785054084856512512\">unblocking tweet</a>",
-      "<a href=\"https://www.turkishminute.com/2016/10/09/turkey-lifts-block-dropbox-google-drive-onedrive-remains-blocked/\">unblocking article</a>"
+      {
+        "label": "blocking article",
+        "target": "https://turkeyblocks.org/2016/10/08/google-drive-dropbox-blocked-in-turkey/"
+      },
+      {
+        "label": "unblocking tweet",
+        "target": "https://twitter.com/TurkeyBlocks/status/785054084856512512"
+      },
+      {
+        "label": "unblocking article",
+        "target": "https://www.turkishminute.com/2016/10/09/turkey-lifts-block-dropbox-google-drive-onedrive-remains-blocked/"
+      }
     ]
   },
   {
@@ -1905,12 +2681,25 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Large decrease in meek users, perhaps caused by problems in Orbot 15.0.2 BETA 1 that were fixed in Orbot 15.2.0 RC8.",
     "description": "Large decrease in meek users, perhaps caused by problems in Orbot 15.0.2 BETA 1 that were fixed in Orbot 15.2.0 RC8.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20495\">ticket</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2016-October/000764.html\">initial email</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2016-November/000778.html\">followup email</a>",
-      "<a href=\"https://groups.google.com/d/msg/traffic-obf/CSJLt3t-_OI/FnAqWqquAwAJ\">Orbot mail</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20495"
+      },
+      {
+        "label": "initial email",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2016-October/000764.html"
+      },
+      {
+        "label": "followup email",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2016-November/000778.html"
+      },
+      {
+        "label": "Orbot mail",
+        "target": "https://groups.google.com/d/msg/traffic-obf/CSJLt3t-_OI/FnAqWqquAwAJ"
+      }
     ]
   },
   {
@@ -1923,9 +2712,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Egypt blocks Tor directory authorities and public relays by TCP RST",
     "description": "Egypt blocks Tor directory authorities and public relays by TCP RST. Bridges work.",
     "links": [
-      "<a href=\"https://ooni.torproject.org/post/egypt-network-interference/#attempts-to-block-tor\">OONI report</a>"
+      {
+        "label": "OONI report",
+        "target": "https://ooni.torproject.org/post/egypt-network-interference/#attempts-to-block-tor"
+      }
     ]
   },
   {
@@ -1933,6 +2726,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Decreased the rate limit on the meek-amazon bridge to 1.0 MB/s, from 3.0 MB/s.",
     "description": "Decreased the rate limit on the meek-amazon bridge to 1.0 MB/s, from 3.0 MB/s."
   },
   {
@@ -1940,6 +2734,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Increased the rate limit on the meek-amazon bridge to 3.0 MB/s, from 1.0 MB/s.",
     "description": "Increased the rate limit on the meek-amazon bridge to 3.0 MB/s, from 1.0 MB/s."
   },
   {
@@ -1948,9 +2743,13 @@
     "places": [
       "tr"
     ],
+    "shortDescription": "Turkey blocks Facebook, Twitter, YouTube, WhatsApp.",
     "description": "Turkey blocks Facebook, Twitter, YouTube, WhatsApp.",
     "links": [
-      "<a href=\"https://turkeyblocks.org/2016/11/04/social-media-shutdown-turkey/\">article</a>"
+      {
+        "label": "article",
+        "target": "https://turkeyblocks.org/2016/11/04/social-media-shutdown-turkey/"
+      }
     ]
   },
   {
@@ -1958,11 +2757,21 @@
     "places": [
       "tr"
     ],
+    "shortDescription": "Turkey orders a block on VPN services and Tor.",
     "description": "Turkey orders a block on VPN services and Tor.",
     "links": [
-      "<a href=\"http://turk-internet.com/portal/yazigoster.php?yaziid=54465\">Turkish article</a>",
-      "<a href=\"https://motherboard.vice.com/read/turkey-doubles-down-on-censorship-with-block-on-vpns-tor\">English article</a>",
-      "<a href=\"https://bugs.torproject.org/21014\">ticket</a>"
+      {
+        "label": "Turkish article",
+        "target": "http://turk-internet.com/portal/yazigoster.php?yaziid=54465"
+      },
+      {
+        "label": "English article",
+        "target": "https://motherboard.vice.com/read/turkey-doubles-down-on-censorship-with-block-on-vpns-tor"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/21014"
+      }
     ]
   },
   {
@@ -1971,9 +2780,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"November 3 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"November 3 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 363C038D0BE61D6E0A63C43DE8EA70771ED7BEA5</code>, <code>geoip6-db-digest 6110A2B794AFF0180FD096A4759434CABD289C40</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=ea597832e25e776a45375d18a973e079ca32d424\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=ea597832e25e776a45375d18a973e079ca32d424"
+      }
     ]
   },
   {
@@ -1981,10 +2794,17 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Tor Browser 6.0.6 is released, unbreaking meek on macOS 10.12",
     "description": "Tor Browser 6.0.6 is released, unbreaking meek on macOS 10.12 (Sierra). (See 2016-09-20 breaking event.)",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-browser-606-released\">blog post</a>",
-      "<a href=\"https://bugs.torproject.org/20250#comment:29\">ticket</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/tor-browser-606-released"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20250#comment:29"
+      }
     ]
   },
   {
@@ -1992,10 +2812,17 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Default obfs4 bridges ndnop3 and ndnop5 turn on timing obfuscation",
     "description": "Default obfs4 bridges ndnop3 and ndnop5 turn on timing obfuscation (<code>iat-mode</code>).",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2016-November/000780.html\">mailing list post</a>",
-      "<a href=\"https://bugs.torproject.org/20837\">ticket</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2016-November/000780.html"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20837"
+      }
     ]
   },
   {
@@ -2003,9 +2830,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Default obfs4 bridge Lisbeth turns on timing obfuscation",
     "description": "Default obfs4 bridge <a href=\"https://metrics.torproject.org/rs.html#details/D9C805C955CB124D188C0D44F271E9BE57DE2109\">Lisbeth</a> turns on timing obfuscation (<code>iat-mode=1</code>).",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20837\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20837"
+      }
     ]
   },
   {
@@ -2013,6 +2844,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Decreased the rate limit on the meek-amazon bridge to 2.0 MB/s, from 3.0 MB/s.",
     "description": "Decreased the rate limit on the meek-amazon bridge to 2.0 MB/s, from 3.0 MB/s."
   },
   {
@@ -2021,11 +2853,21 @@
     "places": [
       "gm"
     ],
+    "shortDescription": "Internet shutdown in Gambia.",
     "description": "Internet shutdown in Gambia.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2016-11-14&end=2016-12-14&country=gm\">relay graph</a>",
-      "<a href=\"https://ooni.torproject.org/post/gambia-internet-shutdown/\">OONI report</a>",
-      "<a href=\"https://blog.cloudflare.com/will-autocrats-ever-learn-the-internet-blackout-in-gambia/\">Cloudflare blog post</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2016-11-14&end=2016-12-14&country=gm"
+      },
+      {
+        "label": "OONI report",
+        "target": "https://ooni.torproject.org/post/gambia-internet-shutdown/"
+      },
+      {
+        "label": "Cloudflare blog post",
+        "target": "https://blog.cloudflare.com/will-autocrats-ever-learn-the-internet-blackout-in-gambia/"
+      }
     ]
   },
   {
@@ -2037,11 +2879,21 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Belarus blocks the addresses of public Tor relays, apparently by RST injection",
     "description": "Belarus blocks the addresses of public Tor relays, apparently by RST injection. Bridges work, even unobfuscated ones.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20907\">ticket</a>",
-      "<a href=\"https://geektimes.ru/post/283392/\">article (Russian)</a>",
-      "<a href=\"https://ooni.torproject.org/post/belarus-fries-onion/\">OONI blog post</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20907"
+      },
+      {
+        "label": "article (Russian)",
+        "target": "https://geektimes.ru/post/283392/"
+      },
+      {
+        "label": "OONI blog post",
+        "target": "https://ooni.torproject.org/post/belarus-fries-onion/"
+      }
     ]
   },
   {
@@ -2050,9 +2902,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"December 7 2016 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"December 7 2016 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 1317BB3525E85E01FB34A89E04CE549AC23D07BD</code>, <code>geoip6-db-digest 865048C69BEC02B37268BFBAD66D9729B21CFCF5</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=9db47e792160766de49b76bff71afdc4f743df88\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=9db47e792160766de49b76bff71afdc4f743df88"
+      }
     ]
   },
   {
@@ -2063,11 +2919,21 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Turkey blocks direct Tor connections",
     "description": "Turkey blocks direct Tor connections. The order to block had come on 2016-11-04.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/21014\">ticket</a>",
-      "<a href=\"https://twitter.com/josswright/status/809379534420185089\">tweet</a>",
-      "<a href=\"https://turkeyblocks.org/2016/12/18/tor-blocked-in-turkey-vpn-ban/\">article</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/21014"
+      },
+      {
+        "label": "tweet",
+        "target": "https://twitter.com/josswright/status/809379534420185089"
+      },
+      {
+        "label": "article",
+        "target": "https://turkeyblocks.org/2016/12/18/tor-blocked-in-turkey-vpn-ban/"
+      }
     ]
   },
   {
@@ -2076,11 +2942,21 @@
     "places": [
       "cd"
     ],
+    "shortDescription": "The Democratic Republic of the Congo orders a block of social media services.",
     "description": "The Democratic Republic of the Congo orders a block of social media services.",
     "links": [
-      "<a href=\"http://wlrn.org/post/congo-block-social-media-sites-ahead-protests-against-president\">article</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2016-10-01&end=2016-12-20&country=cd\">relay graph</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-country.html?start=2016-10-01&end=2016-12-20&country=cd\">bridge graph</a>"
+      {
+        "label": "article",
+        "target": "http://wlrn.org/post/congo-block-social-media-sites-ahead-protests-against-president"
+      },
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2016-10-01&end=2016-12-20&country=cd"
+      },
+      {
+        "label": "bridge graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-country.html?start=2016-10-01&end=2016-12-20&country=cd"
+      }
     ]
   },
   {
@@ -2089,9 +2965,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"January 4 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"January 4 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 672C29A4FA9BF81DE97CFE128741445E2BDE8097</code>, <code>geoip6-db-digest 81F380639A8E1000539204949A363FD3BFAFBA74</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=3833f67dd2dc35dbcfe1d5659c885f0b5f54125b\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=3833f67dd2dc35dbcfe1d5659c885f0b5f54125b"
+      }
     ]
   },
   {
@@ -2099,6 +2979,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Decreased the rate limit on the meek-azure bridge to 2.0 MB/s, from 3.0 MB/s.",
     "description": "Decreased the rate limit on the meek-azure bridge to 2.0 MB/s, from 3.0 MB/s."
   },
   {
@@ -2106,9 +2987,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "1.0-beta release of GAEuploader, a tool that automates the setting up of meek.",
     "description": "1.0-beta release of GAEuploader, a tool that automates the setting up of meek.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-January/011812.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-January/011812.html"
+      }
     ]
   },
   {
@@ -2116,9 +3001,13 @@
     "protocols": [
       "snowflake"
     ],
+    "shortDescription": "Tor Browser 7.0a1 released, including Snowflake for GNU/Linux only.",
     "description": "Tor Browser 7.0a1 released, including Snowflake for GNU/Linux only.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-browser-70a1-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/tor-browser-70a1-released"
+      }
     ]
   },
   {
@@ -2128,9 +3017,13 @@
       "<OR>",
       "exit"
     ],
+    "shortDescription": "Measurement error from bandwidth authority causes decrease in measured bandwidth in Europe.",
     "description": "Measurement error from bandwidth authority causes decrease in measured bandwidth in Europe.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-February/000963.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-February/000963.html"
+      }
     ]
   },
   {
@@ -2139,9 +3032,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"February 8 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"February 8 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest C0C6099CE335916862978F77756C0B42521A74B2</code>, <code>geoip6-db-digest A54B14B9D47584E010F763D3EAE23C4726F4A8D5</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=f6016058b42aa1c4528fd8c7c2da3d13eddd63dc\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=f6016058b42aa1c4528fd8c7c2da3d13eddd63dc"
+      }
     ]
   },
   {
@@ -2149,9 +3046,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Stopped the meek-azure CDN endpoint az668014.vo.msecnd.net.",
     "description": "Stopped the meek-azure CDN endpoint az668014.vo.msecnd.net.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-March/000981.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-March/000981.html"
+      }
     ]
   },
   {
@@ -2159,9 +3060,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Stopped the meek-azure CDN endpoint az786092.vo.msecnd.net.",
     "description": "Stopped the meek-azure CDN endpoint az786092.vo.msecnd.net.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-March/000981.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-March/000981.html"
+      }
     ]
   },
   {
@@ -2169,9 +3074,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Stopped the",
     "description": "Stopped the (unused) meek-azure CDN endpoint meek-reflect.azureedge.net.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-March/000981.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-March/000981.html"
+      }
     ]
   },
   {
@@ -2180,11 +3089,21 @@
       "meek",
       "scramblesuit"
     ],
+    "shortDescription": "Tor Browser 6.5.1 is released, containing the new meek-azure CDN configuration, and removing the last remaining scramblesuit bridge.",
     "description": "Tor Browser 6.5.1 is released, containing the new meek-azure CDN configuration, and removing the last remaining scramblesuit bridge.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-browser-651-released\">blog post</a>",
-      "<a href=\"https://bugs.torproject.org/21342\">meek ticket</a>",
-      "<a href=\"https://bugs.torproject.org/21536\">scramblesuit ticket</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/tor-browser-651-released"
+      },
+      {
+        "label": "meek ticket",
+        "target": "https://bugs.torproject.org/21342"
+      },
+      {
+        "label": "scramblesuit ticket",
+        "target": "https://bugs.torproject.org/21536"
+      }
     ]
   },
   {
@@ -2193,9 +3112,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"March 7 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"March 7 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 63921843E3AAA632088D189D877F836A373CD40D</code>, <code>geoip6-db-digest 2B93B9C6679BB09E1746F212A6DCDC6E710F5F52</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=4488c319dde4c986da01a4635edaabeb1bc574a4\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=4488c319dde4c986da01a4635edaabeb1bc574a4"
+      }
     ]
   },
   {
@@ -2203,10 +3126,17 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Orbot 15.4.0 beta-2 multi is released, containing the new meek-azure CDN configuration.",
     "description": "Orbot 15.4.0 beta-2 multi is released, containing the new meek-azure CDN configuration.",
     "links": [
-      "<a href=\"https://lists.mayfirst.org/pipermail/guardian-dev/2017-March/005220.html\">mailing list post</a>",
-      "<a href=\"https://github.com/n8fr8/orbot/commit/6496cb11d61e0e42c48569c9eae303e0cd625e85\">commit</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.mayfirst.org/pipermail/guardian-dev/2017-March/005220.html"
+      },
+      {
+        "label": "commit",
+        "target": "https://github.com/n8fr8/orbot/commit/6496cb11d61e0e42c48569c9eae303e0cd625e85"
+      }
     ]
   },
   {
@@ -2215,9 +3145,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"April 4 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"April 4 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 0F3D4A456E5078CC9E49398ADCB04C40EA49B793</code>, <code>geoip6-db-digest 04F41F05FA167EF6EEE3FE953404AB0BCCD33008</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=9d7933296c187061ce121012cdd7964321e06db2\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=9d7933296c187061ce121012cdd7964321e06db2"
+      }
     ]
   },
   {
@@ -2226,12 +3160,25 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Directory authority maatuska's bwscanner stops operating, leading to a drop in traffic on some relays.",
     "description": "Directory authority maatuska's bwscanner stops operating, leading to a drop in traffic on some relays.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-consensus-health/2017-April/007845.html\">tor-consensus-health post about start</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-consensus-health/2017-August/008106.html\">tor-consensus-health post about end</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-April/012215.html\">tor-dev thread</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-consensus-health/2017-May/007908.html\">analysis</a>"
+      {
+        "label": "tor-consensus-health post about start",
+        "target": "https://lists.torproject.org/pipermail/tor-consensus-health/2017-April/007845.html"
+      },
+      {
+        "label": "tor-consensus-health post about end",
+        "target": "https://lists.torproject.org/pipermail/tor-consensus-health/2017-August/008106.html"
+      },
+      {
+        "label": "tor-dev thread",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-April/012215.html"
+      },
+      {
+        "label": "analysis",
+        "target": "https://lists.torproject.org/pipermail/tor-consensus-health/2017-May/007908.html"
+      }
     ]
   },
   {
@@ -2239,6 +3186,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "The meek-amazon bridge upgrades to meek-server 0.27.",
     "description": "The meek-amazon bridge upgrades to meek-server 0.27."
   },
   {
@@ -2246,9 +3194,13 @@
     "protocols": [
       "snowflake"
     ],
+    "shortDescription": "Set AssumeReachable 1 on the Snowflake bridge 2B280B23E1107BB62ABFC40DDCC8824814F80A72 in an attempt to make it start publishing statistics.",
     "description": "Set <code>AssumeReachable 1</code> on the Snowflake bridge <a href=\"https://metrics.torproject.org/rs.html#details/2B280B23E1107BB62ABFC40DDCC8824814F80A72\">2B280B23E1107BB62ABFC40DDCC8824814F80A72</a> in an attempt to make it start publishing statistics.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-May/012243.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-May/012243.html"
+      }
     ]
   },
   {
@@ -2257,9 +3209,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"May 2 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"May 2 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest B2E5105287668771E34A66F90B34982D419727EF</code>, <code>geoip6-db-digest 8DA8AC3C8158CBFDF7DB53BBF73338246872371A</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=5207e41ffeb99089adbb56376c0759b97a556801\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=5207e41ffeb99089adbb56376c0759b97a556801"
+      }
     ]
   },
   {
@@ -2267,14 +3223,33 @@
     "places": [
       "ua"
     ],
+    "shortDescription": "Ukraine blocks Russian-operated web services",
     "description": "Ukraine blocks Russian-operated web services. Relay and bridge users increase over 5×. May be partly attributable to the <a href=\"https://freeu.online/\">FreeU Browser</a> , a browser produced and advertised by Mail.ru that includes a tor client.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/22369\">ticket</a>",
-      "<a href=\"https://www.rt.com/business/388502-ukraine-bans-vk-yandex/\">news article</a>",
-      "<a href=\"https://www.reddit.com/r/TOR/comments/6c9ig1\">reddit post</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-05-01&end=2017-05-21&country=ua&events=on\">relay graph</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-country.html?start=2017-05-01&end=2017-05-21&country=ua\">bridge graph</a>",
-      "<a href=\"https://tjournal.ru/44669-vkontakte-predlozhila-ukraincam-peredelannii-brauzer-amigo-s-tor-dlya-obhoda-blokirovok\">news article on FreeU</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/22369"
+      },
+      {
+        "label": "news article",
+        "target": "https://www.rt.com/business/388502-ukraine-bans-vk-yandex/"
+      },
+      {
+        "label": "reddit post",
+        "target": "https://www.reddit.com/r/TOR/comments/6c9ig1"
+      },
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-05-01&end=2017-05-21&country=ua&events=on"
+      },
+      {
+        "label": "bridge graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-country.html?start=2017-05-01&end=2017-05-21&country=ua"
+      },
+      {
+        "label": "news article on FreeU",
+        "target": "https://tjournal.ru/44669-vkontakte-predlozhila-ukraincam-peredelannii-brauzer-amigo-s-tor-dlya-obhoda-blokirovok"
+      }
     ]
   },
   {
@@ -2283,6 +3258,7 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Default obfs4 bridge LeifEricson rejects connections due to a broken firewall forwarding rule",
     "description": "Default obfs4 bridge LeifEricson rejects connections due to a broken firewall forwarding rule. This didn't affect the bridges \"real\" obfs4 port, but it did affect the port at that time configured in Tor Browser."
   },
   {
@@ -2290,9 +3266,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Set AssumeReachable 1 on the default obfs4 bridges cymrubridge31 and cymrubridge33 in an attempt to make them publish statistics.",
     "description": "Set <code>AssumeReachable 1</code> on the default obfs4 bridges <a href=\"https://metrics.torproject.org/rs.html#details/C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4\">cymrubridge31</a> and <a href=\"https://metrics.torproject.org/rs.html#details/0BAC39417268B96B9F514E7F63FA6FBA1A788955\">cymrubridge33</a> in an attempt to make them publish statistics.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-May/012283.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-May/012283.html"
+      }
     ]
   },
   {
@@ -2301,11 +3281,21 @@
       "ipv6",
       "obfs4"
     ],
+    "shortDescription": "Tor Browser 7.0 released",
     "description": "Tor Browser 7.0 released. Adds an IPv6 address for default obfs4 bridge Lisbeth. Adds new default obfs4 bridges <a href=\"https://metrics.torproject.org/rs.html#details/854173307E33686BBBAC36A3A093BEF320B719D4\">frosty</a> and <a href=\"https://metrics.torproject.org/rs.html#details/D9E712E593400635462172121B7DB90B07669F71\">dragon</a>.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-browser-70-released\">blog post</a>",
-      "<a href=\"https://bugs.torproject.org/22429\">IPv6 ticket</a>",
-      "<a href=\"https://bugs.torproject.org/22468\">frosty and dragon ticket</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/tor-browser-70-released"
+      },
+      {
+        "label": "IPv6 ticket",
+        "target": "https://bugs.torproject.org/22429"
+      },
+      {
+        "label": "frosty and dragon ticket",
+        "target": "https://bugs.torproject.org/22468"
+      }
     ]
   },
   {
@@ -2314,9 +3304,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"June 8 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"June 8 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest AFD609025B66305AD9FA8E0B15AF4F2BC82271F1</code>, <code>geoip6-db-digest A69FD14ACE46EE695F589ACE0EB7B915285B51B4</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=104e8fa751c1bef051ac47e39da9bbbc6d158800\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=104e8fa751c1bef051ac47e39da9bbbc6d158800"
+      }
     ]
   },
   {
@@ -2324,9 +3318,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Increased the file descriptor limit on default obfs4 bridges ndnop3 and ndnop5 from 4096 to 32768",
     "description": "Increased the file descriptor limit on default obfs4 bridges ndnop3 and ndnop5 from 4096 to 32768. They had been failing bootstrap attempts from a test location in the U.S. about 40% of the time.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20348#comment:193\">graph showing failed connections</a>"
+      {
+        "label": "graph showing failed connections",
+        "target": "https://bugs.torproject.org/20348#comment:193"
+      }
     ]
   },
   {
@@ -2335,9 +3333,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Outage of default obfs4 bridge frosty.",
     "description": "Outage of default obfs4 bridge <a href=\"https://metrics.torproject.org/rs.html#details/854173307E33686BBBAC36A3A093BEF320B719D4\">frosty</a>.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-June/001211.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-June/001211.html"
+      }
     ]
   },
   {
@@ -2346,9 +3348,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Outage of default obfs4 bridge dragon.",
     "description": "Outage of default obfs4 bridge <a href=\"https://metrics.torproject.org/rs.html#details/D9E712E593400635462172121B7DB90B07669F71\">dragon</a>.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-June/001211.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-June/001211.html"
+      }
     ]
   },
   {
@@ -2357,10 +3363,17 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Outage of meek-azure bridge.",
     "description": "Outage of meek-azure bridge.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-June/001209.html\">start</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-June/001209.html\">end</a>"
+      {
+        "label": "start",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-June/001209.html"
+      },
+      {
+        "label": "end",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-June/001209.html"
+      }
     ]
   },
   {
@@ -2369,9 +3382,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Outage of default obfs4 bridge frosty.",
     "description": "Outage of default obfs4 bridge <a href=\"https://metrics.torproject.org/rs.html#details/854173307E33686BBBAC36A3A093BEF320B719D4\">frosty</a>.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-July/001280.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-July/001280.html"
+      }
     ]
   },
   {
@@ -2380,17 +3397,28 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Outage of default obfs4 bridge dragon.",
     "description": "Outage of default obfs4 bridge <a href=\"https://metrics.torproject.org/rs.html#details/D9E712E593400635462172121B7DB90B07669F71\">dragon</a>.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-July/001280.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-July/001280.html"
+      }
     ]
   },
   {
     "start": "2017-07-02",
+    "shortDescription": "deb.torproject.org upgrades from tor 0.2.9 to tor 0.3.0",
     "description": "deb.torproject.org upgrades from tor 0.2.9 to tor 0.3.0",
     "links": [
-      "<a href=\"https://metrics.torproject.org/versions.html?start=2017-05-01&end=2017-07-15\">relay versions graph</a>",
-      "<a href=\"https://twitter.com/nusenu_/status/884128686764687361\">tweet</a>"
+      {
+        "label": "relay versions graph",
+        "target": "https://metrics.torproject.org/versions.html?start=2017-05-01&end=2017-07-15"
+      },
+      {
+        "label": "tweet",
+        "target": "https://twitter.com/nusenu_/status/884128686764687361"
+      }
     ]
   },
   {
@@ -2399,9 +3427,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Outage of default obfs4 bridge dragon.",
     "description": "Outage of default obfs4 bridge <a href=\"https://metrics.torproject.org/rs.html#details/D9E712E593400635462172121B7DB90B07669F71\">dragon</a>.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-July/001280.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-July/001280.html"
+      }
     ]
   },
   {
@@ -2410,9 +3442,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Outage of default obfs4 bridge frosty.",
     "description": "Outage of default obfs4 bridge <a href=\"https://metrics.torproject.org/rs.html#details/854173307E33686BBBAC36A3A093BEF320B719D4\">frosty</a>.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-July/001280.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-July/001280.html"
+      }
     ]
   },
   {
@@ -2421,9 +3457,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"July 4 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"July 4 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 3D04F191098640F2E03B4D5F7800088D14B7EC30</code>, <code>geoip6-db-digest A3649B9E909C59942FB3D8F874AB4BEA36E8BEC1</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=b6acfa491e7fdb6e3d71665a55617727816155fd\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=b6acfa491e7fdb6e3d71665a55617727816155fd"
+      }
     ]
   },
   {
@@ -2432,11 +3472,21 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Outage of meek-amazon bridge, caused by an expired certificate.",
     "description": "Outage of meek-amazon bridge, caused by an expired certificate.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/rs.html#details/F4AD82B2032EDEF6C02C5A529C42CFAFE516564D\">Atlas</a>",
-      "<a href=\"https://crt.sh/?id=130970041\">expired certificate</a>",
-      "<a href=\"https://crt.sh/?id=192217077\">new certificate</a>"
+      {
+        "label": "Atlas",
+        "target": "https://metrics.torproject.org/rs.html#details/F4AD82B2032EDEF6C02C5A529C42CFAFE516564D"
+      },
+      {
+        "label": "expired certificate",
+        "target": "https://crt.sh/?id=130970041"
+      },
+      {
+        "label": "new certificate",
+        "target": "https://crt.sh/?id=192217077"
+      }
     ]
   },
   {
@@ -2445,9 +3495,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"August 3 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"August 3 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 75AABD32582AC554AF252DDC7BBBABE7C6F28B28</code>, <code>geoip6-db-digest A52EFFEF8CF6F3CAA8EBD34961361544E959FAE1</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=1280de42a41ccf7ae398cc86529c880455e9c5d1\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=1280de42a41ccf7ae398cc86529c880455e9c5d1"
+      }
     ]
   },
   {
@@ -2456,11 +3510,21 @@
     "places": [
       "cd"
     ],
+    "shortDescription": "The Democratic Republic of the Congo orders a block of social media services.",
     "description": "The Democratic Republic of the Congo orders a block of social media services.",
     "links": [
-      "<a href=\"https://www.amnesty.org/en/latest/news/2017/08/drc-block-on-social-media-images-an-appalling-attack-on-freedom-of-expression/\">article</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2017-10-01&country=cd\">relay graph</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-country.html?start=2017-06-01&end=2017-10-01&country=cd\">bridge graph</a>"
+      {
+        "label": "article",
+        "target": "https://www.amnesty.org/en/latest/news/2017/08/drc-block-on-social-media-images-an-appalling-attack-on-freedom-of-expression/"
+      },
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2017-10-01&country=cd"
+      },
+      {
+        "label": "bridge graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-country.html?start=2017-06-01&end=2017-10-01&country=cd"
+      }
     ]
   },
   {
@@ -2468,19 +3532,33 @@
     "protocols": [
       "snowflake"
     ],
+    "shortDescription": "Tor Browser 7.5a4 released, including Snowflake for macOS.",
     "description": "Tor Browser 7.5a4 released, including Snowflake for macOS.",
     "links": [
-      "<a href=\"https://blog.torproject.org/blog/tor-browser-75a4-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/blog/tor-browser-75a4-released"
+      }
     ]
   },
   {
     "start": "2017-08-10",
     "end": "2017-08-11",
+    "shortDescription": "Outage of the op-hk OnionPerf instance",
     "description": "Outage of the op-hk OnionPerf instance. Reported timeouts on the tor network increased, download speed improved.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/torperf.html?start=2017-07-01&end=2017-10-09&source=all&server=public&filesize=50kb\">torperf graph</a>",
-      "<a href=\"https://metrics.torproject.org/torperf-failures.html?start=2017-07-11&end=2017-10-09&source=all&server=public&filesize=50kb\">torperf-failures graph</a>",
-      "<a href=\"https://metrics.torproject.org/torperf.html?start=2017-07-01&end=2017-10-09&source=op-hk&server=public&filesize=50kb\">op-hk graph</a>"
+      {
+        "label": "torperf graph",
+        "target": "https://metrics.torproject.org/torperf.html?start=2017-07-01&end=2017-10-09&source=all&server=public&filesize=50kb"
+      },
+      {
+        "label": "torperf-failures graph",
+        "target": "https://metrics.torproject.org/torperf-failures.html?start=2017-07-11&end=2017-10-09&source=all&server=public&filesize=50kb"
+      },
+      {
+        "label": "op-hk graph",
+        "target": "https://metrics.torproject.org/torperf.html?start=2017-07-01&end=2017-10-09&source=op-hk&server=public&filesize=50kb"
+      }
     ]
   },
   {
@@ -2489,11 +3567,21 @@
     "protocols": [
       "bridge"
     ],
+    "shortDescription": "Outage of the bridge authority Bifroest.",
     "description": "Outage of the bridge authority <a href=\"https://metrics.torproject.org/rs.html#details/1D8F3A91C37C5D1C4C19B1AD1D0CFBE8BF72D8E1\">Bifroest</a>.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-August/000441.html\">mailing list post</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2018-March/000713.html\">mailing list post</a>",
-      "<a href=\"https://metrics.torproject.org/networksize.html?start=2017-07-01&end=2017-08-27\">graph</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-August/000441.html"
+      },
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2018-March/000713.html"
+      },
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/networksize.html?start=2017-07-01&end=2017-08-27"
+      }
     ]
   },
   {
@@ -2502,12 +3590,25 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "A flood of over 4,000 obfs4 bridges nicknamed \"Machiavelli\".",
     "description": "A flood of over 4,000 obfs4 bridges nicknamed \"Machiavelli\".",
     "links": [
-      "<a href=\"https://metrics.torproject.org/networksize.html?start=2017-08-01&end=2017-09-30\">graph of number of bridges</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-relays/2017-September/012925.html\">tor-relays post</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-September/000450.html\">metrics-team thread</a>",
-      "<a href=\"https://twitter.com/nusenu_/status/905580044503969792\">tweet</a>"
+      {
+        "label": "graph of number of bridges",
+        "target": "https://metrics.torproject.org/networksize.html?start=2017-08-01&end=2017-09-30"
+      },
+      {
+        "label": "tor-relays post",
+        "target": "https://lists.torproject.org/pipermail/tor-relays/2017-September/012925.html"
+      },
+      {
+        "label": "metrics-team thread",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-September/000450.html"
+      },
+      {
+        "label": "tweet",
+        "target": "https://twitter.com/nusenu_/status/905580044503969792"
+      }
     ]
   },
   {
@@ -2515,10 +3616,17 @@
     "places": [
       "pr"
     ],
+    "shortDescription": "Hurricane Irma hits Puerto Rico.",
     "description": "Hurricane Irma hits Puerto Rico.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-01&end=2017-11-09&country=pr&events=off\">graph</a>",
-      "<a href=\"https://en.wikipedia.org/wiki/Hurricane_Irma#Puerto_Rico_2\">wikipedia</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-01&end=2017-11-09&country=pr&events=off"
+      },
+      {
+        "label": "wikipedia",
+        "target": "https://en.wikipedia.org/wiki/Hurricane_Irma#Puerto_Rico_2"
+      }
     ]
   },
   {
@@ -2527,9 +3635,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"September 6 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"September 6 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 0CE9EA8882EDED265451C36B49AE7BBB06A11C16</code>, <code>geoip6-db-digest C4573496EBD1CC335843067107DA49E482568FF6</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=09618ffe38bc6cd91755c6c1aedb86dc099dfdf8\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=09618ffe38bc6cd91755c6c1aedb86dc099dfdf8"
+      }
     ]
   },
   {
@@ -2538,6 +3650,7 @@
     "protocols": [
       "bridge"
     ],
+    "shortDescription": "Outage of the bridge authority Bifroest.",
     "description": "Outage of the bridge authority <a href=\"https://metrics.torproject.org/rs.html#details/1D8F3A91C37C5D1C4C19B1AD1D0CFBE8BF72D8E1\">Bifroest</a>."
   },
   {
@@ -2546,21 +3659,41 @@
     "protocols": [
       "bridge"
     ],
+    "shortDescription": "The bridge authority was down due to an issue with its offline master key.",
     "description": "The bridge authority was down due to an issue with its offline master key.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/networksize.html?start=2017-07-01&end=2018-01-01\">graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2018-March/000713.html\">mailing list post</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/networksize.html?start=2017-07-01&end=2018-01-01"
+      },
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2018-March/000713.html"
+      }
     ]
   },
   {
     "start": "2017-09-15",
     "end": "2017-10-12",
+    "shortDescription": "Outage of the op-hk OnionPerf instance",
     "description": "Outage of the op-hk OnionPerf instance. Reported timeouts on the tor network increased, download speed improved.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-October/000476.html\">mailing list post</a>",
-      "<a href=\"https://metrics.torproject.org/torperf.html?start=2017-07-01&end=2017-10-09&source=all&server=public&filesize=50kb\">torperf graph</a>",
-      "<a href=\"https://metrics.torproject.org/torperf-failures.html?start=2017-07-11&end=2017-10-09&source=all&server=public&filesize=50kb\">torperf-failures graph</a>",
-      "<a href=\"https://metrics.torproject.org/torperf.html?start=2017-07-01&end=2017-10-09&source=op-hk&server=public&filesize=50kb\">op-hk graph</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-October/000476.html"
+      },
+      {
+        "label": "torperf graph",
+        "target": "https://metrics.torproject.org/torperf.html?start=2017-07-01&end=2017-10-09&source=all&server=public&filesize=50kb"
+      },
+      {
+        "label": "torperf-failures graph",
+        "target": "https://metrics.torproject.org/torperf-failures.html?start=2017-07-11&end=2017-10-09&source=all&server=public&filesize=50kb"
+      },
+      {
+        "label": "op-hk graph",
+        "target": "https://metrics.torproject.org/torperf.html?start=2017-07-01&end=2017-10-09&source=op-hk&server=public&filesize=50kb"
+      }
     ]
   },
   {
@@ -2568,10 +3701,17 @@
     "places": [
       "pr"
     ],
+    "shortDescription": "Hurricane Maria hits Puerto Rico.",
     "description": "Hurricane Maria hits Puerto Rico.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-01&end=2017-11-09&country=pr&events=off\">graph</a>",
-      "<a href=\"https://en.wikipedia.org/wiki/Hurricane_Maria#Puerto_Rico_3\">wikipedia</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-01&end=2017-11-09&country=pr&events=off"
+      },
+      {
+        "label": "wikipedia",
+        "target": "https://en.wikipedia.org/wiki/Hurricane_Maria#Puerto_Rico_3"
+      }
     ]
   },
   {
@@ -2580,9 +3720,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"October 4 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"October 4 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 3A59213E5CFEE380F544B72DC1105366C6BD1CDE</code>, <code>geoip6-db-digest 1B8C975E5C62CF0FB5B4E598AE27B7189952BB09</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=b9d9b16b7685c79e6440e5f8a1d4bd01a8cefb2c\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=b9d9b16b7685c79e6440e5f8a1d4bd01a8cefb2c"
+      }
     ]
   },
   {
@@ -2591,12 +3735,25 @@
     "places": [
       "cn"
     ],
+    "shortDescription": "Guo Wengui speaks at the National Press Club, 09:00–11:00 eastern time",
     "description": "Guo Wengui speaks at the National Press Club, 09:00–11:00 eastern time. Reports of disruption of VPNs, Tor, Psiphon, Lantern, Shadowsocks in China.",
     "links": [
-      "<a href=\"https://www.msn.com/en-sg/money/markets/exiled-chinese-billionaire-blasts-kleptocracy-running-china-warns-of-spy-infiltration-in-us/ar-AAsXLvL\">article on conference</a>",
-      "<a href=\"https://twitter.com/szshu/status/916289656169275392\">tweet</a>",
-      "<a href=\"https://twitter.com/paulwang_xz/status/916633633548525568\">tweet</a>",
-      "<a href=\"https://twitter.com/iuui/status/916583990085033985\">tweet</a>"
+      {
+        "label": "article on conference",
+        "target": "https://www.msn.com/en-sg/money/markets/exiled-chinese-billionaire-blasts-kleptocracy-running-china-warns-of-spy-infiltration-in-us/ar-AAsXLvL"
+      },
+      {
+        "label": "tweet",
+        "target": "https://twitter.com/szshu/status/916289656169275392"
+      },
+      {
+        "label": "tweet",
+        "target": "https://twitter.com/paulwang_xz/status/916633633548525568"
+      },
+      {
+        "label": "tweet",
+        "target": "https://twitter.com/iuui/status/916583990085033985"
+      }
     ]
   },
   {
@@ -2604,9 +3761,13 @@
     "protocols": [
       "snowflake"
     ],
+    "shortDescription": "Activated client IP address statistics on the Snowflake server and standalone proxies.",
     "description": "Activated client IP address statistics on the Snowflake server and standalone proxies.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/18628#comment:16\">comment</a>"
+      {
+        "label": "comment",
+        "target": "https://bugs.torproject.org/18628#comment:16"
+      }
     ]
   },
   {
@@ -2615,9 +3776,13 @@
     "places": [
       "cn"
     ],
+    "shortDescription": "19th National Congress of the Communist Party of China.",
     "description": "19th National Congress of the Communist Party of China.",
     "links": [
-      "<a href=\"https://en.wikipedia.org/wiki/19th_National_Congress_of_the_Communist_Party_of_China\">wikipedia</a>"
+      {
+        "label": "wikipedia",
+        "target": "https://en.wikipedia.org/wiki/19th_National_Congress_of_the_Communist_Party_of_China"
+      }
     ]
   },
   {
@@ -2626,12 +3791,25 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Release of tor 0.2.5.15, 0.2.8.16, 0.2.9.13, 0.3.0.12, and 0.3.1.8, which add a new directory authority bastet, and change the IP address of the directory authority Longclaw.",
     "description": "Release of tor 0.2.5.15, 0.2.8.16, 0.2.9.13, 0.3.0.12, and 0.3.1.8, which add a new directory authority bastet, and change the IP address of the directory authority Longclaw.",
     "links": [
-      "<a href=\"https://blog.torproject.org/new-stable-tor-releases-0318-03012-02913-02816-02515\">blog post</a>",
-      "<a href=\"https://blog.torproject.org/introducing-bastet-our-new-directory-authority\">Bastet blog post</a>",
-      "<a href=\"https://bugs.torproject.org/23910\">bastet ticket</a>",
-      "<a href=\"https://bugs.torproject.org/23592\">Longclaw ticket</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/new-stable-tor-releases-0318-03012-02913-02816-02515"
+      },
+      {
+        "label": "Bastet blog post",
+        "target": "https://blog.torproject.org/introducing-bastet-our-new-directory-authority"
+      },
+      {
+        "label": "bastet ticket",
+        "target": "https://bugs.torproject.org/23910"
+      },
+      {
+        "label": "Longclaw ticket",
+        "target": "https://bugs.torproject.org/23592"
+      }
     ]
   },
   {
@@ -2639,10 +3817,17 @@
     "places": [
       "ru"
     ],
+    "shortDescription": "Ban on VPNs and anonymizers takes effect in Russia.",
     "description": "Ban on VPNs and anonymizers takes effect in Russia.",
     "links": [
-      "<a href=\"https://www.reuters.com/article/us-russia-internet/putin-bans-vpns-to-stop-russians-accessing-prohibited-websites-idUSKBN1AF0QI\">news article</a>",
-      "<a href=\"http://publication.pravo.gov.ru/Document/View/0001201707300002\">law</a>"
+      {
+        "label": "news article",
+        "target": "https://www.reuters.com/article/us-russia-internet/putin-bans-vpns-to-stop-russians-accessing-prohibited-websites-idUSKBN1AF0QI"
+      },
+      {
+        "label": "law",
+        "target": "http://publication.pravo.gov.ru/Document/View/0001201707300002"
+      }
     ]
   },
   {
@@ -2650,9 +3835,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Turned off the old meek-amazon CDN endpoint d2zfqthxsdq309.cloudfront.net.",
     "description": "Turned off the old meek-amazon CDN endpoint d2zfqthxsdq309.cloudfront.net.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-November/001555.html\">mailing list post</a>"
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-November/001555.html"
+      }
     ]
   },
   {
@@ -2661,17 +3850,25 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"November 6 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"November 6 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest E3C910F3B2A6C916C7BE33A943091EF57048B72C</code>, <code>geoip6-db-digest E8BD5B2E6554C27F718F1222667C09680D75F799</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=6f8c32b7deb9f0cec6d1553aba71969c9fb6064f\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=6f8c32b7deb9f0cec6d1553aba71969c9fb6064f"
+      }
     ]
   },
   {
     "start": "2017-11-11",
     "end": "2017-11-12",
+    "shortDescription": "Outage of the op-hk OnionPerf instance.",
     "description": "Outage of the op-hk OnionPerf instance.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/torperf.html?start=2017-10-01&end=2017-12-01&source=op-hk&server=public&filesize=50kb\">op-hk graph</a>"
+      {
+        "label": "op-hk graph",
+        "target": "https://metrics.torproject.org/torperf.html?start=2017-10-01&end=2017-12-01&source=op-hk&server=public&filesize=50kb"
+      }
     ]
   },
   {
@@ -2680,9 +3877,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Release of Tor Browser 7.0.10, containing tor 0.3.1.8, which adds a new directory authority bastet, and changes the IP address of the directory authority Longclaw.",
     "description": "Release of Tor Browser 7.0.10, containing tor 0.3.1.8, which adds a new directory authority bastet, and changes the IP address of the directory authority Longclaw.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-7010-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-7010-released"
+      }
     ]
   },
   {
@@ -2691,9 +3892,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Outage of meek-amazon bridge.",
     "description": "Outage of meek-amazon bridge.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/24284\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/24284"
+      }
     ]
   },
   {
@@ -2702,9 +3907,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Release of Tor Browser 7.5a8, containing tor 0.3.2.4-alpha, which adds a new directory authority bastet, and changes the IP address of the directory authority Longclaw.",
     "description": "Release of Tor Browser 7.5a8, containing tor 0.3.2.4-alpha, which adds a new directory authority bastet, and changes the IP address of the directory authority Longclaw.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-75a8-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-75a8-released"
+      }
     ]
   },
   {
@@ -2713,11 +3922,21 @@
     "places": [
       "pk"
     ],
+    "shortDescription": "Social media block in Pakistan.",
     "description": "Social media block in Pakistan.",
     "links": [
-      "<a href=\"https://dailytimes.com.pk/147132/social-media-goes-down-in-pakistan/\">article</a>",
-      "<a href=\"https://digitalrightsfoundation.pk/press-release-drf-and-netblocks-find-blanket-and-nation-wide-ban-on-social-media-in-pakistan-and-demand-it-to-be-lifted-immediately/\">NetBlocks data</a>",
-      "<a href=\"https://ooni.torproject.org/post/how-pakistan-blocked-social-media/\">OONI/Bytes For All report</a>"
+      {
+        "label": "article",
+        "target": "https://dailytimes.com.pk/147132/social-media-goes-down-in-pakistan/"
+      },
+      {
+        "label": "NetBlocks data",
+        "target": "https://digitalrightsfoundation.pk/press-release-drf-and-netblocks-find-blanket-and-nation-wide-ban-on-social-media-in-pakistan-and-demand-it-to-be-lifted-immediately/"
+      },
+      {
+        "label": "OONI/Bytes For All report",
+        "target": "https://ooni.torproject.org/post/how-pakistan-blocked-social-media/"
+      }
     ]
   },
   {
@@ -2727,21 +3946,41 @@
       "ipv6",
       "relay"
     ],
+    "shortDescription": "Release of tor 0.2.8.17, 0.2.9.14, 0.3.0.13, 0.3.1.9, and 0.3.2.6-alpha, which add an IPv6 address for the bridge authority bastet.",
     "description": "Release of tor 0.2.8.17, 0.2.9.14, 0.3.0.13, 0.3.1.9, and 0.3.2.6-alpha, which add an IPv6 address for the bridge authority bastet.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/24394\">ticket</a>",
-      "<a href=\"https://blog.torproject.org/new-stable-tor-releases-security-fixes-0319-03013-02914-02817-02516\">blog post</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/24394"
+      },
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/new-stable-tor-releases-security-fixes-0319-03013-02914-02817-02516"
+      }
     ]
   },
   {
     "start": "2017-12-04",
     "ongoing": true,
+    "shortDescription": "DDoS attack creates load on the network.",
     "description": "DDoS attack creates load on the network.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-relays/2017-December/013669.html\">tor-relays thread</a>",
-      "<a href=\"https://metrics.torproject.org/relayflags.html?start=2017-11-01&end=2018-01-31&flag=Running&flag=Exit&flag=Fast&flag=Guard&flag=Stable&flag=HSDir\">relay graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-project/2017-December/001604.html\">summary post</a>",
-      "<a href=\"https://bugs.torproject.org/24902\">ticket</a>"
+      {
+        "label": "tor-relays thread",
+        "target": "https://lists.torproject.org/pipermail/tor-relays/2017-December/013669.html"
+      },
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/relayflags.html?start=2017-11-01&end=2018-01-31&flag=Running&flag=Exit&flag=Fast&flag=Guard&flag=Stable&flag=HSDir"
+      },
+      {
+        "label": "summary post",
+        "target": "https://lists.torproject.org/pipermail/tor-project/2017-December/001604.html"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/24902"
+      }
     ]
   },
   {
@@ -2750,9 +3989,13 @@
     "places": [
       "zw"
     ],
+    "shortDescription": "Internet outage in Zimbabwe.",
     "description": "Internet outage in Zimbabwe.",
     "links": [
-      "<a href=\"https://www.techzim.co.zw/2017/12/zimbabwe-internet-outage-here-what-happened/\">article</a>"
+      {
+        "label": "article",
+        "target": "https://www.techzim.co.zw/2017/12/zimbabwe-internet-outage-here-what-happened/"
+      }
     ]
   },
   {
@@ -2761,10 +4004,17 @@
     "protocols": [
       "bridge"
     ],
+    "shortDescription": "The bridge authority was down for unknown reasons.",
     "description": "The bridge authority was down for unknown reasons.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/networksize.html?start=2017-07-01&end=2018-01-01\">graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2018-March/000713.html\">mailing list post</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/networksize.html?start=2017-07-01&end=2018-01-01"
+      },
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2018-March/000713.html"
+      }
     ]
   },
   {
@@ -2774,9 +4024,13 @@
       "ipv6",
       "relay"
     ],
+    "shortDescription": "Release of Tor Browser 7.0.11, containing tor 0.3.1.9, which adds an IPv6 address for the bridge authority bastet.",
     "description": "Release of Tor Browser 7.0.11, containing tor 0.3.1.9, which adds an IPv6 address for the bridge authority bastet.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-7011-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-7011-released"
+      }
     ]
   },
   {
@@ -2786,9 +4040,13 @@
       "ipv6",
       "relay"
     ],
+    "shortDescription": "Release of Tor Browser 7.5a9, containing tor 0.3.2.6-alpha, which adds an IPv6 address for the bridge authority bastet.",
     "description": "Release of Tor Browser 7.5a9, containing tor 0.3.2.6-alpha, which adds an IPv6 address for the bridge authority bastet.",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-browser-75a9-released\">blog post</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/tor-browser-75a9-released"
+      }
     ]
   },
   {
@@ -2797,6 +4055,7 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Outage of the meek.bamsoftware.com",
     "description": "Outage of the <a href=\"https://metrics.torproject.org/rs.html#details/C20658946DD706A7A2181159A1A04CD838570D04\">meek.bamsoftware.com</a> (unthrottled for public use), <a href=\"https://metrics.torproject.org/rs.html#details/AA033EEB61601B2B7312D89B62AAA23DC3ED8A34\">meek.bamsoftware.com:7443</a> (former meek-azure, now unused), and <a href=\"https://metrics.torproject.org/rs.html#details/D36B0328969EC57AB3085A4470882D99A09C0492\">gaeuploader.meek.bamsoftware.com</a> (used by <a href=\"https://github.com/katherinelitor/GAEuploader\">GAEuploader</a>) bridges."
   },
   {
@@ -2805,17 +4064,28 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"December 6 2017 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"December 6 2017 Maxmind GeoLite2 Country\" (<code>geoip-db-digest 1D486694A710145631B295CC39ECC5682F75858C</code>, <code>geoip6-db-digest F33231CAC761A71F7C19273DB1E11CEE01E2D982</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=428f8a375b8846edd1a056ce66f00fe08117a4ba\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=428f8a375b8846edd1a056ce66f00fe08117a4ba"
+      }
     ]
   },
   {
     "start": "2017-12-21",
+    "shortDescription": "Release of tor 0.3.2.8-rc, intended to fix the KIST bug that enabled a DoS on relays by running them out of memory.",
     "description": "Release of tor 0.3.2.8-rc, intended to fix the KIST bug that enabled a DoS on relays by running them out of memory.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2017-December/043844.html\">announcement</a>",
-      "<a href=\"https://bugs.torproject.org/24665\">ticket</a>"
+      {
+        "label": "announcement",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2017-December/043844.html"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/24665"
+      }
     ]
   },
   {
@@ -2824,12 +4094,25 @@
     "places": [
       "ir"
     ],
+    "shortDescription": "Protests in Iran, blocking of various services including Tor.",
     "description": "Protests in Iran, blocking of various services including Tor.",
     "links": [
-      "<a href=\"https://ooni.torproject.org/post/2018-iran-protests/\">OONI report</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-11-01&end=2018-01-20&country=ir\">relay graph</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-country.html?start=2017-11-01&end=2018-01-20&country=ir\">bridge graph</a>",
-      "<a href=\"https://twitter.com/nusenu_/status/948914485045145601\">tweet</a>"
+      {
+        "label": "OONI report",
+        "target": "https://ooni.torproject.org/post/2018-iran-protests/"
+      },
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-11-01&end=2018-01-20&country=ir"
+      },
+      {
+        "label": "bridge graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-country.html?start=2017-11-01&end=2018-01-20&country=ir"
+      },
+      {
+        "label": "tweet",
+        "target": "https://twitter.com/nusenu_/status/948914485045145601"
+      }
     ]
   },
   {
@@ -2840,17 +4123,25 @@
     "protocols": [
       "relay"
     ],
+    "shortDescription": "User report that the UAE blocked Tor, bridges work.",
     "description": "User report that the UAE blocked Tor, bridges work.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/25137#comment:17\">comment</a>"
+      {
+        "label": "comment",
+        "target": "https://bugs.torproject.org/25137#comment:17"
+      }
     ]
   },
   {
     "start": "2018-01-05",
     "ongoing": true,
+    "shortDescription": "Outage of the op-hk OnionPerf instance.",
     "description": "Outage of the op-hk OnionPerf instance.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/torperf.html?start=2017-12-01&end=2017-02-01&source=op-hk&server=public&filesize=50kb\">op-hk graph</a>"
+      {
+        "label": "op-hk graph",
+        "target": "https://metrics.torproject.org/torperf.html?start=2017-12-01&end=2017-02-01&source=op-hk&server=public&filesize=50kb"
+      }
     ]
   },
   {
@@ -2859,16 +4150,24 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"January 5 2018 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"January 5 2018 Maxmind GeoLite2 Country\" (<code>geoip-db-digest ACE2AF82816B9D3F58FC9C79A41B4506D6DAD713</code>, <code>geoip6-db-digest 387B3F555F1E054F0F9971C726F49848C5B5CF8B</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=8efbeb09826030302481619dab83e83f35fdc26e\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=8efbeb09826030302481619dab83e83f35fdc26e"
+      }
     ]
   },
   {
     "start": "2018-01-16",
+    "shortDescription": "Tor 0.3.2.9 reaches deb.torproject.org.",
     "description": "Tor 0.3.2.9 reaches deb.torproject.org.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/versions.html?start=2017-12-01&end=2018-03-01\">relay versions graph</a>"
+      {
+        "label": "relay versions graph",
+        "target": "https://metrics.torproject.org/versions.html?start=2017-12-01&end=2018-03-01"
+      }
     ]
   },
   {
@@ -2876,9 +4175,13 @@
     "protocols": [
       "relay"
     ],
+    "shortDescription": "Some more directory authorities upgrade to 0.3.2.9 which enforces new requirements for the exit flag",
     "description": "Some more directory authorities upgrade to 0.3.2.9 which enforces new requirements for the exit flag. ~50 relays lose the exit flag",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-relays/2018-February/014478.html\">tor-relays post</a>"
+      {
+        "label": "tor-relays post",
+        "target": "https://lists.torproject.org/pipermail/tor-relays/2018-February/014478.html"
+      }
     ]
   },
   {
@@ -2887,9 +4190,13 @@
       "ipv4",
       "ipv6"
     ],
+    "shortDescription": "geoip and geoip6 databases updated to \"February 7 2018 Maxmind GeoLite2 Country\"",
     "description": "geoip and geoip6 databases updated to \"February 7 2018 Maxmind GeoLite2 Country\" (<code>geoip-db-digest FF83AD73DE7672C77EDF8888F4B241642C7C90F7</code>, <code>geoip6-db-digest B1CDBFEB7C88F82EF3B5289CAFEED1321FA4693F</code>).",
     "links": [
-      "<a href=\"https://gitweb.torproject.org/tor.git/commit/?id=f1278b7e573f01edb8bc3ab4d7fbfbd65b5d2c60\">commit</a>"
+      {
+        "label": "commit",
+        "target": "https://gitweb.torproject.org/tor.git/commit/?id=f1278b7e573f01edb8bc3ab4d7fbfbd65b5d2c60"
+      }
     ]
   },
   {
@@ -2897,9 +4204,13 @@
     "protocols": [
       "relay"
     ],
+    "shortDescription": "Tor 0.3.3.2-alpha is released",
     "description": "Tor 0.3.3.2-alpha is released (containing important denial-of-service migitations for relays)",
     "links": [
-      "<a href=\"https://blog.torproject.org/tor-0332-alpha-released-bugfixes-and-dos-prevention\">blog</a>"
+      {
+        "label": "blog",
+        "target": "https://blog.torproject.org/tor-0332-alpha-released-bugfixes-and-dos-prevention"
+      }
     ]
   },
   {
@@ -2907,6 +4218,7 @@
     "protocols": [
       "relay"
     ],
+    "shortDescription": "Tor 0.3.3.2-alpha reaches FreeBSD repositories",
     "description": "Tor 0.3.3.2-alpha reaches FreeBSD repositories"
   },
   {
@@ -2914,22 +4226,34 @@
     "protocols": [
       "relay"
     ],
+    "shortDescription": "Tor 0.3.3.2-alpha reaches deb.torproject.org repositories",
     "description": "Tor 0.3.3.2-alpha reaches deb.torproject.org repositories"
   },
   {
     "start": "2018-02-27",
     "end": "2018-03-02",
+    "shortDescription": "Less than 3 bandwidth authorities are available.",
     "description": "Less than 3 bandwidth authorities are available.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-relays/2018-February/014676.html\">tor-relays</a>"
+      {
+        "label": "tor-relays",
+        "target": "https://lists.torproject.org/pipermail/tor-relays/2018-February/014676.html"
+      }
     ]
   },
   {
     "start": "2018-03-03",
+    "shortDescription": "Release of tor 0.3.2.10, 0.3.1.10, and 0.2.9.15, which offer better resistance against DoS attacks.",
     "description": "Release of tor 0.3.2.10, 0.3.1.10, and 0.2.9.15, which offer better resistance against DoS attacks.",
     "links": [
-      "<a href=\"https://blog.torproject.org/new-stable-tor-releases-security-fixes-and-dos-prevention-03210-03110-02915\">blog post</a>",
-      "<a href=\"https://bugs.torproject.org/24902\">ticket</a>"
+      {
+        "label": "blog post",
+        "target": "https://blog.torproject.org/new-stable-tor-releases-security-fixes-and-dos-prevention-03210-03110-02915"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/24902"
+      }
     ]
   },
   {
@@ -2940,9 +4264,13 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Large drop in direct users in Turkmenistan.",
     "description": "Large drop in direct users in Turkmenistan.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2015-11-01&end=2016-04-01&country=tm&events=off\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2015-11-01&end=2016-04-01&country=tm&events=off"
+      }
     ],
     "unknown": true
   },
@@ -2955,9 +4283,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Sustained increase in meek users in Brazil",
     "description": "Sustained increase in meek users in Brazil. Locals believe that they are not actual users, rather bots or something like that. End date coincides with shutdown of meek-azure before migration. Would pick up again 2017-06-07.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-combined.html?start=2016-06-01&end=2017-04-01&country=br\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-combined.html?start=2016-06-01&end=2017-04-01&country=br"
+      }
     ],
     "unknown": true
   },
@@ -2967,10 +4299,17 @@
     "places": [
       "ml"
     ],
+    "shortDescription": "Sudden increase of direct and bridge users in Mali.",
     "description": "Sudden increase of direct and bridge users in Mali.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2016-03-01&end=2016-10-01&country=ml&events=off\">relay graph</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-country.html?start=2016-03-01&end=2016-10-01&country=ml&events=off\">bridge graph</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2016-03-01&end=2016-10-01&country=ml&events=off"
+      },
+      {
+        "label": "bridge graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-country.html?start=2016-03-01&end=2016-10-01&country=ml&events=off"
+      }
     ],
     "unknown": true
   },
@@ -2982,10 +4321,17 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Large decrease in users in China.",
     "description": "Large decrease in users in China.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2016-07-30&end=2016-10-28&country=cn&events=off\">relay</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-country.html?start=2016-07-30&end=2016-10-28&country=cn\">bridge</a>"
+      {
+        "label": "relay",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2016-07-30&end=2016-10-28&country=cn&events=off"
+      },
+      {
+        "label": "bridge",
+        "target": "https://metrics.torproject.org/userstats-bridge-country.html?start=2016-07-30&end=2016-10-28&country=cn"
+      }
     ],
     "unknown": true
   },
@@ -2999,9 +4345,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Direct users fluctuate wildly in Israel",
     "description": "Direct users fluctuate wildly in Israel. Bridge users not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2016-07-28&end=2016-10-26&country=il&events=off\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2016-07-28&end=2016-10-26&country=il&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3013,9 +4363,13 @@
     "protocols": [
       "<OR>"
     ],
+    "shortDescription": "Decrease in direct users and increase in bridge users in Saudi Arabia.",
     "description": "Decrease in direct users and increase in bridge users in Saudi Arabia.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20785\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20785"
+      }
     ],
     "unknown": true
   },
@@ -3028,9 +4382,13 @@
     "protocols": [
       "bridge"
     ],
+    "shortDescription": "Decrease in direct users and increase in bridge users in Saudi Arabia",
     "description": "Decrease in direct users and increase in bridge users in Saudi Arabia. The increase in bridge users lasts only about one month while the number of direct users remains down.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/20785\">ticket</a>"
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/20785"
+      }
     ],
     "unknown": true
   },
@@ -3041,10 +4399,17 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Drop in relay users.",
     "description": "Drop in relay users.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2016-December/000260.html\">metrics-team thread</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-January/000264.html\">thread continues</a>"
+      {
+        "label": "metrics-team thread",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2016-December/000260.html"
+      },
+      {
+        "label": "thread continues",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-January/000264.html"
+      }
     ],
     "unknown": true
   },
@@ -3058,12 +4423,25 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Huge increase in relay users",
     "description": "Huge increase in relay users (400k+). An anonymous contributor suggests that it may be a botnet, based on the large number of hosts with an open SMB port in the UAE.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-01-01&end=2017-06-01&country=ae&events=off\">graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-January/000284.html\">metrics-team thread</a>",
-      "<a href=\"https://www.reddit.com/r/TOR/comments/5pbukk/united_arab_emirates_went_from_10k_tor_users_to/\">reddit thread</a>",
-      "<a href=\"https://bugs.torproject.org/25137#comment:10\">comment about botnet</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-01-01&end=2017-06-01&country=ae&events=off"
+      },
+      {
+        "label": "metrics-team thread",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-January/000284.html"
+      },
+      {
+        "label": "reddit thread",
+        "target": "https://www.reddit.com/r/TOR/comments/5pbukk/united_arab_emirates_went_from_10k_tor_users_to/"
+      },
+      {
+        "label": "comment about botnet",
+        "target": "https://bugs.torproject.org/25137#comment:10"
+      }
     ],
     "unknown": true
   },
@@ -3076,11 +4454,21 @@
     "protocols": [
       "obfs3"
     ],
+    "shortDescription": "Increase in obfs3 users from the UAE, from 5K to 100K",
     "description": "Increase in obfs3 users from the UAE, from 5K to 100K. Other transports not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-transport.html?start=2017-01-01&end=2017-08-01&transport=obfs3&transport=obfs4&transport=meek&transport=%3COR%3E\">transport graph</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-country.html?start=2017-01-01&end=2017-08-01&country=ae\">UAE bridge graph</a>",
-      "<a href=\"https://bugs.torproject.org/21345\">ticket</a>"
+      {
+        "label": "transport graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-transport.html?start=2017-01-01&end=2017-08-01&transport=obfs3&transport=obfs4&transport=meek&transport=%3COR%3E"
+      },
+      {
+        "label": "UAE bridge graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-country.html?start=2017-01-01&end=2017-08-01&country=ae"
+      },
+      {
+        "label": "ticket",
+        "target": "https://bugs.torproject.org/21345"
+      }
     ],
     "unknown": true
   },
@@ -3093,9 +4481,13 @@
     "protocols": [
       "obfs3"
     ],
+    "shortDescription": "Abrupt increase and decrease in obfs3 users in Jordan",
     "description": "Abrupt increase and decrease in obfs3 users in Jordan. Relay users and other transports seemingly not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-combined.html?start=2016-11-01&end=2017-07-27&country=jo\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-combined.html?start=2016-11-01&end=2017-07-27&country=jo"
+      }
     ],
     "unknown": true
   },
@@ -3108,9 +4500,13 @@
     "protocols": [
       "obfs3"
     ],
+    "shortDescription": "Gradual but large increase of obfs3 users in India, followed by slow decay",
     "description": "Gradual but large increase of obfs3 users in India, followed by slow decay. Relay users and other transports seemingly not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-combined.html?start=2016-11-01&end=2017-07-27&country=in\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-combined.html?start=2016-11-01&end=2017-07-27&country=in"
+      }
     ],
     "unknown": true
   },
@@ -3124,9 +4520,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Another increase in relay users, with a slower rate of growth than the previous one.",
     "description": "Another increase in relay users, with a slower rate of growth than the previous one.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-01-01&end=2017-09-01&country=ae&events=off\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-01-01&end=2017-09-01&country=ae&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3140,9 +4540,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Sudden increase of direct users in Israel",
     "description": "Sudden increase of direct users in Israel. Bridge users not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-02-22&end=2017-05-23&country=il&events=off\">relay graph</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-02-22&end=2017-05-23&country=il&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3156,9 +4560,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Another sudden increase of direct users in Israel",
     "description": "Another sudden increase of direct users in Israel. Bridge users not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-02-22&end=2017-05-23&country=il&events=off\">relay graph</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-02-22&end=2017-05-23&country=il&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3171,10 +4579,17 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Relay users triple and begin to fluctuate in Taiwan.",
     "description": "Relay users triple and begin to fluctuate in Taiwan.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2017-May/043206.html\">tor-talk post</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-02-22&end=2017-05-24&country=tw&events=on\">graph</a>"
+      {
+        "label": "tor-talk post",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2017-May/043206.html"
+      },
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-02-22&end=2017-05-24&country=tw&events=on"
+      }
     ],
     "unknown": true
   },
@@ -3188,10 +4603,17 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Sudden temporary peak of 3k direct users in Macau.",
     "description": "Sudden temporary peak of 3k direct users in Macau.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2017-May/043206.html\">tor-talk post</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-02-22&end=2017-05-12&country=mo&events=on\">graph</a>"
+      {
+        "label": "tor-talk post",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2017-May/043206.html"
+      },
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-02-22&end=2017-05-12&country=mo&events=on"
+      }
     ],
     "unknown": true
   },
@@ -3204,10 +4626,17 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Drop in direct users from Egypt.",
     "description": "Drop in direct users from Egypt.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-talk/2017-May/043206.html\">tor-talk post</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-03-15&end=2017-06-13&country=eg&events=on\">graph</a>"
+      {
+        "label": "tor-talk post",
+        "target": "https://lists.torproject.org/pipermail/tor-talk/2017-May/043206.html"
+      },
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-03-15&end=2017-06-13&country=eg&events=on"
+      }
     ],
     "unknown": true
   },
@@ -3220,9 +4649,13 @@
     "protocols": [
       "meek"
     ],
+    "shortDescription": "Sustained increase of meek users in Brazil, similar to the one that took place between 2016-07-21 and 2017-03-03.",
     "description": "Sustained increase of meek users in Brazil, similar to the one that took place between 2016-07-21 and 2017-03-03.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-combined.html?start=2016-06-01&end=2018-01-15&country=br\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-combined.html?start=2016-06-01&end=2018-01-15&country=br"
+      }
     ],
     "unknown": true
   },
@@ -3234,10 +4667,17 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "Increase in obfs4 users in Switzerland, from 200 to 400.",
     "description": "Increase in obfs4 users in Switzerland, from 200 to 400.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-country.html?start=2017-01-01&end=2017-08-14&country=ch\">bridge graph</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-combined.html?start=2017-01-01&end=2017-08-14&country=ch\">transport graph</a>"
+      {
+        "label": "bridge graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-country.html?start=2017-01-01&end=2017-08-14&country=ch"
+      },
+      {
+        "label": "transport graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-combined.html?start=2017-01-01&end=2017-08-14&country=ch"
+      }
     ],
     "unknown": true
   },
@@ -3247,10 +4687,17 @@
     "places": [
       "ml"
     ],
+    "shortDescription": "Sudden increase of direct and bridge users in Mali.",
     "description": "Sudden increase of direct and bridge users in Mali.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-03-01&end=2017-09-01&country=ml&events=off\">relay graph</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-country.html?start=2017-03-01&end=2017-09-01&country=ml&events=off\">bridge graph</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-03-01&end=2017-09-01&country=ml&events=off"
+      },
+      {
+        "label": "bridge graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-country.html?start=2017-03-01&end=2017-09-01&country=ml&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3263,9 +4710,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Sudden drop in relay users.",
     "description": "Sudden drop in relay users.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-01-01&end=2017-09-01&country=ae&events=off\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-01-01&end=2017-09-01&country=ae&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3279,9 +4730,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Slow increase in relay users.",
     "description": "Slow increase in relay users.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2017-11-01&country=ae&events=off\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2017-11-01&country=ae&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3295,9 +4750,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Increase of relay users in the Seychelles, from 400 to 6000",
     "description": "Increase of relay users in the Seychelles, from 400 to 6000. Bridge users not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-05-16&end=2017-08-14&country=sc&events=off\">relay graph</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-05-16&end=2017-08-14&country=sc&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3311,20 +4770,34 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Fluctuations of relay users in Austria",
     "description": "Fluctuations of relay users in Austria. Bridge users not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-05-16&end=2017-09-15&country=at&events=off\">relay graph</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-05-16&end=2017-09-15&country=at&events=off"
+      }
     ],
     "unknown": true
   },
   {
     "start": "2017-07-31",
     "end": "2017-08-28",
+    "shortDescription": "Directory authorities using 2× bandwidth.",
     "description": "Directory authorities using 2× bandwidth.",
     "links": [
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-August/012389.html\">mailing list post for start</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-September/012445.html\">mailing list post for end</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html\">post suggesting link to nl, ro, lt, sc increases</a>"
+      {
+        "label": "mailing list post for start",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-August/012389.html"
+      },
+      {
+        "label": "mailing list post for end",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-September/012445.html"
+      },
+      {
+        "label": "post suggesting link to nl, ro, lt, sc increases",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html"
+      }
     ],
     "unknown": true
   },
@@ -3338,12 +4811,25 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Increase of relay users in the Netherlands, from 50k to 100k",
     "description": "Increase of relay users in the Netherlands, from 50k to 100k. Stopped at the same time as increases in Romania, Lithuania, and the Seychelles.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-10-15&country=nl&events=off\">relay graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html\">post suggesting link to 2× dirauth bandwidth</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-August/000428.html\">post about start</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-October/000502.html\">post about end</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-10-15&country=nl&events=off"
+      },
+      {
+        "label": "post suggesting link to 2× dirauth bandwidth",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html"
+      },
+      {
+        "label": "post about start",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-August/000428.html"
+      },
+      {
+        "label": "post about end",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-October/000502.html"
+      }
     ],
     "unknown": true
   },
@@ -3357,10 +4843,17 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Increase of relay users in Romania, from 10k to 40k",
     "description": "Increase of relay users in Romania, from 10k to 40k. Bridge users not affected.  Stopped at the same time as increases in the Netherlands, Lithuania, and the Seychelles. Another increase began immediately after.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-05-16&end=2017-10-15&country=ro&events=off\">relay graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html\">post suggesting link to 2× dirauth bandwidth</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-05-16&end=2017-10-15&country=ro&events=off"
+      },
+      {
+        "label": "post suggesting link to 2× dirauth bandwidth",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html"
+      }
     ],
     "unknown": true
   },
@@ -3374,12 +4867,25 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Increase of relay users in Lithuania, from 2k to 70k",
     "description": "Increase of relay users in Lithuania, from 2k to 70k. Stopped at the same time as increases in the Nethernlands, Romania, and the Seychelles.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-10-15&country=lt&events=off\">relay graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html\">post suggesting link to 2× dirauth bandwidth</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-August/000428.html\">post about start</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-October/000502.html\">post about end</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-10-15&country=lt&events=off"
+      },
+      {
+        "label": "post suggesting link to 2× dirauth bandwidth",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html"
+      },
+      {
+        "label": "post about start",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-August/000428.html"
+      },
+      {
+        "label": "post about end",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-October/000502.html"
+      }
     ],
     "unknown": true
   },
@@ -3393,12 +4899,25 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Further increase of relay users in the Seychelles, from 5k to 100k",
     "description": "Further increase of relay users in the Seychelles, from 5k to 100k. Stopped at the same time as increases in the Netherlands, Romania, and Lithuania.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-10-15&country=sc&events=off\">relay graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html\">post suggesting link to 2× dirauth bandwidth</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-August/000428.html\">post about start</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-October/000502.html\">post about end</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-10-15&country=sc&events=off"
+      },
+      {
+        "label": "post suggesting link to 2× dirauth bandwidth",
+        "target": "https://lists.torproject.org/pipermail/tor-dev/2017-September/012446.html"
+      },
+      {
+        "label": "post about start",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-August/000428.html"
+      },
+      {
+        "label": "post about end",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-October/000502.html"
+      }
     ],
     "unknown": true
   },
@@ -3408,9 +4927,13 @@
       "ipv6",
       "obfs4"
     ],
+    "shortDescription": "Jump in IPv6 users of the Lisbeth default obfs4 bridge.",
     "description": "Jump in IPv6 users of the <a href=\"https://metrics.torproject.org/rs.html#details/D9C805C955CB124D188C0D44F271E9BE57DE2109\">Lisbeth</a> default obfs4 bridge.",
     "links": [
-      "<a href=\"https://bugs.torproject.org/22429#comment:7\">comment</a>"
+      {
+        "label": "comment",
+        "target": "https://bugs.torproject.org/22429#comment:7"
+      }
     ],
     "unknown": true
   },
@@ -3423,9 +4946,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Triple increase in direct Tor users in Hong Kong",
     "description": "Triple increase in direct Tor users in Hong Kong. Bridge users not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2017-08-30&country=hk&events=off\">relay graph</a>"
+      {
+        "label": "relay graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2017-08-30&country=hk&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3438,9 +4965,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Increase of users in South Korea, relay only.",
     "description": "Increase of users in South Korea, relay only.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2017-12-01&country=kr\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2017-12-01&country=kr"
+      }
     ],
     "unknown": true
   },
@@ -3455,10 +4986,17 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Short-lived, simultaneous spike in direct users in Egypt and Turkey",
     "description": "Short-lived, simultaneous spike in direct users in Egypt and Turkey. Bridge users not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-09-15&country=eg&events=off\">eg graph</a>",
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-09-15&country=tr&events=off\">tr graph</a>"
+      {
+        "label": "eg graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-09-15&country=eg&events=off"
+      },
+      {
+        "label": "tr graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-07-01&end=2017-09-15&country=tr&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3471,9 +5009,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Relay users remain volatile but flatten their rate of growth.",
     "description": "Relay users remain volatile but flatten their rate of growth.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2018-02-01&country=ae&events=off\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-06-01&end=2018-02-01&country=ae&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3483,9 +5025,13 @@
     "protocols": [
       "obfs4"
     ],
+    "shortDescription": "About a 35% increase in obfs4 users before returning to normal",
     "description": "About a 35% increase in obfs4 users before returning to normal. Happened in many countries. Other transports do not have it.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-bridge-transport.html?start=2017-07-15&end=2017-11-09&transport=obfs3&transport=obfs4&transport=meek&transport=%3COR%3E\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-bridge-transport.html?start=2017-07-15&end=2017-11-09&transport=obfs3&transport=obfs4&transport=meek&transport=%3COR%3E"
+      }
     ],
     "unknown": true
   },
@@ -3499,10 +5045,17 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Steady increase of relay users in Germany, from 180k to around 500k",
     "description": "Steady increase of relay users in Germany, from 180k to around 500k. It would increase further starting 2017-12-10.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-15&end=2017-12-01&country=de&events=off\">de graph</a>",
-      "<a href=\"https://www.reddit.com/r/TOR/comments/7b53kq/direct_users_from_germany_go_from_200k_to_500k_in/\">reddit thread</a>"
+      {
+        "label": "de graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-15&end=2017-12-01&country=de&events=off"
+      },
+      {
+        "label": "reddit thread",
+        "target": "https://www.reddit.com/r/TOR/comments/7b53kq/direct_users_from_germany_go_from_200k_to_500k_in/"
+      }
     ],
     "unknown": true
   },
@@ -3516,10 +5069,17 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Surge of relay users in Romania, from 10k to around 90k, which later subsided.",
     "description": "Surge of relay users in Romania, from 10k to around 90k, which later subsided.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-09&end=2018-01-15&country=ro&events=off\">graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2017-October/000502.html\">metrics-team thread</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-09&end=2018-01-15&country=ro&events=off"
+      },
+      {
+        "label": "metrics-team thread",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2017-October/000502.html"
+      }
     ],
     "unknown": true
   },
@@ -3533,9 +5093,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Short-lived tripling of relay users in Zambia.",
     "description": "Short-lived tripling of relay users in Zambia.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-01&end=2017-12-15&country=zm&events=off\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-08-01&end=2017-12-15&country=zm&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3549,10 +5113,17 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Further, slow increase of relay users in Germany, from 500k to over 1.5M.",
     "description": "Further, slow increase of relay users in Germany, from 500k to over 1.5M.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-11-01&end=2018-01-15&country=de&events=off\">graph</a>",
-      "<a href=\"https://www.reddit.com/r/TOR/comments/7ldrox/tor_usage_in_germany_what_happend/\">reddit thread</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-11-01&end=2018-01-15&country=de&events=off"
+      },
+      {
+        "label": "reddit thread",
+        "target": "https://www.reddit.com/r/TOR/comments/7ldrox/tor_usage_in_germany_what_happend/"
+      }
     ],
     "unknown": true
   },
@@ -3566,9 +5137,13 @@
       "<OR>",
       "relay"
     ],
+    "shortDescription": "Temporary tripling of relay users in France",
     "description": "Temporary tripling of relay users in France. Bridges not affected.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-10-01&end=2018-03-01&country=fr&events=off\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-10-01&end=2018-03-01&country=fr&events=off"
+      }
     ],
     "unknown": true
   },
@@ -3578,10 +5153,17 @@
     "protocols": [
       "bridge"
     ],
+    "shortDescription": "Drop in the number of measured bridges.",
     "description": "Drop in the number of measured bridges.",
     "links": [
-      "<a href=\"https://metrics.torproject.org/networksize.html?start=2017-07-01&end=2018-01-01\">graph</a>",
-      "<a href=\"https://lists.torproject.org/pipermail/metrics-team/2018-March/000713.html\">mailing list post</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/networksize.html?start=2017-07-01&end=2018-01-01"
+      },
+      {
+        "label": "mailing list post",
+        "target": "https://lists.torproject.org/pipermail/metrics-team/2018-March/000713.html"
+      }
     ],
     "unknown": true
   },
@@ -3595,10 +5177,14 @@
       "<OR>",
       "relay"
     ],
-    "description": "Steady drop in the number of relay users in Germany, from 1.5M to 650k. (Drop coincides with the release of tor 0.3.2.10, 0.3.1.10, and 0.2.9.15, which offer better resistance against DoS attacks; as well as improvements in speed for downloads from onions <a href=\"https://metrics.torproject.org/torperf.html?start=2017-12-10&end=2018-03-10&source=all&server=onion&filesize=5mb\">graph</a>; see this <a href=\"https://metrics.torproject.org/connbidirect.html\">graph</a> as well. More datapoints: DDoS of the network happened <a href=\"https://lists.torproject.org/pipermail/tor-project/2017-December/001604.html\">around the time</a> that saw an increase in the number of relay users in Germany, see entry above or <a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-12-11&end=2017-12-22&country=de&events=off\">graph</a>)",
+    "shortDescription": "Steady drop in the number of relay users in Germany, from 1.5M to 650k",
+    "description": "Steady drop in the number of relay users in Germany, from 1.5M to 650k. (Drop coincides with the release of tor 0.3.2.10, 0.3.1.10, and 0.2.9.15, which offer better resistance against DoS attacks; as well as improvements in speed for downloads from onions <a href=\"https://metrics.torproject.org/torperf.html?start=2017-12-10&end=2018-03-10&source=all&server=onion&filesize=5mb\">graph</a>; see this <a href=\"https://metrics.torproject.org/connbidirect.html\">graph</a> as well. More datapoints: DDoS of the network happened <a href=\"https://lists.torproject.org/pipermail/tor-project/2017-December/001604.html\">around the time</a> that saw an increase in the number of relay users in Germany, see entry above or <a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-12-11&end=2017-12-22&country=de&events=off\">graph</a>)",
     "links": [
-      "<a href=\"https://metrics.torproject.org/userstats-relay-country.html?start=2017-11-10&end=2018-03-10&country=de&events=off\">graph</a>"
+      {
+        "label": "graph",
+        "target": "https://metrics.torproject.org/userstats-relay-country.html?start=2017-11-10&end=2018-03-10&country=de&events=off"
+      }
     ],
     "unknown": true
   }
-]
+]
\ No newline at end of file
diff --git a/src/main/resources/web/jsps/graph.jsp b/src/main/resources/web/jsps/graph.jsp
index 41e751d..06582ab 100644
--- a/src/main/resources/web/jsps/graph.jsp
+++ b/src/main/resources/web/jsps/graph.jsp
@@ -193,8 +193,8 @@
                   be related to the displayed graph.</td></tr>
                   </c:when>
                   <c:otherwise>
-                  <c:forEach var="relatedEvent" items="${relatedEvents}">
-                  ${relatedEvent}
+                  <c:forEach var="entry" items="${relatedEvents}">
+                    <%@ include file="news-item.jsp" %>
                   </c:forEach>
                   </c:otherwise>
                   </c:choose>
diff --git a/src/main/resources/web/jsps/news-item.jsp b/src/main/resources/web/jsps/news-item.jsp
new file mode 100644
index 0000000..5640445
--- /dev/null
+++ b/src/main/resources/web/jsps/news-item.jsp
@@ -0,0 +1,62 @@
+            <tr>
+              <td>
+                <span class="dates">
+                  <c:choose>
+                    <c:when test="${empty entry.start}">
+                      N/A
+                    </c:when>
+                    <c:when test="${entry.ongoing}">
+                      <c:out value="${entry.start}"/> to present
+                    </c:when>
+                    <c:when test="${(empty entry.end) || (entry.start == entry.end)}">
+                      <c:out value="${entry.start}"/>
+                    </c:when>
+                    <c:otherwise>
+                      <c:out value="${entry.start}"/> to
+                      <c:out value="${entry.end}"/>
+                    </c:otherwise>
+                  </c:choose>
+                </span>
+              </td>
+              <td>
+                <c:forEach var="placeName" items="${entry.placeNames}">
+                  <span class="label label-warning"><c:out value="${placeName}"/></span>
+                </c:forEach>
+                <c:forEach var="protocol" items="${entry.protocols}">
+                  <c:choose>
+                    <c:when test="${protocol == 'relay'}">
+                      <span class="label label-success">Relays</span>
+                    </c:when>
+                    <c:when test="${protocol == 'bridge'}">
+                      <span class="label label-primary">Bridges</span>
+                    </c:when>
+                    <c:when test="${protocol == '<OR>'}">
+                      <span class="label label-info"><OR></span>
+                    </c:when>
+                    <c:otherwise>
+                      <span class="label label-info"><c:out value="${protocol}"/></span>
+                    </c:otherwise>
+                  </c:choose>
+                </c:forEach>
+                <c:if test="${entry.unknown}">
+                  <span class="label label-default">Unknown</span>
+                </c:if>
+              </td>
+              <td>
+                ${entry.description}
+                <br />
+                <c:forEach var="link" items="${entry.links}">
+                  <c:choose>
+                    <c:when test="${fn:startsWith(link.target, 'https://metrics.torproject.org/')}">
+                      <c:set value="" var="atarget"/>
+                    </c:when>
+                    <c:otherwise>
+                      <c:set value="_blank" var="atarget"/>
+                    </c:otherwise>
+                  </c:choose>
+                  <a href="${link.target}" class="link metrics-news-link" target="${atarget}">
+                    <c:out value="${link.label}"/>
+                  </a>
+                </c:forEach>
+              </td>
+           </tr>
diff --git a/src/main/resources/web/jsps/news.jsp b/src/main/resources/web/jsps/news.jsp
index 499eade..c0972a0 100644
--- a/src/main/resources/web/jsps/news.jsp
+++ b/src/main/resources/web/jsps/news.jsp
@@ -30,7 +30,7 @@
         </thead>
         <tbody>
           <c:forEach var="entry" items="${category.value}">
-          ${entry}
+            <%@ include file="news-item.jsp" %>
           </c:forEach>
         </tbody>
       </table>





More information about the tor-commits mailing list