diff --git a/projects/nshmp-apps/src/app/gmm/spectra/gmm.utils.ts b/projects/nshmp-apps/src/app/gmm/spectra/gmm.utils.ts
deleted file mode 100644
index c2963c9744f82d192da6fe46bb801e05969c115d..0000000000000000000000000000000000000000
--- a/projects/nshmp-apps/src/app/gmm/spectra/gmm.utils.ts
+++ /dev/null
@@ -1,994 +0,0 @@
-import {HttpParams} from '@angular/common/http';
-import {
-  GmmFormControlIds,
-  GmmParameters,
-  GmmSource,
-  MultiSelectableParam,
-} from '@ghsc/nshmp-lib-ng/gmm';
-import {ServiceCallInfo, TableData} from '@ghsc/nshmp-lib-ng/nshmp';
-import {NshmpPlot, plotUtils} from '@ghsc/nshmp-lib-ng/plot';
-import {XyDataGroup} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz';
-import {XySequence} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/data';
-import {
-  GmmInput,
-  Imt,
-  imtToString,
-} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/gmm';
-import {
-  GmmDistanceUsage,
-  GmmMagnitudeUsage,
-  GmmResponseData,
-  GmmSeries,
-  GmmUsageParameters,
-  SpectraData,
-  TreeValues,
-} from '@ghsc/nshmp-utils-ts/libs/nshmp-ws/gmm-services';
-import {Response} from '@ghsc/nshmp-utils-ts/libs/nshmp-ws-utils';
-import {
-  EnumParameterValues,
-  Parameter,
-} from '@ghsc/nshmp-utils-ts/libs/nshmp-ws-utils/metadata';
-import {PlotlyLayout, PlotlyPlot} from '@ghsc/nshmp-utils-ts/libs/plotly';
-import {DataTitle, PlotData} from 'plotly.js';
-
-/** Default aspect ratio for mean plots */
-export const MEAN_ASPECT_RATIO = '16:9';
-/** Default aspect ratio of sigma plots */
-export const SIGMA_ASPECT_RATIO = '21:9';
-/** X value to use for PGA values */
-export const XS_PGA = 0.008;
-export const XS_PGV = 0.009;
-
-const GMM_QUERY_DELIMITER = '::';
-
-/**
- * GMM plot config.
- */
-export interface GmmPlotConfig {
-  /** Hover template for plot */
-  hoverTemplate: string | string[];
-
-  /** Plot symbol */
-  symbol?: string | string[];
-}
-
-/**
- * The GMM plots.
- */
-export interface GmmPlots {
-  /** Mean plot */
-  means: PlotlyPlot;
-  /** Sigma plot */
-  sigmas: PlotlyPlot;
-}
-
-/**
- * GMM service response config.
- */
-export interface GmmResponse<T, U> {
-  /** GMM input parameters from service response */
-  input: GmmInput;
-  /** Mean plot config */
-  meanPlotConfig: GmmPlotConfig;
-  /** GMM service response data */
-  response: GmmResponseData<T, U>;
-  /** Sigma plot config */
-  sigmaPlotConfig: GmmPlotConfig;
-}
-
-/**
- * Function properties to convert GMM responses to plots.
- *
- * @see {@link gmmResponsesToPlots}
- */
-export interface GmmResponseToPlotProps<T, U> extends GmmProps {
-  /** The mean plot */
-  meanPlot: NshmpPlot;
-  /** GMM responses */
-  responses: GmmResponse<T, U>[];
-  /** The sigma plot */
-  sigmaPlot: NshmpPlot;
-
-  /** Optional title for mean plot */
-  meanTitle?: string;
-  /** Optional title for sigma plot */
-  sigmaTitle?: string;
-}
-
-/** GMM plot types */
-export enum PlotType {
-  MEANS = 'MEANS',
-  SIGMA = 'SIGMA',
-}
-
-/**
- * Function properties for the epistemic plot.
- *
- * @see {@link createEpistemicPlotData}
- */
-interface EpistemicPlotDataProps<T, U> {
-  /** Plot color */
-  color: string;
-  /** Plot config */
-  plotConfig: GmmPlotConfig;
-  /** Plot name */
-  plotName: string;
-  /** GMM series data */
-  series: GmmSeries<T, U>;
-}
-
-/**
- * Common GMM properties.
- */
-interface GmmProps {
-  /** The current multi selectable parameter value */
-  multiSelectableParam: MultiSelectableParam;
-  /** Whether to show epistemic uncertainty int plot */
-  showEpistemicUncertainty: boolean;
-}
-
-/**
- * Function properties to convert GMM series to plot data.
- */
-interface GmmSeriesToPlotDataProps<T, U> extends GmmProps {
-  /** GMM input parameters */
-  input: GmmInput;
-  /** Plot config */
-  plotConfig: GmmPlotConfig;
-  /** The GMM series data */
-  series: GmmSeries<T, U>[];
-
-  /** Optional plot color */
-  color?: string;
-}
-
-/**
- * Returns the intersection of supported IMTs of selected Gmms.
- *
- * @param gmms The GMMs
- * @param usage The usage
- */
-export function getSupportedImts(
-  gmms: GmmSource[],
-  usage: GmmDistanceUsage | GmmMagnitudeUsage,
-): EnumParameterValues[] {
-  const gmmStrings = gmms.map(gmm => gmm.gmm.value);
-
-  const supportedImts = usage.response.parameters.gmm.values
-    .filter(value => gmmStrings.includes(value.id))
-    .map(value => value.supportedImts)
-    .reduce((acc, current) => current.filter(value => acc.includes(value)));
-
-  return usage.response.parameters.imt.values.filter(imt =>
-    supportedImts.includes(imt.value),
-  );
-}
-
-/**
- * Transforms the GMM service responses to Plotly plots.
- *
- * @param props The GMM properties
- */
-export function gmmResponsesToPlots(
-  props: GmmResponseToPlotProps<XySequence, number[]>,
-): GmmPlots {
-  const plots = responsesToPlots(props);
-  plots.means.data = gmmResponseToPlotData(props, PlotType.MEANS);
-  plots.sigmas.data = gmmResponseToPlotData(props, PlotType.SIGMA);
-  return plots;
-}
-
-export function spectraResponsesToPlots(
-  props: GmmResponseToPlotProps<SpectraData, TreeValues>,
-): GmmPlots {
-  const plots = responsesToPlots(props);
-  plots.means.data = spectraResponseToPlotData(props, PlotType.MEANS);
-  plots.sigmas.data = spectraResponseToPlotData(props, PlotType.SIGMA);
-  return plots;
-}
-
-/**
- * Checks to see if GMM data contains logic trees.
- *
- * @param dataGroups The data groups
- */
-export function hasTree<T, U>(
-  dataGroups: XyDataGroup<GmmSeries<T, U>>[],
-): boolean {
-  const tree = dataGroups
-    .map(dataGroup => dataGroup.data.filter(data => data.tree.length > 0))
-    .reduce((previous, current) => [...previous, ...current]);
-
-  return tree.length > 0;
-}
-
-/**
- * Returns the IMT label associated with IMT.
- *
- * @param imt The IMT
- */
-export function imtIdToDisplay(imt: string): string {
-  return imt !== 'default' ? imtToString(imt as Imt) : '';
-}
-
-/**
- * IMT select menu place holder
- */
-export function imtPlaceHolder(): Parameter {
-  return {
-    display: '--- Choose a GMM ---',
-    value: 'default',
-  };
-}
-
-/**
- * Convert Plotly data to X and Y {@link TableData}.
- *
- * @param plotData The Ploty data
- * @param layout The Plotly layout
- * @param exp Whether the values should be in exponential form
- * @param padValues Whether to pad missing values
- * @param xAll All X values
- */
-export function plotDataToDataTable(
-  plotData: Partial<PlotData>,
-  layout: Partial<PlotlyLayout>,
-  exp: boolean,
-  padValues = false,
-  xAll: number[] = [],
-) {
-  console.log(padValues);
-  let xs = (plotData.x as number[])
-    .filter(x => x !== null)
-    .map(x => (x === XS_PGA ? Imt.PGA : x === XS_PGV ? Imt.PGV : x.toFixed(4)));
-
-  let ys: string[] = (plotData.y as number[])
-    .filter(y => y !== null)
-    .map(y => (exp ? y.toExponential(4) : y.toFixed(4)));
-
-  if (padValues) {
-    const values = padValuesForTable(
-      xAll,
-      plotData.x as number[],
-      plotData.y as number[],
-      exp,
-    );
-
-    console.log(values);
-    xs = values.xs.map(x =>
-      parseFloat(x) === XS_PGA
-        ? Imt.PGA
-        : parseFloat(x) === XS_PGV
-          ? Imt.PGV
-          : x,
-    );
-    ys = values.ys;
-  }
-
-  console.log(xs);
-  console.log(ys);
-
-  return {
-    xTable: {
-      td: xs,
-      th: (layout?.xaxis?.title as DataTitle).text,
-    } as TableData,
-    yTable: {
-      td: ys,
-      th: plotData.name,
-    } as TableData,
-  };
-}
-
-/**
- * Convert a {@link PlotlyPlot} to {@link TableData}.
- *
- * @param plotlyPlot The plot to convert
- * @param exp Whether the values should be in exponential form
- * @param commonXValues Whether the X values are the same
- * @param padValues Whether to pad missing values
- * @param xAll All X values
- */
-export function plotToTable(
-  plotlyPlot: PlotlyPlot,
-  exp: boolean,
-  commonXValues: boolean,
-  padValues = false,
-  xAll: number[] = [],
-): TableData[] {
-  const data: TableData[] = [];
-
-  plotlyPlot.data.forEach((plotData, i) => {
-    if (i === 0 && commonXValues) {
-      data.push(
-        plotDataToDataTable(plotData, plotlyPlot.layout, exp, padValues, xAll)
-          .xTable,
-      );
-    } else if (!commonXValues) {
-      data.push(
-        plotDataToDataTable(plotData, plotlyPlot.layout, exp, padValues, xAll)
-          .xTable,
-      );
-    }
-    data.push(
-      plotDataToDataTable(plotData, plotlyPlot.layout, exp, padValues, xAll)
-        .yTable,
-    );
-  });
-
-  return data;
-}
-
-export interface ServiceCallInfoParams {
-  multiSelectableParam: MultiSelectableParam;
-  serviceName: string;
-  serviceResponses: Response<unknown, unknown>[];
-  serviceUrl: string;
-  values: GmmParameters;
-}
-
-/**
- * Convert GmmSources to query strings.
- *
- * @param gmms The GMMs
- */
-export function gmmSourceToQuery(gmms: GmmSource[]): string[] {
-  return gmms.map(
-    gmmSource =>
-      `${gmmSource.group.value}${GMM_QUERY_DELIMITER}${gmmSource.gmm.value}`,
-  );
-}
-
-/**
- * Convert GMM query string(s) to GmmSources.
- *
- * @param gmmQuery The GMM query string(s)
- * @param parameters The usage parameters
- * @returns
- */
-export function queryToGmmSource<T extends GmmUsageParameters>(
-  gmmQuery: string | string[],
-  parameters: T,
-): GmmSource[] {
-  const gmmArray = Array.isArray(gmmQuery)
-    ? gmmQuery
-    : gmmQuery
-      ? [gmmQuery]
-      : [];
-
-  const gmmSource: GmmSource[] = gmmArray
-    ?.map(gmm => gmm.split(GMM_QUERY_DELIMITER))
-    .map(([groupId, gmmId]) => {
-      const group = parameters.group.values.find(val => val.id === groupId);
-      const gmm = parameters.gmm.values.find(val => val.id === gmmId);
-
-      if (group && gmm) {
-        const source: GmmSource = {
-          gmm: {
-            display: gmm.label,
-            value: gmm.id,
-          },
-          group: {
-            display: group.label,
-            value: group.id,
-          },
-        };
-
-        return source;
-      } else {
-        return {
-          gmm: {
-            display: '',
-            value: '',
-          },
-          group: {
-            display: '',
-            value: '',
-          },
-        };
-      }
-    })
-    .filter(gmmSource => gmmSource.gmm.value.length > 0);
-
-  return gmmSource;
-}
-
-/**
- * Returns the service call info.
- *
- * @param state The app state
- */
-export function serviceCallInfo({
-  multiSelectableParam,
-  serviceName,
-  serviceResponses,
-  serviceUrl,
-  values,
-}: ServiceCallInfoParams): ServiceCallInfo {
-  const serviceCalls: string[] = [];
-
-  if (serviceResponses !== null) {
-    const urls = serviceEndpoints(serviceUrl, values, multiSelectableParam);
-    serviceCalls.push(...urls);
-  }
-
-  return {
-    serviceCalls,
-    serviceName,
-    usage: [serviceUrl],
-  };
-}
-
-/**
- * Forms the URLs to call.
- *
- * @param values The control panel values
- * @param multiSelectableParam The mlti-selectable parameter
- */
-export function serviceEndpoints(
-  serviceUrl: string,
-  values: GmmParameters,
-  multiSelectableParam: MultiSelectableParam,
-): string[] {
-  const urls: string[] = [];
-
-  urlQueryParams(values, multiSelectableParam).forEach(params =>
-    urls.push(`${serviceUrl}?${params.toString()}`),
-  );
-
-  return urls;
-}
-
-/**
- * Returns the HttpParams to call the service.
- *
- * @param values The control panel form values
- * @param multiSelectableParam The multi selectable parameter value
- */
-export function urlQueryParams(
-  values: GmmParameters,
-  multiSelectableParam: MultiSelectableParam,
-): HttpParams[] {
-  if (multiSelectableParam === MultiSelectableParam.MW) {
-    return urlQueryParamsMw(values);
-  } else if (multiSelectableParam === MultiSelectableParam.VS30) {
-    return urlQueryParamsVs30(values);
-  } else {
-    return urlQueryParamsGmm(values);
-  }
-}
-
-function createSpectraEpistemicPlotData(
-  props: EpistemicPlotDataProps<SpectraData, TreeValues>,
-): Partial<PlotData>[] {
-  const {color, plotConfig, plotName, series} = props;
-
-  if (series.tree.length === 0) {
-    return [];
-  }
-
-  const plotData = series.tree.map(tree => {
-    if (tree.values.sa.length !== series.data.sa.xs.length) {
-      throw new Error('Tree value length not equal to x value length');
-    }
-
-    const x: (number | null)[] = [];
-    const y: (number | null)[] = [];
-    const hovertemplate: string[] = [];
-    const symbol: string[] = [];
-
-    if (tree.values.pga) {
-      x.push(...[XS_PGA, null]);
-      y.push(...[tree.values.pga, null]);
-      hovertemplate.push(...['PGA, %{y}', '']);
-      symbol.push(...['square-open', '']);
-    }
-
-    if (tree.values.pgv) {
-      x.push(...[XS_PGV, null]);
-      y.push(...[tree.values.pgv, null]);
-      hovertemplate.push(...['PGV, %{y}', '']);
-      symbol.push(...['', '']);
-    }
-
-    x.push(...series.data.sa.xs);
-    y.push(...tree.values.sa);
-    hovertemplate.push(...plotConfig.hoverTemplate);
-
-    const plotSymbol = plotConfig.symbol;
-    if (plotSymbol) {
-      if (Array.isArray(plotSymbol)) {
-        symbol.push(...plotSymbol);
-      } else {
-        symbol.push(plotSymbol);
-      }
-    }
-
-    const plotData: Partial<PlotData> = {
-      connectgaps: false,
-      hovertemplate,
-      line: {
-        color,
-        dash: 'dot',
-        width: 1,
-      },
-      marker: {
-        size: 3,
-        symbol,
-      },
-      mode: 'lines+markers',
-      name: `${plotName} ${tree.id}`,
-      opacity: 0.6,
-      showlegend: false,
-      x,
-      y,
-    };
-
-    return plotData;
-  });
-
-  return plotData;
-}
-
-/**
- * Create the epistemic uncertainity plot data.
- *
- * @param props The properties
- */
-function createEpistemicPlotData(
-  props: EpistemicPlotDataProps<XySequence, number[]>,
-): Partial<PlotData>[] {
-  const {color, plotConfig, plotName, series} = props;
-
-  if (series.tree.length === 0) {
-    return [];
-  }
-
-  const plotData = series.tree.map(tree => {
-    if (tree.values.length !== series.data.xs.length) {
-      throw new Error('Tree value length not equal to x value length');
-    }
-
-    return {
-      connectgaps: false,
-      hovertemplate: plotConfig.hoverTemplate,
-      line: {
-        color,
-        dash: 'dot',
-        width: 1,
-      },
-      marker: {
-        size: 3,
-        symbol: 'circle',
-      },
-      mode: 'lines+markers',
-      name: `${plotName} ${tree.id}`,
-      opacity: 0.6,
-      showlegend: false,
-      x: series.data.xs,
-      y: tree.values,
-    } as Partial<PlotData>;
-  });
-
-  return plotData;
-}
-
-/**
- * Returns the GMM plot name.
- *
- * @param gmmLabel The GMM label
- * @param gmmInput The GMM input
- * @param multiSelectableParam The multi selectable parameter value
- */
-function gmmPlotDataName(
-  gmmLabel: string,
-  gmmInput: GmmInput,
-  multiSelectableParam: MultiSelectableParam,
-): string {
-  switch (multiSelectableParam) {
-    case MultiSelectableParam.MW: {
-      return `${gmmLabel} - Mw = ${gmmInput.Mw}`;
-    }
-    case MultiSelectableParam.VS30: {
-      return `${gmmLabel} - Vs30 = ${gmmInput.vs30}`;
-    }
-    default: {
-      return gmmLabel;
-    }
-  }
-}
-
-/**
- * Convert {@link GmmResponse} to {@link PlotData}.
- *
- * @param props The properties
- * @param plotType The plot type
- */
-function gmmResponseToPlotData(
-  props: GmmResponseToPlotProps<XySequence, number[]>,
-  plotType: PlotType,
-): Partial<PlotData>[] {
-  const colors = plotUtils.COLORWAY;
-  let count = 0;
-
-  const plotData = props.responses
-    .map(gmmResponse => {
-      const color = colors[count++ % colors.length];
-
-      return gmmSeriesToPlotData({
-        ...props,
-        color:
-          props.multiSelectableParam !== MultiSelectableParam.GMM
-            ? color
-            : undefined,
-        input: gmmResponse.input,
-        plotConfig:
-          plotType === PlotType.MEANS
-            ? gmmResponse.meanPlotConfig
-            : gmmResponse.sigmaPlotConfig,
-        series:
-          plotType === PlotType.MEANS
-            ? gmmResponse.response.means.data
-            : gmmResponse.response.sigmas.data,
-      });
-    })
-    .reduce((previous, current) => [...previous, ...current]);
-
-  return plotData;
-}
-
-/**
- * Convert {@link GmmSeries} to {@link PlotData}.
- *
- * @param props The properties
- */
-function gmmSeriesToPlotData(
-  props: GmmSeriesToPlotDataProps<XySequence, number[]>,
-): Partial<PlotData>[] {
-  const colors = plotUtils.COLORWAY;
-  let count = 0;
-
-  const plotData = props.series
-    .map(series => {
-      const color = colors[count++ % colors.length];
-      const gmmPlotName = gmmPlotDataName(
-        series.label,
-        props.input,
-        props.multiSelectableParam,
-      );
-
-      const plotData: Partial<PlotData> = {
-        hovertemplate: props.plotConfig.hoverTemplate,
-        line: {
-          color: props.color ?? color,
-        },
-        marker: {
-          symbol: props.plotConfig.symbol,
-        },
-        mode: 'lines+markers',
-        name: gmmPlotName,
-        x: series.data.xs,
-        y: series.data.ys,
-      };
-
-      const epistemicPlotData = createEpistemicPlotData({
-        color: props.color ?? color,
-        plotConfig: props.plotConfig,
-        plotName: gmmPlotName,
-        series,
-      });
-
-      return props.showEpistemicUncertainty
-        ? [plotData, ...epistemicPlotData]
-        : [plotData];
-    })
-    .reduce((previous, current) => [...previous, ...current]);
-
-  return plotData;
-}
-
-function responsesToPlots<T, U>(props: GmmResponseToPlotProps<T, U>): GmmPlots {
-  const response = [...props.responses].shift()?.response;
-  const {meanPlot, sigmaPlot} = props;
-
-  return {
-    means: {
-      config: meanPlot.plotData.config,
-      data: [],
-      id: PlotType.MEANS,
-      layout: plotUtils.updatePlotLabels({
-        layout: meanPlot.plotData.layout,
-        title: props.meanTitle,
-        xLabel: response?.means.xLabel ?? '',
-        yLabel: response?.means.yLabel ?? '',
-      }),
-      mobileConfig: meanPlot.plotData.mobileConfig,
-      mobileLayout: plotUtils.updatePlotLabels({
-        layout: meanPlot.plotData.mobileLayout,
-        title: props.meanTitle,
-        xLabel: response?.means.xLabel ?? '',
-        yLabel: response?.means.yLabel ?? '',
-      }),
-    },
-    sigmas: {
-      config: sigmaPlot.plotData.config,
-      data: [],
-      id: PlotType.SIGMA,
-      layout: plotUtils.updatePlotLabels({
-        layout: sigmaPlot.plotData.layout,
-        title: props.sigmaTitle,
-        xLabel: response?.sigmas.xLabel ?? '',
-        yLabel: response?.sigmas.yLabel ?? '',
-      }),
-      mobileConfig: sigmaPlot.plotData.mobileConfig,
-      mobileLayout: plotUtils.updatePlotLabels({
-        layout: sigmaPlot.plotData.mobileLayout,
-        title: props.sigmaTitle,
-        xLabel: response?.sigmas.xLabel ?? '',
-        yLabel: response?.sigmas.yLabel ?? '',
-      }),
-    },
-  };
-}
-
-function spectraResponseToPlotData(
-  props: GmmResponseToPlotProps<SpectraData, TreeValues>,
-  plotType: PlotType,
-): Partial<PlotData>[] {
-  const colors = plotUtils.COLORWAY;
-  let count = 0;
-
-  const plotData = props.responses
-    .map(gmmResponse => {
-      const color = colors[count++ % colors.length];
-
-      return spectraSeriesToPlotData({
-        ...props,
-        color:
-          props.multiSelectableParam !== MultiSelectableParam.GMM
-            ? color
-            : undefined,
-        input: gmmResponse.input,
-        plotConfig:
-          plotType === PlotType.MEANS
-            ? gmmResponse.meanPlotConfig
-            : gmmResponse.sigmaPlotConfig,
-        series:
-          plotType === PlotType.MEANS
-            ? gmmResponse.response.means.data
-            : gmmResponse.response.sigmas.data,
-      });
-    })
-    .reduce((previous, current) => [...previous, ...current]);
-
-  return plotData;
-}
-
-function spectraSeriesToPlotData(
-  props: GmmSeriesToPlotDataProps<SpectraData, TreeValues>,
-): Partial<PlotData>[] {
-  const colors = plotUtils.COLORWAY;
-  let count = 0;
-
-  const plotData = props.series
-    .map(series => {
-      const color = colors[count++ % colors.length];
-      const gmmPlotName = gmmPlotDataName(
-        series.label,
-        props.input,
-        props.multiSelectableParam,
-      );
-
-      const x: (number | null)[] = [];
-      const y: (number | null)[] = [];
-      const hovertemplate: string[] = [];
-      const symbol: string[] = [];
-
-      if (series.data.pga) {
-        x.push(...[XS_PGA, null]);
-        y.push(...[series.data.pga, null]);
-        hovertemplate.push(...['PGA, %{y}', '']);
-        symbol.push(...['square-open', '']);
-      }
-
-      if (series.data.pgv) {
-        x.push(...[XS_PGV, null]);
-        y.push(...[series.data.pgv, null]);
-        hovertemplate.push(...['PGV, %{y}', '']);
-        symbol.push(...['', '']);
-      }
-
-      x.push(...series.data.sa.xs);
-      y.push(...series.data.sa.ys);
-      hovertemplate.push(...props.plotConfig.hoverTemplate);
-
-      const plotSymbol = props.plotConfig.symbol;
-      if (plotSymbol) {
-        if (Array.isArray(plotSymbol)) {
-          symbol.push(...plotSymbol);
-        } else {
-          symbol.push(plotSymbol);
-        }
-      }
-
-      const plotData: Partial<PlotData> = {
-        hovertemplate,
-        line: {
-          color: props.color ?? color,
-        },
-        marker: {
-          symbol,
-        },
-        mode: 'lines+markers',
-        name: gmmPlotName,
-        x,
-        y,
-      };
-
-      const epistemicPlotData = createSpectraEpistemicPlotData({
-        color: props.color ?? color,
-        plotConfig: props.plotConfig,
-        plotName: gmmPlotName,
-        series,
-      });
-
-      return props.showEpistemicUncertainty
-        ? [plotData, ...epistemicPlotData]
-        : [plotData];
-    })
-    .reduce((previous, current) => [...previous, ...current]);
-
-  return plotData;
-}
-
-/**
- * Add empty string to missing Y value.
- *
- * @param xAll Array of all X values
- * @param xs Current X values
- * @param ys Values to add empty string to at missing X value
- * @param exp Whether to make Y values exponential
- */
-function padValuesForTable(
-  xAll: number[],
-  xs: number[],
-  ys: number[],
-  exp: boolean,
-) {
-  console.log('padValues');
-  console.log(xs);
-  const xValues = [...xs].filter(x => x !== null).map(x => x.toFixed(4));
-  console.log(xValues);
-  const yValues = [...ys]
-    .filter(y => y !== null)
-    .map(y => (exp ? y.toExponential(4) : y.toFixed(4)));
-
-  const indices = xAll
-    .filter(x => !xs.includes(x))
-    .map(x => xAll.findIndex(xx => xx === x));
-
-  indices.forEach(i => {
-    xValues.splice(i, 0, xAll[i].toFixed(4));
-    yValues.splice(i, 0, '');
-  });
-
-  console.log(xValues);
-  console.log('------');
-
-  return {
-    xs: xValues,
-    ys: yValues,
-  };
-}
-
-/**
- * Returns the {@link HttpParams} for {@link GmmParameters} for when GMMs
- * are multi selectable.
- *
- * @param values GMM parameters
- */
-function urlQueryParamsGmm(values: GmmParameters): HttpParams[] {
-  let params = new HttpParams();
-
-  for (const [key, value] of Object.entries(values) as [
-    string,
-    string | number,
-  ][]) {
-    if (
-      key === GmmFormControlIds.MULTI_SELECTABLE_PARAM.toString() ||
-      value === null ||
-      key === GmmFormControlIds.MW_MULTI.toString() ||
-      key === GmmFormControlIds.VS30_MULTI.toString() ||
-      key === GmmFormControlIds.GMM_GROUP_TYPE.toString()
-    ) {
-      continue;
-    } else if (key === GmmFormControlIds.GMM_SOURCE.toString()) {
-      values.gmmSource.forEach(gmm => {
-        params = params.append(GmmFormControlIds.GMM, gmm.gmm.value);
-      });
-    } else {
-      params = params.append(key, value);
-    }
-  }
-
-  return [params];
-}
-
-/**
- * Returns the {@link HttpParams} for {@link GmmParameters} for when Mw
- * is multi selectable.
- *
- * @param values GMM parameters
- */
-function urlQueryParamsMw(values: GmmParameters): HttpParams[] {
-  const httpParams: HttpParams[] = [];
-
-  values.MwMulti?.forEach(Mw => {
-    let params = new HttpParams();
-    params = params.set(GmmFormControlIds.MW, Mw.toString());
-    for (const [key, value] of Object.entries(values) as [
-      string,
-      string | number,
-    ][]) {
-      if (
-        key === GmmFormControlIds.MULTI_SELECTABLE_PARAM.toString() ||
-        key === GmmFormControlIds.MW.toString() ||
-        key === GmmFormControlIds.MW_MULTI.toString() ||
-        key === GmmFormControlIds.VS30_MULTI.toString() ||
-        key === GmmFormControlIds.GMM_GROUP_TYPE.toString() ||
-        value === null
-      ) {
-        continue;
-      } else if (key === GmmFormControlIds.GMM_SOURCE.toString()) {
-        const gmm = [...values.gmmSource].shift()?.gmm.value;
-
-        if (gmm) {
-          params = params.append(GmmFormControlIds.GMM, gmm);
-        }
-      } else {
-        params = params.append(key, value);
-      }
-    }
-    httpParams.push(params);
-  });
-  return httpParams;
-}
-
-/**
- * Returns the {@link HttpParams} for {@link GmmParameters} for when vs30s
- * are multi selectable.
- *
- * @param values GMM parameters
- */
-function urlQueryParamsVs30(values: GmmParameters): HttpParams[] {
-  const httpParams: HttpParams[] = [];
-  values.vs30Multi?.forEach(vs30 => {
-    let params = new HttpParams();
-    params = params.set(GmmFormControlIds.VS30, vs30.toString());
-    for (const [key, value] of Object.entries(values) as [
-      string,
-      string | number,
-    ][]) {
-      if (
-        key === GmmFormControlIds.MULTI_SELECTABLE_PARAM.toString() ||
-        key === GmmFormControlIds.MW_MULTI.toString() ||
-        key === GmmFormControlIds.VS30_MULTI.toString() ||
-        key === GmmFormControlIds.VS30.toString() ||
-        key === GmmFormControlIds.GMM_GROUP_TYPE.toString() ||
-        value === null
-      ) {
-        continue;
-      } else if (key === GmmFormControlIds.GMM_SOURCE.toString()) {
-        const gmm = [...values.gmmSource].shift()?.gmm.value;
-
-        if (gmm) {
-          params = params.append(GmmFormControlIds.GMM, gmm);
-        }
-      } else {
-        params = params.append(key, value);
-      }
-    }
-    httpParams.push(params);
-  });
-  return httpParams;
-}