public function unparse_graph($v, $style, $myscore)
 {
     global $Conf;
     assert($this->has_options);
     $max = count($this->options);
     if (!is_object($v)) {
         $v = scoreCounts($v, $max);
     }
     $avgtext = $this->unparse_average($v->avg);
     if ($v->n > 1 && $v->stddev) {
         $avgtext .= sprintf(" ± %0.2f", $v->stddev);
     }
     $args = "v=";
     for ($key = 1; $key <= $max; $key++) {
         $args .= ($args == "v=" ? "" : ",") . $v->v[$key];
     }
     if ($myscore && $v->v[$myscore] > 0) {
         $args .= "&amp;h={$myscore}";
     }
     if ($this->option_letter) {
         $args .= "&amp;c=" . chr($this->option_letter - 1);
     }
     if ($this->option_class_prefix !== "sv") {
         $args .= "&amp;sv=" . urlencode($this->option_class_prefix);
     }
     if ($style == 1) {
         $width = 5 * $max + 3;
         $height = 5 * max(3, max($v->v)) + 3;
         $retstr = "<div class=\"need-scorechart\" style=\"width:{$width}px;height:{$height}px\" data-scorechart=\"{$args}&amp;s=1\" title=\"{$avgtext}\"></div>";
     } else {
         if ($style == 2) {
             $retstr = "<div class=\"sc\">" . "<div class=\"need-scorechart\" style=\"width:64px;height:8px\" data-scorechart=\"{$args}&amp;s=2\" title=\"{$avgtext}\"></div>" . "<br />";
             if ($this->option_letter) {
                 for ($key = $max; $key >= 1; $key--) {
                     $retstr .= ($key < $max ? " " : "") . '<span class="' . $this->value_class($key) . '">' . $v->v[$key] . "</span>";
                 }
             } else {
                 for ($key = 1; $key <= $max; $key++) {
                     $retstr .= ($key > 1 ? " " : "") . '<span class="' . $this->value_class($key) . '">' . $v->v[$key] . "</span>";
                 }
             }
             $retstr .= '<br /><span class="sc_sum">' . $avgtext . "</span></div>";
         }
     }
     $Conf->footerScript("\$(scorechart)", "scorechart");
     return $retstr;
 }
 if ($tokens = $Me->review_tokens()) {
     $where[] = "reviewToken in (" . join(",", $tokens) . ")";
 }
 $result = Dbl::qe_raw("select count(reviewSubmitted) num_submitted,\n\tcount(if(reviewNeedsSubmit=0,reviewSubmitted,1)) num_needs_submit,\n\tgroup_concat(if(reviewSubmitted is not null,overAllMerit,null)) scores,\n\tgroup_concat(distinct if(reviewNeedsSubmit!=0 and reviewSubmitted is null,reviewRound,null)) unsubmitted_rounds\n\tfrom PaperReview\n\tjoin Paper using (paperId)\n\twhere (" . join(" or ", $where) . ")\n    and (reviewSubmitted is not null or timeSubmitted>0)\n    group by PaperReview.reviewId>0");
 if ($myrow = edb_orow($result)) {
     $myrow->scores = scoreCounts($myrow->scores, $merit_noptions);
 }
 // Information about PC reviews
 $npc = $sumpcSubmit = $npcScore = $sumpcScore = 0;
 if ($Me->isPC || $Me->privChair) {
     $result = Dbl::qe_raw("select count(reviewId) num_submitted,\n\tgroup_concat(overAllMerit) scores\n\tfrom ContactInfo\n\tleft join PaperReview on (PaperReview.contactId=ContactInfo.contactId and PaperReview.reviewSubmitted is not null)\n        where (roles&" . Contact::ROLE_PC . ")!=0\n\tgroup by ContactInfo.contactId");
     while ($row = edb_row($result)) {
         ++$npc;
         if ($row[0]) {
             $sumpcSubmit += $row[0];
             $scores = scoreCounts($row[1], $merit_noptions);
             ++$npcScore;
             $sumpcScore += $scores->avg;
         }
     }
 }
 // Overview
 echo "<h4>Reviews: &nbsp;</h4> ";
 if ($myrow) {
     if ($myrow->num_needs_submit == 1 && $myrow->num_submitted <= 1) {
         echo "You ", $myrow->num_submitted == 1 ? "have" : "have not", " submitted your <a href=\"", hoturl("search", "q=&amp;t=r"), "\">review</a>";
     } else {
         echo "You have submitted ", $myrow->num_submitted, " of <a href=\"", hoturl("search", "q=&amp;t=r"), "\">", plural($myrow->num_needs_submit, "review"), "</a>";
     }
     if ($merit_field && $merit_field->displayed && $myrow->num_submitted) {
         echo " with an average {$merit_field->name_html} score of ", $merit_field->unparse_average($myrow->scores->avg);
 function content($fieldId, $row)
 {
     global $Conf;
     switch ($fieldId) {
         case self::FIELD_NAME:
             $t = Text::name_html($row);
             if (trim($t) == "") {
                 $t = "[No name]";
             }
             $t = '<span class="taghl">' . $t . '</span>';
             if ($this->contact->privChair) {
                 $t = "<a href=\"" . hoturl("profile", "u=" . urlencode($row->email) . $this->contactLinkArgs) . "\"" . ($row->disabled ? " class='uu'" : "") . ">{$t}</a>";
             }
             if ($row->roles & Contact::ROLE_CHAIR) {
                 $t .= ' <span class="pcrole">(chair)</span>';
             } else {
                 if (($row->roles & (Contact::ROLE_ADMIN | Contact::ROLE_PC)) == (Contact::ROLE_ADMIN | Contact::ROLE_PC)) {
                     $t .= ' <span class="pcrole">(PC, sysadmin)</span>';
                 } else {
                     if ($row->roles & Contact::ROLE_ADMIN) {
                         $t .= ' <span class="pcrole">(sysadmin)</span>';
                     } else {
                         if ($row->roles & Contact::ROLE_PC && $this->limit != "pc") {
                             $t .= ' <span class="pcrole">(PC)</span>';
                         }
                     }
                 }
             }
             if ($this->contact->privChair && $row->email != $this->contact->email) {
                 $t .= " <a href=\"" . hoturl("index", "actas=" . urlencode($row->email)) . "\">" . Ht::img("viewas.png", "[Act as]", array("title" => "Act as " . Text::name_text($row))) . "</a>";
             }
             if ($row->disabled && $this->contact->isPC) {
                 $t .= ' <span class="hint">(disabled)</span>';
             }
             return $t;
         case self::FIELD_EMAIL:
             if (!$this->contact->isPC) {
                 return "";
             }
             $e = htmlspecialchars($row->email);
             if (strpos($row->email, "@") === false) {
                 return $e;
             } else {
                 return "<a href=\"mailto:{$e}\">{$e}</a>";
             }
         case self::FIELD_AFFILIATION:
         case self::FIELD_AFFILIATION_ROW:
             return htmlspecialchars($row->affiliation);
         case self::FIELD_LASTVISIT:
             if (!$row->lastLogin) {
                 return "Never";
             }
             return $Conf->printableTimeShort($row->lastLogin);
         case self::FIELD_SELECTOR:
         case self::FIELD_SELECTOR_ON:
             $this->any->sel = true;
             $c = "";
             if ($fieldId == self::FIELD_SELECTOR_ON) {
                 $c = " checked='checked'";
             }
             return "<input type='checkbox' class='cb' name='pap[]' value='{$row->contactId}' tabindex='1' id='psel{$this->count}' onclick='rangeclick(event,this)' {$c}/>";
         case self::FIELD_HIGHTOPICS:
         case self::FIELD_LOWTOPICS:
             if (!defval($row, "topicIds")) {
                 return "";
             }
             $wanthigh = $fieldId == self::FIELD_HIGHTOPICS;
             $topics = array_combine(explode(",", $row->topicIds), explode(",", $row->topicInterest));
             $nt = $nti = array();
             foreach ($topics as $k => $v) {
                 if ($wanthigh ? $v > 0 : $v < 0) {
                     $nt[] = $k;
                     $nti[] = $v;
                 }
             }
             if (count($nt)) {
                 return PaperInfo::unparse_topic_list_html($nt, $nti, true);
             } else {
                 return "";
             }
         case self::FIELD_REVIEWS:
             if (!$row->numReviews && !$row->numReviewsSubmitted) {
                 return "";
             }
             $a1 = "<a href=\"" . hoturl("search", "t=s&amp;q=re:" . urlencode($row->email)) . "\">";
             if ($row->numReviews == $row->numReviewsSubmitted) {
                 return "{$a1}<b>{$row->numReviewsSubmitted}</b></a>";
             } else {
                 return "{$a1}<b>{$row->numReviewsSubmitted}</b>/{$row->numReviews}</a>";
             }
         case self::FIELD_LEADS:
             if (!$row->numLeads) {
                 return "";
             }
             return "<a href=\"" . hoturl("search", "t=s&amp;q=lead:" . urlencode($row->email)) . "\">{$row->numLeads}</a>";
         case self::FIELD_SHEPHERDS:
             if (!$row->numShepherds) {
                 return "";
             }
             return "<a href=\"" . hoturl("search", "t=s&amp;q=shepherd:" . urlencode($row->email)) . "\">{$row->numShepherds}</a>";
         case self::FIELD_REVIEW_RATINGS:
             if (!$row->numReviews && !$row->numReviewsSubmitted || !$row->numRatings) {
                 return "";
             }
             $a = array();
             $b = array();
             if ($row->sumRatings > 0) {
                 $a[] = $row->sumRatings . " positive";
                 $b[] = "<a href=\"" . hoturl("search", "q=re:" . urlencode($row->email) . "+rate:%2B") . "\">+" . $row->sumRatings . "</a>";
             }
             if ($row->sumRatings < $row->numRatings) {
                 $a[] = $row->numRatings - $row->sumRatings . " negative";
                 $b[] = "<a href=\"" . hoturl("search", "q=re:" . urlencode($row->email) . "+rate:-") . "\">&minus;" . ($row->numRatings - $row->sumRatings) . "</a>";
             }
             return "<span class='hastitle' title='" . join(", ", $a) . "'>" . join(" ", $b) . "</span>";
         case self::FIELD_PAPERS:
             if (!$row->paperIds) {
                 return "";
             }
             $x = explode(",", $row->paperIds);
             sort($x, SORT_NUMERIC);
             foreach ($x as &$v) {
                 $v = '<a href="' . hoturl("paper", "p={$v}") . '">' . $v . '</a>';
             }
             $ls = "p/s/";
             if ($this->limit == "auuns" || $this->limit == "all") {
                 $ls = "p/all/";
             }
             $ls = htmlspecialchars($ls . urlencode("au:" . $row->email));
             return '<div class="has_hotcrp_list" data-hotcrp-list="' . $ls . '">' . join(", ", $x) . '</div>';
         case self::FIELD_REVIEW_PAPERS:
             if (!$row->paperIds) {
                 return "";
             }
             $pids = explode(",", $row->paperIds);
             $rids = explode(",", $row->reviewIds);
             $ords = explode(",", $row->reviewOrdinals);
             $spids = $pids;
             sort($spids, SORT_NUMERIC);
             $m = array();
             for ($i = 0; $i != count($pids); ++$i) {
                 if ($ords[$i]) {
                     $url = hoturl("paper", "p=" . $pids[$i] . "#r" . $pids[$i] . unparseReviewOrdinal($ords[$i]));
                 } else {
                     $url = hoturl("review", "p=" . $pids[$i] . "&amp;r=" . $rids[$i]);
                 }
                 $m[$pids[$i]] = "<a href=\"{$url}\">" . $pids[$i] . "</a>";
             }
             ksort($m, SORT_NUMERIC);
             $ls = htmlspecialchars("p/s/" . urlencode("re:" . $row->email));
             return '<div class="has_hotcrp_list" data-hotcrp-list="' . $ls . '">' . join(", ", $m) . '</div>';
         case self::FIELD_TAGS:
             if ($this->contact->isPC && ($tags = $row->viewable_tags($this->contact))) {
                 $x = [];
                 foreach (TagInfo::split($tags) as $t) {
                     $x[] = '<a class="qq nw" href="' . hoturl("users", "t=%23" . TagInfo::base($t)) . '">' . $this->tagger->unparse_hashed($t) . '</a>';
                 }
                 return join(" ", $x);
             }
             return "";
         case self::FIELD_COLLABORATORS:
             if (!$this->contact->isPC || !($row->roles & Contact::ROLE_PC)) {
                 return "";
             }
             $t = array();
             foreach (explode("\n", $row->collaborators) as $collab) {
                 if (preg_match(',\\A(.*?)\\s*(\\(.*\\))\\s*\\z,', $collab, $m)) {
                     $t[] = '<span class="nw">' . htmlspecialchars($m[1]) . ' <span class="auaff">' . htmlspecialchars($m[2]) . '</span></span>';
                 } else {
                     if (($collab = trim($collab)) !== "" && strcasecmp($collab, "None")) {
                         $t[] = '<span class="nw">' . htmlspecialchars($collab) . '</span>';
                     }
                 }
             }
             return join("; ", $t);
         default:
             $f = ReviewForm::field($fieldId);
             if (!$f) {
                 return "";
             }
             if (!($row->roles & Contact::ROLE_PC) && !$this->contact->privChair && $this->limit != "req") {
                 return "";
             }
             $v = scoreCounts($row->{$fieldId}, $this->scoreMax[$fieldId]);
             $m = "";
             if ($v->n > 0) {
                 $m = $f->unparse_graph($v, 2, 0);
             }
             return $m;
     }
 }