WebSockets: increase maximum retries to 9.

This increases the total time it'll try to reconnect up to 34 minutes
from 17.  Experience with a couple of issues with stunnel have shown it
takes a few minutes for everything to settle back down and we do want
everyone to get reconnected eventually without having to refresh.
WebSockets: add some jitter to retries.

If the websocket server gets restarted or goes down temporarily, we
don't want everyone to be retrying at exactly the same time even though
we have exponential backoff.
WebSockets: allow the caller to choose when to start connecting.

This allows the caller to fully set up event handlers etc. before the
first 'connecting' message is fired.
js i18n: Add a plural no-op function.

This is for marking plurals for extraction while not actually
translating them at the time they're marked.
Change wording from "budget" to "total budget" in campaign editor.
Change tab wording from "self-serve advertising" to "advertising".
CommentBuilder: remove typing.
Un-cythonize _builder.
Combine _builder.py into builder.py.
Add a timer around get_num_children.
Move get_num_children to cython file.
builder: fix up imports.
QueryBuilder: cleanup prewrap_fn argument retrieval.
CommentBuilder: take num as a constructor argument.

This follows the pattern of all other Builders.
Cleanup builder.py.
CommentBuilder: more timers.
morechildren: Pass num to CommentBuilder constructor.
Set children on MoreRecursion objects.

This ensures that the json representation will have valid name,
id, and children.
Delete dead code RecommendedController.
UserController: move skip statement.