diff --git a/.gitignore copy b/.gitignore copy new file mode 100644 index 0000000..1ca9571 --- /dev/null +++ b/.gitignore copy @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log diff --git a/LICENSE b/LICENSE index 261eeb9..8dada3e 100644 --- a/LICENSE +++ b/LICENSE @@ -178,7 +178,7 @@ APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/index.js b/index.js deleted file mode 100644 index 55d9efa..0000000 --- a/index.js +++ /dev/null @@ -1,11 +0,0 @@ -export default function (kibana) { - - return new kibana.Plugin({ - uiExports: { - visTypes: [ - 'plugins/kbn_polar/kbn_polar' - ] - } - }); - -} diff --git a/kibana.json b/kibana.json new file mode 100755 index 0000000..2bf491d --- /dev/null +++ b/kibana.json @@ -0,0 +1,17 @@ +{ + "id": "kbnPolar", + "version": "7.10.0", + "server": false, + "ui": true, + "requiredPlugins": [ + "visualizations", + "data", + "inspector", + "kibanaLegacy" + ], + "requiredBundles": [ + "kibanaUtils", + "visDefaultEditor", + "share" + ] +} \ No newline at end of file diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 044861d..634584d --- a/package.json +++ b/package.json @@ -1,11 +1,12 @@ { "name": "kbn_polar", - "version": "0.0.1", + "version": "7.10.0", + "description": "Visualize polar charts", "kibana": { - "version": "kibana" + "version": "7.10.0" }, "authors": [ - "David Moreno Lumbreras " + "David Moreno Lumbreras " ], "license": "Apache-2.0", "repository": { @@ -16,4 +17,4 @@ "chart.js": "2.7.1", "randomcolor": "0.5.3" } -} +} \ No newline at end of file diff --git a/public/agg_table/_agg_table.scss b/public/agg_table/_agg_table.scss new file mode 100755 index 0000000..b9dd177 --- /dev/null +++ b/public/agg_table/_agg_table.scss @@ -0,0 +1,14 @@ +kbn-polar-agg-table, +kbn-polar-agg-table-group { + display: block; +} + +.striped-rows .kbnAggTable__paginated { + tr:nth-child(odd) td { + background-color: lighten($euiColorLightestShade, 2%); + } + + tr:hover td { + background-color: $euiColorLightestShade; + } +} diff --git a/public/agg_table/_index.scss b/public/agg_table/_index.scss new file mode 100755 index 0000000..b19d4a8 --- /dev/null +++ b/public/agg_table/_index.scss @@ -0,0 +1 @@ +@import 'agg_table'; diff --git a/public/agg_table/agg_table.html b/public/agg_table/agg_table.html new file mode 100755 index 0000000..b80a093 --- /dev/null +++ b/public/agg_table/agg_table.html @@ -0,0 +1,33 @@ + + +
+    + + + +     + + + + + +
+
diff --git a/public/agg_table/agg_table.js b/public/agg_table/agg_table.js new file mode 100755 index 0000000..441fccb --- /dev/null +++ b/public/agg_table/agg_table.js @@ -0,0 +1,195 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import _ from 'lodash'; +import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../../../../src/plugins/share/public'; +import aggTableTemplate from './agg_table.html'; +import { getFormatService } from '../services'; +import { fieldFormatter } from '../field_formatter'; + +export function KbnPolarAggTable(config, RecursionHelper) { + const fieldFormats = getFormatService(); + const numberFormatter = fieldFormats.getDefaultInstance('number').getConverterFor('text'); + + return { + restrict: 'E', + template: aggTableTemplate, + scope: { + table: '=', + perPage: '=?', + sort: '=?', + exportTitle: '=?', + showTotal: '=', + totalFunc: '=', + filter: '=', + }, + controllerAs: 'aggTable', + compile: function ($el) { + // Use the compile function from the RecursionHelper, + // And return the linking function(s) which it returns + return RecursionHelper.compile($el); + }, + controller: function ($scope) { + const self = this; + + self._saveAs = require('@elastic/filesaver').saveAs; + self.csv = { + separator: config.get(CSV_SEPARATOR_SETTING), + quoteValues: config.get(CSV_QUOTE_VALUES_SETTING) + }; + + self.exportAsCsv = function (formatted) { + const csv = new Blob([self.toCsv(formatted)], { type: 'text/plain;charset=utf-8' }); + self._saveAs(csv, self.csv.filename); + }; + + self.toCsv = function (formatted) { + const rows = $scope.table.rows; + const columns = formatted ? $scope.formattedColumns : $scope.table.columns; + const nonAlphaNumRE = /[^a-zA-Z0-9]/; + const allDoubleQuoteRE = /"/g; + + function escape(val) { + if (!formatted && _.isObject(val)) val = val.valueOf(); + val = String(val); + if (self.csv.quoteValues && nonAlphaNumRE.test(val)) { + val = '"' + val.replace(allDoubleQuoteRE, '""') + '"'; + } + return val; + } + + // escape each cell in each row + const csvRows = rows.map(function (row) { + return row.map(escape); + }); + + // add the columns to the rows + csvRows.unshift(columns.map(function (col) { + return escape(col.title); + })); + + return csvRows.map(function (row) { + return row.join(self.csv.separator) + '\r\n'; + }).join(''); + }; + + $scope.$watch('table', function () { + const table = $scope.table; + + if (!table) { + $scope.rows = null; + $scope.formattedColumns = null; + return; + } + + self.csv.filename = ($scope.exportTitle || table.title || 'unsaved') + '.csv'; + $scope.rows = table.rows; + $scope.formattedColumns = table.columns.map(function (col, i) { + const agg = col.aggConfig; + const field = agg.getField(); + const formattedColumn = { + title: col.title, + filterable: field && field.filterable && agg.type.type === 'buckets', + titleAlignmentClass: col.titleAlignmentClass, + totalAlignmentClass: col.totalAlignmentClass + }; + + const last = i === (table.columns.length - 1); + + if (last || (agg.type.type === 'metrics')) { + formattedColumn.class = 'visualize-table-right'; + } + + let isFieldNumeric = false; + let isFieldDate = false; + const aggType = agg.type; + if (aggType && aggType.type === 'metrics') { + if (aggType.name === 'top_hits') { + if (agg.params.aggregate.value !== 'concat') { + // all other aggregate types for top_hits output numbers + // so treat this field as numeric + isFieldNumeric = true; + } + } else if(aggType.name === 'cardinality') { + // Unique count aggregations always produce a numeric value + isFieldNumeric = true; + } else if (field) { + // if the metric has a field, check if it is either number or date + isFieldNumeric = field.type === 'number'; + isFieldDate = field.type === 'date'; + } else { + // if there is no field, then it is count or similar so just say number + isFieldNumeric = true; + } + } else if (field) { + isFieldNumeric = field.type === 'number'; + isFieldDate = field.type === 'date'; + } + + if (isFieldNumeric || isFieldDate || $scope.totalFunc === 'count') { + const sum = function (tableRows) { + return _.reduce(tableRows, function (prev, curr) { + // some metrics return undefined for some of the values + // derivative is an example of this as it returns undefined in the first row + if (curr[i].value === undefined) return prev; + return prev + curr[i].value; + }, 0); + }; + const formatter = col.totalFormatter ? col.totalFormatter('text') : fieldFormatter(agg, 'text'); + + if (col.totalFormula !== undefined) { + formattedColumn.total = formatter(col.total); + } + else { + switch ($scope.totalFunc) { + case 'sum': + if (!isFieldDate) { + formattedColumn.total = formatter(sum(table.rows)); + } + break; + case 'avg': + if (!isFieldDate) { + formattedColumn.total = formatter(sum(table.rows) / table.rows.length); + } + break; + case 'min': + formattedColumn.total = formatter(_.chain(table.rows).map(i).map('value').min().value()); + break; + case 'max': + formattedColumn.total = formatter(_.chain(table.rows).map(i).map('value').max().value()); + break; + case 'count': + formattedColumn.total = numberFormatter(table.rows.length); + break; + default: + break; + } + } + } + + if (i === 0 && table.totalLabel !== undefined && table.columns.length > 0 && formattedColumn.total === undefined) { + formattedColumn.total = table.totalLabel; + } + + return formattedColumn; + }); + }); + } + }; +} diff --git a/public/agg_table/agg_table_group.html b/public/agg_table/agg_table_group.html new file mode 100755 index 0000000..a04b698 --- /dev/null +++ b/public/agg_table/agg_table_group.html @@ -0,0 +1,67 @@ + + + + + + + + + + + +
+ {{ table.title }} +
+ + + +
+ + + + + + + + + + + + +
+ {{ table.title }} +
+ + + +
diff --git a/public/agg_table/agg_table_group.js b/public/agg_table/agg_table_group.js new file mode 100755 index 0000000..0118a6b --- /dev/null +++ b/public/agg_table/agg_table_group.js @@ -0,0 +1,57 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import aggTableGroupTemplate from './agg_table_group.html'; + +export function KbnPolarAggTableGroup(RecursionHelper) { + return { + restrict: 'E', + template: aggTableGroupTemplate, + scope: { + group: '=', + perPage: '=?', + sort: '=?', + exportTitle: '=?', + showTotal: '=', + totalFunc: '=', + filter: '=', + }, + compile: function ($el) { + // Use the compile function from the RecursionHelper, + // And return the linking function(s) which it returns + return RecursionHelper.compile($el, { + post: function ($scope) { + $scope.$watch('group', function (group) { + // clear the previous "state" + $scope.rows = $scope.columns = false; + + if (!group || !group.tables.length) return; + + const firstTable = group.tables[0]; + const params = firstTable.aggConfig && firstTable.aggConfig.params; + // render groups that have Table children as if they were rows, because iteration is cleaner + const childLayout = (params && !params.row) ? 'columns' : 'rows'; + + $scope[childLayout] = group.tables; + }); + } + }); + } + }; +} diff --git a/public/components/field.tsx b/public/components/field.tsx new file mode 100755 index 0000000..5a7afc6 --- /dev/null +++ b/public/components/field.tsx @@ -0,0 +1,120 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { get } from 'lodash'; +import React, { useEffect, useState, useCallback } from 'react'; + +import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { IndexPatternField } from '../../../../src/plugins/data/public'; +import { ComboBoxGroupedOptions } from '../../../../src/plugins/vis_default_editor/public/utils'; + +const label = i18n.translate('visDefaultEditor.controls.field.fieldLabel', { + defaultMessage: 'Field', +}); + +export interface FieldParamEditorProps { + customLabel?: string; + indexPatternFields: IndexPatternField[]; + showValidation: boolean; + value: IndexPatternField; + setValue(value?: IndexPatternField): void; +} + +function createIndexedFields(indexPatternFields: IndexPatternField[]): ComboBoxGroupedOptions { + const indexedFields = []; + indexPatternFields.forEach(field => { + let indexedField = indexedFields.find(indexedField => indexedField.label === field.type); + if (!indexedField) { + indexedField = { label: field.type, options: [] }; + indexedFields.push(indexedField); + } + indexedField.options.push({ label: field.displayName || field.name, target: field }); + }); + + indexedFields.sort((a, b) => a.label < b.label ? -1 : 1); + return indexedFields; +} + +function FieldParamEditor({ + customLabel, + indexPatternFields = [], + showValidation, + value, + setValue, +}: FieldParamEditorProps) { + const indexedFields = React.useMemo(() => createIndexedFields(indexPatternFields), indexPatternFields); + const [isDirty, setIsDirty] = useState(false); + const selectedOptions: ComboBoxGroupedOptions = value + ? [{ label: value.displayName || value.name, target: value }] + : []; + + const onChange = (options: EuiComboBoxOptionOption[]) => { + const selectedOption: IndexPatternField = get(options, '0.target'); + setValue(selectedOption); + }; + + const isValid = !!value || (!isDirty && !showValidation); + + useEffect(() => { + // set field if only one available + if (indexedFields.length !== 1) { + return; + } + + const indexedField = indexedFields[0]; + + if (!('options' in indexedField)) { + setValue(indexedField.target); + } else if (indexedField.options.length === 1) { + setValue(indexedField.options[0].target); + } + }, []); + + const onSearchChange = useCallback(searchValue => setIsDirty(Boolean(searchValue)), []); + + return ( + + setIsDirty(true)} + onSearchChange={onSearchChange} + fullWidth={true} + /> + + ); +} + +export { FieldParamEditor }; diff --git a/public/components/field_column.tsx b/public/components/field_column.tsx new file mode 100755 index 0000000..d50d202 --- /dev/null +++ b/public/components/field_column.tsx @@ -0,0 +1,236 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { clone } from 'lodash'; +import React, { useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; +import { IndexPatternField } from '../../../../src/plugins/data/public'; +import { EuiDraggable, EuiIconTip, EuiSpacer, EuiAccordion, EuiToolTip, EuiButtonIcon, EuiButtonIconProps } from '@elastic/eui'; + +import { TextInputOption } from './text_input'; +import { FieldParamEditor } from './field'; + + +export interface FieldColumn { + label: string; + field: IndexPatternField; + enabled: boolean; + brandNew?: boolean; +} + +function setFieldColumnParam(paramName: string, paramValue: any, fieldColumns: FieldColumn[], fieldColumnToUpdate: FieldColumn, setFieldColumns) { + const newList = fieldColumns.map(fieldColumn => { + if (fieldColumn === fieldColumnToUpdate) { + const updatedFieldColumn = clone(fieldColumnToUpdate); + updatedFieldColumn[paramName] = paramValue; + return updatedFieldColumn; + } + else { + return fieldColumn; + } + }); + setFieldColumns(newList); +} + +function removeFieldColumn(fieldColumns: FieldColumn[], fieldColumnToRemove: FieldColumn, setFieldColumns) { + const newList = fieldColumns.filter(fieldColumn => fieldColumn !== fieldColumnToRemove); + setFieldColumns(newList); +} + +function renderButtons (fieldColumn, fieldColumns, showError, setValue, setFieldColumns, dragHandleProps) { + const actionIcons = []; + + if (showError) { + actionIcons.push({ + id: 'hasErrors', + color: 'danger', + type: 'alert', + tooltip: i18n.translate('visTypeDocumentTable.params.fieldColumns.errorsAriaLabel', { + defaultMessage: 'Field column has errors', + }) + }); + } + + if (fieldColumns.length > 1 && fieldColumn.enabled) { + actionIcons.push({ + id: 'disableFieldColumn', + color: 'text', + disabled: false, + type: 'eye', + onClick: () => setValue('enabled', false), + tooltip: i18n.translate('visTypeDocumentTable.params.fieldColumns.disableColumnButtonTooltip', { + defaultMessage: 'Disable column', + }) + }); + } + if (!fieldColumn.enabled) { + actionIcons.push({ + id: 'enableFieldColumn', + color: 'text', + type: 'eyeClosed', + onClick: () => setValue('enabled', true), + tooltip: i18n.translate('visTypeDocumentTable.params.fieldColumns.enableColumnButtonTooltip', { + defaultMessage: 'Enable column', + }) + }); + } + if (fieldColumns.length > 1) { + actionIcons.push({ + id: 'dragHandle', + type: 'grab', + tooltip: i18n.translate('visTypeDocumentTable.params.fieldColumns.modifyPriorityButtonTooltip', { + defaultMessage: 'Modify order by dragging', + }) + }); + } + if (fieldColumns.length > 1) { + actionIcons.push({ + id: 'removeFieldColumn', + color: 'danger', + type: 'cross', + onClick: () => removeFieldColumn(fieldColumns, fieldColumn, setFieldColumns), + tooltip: i18n.translate('visTypeDocumentTable.params.fieldColumns.removeColumnButtonTooltip', { + defaultMessage: 'Remove column', + }) + }); + } + + return ( +
+ {actionIcons.map(icon => { + if (icon.id === 'dragHandle') { + return ( + + ); + } + + return ( + + + + ); + })} +
+ ); +} + +function FieldColumnEditor({ + fieldColumns, + fieldColumn, + index, + setFieldColumns, + aggs, + setValidity +}) { + + const setValue = (paramName, paramValue) => setFieldColumnParam(paramName, paramValue, fieldColumns, fieldColumn, setFieldColumns); + const [isEditorOpen, setIsEditorOpen] = React.useState(fieldColumn.brandNew); + const [validState, setValidState] = React.useState(true); + const [showValidation, setShowValidation] = React.useState(false); + const showDescription = !isEditorOpen && validState; + const showError = !isEditorOpen && !validState; + const isFieldValid = fieldColumn.field !== undefined; + + if (fieldColumn.brandNew) { + fieldColumn.brandNew = undefined; + } + + const buttonContent = ( + <> + Field col {showDescription && {fieldColumn.label || fieldColumn.field.name}} + + ); + + const onToggle = React.useCallback( + (isOpen: boolean) => { + setIsEditorOpen(isOpen); + setShowValidation(true); + }, + [] + ); + + useEffect(() => { + setValidity(isFieldValid); + setValidState(isFieldValid); + }, [isFieldValid, setValidity, setValidState]); + + return ( + <> + + {provided => ( + + <> + + + setValue('field', value)} + /> + + + + + + )} + + + ); +} + +export { FieldColumnEditor }; diff --git a/public/components/kbn_polar_vis_options.tsx b/public/components/kbn_polar_vis_options.tsx new file mode 100755 index 0000000..eac4d46 --- /dev/null +++ b/public/components/kbn_polar_vis_options.tsx @@ -0,0 +1,53 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { some } from 'lodash'; +import React, { useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiButtonEmpty, EuiDragDropContext, euiDragDropReorder, EuiDroppable, EuiFlexGroup, EuiFlexItem, EuiFormErrorText, EuiIconTip, EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; + +import { IAggConfigs } from '../../../../src/plugins/data/public'; +import { VisOptionsProps } from '../../../../src/plugins/vis_default_editor/public'; +import { NumberInputOption, SelectOption } from '../../../../src/plugins/charts/public'; +import { SwitchOption } from './switch'; +import { TextInputOption } from './text_input'; +import { totalAggregations, AggTypes } from './utils'; +import { array } from 'fp-ts'; + + +export interface KbnPolarVisParams { + type: 'polar'; +} + +function KbnPolarOptions({ + stateParams, + setValue, +}: VisOptionsProps) { + + return ( +
+ +
+ ); +} + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { KbnPolarOptions as default }; diff --git a/public/components/kbn_polar_vis_options_lazy.tsx b/public/components/kbn_polar_vis_options_lazy.tsx new file mode 100755 index 0000000..9408f0f --- /dev/null +++ b/public/components/kbn_polar_vis_options_lazy.tsx @@ -0,0 +1,30 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React, { lazy, Suspense } from 'react'; +import { EuiLoadingSpinner } from '@elastic/eui'; +import { VisOptionsProps } from '../../../../src/plugins/vis_default_editor/public'; +import { KbnPolarVisParams } from './kbn_polar_vis_options'; + +const KbnPolarOptionsComponent = lazy(() => import('./kbn_polar_vis_options')); + +export const KbnPolarOptions = (props: VisOptionsProps) => ( + }> + + +); diff --git a/public/components/switch.tsx b/public/components/switch.tsx new file mode 100755 index 0000000..1e46bba --- /dev/null +++ b/public/components/switch.tsx @@ -0,0 +1,68 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; + +import { EuiFormRow, EuiSwitch, EuiIconTip } from '@elastic/eui'; + +interface SwitchOptionProps { + 'data-test-subj'?: string; + label?: string; + icontip?: string; + disabled?: boolean; + value?: boolean; + paramName: ParamName; + setValue: (paramName: ParamName, value: boolean) => void; +} + +function SwitchOption({ + 'data-test-subj': dataTestSubj, + icontip, + label, + disabled, + paramName, + value = false, + setValue, +}: SwitchOptionProps) { + return ( + + <> + setValue(paramName, ev.target.checked)} + /> + { icontip && ( + <> +   + + + )} + + + ); +} + +export { SwitchOption }; diff --git a/public/components/text_input.tsx b/public/components/text_input.tsx new file mode 100755 index 0000000..28ea232 --- /dev/null +++ b/public/components/text_input.tsx @@ -0,0 +1,64 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { EuiFormRow, EuiFieldText } from '@elastic/eui'; + +interface TextInputOptionProps { + disabled?: boolean; + helpText?: React.ReactNode; + error?: React.ReactNode; + isInvalid?: boolean; + label?: React.ReactNode; + placeholder?: string; + paramName: ParamName; + value?: string; + 'data-test-subj'?: string; + setValue: (paramName: ParamName, value: string) => void; +} + +function TextInputOption({ + 'data-test-subj': dataTestSubj, + disabled, + helpText, + error, + isInvalid, + label, + placeholder, + paramName, + value = '', + setValue, +}: TextInputOptionProps) { + return ( + + setValue(paramName, ev.target.value)} + /> + + ); +} + +export { TextInputOption }; diff --git a/public/components/utils.ts b/public/components/utils.ts new file mode 100755 index 0000000..a61130a --- /dev/null +++ b/public/components/utils.ts @@ -0,0 +1,61 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; + +export enum AggTypes { + SUM = 'sum', + AVG = 'avg', + MIN = 'min', + MAX = 'max', + COUNT = 'count', +} + +export const totalAggregations = [ + { + value: AggTypes.SUM, + text: i18n.translate('visTypeTable.totalAggregations.sumText', { + defaultMessage: 'Sum', + }), + }, + { + value: AggTypes.AVG, + text: i18n.translate('visTypeTable.totalAggregations.averageText', { + defaultMessage: 'Average', + }), + }, + { + value: AggTypes.MIN, + text: i18n.translate('visTypeTable.totalAggregations.minText', { + defaultMessage: 'Min', + }), + }, + { + value: AggTypes.MAX, + text: i18n.translate('visTypeTable.totalAggregations.maxText', { + defaultMessage: 'Max', + }), + }, + { + value: AggTypes.COUNT, + text: i18n.translate('visTypeTable.totalAggregations.countText', { + defaultMessage: 'Count', + }), + }, +]; diff --git a/public/data_load/agg_config_result.js b/public/data_load/agg_config_result.js new file mode 100755 index 0000000..37e554e --- /dev/null +++ b/public/data_load/agg_config_result.js @@ -0,0 +1,74 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { fieldFormatter } from '../field_formatter'; + +function computeBasePath(pathname) { + const endIndex = pathname ? pathname.indexOf('/app/kibana') : -1; + const basePath = endIndex !== -1 ? pathname.substring(0, endIndex) : ''; + return basePath; +} + +// eslint-disable-next-line import/no-default-export +export default function AggConfigResult(aggConfig, parent, value, key, filters) { + this.key = key; + this.value = value; + this.aggConfig = aggConfig; + this.filters = filters; + this.$parent = parent; + + if (aggConfig.type.type === 'buckets') { + this.type = 'bucket'; + } else { + this.type = 'metric'; + } +} + +/** + * Returns an array of the aggConfigResult and parents up the branch + * @returns {array} Array of aggConfigResults + */ +AggConfigResult.prototype.getPath = function () { + return (function walk(result, path) { + path.unshift(result); + if (result.$parent) return walk(result.$parent, path); + return path; + }(this, [])); +}; + +/** + * Returns an Elasticsearch filter that represents the result. + * @returns {object} Elasticsearch filter + */ +AggConfigResult.prototype.createFilter = function () { + return this.filters || this.aggConfig.createFilter(this.key); +}; + +AggConfigResult.prototype.toString = function (contentType) { + const parsedUrl = { + origin: window.location.origin, + pathname: window.location.pathname, + basePath: computeBasePath(window.location.pathname), + }; + const options = { parsedUrl }; + return fieldFormatter(this.aggConfig, contentType)(this.value, options); +}; + +AggConfigResult.prototype.valueOf = function () { + return this.value; +}; diff --git a/public/data_load/kbn-polar-request-handler.js b/public/data_load/kbn-polar-request-handler.js new file mode 100755 index 0000000..1d72a0f --- /dev/null +++ b/public/data_load/kbn-polar-request-handler.js @@ -0,0 +1,119 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import _ from 'lodash'; +import { RequestAdapter, DataAdapter } from '../../../../src/plugins/inspector/public'; +import { getSearchService, getQueryService } from '../services'; +import { handleCourierRequest } from './kibana_cloned_code/courier'; +import { serializeAggConfig } from './kibana_cloned_code/utils'; + +export async function kbnPolarRequestHandler ({ + partialRows, + metricsAtAllLevels, + visParams, + timeRange, + query, + filters, + inspectorAdapters, + forceFetch, + aggs +}) { + + const { filterManager } = getQueryService(); + + // create search source with query parameters + const searchService = getSearchService(); + const searchSource = await searchService.searchSource.create(); + searchSource.setField('index', aggs.indexPattern); + const hitsSize = (visParams.hitsSize !== undefined ? visParams.hitsSize : 0); + searchSource.setField('size', hitsSize); + + // specific request params for "field columns" + if (visParams.fieldColumns !== undefined) { + if (!visParams.fieldColumns.some(fieldColumn => fieldColumn.field.name === '_source')) { + searchSource.setField('_source', visParams.fieldColumns.map(fieldColumn => fieldColumn.field.name)); + } + searchSource.setField('docvalue_fields', visParams.fieldColumns.filter(fieldColumn => fieldColumn.field.readFromDocValues).map(fieldColumn => fieldColumn.field.name)); + const scriptFields = {}; + visParams.fieldColumns.filter(fieldColumn => fieldColumn.field.scripted).forEach(fieldColumn => { + scriptFields[fieldColumn.field.name] = { + script: { + source: fieldColumn.field.script + } + }; + }); + searchSource.setField('script_fields', scriptFields); + } + + // set search sort + if (visParams.sortField !== undefined) { + searchSource.setField('sort', [{ + [visParams.sortField.name]: { + order: visParams.sortOrder + } + }]); + } + + // add 'count' metric if there is no input column + if (aggs.aggs.length === 0) { + aggs.createAggConfig({ + id: '1', + enabled: true, + type: 'count', + schema: 'metric', + params: {} + }); + } + + inspectorAdapters.requests = new RequestAdapter(); + inspectorAdapters.data = new DataAdapter(); + + // execute elasticsearch query + const response = await handleCourierRequest({ + searchSource, + aggs, + indexPattern: aggs.indexPattern, + timeRange, + query, + filters, + forceFetch, + metricsAtAllLevels, + partialRows, + inspectorAdapters, + filterManager + }); + + // set 'split tables' direction + const splitAggs = aggs.bySchemaName('split'); + if (splitAggs.length > 0) { + splitAggs[0].params.row = visParams.row; + } + + // enrich elasticsearch response and return it + response.totalHits = _.get(searchSource, 'finalResponse.hits.total', -1); + response.aggs = aggs; + response.columns.forEach(column => { + column.meta = serializeAggConfig(column.aggConfig); + }); + if (visParams.fieldColumns !== undefined) { + response.fieldColumns = visParams.fieldColumns; + response.hits = _.get(searchSource, 'finalResponse.hits.hits', []); + } + return response; +} diff --git a/public/data_load/kbn-polar-response-handler.js b/public/data_load/kbn-polar-response-handler.js new file mode 100755 index 0000000..a50d236 --- /dev/null +++ b/public/data_load/kbn-polar-response-handler.js @@ -0,0 +1,108 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { get, findLastIndex } from 'lodash'; +import AggConfigResult from './agg_config_result'; +import { fieldFormatter } from '../field_formatter'; + +/** + * Takes an array of tabified rows and splits them by column value: + * + * const rows = [ + * { col-1: 'foo', col-2: 'X' }, + * { col-1: 'bar', col-2: 50 }, + * { col-1: 'baz', col-2: 'X' }, + * ]; + * const splitRows = splitRowsOnColumn(rows, 'col-2'); + * splitRows.results; // ['X', 50]; + * splitRows.rowsGroupedByResult; // { X: [{ col-1: 'foo' }, { col-1: 'baz' }], 50: [{ col-1: 'bar' }] } + */ +function splitRowsOnColumn(rows, columnId) { + const resultsMap = {}; // Used to preserve types, since object keys are always converted to strings. + return { + rowsGroupedByResult: rows.reduce((acc, row) => { + const { [columnId]: splitValue, ...rest } = row; + resultsMap[splitValue] = splitValue; + acc[splitValue] = [...(acc[splitValue] || []), rest]; + return acc; + }, {}), + results: Object.values(resultsMap), + }; +} + +function splitTable(columns, rows, $parent) { + const splitColumn = columns.find(column => get(column, 'aggConfig.schema') === 'split'); + + if (!splitColumn) { + return [{ + $parent, + columns: columns.map(column => ({ title: column.name, ...column })), + rows: rows.map((row, rowIndex) => { + const newRow = columns.map(column => { + const aggConfigResult = new AggConfigResult(column.aggConfig, $parent, row[column.id], row[column.id]); + aggConfigResult.rawData = { + table: { columns, rows }, + column: columns.findIndex(c => c.id === column.id), + row: rowIndex, + }; + return aggConfigResult; + }); + columns.forEach(column => newRow[column.id] = row[column.id]); + return newRow; + }) + }]; + } + + const splitColumnIndex = columns.findIndex(column => column.id === splitColumn.id); + const splitRows = splitRowsOnColumn(rows, splitColumn.id); + + // Check if there are buckets after the first metric. + const firstMetricsColumnIndex = columns.findIndex(column => get(column, 'aggConfig.type.type') === 'metrics'); + const lastBucketsColumnIndex = findLastIndex(columns, column => get(column, 'aggConfig.type.type') === 'buckets'); + const metricsAtAllLevels = firstMetricsColumnIndex < lastBucketsColumnIndex; + + // Calculate metrics:bucket ratio. + const numberOfMetrics = columns.filter(column => get(column, 'aggConfig.type.type') === 'metrics').length; + const numberOfBuckets = columns.filter(column => get(column, 'aggConfig.type.type') === 'buckets').length; + const metricsPerBucket = numberOfMetrics / numberOfBuckets; + + const filteredColumns = columns + .filter((column, i) => { + const isSplitColumn = i === splitColumnIndex; + const isSplitMetric = metricsAtAllLevels && i > splitColumnIndex && i <= splitColumnIndex + metricsPerBucket; + return !isSplitColumn && !isSplitMetric; + }) + .map(column => ({ title: column.name, ...column })); + + return splitRows.results.map(splitValue => { + const $newParent = new AggConfigResult(splitColumn.aggConfig, $parent, splitValue, splitValue); + return { + $parent: $newParent, + aggConfig: splitColumn.aggConfig, + title: `${fieldFormatter(splitColumn.aggConfig)(splitValue)}: ${splitColumn.aggConfig.makeLabel()}`, + key: splitValue, + // Recurse with filtered data to continue the search for additional split columns. + tables: splitTable(filteredColumns, splitRows.rowsGroupedByResult[splitValue], $newParent), + }; + }); +} + +export function kbnPolarResponseHandler(response) { + return { tables: splitTable(response.columns, response.rows, null), totalHits: response.totalHits, aggs: response.aggs, newResponse: true }; +} diff --git a/public/data_load/kibana_cloned_code/build_tabular_inspector_data.ts b/public/data_load/kibana_cloned_code/build_tabular_inspector_data.ts new file mode 100755 index 0000000..347c6b2 --- /dev/null +++ b/public/data_load/kibana_cloned_code/build_tabular_inspector_data.ts @@ -0,0 +1,97 @@ +import { set } from '@elastic/safer-lodash-set'; +import { FormattedData } from '../../../../../src/plugins/inspector/public'; +import { FormatFactory } from './utils'; +import { TabbedTable } from '../../../../../src/plugins/data/public'; +import { createFilter } from './create_filter'; + +/** + * Clone of: '../../../../../src/plugins/data/public/search/expressions/build_tabular_inspector_data.ts' + */ + + +/** + * @deprecated + * + * Do not use this function. + * + * @todo This function is used only by Courier. Courier will + * soon be removed, and this function will be deleted, too. If Courier is not removed, + * move this function inside Courier. + * + * --- + * + * This function builds tabular data from the response and attaches it to the + * inspector. It will only be called when the data view in the inspector is opened. + */ +export async function buildTabularInspectorData( + table: TabbedTable, + { + queryFilter, + deserializeFieldFormat, + }: { + queryFilter: { addFilters: (filter: any) => void }; + deserializeFieldFormat: FormatFactory; + } +) { + const aggConfigs = table.columns.map((column) => column.aggConfig); + const rows = table.rows.map((row) => { + return table.columns.reduce>((prev, cur, colIndex) => { + const value = row[cur.id]; + + let format = cur.aggConfig.toSerializedFieldFormat(); + if (Object.keys(format).length < 1) { + // If no format exists, fall back to string as a default + format = { id: 'string' }; + } + const fieldFormatter = deserializeFieldFormat(format); + + prev[`col-${colIndex}-${cur.aggConfig.id}`] = new FormattedData( + value, + fieldFormatter.convert(value) + ); + return prev; + }, {}); + }); + + const columns = table.columns.map((col, colIndex) => { + const field = col.aggConfig.getField(); + const isCellContentFilterable = col.aggConfig.isFilterable() && (!field || field.filterable); + return { + name: col.name, + field: `col-${colIndex}-${col.aggConfig.id}`, + filter: + isCellContentFilterable && + ((value: { raw: unknown }) => { + const rowIndex = rows.findIndex( + (row) => row[`col-${colIndex}-${col.aggConfig.id}`].raw === value.raw + ); + const filter = createFilter(aggConfigs, table, colIndex, rowIndex, value.raw); + + if (filter) { + queryFilter.addFilters(filter); + } + }), + filterOut: + isCellContentFilterable && + ((value: { raw: unknown }) => { + const rowIndex = rows.findIndex( + (row) => row[`col-${colIndex}-${col.aggConfig.id}`].raw === value.raw + ); + const filter = createFilter(aggConfigs, table, colIndex, rowIndex, value.raw); + + if (filter) { + const notOther = value.raw !== '__other__'; + const notMissing = value.raw !== '__missing__'; + if (Array.isArray(filter)) { + filter.forEach((f) => set(f, 'meta.negate', notOther && notMissing)); + } else { + set(filter, 'meta.negate', notOther && notMissing); + } + queryFilter.addFilters(filter); + } + }), + }; + }); + + return { columns, rows }; +} diff --git a/public/data_load/kibana_cloned_code/courier.ts b/public/data_load/kibana_cloned_code/courier.ts new file mode 100755 index 0000000..e870c30 --- /dev/null +++ b/public/data_load/kibana_cloned_code/courier.ts @@ -0,0 +1,206 @@ +import { hasIn } from 'lodash'; +import { i18n } from '@kbn/i18n'; + +import { calculateObjectHash } from '../../../../../src/plugins/kibana_utils/public'; +import { PersistedState } from '../../../../../src/plugins/visualizations/public'; +import { Adapters } from '../../../../../src/plugins/inspector/public'; + +import { IAggConfigs } from '../../../../../src/plugins/data/public/search/aggs'; +import { ISearchSource } from '../../../../../src/plugins/data/public/search/search_source'; +import { + calculateBounds, + Filter, + getTime, + IIndexPattern, + isRangeFilter, + Query, + TimeRange, +} from '../../../../../src/plugins/data/common'; +import { FilterManager } from '../../../../../src/plugins/data/public/query'; +import { buildTabularInspectorData } from './build_tabular_inspector_data'; +import { search } from '../../../../../src/plugins/data/public'; + +import { getFormatService as getFieldFormats } from '../../services'; + +/** + * Clone of: ../../../../../src/plugins/data/public/search/expressions/esaggs.ts + * Components: RequestHandlerParams and handleCourierRequest + */ +interface RequestHandlerParams { + searchSource: ISearchSource; + aggs: IAggConfigs; + timeRange?: TimeRange; + timeFields?: string[]; + indexPattern?: IIndexPattern; + query?: Query; + filters?: Filter[]; + forceFetch: boolean; + filterManager: FilterManager; + uiState?: PersistedState; + partialRows?: boolean; + inspectorAdapters: Adapters; + metricsAtAllLevels?: boolean; + visParams?: any; + abortSignal?: AbortSignal; +} + +export const handleCourierRequest = async ({ + searchSource, + aggs, + timeRange, + timeFields, + indexPattern, + query, + filters, + forceFetch, + partialRows, + metricsAtAllLevels, + inspectorAdapters, + filterManager, + abortSignal, +}: RequestHandlerParams) => { + // Create a new search source that inherits the original search source + // but has the appropriate timeRange applied via a filter. + // This is a temporary solution until we properly pass down all required + // information for the request to the request handler (https://github.com/elastic/kibana/issues/16641). + // Using callParentStartHandlers: true we make sure, that the parent searchSource + // onSearchRequestStart will be called properly even though we use an inherited + // search source. + const timeFilterSearchSource = searchSource.createChild({ callParentStartHandlers: true }); + const requestSearchSource = timeFilterSearchSource.createChild({ callParentStartHandlers: true }); + + aggs.setTimeRange(timeRange as TimeRange); + + // For now we need to mirror the history of the passed search source, since + // the request inspector wouldn't work otherwise. + Object.defineProperty(requestSearchSource, 'history', { + get() { + return searchSource.history; + }, + set(history) { + return (searchSource.history = history); + }, + }); + + requestSearchSource.setField('aggs', function () { + return aggs.toDsl(metricsAtAllLevels); + }); + + requestSearchSource.onRequestStart((paramSearchSource, options) => { + return aggs.onSearchRequestStart(paramSearchSource, options); + }); + + // If timeFields have been specified, use the specified ones, otherwise use primary time field of index + // pattern if it's available. + const defaultTimeField = indexPattern?.getTimeField?.(); + const defaultTimeFields = defaultTimeField ? [defaultTimeField.name] : []; + const allTimeFields = timeFields && timeFields.length > 0 ? timeFields : defaultTimeFields; + + // If a timeRange has been specified and we had at least one timeField available, create range + // filters for that those time fields + if (timeRange && allTimeFields.length > 0) { + timeFilterSearchSource.setField('filter', () => { + return allTimeFields + .map((fieldName) => getTime(indexPattern, timeRange, { fieldName })) + .filter(isRangeFilter); + }); + } + + requestSearchSource.setField('filter', filters); + requestSearchSource.setField('query', query); + + const reqBody = await requestSearchSource.getSearchRequestBody(); + + const queryHash = calculateObjectHash(reqBody); + // We only need to reexecute the query, if forceFetch was true or the hash of the request body has changed + // since the last request + const shouldQuery = forceFetch || (searchSource as any).lastQuery !== queryHash; + + if (shouldQuery) { + inspectorAdapters.requests.reset(); + const request = inspectorAdapters.requests.start( + i18n.translate('data.functions.esaggs.inspector.dataRequest.title', { + defaultMessage: 'Data', + }), + { + description: i18n.translate('data.functions.esaggs.inspector.dataRequest.description', { + defaultMessage: + 'This request queries Elasticsearch to fetch the data for the visualization.', + }), + } + ); + request.stats(search.getRequestInspectorStats(requestSearchSource)); + + try { + const response = await requestSearchSource.fetch({ abortSignal }); + + (searchSource as any).lastQuery = queryHash; + + request.stats(search.getResponseInspectorStats(searchSource, response)).ok({ json: response }); + + (searchSource as any).rawResponse = response; + } catch (e) { + // Log any error during request to the inspector + request.error({ json: e }); + throw e; + } finally { + // Add the request body no matter if things went fine or not + requestSearchSource.getSearchRequestBody().then((req: unknown) => { + request.json(req); + }); + } + } + + // Note that rawResponse is not deeply cloned here, so downstream applications using courier + // must take care not to mutate it, or it could have unintended side effects, e.g. displaying + // response data incorrectly in the inspector. + let resp = (searchSource as any).rawResponse; + for (const agg of aggs.aggs) { + if (hasIn(agg, 'type.postFlightRequest')) { + resp = await agg.type.postFlightRequest( + resp, + aggs, + agg, + requestSearchSource, + inspectorAdapters.requests, + abortSignal + ); + } + } + + (searchSource as any).finalResponse = resp; + + const parsedTimeRange = timeRange ? calculateBounds(timeRange) : null; + const tabifyParams = { + metricsAtAllLevels, + partialRows, + timeRange: parsedTimeRange + ? { from: parsedTimeRange.min, to: parsedTimeRange.max, timeFields: allTimeFields } + : undefined, + }; + + const tabifyCacheHash = calculateObjectHash({ tabifyAggs: aggs, ...tabifyParams }); + // We only need to reexecute tabify, if either we did a new request or some input params to tabify changed + const shouldCalculateNewTabify = + shouldQuery || (searchSource as any).lastTabifyHash !== tabifyCacheHash; + + if (shouldCalculateNewTabify) { + (searchSource as any).lastTabifyHash = tabifyCacheHash; + (searchSource as any).tabifiedResponse = search.tabifyAggResponse( + aggs, + (searchSource as any).finalResponse, + tabifyParams + ); + } + + inspectorAdapters.data.setTabularLoader( + () => + buildTabularInspectorData((searchSource as any).tabifiedResponse, { + queryFilter: filterManager, + deserializeFieldFormat: getFieldFormats().deserialize, + }), + { returnsFormattedValues: true } + ); + + return (searchSource as any).tabifiedResponse; +}; diff --git a/public/data_load/kibana_cloned_code/create_filter.ts b/public/data_load/kibana_cloned_code/create_filter.ts new file mode 100755 index 0000000..a4bdd13 --- /dev/null +++ b/public/data_load/kibana_cloned_code/create_filter.ts @@ -0,0 +1,63 @@ +import { IAggConfig } from '../../../../../src/plugins/data/public/search/aggs'; +import { TabbedTable } from '../../../../../src/plugins/data/public'; +import { Filter } from '../../../../../src/plugins/data/common'; + +/** + * Clone of: '../../../../../src/plugins/data/public/search/expressions/create_filter.ts' + */ + +const getOtherBucketFilterTerms = (table: TabbedTable, columnIndex: number, rowIndex: number) => { + if (rowIndex === -1) { + return []; + } + + // get only rows where cell value matches current row for all the fields before columnIndex + const rows = table.rows.filter((row) => { + return table.columns.every((column, i) => { + return row[column.id] === table.rows[rowIndex][column.id] || i >= columnIndex; + }); + }); + const terms = rows.map((row) => row[table.columns[columnIndex].id]); + + return [ + ...new Set( + terms.filter((term) => { + const notOther = term !== '__other__'; + const notMissing = term !== '__missing__'; + return notOther && notMissing; + }) + ), + ]; +}; + +export const createFilter = ( + aggConfigs: IAggConfig[], + table: TabbedTable, + columnIndex: number, + rowIndex: number, + cellValue: any +) => { + const column = table.columns[columnIndex]; + const aggConfig = aggConfigs[columnIndex]; + let filter: Filter[] = []; + const value: any = rowIndex > -1 ? table.rows[rowIndex][column.id] : cellValue; + if (value === null || value === undefined || !aggConfig.isFilterable()) { + return; + } + if (aggConfig.type.name === 'terms' && aggConfig.params.otherBucket) { + const terms = getOtherBucketFilterTerms(table, columnIndex, rowIndex); + filter = aggConfig.createFilter(value, { terms }); + } else { + filter = aggConfig.createFilter(value); + } + + if (!filter) { + return; + } + + if (!Array.isArray(filter)) { + filter = [filter]; + } + + return filter; +}; diff --git a/public/data_load/kibana_cloned_code/utils.ts b/public/data_load/kibana_cloned_code/utils.ts new file mode 100755 index 0000000..8fa335f --- /dev/null +++ b/public/data_load/kibana_cloned_code/utils.ts @@ -0,0 +1,19 @@ +import { IFieldFormat } from '../../../../../src/plugins/data/common'; + +/** + * Clone of: '../../../../../src/plugins/data/public/search/expressions/utils/serialize_agg_config.ts' + * Component: serializeAggConfig + */ +export function serializeAggConfig(aggConfig) { + return { + type: aggConfig.type.name, + indexPatternId: aggConfig.getIndexPattern().id, + aggConfigParams: aggConfig.serialize().params, + }; +}; + +/** + * Clone of: '../../../../../src/plugins/data/common/field_formats/utils.ts' + * Component: FormatFactory +*/ +export type FormatFactory = (mapping?) => IFieldFormat; diff --git a/public/field_formatter.ts b/public/field_formatter.ts new file mode 100755 index 0000000..ae89e52 --- /dev/null +++ b/public/field_formatter.ts @@ -0,0 +1,11 @@ +import { getFormatService } from './services'; +import { IAggConfig, IFieldFormat, FieldFormatsContentType } from '../../../src/plugins/data/public'; + +/** + * Returns the fieldFormatter function associated to aggConfig, for the requested contentType (html or text). + * Returned fieldFormatter is a function, whose prototype is: fieldFormatter(value, options?) + */ +export function fieldFormatter(aggConfig: IAggConfig, contentType: FieldFormatsContentType) { + const fieldFormat: IFieldFormat = getFormatService().deserialize(aggConfig.toSerializedFieldFormat()); + return fieldFormat.getConverterFor(contentType); +} diff --git a/public/get_inner_angular.ts b/public/get_inner_angular.ts new file mode 100755 index 0000000..81a8254 --- /dev/null +++ b/public/get_inner_angular.ts @@ -0,0 +1,102 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// inner angular imports +// these are necessary to bootstrap the local angular. +// They can stay even after NP cutover +import angular from 'angular'; +// required for `ngSanitize` angular module +import 'angular-sanitize'; +import 'angular-recursion'; +import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular'; +import { CoreStart, IUiSettingsClient, PluginInitializerContext } from 'kibana/public'; +import { + initAngularBootstrap, + PaginateDirectiveProvider, + PaginateControlsDirectiveProvider, + PrivateProvider, + watchMultiDecorator, + KbnAccessibleClickProvider, +} from '../../../src/plugins/kibana_legacy/public'; + +initAngularBootstrap(); + +const thirdPartyAngularDependencies = ['ngSanitize', 'ui.bootstrap', 'RecursionHelper']; + +export function getAngularModule(name: string, core: CoreStart, context: PluginInitializerContext) { + const uiModule = getInnerAngular(name, core); + return uiModule; +} + +let initialized = false; + +export function getInnerAngular(name = 'kibana/kbn_polar_vis', core: CoreStart) { + if (!initialized) { + createLocalPrivateModule(); + createLocalI18nModule(); + createLocalConfigModule(core.uiSettings); + createLocalPaginateModule(); + initialized = true; + } + return angular + .module(name, [ + ...thirdPartyAngularDependencies, + 'tableVisPaginate', + 'tableVisConfig', + 'tableVisPrivate', + 'tableVisI18n', + ]) + .config(watchMultiDecorator) + .directive('kbnAccessibleClick', KbnAccessibleClickProvider); +} + +function createLocalPrivateModule() { + angular.module('tableVisPrivate', []).provider('Private', PrivateProvider); +} + +function createLocalConfigModule(uiSettings: IUiSettingsClient) { + angular.module('tableVisConfig', []).provider('config', function () { + return { + $get: () => ({ + get: (value: string) => { + return uiSettings ? uiSettings.get(value) : undefined; + }, + // set method is used in agg_table mocha test + set: (key: string, value: string) => { + return uiSettings ? uiSettings.set(key, value) : undefined; + }, + }), + }; + }); +} + +function createLocalI18nModule() { + angular + .module('tableVisI18n', []) + .provider('i18n', I18nProvider) + .filter('i18n', i18nFilter) + .directive('i18nId', i18nDirective); +} + +function createLocalPaginateModule() { + angular + .module('tableVisPaginate', []) + .directive('paginate', PaginateDirectiveProvider) + .directive('paginateControls', PaginateControlsDirectiveProvider); +} diff --git a/public/images/icon-polar.svg b/public/images/icon-polar.svg new file mode 100644 index 0000000..25adf5a --- /dev/null +++ b/public/images/icon-polar.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/polar.svg b/public/images/polar.svg deleted file mode 100644 index 7c97dbd..0000000 --- a/public/images/polar.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - Svg Vector Icons : http://www.onlinewebfonts.com/icon - - \ No newline at end of file diff --git a/public/images/polar_example.png b/public/images/polar_example.png deleted file mode 100644 index 6e77113..0000000 Binary files a/public/images/polar_example.png and /dev/null differ diff --git a/public/index.scss b/public/index.scss new file mode 100755 index 0000000..fc31a0e --- /dev/null +++ b/public/index.scss @@ -0,0 +1 @@ +@import 'kbn_polar'; diff --git a/public/index.ts b/public/index.ts new file mode 100755 index 0000000..2e2d40a --- /dev/null +++ b/public/index.ts @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import './index.scss'; +import { PluginInitializerContext } from 'kibana/public'; +import { KbnPolarPlugin as Plugin } from './plugin'; + +export function plugin(initializerContext: PluginInitializerContext) { + return new Plugin(initializerContext); +} diff --git a/public/kbn-polar-vis-controller.js b/public/kbn-polar-vis-controller.js new file mode 100755 index 0000000..0576ece --- /dev/null +++ b/public/kbn-polar-vis-controller.js @@ -0,0 +1,96 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import _ from 'lodash'; + +import randomColor from 'randomcolor'; +import Chartjs from 'chart.js' + +import AggConfigResult from './data_load/agg_config_result'; +import { getNotifications, getFormatService } from './services'; + +// KbnPolarVis AngularJS controller +function KbnPolarVisController($scope, config, $timeout) { + + $scope.$watchMulti(['esResponse'], function ([resp]) { + if ($scope.polarchart) { + $scope.polarchart.destroy() + } + + if (resp) { + //Names of the field that have been selected + if (resp.aggs.bySchemaName('field')) { + var firstFieldAggId = resp.aggs.bySchemaName('field')[0].id; + var fieldAggName = resp.aggs.bySchemaName('field')[0].params.field.displayName; + } + + + // Retrieve the metrics aggregation configured + if (resp.aggs.bySchemaName('metric')) { + var metricsAgg_xAxis = resp.aggs.bySchemaName('metric')[0]; + if (resp.aggs.bySchemaName('metric')[0].type.name != "count") { + var metricsAgg_xAxis_name = resp.aggs.bySchemaName('metric')[0].params.field.displayName; + } else { + var metricsAgg_xAxis_name = "" + } + var metricsAgg_xAxis_title = resp.aggs.bySchemaName('metric')[0].type.title + } + + + var labels = [] + var dataParsed = []; + for (let index = 0; index < resp.tables[0].rows.length; index++) { + const bucket = resp.tables[0].rows[index]; + labels.push(bucket[0].value) + dataParsed.push(bucket[1].value) + } + var colors = randomColor({ hue: 'random', luminosity: 'bright', count: 200 }); + var dataComplete = { + datasets: [{ + data: dataParsed, + backgroundColor: colors //["rgb(255, 99, 132)", "rgb(75, 192, 192)", "rgb(255, 205, 86)", "rgb(201, 203, 207)", "rgb(54, 162, 235)"] + }], + labels: labels + } + } + + $timeout(function () { + //DOM has finished rendering + var canvas = document.getElementById('polar_chart_' + $scope.$id); + var ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, canvas.width, canvas.height); + var options = { + legend: { + display: false + } + } + + $scope.polarchart = new Chartjs(ctx, { + data: dataComplete, + type: 'polarArea', + options: options + }); + }); + + + + }); +} + +export { KbnPolarVisController }; \ No newline at end of file diff --git a/public/kbn_polar.html b/public/kbn-polar-vis.html old mode 100644 new mode 100755 similarity index 95% rename from public/kbn_polar.html rename to public/kbn-polar-vis.html index b6224d1..6390b74 --- a/public/kbn_polar.html +++ b/public/kbn-polar-vis.html @@ -1,4 +1,3 @@
-
- + \ No newline at end of file diff --git a/public/kbn-polar-vis.js b/public/kbn-polar-vis.js new file mode 100755 index 0000000..1c9aaeb --- /dev/null +++ b/public/kbn-polar-vis.js @@ -0,0 +1,88 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { AggGroupNames } from '../../../src/plugins/data/public'; +import { Schemas } from '../../../src/plugins/vis_default_editor/public'; + +import tableVisTemplate from './kbn-polar-vis.html'; +import { getKbnPolarVisualizationController } from './vis_controller'; +import { kbnPolarRequestHandler } from './data_load/kbn-polar-request-handler'; +import { kbnPolarResponseHandler } from './data_load/kbn-polar-response-handler'; +import { KbnPolarOptions } from './components/kbn_polar_vis_options_lazy'; +import { VIS_EVENT_TO_TRIGGER } from '../../../src/plugins/visualizations/public'; +import './index.scss' +import image from './images/icon-polar.svg'; + + +// define the visType object, which kibana will use to display and configure new Vis object of this type. +export function kbnPolarVisTypeDefinition(core, context) { + return { + type: 'polar', + name: 'kbn_polar', + title: i18n.translate('visTypeKbnPolar.visTitle', { + defaultMessage: 'Polar' + }), + icon: image, + description: i18n.translate('visTypeKbnPolar.visDescription', { + defaultMessage: 'Visualize Polar charts' + }), + visualization: getKbnPolarVisualizationController(core, context), + getSupportedTriggers: () => { + return [VIS_EVENT_TO_TRIGGER.filter]; + }, + visConfig: { + defaults: {}, + template: tableVisTemplate + }, + editorConfig: { + optionsTemplate: KbnPolarOptions, + schemas: new Schemas([ + { + group: AggGroupNames.Metrics, + name: 'metric', + title: 'Metric', + aggFilter: ['!geo_centroid', '!geo_bounds'], + aggSettings: { + top_hits: { + allowStrings: false + } + }, + max: 1, + min: 1, + defaults: [{ type: 'count', schema: 'metric' }] + }, + { + group: AggGroupNames.Buckets, + name: 'field', + title: "Field", + min: 1, + max: 1, + aggFilter: ['terms', 'filters'] + } + ]) + }, + implementsRenderComplete: true, + requestHandler: kbnPolarRequestHandler, + responseHandler: kbnPolarResponseHandler, + hierarchicalData: (vis) => { + return true; + } + }; +} diff --git a/public/kbn_polar.js b/public/kbn_polar.js deleted file mode 100644 index d2a24b9..0000000 --- a/public/kbn_polar.js +++ /dev/null @@ -1,74 +0,0 @@ -import 'plugins/kbn_polar/kbn_polar.less'; -import 'plugins/kbn_polar/kbn_polar_controller'; -import 'ui/agg_table'; -import 'ui/agg_table/agg_table_group'; -import 'ui/agg_table'; -import 'ui/agg_table/agg_table_group'; - -import { CATEGORY } from 'ui/vis/vis_category'; -import { VisFactoryProvider } from 'ui/vis/vis_factory'; -import { Schemas } from 'ui/vis/editors/default/schemas'; -import PolarVisTemplate from 'plugins/kbn_polar/kbn_polar.html'; -import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; -import image from './images/polar.svg'; -// we need to load the css ourselves - -// we also need to load the controller and used by the template - -// our params are a bit complex so we will manage them with a directive - -// require the directives that we use as well - -// register the provider with the visTypes registry -VisTypesRegistryProvider.register(PolarVisTypeProvider); - -// define the PolarVisType -function PolarVisTypeProvider(Private) { - const VisFactory = Private(VisFactoryProvider); - - // define the PolarVisController which is used in the template - // by angular's ng-controller directive - - // return the visType object, which kibana will use to display and configure new - // Vis object of this type. - return VisFactory.createAngularVisualization({ - name: 'polar', - title: 'Polar', - image, - description: 'Display values in a polar chart', - category: CATEGORY.BASIC, - visConfig: { - template: PolarVisTemplate - }, - editorConfig: { - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Metric', - aggFilter: '!geo_centroid', - min: 1, - max: 1, - defaults: [ - { type: 'count', schema: 'metric' } - ] - }, - { - group: 'buckets', - name: 'field', - title: 'Field', - max: 1, - min: 1, - aggFilter: ['terms'] - } - ]) - }, - implementsRenderComplete: true, - hierarchicalData: function (vis) { - return true; - } - - }); -} - -export default PolarVisTypeProvider; diff --git a/public/kbn_polar.less b/public/kbn_polar.scss old mode 100644 new mode 100755 similarity index 61% rename from public/kbn_polar.less rename to public/kbn_polar.scss index 8da5175..e780250 --- a/public/kbn_polar.less +++ b/public/kbn_polar.scss @@ -1,3 +1,8 @@ +.embPanel__content[data-error], .embPanel__content[data-loading]{ + pointer-events: all !important; + filter: none !important; +} + .kbn-polar { width: 100%; height: 100%; @@ -8,4 +13,4 @@ align-items: center; overflow-x: hidden; overflow-y: hidden; -} +} \ No newline at end of file diff --git a/public/kbn_polar_controller.js b/public/kbn_polar_controller.js deleted file mode 100644 index d0a740e..0000000 --- a/public/kbn_polar_controller.js +++ /dev/null @@ -1,87 +0,0 @@ -import { uiModules } from 'ui/modules'; -import { assign } from 'lodash'; - -// get the kibana/kbn_polar module, and make sure that it requires the "kibana" module if it -// didn't already -const module = uiModules.get('kibana/kbn_polar', ['kibana']); - -// add a controller to tha module, which will transform the esResponse into a -// tabular format that we can pass to the table directive -module.controller('KbnPolarVisController', function ($scope, $element, $timeout, Private) { - const uiStateSort = ($scope.uiState) ? $scope.uiState.get('vis.params.sort') : {}; - assign($scope.vis.params.sort, uiStateSort); - - var Chartjs = require('chart.js'); - - const randomColor = require('randomcolor'); - - $scope.$watchMulti(['esResponse'], function ([resp]) { - if($scope.polarchart){ - $scope.polarchart.destroy() - } - - if(resp){ - var id_firstfield = '0' - var id_secondfield; - var id_x = '1' - var id_y = '2' - var id_size = '3' - var dicColor = {} - //Names of the field that have been selected - if ($scope.vis.aggs.bySchemaName['field']) { - var firstFieldAggId = $scope.vis.aggs.bySchemaName['field'][0].id; - var fieldAggName = $scope.vis.aggs.bySchemaName['field'][0].params.field.displayName; - } - - - // Retrieve the metrics aggregation configured - if($scope.vis.aggs.bySchemaName['metric']){ - var metricsAgg_xAxis = $scope.vis.aggs.bySchemaName['metric'][0]; - if ($scope.vis.aggs.bySchemaName['metric'][0].type.name != "count"){ - var metricsAgg_xAxis_name = $scope.vis.aggs.bySchemaName['metric'][0].params.field.displayName; - }else{ - var metricsAgg_xAxis_name = "" - } - var metricsAgg_xAxis_title = $scope.vis.aggs.bySchemaName['metric'][0].type.title - } - - - var labels = [] - var dataParsed = []; - for (let index = 0; index < resp.tables[0].rows.length; index++) { - const bucket = resp.tables[0].rows[index]; - labels.push(bucket[0]) - dataParsed.push(bucket[1]) - } - var colors = randomColor({ hue: 'random', luminosity: 'bright', count: 200 }); - var dataComplete = { - datasets: [{ - data: dataParsed, - backgroundColor: colors //["rgb(255, 99, 132)", "rgb(75, 192, 192)", "rgb(255, 205, 86)", "rgb(201, 203, 207)", "rgb(54, 162, 235)"] - }], - labels: labels - } - } - - $timeout(function () { - //DOM has finished rendering - var canvas = document.getElementById('polar_chart_' + $scope.$id); - var ctx = canvas.getContext('2d'); - ctx.clearRect(0, 0, canvas.width, canvas.height); - var options = { - legend: { - display: false - } - } - - $scope.polarchart = new Chartjs(ctx, { - data: dataComplete, - type: 'polarArea', - options: options - }); - }); - - - - }); -}); diff --git a/public/legacy.ts b/public/legacy.ts new file mode 100755 index 0000000..5a42fac --- /dev/null +++ b/public/legacy.ts @@ -0,0 +1,38 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { PluginInitializerContext } from '../../../src/core/public'; +import { npSetup, npStart } from 'ui/new_platform'; +import { plugin } from '.'; + +import { TablePluginSetupDependencies } from './plugin'; +import { TablePluginStartDependencies } from './plugin'; + +const plugins: Readonly = { + visualizations: npSetup.plugins.visualizations, +}; + +const startData: Readonly = { + data: npStart.plugins.data +} + +const pluginInstance = plugin({} as PluginInitializerContext); + +export const setup = pluginInstance.setup(npSetup.core, plugins); +export const start = pluginInstance.start(npStart.core, startData); diff --git a/public/paginated_table/_index.scss b/public/paginated_table/_index.scss new file mode 100755 index 0000000..7b44941 --- /dev/null +++ b/public/paginated_table/_index.scss @@ -0,0 +1 @@ +@import './paginated_table'; diff --git a/public/paginated_table/paginated_table.html b/public/paginated_table/paginated_table.html new file mode 100755 index 0000000..5bdea44 --- /dev/null +++ b/public/paginated_table/paginated_table.html @@ -0,0 +1,53 @@ + +
+ + + + + + + + + + + + + +
+ + + + + + +
{{col.total}}
+
+ + + +
+
diff --git a/public/paginated_table/paginated_table.js b/public/paginated_table/paginated_table.js new file mode 100755 index 0000000..cfa816a --- /dev/null +++ b/public/paginated_table/paginated_table.js @@ -0,0 +1,125 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import _ from 'lodash'; + +import AggConfigResult from '../data_load/agg_config_result'; +import paginatedTableTemplate from './paginated_table.html'; + +export function PolarPaginatedTable($filter) { + const orderBy = $filter('orderBy'); + + return { + restrict: 'E', + template: paginatedTableTemplate, + transclude: true, + scope: { + table: '=', + rows: '=', + columns: '=', + linkToTop: '=', + perPage: '=?', + showBlankRows: '=?', + sortHandler: '=?', + sort: '=?', + showSelector: '=?', + showTotal: '=', + totalFunc: '=', + filter: '=' + }, + controllerAs: 'polarPaginatedTable', + controller: function ($scope) { + const self = this; + self.sort = { + columnIndex: null, + direction: null + }; + + self.sortColumn = function (colIndex, sortDirection = 'asc') { + const col = $scope.columns[colIndex]; + + if (!col) return; + if (col.sortable === false) return; + + if (self.sort.columnIndex === colIndex) { + const directions = { + null: 'asc', + 'asc': 'desc', + 'desc': null + }; + sortDirection = directions[self.sort.direction]; + } + + self.sort.columnIndex = colIndex; + self.sort.direction = sortDirection; + if ($scope.sort) { + _.assign($scope.sort, self.sort); + } + }; + + self.rowsToShow = function (numRowsPerPage, actualNumRowsOnThisPage) { + if ($scope.showBlankRows === false) { + return actualNumRowsOnThisPage; + } else { + return numRowsPerPage; + } + }; + + function valueGetter(row) { + let value = row[self.sort.columnIndex]; + if (value && value.value != null) value = value.value; + if (typeof value === 'boolean') value = value ? 0 : 1; + if (value instanceof AggConfigResult && value.valueOf() === null) value = false; + return value; + } + + // Set the sort state if it is set + if ($scope.sort && $scope.sort.columnIndex !== null) { + self.sortColumn($scope.sort.columnIndex, $scope.sort.direction); + } + function resortRows() { + const newSort = $scope.sort; + if (newSort && !_.isEqual(newSort, self.sort)) { + self.sortColumn(newSort.columnIndex, newSort.direction); + } + + if (!$scope.rows || !$scope.columns) { + $scope.sortedRows = false; + return; + } + + const sort = self.sort; + if (sort.direction == null) { + $scope.sortedRows = $scope.rows.slice(0); + } else { + $scope.sortedRows = orderBy($scope.rows, valueGetter, sort.direction === 'desc'); + } + } + + + // update the sortedRows result + $scope.$watchMulti([ + 'rows', + 'columns', + '[]sort', + '[]polarPaginatedTable.sort' + ], resortRows); + } + }; +} diff --git a/public/paginated_table/paginated_table.scss b/public/paginated_table/paginated_table.scss new file mode 100755 index 0000000..e9d7607 --- /dev/null +++ b/public/paginated_table/paginated_table.scss @@ -0,0 +1,5 @@ +// all basic CSS is inherited from core 'Data Table' + +.kbnAggTable__paginated tr:hover td.cell-custom-background-hover, .kbnAggTable__paginated td.cell-custom-background-hover .kbnTableCellFilter { + opacity: .8; +} \ No newline at end of file diff --git a/public/paginated_table/rows.js b/public/paginated_table/rows.js new file mode 100755 index 0000000..6535cc6 --- /dev/null +++ b/public/paginated_table/rows.js @@ -0,0 +1,154 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import $ from 'jquery'; +import _ from 'lodash'; +import AggConfigResult from '../data_load/agg_config_result'; +import tableCellFilterHtml from './table_cell_filter.html'; + +export function KbnPolarRows($compile) { + return { + restrict: 'A', + link: function ($scope, $el, attr) { + function addCell($tr, contents, iColumn, row) { + function createCell() { + return $(document.createElement('td')); + } + + function createFilterableCell(aggConfigResult) { + const $template = $(tableCellFilterHtml); + $template.addClass('kbnKbnPolarCellFilter__hover'); + + const scope = $scope.$new(); + + scope.onFilterClick = (event, negate) => { + // Don't add filter if a link was clicked. + if ($(event.target).is('a')) { + return; + } + + $scope.filter({ data: [{ + table: $scope.table, + row: $scope.rows.findIndex(r => r === row), + column: iColumn, + value: aggConfigResult.value + }], negate }); + }; + + return $compile($template)(scope); + } + + let $cell; + let $cellContent; + + if (contents instanceof AggConfigResult) { + const field = contents.aggConfig.getField(); + const isCellContentFilterable = + contents.aggConfig.isFilterable() + && (!field || field.filterable); + + if (isCellContentFilterable) { + $cell = createFilterableCell(contents); + $cellContent = $cell.find('[data-cell-content]'); + } else { + $cell = $cellContent = createCell(); + } + + if (row.cssStyle !== undefined || contents.cssStyle !== undefined) { + let cssStyle = (row.cssStyle !== undefined) ? row.cssStyle : ''; + if (contents.cssStyle !== undefined) { + cssStyle += '; ' + contents.cssStyle; + } + $cell.attr('style', cssStyle); + if (cssStyle.indexOf('background') !== -1) { + $cell.addClass('cell-custom-background-hover'); + } + } + + // An AggConfigResult can "enrich" cell contents by applying a field formatter, + // which we want to do if possible. + contents = contents.toString('html'); + } else { + $cell = $cellContent = createCell(); + } + + if (_.isObject(contents)) { + + if (contents.class) { + $cellContent.addClass(contents.class); + } + + if (contents.scope) { + $cellContent = $compile($cellContent.prepend(contents.markup))(contents.scope); + } else { + $cellContent.prepend(contents.markup); + } + + if (contents.attr) { + $cellContent.attr(contents.attr); + } + } else { + if (contents === '') { + $cellContent.prepend(' '); + } else { + $cellContent.prepend(contents); + } + } + + $tr.append($cell); + } + + function maxRowSize(max, row) { + return Math.max(max, row.length); + } + + $scope.$watchMulti([ + attr.kbnPolarRows, + attr.kbnPolarRowsMin + ], function (vals) { + let rows = vals[0]; + const min = vals[1]; + + $el.empty(); + + if (!Array.isArray(rows)) rows = []; + const width = rows.reduce(maxRowSize, 0); + + if (isFinite(min) && rows.length < min) { + // clone the rows so that we can add elements to it without upsetting the original + rows = _.clone(rows); + // crate the empty row which will be pushed into the row list over and over + const emptyRow = new Array(width); + // fill the empty row with values + _.times(width, function (i) { emptyRow[i] = ''; }); + // push as many empty rows into the row array as needed + _.times(min - rows.length, function () { rows.push(emptyRow); }); + } + + rows.forEach(function (row) { + const $tr = $(document.createElement('tr')).appendTo($el); + $scope.columns.forEach(function (column, iColumn) { + const value = row[iColumn]; + addCell($tr, value, iColumn, row); + }); + }); + }); + } + }; +} diff --git a/public/paginated_table/table_cell_filter.html b/public/paginated_table/table_cell_filter.html new file mode 100755 index 0000000..ae5ea3e --- /dev/null +++ b/public/paginated_table/table_cell_filter.html @@ -0,0 +1,23 @@ + +
+ + + + + +
+ diff --git a/public/plugin.ts b/public/plugin.ts new file mode 100755 index 0000000..0a40690 --- /dev/null +++ b/public/plugin.ts @@ -0,0 +1,66 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../src/core/public'; +import { VisualizationsSetup } from '../../../src/plugins/visualizations/public'; + +import { kbnPolarVisTypeDefinition } from './kbn-polar-vis'; + +import { DataPublicPluginStart } from '../../../src/plugins/data/public'; +import { setFormatService, setKibanaLegacy, setNotifications, setQueryService, setSearchService } from './services'; +import { KibanaLegacyStart } from '../../../src/plugins/kibana_legacy/public'; + + +/** @internal */ +export interface TablePluginSetupDependencies { + visualizations: VisualizationsSetup; +} + +/** @internal */ +export interface TablePluginStartDependencies { + data: DataPublicPluginStart; + kibanaLegacy: KibanaLegacyStart; +} + +/** @internal */ +export class KbnPolarPlugin implements Plugin, void> { + initializerContext: PluginInitializerContext; + createBaseVisualization: any; + + constructor(initializerContext: PluginInitializerContext) { + this.initializerContext = initializerContext; + } + + public async setup( + core: CoreSetup, + { visualizations }: TablePluginSetupDependencies + ) { + visualizations.createBaseVisualization( + kbnPolarVisTypeDefinition(core, this.initializerContext) + ); + + } + + public start(core: CoreStart, { data, kibanaLegacy }: TablePluginStartDependencies) { + setFormatService(data.fieldFormats); + setKibanaLegacy(kibanaLegacy); + setNotifications(core.notifications); + setQueryService(data.query); + setSearchService(data.search); + } +} diff --git a/public/services.ts b/public/services.ts new file mode 100755 index 0000000..9661f19 --- /dev/null +++ b/public/services.ts @@ -0,0 +1,43 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { createGetterSetter } from '../../../src/plugins/kibana_utils/public'; +import { NotificationsStart } from '../../../src/core/public'; +import { DataPublicPluginStart } from '../../../src/plugins/data/public'; +import { KibanaLegacyStart } from '../../../src/plugins/kibana_legacy/public'; + +export const [getFormatService, setFormatService] = createGetterSetter< + DataPublicPluginStart['fieldFormats'] +>('table data.fieldFormats'); + +export const [getKibanaLegacy, setKibanaLegacy] = createGetterSetter( + 'table kibanaLegacy' +); + +export const [getNotifications, setNotifications] = createGetterSetter< + NotificationsStart +>('Notifications'); + +export const [getQueryService, setQueryService] = createGetterSetter< + DataPublicPluginStart['query'] +>('Query'); + +export const [getSearchService, setSearchService] = createGetterSetter< + DataPublicPluginStart['search'] +>('Search'); diff --git a/public/table_vis_legacy_module.ts b/public/table_vis_legacy_module.ts new file mode 100755 index 0000000..25e7512 --- /dev/null +++ b/public/table_vis_legacy_module.ts @@ -0,0 +1,41 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { IModule } from 'angular'; + +// @ts-ignore +import { KbnPolarVisController } from './kbn-polar-vis-controller.js'; +// @ts-ignore +import { KbnPolarAggTable } from './agg_table/agg_table'; +// @ts-ignore +import { KbnPolarAggTableGroup } from './agg_table/agg_table_group'; +// @ts-ignore +import { KbnPolarRows } from './paginated_table/rows'; +// @ts-ignore +import { PolarPaginatedTable } from './paginated_table/paginated_table'; + +/** @internal */ +export const initTableVisLegacyModule = (angularIns: IModule): void => { + angularIns + .controller('KbnPolarVisController', KbnPolarVisController) + .directive('kbnPolarAggTable', KbnPolarAggTable) + .directive('kbnPolarAggTableGroup', KbnPolarAggTableGroup) + .directive('kbnPolarRows', KbnPolarRows) + .directive('polarPaginatedTable', PolarPaginatedTable); +}; diff --git a/public/vis_controller.ts b/public/vis_controller.ts new file mode 100755 index 0000000..9fdc99f --- /dev/null +++ b/public/vis_controller.ts @@ -0,0 +1,121 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { CoreSetup, PluginInitializerContext } from 'kibana/public'; +import angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular'; +import $ from 'jquery'; + +import { VisParams, ExprVis } from '../../../src/plugins/visualizations/public'; +import { getAngularModule } from './get_inner_angular'; +import { getKibanaLegacy } from './services'; +import { initTableVisLegacyModule } from './table_vis_legacy_module'; + +const innerAngularName = 'kibana/kbn_polar_vis'; + +export function getKbnPolarVisualizationController( + core: CoreSetup, + context: PluginInitializerContext +) { + return class KbnPolarVisualizationController { + private tableVisModule: IModule | undefined; + private injector: auto.IInjectorService | undefined; + el: JQuery; + vis: ExprVis; + $rootScope: IRootScopeService | null = null; + $scope: (IScope & { [key: string]: any }) | undefined; + $compile: ICompileService | undefined; + + constructor(domeElement: Element, vis: ExprVis) { + this.el = $(domeElement); + this.vis = vis; + } + + getInjector() { + if (!this.injector) { + const mountpoint = document.createElement('div'); + mountpoint.setAttribute('style', 'height: 100%; width: 100%;'); + this.injector = angular.bootstrap(mountpoint, [innerAngularName]); + this.el.append(mountpoint); + } + + return this.injector; + } + + async initLocalAngular() { + if (!this.tableVisModule) { + const [coreStart] = await core.getStartServices(); + this.tableVisModule = getAngularModule(innerAngularName, coreStart, context); + initTableVisLegacyModule(this.tableVisModule); + } + } + + async render(esResponse: object, visParams: VisParams) { + getKibanaLegacy().loadFontAwesome(); + await this.initLocalAngular(); + + return new Promise(async (resolve, reject) => { + if (!this.$rootScope) { + const $injector = this.getInjector(); + this.$rootScope = $injector.get('$rootScope'); + this.$compile = $injector.get('$compile'); + } + const updateScope = () => { + if (!this.$scope) { + return; + } + + // How things get into this $scope? + // To inject variables into this $scope there's the following pipeline of stuff to check: + // - visualize_embeddable => that's what the editor creates to wrap this Angular component + // - build_pipeline => it serialize all the params into an Angular template compiled on the fly + // - table_vis_fn => unserialize the params and prepare them for the final React/Angular bridge + // - visualization_renderer => creates the wrapper component for this controller and passes the params + // + // In case some prop is missing check into the top of the chain if they are available and check + // the list above that it is passing through + this.$scope.vis = this.vis; + this.$scope.visState = { params: visParams, title: visParams.title }; + this.$scope.esResponse = esResponse; + + this.$scope.visParams = visParams; + this.$scope.renderComplete = resolve; + this.$scope.renderFailed = reject; + this.$scope.resize = Date.now(); + this.$scope.$apply(); + }; + + if (!this.$scope && this.$compile) { + this.$scope = this.$rootScope.$new(); + this.$scope.uiState = this.vis.getUiState(); + updateScope(); + this.el.find('div').append(this.$compile(this.vis.type!.visConfig.template)(this.$scope)); + this.$scope.$apply(); + } else { + updateScope(); + } + }); + } + + destroy() { + if (this.$rootScope) { + this.$rootScope.$destroy(); + this.$rootScope = null; + } + } + }; +} diff --git a/target/public/.kbn-optimizer-cache b/target/public/.kbn-optimizer-cache new file mode 100644 index 0000000..895dfac --- /dev/null +++ b/target/public/.kbn-optimizer-cache @@ -0,0 +1,231 @@ +{ + "bundleRefExportIds": [ + "plugin/data/common", + "plugin/data/public", + "plugin/inspector/public", + "plugin/kibanaLegacy/public", + "plugin/kibanaUtils/public", + "plugin/share/public", + "plugin/visDefaultEditor/public", + "plugin/visualizations/public" + ], + "optimizerCacheKey": { + "lastCommit": "13fe63966573dc0280b92bbc1624f61bc7bdc5b4", + "bootstrap": "# this is only human readable for debugging, please don't try to parse this\n@kbn/babel-preset:d58bf73e50029d7fd3980be85f911ddc57810adb\n@kbn/config-schema:a415d3c93ada605610585ac6d6ad25e520bfe85b\n@kbn/dev-utils:b69b52df5eabbab0018b5c20071af2f85ac2a8db\n@kbn/expect:99d9fd3f3047da91954adace22b74254a91be5df\n@kbn/i18n:e65f0c5b66dde65e0edc7b5f830e769cdc41a07d\n@kbn/monaco:a7e1652f1b4e594141aa8679b5c0699297397bd9\n@kbn/optimizer:ba456337be45d664c72b2b51c30fff50b0ec6127\n@kbn/std:0310eee2f56a0db0b0841da78dfe9a2fe428f0f3\n@kbn/ui-shared-deps:c443538a57621cd8586cc5e966bf82e924faddce\n@kbn/utility-types:2cc6aeb1f2ee0693b67c7b7d932f93208274a453\n@kbn/utils:6205ee44b09fcfb6c7d8d07ee1c6c95c4e7108bc", + "deletedPaths": [], + "modifiedTimes": {}, + "workerConfig": { + "dist": false, + "repoRoot": "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic", + "optimizerCacheKey": "â™»", + "themeTags": [ + "v7dark", + "v7light" + ], + "browserslistEnv": "dev" + } + }, + "cacheKey": { + "spec": { + "type": "plugin", + "id": "kbnPolar", + "publicDirNames": [ + "public" + ], + "contextDir": "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar", + "sourceRoot": "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic", + "outputDir": "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/target/public", + "manifestPath": "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/kibana.json" + }, + "mtimes": { + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/functions/_colors.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/functions/_index.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/functions/_math.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_beta_badge.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_button.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_form.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_header.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_helpers.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_icons.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_index.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_loading.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_panel.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_popover.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_range.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_responsive.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_shadow.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_size.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_states.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_tool_tip.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_typography.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_animations.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_borders.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_buttons.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_colors.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_form.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_header.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_index.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_panel.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_responsive.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_shadows.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_size.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_states.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_tool_tip.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_typography.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_z_index.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/themes/eui/eui_colors_dark.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/themes/eui/eui_colors_light.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/themes/eui/eui_globals.scss": 1608569664977, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/filesaver/package.json": 1606730964406, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/angular-recursion/package.json": 1606730979842, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/angular-sanitize/package.json": 1606731004679, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/css-loader/package.json": 1606730969850, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/package.json": 1606729784960, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/style-loader/package.json": 1608569669929, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/webpack/package.json": 1606729793927, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/elastic-safer-lodash-set/index.js": 1606388457592.2944, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/elastic-safer-lodash-set/lodash/_baseSet.js": 1606388457532.2952, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/elastic-safer-lodash-set/lodash/set.js": 1606388457504.2954, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/elastic-safer-lodash-set/lodash/setWith.js": 1606388457516.2954, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/kbn-optimizer/postcss.config.js": 1608569291536.7827, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/kbn-optimizer/target/worker/entry_point_creator.js": 1608569944255.3154, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/kbn-ui-shared-deps/public_path_module_creator.js": 1606388316189.8308, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/kibana.json": 1612110627938.6672, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/chart.js/package.json": 1612092598922, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/chartjs-color-string/package.json": 1612092598923, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/chartjs-color/package.json": 1612092598914, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/color-convert/package.json": 1608569689366, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/color-name/package.json": 1606729795899, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/randomcolor/package.json": 1612092598927, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/agg_table/agg_table_group.html": 1612111061051.3674, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/agg_table/agg_table_group.js": 1612111074107.2498, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/agg_table/agg_table.html": 1612111089399.1108, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/agg_table/agg_table.js": 1612111074107.2498, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/components/kbn_polar_vis_options_lazy.tsx": 1612111170648, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/components/kbn_polar_vis_options.tsx": 1612111165820, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/agg_config_result.js": 1612110598606.8325, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kbn-polar-request-handler.js": 1612111148313, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kbn-polar-response-handler.js": 1612111152323, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kibana_cloned_code/build_tabular_inspector_data.ts": 1612110598606.8325, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kibana_cloned_code/courier.ts": 1612110598606.8325, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kibana_cloned_code/create_filter.ts": 1612110598606.8325, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kibana_cloned_code/utils.ts": 1612110598606.8325, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/field_formatter.ts": 1612110598610.8325, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/get_inner_angular.ts": 1612111051863.4497, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/images/icon-polar.svg": 1612111013051.7935, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/index.scss": 1612111051859.45, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/index.ts": 1612111074107.2498, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/kbn_polar.scss": 1612111331152.7952, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/kbn-polar-vis-controller.js": 1612111657257.4233, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/kbn-polar-vis.html": 1612111458255.507, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/kbn-polar-vis.js": 1612111380492.2998, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/paginated_table/paginated_table.html": 1612111089399.1108, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/paginated_table/paginated_table.js": 1612111097203.0393, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/paginated_table/rows.js": 1612111082143.1768, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/paginated_table/table_cell_filter.html": 1612110598614.8325, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/plugin.ts": 1612111082131.177, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/services.ts": 1612110598618.8325, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/table_vis_legacy_module.ts": 1612111097203.0393, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/vis_controller.ts": 1612111074107.2498, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/src/core/public/core_app/styles/_globals_v7dark.scss": 1608569291588.7822, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/src/core/public/core_app/styles/_globals_v7light.scss": 1608569291588.7822, + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/src/core/public/core_app/styles/_mixins.scss": 1608569291588.7822 + } + }, + "moduleCount": 160, + "workUnits": 700, + "files": [ + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/functions/_colors.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/functions/_index.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/functions/_math.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_beta_badge.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_button.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_form.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_header.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_helpers.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_icons.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_index.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_loading.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_panel.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_popover.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_range.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_responsive.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_shadow.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_size.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_states.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_tool_tip.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/mixins/_typography.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_animations.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_borders.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_buttons.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_colors.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_form.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_header.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_index.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_panel.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_responsive.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_shadows.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_size.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_states.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_tool_tip.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_typography.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/global_styling/variables/_z_index.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/themes/eui/eui_colors_dark.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/themes/eui/eui_colors_light.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/eui/src/themes/eui/eui_globals.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/filesaver/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/angular-recursion/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/angular-sanitize/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/css-loader/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/style-loader/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/webpack/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/elastic-safer-lodash-set/index.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/elastic-safer-lodash-set/lodash/_baseSet.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/elastic-safer-lodash-set/lodash/set.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/elastic-safer-lodash-set/lodash/setWith.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/kbn-optimizer/postcss.config.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/kbn-optimizer/target/worker/entry_point_creator.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/packages/kbn-ui-shared-deps/public_path_module_creator.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/kibana.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/chart.js/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/chartjs-color-string/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/chartjs-color/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/color-convert/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/color-name/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/node_modules/randomcolor/package.json", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/agg_table/agg_table_group.html", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/agg_table/agg_table_group.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/agg_table/agg_table.html", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/agg_table/agg_table.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/components/kbn_polar_vis_options_lazy.tsx", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/components/kbn_polar_vis_options.tsx", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/agg_config_result.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kbn-polar-request-handler.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kbn-polar-response-handler.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kibana_cloned_code/build_tabular_inspector_data.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kibana_cloned_code/courier.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kibana_cloned_code/create_filter.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/data_load/kibana_cloned_code/utils.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/field_formatter.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/get_inner_angular.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/images/icon-polar.svg", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/index.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/index.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/kbn_polar.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/kbn-polar-vis-controller.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/kbn-polar-vis.html", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/kbn-polar-vis.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/paginated_table/paginated_table.html", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/paginated_table/paginated_table.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/paginated_table/rows.js", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/paginated_table/table_cell_filter.html", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/plugin.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/services.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/table_vis_legacy_module.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/plugins/kbn_polar/public/vis_controller.ts", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/src/core/public/core_app/styles/_globals_v7dark.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/src/core/public/core_app/styles/_globals_v7light.scss", + "/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/src/core/public/core_app/styles/_mixins.scss" + ] +} \ No newline at end of file diff --git a/target/public/kbnPolar.chunk.0.js b/target/public/kbnPolar.chunk.0.js new file mode 100644 index 0000000..dbe9d45 --- /dev/null +++ b/target/public/kbnPolar.chunk.0.js @@ -0,0 +1,51 @@ +(window["kbnPolar_bundle_jsonpfunction"] = window["kbnPolar_bundle_jsonpfunction"] || []).push([[0],{ + +/***/ "./public/components/kbn_polar_vis_options.tsx": +/*!*****************************************************!*\ + !*** ./public/components/kbn_polar_vis_options.tsx ***! + \*****************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return KbnPolarOptions; }); +/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); +/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +function KbnPolarOptions({ + stateParams, + setValue +}) { + return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + className: "kbn-polar-vis-params" + }); +} // default export required for React.Lazy +// eslint-disable-next-line import/no-default-export + + + + +/***/ }) + +}]); +//# sourceMappingURL=kbnPolar.chunk.0.js.map \ No newline at end of file diff --git a/target/public/kbnPolar.chunk.0.js.map b/target/public/kbnPolar.chunk.0.js.map new file mode 100644 index 0000000..c7956e9 --- /dev/null +++ b/target/public/kbnPolar.chunk.0.js.map @@ -0,0 +1 @@ +{"version":3,"file":"kbnPolar.chunk.0.js","sources":["/plugin:kbnPolar/plugins/kbn_polar/public/components/kbn_polar_vis_options.tsx"],"sourcesContent":["/*\n * Licensed to Elasticsearch B.V. under one or more contributor\n * license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright\n * ownership. Elasticsearch B.V. licenses this file to you under\n * the Apache License, Version 2.0 (the \"License\"); you may\n * not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\nimport React from 'react';\n\nfunction KbnPolarOptions({\n stateParams,\n setValue\n}) {\n return /*#__PURE__*/React.createElement(\"div\", {\n className: \"kbn-polar-vis-params\"\n });\n} // default export required for React.Lazy\n// eslint-disable-next-line import/no-default-export\n\n\nexport { KbnPolarOptions as default };"],"mappings":";;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;A","sourceRoot":""} \ No newline at end of file diff --git a/target/public/kbnPolar.plugin.js b/target/public/kbnPolar.plugin.js new file mode 100644 index 0000000..0a8162c --- /dev/null +++ b/target/public/kbnPolar.plugin.js @@ -0,0 +1,21669 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ function webpackJsonpCallback(data) { +/******/ var chunkIds = data[0]; +/******/ var moreModules = data[1]; +/******/ +/******/ +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(data); +/******/ +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ +/******/ }; +/******/ +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ "kbnPolar": 0 +/******/ }; +/******/ +/******/ +/******/ +/******/ // script path function +/******/ function jsonpScriptSrc(chunkId) { +/******/ return __webpack_require__.p + "kbnPolar.chunk." + chunkId + ".js" +/******/ } +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = function requireEnsure(chunkId) { +/******/ var promises = []; +/******/ +/******/ +/******/ // JSONP chunk loading for javascript +/******/ +/******/ var installedChunkData = installedChunks[chunkId]; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[2]); +/******/ } else { +/******/ // setup Promise in chunk cache +/******/ var promise = new Promise(function(resolve, reject) { +/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; +/******/ }); +/******/ promises.push(installedChunkData[2] = promise); +/******/ +/******/ // start chunk loading +/******/ var script = document.createElement('script'); +/******/ var onScriptComplete; +/******/ +/******/ script.charset = 'utf-8'; +/******/ script.timeout = 120; +/******/ if (__webpack_require__.nc) { +/******/ script.setAttribute("nonce", __webpack_require__.nc); +/******/ } +/******/ script.src = jsonpScriptSrc(chunkId); +/******/ +/******/ // create error before stack unwound to get useful stacktrace later +/******/ var error = new Error(); +/******/ onScriptComplete = function (event) { +/******/ // avoid mem leaks in IE. +/******/ script.onerror = script.onload = null; +/******/ clearTimeout(timeout); +/******/ var chunk = installedChunks[chunkId]; +/******/ if(chunk !== 0) { +/******/ if(chunk) { +/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); +/******/ var realSrc = event && event.target && event.target.src; +/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; +/******/ error.name = 'ChunkLoadError'; +/******/ error.type = errorType; +/******/ error.request = realSrc; +/******/ chunk[1](error); +/******/ } +/******/ installedChunks[chunkId] = undefined; +/******/ } +/******/ }; +/******/ var timeout = setTimeout(function(){ +/******/ onScriptComplete({ type: 'timeout', target: script }); +/******/ }, 120000); +/******/ script.onerror = script.onload = onScriptComplete; +/******/ document.head.appendChild(script); +/******/ } +/******/ } +/******/ return Promise.all(promises); +/******/ }; +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // on error function for async loading +/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; +/******/ +/******/ var jsonpArray = window["kbnPolar_bundle_jsonpfunction"] = window["kbnPolar_bundle_jsonpfunction"] || []; +/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); +/******/ jsonpArray.push = webpackJsonpCallback; +/******/ jsonpArray = jsonpArray.slice(); +/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); +/******/ var parentJsonpFunction = oldJsonpFunction; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = "../../packages/kbn-optimizer/target/worker/entry_point_creator.js"); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "../../node_modules/@elastic/filesaver/file-saver.js": +/*!*********************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/@elastic/filesaver/file-saver.js ***! + \*********************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* FileSaver.js + * A saveAs() FileSaver implementation. + * 1.1.20150716 + * + * By Eli Grey, http://eligrey.com + * License: X11/MIT + * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md + */ + +/*global self */ +/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ + +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ + +var saveAs = saveAs || (function(view) { + "use strict"; + // IE <10 is explicitly unsupported + if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { + return; + } + var + doc = view.document + // only get URL when necessary in case Blob.js hasn't overridden it yet + , get_URL = function() { + return view.URL || view.webkitURL || view; + } + , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") + , can_use_save_link = "download" in save_link + , click = function(node) { + var event = new MouseEvent("click"); + node.dispatchEvent(event); + } + , webkit_req_fs = view.webkitRequestFileSystem + , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem + , throw_outside = function(ex) { + (view.setImmediate || view.setTimeout)(function() { + throw ex; + }, 0); + } + , force_saveable_type = "application/octet-stream" + , fs_min_size = 0 + // See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and + // https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047 + // for the reasoning behind the timeout and revocation flow + , arbitrary_revoke_timeout = 500 // in ms + , revoke = function(file) { + var revoker = function() { + if (typeof file === "string") { // file is an object URL + get_URL().revokeObjectURL(file); + } else { // file is a File + file.remove(); + } + }; + if (view.chrome) { + revoker(); + } else { + setTimeout(revoker, arbitrary_revoke_timeout); + } + } + , dispatch = function(filesaver, event_types, event) { + event_types = [].concat(event_types); + var i = event_types.length; + while (i--) { + var listener = filesaver["on" + event_types[i]]; + if (typeof listener === "function") { + try { + listener.call(filesaver, event || filesaver); + } catch (ex) { + throw_outside(ex); + } + } + } + } + , auto_bom = function(blob) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob(["\ufeff", blob], {type: blob.type}); + } + return blob; + } + , FileSaver = function(blob, name, no_auto_bom) { + if (!no_auto_bom) { + blob = auto_bom(blob); + } + // First try a.download, then web filesystem, then object URLs + var + filesaver = this + , type = blob.type + , blob_changed = false + , object_url + , target_view + , dispatch_all = function() { + dispatch(filesaver, "writestart progress write writeend".split(" ")); + } + // on any filesys errors revert to saving with object URLs + , fs_error = function() { + // don't create more object URLs than needed + if (blob_changed || !object_url) { + object_url = get_URL().createObjectURL(blob); + } + if (target_view) { + target_view.location.href = object_url; + } else { + var new_tab = view.open(object_url, "_blank"); + if (new_tab == undefined && typeof safari !== "undefined") { + //Apple do not allow window.open, see http://bit.ly/1kZffRI + view.location.href = object_url + } + } + filesaver.readyState = filesaver.DONE; + dispatch_all(); + revoke(object_url); + } + , abortable = function(func) { + return function() { + if (filesaver.readyState !== filesaver.DONE) { + return func.apply(this, arguments); + } + }; + } + , create_if_not_found = {create: true, exclusive: false} + , slice + ; + filesaver.readyState = filesaver.INIT; + if (!name) { + name = "download"; + } + if (can_use_save_link) { + object_url = get_URL().createObjectURL(blob); + save_link.href = object_url; + save_link.download = name; + setTimeout(function() { + click(save_link); + dispatch_all(); + revoke(object_url); + filesaver.readyState = filesaver.DONE; + }); + return; + } + // Object and web filesystem URLs have a problem saving in Google Chrome when + // viewed in a tab, so I force save with application/octet-stream + // http://code.google.com/p/chromium/issues/detail?id=91158 + // Update: Google errantly closed 91158, I submitted it again: + // https://code.google.com/p/chromium/issues/detail?id=389642 + if (view.chrome && type && type !== force_saveable_type) { + slice = blob.slice || blob.webkitSlice; + blob = slice.call(blob, 0, blob.size, force_saveable_type); + blob_changed = true; + } + // Since I can't be sure that the guessed media type will trigger a download + // in WebKit, I append .download to the filename. + // https://bugs.webkit.org/show_bug.cgi?id=65440 + if (webkit_req_fs && name !== "download") { + name += ".download"; + } + if (type === force_saveable_type || webkit_req_fs) { + target_view = view; + } + if (!req_fs) { + fs_error(); + return; + } + fs_min_size += blob.size; + req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) { + fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) { + var save = function() { + dir.getFile(name, create_if_not_found, abortable(function(file) { + file.createWriter(abortable(function(writer) { + writer.onwriteend = function(event) { + target_view.location.href = file.toURL(); + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "writeend", event); + revoke(file); + }; + writer.onerror = function() { + var error = writer.error; + if (error.code !== error.ABORT_ERR) { + fs_error(); + } + }; + "writestart progress write abort".split(" ").forEach(function(event) { + writer["on" + event] = filesaver["on" + event]; + }); + writer.write(blob); + filesaver.abort = function() { + writer.abort(); + filesaver.readyState = filesaver.DONE; + }; + filesaver.readyState = filesaver.WRITING; + }), fs_error); + }), fs_error); + }; + dir.getFile(name, {create: false}, abortable(function(file) { + // delete file if it already exists + file.remove(); + save(); + }), abortable(function(ex) { + if (ex.code === ex.NOT_FOUND_ERR) { + save(); + } else { + fs_error(); + } + })); + }), fs_error); + }), fs_error); + } + , FS_proto = FileSaver.prototype + , saveAs = function(blob, name, no_auto_bom) { + return new FileSaver(blob, name, no_auto_bom); + } + ; + // IE 10+ (native saveAs) + if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { + return function(blob, name, no_auto_bom) { + if (!no_auto_bom) { + blob = auto_bom(blob); + } + return navigator.msSaveOrOpenBlob(blob, name || "download"); + }; + } + + FS_proto.abort = function() { + var filesaver = this; + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "abort"); + }; + FS_proto.readyState = FS_proto.INIT = 0; + FS_proto.WRITING = 1; + FS_proto.DONE = 2; + + FS_proto.error = + FS_proto.onwritestart = + FS_proto.onprogress = + FS_proto.onwrite = + FS_proto.onabort = + FS_proto.onerror = + FS_proto.onwriteend = + null; + + return saveAs; +}( + typeof self !== "undefined" && self + || typeof window !== "undefined" && window + || this.content +)); +// `self` is undefined in Firefox for Android content script context +// while `this` is nsIContentFrameMessageManager +// with an attribute `content` that corresponds to the window + +if ( true && module.exports) { + module.exports.saveAs = saveAs; +} else if (( true && __webpack_require__(/*! !webpack amd define */ "../../node_modules/webpack/buildin/amd-define.js") !== null) && (__webpack_require__(/*! !webpack amd options */ "../../node_modules/webpack/buildin/amd-options.js") != null)) { + !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { + return saveAs; + }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); +} + + +/***/ }), + +/***/ "../../node_modules/angular-recursion/angular-recursion.js": +/*!***************************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/angular-recursion/angular-recursion.js ***! + \***************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/* + * An Angular service which helps with creating recursive directives. + * @author Mark Lagendijk + * @license MIT + */ +angular.module('RecursionHelper', []).factory('RecursionHelper', ['$compile', function($compile){ + return { + /** + * Manually compiles the element, fixing the recursion loop. + * @param element + * @param [link] A post-link function, or an object with function(s) registered via pre and post properties. + * @returns An object containing the linking functions. + */ + compile: function(element, link){ + // Normalize the link parameter + if(angular.isFunction(link)){ + link = { post: link }; + } + + // Break the recursion loop by removing the contents + var contents = element.contents().remove(); + var compiledContents; + return { + pre: (link && link.pre) ? link.pre : null, + /** + * Compiles and re-adds the contents + */ + post: function(scope, element){ + // Compile the contents + if(!compiledContents){ + compiledContents = $compile(contents); + } + // Re-add the compiled contents to the element + compiledContents(scope, function(clone){ + element.append(clone); + }); + + // Call the post-linking function, if any + if(link && link.post){ + link.post.apply(null, arguments); + } + } + }; + } + }; +}]); + +/***/ }), + +/***/ "../../node_modules/angular-sanitize/angular-sanitize.js": +/*!*************************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/angular-sanitize/angular-sanitize.js ***! + \*************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * @license AngularJS v1.8.0 + * (c) 2010-2020 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular) {'use strict'; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Any commits to this file should be reviewed with security in mind. * + * Changes to this file can potentially create security vulnerabilities. * + * An approval from 2 Core members with history of modifying * + * this file is required. * + * * + * Does the change somehow allow for arbitrary javascript to be executed? * + * Or allows for someone to change the prototype of built-in objects? * + * Or gives undesired access to variables likes document or window? * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +var $sanitizeMinErr = angular.$$minErr('$sanitize'); +var bind; +var extend; +var forEach; +var isArray; +var isDefined; +var lowercase; +var noop; +var nodeContains; +var htmlParser; +var htmlSanitizeWriter; + +/** + * @ngdoc module + * @name ngSanitize + * @description + * + * The `ngSanitize` module provides functionality to sanitize HTML. + * + * See {@link ngSanitize.$sanitize `$sanitize`} for usage. + */ + +/** + * @ngdoc service + * @name $sanitize + * @kind function + * + * @description + * Sanitizes an html string by stripping all potentially dangerous tokens. + * + * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are + * then serialized back to a properly escaped HTML string. This means that no unsafe input can make + * it into the returned string. + * + * The whitelist for URL sanitization of attribute values is configured using the functions + * `aHrefSanitizationWhitelist` and `imgSrcSanitizationWhitelist` of {@link $compileProvider}. + * + * The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}. + * + * @param {string} html HTML input. + * @returns {string} Sanitized HTML. + * + * @example + + + +
+ Snippet: + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectiveHowSourceRendered
ng-bind-htmlAutomatically uses $sanitize
<div ng-bind-html="snippet">
</div>
ng-bind-htmlBypass $sanitize by explicitly trusting the dangerous value +
<div ng-bind-html="deliberatelyTrustDangerousSnippet()">
+</div>
+
ng-bindAutomatically escapes
<div ng-bind="snippet">
</div>
+
+
+ + it('should sanitize the html snippet by default', function() { + expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')). + toBe('

an html\nclick here\nsnippet

'); + }); + + it('should inline raw snippet if bound to a trusted value', function() { + expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')). + toBe("

an html\n" + + "click here\n" + + "snippet

"); + }); + + it('should escape snippet without any filter', function() { + expect(element(by.css('#bind-default div')).getAttribute('innerHTML')). + toBe("<p style=\"color:blue\">an html\n" + + "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + + "snippet</p>"); + }); + + it('should update', function() { + element(by.model('snippet')).clear(); + element(by.model('snippet')).sendKeys('new text'); + expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')). + toBe('new text'); + expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')).toBe( + 'new text'); + expect(element(by.css('#bind-default div')).getAttribute('innerHTML')).toBe( + "new <b onclick=\"alert(1)\">text</b>"); + }); +
+
+ */ + + +/** + * @ngdoc provider + * @name $sanitizeProvider + * @this + * + * @description + * Creates and configures {@link $sanitize} instance. + */ +function $SanitizeProvider() { + var hasBeenInstantiated = false; + var svgEnabled = false; + + this.$get = ['$$sanitizeUri', function($$sanitizeUri) { + hasBeenInstantiated = true; + if (svgEnabled) { + extend(validElements, svgElements); + } + return function(html) { + var buf = []; + htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) { + return !/^unsafe:/.test($$sanitizeUri(uri, isImage)); + })); + return buf.join(''); + }; + }]; + + + /** + * @ngdoc method + * @name $sanitizeProvider#enableSvg + * @kind function + * + * @description + * Enables a subset of svg to be supported by the sanitizer. + * + *
+ *

By enabling this setting without taking other precautions, you might expose your + * application to click-hijacking attacks. In these attacks, sanitized svg elements could be positioned + * outside of the containing element and be rendered over other elements on the page (e.g. a login + * link). Such behavior can then result in phishing incidents.

+ * + *

To protect against these, explicitly setup `overflow: hidden` css rule for all potential svg + * tags within the sanitized content:

+ * + *
+ * + *

+   *   .rootOfTheIncludedContent svg {
+   *     overflow: hidden !important;
+   *   }
+   *   
+ *
+ * + * @param {boolean=} flag Enable or disable SVG support in the sanitizer. + * @returns {boolean|$sanitizeProvider} Returns the currently configured value if called + * without an argument or self for chaining otherwise. + */ + this.enableSvg = function(enableSvg) { + if (isDefined(enableSvg)) { + svgEnabled = enableSvg; + return this; + } else { + return svgEnabled; + } + }; + + + /** + * @ngdoc method + * @name $sanitizeProvider#addValidElements + * @kind function + * + * @description + * Extends the built-in lists of valid HTML/SVG elements, i.e. elements that are considered safe + * and are not stripped off during sanitization. You can extend the following lists of elements: + * + * - `htmlElements`: A list of elements (tag names) to extend the current list of safe HTML + * elements. HTML elements considered safe will not be removed during sanitization. All other + * elements will be stripped off. + * + * - `htmlVoidElements`: This is similar to `htmlElements`, but marks the elements as + * "void elements" (similar to HTML + * [void elements](https://rawgit.com/w3c/html/html5.1-2/single-page.html#void-elements)). These + * elements have no end tag and cannot have content. + * + * - `svgElements`: This is similar to `htmlElements`, but for SVG elements. This list is only + * taken into account if SVG is {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for + * `$sanitize`. + * + *
+ * This method must be called during the {@link angular.Module#config config} phase. Once the + * `$sanitize` service has been instantiated, this method has no effect. + *
+ * + *
+ * Keep in mind that extending the built-in lists of elements may expose your app to XSS or + * other vulnerabilities. Be very mindful of the elements you add. + *
+ * + * @param {Array|Object} elements - A list of valid HTML elements or an object with one or + * more of the following properties: + * - **htmlElements** - `{Array}` - A list of elements to extend the current list of + * HTML elements. + * - **htmlVoidElements** - `{Array}` - A list of elements to extend the current list of + * void HTML elements; i.e. elements that do not have an end tag. + * - **svgElements** - `{Array}` - A list of elements to extend the current list of SVG + * elements. The list of SVG elements is only taken into account if SVG is + * {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for `$sanitize`. + * + * Passing an array (`[...]`) is equivalent to passing `{htmlElements: [...]}`. + * + * @return {$sanitizeProvider} Returns self for chaining. + */ + this.addValidElements = function(elements) { + if (!hasBeenInstantiated) { + if (isArray(elements)) { + elements = {htmlElements: elements}; + } + + addElementsTo(svgElements, elements.svgElements); + addElementsTo(voidElements, elements.htmlVoidElements); + addElementsTo(validElements, elements.htmlVoidElements); + addElementsTo(validElements, elements.htmlElements); + } + + return this; + }; + + + /** + * @ngdoc method + * @name $sanitizeProvider#addValidAttrs + * @kind function + * + * @description + * Extends the built-in list of valid attributes, i.e. attributes that are considered safe and are + * not stripped off during sanitization. + * + * **Note**: + * The new attributes will not be treated as URI attributes, which means their values will not be + * sanitized as URIs using `$compileProvider`'s + * {@link ng.$compileProvider#aHrefSanitizationWhitelist aHrefSanitizationWhitelist} and + * {@link ng.$compileProvider#imgSrcSanitizationWhitelist imgSrcSanitizationWhitelist}. + * + *
+ * This method must be called during the {@link angular.Module#config config} phase. Once the + * `$sanitize` service has been instantiated, this method has no effect. + *
+ * + *
+ * Keep in mind that extending the built-in list of attributes may expose your app to XSS or + * other vulnerabilities. Be very mindful of the attributes you add. + *
+ * + * @param {Array} attrs - A list of valid attributes. + * + * @returns {$sanitizeProvider} Returns self for chaining. + */ + this.addValidAttrs = function(attrs) { + if (!hasBeenInstantiated) { + extend(validAttrs, arrayToMap(attrs, true)); + } + return this; + }; + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // Private stuff + ////////////////////////////////////////////////////////////////////////////////////////////////// + + bind = angular.bind; + extend = angular.extend; + forEach = angular.forEach; + isArray = angular.isArray; + isDefined = angular.isDefined; + lowercase = angular.$$lowercase; + noop = angular.noop; + + htmlParser = htmlParserImpl; + htmlSanitizeWriter = htmlSanitizeWriterImpl; + + nodeContains = window.Node.prototype.contains || /** @this */ function(arg) { + // eslint-disable-next-line no-bitwise + return !!(this.compareDocumentPosition(arg) & 16); + }; + + // Regular Expressions for parsing tags and attributes + var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + // Match everything outside of normal chars and " (quote character) + NON_ALPHANUMERIC_REGEXP = /([^#-~ |!])/g; + + + // Good source of info about elements and attributes + // http://dev.w3.org/html5/spec/Overview.html#semantics + // http://simon.html5.org/html-elements + + // Safe Void Elements - HTML5 + // http://dev.w3.org/html5/spec/Overview.html#void-elements + var voidElements = stringToMap('area,br,col,hr,img,wbr'); + + // Elements that you can, intentionally, leave open (and which close themselves) + // http://dev.w3.org/html5/spec/Overview.html#optional-tags + var optionalEndTagBlockElements = stringToMap('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr'), + optionalEndTagInlineElements = stringToMap('rp,rt'), + optionalEndTagElements = extend({}, + optionalEndTagInlineElements, + optionalEndTagBlockElements); + + // Safe Block Elements - HTML5 + var blockElements = extend({}, optionalEndTagBlockElements, stringToMap('address,article,' + + 'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' + + 'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul')); + + // Inline Elements - HTML5 + var inlineElements = extend({}, optionalEndTagInlineElements, stringToMap('a,abbr,acronym,b,' + + 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' + + 'samp,small,span,strike,strong,sub,sup,time,tt,u,var')); + + // SVG Elements + // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements + // Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted. + // They can potentially allow for arbitrary javascript to be executed. See #11290 + var svgElements = stringToMap('circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' + + 'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' + + 'radialGradient,rect,stop,svg,switch,text,title,tspan'); + + // Blocked Elements (will be stripped) + var blockedElements = stringToMap('script,style'); + + var validElements = extend({}, + voidElements, + blockElements, + inlineElements, + optionalEndTagElements); + + //Attributes that have href and hence need to be sanitized + var uriAttrs = stringToMap('background,cite,href,longdesc,src,xlink:href,xml:base'); + + var htmlAttrs = stringToMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' + + 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' + + 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' + + 'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' + + 'valign,value,vspace,width'); + + // SVG attributes (without "id" and "name" attributes) + // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes + var svgAttrs = stringToMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' + + 'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' + + 'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' + + 'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' + + 'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' + + 'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' + + 'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' + + 'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' + + 'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' + + 'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' + + 'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' + + 'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' + + 'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' + + 'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' + + 'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true); + + var validAttrs = extend({}, + uriAttrs, + svgAttrs, + htmlAttrs); + + function stringToMap(str, lowercaseKeys) { + return arrayToMap(str.split(','), lowercaseKeys); + } + + function arrayToMap(items, lowercaseKeys) { + var obj = {}, i; + for (i = 0; i < items.length; i++) { + obj[lowercaseKeys ? lowercase(items[i]) : items[i]] = true; + } + return obj; + } + + function addElementsTo(elementsMap, newElements) { + if (newElements && newElements.length) { + extend(elementsMap, arrayToMap(newElements)); + } + } + + /** + * Create an inert document that contains the dirty HTML that needs sanitizing + * Depending upon browser support we use one of three strategies for doing this. + * Support: Safari 10.x -> XHR strategy + * Support: Firefox -> DomParser strategy + */ + var getInertBodyElement /* function(html: string): HTMLBodyElement */ = (function(window, document) { + var inertDocument; + if (document && document.implementation) { + inertDocument = document.implementation.createHTMLDocument('inert'); + } else { + throw $sanitizeMinErr('noinert', 'Can\'t create an inert html document'); + } + var inertBodyElement = (inertDocument.documentElement || inertDocument.getDocumentElement()).querySelector('body'); + + // Check for the Safari 10.1 bug - which allows JS to run inside the SVG G element + inertBodyElement.innerHTML = ''; + if (!inertBodyElement.querySelector('svg')) { + return getInertBodyElement_XHR; + } else { + // Check for the Firefox bug - which prevents the inner img JS from being sanitized + inertBodyElement.innerHTML = '

'; + if (inertBodyElement.querySelector('svg img')) { + return getInertBodyElement_DOMParser; + } else { + return getInertBodyElement_InertDocument; + } + } + + function getInertBodyElement_XHR(html) { + // We add this dummy element to ensure that the rest of the content is parsed as expected + // e.g. leading whitespace is maintained and tags like `` do not get hoisted to the `` tag. + html = '' + html; + try { + html = encodeURI(html); + } catch (e) { + return undefined; + } + var xhr = new window.XMLHttpRequest(); + xhr.responseType = 'document'; + xhr.open('GET', 'data:text/html;charset=utf-8,' + html, false); + xhr.send(null); + var body = xhr.response.body; + body.firstChild.remove(); + return body; + } + + function getInertBodyElement_DOMParser(html) { + // We add this dummy element to ensure that the rest of the content is parsed as expected + // e.g. leading whitespace is maintained and tags like `` do not get hoisted to the `` tag. + html = '' + html; + try { + var body = new window.DOMParser().parseFromString(html, 'text/html').body; + body.firstChild.remove(); + return body; + } catch (e) { + return undefined; + } + } + + function getInertBodyElement_InertDocument(html) { + inertBodyElement.innerHTML = html; + + // Support: IE 9-11 only + // strip custom-namespaced attributes on IE<=11 + if (document.documentMode) { + stripCustomNsAttrs(inertBodyElement); + } + + return inertBodyElement; + } + })(window, window.document); + + /** + * @example + * htmlParser(htmlString, { + * start: function(tag, attrs) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * }); + * + * @param {string} html string + * @param {object} handler + */ + function htmlParserImpl(html, handler) { + if (html === null || html === undefined) { + html = ''; + } else if (typeof html !== 'string') { + html = '' + html; + } + + var inertBodyElement = getInertBodyElement(html); + if (!inertBodyElement) return ''; + + //mXSS protection + var mXSSAttempts = 5; + do { + if (mXSSAttempts === 0) { + throw $sanitizeMinErr('uinput', 'Failed to sanitize html because the input is unstable'); + } + mXSSAttempts--; + + // trigger mXSS if it is going to happen by reading and writing the innerHTML + html = inertBodyElement.innerHTML; + inertBodyElement = getInertBodyElement(html); + } while (html !== inertBodyElement.innerHTML); + + var node = inertBodyElement.firstChild; + while (node) { + switch (node.nodeType) { + case 1: // ELEMENT_NODE + handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes)); + break; + case 3: // TEXT NODE + handler.chars(node.textContent); + break; + } + + var nextNode; + if (!(nextNode = node.firstChild)) { + if (node.nodeType === 1) { + handler.end(node.nodeName.toLowerCase()); + } + nextNode = getNonDescendant('nextSibling', node); + if (!nextNode) { + while (nextNode == null) { + node = getNonDescendant('parentNode', node); + if (node === inertBodyElement) break; + nextNode = getNonDescendant('nextSibling', node); + if (node.nodeType === 1) { + handler.end(node.nodeName.toLowerCase()); + } + } + } + } + node = nextNode; + } + + while ((node = inertBodyElement.firstChild)) { + inertBodyElement.removeChild(node); + } + } + + function attrToMap(attrs) { + var map = {}; + for (var i = 0, ii = attrs.length; i < ii; i++) { + var attr = attrs[i]; + map[attr.name] = attr.value; + } + return map; + } + + + /** + * Escapes all potentially dangerous characters, so that the + * resulting string can be safely inserted into attribute or + * element text. + * @param value + * @returns {string} escaped text + */ + function encodeEntities(value) { + return value. + replace(/&/g, '&'). + replace(SURROGATE_PAIR_REGEXP, function(value) { + var hi = value.charCodeAt(0); + var low = value.charCodeAt(1); + return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';'; + }). + replace(NON_ALPHANUMERIC_REGEXP, function(value) { + return '&#' + value.charCodeAt(0) + ';'; + }). + replace(//g, '>'); + } + + /** + * create an HTML/XML writer which writes to buffer + * @param {Array} buf use buf.join('') to get out sanitized html string + * @returns {object} in the form of { + * start: function(tag, attrs) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * } + */ + function htmlSanitizeWriterImpl(buf, uriValidator) { + var ignoreCurrentElement = false; + var out = bind(buf, buf.push); + return { + start: function(tag, attrs) { + tag = lowercase(tag); + if (!ignoreCurrentElement && blockedElements[tag]) { + ignoreCurrentElement = tag; + } + if (!ignoreCurrentElement && validElements[tag] === true) { + out('<'); + out(tag); + forEach(attrs, function(value, key) { + var lkey = lowercase(key); + var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background'); + if (validAttrs[lkey] === true && + (uriAttrs[lkey] !== true || uriValidator(value, isImage))) { + out(' '); + out(key); + out('="'); + out(encodeEntities(value)); + out('"'); + } + }); + out('>'); + } + }, + end: function(tag) { + tag = lowercase(tag); + if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) { + out(''); + } + // eslint-disable-next-line eqeqeq + if (tag == ignoreCurrentElement) { + ignoreCurrentElement = false; + } + }, + chars: function(chars) { + if (!ignoreCurrentElement) { + out(encodeEntities(chars)); + } + } + }; + } + + + /** + * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1' attribute to declare + * ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo'). This is undesirable since we don't want + * to allow any of these custom attributes. This method strips them all. + * + * @param node Root element to process + */ + function stripCustomNsAttrs(node) { + while (node) { + if (node.nodeType === window.Node.ELEMENT_NODE) { + var attrs = node.attributes; + for (var i = 0, l = attrs.length; i < l; i++) { + var attrNode = attrs[i]; + var attrName = attrNode.name.toLowerCase(); + if (attrName === 'xmlns:ns1' || attrName.lastIndexOf('ns1:', 0) === 0) { + node.removeAttributeNode(attrNode); + i--; + l--; + } + } + } + + var nextNode = node.firstChild; + if (nextNode) { + stripCustomNsAttrs(nextNode); + } + + node = getNonDescendant('nextSibling', node); + } + } + + function getNonDescendant(propName, node) { + // An element is clobbered if its `propName` property points to one of its descendants + var nextNode = node[propName]; + if (nextNode && nodeContains.call(node, nextNode)) { + throw $sanitizeMinErr('elclob', 'Failed to sanitize html because the element is clobbered: {0}', node.outerHTML || node.outerText); + } + return nextNode; + } +} + +function sanitizeText(chars) { + var buf = []; + var writer = htmlSanitizeWriter(buf, noop); + writer.chars(chars); + return buf.join(''); +} + + +// define ngSanitize module and register $sanitize service +angular.module('ngSanitize', []) + .provider('$sanitize', $SanitizeProvider) + .info({ angularVersion: '1.8.0' }); + +/** + * @ngdoc filter + * @name linky + * @kind function + * + * @description + * Finds links in text input and turns them into html links. Supports `http/https/ftp/sftp/mailto` and + * plain email address links. + * + * Requires the {@link ngSanitize `ngSanitize`} module to be installed. + * + * @param {string} text Input text. + * @param {string} [target] Window (`_blank|_self|_parent|_top`) or named frame to open links in. + * @param {object|function(url)} [attributes] Add custom attributes to the link element. + * + * Can be one of: + * + * - `object`: A map of attributes + * - `function`: Takes the url as a parameter and returns a map of attributes + * + * If the map of attributes contains a value for `target`, it overrides the value of + * the target parameter. + * + * + * @returns {string} Html-linkified and {@link $sanitize sanitized} text. + * + * @usage + + * + * @example + + +

+ Snippet: + + + + + + + + + + + + + + + + + + + + + + + + + + +
FilterSourceRendered
linky filter +
<div ng-bind-html="snippet | linky">
</div>
+
+
+
linky target +
<div ng-bind-html="snippetWithSingleURL | linky:'_blank'">
</div>
+
+
+
linky custom attributes +
<div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}">
</div>
+
+
+
no filter
<div ng-bind="snippet">
</div>
+ + + angular.module('linkyExample', ['ngSanitize']) + .controller('ExampleController', ['$scope', function($scope) { + $scope.snippet = + 'Pretty text with some links:\n' + + 'http://angularjs.org/,\n' + + 'mailto:us@somewhere.org,\n' + + 'another@somewhere.org,\n' + + 'and one more: ftp://127.0.0.1/.'; + $scope.snippetWithSingleURL = 'http://angularjs.org/'; + }]); + + + it('should linkify the snippet with urls', function() { + expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). + toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' + + 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); + expect(element.all(by.css('#linky-filter a')).count()).toEqual(4); + }); + + it('should not linkify snippet without the linky filter', function() { + expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()). + toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' + + 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); + expect(element.all(by.css('#escaped-html a')).count()).toEqual(0); + }); + + it('should update', function() { + element(by.model('snippet')).clear(); + element(by.model('snippet')).sendKeys('new http://link.'); + expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). + toBe('new http://link.'); + expect(element.all(by.css('#linky-filter a')).count()).toEqual(1); + expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()) + .toBe('new http://link.'); + }); + + it('should work with the target property', function() { + expect(element(by.id('linky-target')). + element(by.binding("snippetWithSingleURL | linky:'_blank'")).getText()). + toBe('http://angularjs.org/'); + expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank'); + }); + + it('should optionally add custom attributes', function() { + expect(element(by.id('linky-custom-attributes')). + element(by.binding("snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}")).getText()). + toBe('http://angularjs.org/'); + expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow'); + }); + + + */ +angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { + var LINKY_URL_REGEXP = + /((s?ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i, + MAILTO_REGEXP = /^mailto:/i; + + var linkyMinErr = angular.$$minErr('linky'); + var isDefined = angular.isDefined; + var isFunction = angular.isFunction; + var isObject = angular.isObject; + var isString = angular.isString; + + return function(text, target, attributes) { + if (text == null || text === '') return text; + if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text); + + var attributesFn = + isFunction(attributes) ? attributes : + isObject(attributes) ? function getAttributesObject() {return attributes;} : + function getEmptyAttributesObject() {return {};}; + + var match; + var raw = text; + var html = []; + var url; + var i; + while ((match = raw.match(LINKY_URL_REGEXP))) { + // We can not end in these as they are sometimes found at the end of the sentence + url = match[0]; + // if we did not match ftp/http/www/mailto then assume mailto + if (!match[2] && !match[4]) { + url = (match[3] ? 'http://' : 'mailto:') + url; + } + i = match.index; + addText(raw.substr(0, i)); + addLink(url, match[0].replace(MAILTO_REGEXP, '')); + raw = raw.substring(i + match[0].length); + } + addText(raw); + return $sanitize(html.join('')); + + function addText(text) { + if (!text) { + return; + } + html.push(sanitizeText(text)); + } + + function addLink(url, text) { + var key, linkAttributes = attributesFn(url); + html.push(''); + addText(text); + html.push(''); + } + }; +}]); + + +})(window, window.angular); + + +/***/ }), + +/***/ "../../node_modules/angular-sanitize/index.js": +/*!**************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/angular-sanitize/index.js ***! + \**************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(/*! ./angular-sanitize */ "../../node_modules/angular-sanitize/angular-sanitize.js"); +module.exports = 'ngSanitize'; + + +/***/ }), + +/***/ "../../node_modules/css-loader/dist/cjs.js?!../../node_modules/postcss-loader/src/index.js?!../../node_modules/sass-loader/dist/cjs.js?!./public/index.scss?v7dark": +/*!*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/css-loader/dist/cjs.js??ref--6-oneOf-0-1!/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/postcss-loader/src??ref--6-oneOf-0-2!/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/sass-loader/dist/cjs.js??ref--6-oneOf-0-3!./public/index.scss?v7dark ***! + \*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +// Imports +var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ "../../node_modules/css-loader/dist/runtime/api.js"); +exports = ___CSS_LOADER_API_IMPORT___(true); +// Module +exports.push([module.i, ".embPanel__content[data-error], .embPanel__content[data-loading] {\n pointer-events: all !important;\n filter: none !important; }\n\n.kbn-polar {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: space-around;\n align-items: center;\n overflow-x: hidden;\n overflow-y: hidden; }\n", "",{"version":3,"sources":["index.scss"],"names":[],"mappings":"AAAA;EACE,8BAA8B;EAC9B,uBAAuB,EAAE;;AAE3B;EACE,WAAW;EACX,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,eAAe;EACf,6BAA6B;EAC7B,mBAAmB;EACnB,kBAAkB;EAClB,kBAAkB,EAAE","file":"index.scss","sourcesContent":[".embPanel__content[data-error], .embPanel__content[data-loading] {\n pointer-events: all !important;\n filter: none !important; }\n\n.kbn-polar {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: space-around;\n align-items: center;\n overflow-x: hidden;\n overflow-y: hidden; }\n"]}]); +// Exports +module.exports = exports; + + +/***/ }), + +/***/ "../../node_modules/css-loader/dist/cjs.js?!../../node_modules/postcss-loader/src/index.js?!../../node_modules/sass-loader/dist/cjs.js?!./public/index.scss?v7light": +/*!**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/postcss-loader/src??ref--6-oneOf-1-2!/home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/sass-loader/dist/cjs.js??ref--6-oneOf-1-3!./public/index.scss?v7light ***! + \**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +// Imports +var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ "../../node_modules/css-loader/dist/runtime/api.js"); +exports = ___CSS_LOADER_API_IMPORT___(true); +// Module +exports.push([module.i, ".embPanel__content[data-error], .embPanel__content[data-loading] {\n pointer-events: all !important;\n filter: none !important; }\n\n.kbn-polar {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: space-around;\n align-items: center;\n overflow-x: hidden;\n overflow-y: hidden; }\n", "",{"version":3,"sources":["index.scss"],"names":[],"mappings":"AAAA;EACE,8BAA8B;EAC9B,uBAAuB,EAAE;;AAE3B;EACE,WAAW;EACX,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,eAAe;EACf,6BAA6B;EAC7B,mBAAmB;EACnB,kBAAkB;EAClB,kBAAkB,EAAE","file":"index.scss","sourcesContent":[".embPanel__content[data-error], .embPanel__content[data-loading] {\n pointer-events: all !important;\n filter: none !important; }\n\n.kbn-polar {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: space-around;\n align-items: center;\n overflow-x: hidden;\n overflow-y: hidden; }\n"]}]); +// Exports +module.exports = exports; + + +/***/ }), + +/***/ "../../node_modules/css-loader/dist/runtime/api.js": +/*!*******************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/css-loader/dist/runtime/api.js ***! + \*******************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +// css base code, injected by the css-loader +// eslint-disable-next-line func-names +module.exports = function (useSourceMap) { + var list = []; // return the list of modules as css string + + list.toString = function toString() { + return this.map(function (item) { + var content = cssWithMappingToString(item, useSourceMap); + + if (item[2]) { + return "@media ".concat(item[2], " {").concat(content, "}"); + } + + return content; + }).join(''); + }; // import a list of modules into the list + // eslint-disable-next-line func-names + + + list.i = function (modules, mediaQuery, dedupe) { + if (typeof modules === 'string') { + // eslint-disable-next-line no-param-reassign + modules = [[null, modules, '']]; + } + + var alreadyImportedModules = {}; + + if (dedupe) { + for (var i = 0; i < this.length; i++) { + // eslint-disable-next-line prefer-destructuring + var id = this[i][0]; + + if (id != null) { + alreadyImportedModules[id] = true; + } + } + } + + for (var _i = 0; _i < modules.length; _i++) { + var item = [].concat(modules[_i]); + + if (dedupe && alreadyImportedModules[item[0]]) { + // eslint-disable-next-line no-continue + continue; + } + + if (mediaQuery) { + if (!item[2]) { + item[2] = mediaQuery; + } else { + item[2] = "".concat(mediaQuery, " and ").concat(item[2]); + } + } + + list.push(item); + } + }; + + return list; +}; + +function cssWithMappingToString(item, useSourceMap) { + var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring + + var cssMapping = item[3]; + + if (!cssMapping) { + return content; + } + + if (useSourceMap && typeof btoa === 'function') { + var sourceMapping = toComment(cssMapping); + var sourceURLs = cssMapping.sources.map(function (source) { + return "/*# sourceURL=".concat(cssMapping.sourceRoot || '').concat(source, " */"); + }); + return [content].concat(sourceURLs).concat([sourceMapping]).join('\n'); + } + + return [content].join('\n'); +} // Adapted from convert-source-map (MIT) + + +function toComment(sourceMap) { + // eslint-disable-next-line no-undef + var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))); + var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64); + return "/*# ".concat(data, " */"); +} + +/***/ }), + +/***/ "../../node_modules/lodash/_Hash.js": +/*!****************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_Hash.js ***! + \****************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var hashClear = __webpack_require__(/*! ./_hashClear */ "../../node_modules/lodash/_hashClear.js"), + hashDelete = __webpack_require__(/*! ./_hashDelete */ "../../node_modules/lodash/_hashDelete.js"), + hashGet = __webpack_require__(/*! ./_hashGet */ "../../node_modules/lodash/_hashGet.js"), + hashHas = __webpack_require__(/*! ./_hashHas */ "../../node_modules/lodash/_hashHas.js"), + hashSet = __webpack_require__(/*! ./_hashSet */ "../../node_modules/lodash/_hashSet.js"); + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +module.exports = Hash; + + +/***/ }), + +/***/ "../../node_modules/lodash/_ListCache.js": +/*!*********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_ListCache.js ***! + \*********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var listCacheClear = __webpack_require__(/*! ./_listCacheClear */ "../../node_modules/lodash/_listCacheClear.js"), + listCacheDelete = __webpack_require__(/*! ./_listCacheDelete */ "../../node_modules/lodash/_listCacheDelete.js"), + listCacheGet = __webpack_require__(/*! ./_listCacheGet */ "../../node_modules/lodash/_listCacheGet.js"), + listCacheHas = __webpack_require__(/*! ./_listCacheHas */ "../../node_modules/lodash/_listCacheHas.js"), + listCacheSet = __webpack_require__(/*! ./_listCacheSet */ "../../node_modules/lodash/_listCacheSet.js"); + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +module.exports = ListCache; + + +/***/ }), + +/***/ "../../node_modules/lodash/_Map.js": +/*!***************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_Map.js ***! + \***************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"), + root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'); + +module.exports = Map; + + +/***/ }), + +/***/ "../../node_modules/lodash/_MapCache.js": +/*!********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_MapCache.js ***! + \********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var mapCacheClear = __webpack_require__(/*! ./_mapCacheClear */ "../../node_modules/lodash/_mapCacheClear.js"), + mapCacheDelete = __webpack_require__(/*! ./_mapCacheDelete */ "../../node_modules/lodash/_mapCacheDelete.js"), + mapCacheGet = __webpack_require__(/*! ./_mapCacheGet */ "../../node_modules/lodash/_mapCacheGet.js"), + mapCacheHas = __webpack_require__(/*! ./_mapCacheHas */ "../../node_modules/lodash/_mapCacheHas.js"), + mapCacheSet = __webpack_require__(/*! ./_mapCacheSet */ "../../node_modules/lodash/_mapCacheSet.js"); + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +module.exports = MapCache; + + +/***/ }), + +/***/ "../../node_modules/lodash/_Symbol.js": +/*!******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_Symbol.js ***! + \******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/** Built-in value references. */ +var Symbol = root.Symbol; + +module.exports = Symbol; + + +/***/ }), + +/***/ "../../node_modules/lodash/_arrayMap.js": +/*!********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_arrayMap.js ***! + \********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +module.exports = arrayMap; + + +/***/ }), + +/***/ "../../node_modules/lodash/_assignValue.js": +/*!***********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_assignValue.js ***! + \***********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var baseAssignValue = __webpack_require__(/*! ./_baseAssignValue */ "../../node_modules/lodash/_baseAssignValue.js"), + eq = __webpack_require__(/*! ./eq */ "../../node_modules/lodash/eq.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } +} + +module.exports = assignValue; + + +/***/ }), + +/***/ "../../node_modules/lodash/_assocIndexOf.js": +/*!************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_assocIndexOf.js ***! + \************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var eq = __webpack_require__(/*! ./eq */ "../../node_modules/lodash/eq.js"); + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +module.exports = assocIndexOf; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseAssignValue.js": +/*!***************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_baseAssignValue.js ***! + \***************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var defineProperty = __webpack_require__(/*! ./_defineProperty */ "../../node_modules/lodash/_defineProperty.js"); + +/** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } +} + +module.exports = baseAssignValue; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseGetTag.js": +/*!**********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_baseGetTag.js ***! + \**********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var Symbol = __webpack_require__(/*! ./_Symbol */ "../../node_modules/lodash/_Symbol.js"), + getRawTag = __webpack_require__(/*! ./_getRawTag */ "../../node_modules/lodash/_getRawTag.js"), + objectToString = __webpack_require__(/*! ./_objectToString */ "../../node_modules/lodash/_objectToString.js"); + +/** `Object#toString` result references. */ +var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); +} + +module.exports = baseGetTag; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseIsNative.js": +/*!************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_baseIsNative.js ***! + \************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var isFunction = __webpack_require__(/*! ./isFunction */ "../../node_modules/lodash/isFunction.js"), + isMasked = __webpack_require__(/*! ./_isMasked */ "../../node_modules/lodash/_isMasked.js"), + isObject = __webpack_require__(/*! ./isObject */ "../../node_modules/lodash/isObject.js"), + toSource = __webpack_require__(/*! ./_toSource */ "../../node_modules/lodash/_toSource.js"); + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +module.exports = baseIsNative; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseToString.js": +/*!************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_baseToString.js ***! + \************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var Symbol = __webpack_require__(/*! ./_Symbol */ "../../node_modules/lodash/_Symbol.js"), + arrayMap = __webpack_require__(/*! ./_arrayMap */ "../../node_modules/lodash/_arrayMap.js"), + isArray = __webpack_require__(/*! ./isArray */ "../../node_modules/lodash/isArray.js"), + isSymbol = __webpack_require__(/*! ./isSymbol */ "../../node_modules/lodash/isSymbol.js"); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +module.exports = baseToString; + + +/***/ }), + +/***/ "../../node_modules/lodash/_castPath.js": +/*!********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_castPath.js ***! + \********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var isArray = __webpack_require__(/*! ./isArray */ "../../node_modules/lodash/isArray.js"), + isKey = __webpack_require__(/*! ./_isKey */ "../../node_modules/lodash/_isKey.js"), + stringToPath = __webpack_require__(/*! ./_stringToPath */ "../../node_modules/lodash/_stringToPath.js"), + toString = __webpack_require__(/*! ./toString */ "../../node_modules/lodash/toString.js"); + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); +} + +module.exports = castPath; + + +/***/ }), + +/***/ "../../node_modules/lodash/_coreJsData.js": +/*!**********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_coreJsData.js ***! + \**********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +module.exports = coreJsData; + + +/***/ }), + +/***/ "../../node_modules/lodash/_defineProperty.js": +/*!**************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_defineProperty.js ***! + \**************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"); + +var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} +}()); + +module.exports = defineProperty; + + +/***/ }), + +/***/ "../../node_modules/lodash/_freeGlobal.js": +/*!**********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_freeGlobal.js ***! + \**********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +module.exports = freeGlobal; + +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "../../node_modules/webpack/buildin/global.js"))) + +/***/ }), + +/***/ "../../node_modules/lodash/_getMapData.js": +/*!**********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_getMapData.js ***! + \**********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var isKeyable = __webpack_require__(/*! ./_isKeyable */ "../../node_modules/lodash/_isKeyable.js"); + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +module.exports = getMapData; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getNative.js": +/*!*********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_getNative.js ***! + \*********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var baseIsNative = __webpack_require__(/*! ./_baseIsNative */ "../../node_modules/lodash/_baseIsNative.js"), + getValue = __webpack_require__(/*! ./_getValue */ "../../node_modules/lodash/_getValue.js"); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +module.exports = getNative; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getRawTag.js": +/*!*********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_getRawTag.js ***! + \*********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var Symbol = __webpack_require__(/*! ./_Symbol */ "../../node_modules/lodash/_Symbol.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ +function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; +} + +module.exports = getRawTag; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getValue.js": +/*!********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_getValue.js ***! + \********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +module.exports = getValue; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashClear.js": +/*!*********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_hashClear.js ***! + \*********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var nativeCreate = __webpack_require__(/*! ./_nativeCreate */ "../../node_modules/lodash/_nativeCreate.js"); + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; +} + +module.exports = hashClear; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashDelete.js": +/*!**********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_hashDelete.js ***! + \**********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; +} + +module.exports = hashDelete; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashGet.js": +/*!*******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_hashGet.js ***! + \*******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var nativeCreate = __webpack_require__(/*! ./_nativeCreate */ "../../node_modules/lodash/_nativeCreate.js"); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +module.exports = hashGet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashHas.js": +/*!*******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_hashHas.js ***! + \*******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var nativeCreate = __webpack_require__(/*! ./_nativeCreate */ "../../node_modules/lodash/_nativeCreate.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); +} + +module.exports = hashHas; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashSet.js": +/*!*******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_hashSet.js ***! + \*******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var nativeCreate = __webpack_require__(/*! ./_nativeCreate */ "../../node_modules/lodash/_nativeCreate.js"); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +module.exports = hashSet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_isIndex.js": +/*!*******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_isIndex.js ***! + \*******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); +} + +module.exports = isIndex; + + +/***/ }), + +/***/ "../../node_modules/lodash/_isKey.js": +/*!*****************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_isKey.js ***! + \*****************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var isArray = __webpack_require__(/*! ./isArray */ "../../node_modules/lodash/isArray.js"), + isSymbol = __webpack_require__(/*! ./isSymbol */ "../../node_modules/lodash/isSymbol.js"); + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +module.exports = isKey; + + +/***/ }), + +/***/ "../../node_modules/lodash/_isKeyable.js": +/*!*********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_isKeyable.js ***! + \*********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +module.exports = isKeyable; + + +/***/ }), + +/***/ "../../node_modules/lodash/_isMasked.js": +/*!********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_isMasked.js ***! + \********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var coreJsData = __webpack_require__(/*! ./_coreJsData */ "../../node_modules/lodash/_coreJsData.js"); + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +module.exports = isMasked; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheClear.js": +/*!**************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_listCacheClear.js ***! + \**************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; + this.size = 0; +} + +module.exports = listCacheClear; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheDelete.js": +/*!***************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_listCacheDelete.js ***! + \***************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var assocIndexOf = __webpack_require__(/*! ./_assocIndexOf */ "../../node_modules/lodash/_assocIndexOf.js"); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; +} + +module.exports = listCacheDelete; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheGet.js": +/*!************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_listCacheGet.js ***! + \************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var assocIndexOf = __webpack_require__(/*! ./_assocIndexOf */ "../../node_modules/lodash/_assocIndexOf.js"); + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +module.exports = listCacheGet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheHas.js": +/*!************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_listCacheHas.js ***! + \************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var assocIndexOf = __webpack_require__(/*! ./_assocIndexOf */ "../../node_modules/lodash/_assocIndexOf.js"); + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +module.exports = listCacheHas; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheSet.js": +/*!************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_listCacheSet.js ***! + \************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var assocIndexOf = __webpack_require__(/*! ./_assocIndexOf */ "../../node_modules/lodash/_assocIndexOf.js"); + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +module.exports = listCacheSet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheClear.js": +/*!*************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_mapCacheClear.js ***! + \*************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var Hash = __webpack_require__(/*! ./_Hash */ "../../node_modules/lodash/_Hash.js"), + ListCache = __webpack_require__(/*! ./_ListCache */ "../../node_modules/lodash/_ListCache.js"), + Map = __webpack_require__(/*! ./_Map */ "../../node_modules/lodash/_Map.js"); + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +module.exports = mapCacheClear; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheDelete.js": +/*!**************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_mapCacheDelete.js ***! + \**************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var getMapData = __webpack_require__(/*! ./_getMapData */ "../../node_modules/lodash/_getMapData.js"); + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; +} + +module.exports = mapCacheDelete; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheGet.js": +/*!***********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_mapCacheGet.js ***! + \***********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var getMapData = __webpack_require__(/*! ./_getMapData */ "../../node_modules/lodash/_getMapData.js"); + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +module.exports = mapCacheGet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheHas.js": +/*!***********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_mapCacheHas.js ***! + \***********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var getMapData = __webpack_require__(/*! ./_getMapData */ "../../node_modules/lodash/_getMapData.js"); + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +module.exports = mapCacheHas; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheSet.js": +/*!***********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_mapCacheSet.js ***! + \***********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var getMapData = __webpack_require__(/*! ./_getMapData */ "../../node_modules/lodash/_getMapData.js"); + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; +} + +module.exports = mapCacheSet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_memoizeCapped.js": +/*!*************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_memoizeCapped.js ***! + \*************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var memoize = __webpack_require__(/*! ./memoize */ "../../node_modules/lodash/memoize.js"); + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +module.exports = memoizeCapped; + + +/***/ }), + +/***/ "../../node_modules/lodash/_nativeCreate.js": +/*!************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_nativeCreate.js ***! + \************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"); + +/* Built-in method references that are verified to be native. */ +var nativeCreate = getNative(Object, 'create'); + +module.exports = nativeCreate; + + +/***/ }), + +/***/ "../../node_modules/lodash/_objectToString.js": +/*!**************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_objectToString.js ***! + \**************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ +function objectToString(value) { + return nativeObjectToString.call(value); +} + +module.exports = objectToString; + + +/***/ }), + +/***/ "../../node_modules/lodash/_root.js": +/*!****************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_root.js ***! + \****************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var freeGlobal = __webpack_require__(/*! ./_freeGlobal */ "../../node_modules/lodash/_freeGlobal.js"); + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +module.exports = root; + + +/***/ }), + +/***/ "../../node_modules/lodash/_stringToPath.js": +/*!************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_stringToPath.js ***! + \************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var memoizeCapped = __webpack_require__(/*! ./_memoizeCapped */ "../../node_modules/lodash/_memoizeCapped.js"); + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +module.exports = stringToPath; + + +/***/ }), + +/***/ "../../node_modules/lodash/_toKey.js": +/*!*****************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_toKey.js ***! + \*****************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var isSymbol = __webpack_require__(/*! ./isSymbol */ "../../node_modules/lodash/isSymbol.js"); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +module.exports = toKey; + + +/***/ }), + +/***/ "../../node_modules/lodash/_toSource.js": +/*!********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/_toSource.js ***! + \********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** Used for built-in method references. */ +var funcProto = Function.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +module.exports = toSource; + + +/***/ }), + +/***/ "../../node_modules/lodash/eq.js": +/*!*************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/eq.js ***! + \*************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +module.exports = eq; + + +/***/ }), + +/***/ "../../node_modules/lodash/isArray.js": +/*!******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/isArray.js ***! + \******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +module.exports = isArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/isFunction.js": +/*!*********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/isFunction.js ***! + \*********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var baseGetTag = __webpack_require__(/*! ./_baseGetTag */ "../../node_modules/lodash/_baseGetTag.js"), + isObject = __webpack_require__(/*! ./isObject */ "../../node_modules/lodash/isObject.js"); + +/** `Object#toString` result references. */ +var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; +} + +module.exports = isFunction; + + +/***/ }), + +/***/ "../../node_modules/lodash/isObject.js": +/*!*******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/isObject.js ***! + \*******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); +} + +module.exports = isObject; + + +/***/ }), + +/***/ "../../node_modules/lodash/isObjectLike.js": +/*!***********************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/isObjectLike.js ***! + \***********************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return value != null && typeof value == 'object'; +} + +module.exports = isObjectLike; + + +/***/ }), + +/***/ "../../node_modules/lodash/isSymbol.js": +/*!*******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/isSymbol.js ***! + \*******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var baseGetTag = __webpack_require__(/*! ./_baseGetTag */ "../../node_modules/lodash/_baseGetTag.js"), + isObjectLike = __webpack_require__(/*! ./isObjectLike */ "../../node_modules/lodash/isObjectLike.js"); + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); +} + +module.exports = isSymbol; + + +/***/ }), + +/***/ "../../node_modules/lodash/memoize.js": +/*!******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/memoize.js ***! + \******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var MapCache = __webpack_require__(/*! ./_MapCache */ "../../node_modules/lodash/_MapCache.js"); + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ +function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; +} + +// Expose `MapCache`. +memoize.Cache = MapCache; + +module.exports = memoize; + + +/***/ }), + +/***/ "../../node_modules/lodash/toString.js": +/*!*******************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/lodash/toString.js ***! + \*******************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var baseToString = __webpack_require__(/*! ./_baseToString */ "../../node_modules/lodash/_baseToString.js"); + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString(value) { + return value == null ? '' : baseToString(value); +} + +module.exports = toString; + + +/***/ }), + +/***/ "../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js": +/*!******************************************************************************************************************************!*\ + !*** /home/dlumbrer/devel/kibanaworkspace/kibana-elastic/node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***! + \******************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var isOldIE = function isOldIE() { + var memo; + return function memorize() { + if (typeof memo === 'undefined') { + // Test for IE <= 9 as proposed by Browserhacks + // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805 + // Tests for existence of standard globals is to allow style-loader + // to operate correctly into non-standard environments + // @see https://github.com/webpack-contrib/style-loader/issues/177 + memo = Boolean(window && document && document.all && !window.atob); + } + + return memo; + }; +}(); + +var getTarget = function getTarget() { + var memo = {}; + return function memorize(target) { + if (typeof memo[target] === 'undefined') { + var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself + + if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) { + try { + // This will throw an exception if access to iframe is blocked + // due to cross-origin restrictions + styleTarget = styleTarget.contentDocument.head; + } catch (e) { + // istanbul ignore next + styleTarget = null; + } + } + + memo[target] = styleTarget; + } + + return memo[target]; + }; +}(); + +var stylesInDom = []; + +function getIndexByIdentifier(identifier) { + var result = -1; + + for (var i = 0; i < stylesInDom.length; i++) { + if (stylesInDom[i].identifier === identifier) { + result = i; + break; + } + } + + return result; +} + +function modulesToDom(list, options) { + var idCountMap = {}; + var identifiers = []; + + for (var i = 0; i < list.length; i++) { + var item = list[i]; + var id = options.base ? item[0] + options.base : item[0]; + var count = idCountMap[id] || 0; + var identifier = "".concat(id, " ").concat(count); + idCountMap[id] = count + 1; + var index = getIndexByIdentifier(identifier); + var obj = { + css: item[1], + media: item[2], + sourceMap: item[3] + }; + + if (index !== -1) { + stylesInDom[index].references++; + stylesInDom[index].updater(obj); + } else { + stylesInDom.push({ + identifier: identifier, + updater: addStyle(obj, options), + references: 1 + }); + } + + identifiers.push(identifier); + } + + return identifiers; +} + +function insertStyleElement(options) { + var style = document.createElement('style'); + var attributes = options.attributes || {}; + + if (typeof attributes.nonce === 'undefined') { + var nonce = true ? __webpack_require__.nc : undefined; + + if (nonce) { + attributes.nonce = nonce; + } + } + + Object.keys(attributes).forEach(function (key) { + style.setAttribute(key, attributes[key]); + }); + + if (typeof options.insert === 'function') { + options.insert(style); + } else { + var target = getTarget(options.insert || 'head'); + + if (!target) { + throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."); + } + + target.appendChild(style); + } + + return style; +} + +function removeStyleElement(style) { + // istanbul ignore if + if (style.parentNode === null) { + return false; + } + + style.parentNode.removeChild(style); +} +/* istanbul ignore next */ + + +var replaceText = function replaceText() { + var textStore = []; + return function replace(index, replacement) { + textStore[index] = replacement; + return textStore.filter(Boolean).join('\n'); + }; +}(); + +function applyToSingletonTag(style, index, remove, obj) { + var css = remove ? '' : obj.media ? "@media ".concat(obj.media, " {").concat(obj.css, "}") : obj.css; // For old IE + + /* istanbul ignore if */ + + if (style.styleSheet) { + style.styleSheet.cssText = replaceText(index, css); + } else { + var cssNode = document.createTextNode(css); + var childNodes = style.childNodes; + + if (childNodes[index]) { + style.removeChild(childNodes[index]); + } + + if (childNodes.length) { + style.insertBefore(cssNode, childNodes[index]); + } else { + style.appendChild(cssNode); + } + } +} + +function applyToTag(style, options, obj) { + var css = obj.css; + var media = obj.media; + var sourceMap = obj.sourceMap; + + if (media) { + style.setAttribute('media', media); + } else { + style.removeAttribute('media'); + } + + if (sourceMap && btoa) { + css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */"); + } // For old IE + + /* istanbul ignore if */ + + + if (style.styleSheet) { + style.styleSheet.cssText = css; + } else { + while (style.firstChild) { + style.removeChild(style.firstChild); + } + + style.appendChild(document.createTextNode(css)); + } +} + +var singleton = null; +var singletonCounter = 0; + +function addStyle(obj, options) { + var style; + var update; + var remove; + + if (options.singleton) { + var styleIndex = singletonCounter++; + style = singleton || (singleton = insertStyleElement(options)); + update = applyToSingletonTag.bind(null, style, styleIndex, false); + remove = applyToSingletonTag.bind(null, style, styleIndex, true); + } else { + style = insertStyleElement(options); + update = applyToTag.bind(null, style, options); + + remove = function remove() { + removeStyleElement(style); + }; + } + + update(obj); + return function updateStyle(newObj) { + if (newObj) { + if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) { + return; + } + + update(obj = newObj); + } else { + remove(); + } + }; +} + +module.exports = function (list, options) { + options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of ';\n if (inertBodyElement.querySelector('svg img')) {\n return getInertBodyElement_DOMParser;\n } else {\n return getInertBodyElement_InertDocument;\n }\n }\n\n function getInertBodyElement_XHR(html) {\n // We add this dummy element to ensure that the rest of the content is parsed as expected\n // e.g. leading whitespace is maintained and tags like `` do not get hoisted to the `` tag.\n html = '' + html;\n try {\n html = encodeURI(html);\n } catch (e) {\n return undefined;\n }\n var xhr = new window.XMLHttpRequest();\n xhr.responseType = 'document';\n xhr.open('GET', 'data:text/html;charset=utf-8,' + html, false);\n xhr.send(null);\n var body = xhr.response.body;\n body.firstChild.remove();\n return body;\n }\n\n function getInertBodyElement_DOMParser(html) {\n // We add this dummy element to ensure that the rest of the content is parsed as expected\n // e.g. leading whitespace is maintained and tags like `` do not get hoisted to the `` tag.\n html = '' + html;\n try {\n var body = new window.DOMParser().parseFromString(html, 'text/html').body;\n body.firstChild.remove();\n return body;\n } catch (e) {\n return undefined;\n }\n }\n\n function getInertBodyElement_InertDocument(html) {\n inertBodyElement.innerHTML = html;\n\n // Support: IE 9-11 only\n // strip custom-namespaced attributes on IE<=11\n if (document.documentMode) {\n stripCustomNsAttrs(inertBodyElement);\n }\n\n return inertBodyElement;\n }\n })(window, window.document);\n\n /**\n * @example\n * htmlParser(htmlString, {\n * start: function(tag, attrs) {},\n * end: function(tag) {},\n * chars: function(text) {},\n * comment: function(text) {}\n * });\n *\n * @param {string} html string\n * @param {object} handler\n */\n function htmlParserImpl(html, handler) {\n if (html === null || html === undefined) {\n html = '';\n } else if (typeof html !== 'string') {\n html = '' + html;\n }\n\n var inertBodyElement = getInertBodyElement(html);\n if (!inertBodyElement) return '';\n\n //mXSS protection\n var mXSSAttempts = 5;\n do {\n if (mXSSAttempts === 0) {\n throw $sanitizeMinErr('uinput', 'Failed to sanitize html because the input is unstable');\n }\n mXSSAttempts--;\n\n // trigger mXSS if it is going to happen by reading and writing the innerHTML\n html = inertBodyElement.innerHTML;\n inertBodyElement = getInertBodyElement(html);\n } while (html !== inertBodyElement.innerHTML);\n\n var node = inertBodyElement.firstChild;\n while (node) {\n switch (node.nodeType) {\n case 1: // ELEMENT_NODE\n handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes));\n break;\n case 3: // TEXT NODE\n handler.chars(node.textContent);\n break;\n }\n\n var nextNode;\n if (!(nextNode = node.firstChild)) {\n if (node.nodeType === 1) {\n handler.end(node.nodeName.toLowerCase());\n }\n nextNode = getNonDescendant('nextSibling', node);\n if (!nextNode) {\n while (nextNode == null) {\n node = getNonDescendant('parentNode', node);\n if (node === inertBodyElement) break;\n nextNode = getNonDescendant('nextSibling', node);\n if (node.nodeType === 1) {\n handler.end(node.nodeName.toLowerCase());\n }\n }\n }\n }\n node = nextNode;\n }\n\n while ((node = inertBodyElement.firstChild)) {\n inertBodyElement.removeChild(node);\n }\n }\n\n function attrToMap(attrs) {\n var map = {};\n for (var i = 0, ii = attrs.length; i < ii; i++) {\n var attr = attrs[i];\n map[attr.name] = attr.value;\n }\n return map;\n }\n\n\n /**\n * Escapes all potentially dangerous characters, so that the\n * resulting string can be safely inserted into attribute or\n * element text.\n * @param value\n * @returns {string} escaped text\n */\n function encodeEntities(value) {\n return value.\n replace(/&/g, '&').\n replace(SURROGATE_PAIR_REGEXP, function(value) {\n var hi = value.charCodeAt(0);\n var low = value.charCodeAt(1);\n return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';\n }).\n replace(NON_ALPHANUMERIC_REGEXP, function(value) {\n return '&#' + value.charCodeAt(0) + ';';\n }).\n replace(//g, '>');\n }\n\n /**\n * create an HTML/XML writer which writes to buffer\n * @param {Array} buf use buf.join('') to get out sanitized html string\n * @returns {object} in the form of {\n * start: function(tag, attrs) {},\n * end: function(tag) {},\n * chars: function(text) {},\n * comment: function(text) {}\n * }\n */\n function htmlSanitizeWriterImpl(buf, uriValidator) {\n var ignoreCurrentElement = false;\n var out = bind(buf, buf.push);\n return {\n start: function(tag, attrs) {\n tag = lowercase(tag);\n if (!ignoreCurrentElement && blockedElements[tag]) {\n ignoreCurrentElement = tag;\n }\n if (!ignoreCurrentElement && validElements[tag] === true) {\n out('<');\n out(tag);\n forEach(attrs, function(value, key) {\n var lkey = lowercase(key);\n var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');\n if (validAttrs[lkey] === true &&\n (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {\n out(' ');\n out(key);\n out('=\"');\n out(encodeEntities(value));\n out('\"');\n }\n });\n out('>');\n }\n },\n end: function(tag) {\n tag = lowercase(tag);\n if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) {\n out('');\n }\n // eslint-disable-next-line eqeqeq\n if (tag == ignoreCurrentElement) {\n ignoreCurrentElement = false;\n }\n },\n chars: function(chars) {\n if (!ignoreCurrentElement) {\n out(encodeEntities(chars));\n }\n }\n };\n }\n\n\n /**\n * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1' attribute to declare\n * ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo'). This is undesirable since we don't want\n * to allow any of these custom attributes. This method strips them all.\n *\n * @param node Root element to process\n */\n function stripCustomNsAttrs(node) {\n while (node) {\n if (node.nodeType === window.Node.ELEMENT_NODE) {\n var attrs = node.attributes;\n for (var i = 0, l = attrs.length; i < l; i++) {\n var attrNode = attrs[i];\n var attrName = attrNode.name.toLowerCase();\n if (attrName === 'xmlns:ns1' || attrName.lastIndexOf('ns1:', 0) === 0) {\n node.removeAttributeNode(attrNode);\n i--;\n l--;\n }\n }\n }\n\n var nextNode = node.firstChild;\n if (nextNode) {\n stripCustomNsAttrs(nextNode);\n }\n\n node = getNonDescendant('nextSibling', node);\n }\n }\n\n function getNonDescendant(propName, node) {\n // An element is clobbered if its `propName` property points to one of its descendants\n var nextNode = node[propName];\n if (nextNode && nodeContains.call(node, nextNode)) {\n throw $sanitizeMinErr('elclob', 'Failed to sanitize html because the element is clobbered: {0}', node.outerHTML || node.outerText);\n }\n return nextNode;\n }\n}\n\nfunction sanitizeText(chars) {\n var buf = [];\n var writer = htmlSanitizeWriter(buf, noop);\n writer.chars(chars);\n return buf.join('');\n}\n\n\n// define ngSanitize module and register $sanitize service\nangular.module('ngSanitize', [])\n .provider('$sanitize', $SanitizeProvider)\n .info({ angularVersion: '1.8.0' });\n\n/**\n * @ngdoc filter\n * @name linky\n * @kind function\n *\n * @description\n * Finds links in text input and turns them into html links. Supports `http/https/ftp/sftp/mailto` and\n * plain email address links.\n *\n * Requires the {@link ngSanitize `ngSanitize`} module to be installed.\n *\n * @param {string} text Input text.\n * @param {string} [target] Window (`_blank|_self|_parent|_top`) or named frame to open links in.\n * @param {object|function(url)} [attributes] Add custom attributes to the link element.\n *\n * Can be one of:\n *\n * - `object`: A map of attributes\n * - `function`: Takes the url as a parameter and returns a map of attributes\n *\n * If the map of attributes contains a value for `target`, it overrides the value of\n * the target parameter.\n *\n *\n * @returns {string} Html-linkified and {@link $sanitize sanitized} text.\n *\n * @usage\n \n *\n * @example\n \n \n
\n Snippet: \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
FilterSourceRendered
linky filter\n
<div ng-bind-html=\"snippet | linky\">
</div>
\n
\n
\n
linky target\n
<div ng-bind-html=\"snippetWithSingleURL | linky:'_blank'\">
</div>
\n
\n
\n
linky custom attributes\n
<div ng-bind-html=\"snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}\">
</div>
\n
\n
\n
no filter
<div ng-bind=\"snippet\">
</div>
\n \n \n angular.module('linkyExample', ['ngSanitize'])\n .controller('ExampleController', ['$scope', function($scope) {\n $scope.snippet =\n 'Pretty text with some links:\\n' +\n 'http://angularjs.org/,\\n' +\n 'mailto:us@somewhere.org,\\n' +\n 'another@somewhere.org,\\n' +\n 'and one more: ftp://127.0.0.1/.';\n $scope.snippetWithSingleURL = 'http://angularjs.org/';\n }]);\n \n \n it('should linkify the snippet with urls', function() {\n expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).\n toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +\n 'another@somewhere.org, and one more: ftp://127.0.0.1/.');\n expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);\n });\n\n it('should not linkify snippet without the linky filter', function() {\n expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).\n toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +\n 'another@somewhere.org, and one more: ftp://127.0.0.1/.');\n expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);\n });\n\n it('should update', function() {\n element(by.model('snippet')).clear();\n element(by.model('snippet')).sendKeys('new http://link.');\n expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).\n toBe('new http://link.');\n expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);\n expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())\n .toBe('new http://link.');\n });\n\n it('should work with the target property', function() {\n expect(element(by.id('linky-target')).\n element(by.binding(\"snippetWithSingleURL | linky:'_blank'\")).getText()).\n toBe('http://angularjs.org/');\n expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');\n });\n\n it('should optionally add custom attributes', function() {\n expect(element(by.id('linky-custom-attributes')).\n element(by.binding(\"snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}\")).getText()).\n toBe('http://angularjs.org/');\n expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow');\n });\n \n \n */\nangular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {\n var LINKY_URL_REGEXP =\n /((s?ftp|https?):\\/\\/|(www\\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\\S*[^\\s.;,(){}<>\"\\u201d\\u2019]/i,\n MAILTO_REGEXP = /^mailto:/i;\n\n var linkyMinErr = angular.$$minErr('linky');\n var isDefined = angular.isDefined;\n var isFunction = angular.isFunction;\n var isObject = angular.isObject;\n var isString = angular.isString;\n\n return function(text, target, attributes) {\n if (text == null || text === '') return text;\n if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text);\n\n var attributesFn =\n isFunction(attributes) ? attributes :\n isObject(attributes) ? function getAttributesObject() {return attributes;} :\n function getEmptyAttributesObject() {return {};};\n\n var match;\n var raw = text;\n var html = [];\n var url;\n var i;\n while ((match = raw.match(LINKY_URL_REGEXP))) {\n // We can not end in these as they are sometimes found at the end of the sentence\n url = match[0];\n // if we did not match ftp/http/www/mailto then assume mailto\n if (!match[2] && !match[4]) {\n url = (match[3] ? 'http://' : 'mailto:') + url;\n }\n i = match.index;\n addText(raw.substr(0, i));\n addLink(url, match[0].replace(MAILTO_REGEXP, ''));\n raw = raw.substring(i + match[0].length);\n }\n addText(raw);\n return $sanitize(html.join(''));\n\n function addText(text) {\n if (!text) {\n return;\n }\n html.push(sanitizeText(text));\n }\n\n function addLink(url, text) {\n var key, linkAttributes = attributesFn(url);\n html.push('');\n addText(text);\n html.push('');\n }\n };\n}]);\n\n\n})(window, window.angular);\n","require('./angular-sanitize');\nmodule.exports = 'ngSanitize';\n","// Imports\nvar ___CSS_LOADER_API_IMPORT___ = require(\"../../../node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(true);\n// Module\nexports.push([module.id, \".embPanel__content[data-error], .embPanel__content[data-loading] {\\n pointer-events: all !important;\\n filter: none !important; }\\n\\n.kbn-polar {\\n width: 100%;\\n height: 100%;\\n display: flex;\\n flex-direction: row;\\n flex-wrap: wrap;\\n justify-content: space-around;\\n align-items: center;\\n overflow-x: hidden;\\n overflow-y: hidden; }\\n\", \"\",{\"version\":3,\"sources\":[\"index.scss\"],\"names\":[],\"mappings\":\"AAAA;EACE,8BAA8B;EAC9B,uBAAuB,EAAE;;AAE3B;EACE,WAAW;EACX,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,eAAe;EACf,6BAA6B;EAC7B,mBAAmB;EACnB,kBAAkB;EAClB,kBAAkB,EAAE\",\"file\":\"index.scss\",\"sourcesContent\":[\".embPanel__content[data-error], .embPanel__content[data-loading] {\\n pointer-events: all !important;\\n filter: none !important; }\\n\\n.kbn-polar {\\n width: 100%;\\n height: 100%;\\n display: flex;\\n flex-direction: row;\\n flex-wrap: wrap;\\n justify-content: space-around;\\n align-items: center;\\n overflow-x: hidden;\\n overflow-y: hidden; }\\n\"]}]);\n// Exports\nmodule.exports = exports;\n","// Imports\nvar ___CSS_LOADER_API_IMPORT___ = require(\"../../../node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(true);\n// Module\nexports.push([module.id, \".embPanel__content[data-error], .embPanel__content[data-loading] {\\n pointer-events: all !important;\\n filter: none !important; }\\n\\n.kbn-polar {\\n width: 100%;\\n height: 100%;\\n display: flex;\\n flex-direction: row;\\n flex-wrap: wrap;\\n justify-content: space-around;\\n align-items: center;\\n overflow-x: hidden;\\n overflow-y: hidden; }\\n\", \"\",{\"version\":3,\"sources\":[\"index.scss\"],\"names\":[],\"mappings\":\"AAAA;EACE,8BAA8B;EAC9B,uBAAuB,EAAE;;AAE3B;EACE,WAAW;EACX,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,eAAe;EACf,6BAA6B;EAC7B,mBAAmB;EACnB,kBAAkB;EAClB,kBAAkB,EAAE\",\"file\":\"index.scss\",\"sourcesContent\":[\".embPanel__content[data-error], .embPanel__content[data-loading] {\\n pointer-events: all !important;\\n filter: none !important; }\\n\\n.kbn-polar {\\n width: 100%;\\n height: 100%;\\n display: flex;\\n flex-direction: row;\\n flex-wrap: wrap;\\n justify-content: space-around;\\n align-items: center;\\n overflow-x: hidden;\\n overflow-y: hidden; }\\n\"]}]);\n// Exports\nmodule.exports = exports;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (useSourceMap) {\n var list = []; // return the list of modules as css string\n\n list.toString = function toString() {\n return this.map(function (item) {\n var content = cssWithMappingToString(item, useSourceMap);\n\n if (item[2]) {\n return \"@media \".concat(item[2], \" {\").concat(content, \"}\");\n }\n\n return content;\n }).join('');\n }; // import a list of modules into the list\n // eslint-disable-next-line func-names\n\n\n list.i = function (modules, mediaQuery, dedupe) {\n if (typeof modules === 'string') {\n // eslint-disable-next-line no-param-reassign\n modules = [[null, modules, '']];\n }\n\n var alreadyImportedModules = {};\n\n if (dedupe) {\n for (var i = 0; i < this.length; i++) {\n // eslint-disable-next-line prefer-destructuring\n var id = this[i][0];\n\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n\n for (var _i = 0; _i < modules.length; _i++) {\n var item = [].concat(modules[_i]);\n\n if (dedupe && alreadyImportedModules[item[0]]) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (mediaQuery) {\n if (!item[2]) {\n item[2] = mediaQuery;\n } else {\n item[2] = \"\".concat(mediaQuery, \" and \").concat(item[2]);\n }\n }\n\n list.push(item);\n }\n };\n\n return list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring\n\n var cssMapping = item[3];\n\n if (!cssMapping) {\n return content;\n }\n\n if (useSourceMap && typeof btoa === 'function') {\n var sourceMapping = toComment(cssMapping);\n var sourceURLs = cssMapping.sources.map(function (source) {\n return \"/*# sourceURL=\".concat(cssMapping.sourceRoot || '').concat(source, \" */\");\n });\n return [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n }\n\n return [content].join('\\n');\n} // Adapted from convert-source-map (MIT)\n\n\nfunction toComment(sourceMap) {\n // eslint-disable-next-line no-undef\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n return \"/*# \".concat(data, \" */\");\n}","var hashClear = require('./_hashClear'),\n hashDelete = require('./_hashDelete'),\n hashGet = require('./_hashGet'),\n hashHas = require('./_hashHas'),\n hashSet = require('./_hashSet');\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nmodule.exports = Hash;\n","var listCacheClear = require('./_listCacheClear'),\n listCacheDelete = require('./_listCacheDelete'),\n listCacheGet = require('./_listCacheGet'),\n listCacheHas = require('./_listCacheHas'),\n listCacheSet = require('./_listCacheSet');\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nmodule.exports = ListCache;\n","var getNative = require('./_getNative'),\n root = require('./_root');\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nmodule.exports = Map;\n","var mapCacheClear = require('./_mapCacheClear'),\n mapCacheDelete = require('./_mapCacheDelete'),\n mapCacheGet = require('./_mapCacheGet'),\n mapCacheHas = require('./_mapCacheHas'),\n mapCacheSet = require('./_mapCacheSet');\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nmodule.exports = MapCache;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nmodule.exports = arrayMap;\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignValue;\n","var eq = require('./eq');\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nmodule.exports = assocIndexOf;\n","var defineProperty = require('./_defineProperty');\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nmodule.exports = baseAssignValue;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","var Symbol = require('./_Symbol'),\n arrayMap = require('./_arrayMap'),\n isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = baseToString;\n","var isArray = require('./isArray'),\n isKey = require('./_isKey'),\n stringToPath = require('./_stringToPath'),\n toString = require('./toString');\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nmodule.exports = castPath;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var isKeyable = require('./_isKeyable');\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nmodule.exports = getMapData;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","var nativeCreate = require('./_nativeCreate');\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nmodule.exports = hashClear;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = hashDelete;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nmodule.exports = hashGet;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nmodule.exports = hashHas;\n","var nativeCreate = require('./_nativeCreate');\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nmodule.exports = hashSet;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nmodule.exports = isIndex;\n","var isArray = require('./isArray'),\n isSymbol = require('./isSymbol');\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nmodule.exports = isKey;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nmodule.exports = isKeyable;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nmodule.exports = listCacheClear;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nmodule.exports = listCacheDelete;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nmodule.exports = listCacheGet;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nmodule.exports = listCacheHas;\n","var assocIndexOf = require('./_assocIndexOf');\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nmodule.exports = listCacheSet;\n","var Hash = require('./_Hash'),\n ListCache = require('./_ListCache'),\n Map = require('./_Map');\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nmodule.exports = mapCacheClear;\n","var getMapData = require('./_getMapData');\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nmodule.exports = mapCacheDelete;\n","var getMapData = require('./_getMapData');\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nmodule.exports = mapCacheGet;\n","var getMapData = require('./_getMapData');\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nmodule.exports = mapCacheHas;\n","var getMapData = require('./_getMapData');\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nmodule.exports = mapCacheSet;\n","var memoize = require('./memoize');\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nmodule.exports = memoizeCapped;\n","var getNative = require('./_getNative');\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nmodule.exports = nativeCreate;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","var memoizeCapped = require('./_memoizeCapped');\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nmodule.exports = stringToPath;\n","var isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = toKey;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nmodule.exports = eq;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var MapCache = require('./_MapCache');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nmodule.exports = memoize;\n","var baseToString = require('./_baseToString');\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n","\"use strict\";\n\nvar isOldIE = function isOldIE() {\n var memo;\n return function memorize() {\n if (typeof memo === 'undefined') {\n // Test for IE <= 9 as proposed by Browserhacks\n // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n // Tests for existence of standard globals is to allow style-loader\n // to operate correctly into non-standard environments\n // @see https://github.com/webpack-contrib/style-loader/issues/177\n memo = Boolean(window && document && document.all && !window.atob);\n }\n\n return memo;\n };\n}();\n\nvar getTarget = function getTarget() {\n var memo = {};\n return function memorize(target) {\n if (typeof memo[target] === 'undefined') {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n };\n}();\n\nvar stylesInDom = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDom.length; i++) {\n if (stylesInDom[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var index = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3]\n };\n\n if (index !== -1) {\n stylesInDom[index].references++;\n stylesInDom[index].updater(obj);\n } else {\n stylesInDom.push({\n identifier: identifier,\n updater: addStyle(obj, options),\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction insertStyleElement(options) {\n var style = document.createElement('style');\n var attributes = options.attributes || {};\n\n if (typeof attributes.nonce === 'undefined') {\n var nonce = typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;\n\n if (nonce) {\n attributes.nonce = nonce;\n }\n }\n\n Object.keys(attributes).forEach(function (key) {\n style.setAttribute(key, attributes[key]);\n });\n\n if (typeof options.insert === 'function') {\n options.insert(style);\n } else {\n var target = getTarget(options.insert || 'head');\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n }\n\n return style;\n}\n\nfunction removeStyleElement(style) {\n // istanbul ignore if\n if (style.parentNode === null) {\n return false;\n }\n\n style.parentNode.removeChild(style);\n}\n/* istanbul ignore next */\n\n\nvar replaceText = function replaceText() {\n var textStore = [];\n return function replace(index, replacement) {\n textStore[index] = replacement;\n return textStore.filter(Boolean).join('\\n');\n };\n}();\n\nfunction applyToSingletonTag(style, index, remove, obj) {\n var css = remove ? '' : obj.media ? \"@media \".concat(obj.media, \" {\").concat(obj.css, \"}\") : obj.css; // For old IE\n\n /* istanbul ignore if */\n\n if (style.styleSheet) {\n style.styleSheet.cssText = replaceText(index, css);\n } else {\n var cssNode = document.createTextNode(css);\n var childNodes = style.childNodes;\n\n if (childNodes[index]) {\n style.removeChild(childNodes[index]);\n }\n\n if (childNodes.length) {\n style.insertBefore(cssNode, childNodes[index]);\n } else {\n style.appendChild(cssNode);\n }\n }\n}\n\nfunction applyToTag(style, options, obj) {\n var css = obj.css;\n var media = obj.media;\n var sourceMap = obj.sourceMap;\n\n if (media) {\n style.setAttribute('media', media);\n } else {\n style.removeAttribute('media');\n }\n\n if (sourceMap && btoa) {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n while (style.firstChild) {\n style.removeChild(style.firstChild);\n }\n\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar singleton = null;\nvar singletonCounter = 0;\n\nfunction addStyle(obj, options) {\n var style;\n var update;\n var remove;\n\n if (options.singleton) {\n var styleIndex = singletonCounter++;\n style = singleton || (singleton = insertStyleElement(options));\n update = applyToSingletonTag.bind(null, style, styleIndex, false);\n remove = applyToSingletonTag.bind(null, style, styleIndex, true);\n } else {\n style = insertStyleElement(options);\n update = applyToTag.bind(null, style, options);\n\n remove = function remove() {\n removeStyleElement(style);\n };\n }\n\n update(obj);\n return function updateStyle(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n return;\n }\n\n update(obj = newObj);\n } else {\n remove();\n }\n };\n}\n\nmodule.exports = function (list, options) {\n options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of