diff --git a/types/d3/3d/D33dAxis.d.ts b/types/d3/3d/D33dAxis.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..87ac30189c1c5af21033418bc97f661d6c921018
--- /dev/null
+++ b/types/d3/3d/D33dAxis.d.ts
@@ -0,0 +1,48 @@
+import { D33dGroup } from './D33dGroup';
+import { D33dAxisOptions } from './D33dOptions';
+
+/**
+ * A 3d axis.
+ *
+ * options {Object}
+ * extent {Array<Array<Number>>}
+ *        default [[0, 0, 0], [1, 0, 0]].
+ *        axis extent.
+ * format {Function(Array<Number>)}
+ *        format one coordinate (for ticks).
+ * labelAnchor {'start'|'middle'|'end'}
+ *        default 'middle'.
+ *        svg text-anchor property for tick labels.
+ * labelDirection {Array<Number>}
+ *        default null.
+ *        rotate label text to be parallel to this vector.
+ * labelVector {Array<Number>}
+ *        default tickVector.multiply(2).
+ *        placement of tick labels
+ * padding {Number}
+ *        default 0.05
+ *        padding outside extent.  0.05 would be 5% padding based on extent.
+ * tickVector {Array<Number>}
+ *        direction and length of tick marks.
+ * ticks {Number}
+ *        number of ticks to create.
+ * title {String}
+ *        axis title.
+ * titleAnchor {'start'|'middle'|'end'}
+ *        default 'middle'.
+ *        svg text-anchor property for title.
+ * titleDirection {Array<Number>}
+ *        default null.
+ *        rotate title to be parallel to this vector.
+ * titleVector {Array<Number>}
+ *        default Vector(tickVector).multiply(5).
+ *        direction and distance to title from center of axis extent.
+ */
+export class D33dAxis extends D33dGroup {
+  constructor(options?: D33dAxisOptions);
+
+  /**
+   * Free references.
+   */
+  destroy(): void;
+}
diff --git a/types/d3/3d/D33dCuboid.d.ts b/types/d3/3d/D33dCuboid.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2dfd8327321ddf1ec8b310527d054d2b6412d51f
--- /dev/null
+++ b/types/d3/3d/D33dCuboid.d.ts
@@ -0,0 +1,14 @@
+import { D33dGroup } from './D33dGroup';
+import { D33dCuboidOptions } from './D33dOptions';
+
+/**
+ * A 3d cuboid.
+ */
+export class D33dCuboid extends D33dGroup {
+  constructor(options?: D33dCuboidOptions);
+
+  /**
+   * Unbind listeners, free references.
+   */
+  destroy(): void;
+}
diff --git a/types/d3/3d/D33dGroup.d.ts b/types/d3/3d/D33dGroup.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a11bd698b56a5ab380560c26caba316f499d5ee9
--- /dev/null
+++ b/types/d3/3d/D33dGroup.d.ts
@@ -0,0 +1,32 @@
+import { D33dSubView } from '../view/D33dSubView';
+import { D33dView } from '../view/D33dView';
+import { D33dGroupOptions } from './D33dOptions';
+
+/**
+ * Text to be plotted at a point in the view.
+ *
+ * options {Object}
+ * options.className {String}
+ *        default 'D33dGroup'.
+ *        element class attribute value (may include spaces).
+ * options.coords {Array<Number>}
+ *        3d coordinates where text should be positioned.
+ * options.items {Array<Object>}
+ *        nested items.
+ */
+export class D33dGroup extends D33dSubView {
+  constructor(options?: D33dGroupOptions);
+
+  /**
+   * @return data for D33dView plotting.
+   */
+  getData(): {
+    el: SVGElement;
+    items: any[];
+  };
+
+  /**
+   * Render everything except position.
+   */
+  render(view: D33dView): void;
+}
diff --git a/types/d3/3d/D33dOptions.d.ts b/types/d3/3d/D33dOptions.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d980644eebd55887b62c40282c8ff9a9c90cce20
--- /dev/null
+++ b/types/d3/3d/D33dOptions.d.ts
@@ -0,0 +1,60 @@
+import { D3Options } from '../view/D3Options';
+
+export type Anchor = 'start' | 'middle' | 'end';
+
+export interface D3ViewOptions extends D3Options {
+  lookAt?: number[];
+  origin?: number[];
+  up?: number[];
+  zoom?: number;
+}
+
+export interface D33dSubViewOptions {
+  element?: string;
+  elementNamespace?: string;
+  id?: number;
+}
+
+export interface D33dPathOptions extends D33dSubViewOptions {
+  className?: string;
+  close?: boolean;
+  coords?: number[];
+}
+
+export interface D33dTextOptions extends D33dSubViewOptions {
+  className?: string;
+  coords?: number[];
+  direction?: number[];
+  text?: string;
+  textAnchor?: Anchor;
+}
+
+export interface D33dGroupOptions {
+  className?: string;
+  coords?: number[];
+  items?: object[];
+}
+
+export interface D33dAxisOptions extends D33dGroupOptions {
+  extent?: number[][];
+  format?: (coord: number[]) => {};
+  labelAnchor?: Anchor;
+  labelDirection?: number[];
+  labelVector?: number[];
+  padding?: number;
+  tickVector?: number[];
+  ticks?: number;
+  title?: string;
+  titleAnchor?: Anchor;
+  titleDirection?: number[];
+  titleVector?: number[];
+}
+
+export interface D33dCuboidOptions extends D33dGroupOptions {
+  x0: number;
+  x1: number;
+  y0: number;
+  y1: number;
+  z0: number;
+  z1: number;
+}
diff --git a/types/d3/3d/D33dPath.d.ts b/types/d3/3d/D33dPath.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c4d5f08ad7840ee3f1dac866f72749fca54a5f69
--- /dev/null
+++ b/types/d3/3d/D33dPath.d.ts
@@ -0,0 +1,23 @@
+import { D33dSubView } from '../view/D33dSubView';
+import { D33dPathOptions } from './D33dOptions';
+
+/**
+ * Class info and constructor parameters.
+ */
+export class D33dPath extends D33dSubView {
+  constructor(options?: D33dPathOptions);
+
+  /**
+   * @return data for D33dView plotting.
+   */
+  getData(): {
+    close: boolean;
+    coords: number[];
+    el: SVGElement;
+  };
+
+  /**
+   * Render everything except coordinates.
+   */
+  render(): void;
+}
diff --git a/types/d3/3d/D33dText.d.ts b/types/d3/3d/D33dText.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0e0e9e80541a0270a490f47f103bf68923375c30
--- /dev/null
+++ b/types/d3/3d/D33dText.d.ts
@@ -0,0 +1,40 @@
+import { D33dSubView } from '../view/D33dSubView';
+import { D33dTextOptions } from './D33dOptions';
+
+/**
+ * Text to be plotted at a point in the view.
+ *
+ * options {Object}
+ * options.className {String}
+ *        default 'D33dText'.
+ *        element class attribute value (may include spaces).
+ * options.coords {Array<Number>}
+ *        3d coordinates where text should be positioned.
+ * options.text {String}
+ *        text content.
+ * options.textAnchor {String}
+ *        default 'start'.
+ *        svg text anchor.
+ */
+export class D33dText extends D33dSubView {
+  constructor(options: D33dTextOptions);
+
+  /**
+   * Free references.
+   */
+  destroy(): void;
+
+  /**
+   * @return data for D33dView plotting.
+   */
+  getData(): {
+    coords: number[];
+    direction: number[];
+    el: SVGElement;
+  };
+
+  /**
+   * Render everything except position.
+   */
+  render(): void;
+}
diff --git a/types/d3/index.d.ts b/types/d3/index.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0bb4e56b5b88d87801ef45d5281f4544b6d81cb0
--- /dev/null
+++ b/types/d3/index.d.ts
@@ -0,0 +1,17 @@
+export * from './3d/D33dAxis';
+export * from './3d/D33dCuboid';
+export * from './3d/D33dGroup';
+export * from './3d/D33dOptions';
+export * from './3d/D33dPath';
+export * from './3d/D33dText';
+
+export * from './util/ClassList';
+export * from './util/D3Util';
+
+export * from './view/D33dSubView';
+export * from './view/D33dView';
+export * from './view/D3BaseView';
+export * from './view/D3Options';
+export * from './view/D3SubView';
+export * from './view/D3View';
+export * from './view/Info';
diff --git a/types/d3/util/ClassList.d.ts b/types/d3/util/ClassList.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e41996c923dcbe77c58a3d62474aabba7404e798
--- /dev/null
+++ b/types/d3/util/ClassList.d.ts
@@ -0,0 +1,53 @@
+/**
+ * Simulates a class list.
+ *
+ * If changes are made outside this object, resync using synchronize().
+ */
+export class ClassList {
+  constructor(el: HTMLElement);
+
+  /**
+   * Add a class.
+   *
+   * @param className
+   *        class to add.
+   */
+  add(className: string): void;
+
+  /**
+   * Check if element has a class.
+   *
+   * @param className
+   *        class to add.
+   * @return
+   *         true if element list includes class.
+   */
+  contains(className: string): boolean;
+
+  /**
+   * Access a class.
+   *
+   * @param pos
+   *        index in list [0,ClassList.length-1].
+   * @return className in list, or null if out of range.
+   */
+  item(pos: string): string;
+
+  /**
+   * Remove a class.
+   *
+   * @param className
+   *        class to remove.
+   */
+  remove(className: string): void;
+
+  /**
+   * Toggle a class.
+   *
+   * Add is not in list, otherwise remove.
+   *
+   * @param className
+   *        class to add.
+   */
+  toggle(className: string): void;
+}
diff --git a/types/d3/util/D3Util.d.ts b/types/d3/util/D3Util.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ab9815df50ff87e04e5259839fb6c51bfb1004b1
--- /dev/null
+++ b/types/d3/util/D3Util.d.ts
@@ -0,0 +1,54 @@
+export class D3Util {
+  /**
+   * Format text content.
+   *
+   * @param el
+   *        tooltip container element.
+   * @param data
+   *        data passed to showTooltip.
+   *        this implementation expects objects (or arrays of objects):
+   *        obj.class {String} class attribute for text|tspan.
+   *        obj.text {String} content for text|tspan.
+   */
+  static formatText(el: SVGElement, data: any): void;
+
+  /**
+   * Persistently tries to get the bounding box for the given element.
+   *
+   * @param element
+   *      The element for which to get the bounding box.
+   * @return
+   *      A bounding box object with x, y, width, height attributes
+   */
+  static getBBox(element: SVGTextElement): DOMRect;
+
+  /**
+   * Pad an extent.
+   *
+   * @param extent
+   *        first entry should be minimum.
+   *        last entry should be maximum.
+   * @param amount
+   *        percentage of range to pad.
+   *        For example: 0.05 = +/- 5% of range.
+   * @return
+   *         padded extent.
+   */
+  static padExtent(extent: number[], amount: number): number[];
+
+  /**
+   * Pad a log based extent.
+   *
+   * Similar to _padExtent(), but padding occurs in log space.
+   *
+   * @param extent
+   *        first entry should be minimum.
+   *        last entry should be maximum.
+   * @param amount
+   *        percentage of range to pad.
+   *        For example: 0.05 = +/- 5% of range.
+   * @return
+   *         padded extent.
+   */
+  static padLogExtent(extent: number[], amount: number): number;
+}
diff --git a/types/d3/view/D33dSubView.d.ts b/types/d3/view/D33dSubView.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6fad986437d0c29c454897395fd4566a1ae4289e
--- /dev/null
+++ b/types/d3/view/D33dSubView.d.ts
@@ -0,0 +1,74 @@
+import { D33dSubViewOptions } from '../3d/D33dOptions';
+
+/**
+ * Sub view for a D3 plot.
+ *
+ * Manages mouseover, mouseout, click events for view.
+ * mouseover and mouseout toggle a "mouseover" class on view.
+ * click triggers "click" event.
+ *
+ * When added to a D3BaseView, "click" event triggers "select" in collection.
+ * D3BaseView calls onSelect, onDeselect methods when collection selection
+ * changes.
+ *
+ * @param options
+ *        all options are passed to View.
+ */
+export class D33dSubView {
+  constructor(options?: D33dSubViewOptions);
+
+  /**
+   * Destroy view.
+   */
+  destroy(): void;
+
+  /**
+   * Click event handler.
+   */
+  onClick(): void;
+
+  /**
+   * Deselect event handler.
+   */
+  onDeselect(): void;
+
+  /**
+   * Mouseout event handler.
+   */
+  onMouseOut(): void;
+
+  /**
+   * Mouseover event handler.
+   */
+  onMouseOver(): void;
+
+  /**
+   * Select event handler.
+   */
+  onSelect(): void;
+
+  /**
+   * Get plotting data for D33dView.
+   *
+   * @return
+   *         el - view element
+   *         when el is a SVG "g" element
+   *             items {Array<Object>}
+   *                 items within group
+   *         when el is a SVG "text" element
+   *             coords {Array<Number>}
+   *                 coordinates for text anchor point.
+   *         when el is a SVG "path" element
+   *             close {Boolean}
+   *                 default true
+   *             coords {Array<Array<Number>>}
+   *                 array of path coordinates.
+   */
+  getData(): void;
+
+  /**
+   * Render sub view.
+   * Update all view attributes except coordinates (updated by D33dView).
+   */
+  render(): void;
+}
diff --git a/types/d3/view/D33dView.d.ts b/types/d3/view/D33dView.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e04af00f9e30f3d9bb08417fb094af2a8213284d
--- /dev/null
+++ b/types/d3/view/D33dView.d.ts
@@ -0,0 +1,58 @@
+import { Collection } from '../../mvc';
+import { D3ViewOptions } from '../3d/D33dOptions';
+import { D3BaseView } from './D3BaseView';
+import { Info } from './Info';
+
+/**
+ * Simulate a 3D view.
+ *
+ * Add objects to the D33dView.views collection to make them plot:
+ * - D33dGroup
+ *   - D33dAxis
+ *   - D33dCuboid
+ * - D33dPath
+ * - D33dText
+ *
+ * The properties lookAt, origin, up, and zoom, can be modified by updating the
+ * corresponding D33dView.model properties.
+ *
+ * options {Object}
+ * options.lookAt {Array<x, y, z>}
+ *        default [0, 0, 0].
+ *        where view looks at.
+ * options.origin {Array<x, y, z>}
+ *        default [100, 100, 100].
+ *        where view looks from.
+ * options.up {Array<x, y, z>}
+ *        default [0, 0, 1] (z-axis up).
+ *        up vector.
+ * options.zoom {Number}
+ *        default 10.
+ *        scaling factor for plot.
+ */
+export class D33dView extends D3BaseView {
+  views: Collection<D33dView>;
+
+  constructor(options?: D3ViewOptions);
+
+  /**
+   * Free references.
+   */
+  destroy(): void;
+
+  /**
+   * Project a single coordinate into the view x/y plane.
+   *
+   * @return projected coordinates.
+   *         z represents the distance from the camera plane to the object.
+   */
+  project(coord: number[]): number[];
+
+  /**
+   * Render all views.
+   *
+   * @param info
+   *        plot information.
+   */
+  renderViews(info: Info): void;
+}
diff --git a/types/d3/view/D3BaseView.d.ts b/types/d3/view/D3BaseView.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4812c513c42b0efab058309f4b90ae8eb1d2fa9d
--- /dev/null
+++ b/types/d3/view/D3BaseView.d.ts
@@ -0,0 +1,112 @@
+import { Collection, View } from '../../mvc';
+import { D3Options } from './D3Options';
+import { D3SubView } from './D3SubView';
+import { D3View } from './D3View';
+import { Info } from './Info';
+
+/**
+ * View for a D3 plot.
+ *
+ * @param options
+ *        options are passed to View.
+ */
+export class D3BaseView extends View<T> {
+  views: Collection<D3BaseView | D3View>;
+
+  constructor(options?: D3Options);
+
+  /**
+   * Destroy view.
+   */
+  destroy(): void;
+
+  /**
+   * Views collection add handler.
+   *
+   * @param views
+   *        views that were added.
+   */
+  onAdd(views: D3SubView[], dontrender: boolean): void;
+
+  /**
+   * Called when a view is clicked.
+   *
+   * @param view
+   *        view that was clicked.
+   */
+  onClick(view: D3SubView): void;
+
+  /**
+   * Views collection select handler.
+   *
+   * @param view
+   *        view that was selected.
+   */
+  onDeselect(view: D3SubView): void;
+  /**
+   * Views collection remove handler.
+   *
+   * @param views
+   *        views that were removed.
+   */
+  onRemove(views: D3SubView, dontrender: boolean): void;
+
+  /**
+   * Views collection reset handler.
+   */
+  onReset(): void;
+
+  /**
+   * Views collection select handler.
+   *
+   * @param view
+   *        view that was selected.
+   */
+  onSelect(view: D3BaseView): void;
+
+  /**
+   * Project data coordinates to plot coordinates.
+   *
+   * @param coords
+   *        data coordinate.
+   * @return
+   *         plot coordinate.
+   */
+  project(coords: number[]): number[];
+
+  /**
+   * Render view.
+   *
+   * @param changed
+   *        default is _this.model.get.
+   *        list of properties that have changed.
+   */
+  render(changed: object): void;
+
+  /**
+   * Re-render sub-views.
+   *
+   * @param info
+   *        plot information.
+   *
+   */
+  renderViews(info: Info): void;
+
+  /**
+   * Re-render legend.
+   *
+   * @param info
+   *        plot information.
+   */
+  renderLegend(info: Info): void;
+
+  /**
+   * Show a tooltip on the graph.
+   *
+   * @param coords
+   *        plot coordinates for origin of tooltip, should be pre-projected.
+   * @param data
+   *        tooltip content, passed to formatTooltip.
+   */
+  showTooltip(coords: number[], data: any[]): void;
+}
diff --git a/types/d3/view/D3Options.d.ts b/types/d3/view/D3Options.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8c40417a4902d49cc72b4f1c62931a951c1a9c4e
--- /dev/null
+++ b/types/d3/view/D3Options.d.ts
@@ -0,0 +1,41 @@
+import * as d3 from 'd3';
+import { D33dView } from './D33dView';
+import { D3BaseView } from './D3BaseView';
+import { D3View } from './D3View';
+
+export interface D3Options {
+  el?: SVGElement | HTMLElement;
+  legend?: SVGElement;
+  className?: string;
+  clickToSelect?: boolean;
+  height?: number;
+  label?: string;
+  legendPosition?: 'topright' | 'topleft' | 'bottomright' | 'bottomleft';
+  legendOffset?: number;
+  marginBottom?: number;
+  marginLeft?: number;
+  marginRight?: number;
+  marginTop?: number;
+  paddingBottom?: number;
+  paddingLeft?: number;
+  paddingRight?: number;
+  paddingTop?: number;
+  pointRadius?: number;
+  title?: string;
+  tooltipOffset?: number;
+  tooltipPadding?: number;
+  width?: number;
+  xAxisFormat?: () => {} | string;
+  xAxisPadding?: number;
+  xAxisScale?: d3.scale.Linear<number, number>;
+  xAxisTicks?: (extent: number[]) => {} | number[];
+  xExtent?: number[];
+  xLabel?: string;
+  yAxisFormat?: () => {} | string;
+  yAxisPadding?: number;
+  yAxisScale?: d3.scale.Linear<number, number>;
+  yAxisTicks?: (extent: number[]) => {} | number[];
+  yExtent?: number[];
+  yLabel?: string;
+  view?: D3View | D3BaseView | D33dView;
+}
diff --git a/types/d3/view/D3SubView.d.ts b/types/d3/view/D3SubView.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..70df0d4aee1b501953dfb56a703efdd7c22057c4
--- /dev/null
+++ b/types/d3/view/D3SubView.d.ts
@@ -0,0 +1,73 @@
+import { View } from '../../mvc/View';
+import { D3Options } from './D3Options';
+
+/**
+ * Sub view for a D3 plot.
+ *
+ * Manages mouseover, mouseout, click events for view.
+ * mouseover and mouseout toggle a "mouseover" class on view.
+ * click triggers "click" event.
+ *
+ * When added to a D3View, "click" event triggers "select" in collection.
+ * D3View calls onSelect, onDeselect methods when collection selection changes.
+ *
+ * Subclasses should override at least getXExtent(), getYExtent(), render(view).
+ *
+ * @param options
+ *        all options are passed to View.
+ */
+export class D3SubView extends View<T> {
+  constructor(options?: D3Options);
+
+  /**
+   * Destroy view.
+   */
+  destroy(): void;
+
+  /**
+   * X extent for view.
+   *
+   * @return
+   *         x extent for view.
+   */
+  getXExtent(): number[];
+
+  /**
+   * Y extent for view.
+   *
+   * @return
+   *         y extent for view.
+   */
+  getYExtent(): number[];
+
+  /**
+   * Click event handler.
+   */
+  onClick(): void;
+
+  /**
+   * Deselect event handler.
+   */
+  onDeselect(): void;
+
+  /**
+   * Mouseout event handler.
+   */
+  onMouseOut(): void;
+
+  /**
+   * Mouseover event handler.
+   */
+  onMouseOver(): void;
+
+  /**
+   * Select event handler.
+   */
+  onSelect(): void;
+
+  /**
+   * Render sub view.
+   * Element has already been attached to view.
+   */
+  render(): void;
+}
diff --git a/types/d3/view/D3View.d.ts b/types/d3/view/D3View.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ffb34e38be23a0977e6201cd98152544d1a23ab4
--- /dev/null
+++ b/types/d3/view/D3View.d.ts
@@ -0,0 +1,123 @@
+import { Collection } from '../../mvc';
+import { View } from '../../mvc/View';
+import { D3BaseView } from './D3BaseView';
+import { D3Options } from './D3Options';
+import { D3SubView } from './D3SubView';
+
+/**
+ * View for a D3 plot.
+ *
+ * @param options
+ *        options are passed to View.
+ */
+export class D3View extends View<T> {
+  views: Collection<D3View | D3BaseView>;
+
+  constructor(options?: D3Options);
+
+  /**
+   * Destroy view.
+   */
+  destroy(): void;
+
+  /**
+   * Views collection add handler.
+   *
+   * @param views
+   *        views that were added.
+   */
+  onAdd(views: D3SubView[], dontrender: boolean): void;
+
+  /**
+   * Called when a view is clicked.
+   *
+   * @param view
+   *        view that was clicked.
+   */
+  onClick(view: D3SubView): void;
+
+  /**
+   * Views collection select handler.
+   *
+   * @param view
+   *        view that was selected.
+   */
+  onDeselect(view: D3SubView): void;
+
+  /**
+   * Views collection remove handler.
+   *
+   * @param views
+   *        views that were removed.
+   */
+  onRemove(views: D3SubView[], dontrender: boolean): void;
+
+  /**
+   * Views collection reset handler.
+   */
+  onReset(): void;
+
+  /**
+   * Views collection select handler.
+   *
+   * @param view
+   *        view that was selected.
+   */
+  onSelect(view: D3SubView): void;
+
+  /**
+   * Render view.
+   *
+   * @param changed
+   *        default is _this.model.get.
+   *        list of properties that have changed.
+   */
+  render(changed: object): void;
+
+  /**
+   * Re-render sub-views.
+   */
+  renderViews(): void;
+
+  /**
+   * Get the plot x extent, including padding.
+   *
+   * @return x extents.
+   */
+  getPlotXExtent(xExtent: number[]): number[];
+
+  /**
+   * Get the plot y extent, including padding.
+   *
+   * @param xExtent
+   *        xExtent is passed to _this.getYExtent().
+   * @return y extents.
+   */
+  getPlotYExtent(xExtent: number[]): number[];
+
+  /**
+   * Get the data x extent.
+   *
+   * @return x extents.
+   */
+  getXExtent(): number[];
+
+  /**
+   * Get the data y extent, including padding.
+   *
+   * @param xExtent
+   *        x extent, in case y extent is filtered based on x extent.
+   * @return x extents.
+   */
+  getYExtent(): number[];
+
+  /**
+   * Show a tooltip on the graph.
+   *
+   * @param coords
+   *        coordinate for origin of tooltip.
+   * @param data
+   *        tooltip content, passed to formatTooltip.
+   */
+  showTooltip(coords: number[], data: any[]): void;
+}
diff --git a/types/d3/view/Info.d.ts b/types/d3/view/Info.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b53b4c15f513a4759c43053cb7c273a9a2081932
--- /dev/null
+++ b/types/d3/view/Info.d.ts
@@ -0,0 +1,12 @@
+export interface Info {
+  el?: SVGElement;
+  height?: number;
+  innerHeight?: number;
+  innerWidth?: number;
+  marginBottom?: number;
+  marginLeft?: number;
+  marginRight?: number;
+  marginTop?: number;
+  outerHeight?: number;
+  outerWidth?: number;
+}
diff --git a/types/disagg/D33dDeaggregationBin.d.ts b/types/disagg/D33dDeaggregationBin.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..121e8db54ddfa931e78b8cb1a0a4e9c5de7d17db
--- /dev/null
+++ b/types/disagg/D33dDeaggregationBin.d.ts
@@ -0,0 +1,13 @@
+import { DisaggBinOptions } from './DisaggBinOptions';
+
+/**
+ * Represents one vertical bar on a deaggregation plot.
+ */
+export class D33dDeaggregationBin {
+  constructor(options?: DisaggBinOptions);
+
+  /**
+   * Create all epsilon bins within this magnitude/distance bin.
+   */
+  createEpsilonCuboids(options: DisaggBinOptions): void;
+}
diff --git a/types/disagg/DeaggResponse.d.ts b/types/disagg/DeaggResponse.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c86579f1fe9583cd24446a84f1cb686264f14ed1
--- /dev/null
+++ b/types/disagg/DeaggResponse.d.ts
@@ -0,0 +1,14 @@
+import { DeaggResponseData } from '@nshmp/nshmp-utils/nshmp';
+import { Model } from '../mvc/Model';
+
+/**
+ * Class: DeaggResponse
+ *
+ * @param params
+ *      Configuration options. See _DEFAULTS for more details.
+ */
+export class DeaggResponse extends Model<DeaggResponseData> {
+  constructor(params: DeaggResponseData);
+
+  destroy(): void;
+}
diff --git a/types/disagg/Deaggregation.d.ts b/types/disagg/Deaggregation.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b7b7003d90295ce76be1df78262c18a1d57c53a1
--- /dev/null
+++ b/types/disagg/Deaggregation.d.ts
@@ -0,0 +1,5 @@
+import { DisaggParameters } from './DisaggParameters';
+
+export class Deaggregation {
+  constructor(params: DisaggParameters);
+}
diff --git a/types/disagg/DeaggregationGraphView.d.ts b/types/disagg/DeaggregationGraphView.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a9458f1a2f2c640fa37bcce28fd2da4a735986a9
--- /dev/null
+++ b/types/disagg/DeaggregationGraphView.d.ts
@@ -0,0 +1,109 @@
+import { Info } from '../d3/view/Info';
+import { SelectedCollectionView } from '../mvc/SelectedCollectionView';
+import { DisaggBin } from './DisaggBinOptions';
+import { DisaggGraphViewOptions } from './DisaggGraphViewOptions';
+
+/**
+ * A deaggregation distance/magnitude plot.
+ */
+export class DeaggregationGraphView extends SelectedCollectionView<DisaggGraphViewOptions> {
+  constructor(options: DisaggGraphViewOptions);
+
+  /**
+   * Calculate deaggregation data bounds.
+   *
+   * @param bindata
+   *     array of deaggregation bins
+   *     where Bin is an Object:
+   *       bin.r
+   *             distance to bin (x-axis)
+   *       bin.m
+   *             magnitude of bin (y-axis)
+   *       bin.εdata
+   *             array of epsilon data for bin (z-axis)
+   *             Each Object has properties:
+   *               εdata.value {Number}
+   *                           % contribution to hazard
+   *               εdata.εbin {Number}
+   *                          id of epsilon bin.
+   *
+   * @return
+   *         bounds of deaggregation data.
+   *         Array contains two sub arrays,
+   *         containing minimum and maximum values for each axis.
+   */
+  calculateBounds(bindata: DisaggBin[]): number[][];
+
+  /**
+   * Use data extents to set view lookAt, origin, and zoom so plot is
+   * roughly centered within view plot area.
+   */
+  centerView(): void;
+
+  /**
+   * Create axes to be plotted.
+   *
+   * TODO: eliminate "magic" numbers.
+   * Extents and tick, label, and title, vectors arre hard coded and work for
+   * the current lookAt, origin, and zoom, combination.
+   */
+  createAxes(): void;
+
+  /**
+   * Format x-axis {distance} labels.
+   *
+   * @param c
+   *        tick coordinate.
+   * @return
+   *         formatted coordinate.
+   */
+  formatX(c: number[]): string;
+
+  /**
+   * Format y-axis (magnitude) labels.
+   *
+   * @param c
+   *        tick coordinate.
+   * @return
+   *         formatted coordinate.
+   */
+  formatY(c: number[]): string;
+
+  /**
+   * Format z-axis (percent contribution) labels.
+   *
+   * @param c
+   *        tick coordinate.
+   * @return
+   *         formatted coordinate.
+   */
+  formatZ(c: number[]): string;
+
+  /**
+   * Get data bounds for plotting.
+   *
+   * @return
+   *         bounds of deaggregation data.
+   *         Array contains two sub arrays,
+   *         containing minimum and maximum values for each axis.
+   */
+  getBounds(): number[][];
+
+  /**
+   * Update displayed data.
+   *
+   * When a model is selected, bins are plotted on the graph.
+   * Otherwise, any existing bins are destroyed and removed from the graph.
+   */
+  render(): void;
+
+  /**
+   * Custom legend rendering function for wrapped D33dView.
+   *
+   * @param info
+   *        rendering information.
+   * @param info.el
+   *        element where legend should be rendered.
+   */
+  renderLegend(info: Info): void;
+}
diff --git a/types/disagg/DisaggBinOptions.d.ts b/types/disagg/DisaggBinOptions.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f5c550f65fb8cbae3b2d4a3c3932be813af16a86
--- /dev/null
+++ b/types/disagg/DisaggBinOptions.d.ts
@@ -0,0 +1,39 @@
+export interface DisaggBinOptions {
+  /** one magnitude/distance bin object */
+  bin: DisaggBin;
+
+  /**
+   * Size of bin around distance/magnitude point on graph
+   * Default: 1.
+   */
+  size: number;
+
+  /**
+   * Multiplier for raw x values.
+   * Default: 1
+   */
+  xScale: number;
+
+  /**
+   * Multiplier for raw y values.
+   * Default: 1
+   */
+  yScale: number;
+
+  /**
+   * Multiplier for raw z values.
+   * Default: 1
+   */
+  zScale: number;
+}
+
+export interface DisaggBin {
+  /** Magnitude */
+  m: number;
+
+  /** Distance */
+  r: number;
+
+  /** epsilon bin percent contributions */
+  εdata: object[];
+}
diff --git a/types/disagg/DisaggGraphViewOptions.d.ts b/types/disagg/DisaggGraphViewOptions.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..16df4c05b2b6d80432c085cd90ac476bec757aed
--- /dev/null
+++ b/types/disagg/DisaggGraphViewOptions.d.ts
@@ -0,0 +1,17 @@
+import { Collection, SelectedCollectionViewOptions } from '../mvc';
+import { Deaggregation } from './Deaggregation';
+
+export interface DisaggGraphViewOptions extends SelectedCollectionViewOptions<Deaggregation> {
+  /**
+   * Default null.
+   * Plotting bounds.
+   * Can be changed later by setting VIEW.bounds and calling VIEW.render
+   */
+  bounds?: number[][];
+
+  /**
+   * Collection with data to display.
+   * Selected Deaggregation object is displayed.
+   */
+  collection: Collection<Deaggregation>;
+}
diff --git a/types/disagg/DisaggParameters.d.ts b/types/disagg/DisaggParameters.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..21dd5fd5aa09e4dca0dc207f173fccc598a1402a
--- /dev/null
+++ b/types/disagg/DisaggParameters.d.ts
@@ -0,0 +1,9 @@
+import { DisaggBin } from './DisaggBinOptions';
+
+export interface DisaggParameters {
+  /** GMPE Name or "Total" */
+  component: string;
+
+  /** Hazard contirbution bins */
+  data: DisaggBin[];
+}
diff --git a/types/disagg/index.d.ts b/types/disagg/index.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d8ebcf80bec256c65fe41151797ac9f4a7a54ede
--- /dev/null
+++ b/types/disagg/index.d.ts
@@ -0,0 +1,7 @@
+export * from './D33dDeaggregationBin';
+export * from './DeaggResponse';
+export * from './Deaggregation';
+export * from './DeaggregationGraphView';
+export * from './DisaggBinOptions';
+export * from './DisaggGraphViewOptions';
+export * from './DisaggParameters';
diff --git a/types/math/Camera.d.ts b/types/math/Camera.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a0c02c403a57b0fc4451268c3a285f6caed60b5e
--- /dev/null
+++ b/types/math/Camera.d.ts
@@ -0,0 +1,24 @@
+import { CameraOptions } from './';
+
+/**
+ * Camera defines a coordinate translation from World coordinates (X, Y, Z)
+ * to Camera coordinates (x, y, z).
+ *
+ * After projection:
+ *     +z is to lookAt from camera
+ *     +x is right from camera
+ *     +y is up from camera
+ */
+export class Camera {
+  constructor(options: CameraOptions);
+
+  /**
+   * Project a point from world coordinates to camera coordinates.
+   *
+   * @param world
+   *        x, y, z world coordinates.
+   * @return
+   *        x, y, z, camera coordinates.
+   */
+  project(world: number[]): number[];
+}
diff --git a/types/math/CameraOptions.d.ts b/types/math/CameraOptions.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7948435ce72c2c8fa6e811f394a622f6f2f6ddc4
--- /dev/null
+++ b/types/math/CameraOptions.d.ts
@@ -0,0 +1,18 @@
+/**
+ * origin:
+ *        default [100, 100, 100].
+ *        position of camera in world coordinates.
+ *
+ * lookAt:
+ *        default [0, 0, 0].
+ *        position for camera to look at in world coordinates.
+ *
+ * up:
+ *        default [0, 0, 1].
+ *        vector pointing up in world coordinates.
+ */
+export interface CameraOptions {
+  origin: number[];
+  lookAt: number[];
+  up: number;
+}
diff --git a/types/math/Matrix.d.ts b/types/math/Matrix.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fd70b87aa10b1ceea0614acc555ffda739003b35
--- /dev/null
+++ b/types/math/Matrix.d.ts
@@ -0,0 +1,338 @@
+import { Vector } from './';
+
+/**
+ * Construct a new Matrix object.
+ *
+ * If m and n are omitted, Matrix is assumed to be square and
+ * data length is used to compute size.
+ *
+ * If m or n are omitted, data length is used to compute omitted value.
+ *
+ * @param data
+ *        matrix data.
+ * @param m
+ *        number of rows.
+ * @param n
+ *        number of columns.
+ */
+export class Matrix {
+  constructor(data: number[], m: number, n: number);
+
+  /**
+   * Extract a column from this matrix.
+   *
+   * @param data
+   *        matrix data.
+   * @param m
+   *        number of rows.
+   * @param n
+   *        number of columns.
+   * @param col
+   *        index of column, in range [0,n)
+   * @throws Error if column out of range.
+   * @return column elements.
+   */
+  static col(data: number[], m: number, n: number, col: number): number[];
+
+  /**
+   * Get array of elements on the diagonal.
+   *
+   * @param data
+   *        matrix data.
+   * @param m
+   *        number of rows.
+   * @param n
+   *        number of columns.
+   * @return elements on the diagonal.
+   */
+  static diagonal(data: number[], m: number, n: number): number[];
+
+  /**
+   * Get the value of an element of this matrix.
+   *
+   * @param data
+   *        matrix data.
+   * @param m
+   *        number of rows.
+   * @param n
+   *        number of columns.
+   * @param row
+   *        row of element, in range [0,m)
+   * @param col
+   *        column of element, in range [0,n)
+   * @throws Error if row or col are out of range.
+   * @return value.
+   */
+  static get(data: number[], m: number, n: number, row: number, col: number): number;
+
+  /**
+   * Create an identity Matrix.
+   *
+   * @param n
+   *        number of rows and columns.
+   * @return identity matrix of size n.
+   */
+  static identity(n: number): number[];
+
+  /**
+   * Get the index of an element of this matrix.
+   *
+   * @param data
+   *        matrix data.
+   * @param m
+   *        number of rows.
+   * @param n
+   *        number of columns.
+   * @param row
+   *        row of element, in range [0,m)
+   * @param col
+   *        column of element, in range [0,n)
+   * @return index.
+   */
+  static index(data: number[], m: number, n: number, row: number, col: number): number;
+
+  /**
+   * Jacobi eigenvalue algorithm.
+   *
+   * Ported from:
+   *     http://users-phys.au.dk/fedorov/nucltheo/Numeric/now/eigen.pdf
+   *
+   * An iterative method for eigenvalues and eigenvectors,
+   * only works on symmetric matrices.
+   *
+   * @param data
+   *        matrix data.
+   * @param m
+   *        number of rows.
+   * @param n
+   *        number of columns.
+   * @param maxRotations
+   *        maximum number of rotations.
+   *        Optional, default 100.
+   * @return array of eigenvectors, magnitude is eigenvalue.
+   */
+  static jacobi(data: number[], m: number, n: number, maxRotations: number): Vector[];
+
+  /**
+   * Multiply this matrix by another matrix.
+   *
+   * @param data1
+   *        first matrix data.
+   * @param m1
+   *        number of rows in first matrix.
+   * @param n1
+   *        number of columns in first matrix.
+   * @param data2
+   *        second matrix data.
+   * @param m2
+   *        number of rows in second matrix.
+   * @param n2
+   *        number of columns in second matrix.
+   * @throws Error if n1 !== m2
+   * @return result of multiplication (original matrix is unchanged).
+   */
+  static multiply(
+    data1: number[],
+    m1: number,
+    n1: number,
+    data2: number[],
+    m2: number,
+    n2: number
+  ): number[];
+
+  /**
+   * Extract a row from this matrix.
+   *
+   * @param data
+   *        matrix data.
+   * @param m
+   *        number of rows.
+   * @param n
+   *        number of columns.
+   * @param row
+   *        index of row, in range [0,m)
+   * @throws Error if row out of range.
+   * @return row elements.
+   */
+  static row(data: number[], m: number, n: number, row: number): number[];
+
+  /**
+   * Set the value of an element of this matrix.
+   *
+   * NOTE: this method modifies the contents of this matrix.
+   *
+   * @param data
+   *        matrix data.
+   * @param m
+   *        number of rows.
+   * @param n
+   *        number of columns.
+   * @param row
+   *        row of element, in range [0,m)
+   * @param col
+   *        column of element, in range [0,n)
+   * @param value
+   *        value to set.
+   * @throws Error if row or col are out of range.
+   */
+  static set(data: number[], m: number, n: number, row: number, col: number, value: number): void;
+
+  /**
+   * Display matrix as a string.
+   *
+   * @param data
+   *        matrix data.
+   * @param m
+   *        number of rows.
+   * @param n
+   *        number of columns.
+   * @return formatted matrix.
+   */
+  static stringify(data: number[], m: number, n: number): string;
+
+  /**
+   * Transpose this matrix.
+   *
+   * @param data
+   *        matrix data.
+   * @param m
+   *        number of rows.
+   * @param n
+   *        number of columns.
+   * @return transposed matrix (original matrix is unchanged).
+   */
+  static transpose(data: number[], m: number, n: number): number[];
+
+  /**
+   * Add matrices.
+   *
+   * @param that
+   *        matrix to add.
+   * @throws Error if dimensions do not match.
+   * @return result of addition (original matrix is unchanged).
+   */
+  add(that: Matrix): Matrix;
+
+  /**
+   * Get a column from this matrix.
+   *
+   * @param col
+   *        zero-based column index.
+   * @return array containing elements from column.
+   */
+  col(col: number): number[];
+
+  /**
+   * Access the wrapped array.
+   */
+  data(): number[][];
+
+  /**
+   * Get the diagonal from this matrix.
+   *
+   * @return array containing elements from diagonal.
+   */
+  diagonal(): number[];
+
+  /**
+   * Get a value from this matrix.
+   *
+   * @param row
+   *        zero-based index of row.
+   * @param col
+   *        zero-based index of column.
+   * @return value at (row, col).
+   */
+  get(row: number, col: number): number;
+
+  /**
+   * Compute the eigenvectors of this matrix.
+   *
+   * NOTE: Matrix should be 3x3 and symmetric.
+   *
+   * @param maxRotations
+   *        default 100.
+   *        maximum number of iterations.
+   * @return eigenvectors.
+   *         Magnitude of each vector is eigenvalue.
+   */
+  jacobi(maxRotations: number): Vector[];
+
+  /**
+   * Get the number of rows in matrix.
+   *
+   * @return
+   *         number of rows.
+   */
+  m(): number;
+
+  /**
+   * Multiply matrices.
+   *
+   * @param that
+   *        matrix to multiply.
+   * @return result of multiplication.
+   */
+  multiply(that: Matrix): Matrix;
+
+  /**
+   * Get number of columns in matrix.
+   *
+   * @return number of columns.
+   */
+  n(): number;
+
+  /**
+   * Multiply each element by -1.
+   *
+   * @return result of negation.
+   */
+  negative(): Matrix;
+
+  /**
+   * Get a row from this matrix.
+   *
+   * @param row
+   *        zero-based index of row.
+   * @return elements from row.
+   */
+  row(row: number): number[];
+
+  /**
+   * Set a value in this matrix.
+   *
+   * @param row
+   *        zero-based row index.
+   * @param col
+   *        zero-based column index.
+   * @param value
+   *        value to set.
+   */
+  set(row: number, col: number, value: number): void;
+
+  /**
+   * Subtract another matrix from this matrix.
+   *
+   * @param that
+   *        matrix to subtract.
+   * @throws Error if dimensions do not match.
+   * @return result of subtraction (original matrix is unchanged).
+   */
+  subtract(that: Matrix): Matrix;
+
+  /**
+   * Display matrix as a string.
+   *
+   * @return formatted matrix.
+   */
+  toString(): string;
+
+  /**
+   * Transpose matrix.
+   *
+   * Columns become rows, and rows become columns.
+   *
+   * @return result of transpose.
+   */
+  transpose(): Matrix;
+}
diff --git a/types/math/Vector.d.ts b/types/math/Vector.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4340e007660e09f0d4a4639ab03508ed79df6a6c
--- /dev/null
+++ b/types/math/Vector.d.ts
@@ -0,0 +1,363 @@
+/**
+ * A vector object that wraps an array.
+ *
+ * This is a convenience object to call the static methods on the wrapped array.
+ * Only the methods x(), y(), and z() modify data; other methods return new
+ * Vector objects without modifying the existing object.
+ *
+ * @param data
+ *        array to wrap.
+ */
+export class Vector {
+  constructor(data: number[]);
+
+  /**
+   * Add two vectors.
+   *
+   * @param v1
+   *        the first vector.
+   * @param v2
+   *        the second vector.
+   * @return
+   *         result of addition.
+   * @throws when vectors are different lengths.
+   */
+  static add(v1: number[], v2: number[]): number[];
+
+  /**
+   * Compute the angle between two vectors.
+   *
+   * @param v1
+   *        the first vector.
+   * @param v2
+   *        the second vector.
+   * @return
+   *         angle between vectors in radians.
+   */
+  static angle(v1: number[], v2: number[]): number;
+
+  /**
+   * Compute the azimuth of a vector.
+   *
+   * @param v1
+   *        the first vector.
+   * @param v2
+   *        the second vector.
+   * @return
+   *         angle between vectors in radians.
+   */
+  static azimuth(v1: number[]): number;
+
+  /**
+   * Compute vector cross product.
+   *
+   * Note: only computes cross product in 3 dimensions.
+   *
+   * @param v1
+   *        the first vector.
+   * @param v2
+   *        the second vector.
+   * @return
+   *         the 3 dimensional cross product.
+   *         the resulting vector follows the right-hand rule: if the fingers on
+   *         your right hand point to v1, and you close your hand to get to v2,
+   *         the resulting vector points in the direction of your thumb.
+   */
+  static cross(v1: number[], v2: number[]): number[];
+
+  /**
+   * Compute vector dot product.
+   *
+   * @param v1
+   *        the first vector.
+   * @param v2
+   *        the second vector.
+   * @return
+   *         the dot product.
+   */
+  static dot(v1: number[], v2: number[]): number;
+
+  /**
+   * Check if two vectors are equal.
+   *
+   * @param v1
+   *        the first vector.
+   * @param v2
+   *        the second vector.
+   * @return
+   *         true if vectors are same length and all elements are equal.
+   */
+  static equals(v1: number[], v2: number[]): boolean;
+
+  /**
+   * Compute length of vector.
+   *
+   * @param v1
+   *        vector.
+   * @return
+   *         magnitude of vector.
+   */
+  static magnitude(v1: number[]): number;
+
+  /**
+   * Multiply vector by a constant.
+   *
+   * @param v1
+   *        vector to multiply.
+   * @param n
+   *        number to multiply by.
+   * @return
+   *         result of multiplication.
+   */
+  static multiply(v1: number[], n: number): number[];
+
+  /**
+   * Compute angle from plane z=0 to vector.
+   *
+   * @param v
+   *        the vector.
+   * @return
+   *         angle from plane z=0 to vector.
+   *         angle is positive when z > 0, negative when z < 0.
+   */
+  static plunge(v: number[]): number;
+
+  /**
+   * Rotate a vector around an axis.
+   *
+   * From "6.2 The normalized matrix for rotation about an arbitrary line",
+   *      http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/
+   *
+   * @param v1
+   *        the "point" to rotate.
+   * @param axis
+   *        direction vector of rotation axis.
+   * @param theta
+   *        angle of rotation in radians.
+   * @param origin
+   *        default [0, 0, 0].
+   *        origin of axis of rotation.
+   */
+  static rotate(v1: number[], axis: number[], theta: number, origin: number[]): number[];
+
+  /**
+   * Subtract two vectors.
+   *
+   * @param v1
+   *        the first vector.
+   * @param v2
+   *        the vector to subtract.
+   * @return
+   *         result of subtraction.
+   * @throws {Error} when vectors are different lengths.
+   */
+  static subtract(v1: number[], v2: number): number[];
+
+  /**
+   * Convert vector to length 1.
+   *
+   * Same as __multiply(v1, 1 / __magnitude(v1))
+   *
+   * @param v1
+   *        the vector.
+   * @return
+   *         vector converted to length 1.
+   * @throws {Error} if vector magnitude is 0.
+   */
+  static unit(v1: number[]): number[];
+
+  /**
+   * Get, and optionally set, the x component of a vector.
+   *
+   * @param v
+   *        the vector.
+   * @param value
+   *        default undefined.
+   *        when defined, set x component.
+   * @return
+   *         the x component.
+   */
+  static x(v: number[], value: number): number;
+
+  /**
+   * Get, and optionally set, the y component of a vector.
+   *
+   * @param v
+   *        the vector.
+   * @param value
+   *        default undefined.
+   *        when defined, set y component.
+   * @return
+   *         the y component.
+   */
+  static y(v: number[], value: number): number;
+
+  /**
+   * Get, and optionally set, the z component of a vector.
+   *
+   * @param v
+   *        the vector.
+   * @param value
+   *        default undefined.
+   *        when defined, set z component.
+   * @return
+   *         the z component.
+   */
+  static z(v: number[], value: number): number;
+
+  /**
+   * Add two vectors.
+   *
+   * @param that
+   *        vector to add.
+   * @return
+   *         result of addition.
+   */
+  add(that: Vector | number[]): Vector;
+
+  /**
+   * Compute angle between vectors.
+   *
+   * @param that
+   *        vector to compute angle between.
+   * @return angle between vectors in radians.
+   */
+  angle(that: Vector | number[]): number;
+
+  /**
+   * Compute azimuth of this vector.
+   *
+   * @return azimuth of this vector in radians.
+   */
+  azimuth(): number;
+
+  /**
+   * Compute the cross product between vectors.
+   *
+   * @param that
+   *        the vector to cross.
+   * @return result of the cross product.
+   */
+  cross(that: Vector | number[]): Vector;
+
+  /**
+   * Access the wrapped array.
+   *
+   * @return
+   *         the wrapped array.
+   */
+  data(): number[];
+
+  /**
+   * Compute dot product between vectors.
+   *
+   * @param that
+   *        vector to dot.
+   * @return result of dot product.
+   */
+  dot(that: Vector | number[]): number;
+
+  /**
+   * Check if two vectors are equal.
+   *
+   * @param that
+   *        vector to compare.
+   * @return true if equal, false otherwise.
+   */
+  equals(that: Vector | number[]): boolean;
+
+  /**
+   * Compute length of this vector.
+   *
+   * @return length of vector.
+   *         Square root of the sum of squares of all components.
+   */
+  magnitude(): number;
+
+  /**
+   * Multiply this vector by a number.
+   *
+   * @param n
+   *        number to multiply.
+   * @return result of multiplication.
+   */
+  multiply(n: number): Vector;
+
+  /**
+   * Same as multiply(-1).
+   */
+  negative(): Vector;
+
+  /**
+   * Compute plunge of this vector.
+   *
+   * Plunge is the angle between this vector and the plane z=0.
+   *
+   * @return plunge in radians.
+   *         positive when z>0, negative when z<0.
+   */
+  plunge(): number;
+
+  /**
+   * Rotate this vector around an arbitrary axis.
+   *
+   * @param axis
+   *        direction of axis of rotation.
+   * @param theta
+   *        angle of rotation in radians.
+   * @param origin
+   *        origin of axis of rotation.
+   * @return result of rotation.
+   */
+  rotate(axis: Vector | number[], theta: number, origin: Vector | number[]): Vector;
+
+  /**
+   * Subtract another vector.
+   *
+   * @param that
+   *        vector to subtract.
+   * @return result of subtraction.
+   */
+  subtract(that: Vector | number[]): Vector;
+
+  /**
+   * Convert vector to string.
+   *
+   * @return wrapped array converted to string.
+   */
+  toString(): string;
+
+  /**
+   * Convert this vector to length 1.
+   *
+   * @return vector / |vector|.
+   */
+  unit(): Vector;
+
+  /**
+   * Get or set x component.
+   *
+   * @param value
+   *        when defined, set x component to value.
+   * @return x component value.
+   */
+  x(value: number): number;
+
+  /**
+   * Get or set y component.
+   *
+   * @param value
+   *        when defined, set y component to value.
+   * @return y component value.
+   */
+  y(value: number): number;
+
+  /**
+   * Get or set z component.
+   *
+   * @param value
+   *        when defined, set z component to value.
+   * @return z component value.
+   */
+  z(value: number): number;
+}
diff --git a/types/math/index.d.ts b/types/math/index.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..25f2b71025427667592b7f147a5d6a1d27777ae0
--- /dev/null
+++ b/types/math/index.d.ts
@@ -0,0 +1,4 @@
+export * from './Camera';
+export * from './CameraOptions';
+export * from './Matrix';
+export * from './Vector';
diff --git a/types/mvc/Collection.d.ts b/types/mvc/Collection.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7f71722696944ec8b4d26b232bb7d9784a745fc3
--- /dev/null
+++ b/types/mvc/Collection.d.ts
@@ -0,0 +1,143 @@
+import { Events } from '../util/Events';
+import { CollectionOptions } from './';
+
+/**
+ * Create a new Collection.
+ */
+export class Collection<T> extends Events {
+  constructor(data: T[]);
+
+  /**
+   * Add objects to the collection.
+   *
+   * Calls wrapped array.push, and clears the id cache.
+   *
+   * @param
+   *      a variable number of objects to append to the collection.
+   * @deprecated see #addAll()
+   */
+  add(...object: T[]): void;
+
+  /**
+   * Add objects to the collection.
+   *
+   * Calls wrapped array.push, and clears the id cache.
+   *
+   * @param toadd
+   *        objects to be added to the collection.
+   */
+  addAll(toadd: T[], options?: CollectionOptions): void;
+
+  /**
+   * Get the wrapped array.
+   *
+   * @return
+   *      the wrapped array.
+   */
+  data(): T[];
+
+  /**
+   * Deselect current selection.
+   */
+  deselect(options: CollectionOptions): void;
+
+  /**
+   * Free the array and id cache.
+   *
+   * @param options
+   *        passed to #deselect().
+   */
+  destroy(options: CollectionOptions): void;
+
+  /**
+   * Get an object in the collection by ID.
+   *
+   * Uses getIds(), so builds map of ID to INDEX on first access O(N).
+   * Subsequent access should be O(1).
+   *
+   * @param id
+   *      if the collection contains more than one object with the same id,
+   *      the last element with that id is returned.
+   */
+  get<V>(id: V): T;
+
+  /**
+   * Get a map from ID to INDEX.
+   *
+   * @param force
+   *      rebuild the map even if it exists.
+   */
+  getIds<V>(force: boolean): V[];
+
+  /**
+   * Get the currently selected object.
+   */
+  getSelected(): T;
+
+  /**
+   * Remove objects from the collection.
+   *
+   * This method calls array.splice to remove item from array.
+   * Reset would be faster if modifying large chunks of the array.
+   *
+   * @param o
+   *      object to remove.
+   * @deprecated see #removeAll()
+   */
+  remove(...o: T[]): void;
+
+  /**
+   * Remove objects from the collection.
+   *
+   * Reset is faster if modifying large chunks of the array.
+   *
+   * @param toremove
+   *        objects to remove.
+   * @param options
+   *        default false.
+   *        whether to trigger events (false), or not (true).
+   */
+  removeAll(toremove: T[], options?: CollectionOptions): void;
+
+  /**
+   * Replace the wrapped array with a new one.
+   */
+  reset(data: T[], options?: CollectionOptions): void;
+
+  /**
+   * Select an object in the collection.
+   *
+   * @param obj
+   *      object in the collection to select.
+   * @throws exception
+   *      if obj not in collection.
+   */
+  select(obj: T, options?: CollectionOptions): void;
+
+  /**
+   * Utility method to select collection item using its id.
+   *
+   * Selects matching item if it exists, otherwise clears any selection.
+   *
+   * @param id
+   *        id of item to select.
+   * @param options
+   *        options passed to #select() or #deselect().
+   */
+  selectById<V>(id: V, options?: CollectionOptions): T;
+
+  /**
+   * Sorts the data.
+   *
+   * @param method
+   *        javascript sort method.
+   * @param options
+   *        passed to #reset()
+   */
+  sort(method: () => {}, options?: CollectionOptions): void;
+
+  /**
+   * Override toJSON method to serialize only collection data.
+   */
+  toJSON(): T[];
+}
diff --git a/types/mvc/Column.d.ts b/types/mvc/Column.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4d9da0aca169aba967b953dabd6598584df77105
--- /dev/null
+++ b/types/mvc/Column.d.ts
@@ -0,0 +1,4 @@
+export interface Column {
+  downloadFormat: (object: any) => {};
+  downloadTitle: string;
+}
diff --git a/types/mvc/Model.d.ts b/types/mvc/Model.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..62a84070f0f28959eeba110c364beaf8984c2080
--- /dev/null
+++ b/types/mvc/Model.d.ts
@@ -0,0 +1,42 @@
+import { Events } from '../util';
+import { ModelOptions } from './';
+
+/**
+ * Constructor
+ *
+ */
+export class Model<T> extends Events {
+  /**
+   * @param data
+   *      key/value attributes of this model.
+   */
+  constructor(data: T);
+
+  /**
+   * Get one or more values.
+   *
+   * @param key
+   *      the value to get; when key is undefined, returns the object with all
+   *      values.
+   * @return
+   *      - if key is specified, the value or null if no value exists.
+   *      - when key is not specified, the underlying object is returned.
+   *        (Any changes to this underlying object will not trigger events!!!)
+   */
+  get<V>(key: string): V;
+
+  /**
+   * Update one or more values.
+   *
+   * @param data
+   *      the keys and values to update.
+   * @param options
+   *      options for this method.
+   */
+  set(data: T, options: ModelOptions): void;
+
+  /**
+   * Override toJSON method to serialize only model data.
+   */
+  toJSON(): T;
+}
diff --git a/types/mvc/MvcOptions.d.ts b/types/mvc/MvcOptions.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f929047a70e0a570be0671ff0517142f5c610979
--- /dev/null
+++ b/types/mvc/MvcOptions.d.ts
@@ -0,0 +1,20 @@
+import { Collection } from '.';
+import { Model } from './Model';
+
+export interface ViewOptions<T> {
+  el: HTMLElement;
+  model?: Model<T>;
+}
+
+export interface CollectionOptions {
+  silent?: boolean;
+}
+
+export interface SelectedCollectionViewOptions<T> {
+  el: HTMLElement;
+  collection?: Collection<T>;
+}
+
+export interface ModelOptions extends CollectionOptions {
+  force: boolean;
+}
diff --git a/types/mvc/SelectedCollectionView.d.ts b/types/mvc/SelectedCollectionView.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..99c72a6d22c1204fff69c83c817c25b0c34091f1
--- /dev/null
+++ b/types/mvc/SelectedCollectionView.d.ts
@@ -0,0 +1,31 @@
+import { SelectedCollectionViewOptions } from '.';
+
+/** create a new view based on a collection of models. */
+export class SelectedCollectionView<T> {
+  constructor(params: SelectedCollectionViewOptions<T>);
+
+  /**
+   * clean up the view
+   */
+  destroy(): void;
+
+  /**
+   * unset the event bindings for the collection
+   */
+  onCollectionDeselect(): void;
+
+  /**
+   * unset event bindings for the collection, if set.
+   */
+  onCollectionReset(): void;
+
+  /**
+   * set event bindings for the collection
+   */
+  onCollectionSelect(): void;
+
+  /**
+   * render the selected model in the view
+   */
+  render(): void;
+}
diff --git a/types/mvc/View.d.ts b/types/mvc/View.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cf8a2ee947f93c1f4027f0c45331b37b0685d8e8
--- /dev/null
+++ b/types/mvc/View.d.ts
@@ -0,0 +1,21 @@
+import { ViewOptions } from './';
+
+/** create a new view. */
+export class View<T> {
+  constructor(params: ViewOptions<T>);
+
+  /**
+   * API Method
+   *
+   * Renders the view
+   */
+  render(): void;
+
+  /**
+   * API Method
+   *
+   * Cleans up resources allocated by the view. Should be called before
+   * discarding a view.
+   */
+  destroy(): void;
+}
diff --git a/types/mvc/index.d.ts b/types/mvc/index.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2a5ecc6c09c6ddd415da85214fa3aa5f13a22f52
--- /dev/null
+++ b/types/mvc/index.d.ts
@@ -0,0 +1,6 @@
+export * from './Collection';
+export * from './Column';
+export * from './Model';
+export * from './SelectedCollectionView';
+export * from './View';
+export * from './MvcOptions';
diff --git a/types/util/Events.d.ts b/types/util/Events.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..41e804d4b81bee8dc44c53e072d5222c1918a6f0
--- /dev/null
+++ b/types/util/Events.d.ts
@@ -0,0 +1,43 @@
+export class Events {
+  /**
+   * Free all references.
+   */
+  destroy(): void;
+
+  /**
+   * Remove an event listener
+   *
+   * Omitting callback clears all listeners for given event.
+   * Omitting event clears all listeners for all events.
+   *
+   * @param event
+   *      event name to unbind.
+   * @param callback
+   *      callback to unbind.
+   * @param context
+   *      context for "this" when callback is called
+   */
+  off(evt: string, callback: () => {}, context: object): void;
+
+  /**
+   * Add an event listener
+   *
+   * @param event
+   *      event name (singular).  E.g. 'reset'
+   * @param callback
+   *      function to call when event is triggered.
+   * @param context
+   *      context for "this" when callback is called
+   */
+  on(event: string, callback: () => {}, context: object): void;
+
+  /**
+   * Trigger an event
+   *
+   * @param event
+   *      event name.
+   * @param args
+   *      variable length arguments after event are passed to listeners.
+   */
+  trigger(event: string, ...args: any[]): void;
+}
diff --git a/types/util/Util.d.ts b/types/util/Util.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6d76180d274f27724b5042c15f5afa5fac31b61d
--- /dev/null
+++ b/types/util/Util.d.ts
@@ -0,0 +1,33 @@
+export class Util {
+  /**
+   * Merge properties from a series of objects.
+   *
+   * @param dst
+   *      target where merged properties are copied to.
+   * @param <variable>
+   *      source objects for properties. When a source is non null, it's
+   *      properties are copied to the dst object. Properties are copied in
+   *      the order of arguments: a property on a later argument overrides a
+   *      property on an earlier argument.
+   */
+  static extend(dst: object): object;
+
+  // remove an elements child nodes
+  static empty(el: HTMLElement): void;
+
+  /**
+   * Creates a function that is a composition of other functions.
+   *
+   * For example:
+   *      a(b(c(x))) === compose(c, b, a)(x);
+   *
+   * Each function should accept as an argument, the result of the previous
+   * function call in the chain. It is allowable for all functions to have no
+   * return value as well.
+   *
+   * @param functions variable set of functions to call, in order.
+   *
+   * @return The composition of the functions provided as arguments.
+   */
+  static compose(...functions: (() => {})[]): () => {};
+}
diff --git a/types/util/index.d.ts b/types/util/index.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5b17b47fb4cd6f5874b28dc3c5cf75e941a4f7ab
--- /dev/null
+++ b/types/util/index.d.ts
@@ -0,0 +1,2 @@
+export * from './Events';
+export * from './Util';