Create PluginController, and the ability to add md2d plugins.

A plugin is a set of related functions and changes to the md2d arrays, which
would normally be in md2d.js, but can be extracted out and optionally enabled
or disabled.

For example, all functions related to Quantum Dynamics can be extracted out, so
that they can be found an a single meaningful place, and so that they do not
need to be invoked when a model is not using quantum dynamics (and so md2d doesn't
need a large number of "if (quantumDynamics) { ... }" statements).

Since this is code that would otherwise be directly in md2d.js, the plugins are
"privileged" and can update atom tables and do other things that can be freely
done within md2d.js.
Add initial stub of QuantumDynamics plugin

QuantumDynamics plugin initially just adds a new array to the atoms array,
"excitation", which is an int representing the current level of excitation
of an atom, where levels are defined in a new not-yet-existant property,
"elementEnergyLevels", to be defined in the model.

Per Classic MW, we currently (and for the known-future) make the simplification
that each atom only has one single electron that can be excited to a new energy
level, and so we can safely model this as a single int per atom.
Add quantum dynamics props to metadata

As part of having quantum dynamics being its own self-contained
plugin, it seems desirable not to need to update all other model
json files (or their serializations) with default QD property values,
such as energy levels or excitation.

For this reason, the QD properties do not have a default value (or
they would be serialized).

Another option was to define the new properties in the plugin itself,
and add them to to metadata dynamically as needed. However, so further
restructuring of the metadata would be required to allow that.

A consequence of this is that when we initialize the model, we have to
check if a property exists in the atoms table, and not just assume that
if it's in the metadata then it must be in the table.

We can also consider other ways to handle this issue.
Parse quantum dynamics properties from MML; add tests

Currently just parsing whether to use QD, element energy levels,
and atom excitation states.
QD: Add excitation after collisions; call within intgration loop

Quantum dynamics plugin will now excite an atom if two atoms are
close enough to each other and their relative KE is above that required
to reach the next electron energy state.

If an atom gets excited, the velocities of the two atoms will drop,
resulting in a drop in KE. This will also result in a drop in total
energy, because the potential energy of the electron state isn't
added to the model's potential energy.

The excitation algorithm is functionally identical to the one used
by Classic MW.

MD2D calls "performActionWithinIntegrationLoop" as the last action
within the loop, and passes the current neighborList (for quick finding
of close neighbors within QD). Any other plugin that needs to act within
the integration loop can also respond to this action, and will get called
automatically. If they need new arguments passed in, they can easily be
added to the object argument without needing to update existing plugins.
Add example QD model and interactive

For now using a simple script to mark excited atoms, instead
of worrying about rendering this feature yet.
Parse radiationlessEmission probability from mml; +test

This is the probability that an electron will deexcite
only by adding KE after a collision, vs emitting a
photon at any time.

[#48674945]
Refactor QD excitation to anticipate de-excitation.

Refactoring the code so that we will check for close neighbors only
once, and then try to perform both excitation and de-excitation on
each pair.

This is more efficient than ClassicMW's model (which recomputes
close neighbors each time), and should provide the exact same
results.

[#48674945]
De-excite atoms during collision; possibly increase KE

When atoms collide, if one atom has an electron in an excited
state it will dexcite. It will then randomly either emit that
energy as an increase in the velocities of the two atoms (>KE),
or as a photon (not yet implemented), with a probability based
on the model settings.
Always excite an atom if one can be excited

Previously if both atoms had electrons that could be excited,
we randomly selected one and then tried to excite it.

Now we check the result of that excitation and try to excite
the other if the first one failed.

This prevents the situation where we have enough energy to only
excite one of the atoms, but we randomly picked the other, resulting
in neither atom getting excited.

[#48674803]
Prevent multiple QD operations during same collision

We maintain a list of the pairs of atoms that have just
had a QD operation, and only clear them from that list
once their collision has ended. This allows us to prevent
multiple QD operations occurring during the same collision.

Classic MW handles this slightly differently, by defining
a minimum-interval time during which the quantum engine
will not respond to events. This seems to be a slightly
cleaner way of achieving the same ends.

[#48674945]
Update collision example so textbox updates with slider

[#48674803]
Add initial rendering of excitation state as a glow

[#48675143]
Update QD example interactive 

We don't need to use markAtoms hack now that we are rendering excitation
state; fix graph axes; show step buttons; mark as public.
Add simple serialization mocha test for QD plugin

Asserts that excitation table defined by plugin only exists
when plugin is enabled, and works correctly.

[#48674673]